Files
docker-cli/cli/command/swarm/join_token.go
Sebastiaan van Stijn 0adaf6be3b verify that DisableFlagsInUseLine is set for all commands
This replaces the visitAll recursive function with a test that verifies that
the option is set for all commands and subcommands, so that it doesn't have
to be modified at runtime.

We currently still have to loop over all functions for the setValidateArgs
call, but that can be looked at separately.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 09:39:46 +02:00

123 lines
2.9 KiB
Go

package swarm
import (
"context"
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/moby/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type joinTokenOptions struct {
role string
rotate bool
quiet bool
}
func newJoinTokenCommand(dockerCLI command.Cli) *cobra.Command {
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 {
opts.role = args[0]
return runJoinToken(cmd.Context(), dockerCLI, opts)
},
Annotations: map[string]string{
"version": "1.24",
"swarm": "manager",
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.BoolVar(&opts.rotate, flagRotate, false, "Rotate join token")
flags.BoolVarP(&opts.quiet, flagQuiet, "q", false, "Only display token")
return cmd
}
func runJoinToken(ctx context.Context, dockerCLI command.Cli, opts joinTokenOptions) error {
worker := opts.role == "worker"
manager := opts.role == "manager"
if !worker && !manager {
return errors.New("unknown role " + opts.role)
}
apiClient := dockerCLI.Client()
if opts.rotate {
sw, err := apiClient.SwarmInspect(ctx)
if err != nil {
return err
}
err = apiClient.SwarmUpdate(ctx, sw.Version, sw.Spec, client.SwarmUpdateFlags{
RotateWorkerToken: worker,
RotateManagerToken: manager,
})
if 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 := apiClient.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 := apiClient.Info(ctx)
if err != nil {
return err
}
return printJoinCommand(ctx, dockerCLI, info.Swarm.NodeID, worker, manager)
}
func printJoinCommand(ctx context.Context, dockerCLI command.Cli, nodeID string, worker bool, manager bool) error {
apiClient := dockerCLI.Client()
node, _, err := apiClient.NodeInspectWithRaw(ctx, nodeID)
if err != nil {
return err
}
sw, err := apiClient.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 --token %s %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 --token %s %s\n\n", sw.JoinTokens.Manager, node.ManagerStatus.Addr)
}
}
return nil
}