github.com/itscaro/cli@v0.0.0-20190705081621-c9db0fe93829/cli/command/swarm/join.go (about) 1 package swarm 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/docker/cli/cli" 9 "github.com/docker/cli/cli/command" 10 "github.com/docker/docker/api/types/swarm" 11 "github.com/pkg/errors" 12 "github.com/spf13/cobra" 13 "github.com/spf13/pflag" 14 ) 15 16 type joinOptions struct { 17 remote string 18 listenAddr NodeAddrOption 19 // Not a NodeAddrOption because it has no default port. 20 advertiseAddr string 21 dataPathAddr string 22 token string 23 availability string 24 } 25 26 func newJoinCommand(dockerCli command.Cli) *cobra.Command { 27 opts := joinOptions{ 28 listenAddr: NewListenAddrOption(), 29 } 30 31 cmd := &cobra.Command{ 32 Use: "join [OPTIONS] HOST:PORT", 33 Short: "Join a swarm as a node and/or manager", 34 Args: cli.ExactArgs(1), 35 RunE: func(cmd *cobra.Command, args []string) error { 36 opts.remote = args[0] 37 return runJoin(dockerCli, cmd.Flags(), opts) 38 }, 39 } 40 41 flags := cmd.Flags() 42 flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: <ip|interface>[:port])") 43 flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])") 44 flags.StringVar(&opts.dataPathAddr, flagDataPathAddr, "", "Address or interface to use for data path traffic (format: <ip|interface>)") 45 flags.SetAnnotation(flagDataPathAddr, "version", []string{"1.31"}) 46 flags.StringVar(&opts.token, flagToken, "", "Token for entry into the swarm") 47 flags.StringVar(&opts.availability, flagAvailability, "active", `Availability of the node ("active"|"pause"|"drain")`) 48 return cmd 49 } 50 51 func runJoin(dockerCli command.Cli, flags *pflag.FlagSet, opts joinOptions) error { 52 client := dockerCli.Client() 53 ctx := context.Background() 54 55 req := swarm.JoinRequest{ 56 JoinToken: opts.token, 57 ListenAddr: opts.listenAddr.String(), 58 AdvertiseAddr: opts.advertiseAddr, 59 DataPathAddr: opts.dataPathAddr, 60 RemoteAddrs: []string{opts.remote}, 61 } 62 if flags.Changed(flagAvailability) { 63 availability := swarm.NodeAvailability(strings.ToLower(opts.availability)) 64 switch availability { 65 case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain: 66 req.Availability = availability 67 default: 68 return errors.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability) 69 } 70 } 71 72 err := client.SwarmJoin(ctx, req) 73 if err != nil { 74 return err 75 } 76 77 info, err := client.Info(ctx) 78 if err != nil { 79 return err 80 } 81 82 if info.Swarm.ControlAvailable { 83 fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a manager.") 84 } else { 85 fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a worker.") 86 } 87 return nil 88 }