2016-07-20 14:15:08 -04:00
package swarm
import (
"fmt"
2016-09-06 14:18:12 -04:00
"github.com/docker/docker/api/types/swarm"
2016-07-20 14:15:08 -04:00
"github.com/docker/docker/cli"
2016-09-08 13:11:39 -04:00
"github.com/docker/docker/cli/command"
2017-03-27 21:21:59 -04:00
"github.com/pkg/errors"
"github.com/spf13/cobra"
2016-07-20 14:15:08 -04:00
"golang.org/x/net/context"
)
2016-11-21 05:22:22 -05:00
type joinTokenOptions struct {
role string
rotate bool
quiet bool
}
2016-12-25 16:23:35 -05:00
func newJoinTokenCommand ( dockerCli command . Cli ) * cobra . Command {
2016-11-21 05:22:22 -05:00
opts := joinTokenOptions { }
2016-07-20 14:15:08 -04:00
cmd := & cobra . Command {
2016-08-17 03:45:04 -04:00
Use : "join-token [OPTIONS] (worker|manager)" ,
2016-07-20 14:15:08 -04:00
Short : "Manage join tokens" ,
Args : cli . ExactArgs ( 1 ) ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2016-11-21 05:22:22 -05:00
opts . role = args [ 0 ]
return runJoinToken ( dockerCli , opts )
2016-07-20 14:15:08 -04:00
} ,
}
flags := cmd . Flags ( )
2016-11-21 05:22:22 -05:00
flags . BoolVar ( & opts . rotate , flagRotate , false , "Rotate join token" )
flags . BoolVarP ( & opts . quiet , flagQuiet , "q" , false , "Only display token" )
2016-07-20 14:15:08 -04:00
return cmd
}
2016-12-25 16:23:35 -05:00
func runJoinToken ( dockerCli command . Cli , opts joinTokenOptions ) error {
2016-11-21 05:22:22 -05:00
worker := opts . role == "worker"
manager := opts . role == "manager"
if ! worker && ! manager {
return errors . New ( "unknown role " + opts . role )
}
2016-07-20 14:15:08 -04:00
client := dockerCli . Client ( )
2016-11-21 05:22:22 -05:00
ctx := context . Background ( )
if opts . rotate {
flags := swarm . UpdateFlags {
RotateWorkerToken : worker ,
RotateManagerToken : manager ,
}
sw , err := client . SwarmInspect ( ctx )
if err != nil {
return err
}
if err := client . SwarmUpdate ( ctx , sw . Version , sw . Spec , flags ) ; err != nil {
return err
}
if ! opts . quiet {
fmt . Fprintf ( dockerCli . Out ( ) , "Successfully rotated %s join token.\n\n" , opts . role )
}
}
// second SwarmInspect in this function,
// this is necessary since SwarmUpdate after first changes the join tokens
sw , err := client . SwarmInspect ( ctx )
if err != nil {
return err
}
if opts . quiet && worker {
fmt . Fprintln ( dockerCli . Out ( ) , sw . JoinTokens . Worker )
return nil
}
if opts . quiet && manager {
fmt . Fprintln ( dockerCli . Out ( ) , sw . JoinTokens . Manager )
return nil
}
2016-07-20 14:15:08 -04:00
2016-11-21 05:22:22 -05:00
info , err := client . Info ( ctx )
2016-07-20 14:15:08 -04:00
if err != nil {
return err
}
2016-11-21 05:22:22 -05:00
return printJoinCommand ( ctx , dockerCli , info . Swarm . NodeID , worker , manager )
}
2016-12-25 16:23:35 -05:00
func printJoinCommand ( ctx context . Context , dockerCli command . Cli , nodeID string , worker bool , manager bool ) error {
2016-11-21 05:22:22 -05:00
client := dockerCli . Client ( )
2016-07-20 14:15:08 -04:00
node , _ , err := client . NodeInspectWithRaw ( ctx , nodeID )
if err != nil {
return err
}
2016-11-21 05:22:22 -05:00
sw , err := client . SwarmInspect ( ctx )
if err != nil {
return err
}
2016-07-20 14:15:08 -04:00
if node . ManagerStatus != nil {
if worker {
2016-11-21 05:22:22 -05:00
fmt . Fprintf ( dockerCli . Out ( ) , "To add a worker to this swarm, run the following command:\n\n docker swarm join \\\n --token %s \\\n %s\n\n" , sw . JoinTokens . Worker , node . ManagerStatus . Addr )
2016-07-20 14:15:08 -04:00
}
if manager {
2016-11-21 05:22:22 -05:00
fmt . Fprintf ( dockerCli . Out ( ) , "To add a manager to this swarm, run the following command:\n\n docker swarm join \\\n --token %s \\\n %s\n\n" , sw . JoinTokens . Manager , node . ManagerStatus . Addr )
2016-07-20 14:15:08 -04:00
}
}
return nil
}