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

Move secret name or ID prefix resolving from client to daemon
This commit is contained in:
Alexander Morozov 2017-01-27 13:31:04 -08:00 committed by GitHub
commit 3c32e1775a
4 changed files with 66 additions and 22 deletions

View file

@ -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)
}

View file

@ -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 {

View file

@ -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()
req := &swarmapi.RemoveSecretRequest{
SecretID: id,
secret, err := getSecretByNameOrIDPrefix(ctx, &state, nameOrIDPrefix)
if err != nil {
return err
}
_, err := state.controlClient.RemoveSecret(ctx, req)
req := &swarmapi.RemoveSecretRequest{
SecretID: secret.ID,
}
_, err = state.controlClient.RemoveSecret(ctx, req)
return err
}

View file

@ -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)