Replace secrets with join tokens
Implement the proposal from https://github.com/docker/docker/issues/24430#issuecomment-233100121 Removes acceptance policy and secret in favor of an automatically generated join token that combines the secret, CA hash, and manager/worker role into a single opaque string. Adds a docker swarm join-token subcommand to inspect and rotate the tokens. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com> Upstream-commit: 2cc5bd33eef038bf5721582e2410ba459bb656e9 Component: engine
This commit is contained in:
@@ -216,15 +216,17 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *Swarm
|
||||
|
||||
if joinSwarm == true {
|
||||
if len(s.daemons) > 0 {
|
||||
tokens := s.daemons[0].joinTokens(c)
|
||||
token := tokens.Worker
|
||||
if manager {
|
||||
token = tokens.Manager
|
||||
}
|
||||
c.Assert(d.Join(swarm.JoinRequest{
|
||||
RemoteAddrs: []string{s.daemons[0].listenAddr},
|
||||
Manager: manager}), check.IsNil)
|
||||
} else {
|
||||
c.Assert(d.Init(swarm.InitRequest{
|
||||
Spec: swarm.Spec{
|
||||
AcceptancePolicy: autoAcceptPolicy,
|
||||
},
|
||||
JoinToken: token,
|
||||
}), check.IsNil)
|
||||
} else {
|
||||
c.Assert(d.Init(swarm.InitRequest{}), check.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,6 @@ type SwarmDaemon struct {
|
||||
listenAddr string
|
||||
}
|
||||
|
||||
// default policy in tests is allow-all
|
||||
var autoAcceptPolicy = swarm.AcceptancePolicy{
|
||||
Policies: []swarm.Policy{
|
||||
{Role: swarm.NodeRoleWorker, Autoaccept: true},
|
||||
{Role: swarm.NodeRoleManager, Autoaccept: true},
|
||||
},
|
||||
}
|
||||
|
||||
// Init initializes a new swarm cluster.
|
||||
func (d *SwarmDaemon) Init(req swarm.InitRequest) error {
|
||||
if req.ListenAddr == "" {
|
||||
@@ -271,6 +263,28 @@ func (d *SwarmDaemon) updateSwarm(c *check.C, f ...specConstructor) {
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) rotateTokens(c *check.C) {
|
||||
var sw swarm.Swarm
|
||||
status, out, err := d.SockRequest("GET", "/swarm", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
|
||||
|
||||
url := fmt.Sprintf("/swarm/update?version=%d&rotate_worker_token=true&rotate_manager_token=true", sw.Version.Index)
|
||||
status, out, err = d.SockRequest("POST", url, sw.Spec)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) joinTokens(c *check.C) swarm.JoinTokens {
|
||||
var sw swarm.Swarm
|
||||
status, out, err := d.SockRequest("GET", "/swarm", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
|
||||
return sw.JoinTokens
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) checkLocalNodeState(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info, err := d.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
@@ -43,7 +43,7 @@ func (s *DockerSwarmSuite) TestApiSwarmInit(c *check.C) {
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: d1.joinTokens(c).Worker, RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
@@ -72,89 +72,29 @@ func (s *DockerSwarmSuite) TestApiSwarmInit(c *check.C) {
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmManualAcceptance(c *check.C) {
|
||||
func (s *DockerSwarmSuite) TestApiSwarmJoinToken(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
s.testAPISwarmManualAcceptance(c, "")
|
||||
}
|
||||
func (s *DockerSwarmSuite) TestApiSwarmManualAcceptanceSecret(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
s.testAPISwarmManualAcceptance(c, "foobaz")
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) testAPISwarmManualAcceptance(c *check.C, secret string) {
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d1.Init(swarm.InitRequest{
|
||||
Spec: swarm.Spec{
|
||||
AcceptancePolicy: swarm.AcceptancePolicy{
|
||||
Policies: []swarm.Policy{
|
||||
{Role: swarm.NodeRoleWorker, Secret: &secret},
|
||||
{Role: swarm.NodeRoleManager, Secret: &secret},
|
||||
},
|
||||
},
|
||||
},
|
||||
}), checker.IsNil)
|
||||
c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
|
||||
|
||||
d2 := s.AddDaemon(c, false, false)
|
||||
err := d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
if secret == "" {
|
||||
c.Assert(err.Error(), checker.Contains, "needs to be accepted")
|
||||
info, err := d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
} else {
|
||||
c.Assert(err.Error(), checker.Contains, "valid secret token is necessary")
|
||||
info, err := d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
}
|
||||
d3 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d3.Join(swarm.JoinRequest{Secret: secret, RemoteAddrs: []string{d1.listenAddr}}), checker.NotNil)
|
||||
info, err := d3.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
|
||||
c.Assert(len(info.NodeID), checker.GreaterThan, 5)
|
||||
d1.updateNode(c, info.NodeID, func(n *swarm.Node) {
|
||||
n.Spec.Membership = swarm.NodeMembershipAccepted
|
||||
})
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d3.checkLocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmSecretAcceptance(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
secret := "foobar"
|
||||
c.Assert(d1.Init(swarm.InitRequest{
|
||||
Spec: swarm.Spec{
|
||||
AcceptancePolicy: swarm.AcceptancePolicy{
|
||||
Policies: []swarm.Policy{
|
||||
{Role: swarm.NodeRoleWorker, Autoaccept: true, Secret: &secret},
|
||||
{Role: swarm.NodeRoleManager, Secret: &secret},
|
||||
},
|
||||
},
|
||||
},
|
||||
}), checker.IsNil)
|
||||
|
||||
d2 := s.AddDaemon(c, false, false)
|
||||
err := d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "secret token is necessary")
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err := d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{Secret: "foobaz", RemoteAddrs: []string{d1.listenAddr}})
|
||||
err = d2.Join(swarm.JoinRequest{JoinToken: "foobaz", RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "secret token is necessary")
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{Secret: "foobar", RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
workerToken := d1.joinTokens(c).Worker
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
@@ -163,22 +103,19 @@ func (s *DockerSwarmSuite) TestApiSwarmSecretAcceptance(c *check.C) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
// change secret
|
||||
d1.updateSwarm(c, func(s *swarm.Spec) {
|
||||
for i := range s.AcceptancePolicy.Policies {
|
||||
p := "foobaz"
|
||||
s.AcceptancePolicy.Policies[i].Secret = &p
|
||||
}
|
||||
})
|
||||
// change tokens
|
||||
d1.rotateTokens(c)
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{Secret: "foobar", RemoteAddrs: []string{d1.listenAddr}})
|
||||
err = d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "secret token is necessary")
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{Secret: "foobaz", RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
workerToken = d1.joinTokens(c).Worker
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
@@ -187,24 +124,17 @@ func (s *DockerSwarmSuite) TestApiSwarmSecretAcceptance(c *check.C) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
// change policy, don't change secret
|
||||
d1.updateSwarm(c, func(s *swarm.Spec) {
|
||||
for i, p := range s.AcceptancePolicy.Policies {
|
||||
if p.Role == swarm.NodeRoleManager {
|
||||
s.AcceptancePolicy.Policies[i].Autoaccept = false
|
||||
}
|
||||
s.AcceptancePolicy.Policies[i].Secret = nil
|
||||
}
|
||||
})
|
||||
// change spec, don't change tokens
|
||||
d1.updateSwarm(c, func(s *swarm.Spec) {})
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "secret token is necessary")
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{Secret: "foobaz", RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
@@ -212,51 +142,24 @@ func (s *DockerSwarmSuite) TestApiSwarmSecretAcceptance(c *check.C) {
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
// clear secret
|
||||
d1.updateSwarm(c, func(s *swarm.Spec) {
|
||||
for i := range s.AcceptancePolicy.Policies {
|
||||
p := ""
|
||||
s.AcceptancePolicy.Policies[i].Secret = &p
|
||||
}
|
||||
})
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
info, err = d2.info()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmCAHash(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
d1 := s.AddDaemon(c, true, true)
|
||||
d2 := s.AddDaemon(c, false, false)
|
||||
err := d2.Join(swarm.JoinRequest{CACertHash: "foobar", RemoteAddrs: []string{d1.listenAddr}})
|
||||
splitToken := strings.Split(d1.joinTokens(c).Worker, "-")
|
||||
splitToken[2] = "1kxftv4ofnc6mt30lmgipg6ngf9luhwqopfk1tz6bdmnkubg0e"
|
||||
replacementToken := strings.Join(splitToken, "-")
|
||||
err := d2.Join(swarm.JoinRequest{JoinToken: replacementToken, RemoteAddrs: []string{d1.listenAddr}})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "invalid checksum digest format")
|
||||
|
||||
c.Assert(len(d1.CACertHash), checker.GreaterThan, 0)
|
||||
c.Assert(d2.Join(swarm.JoinRequest{CACertHash: d1.CACertHash, RemoteAddrs: []string{d1.listenAddr}}), checker.IsNil)
|
||||
c.Assert(err.Error(), checker.Contains, "remote CA does not match fingerprint")
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmPromoteDemote(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d1.Init(swarm.InitRequest{
|
||||
Spec: swarm.Spec{
|
||||
AcceptancePolicy: swarm.AcceptancePolicy{
|
||||
Policies: []swarm.Policy{
|
||||
{Role: swarm.NodeRoleWorker, Autoaccept: true},
|
||||
{Role: swarm.NodeRoleManager},
|
||||
},
|
||||
},
|
||||
},
|
||||
}), checker.IsNil)
|
||||
c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
|
||||
d2 := s.AddDaemon(c, true, false)
|
||||
|
||||
info, err := d2.info()
|
||||
@@ -838,9 +741,7 @@ func (s *DockerSwarmSuite) TestApiSwarmForceNewCluster(c *check.C) {
|
||||
|
||||
c.Assert(d1.Init(swarm.InitRequest{
|
||||
ForceNewCluster: true,
|
||||
Spec: swarm.Spec{
|
||||
AcceptancePolicy: autoAcceptPolicy,
|
||||
},
|
||||
Spec: swarm.Spec{},
|
||||
}), checker.IsNil)
|
||||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d1.checkActiveContainerCount, checker.Equals, instances)
|
||||
@@ -937,7 +838,6 @@ func checkClusterHealth(c *check.C, cl []*SwarmDaemon, managerCount, workerCount
|
||||
for _, n := range d.listNodes(c) {
|
||||
c.Assert(n.Status.State, checker.Equals, swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.Info.NodeID))
|
||||
c.Assert(n.Spec.Availability, checker.Equals, swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.Info.NodeID))
|
||||
c.Assert(n.Spec.Membership, checker.Equals, swarm.NodeMembershipAccepted, check.Commentf("membership of node %s, reported by %s", n.ID, d.Info.NodeID))
|
||||
if n.Spec.Role == swarm.NodeRoleManager {
|
||||
c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.Info.NodeID))
|
||||
if n.ManagerStatus.Leader {
|
||||
|
||||
@@ -25,50 +25,13 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) {
|
||||
return sw[0].Spec
|
||||
}
|
||||
|
||||
out, err := d.Cmd("swarm", "update", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", "--auto-accept", "manager", "--auto-accept", "worker", "--secret", "foo")
|
||||
out, err := d.Cmd("swarm", "update", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
||||
|
||||
spec := getSpec()
|
||||
c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour)
|
||||
c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, uint64(11*time.Second))
|
||||
|
||||
c.Assert(spec.AcceptancePolicy.Policies, checker.HasLen, 2)
|
||||
|
||||
for _, p := range spec.AcceptancePolicy.Policies {
|
||||
c.Assert(p.Autoaccept, checker.Equals, true)
|
||||
c.Assert(p.Secret, checker.NotNil)
|
||||
c.Assert(*p.Secret, checker.Not(checker.Equals), "")
|
||||
}
|
||||
|
||||
out, err = d.Cmd("swarm", "update", "--auto-accept", "none")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
||||
|
||||
spec = getSpec()
|
||||
c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour)
|
||||
c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, uint64(11*time.Second))
|
||||
|
||||
c.Assert(spec.AcceptancePolicy.Policies, checker.HasLen, 2)
|
||||
|
||||
for _, p := range spec.AcceptancePolicy.Policies {
|
||||
c.Assert(p.Autoaccept, checker.Equals, false)
|
||||
// secret is still set
|
||||
c.Assert(p.Secret, checker.NotNil)
|
||||
c.Assert(*p.Secret, checker.Not(checker.Equals), "")
|
||||
}
|
||||
|
||||
out, err = d.Cmd("swarm", "update", "--auto-accept", "manager", "--secret", "")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
||||
|
||||
spec = getSpec()
|
||||
|
||||
c.Assert(spec.AcceptancePolicy.Policies, checker.HasLen, 2)
|
||||
|
||||
for _, p := range spec.AcceptancePolicy.Policies {
|
||||
c.Assert(p.Autoaccept, checker.Equals, p.Role == swarm.NodeRoleManager)
|
||||
// secret has been removed
|
||||
c.Assert(p.Secret, checker.IsNil)
|
||||
}
|
||||
|
||||
// setting anything under 30m for cert-expiry is not allowed
|
||||
out, err = d.Cmd("swarm", "update", "--cert-expiry", "15m")
|
||||
c.Assert(err, checker.NotNil)
|
||||
@@ -89,37 +52,21 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
|
||||
return sw[0].Spec
|
||||
}
|
||||
|
||||
out, err := d.Cmd("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", "--auto-accept", "manager", "--auto-accept", "worker", "--secret", "foo")
|
||||
out, err := d.Cmd("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
||||
|
||||
spec := getSpec()
|
||||
c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour)
|
||||
c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, uint64(11*time.Second))
|
||||
|
||||
c.Assert(spec.AcceptancePolicy.Policies, checker.HasLen, 2)
|
||||
|
||||
for _, p := range spec.AcceptancePolicy.Policies {
|
||||
c.Assert(p.Autoaccept, checker.Equals, true)
|
||||
c.Assert(p.Secret, checker.NotNil)
|
||||
c.Assert(*p.Secret, checker.Not(checker.Equals), "")
|
||||
}
|
||||
|
||||
c.Assert(d.Leave(true), checker.IsNil)
|
||||
|
||||
out, err = d.Cmd("swarm", "init", "--auto-accept", "none", "--secret", "")
|
||||
out, err = d.Cmd("swarm", "init")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
||||
|
||||
spec = getSpec()
|
||||
c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour)
|
||||
c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, uint64(5*time.Second))
|
||||
|
||||
c.Assert(spec.AcceptancePolicy.Policies, checker.HasLen, 2)
|
||||
|
||||
for _, p := range spec.AcceptancePolicy.Policies {
|
||||
c.Assert(p.Autoaccept, checker.Equals, false)
|
||||
c.Assert(p.Secret, checker.IsNil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) {
|
||||
|
||||
Reference in New Issue
Block a user