From 0b243acbfccddc150d4bb8321d41713a67e039fc Mon Sep 17 00:00:00 2001 From: allencloud Date: Mon, 21 Nov 2016 18:22:22 +0800 Subject: [PATCH] split function out of command description scope Signed-off-by: allencloud --- cli/command/swarm/join_token.go | 129 ++++++++++++++++++-------------- cli/command/swarm/unlock.go | 66 +++++++++------- cli/command/swarm/unlock_key.go | 100 +++++++++++++------------ 3 files changed, 163 insertions(+), 132 deletions(-) diff --git a/cli/command/swarm/join_token.go b/cli/command/swarm/join_token.go index 3a17a8020f..d800b769ba 100644 --- a/cli/command/swarm/join_token.go +++ b/cli/command/swarm/join_token.go @@ -12,92 +12,107 @@ import ( "golang.org/x/net/context" ) +type joinTokenOptions struct { + role string + rotate bool + quiet bool +} + func newJoinTokenCommand(dockerCli *command.DockerCli) *cobra.Command { - var rotate, quiet bool + opts := joinTokenOptions{} cmd := &cobra.Command{ Use: "join-token [OPTIONS] (worker|manager)", Short: "Manage join tokens", Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - worker := args[0] == "worker" - manager := args[0] == "manager" - - if !worker && !manager { - return errors.New("unknown role " + args[0]) - } - - client := dockerCli.Client() - ctx := context.Background() - - if rotate { - var flags swarm.UpdateFlags - - swarm, err := client.SwarmInspect(ctx) - if err != nil { - return err - } - - flags.RotateWorkerToken = worker - flags.RotateManagerToken = manager - - err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec, flags) - if err != nil { - return err - } - if !quiet { - fmt.Fprintf(dockerCli.Out(), "Successfully rotated %s join token.\n\n", args[0]) - } - } - - swarm, err := client.SwarmInspect(ctx) - if err != nil { - return err - } - - if quiet { - if worker { - fmt.Fprintln(dockerCli.Out(), swarm.JoinTokens.Worker) - } else { - fmt.Fprintln(dockerCli.Out(), swarm.JoinTokens.Manager) - } - } else { - info, err := client.Info(ctx) - if err != nil { - return err - } - return printJoinCommand(ctx, dockerCli, info.Swarm.NodeID, worker, manager) - } - return nil + opts.role = args[0] + return runJoinToken(dockerCli, opts) }, } flags := cmd.Flags() - flags.BoolVar(&rotate, flagRotate, false, "Rotate join token") - flags.BoolVarP(&quiet, flagQuiet, "q", false, "Only display token") + flags.BoolVar(&opts.rotate, flagRotate, false, "Rotate join token") + flags.BoolVarP(&opts.quiet, flagQuiet, "q", false, "Only display token") return cmd } -func printJoinCommand(ctx context.Context, dockerCli *command.DockerCli, nodeID string, worker bool, manager bool) error { - client := dockerCli.Client() +func runJoinToken(dockerCli *command.DockerCli, opts joinTokenOptions) error { + worker := opts.role == "worker" + manager := opts.role == "manager" - swarm, err := client.SwarmInspect(ctx) + if !worker && !manager { + return errors.New("unknown role " + opts.role) + } + + client := dockerCli.Client() + 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 + } + + info, err := client.Info(ctx) + if err != nil { + return err + } + + return printJoinCommand(ctx, dockerCli, info.Swarm.NodeID, worker, manager) +} + +func printJoinCommand(ctx context.Context, dockerCli *command.DockerCli, nodeID string, worker bool, manager bool) error { + client := dockerCli.Client() + node, _, err := client.NodeInspectWithRaw(ctx, nodeID) if err != nil { return err } + sw, err := client.SwarmInspect(ctx) + if err != nil { + return err + } + if node.ManagerStatus != nil { if worker { - 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", swarm.JoinTokens.Worker, node.ManagerStatus.Addr) + 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) } if manager { - 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", swarm.JoinTokens.Manager, node.ManagerStatus.Addr) + 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) } } diff --git a/cli/command/swarm/unlock.go b/cli/command/swarm/unlock.go index abb9e89fe7..f7d418760b 100644 --- a/cli/command/swarm/unlock.go +++ b/cli/command/swarm/unlock.go @@ -16,46 +16,54 @@ import ( "golang.org/x/net/context" ) +type unlockOptions struct{} + func newUnlockCommand(dockerCli *command.DockerCli) *cobra.Command { + opts := unlockOptions{} + cmd := &cobra.Command{ Use: "unlock", Short: "Unlock swarm", - Args: cli.ExactArgs(0), + Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client := dockerCli.Client() - ctx := context.Background() - - // First see if the node is actually part of a swarm, and if it's is actually locked first. - // If it's in any other state than locked, don't ask for the key. - info, err := client.Info(ctx) - if err != nil { - return err - } - - switch info.Swarm.LocalNodeState { - case swarm.LocalNodeStateInactive: - return errors.New("Error: This node is not part of a swarm") - case swarm.LocalNodeStateLocked: - break - default: - return errors.New("Error: swarm is not locked") - } - - key, err := readKey(dockerCli.In(), "Please enter unlock key: ") - if err != nil { - return err - } - req := swarm.UnlockRequest{ - UnlockKey: key, - } - - return client.SwarmUnlock(ctx, req) + return runUnlock(dockerCli, opts) }, } return cmd } +func runUnlock(dockerCli *command.DockerCli, opts unlockOptions) error { + client := dockerCli.Client() + ctx := context.Background() + + // First see if the node is actually part of a swarm, and if it's is actually locked first. + // If it's in any other state than locked, don't ask for the key. + info, err := client.Info(ctx) + if err != nil { + return err + } + + switch info.Swarm.LocalNodeState { + case swarm.LocalNodeStateInactive: + return errors.New("Error: This node is not part of a swarm") + case swarm.LocalNodeStateLocked: + break + default: + return errors.New("Error: swarm is not locked") + } + + key, err := readKey(dockerCli.In(), "Please enter unlock key: ") + if err != nil { + return err + } + req := swarm.UnlockRequest{ + UnlockKey: key, + } + + return client.SwarmUnlock(ctx, req) +} + func readKey(in *command.InStream, prompt string) (string, error) { if in.IsTerminal() { fmt.Print(prompt) diff --git a/cli/command/swarm/unlock_key.go b/cli/command/swarm/unlock_key.go index 96450f55b8..e571e6645f 100644 --- a/cli/command/swarm/unlock_key.go +++ b/cli/command/swarm/unlock_key.go @@ -12,68 +12,76 @@ import ( "golang.org/x/net/context" ) +type unlockKeyOptions struct { + rotate bool + quiet bool +} + func newUnlockKeyCommand(dockerCli *command.DockerCli) *cobra.Command { - var rotate, quiet bool + opts := unlockKeyOptions{} cmd := &cobra.Command{ Use: "unlock-key [OPTIONS]", Short: "Manage the unlock key", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client := dockerCli.Client() - ctx := context.Background() - - if rotate { - flags := swarm.UpdateFlags{RotateManagerUnlockKey: true} - - swarm, err := client.SwarmInspect(ctx) - if err != nil { - return err - } - - if !swarm.Spec.EncryptionConfig.AutoLockManagers { - return errors.New("cannot rotate because autolock is not turned on") - } - - err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec, flags) - if err != nil { - return err - } - if !quiet { - fmt.Fprintf(dockerCli.Out(), "Successfully rotated manager unlock key.\n\n") - } - } - - unlockKeyResp, err := client.SwarmGetUnlockKey(ctx) - if err != nil { - return errors.Wrap(err, "could not fetch unlock key") - } - - if unlockKeyResp.UnlockKey == "" { - return errors.New("no unlock key is set") - } - - if quiet { - fmt.Fprintln(dockerCli.Out(), unlockKeyResp.UnlockKey) - } else { - printUnlockCommand(ctx, dockerCli, unlockKeyResp.UnlockKey) - } - return nil + return runUnlockKey(dockerCli, opts) }, } flags := cmd.Flags() - flags.BoolVar(&rotate, flagRotate, false, "Rotate unlock key") - flags.BoolVarP(&quiet, flagQuiet, "q", false, "Only display token") + flags.BoolVar(&opts.rotate, flagRotate, false, "Rotate unlock key") + flags.BoolVarP(&opts.quiet, flagQuiet, "q", false, "Only display token") return cmd } -func printUnlockCommand(ctx context.Context, dockerCli *command.DockerCli, unlockKey string) { - if len(unlockKey) == 0 { - return +func runUnlockKey(dockerCli *command.DockerCli, opts unlockKeyOptions) error { + client := dockerCli.Client() + ctx := context.Background() + + if opts.rotate { + flags := swarm.UpdateFlags{RotateManagerUnlockKey: true} + + sw, err := client.SwarmInspect(ctx) + if err != nil { + return err + } + + if !sw.Spec.EncryptionConfig.AutoLockManagers { + return errors.New("cannot rotate because autolock is not turned on") + } + + if err := client.SwarmUpdate(ctx, sw.Version, sw.Spec, flags); err != nil { + return err + } + + if !opts.quiet { + fmt.Fprintf(dockerCli.Out(), "Successfully rotated manager unlock key.\n\n") + } } - fmt.Fprintf(dockerCli.Out(), "To unlock a swarm manager after it restarts, run the `docker swarm unlock`\ncommand and provide the following key:\n\n %s\n\nPlease remember to store this key in a password manager, since without it you\nwill not be able to restart the manager.\n", unlockKey) + unlockKeyResp, err := client.SwarmGetUnlockKey(ctx) + if err != nil { + return errors.Wrap(err, "could not fetch unlock key") + } + + if unlockKeyResp.UnlockKey == "" { + return errors.New("no unlock key is set") + } + + if opts.quiet { + fmt.Fprintln(dockerCli.Out(), unlockKeyResp.UnlockKey) + return nil + } + + printUnlockCommand(ctx, dockerCli, unlockKeyResp.UnlockKey) + return nil +} + +func printUnlockCommand(ctx context.Context, dockerCli *command.DockerCli, unlockKey string) { + if len(unlockKey) > 0 { + fmt.Fprintf(dockerCli.Out(), "To unlock a swarm manager after it restarts, run the `docker swarm unlock`\ncommand and provide the following key:\n\n %s\n\nPlease remember to store this key in a password manager, since without it you\nwill not be able to restart the manager.\n", unlockKey) + } return }