Browse Source

Merge pull request #29218 from yongtang/28884-secret-inspect-follow-up

Move secret name or ID prefix resolving from client to daemon
Alexander Morozov 8 years ago
parent
commit
3c32e1775a

+ 1 - 5
cli/command/secret/inspect.go

@@ -33,13 +33,9 @@ func runSecretInspect(dockerCli *command.DockerCli, opts inspectOptions) error {
 	client := dockerCli.Client()
 	ctx := context.Background()
 
-	ids, err := getCliRequestedSecretIDs(ctx, client, opts.names)
-	if err != nil {
-		return err
-	}
 	getRef := func(id string) (interface{}, []byte, error) {
 		return client.SecretInspectWithRaw(ctx, id)
 	}
 
-	return inspect.Inspect(dockerCli.Out(), ids, opts.format, getRef)
+	return inspect.Inspect(dockerCli.Out(), opts.names, opts.format, getRef)
 }

+ 3 - 8
cli/command/secret/remove.go

@@ -33,20 +33,15 @@ func runSecretRemove(dockerCli *command.DockerCli, opts removeOptions) error {
 	client := dockerCli.Client()
 	ctx := context.Background()
 
-	ids, err := getCliRequestedSecretIDs(ctx, client, opts.names)
-	if err != nil {
-		return err
-	}
-
 	var errs []string
 
-	for _, id := range ids {
-		if err := client.SecretRemove(ctx, id); err != nil {
+	for _, name := range opts.names {
+		if err := client.SecretRemove(ctx, name); err != nil {
 			errs = append(errs, err.Error())
 			continue
 		}
 
-		fmt.Fprintln(dockerCli.Out(), id)
+		fmt.Fprintln(dockerCli.Out(), name)
 	}
 
 	if len(errs) > 0 {

+ 60 - 7
daemon/cluster/secrets.go

@@ -1,14 +1,63 @@
 package cluster
 
 import (
+	"fmt"
+	"strings"
+
 	apitypes "github.com/docker/docker/api/types"
 	types "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/daemon/cluster/convert"
 	swarmapi "github.com/docker/swarmkit/api"
+	"golang.org/x/net/context"
 )
 
+func getSecretByNameOrIDPrefix(ctx context.Context, state *nodeState, nameOrIDPrefix string) (*swarmapi.Secret, error) {
+	// attempt to lookup secret by full ID
+	if r, err := state.controlClient.GetSecret(ctx, &swarmapi.GetSecretRequest{
+		SecretID: nameOrIDPrefix,
+	}); err == nil {
+		return r.Secret, nil
+	}
+
+	// attempt to lookup secret by full name and partial ID
+	// Note here ListSecretRequest_Filters operate with `or`
+	r, err := state.controlClient.ListSecrets(ctx, &swarmapi.ListSecretsRequest{
+		Filters: &swarmapi.ListSecretsRequest_Filters{
+			Names:      []string{nameOrIDPrefix},
+			IDPrefixes: []string{nameOrIDPrefix},
+		},
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	// attempt to lookup secret by full name
+	for _, s := range r.Secrets {
+		if s.Spec.Annotations.Name == nameOrIDPrefix {
+			return s, nil
+		}
+	}
+	// attempt to lookup secret by partial ID (prefix)
+	// return error if more than one matches found (ambiguous)
+	n := 0
+	var found *swarmapi.Secret
+	for _, s := range r.Secrets {
+		if strings.HasPrefix(s.ID, nameOrIDPrefix) {
+			found = s
+			n++
+		}
+	}
+	if n > 1 {
+		return nil, fmt.Errorf("secret %s is ambiguous (%d matches found)", nameOrIDPrefix, n)
+	}
+	if found == nil {
+		return nil, fmt.Errorf("no such secret: %s", nameOrIDPrefix)
+	}
+	return found, nil
+}
+
 // GetSecret returns a secret from a managed swarm cluster
-func (c *Cluster) GetSecret(id string) (types.Secret, error) {
+func (c *Cluster) GetSecret(nameOrIDPrefix string) (types.Secret, error) {
 	c.mu.RLock()
 	defer c.mu.RUnlock()
 
@@ -20,12 +69,11 @@ func (c *Cluster) GetSecret(id string) (types.Secret, error) {
 	ctx, cancel := c.getRequestContext()
 	defer cancel()
 
-	r, err := state.controlClient.GetSecret(ctx, &swarmapi.GetSecretRequest{SecretID: id})
+	secret, err := getSecretByNameOrIDPrefix(ctx, &state, nameOrIDPrefix)
 	if err != nil {
 		return types.Secret{}, err
 	}
-
-	return convert.SecretFromGRPC(r.Secret), nil
+	return convert.SecretFromGRPC(secret), nil
 }
 
 // GetSecrets returns all secrets of a managed swarm cluster.
@@ -85,7 +133,7 @@ func (c *Cluster) CreateSecret(s types.SecretSpec) (string, error) {
 }
 
 // RemoveSecret removes a secret from a managed swarm cluster.
-func (c *Cluster) RemoveSecret(id string) error {
+func (c *Cluster) RemoveSecret(nameOrIDPrefix string) error {
 	c.mu.RLock()
 	defer c.mu.RUnlock()
 
@@ -97,11 +145,16 @@ func (c *Cluster) RemoveSecret(id string) error {
 	ctx, cancel := c.getRequestContext()
 	defer cancel()
 
+	secret, err := getSecretByNameOrIDPrefix(ctx, &state, nameOrIDPrefix)
+	if err != nil {
+		return err
+	}
+
 	req := &swarmapi.RemoveSecretRequest{
-		SecretID: id,
+		SecretID: secret.ID,
 	}
 
-	_, err := state.controlClient.RemoveSecret(ctx, req)
+	_, err = state.controlClient.RemoveSecret(ctx, req)
 	return err
 }
 

+ 1 - 1
integration-cli/docker_cli_secret_create_test.go

@@ -101,7 +101,7 @@ func (s *DockerSwarmSuite) TestSecretCreateResolve(c *check.C) {
 
 	// Remove based on ID prefix of the fake one should succeed
 	out, err = d.Cmd("secret", "rm", fake[:5])
-	c.Assert(out, checker.Contains, fake)
+	c.Assert(out, checker.Contains, fake[:5])
 	out, err = d.Cmd("secret", "ls")
 	c.Assert(err, checker.IsNil)
 	c.Assert(out, checker.Not(checker.Contains), name)