diff --git a/command/secret/utils.go b/command/secret/utils.go index 42493896ca..11d31ffd16 100644 --- a/command/secret/utils.go +++ b/command/secret/utils.go @@ -11,7 +11,8 @@ import ( "golang.org/x/net/context" ) -func getSecretsByNameOrIDPrefixes(ctx context.Context, client client.APIClient, terms []string) ([]swarm.Secret, error) { +// GetSecretsByNameOrIDPrefixes returns secrets given a list of ids or names +func GetSecretsByNameOrIDPrefixes(ctx context.Context, client client.APIClient, terms []string) ([]swarm.Secret, error) { args := filters.NewArgs() for _, n := range terms { args.Add("names", n) @@ -24,7 +25,7 @@ func getSecretsByNameOrIDPrefixes(ctx context.Context, client client.APIClient, } func getCliRequestedSecretIDs(ctx context.Context, client client.APIClient, terms []string) ([]string, error) { - secrets, err := getSecretsByNameOrIDPrefixes(ctx, client, terms) + secrets, err := GetSecretsByNameOrIDPrefixes(ctx, client, terms) if err != nil { return nil, err } diff --git a/command/stack/deploy.go b/command/stack/deploy.go index 6856624128..203ae6d39c 100644 --- a/command/stack/deploy.go +++ b/command/stack/deploy.go @@ -1,24 +1,24 @@ package stack import ( - "errors" "fmt" "io/ioutil" "os" "sort" "strings" - "github.com/spf13/cobra" - "golang.org/x/net/context" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" + secretcli "github.com/docker/docker/cli/command/secret" "github.com/docker/docker/cli/compose/convert" "github.com/docker/docker/cli/compose/loader" composetypes "github.com/docker/docker/cli/compose/types" dockerclient "github.com/docker/docker/client" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "golang.org/x/net/context" ) const ( @@ -228,9 +228,22 @@ func createSecrets( ) error { client := dockerCli.Client() - for _, secret := range secrets { - fmt.Fprintf(dockerCli.Out(), "Creating secret %s\n", secret.Name) - _, err := client.SecretCreate(ctx, secret) + for _, secretSpec := range secrets { + // TODO: fix this after https://github.com/docker/docker/pull/29218 + secrets, err := secretcli.GetSecretsByNameOrIDPrefixes(ctx, client, []string{secretSpec.Name}) + switch { + case err != nil: + return err + case len(secrets) > 1: + return errors.Errorf("ambiguous secret name: %s", secretSpec.Name) + case len(secrets) == 0: + fmt.Fprintf(dockerCli.Out(), "Creating secret %s\n", secretSpec.Name) + _, err = client.SecretCreate(ctx, secretSpec) + default: + secret := secrets[0] + // Update secret to ensure that the local data hasn't changed + err = client.SecretUpdate(ctx, secret.ID, secret.Meta.Version, secretSpec) + } if err != nil { return err } diff --git a/compose/convert/compose_test.go b/compose/convert/compose_test.go index d88ac7f7c4..18c7aac938 100644 --- a/compose/convert/compose_test.go +++ b/compose/convert/compose_test.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/types/network" composetypes "github.com/docker/docker/cli/compose/types" "github.com/docker/docker/pkg/testutil/assert" + "github.com/docker/docker/pkg/testutil/tempfile" ) func TestNamespaceScope(t *testing.T) { @@ -88,3 +89,34 @@ func TestNetworks(t *testing.T) { assert.DeepEqual(t, networks, expected) assert.DeepEqual(t, externals, []string{"special"}) } + +func TestSecrets(t *testing.T) { + namespace := Namespace{name: "foo"} + + secretText := "this is the first secret" + secretFile := tempfile.NewTempFile(t, "convert-secrets", secretText) + defer secretFile.Remove() + + source := map[string]composetypes.SecretConfig{ + "one": { + File: secretFile.Name(), + Labels: map[string]string{"monster": "mash"}, + }, + "ext": { + External: composetypes.External{ + External: true, + }, + }, + } + + specs, err := Secrets(namespace, source) + assert.NilError(t, err) + assert.Equal(t, len(specs), 1) + secret := specs[0] + assert.Equal(t, secret.Name, "foo_one") + assert.DeepEqual(t, secret.Labels, map[string]string{ + "monster": "mash", + LabelNamespace: "foo", + }) + assert.DeepEqual(t, secret.Data, []byte(secretText)) +}