github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/api/client/swarm/opts.go (about)

     1  package swarm
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/docker/docker/opts"
     9  	"github.com/docker/engine-api/types/swarm"
    10  	"github.com/spf13/pflag"
    11  )
    12  
    13  const (
    14  	defaultListenAddr = "0.0.0.0:2377"
    15  	// WORKER constant for worker name
    16  	WORKER = "WORKER"
    17  	// MANAGER constant for manager name
    18  	MANAGER = "MANAGER"
    19  
    20  	flagAutoAccept          = "auto-accept"
    21  	flagCertExpiry          = "cert-expiry"
    22  	flagDispatcherHeartbeat = "dispatcher-heartbeat"
    23  	flagListenAddr          = "listen-addr"
    24  	flagSecret              = "secret"
    25  	flagTaskHistoryLimit    = "task-history-limit"
    26  )
    27  
    28  var (
    29  	defaultPolicies = []swarm.Policy{
    30  		{Role: WORKER, Autoaccept: true},
    31  		{Role: MANAGER, Autoaccept: false},
    32  	}
    33  )
    34  
    35  type swarmOptions struct {
    36  	autoAccept          AutoAcceptOption
    37  	secret              string
    38  	taskHistoryLimit    int64
    39  	dispatcherHeartbeat time.Duration
    40  	nodeCertExpiry      time.Duration
    41  }
    42  
    43  // NodeAddrOption is a pflag.Value for listen and remote addresses
    44  type NodeAddrOption struct {
    45  	addr string
    46  }
    47  
    48  // String prints the representation of this flag
    49  func (a *NodeAddrOption) String() string {
    50  	return a.Value()
    51  }
    52  
    53  // Set the value for this flag
    54  func (a *NodeAddrOption) Set(value string) error {
    55  	addr, err := opts.ParseTCPAddr(value, a.addr)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	a.addr = addr
    60  	return nil
    61  }
    62  
    63  // Type returns the type of this flag
    64  func (a *NodeAddrOption) Type() string {
    65  	return "node-addr"
    66  }
    67  
    68  // Value returns the value of this option as addr:port
    69  func (a *NodeAddrOption) Value() string {
    70  	return strings.TrimPrefix(a.addr, "tcp://")
    71  }
    72  
    73  // NewNodeAddrOption returns a new node address option
    74  func NewNodeAddrOption(addr string) NodeAddrOption {
    75  	return NodeAddrOption{addr}
    76  }
    77  
    78  // NewListenAddrOption returns a NodeAddrOption with default values
    79  func NewListenAddrOption() NodeAddrOption {
    80  	return NewNodeAddrOption(defaultListenAddr)
    81  }
    82  
    83  // AutoAcceptOption is a value type for auto-accept policy
    84  type AutoAcceptOption struct {
    85  	values map[string]bool
    86  }
    87  
    88  // String prints a string representation of this option
    89  func (o *AutoAcceptOption) String() string {
    90  	keys := []string{}
    91  	for key, value := range o.values {
    92  		keys = append(keys, fmt.Sprintf("%s=%v", strings.ToLower(key), value))
    93  	}
    94  	return strings.Join(keys, ", ")
    95  }
    96  
    97  // Set sets a new value on this option
    98  func (o *AutoAcceptOption) Set(value string) error {
    99  	value = strings.ToUpper(value)
   100  	switch value {
   101  	case "", "NONE":
   102  		if accept, ok := o.values[WORKER]; ok && accept {
   103  			return fmt.Errorf("value NONE is incompatible with %s", WORKER)
   104  		}
   105  		if accept, ok := o.values[MANAGER]; ok && accept {
   106  			return fmt.Errorf("value NONE is incompatible with %s", MANAGER)
   107  		}
   108  		o.values[WORKER] = false
   109  		o.values[MANAGER] = false
   110  	case WORKER, MANAGER:
   111  		if accept, ok := o.values[value]; ok && !accept {
   112  			return fmt.Errorf("value NONE is incompatible with %s", value)
   113  		}
   114  		o.values[value] = true
   115  	default:
   116  		return fmt.Errorf("must be one of %s, %s, NONE", WORKER, MANAGER)
   117  	}
   118  
   119  	return nil
   120  }
   121  
   122  // Type returns the type of this option
   123  func (o *AutoAcceptOption) Type() string {
   124  	return "auto-accept"
   125  }
   126  
   127  // Policies returns a representation of this option for the api
   128  func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy {
   129  	policies := []swarm.Policy{}
   130  	for _, p := range defaultPolicies {
   131  		if len(o.values) != 0 {
   132  			p.Autoaccept = o.values[string(p.Role)]
   133  		}
   134  		p.Secret = secret
   135  		policies = append(policies, p)
   136  	}
   137  	return policies
   138  }
   139  
   140  // NewAutoAcceptOption returns a new auto-accept option
   141  func NewAutoAcceptOption() AutoAcceptOption {
   142  	return AutoAcceptOption{values: make(map[string]bool)}
   143  }
   144  
   145  func addSwarmFlags(flags *pflag.FlagSet, opts *swarmOptions) {
   146  	flags.Var(&opts.autoAccept, flagAutoAccept, "Auto acceptance policy (worker, manager or none)")
   147  	flags.StringVar(&opts.secret, flagSecret, "", "Set secret value needed to accept nodes into cluster")
   148  	flags.Int64Var(&opts.taskHistoryLimit, flagTaskHistoryLimit, 10, "Task history retention limit")
   149  	flags.DurationVar(&opts.dispatcherHeartbeat, flagDispatcherHeartbeat, time.Duration(5*time.Second), "Dispatcher heartbeat period")
   150  	flags.DurationVar(&opts.nodeCertExpiry, flagCertExpiry, time.Duration(90*24*time.Hour), "Validity period for node certificates")
   151  }
   152  
   153  func (opts *swarmOptions) ToSpec() swarm.Spec {
   154  	spec := swarm.Spec{}
   155  	if opts.secret != "" {
   156  		spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(&opts.secret)
   157  	} else {
   158  		spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(nil)
   159  	}
   160  	spec.Orchestration.TaskHistoryRetentionLimit = opts.taskHistoryLimit
   161  	spec.Dispatcher.HeartbeatPeriod = uint64(opts.dispatcherHeartbeat.Nanoseconds())
   162  	spec.CAConfig.NodeCertExpiry = opts.nodeCertExpiry
   163  	return spec
   164  }