1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/api/client/node/update.go
Aaron Lehmann 2cc5bd33ee Replace secrets with join tokens
Implement the proposal from
https://github.com/docker/docker/issues/24430#issuecomment-233100121

Removes acceptance policy and secret in favor of an automatically
generated join token that combines the secret, CA hash, and
manager/worker role into a single opaque string.

Adds a docker swarm join-token subcommand to inspect and rotate the
tokens.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-07-21 15:23:03 -07:00

113 lines
3.1 KiB
Go

package node
import (
"fmt"
"github.com/docker/docker/api/client"
"github.com/docker/docker/cli"
"github.com/docker/docker/opts"
runconfigopts "github.com/docker/docker/runconfig/opts"
"github.com/docker/engine-api/types/swarm"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/net/context"
)
func newUpdateCommand(dockerCli *client.DockerCli) *cobra.Command {
nodeOpts := newNodeOptions()
cmd := &cobra.Command{
Use: "update [OPTIONS] NODE",
Short: "Update a node",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runUpdate(dockerCli, cmd.Flags(), args[0])
},
}
flags := cmd.Flags()
flags.StringVar(&nodeOpts.role, flagRole, "", "Role of the node (worker/manager)")
flags.StringVar(&nodeOpts.availability, flagAvailability, "", "Availability of the node (active/pause/drain)")
flags.Var(&nodeOpts.annotations.labels, flagLabelAdd, "Add or update a node label (key=value)")
labelKeys := opts.NewListOpts(nil)
flags.Var(&labelKeys, flagLabelRemove, "Remove a node label if exists")
return cmd
}
func runUpdate(dockerCli *client.DockerCli, flags *pflag.FlagSet, nodeID string) error {
success := func(_ string) {
fmt.Fprintln(dockerCli.Out(), nodeID)
}
return updateNodes(dockerCli, []string{nodeID}, mergeNodeUpdate(flags), success)
}
func updateNodes(dockerCli *client.DockerCli, nodes []string, mergeNode func(node *swarm.Node) error, success func(nodeID string)) error {
client := dockerCli.Client()
ctx := context.Background()
for _, nodeID := range nodes {
node, _, err := client.NodeInspectWithRaw(ctx, nodeID)
if err != nil {
return err
}
err = mergeNode(&node)
if err != nil {
return err
}
err = client.NodeUpdate(ctx, node.ID, node.Version, node.Spec)
if err != nil {
return err
}
success(nodeID)
}
return nil
}
func mergeNodeUpdate(flags *pflag.FlagSet) func(*swarm.Node) error {
return func(node *swarm.Node) error {
spec := &node.Spec
if flags.Changed(flagRole) {
str, err := flags.GetString(flagRole)
if err != nil {
return err
}
spec.Role = swarm.NodeRole(str)
}
if flags.Changed(flagAvailability) {
str, err := flags.GetString(flagAvailability)
if err != nil {
return err
}
spec.Availability = swarm.NodeAvailability(str)
}
if spec.Annotations.Labels == nil {
spec.Annotations.Labels = make(map[string]string)
}
if flags.Changed(flagLabelAdd) {
labels := flags.Lookup(flagLabelAdd).Value.(*opts.ListOpts).GetAll()
for k, v := range runconfigopts.ConvertKVStringsToMap(labels) {
spec.Annotations.Labels[k] = v
}
}
if flags.Changed(flagLabelRemove) {
keys := flags.Lookup(flagLabelRemove).Value.(*opts.ListOpts).GetAll()
for _, k := range keys {
// if a key doesn't exist, fail the command explicitly
if _, exists := spec.Annotations.Labels[k]; !exists {
return fmt.Errorf("key %s doesn't exist in node's labels", k)
}
delete(spec.Annotations.Labels, k)
}
}
return nil
}
}
const (
flagRole = "role"
flagAvailability = "availability"
flagLabelAdd = "label-add"
flagLabelRemove = "label-rm"
)