1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #24146 from johnharris85/fix-swarm-update-auto-accept

Add comma-separated --auto-accept support.
This commit is contained in:
Sebastiaan van Stijn 2016-07-12 16:29:21 +02:00 committed by GitHub
commit 7da11b1afd
3 changed files with 70 additions and 44 deletions

View file

@ -14,10 +14,10 @@ import (
const ( const (
defaultListenAddr = "0.0.0.0:2377" defaultListenAddr = "0.0.0.0:2377"
// WORKER constant for worker name
WORKER = "WORKER" worker = "WORKER"
// MANAGER constant for manager name manager = "MANAGER"
MANAGER = "MANAGER" none = "NONE"
flagAutoAccept = "auto-accept" flagAutoAccept = "auto-accept"
flagCertExpiry = "cert-expiry" flagCertExpiry = "cert-expiry"
@ -30,8 +30,8 @@ const (
var ( var (
defaultPolicies = []swarm.Policy{ defaultPolicies = []swarm.Policy{
{Role: WORKER, Autoaccept: true}, {Role: worker, Autoaccept: true},
{Role: MANAGER, Autoaccept: false}, {Role: manager, Autoaccept: false},
} }
) )
@ -86,40 +86,33 @@ func NewListenAddrOption() NodeAddrOption {
// AutoAcceptOption is a value type for auto-accept policy // AutoAcceptOption is a value type for auto-accept policy
type AutoAcceptOption struct { type AutoAcceptOption struct {
values map[string]bool values map[string]struct{}
} }
// String prints a string representation of this option // String prints a string representation of this option
func (o *AutoAcceptOption) String() string { func (o *AutoAcceptOption) String() string {
keys := []string{} keys := []string{}
for key, value := range o.values { for key := range o.values {
keys = append(keys, fmt.Sprintf("%s=%v", strings.ToLower(key), value)) keys = append(keys, fmt.Sprintf("%s=true", strings.ToLower(key)))
} }
return strings.Join(keys, ", ") return strings.Join(keys, ", ")
} }
// Set sets a new value on this option // Set sets a new value on this option
func (o *AutoAcceptOption) Set(value string) error { func (o *AutoAcceptOption) Set(acceptValues string) error {
value = strings.ToUpper(value) for _, value := range strings.Split(acceptValues, ",") {
switch value { value = strings.ToUpper(value)
case "", "NONE": switch value {
if accept, ok := o.values[WORKER]; ok && accept { case none, worker, manager:
return fmt.Errorf("value NONE is incompatible with %s", WORKER) o.values[value] = struct{}{}
default:
return fmt.Errorf("must be one / combination of %s, %s; or NONE", worker, manager)
} }
if accept, ok := o.values[MANAGER]; ok && accept {
return fmt.Errorf("value NONE is incompatible with %s", MANAGER)
}
o.values[WORKER] = false
o.values[MANAGER] = false
case WORKER, MANAGER:
if accept, ok := o.values[value]; ok && !accept {
return fmt.Errorf("value NONE is incompatible with %s", value)
}
o.values[value] = true
default:
return fmt.Errorf("must be one of %s, %s, NONE", WORKER, MANAGER)
} }
// NONE must stand alone, so if any non-NONE setting exist with it, error with conflict
if o.isPresent(none) && len(o.values) > 1 {
return fmt.Errorf("value NONE cannot be specified alongside other node types")
}
return nil return nil
} }
@ -133,7 +126,11 @@ func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy {
policies := []swarm.Policy{} policies := []swarm.Policy{}
for _, p := range defaultPolicies { for _, p := range defaultPolicies {
if len(o.values) != 0 { if len(o.values) != 0 {
p.Autoaccept = o.values[string(p.Role)] if _, ok := o.values[string(p.Role)]; ok {
p.Autoaccept = true
} else {
p.Autoaccept = false
}
} }
p.Secret = secret p.Secret = secret
policies = append(policies, p) policies = append(policies, p)
@ -141,9 +138,15 @@ func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy {
return policies return policies
} }
// isPresent returns whether the key exists in the set or not
func (o *AutoAcceptOption) isPresent(key string) bool {
_, c := o.values[key]
return c
}
// NewAutoAcceptOption returns a new auto-accept option // NewAutoAcceptOption returns a new auto-accept option
func NewAutoAcceptOption() AutoAcceptOption { func NewAutoAcceptOption() AutoAcceptOption {
return AutoAcceptOption{values: make(map[string]bool)} return AutoAcceptOption{values: make(map[string]struct{})}
} }
// ExternalCAOption is a Value type for parsing external CA specifications. // ExternalCAOption is a Value type for parsing external CA specifications.

View file

@ -40,35 +40,51 @@ func TestNodeAddrOptionSetInvalidFormat(t *testing.T) {
func TestAutoAcceptOptionSetWorker(t *testing.T) { func TestAutoAcceptOptionSetWorker(t *testing.T) {
opt := NewAutoAcceptOption() opt := NewAutoAcceptOption()
assert.NilError(t, opt.Set("worker")) assert.NilError(t, opt.Set("worker"))
assert.Equal(t, opt.values[WORKER], true) assert.Equal(t, opt.isPresent(worker), true)
} }
func TestAutoAcceptOptionSetManager(t *testing.T) { func TestAutoAcceptOptionSetManager(t *testing.T) {
opt := NewAutoAcceptOption() opt := NewAutoAcceptOption()
assert.NilError(t, opt.Set("manager")) assert.NilError(t, opt.Set("manager"))
assert.Equal(t, opt.values[MANAGER], true) assert.Equal(t, opt.isPresent(manager), true)
} }
func TestAutoAcceptOptionSetInvalid(t *testing.T) { func TestAutoAcceptOptionSetInvalid(t *testing.T) {
opt := NewAutoAcceptOption() opt := NewAutoAcceptOption()
assert.Error(t, opt.Set("bogus"), "must be one of") assert.Error(t, opt.Set("bogus"), "must be one / combination")
}
func TestAutoAcceptOptionSetEmpty(t *testing.T) {
opt := NewAutoAcceptOption()
assert.Error(t, opt.Set(""), "must be one / combination")
} }
func TestAutoAcceptOptionSetNone(t *testing.T) { func TestAutoAcceptOptionSetNone(t *testing.T) {
opt := NewAutoAcceptOption() opt := NewAutoAcceptOption()
assert.NilError(t, opt.Set("none")) assert.NilError(t, opt.Set("none"))
assert.Equal(t, opt.values[MANAGER], false) assert.Equal(t, opt.isPresent(manager), false)
assert.Equal(t, opt.values[WORKER], false) assert.Equal(t, opt.isPresent(worker), false)
}
func TestAutoAcceptOptionSetTwo(t *testing.T) {
opt := NewAutoAcceptOption()
assert.NilError(t, opt.Set("worker,manager"))
assert.Equal(t, opt.isPresent(manager), true)
assert.Equal(t, opt.isPresent(worker), true)
} }
func TestAutoAcceptOptionSetConflict(t *testing.T) { func TestAutoAcceptOptionSetConflict(t *testing.T) {
opt := NewAutoAcceptOption() opt := NewAutoAcceptOption()
assert.NilError(t, opt.Set("manager")) assert.Error(t, opt.Set("none,manager"), "value NONE cannot be specified alongside other node types")
assert.Error(t, opt.Set("none"), "value NONE is incompatible with MANAGER")
opt = NewAutoAcceptOption() opt = NewAutoAcceptOption()
assert.NilError(t, opt.Set("none")) assert.Error(t, opt.Set("none,worker"), "value NONE cannot be specified alongside other node types")
assert.Error(t, opt.Set("worker"), "value NONE is incompatible with WORKER")
opt = NewAutoAcceptOption()
assert.Error(t, opt.Set("worker,none,manager"), "value NONE cannot be specified alongside other node types")
opt = NewAutoAcceptOption()
assert.Error(t, opt.Set("worker,manager,none"), "value NONE cannot be specified alongside other node types")
} }
func TestAutoAcceptOptionPoliciesDefault(t *testing.T) { func TestAutoAcceptOptionPoliciesDefault(t *testing.T) {
@ -78,12 +94,12 @@ func TestAutoAcceptOptionPoliciesDefault(t *testing.T) {
policies := opt.Policies(&secret) policies := opt.Policies(&secret)
assert.Equal(t, len(policies), 2) assert.Equal(t, len(policies), 2)
assert.Equal(t, policies[0], swarm.Policy{ assert.Equal(t, policies[0], swarm.Policy{
Role: WORKER, Role: worker,
Autoaccept: true, Autoaccept: true,
Secret: &secret, Secret: &secret,
}) })
assert.Equal(t, policies[1], swarm.Policy{ assert.Equal(t, policies[1], swarm.Policy{
Role: MANAGER, Role: manager,
Autoaccept: false, Autoaccept: false,
Secret: &secret, Secret: &secret,
}) })
@ -98,12 +114,12 @@ func TestAutoAcceptOptionPoliciesWithManager(t *testing.T) {
policies := opt.Policies(&secret) policies := opt.Policies(&secret)
assert.Equal(t, len(policies), 2) assert.Equal(t, len(policies), 2)
assert.Equal(t, policies[0], swarm.Policy{ assert.Equal(t, policies[0], swarm.Policy{
Role: WORKER, Role: worker,
Autoaccept: false, Autoaccept: false,
Secret: &secret, Secret: &secret,
}) })
assert.Equal(t, policies[1], swarm.Policy{ assert.Equal(t, policies[1], swarm.Policy{
Role: MANAGER, Role: manager,
Autoaccept: true, Autoaccept: true,
Secret: &secret, Secret: &secret,
}) })

View file

@ -17,7 +17,7 @@ Usage: docker swarm init [OPTIONS]
Initialize a Swarm Initialize a Swarm
Options: Options:
--auto-accept value Auto acceptance policy (worker, manager or none) --auto-accept value Auto acceptance policy (default worker)
--cert-expiry duration Validity period for node certificates (default 2160h0m0s) --cert-expiry duration Validity period for node certificates (default 2160h0m0s)
--dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s) --dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s)
--external-ca value Specifications of one or more certificate signing endpoints --external-ca value Specifications of one or more certificate signing endpoints
@ -66,6 +66,13 @@ For example, the following initializes a cluster with auto-acceptance of workers
$ docker swarm init --listen-addr 192.168.99.121:2377 --auto-accept worker $ docker swarm init --listen-addr 192.168.99.121:2377 --auto-accept worker
``` ```
It is possible to pass a comma-separated list of node types. The following initializes a cluster
with auto-acceptance of both `worker` and `manager` nodes
```bash
$ docker swarm init --listen-addr 192.168.99.121:2377 --auto-accept worker,manager
```
### `--cert-expiry` ### `--cert-expiry`
This flag sets the validity period for node certificates. This flag sets the validity period for node certificates.