2016-06-14 02:56:23 +00:00
|
|
|
package swarm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2016-06-17 19:42:16 +00:00
|
|
|
"net"
|
|
|
|
"strconv"
|
2016-06-14 02:56:23 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/docker/engine-api/types/swarm"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-06-17 19:42:16 +00:00
|
|
|
defaultListenAddr = "0.0.0.0"
|
|
|
|
defaultListenPort uint16 = 2377
|
2016-06-14 02:56:23 +00:00
|
|
|
// WORKER constant for worker name
|
|
|
|
WORKER = "WORKER"
|
|
|
|
// MANAGER constant for manager name
|
|
|
|
MANAGER = "MANAGER"
|
2016-06-17 19:42:16 +00:00
|
|
|
|
|
|
|
flagAutoAccept = "auto-accept"
|
|
|
|
flagCertExpiry = "cert-expiry"
|
|
|
|
flagDispatcherHeartbeat = "dispatcher-heartbeat"
|
|
|
|
flagListenAddr = "listen-addr"
|
|
|
|
flagSecret = "secret"
|
|
|
|
flagTaskHistoryLimit = "task-history-limit"
|
2016-06-14 02:56:23 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
defaultPolicies = []swarm.Policy{
|
|
|
|
{Role: WORKER, Autoaccept: true},
|
|
|
|
{Role: MANAGER, Autoaccept: false},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// NodeAddrOption is a pflag.Value for listen and remote addresses
|
|
|
|
type NodeAddrOption struct {
|
|
|
|
addr string
|
2016-06-17 19:42:16 +00:00
|
|
|
port uint16
|
2016-06-14 02:56:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// String prints the representation of this flag
|
|
|
|
func (a *NodeAddrOption) String() string {
|
2016-06-17 19:42:16 +00:00
|
|
|
return a.Value()
|
2016-06-14 02:56:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the value for this flag
|
|
|
|
func (a *NodeAddrOption) Set(value string) error {
|
|
|
|
if !strings.Contains(value, ":") {
|
2016-06-17 19:42:16 +00:00
|
|
|
a.addr = value
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
host, port, err := net.SplitHostPort(value)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Invalid url, %v", err)
|
2016-06-14 02:56:23 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 19:42:16 +00:00
|
|
|
portInt, err := strconv.ParseUint(port, 10, 16)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("invalid url, %v", err)
|
2016-06-14 02:56:23 +00:00
|
|
|
}
|
2016-06-17 19:42:16 +00:00
|
|
|
a.port = uint16(portInt)
|
2016-06-14 02:56:23 +00:00
|
|
|
|
2016-06-17 19:42:16 +00:00
|
|
|
if host != "" {
|
|
|
|
a.addr = host
|
|
|
|
}
|
2016-06-14 02:56:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Type returns the type of this flag
|
|
|
|
func (a *NodeAddrOption) Type() string {
|
|
|
|
return "node-addr"
|
|
|
|
}
|
|
|
|
|
2016-06-17 19:42:16 +00:00
|
|
|
// Value returns the value of this option as addr:port
|
|
|
|
func (a *NodeAddrOption) Value() string {
|
|
|
|
return net.JoinHostPort(a.addr, strconv.Itoa(int(a.port)))
|
|
|
|
}
|
|
|
|
|
2016-06-14 02:56:23 +00:00
|
|
|
// NewNodeAddrOption returns a new node address option
|
2016-06-17 19:42:16 +00:00
|
|
|
func NewNodeAddrOption(host string, port uint16) NodeAddrOption {
|
|
|
|
return NodeAddrOption{addr: host, port: port}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewListenAddrOption returns a NodeAddrOption with default values
|
|
|
|
func NewListenAddrOption() NodeAddrOption {
|
|
|
|
return NewNodeAddrOption(defaultListenAddr, defaultListenPort)
|
2016-06-14 02:56:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// AutoAcceptOption is a value type for auto-accept policy
|
|
|
|
type AutoAcceptOption struct {
|
|
|
|
values map[string]bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// String prints a string representation of this option
|
|
|
|
func (o *AutoAcceptOption) String() string {
|
|
|
|
keys := []string{}
|
|
|
|
for key := range o.values {
|
|
|
|
keys = append(keys, key)
|
|
|
|
}
|
|
|
|
return strings.Join(keys, " ")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set sets a new value on this option
|
|
|
|
func (o *AutoAcceptOption) Set(value string) error {
|
|
|
|
value = strings.ToUpper(value)
|
|
|
|
switch value {
|
|
|
|
case "", "NONE":
|
|
|
|
if accept, ok := o.values[WORKER]; ok && accept {
|
|
|
|
return fmt.Errorf("value NONE is incompatible with %s", WORKER)
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Type returns the type of this option
|
|
|
|
func (o *AutoAcceptOption) Type() string {
|
|
|
|
return "auto-accept"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Policies returns a representation of this option for the api
|
2016-06-15 21:30:54 +00:00
|
|
|
func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy {
|
2016-06-14 02:56:23 +00:00
|
|
|
policies := []swarm.Policy{}
|
|
|
|
for _, p := range defaultPolicies {
|
|
|
|
if len(o.values) != 0 {
|
|
|
|
p.Autoaccept = o.values[string(p.Role)]
|
|
|
|
}
|
|
|
|
p.Secret = secret
|
|
|
|
policies = append(policies, p)
|
|
|
|
}
|
|
|
|
return policies
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewAutoAcceptOption returns a new auto-accept option
|
|
|
|
func NewAutoAcceptOption() AutoAcceptOption {
|
|
|
|
return AutoAcceptOption{values: make(map[string]bool)}
|
|
|
|
}
|