Преглед изворни кода

Remove secrets as part of stack remove.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Daniel Nephin пре 8 година
родитељ
комит
f0a5531c46

+ 10 - 0
cli/command/stack/common.go

@@ -48,3 +48,13 @@ func getStackNetworks(
 		ctx,
 		types.NetworkListOptions{Filters: getStackFilter(namespace)})
 }
+
+func getStackSecrets(
+	ctx context.Context,
+	apiclient client.APIClient,
+	namespace string,
+) ([]swarm.Secret, error) {
+	return apiclient.SecretList(
+		ctx,
+		types.SecretListOptions{Filters: getStackFilter(namespace)})
+}

+ 57 - 18
cli/command/stack/remove.go

@@ -3,11 +3,12 @@ package stack
 import (
 	"fmt"
 
-	"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"
 	"github.com/spf13/cobra"
+	"golang.org/x/net/context"
 )
 
 type removeOptions struct {
@@ -33,41 +34,79 @@ func newRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
 func runRemove(dockerCli *command.DockerCli, opts removeOptions) error {
 	namespace := opts.namespace
 	client := dockerCli.Client()
-	stderr := dockerCli.Err()
 	ctx := context.Background()
-	hasError := false
 
 	services, err := getServices(ctx, client, namespace)
 	if err != nil {
 		return err
 	}
-	for _, service := range services {
-		fmt.Fprintf(stderr, "Removing service %s\n", service.Spec.Name)
-		if err := client.ServiceRemove(ctx, service.ID); err != nil {
-			hasError = true
-			fmt.Fprintf(stderr, "Failed to remove service %s: %s", service.ID, err)
-		}
-	}
 
 	networks, err := getStackNetworks(ctx, client, namespace)
 	if err != nil {
 		return err
 	}
-	for _, network := range networks {
-		fmt.Fprintf(stderr, "Removing network %s\n", network.Name)
-		if err := client.NetworkRemove(ctx, network.ID); err != nil {
-			hasError = true
-			fmt.Fprintf(stderr, "Failed to remove network %s: %s", network.ID, err)
-		}
+
+	secrets, err := getStackSecrets(ctx, client, namespace)
+	if err != nil {
+		return err
 	}
 
-	if len(services) == 0 && len(networks) == 0 {
+	if len(services)+len(networks)+len(secrets) == 0 {
 		fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace)
 		return nil
 	}
 
+	hasError := removeServices(ctx, dockerCli, services)
+	hasError = removeSecrets(ctx, dockerCli, secrets) || hasError
+	hasError = removeNetworks(ctx, dockerCli, networks) || hasError
+
 	if hasError {
 		return fmt.Errorf("Failed to remove some resources")
 	}
 	return nil
 }
+
+func removeServices(
+	ctx context.Context,
+	dockerCli *command.DockerCli,
+	services []swarm.Service,
+) bool {
+	var err error
+	for _, service := range services {
+		fmt.Fprintf(dockerCli.Err(), "Removing service %s\n", service.Spec.Name)
+		if err = dockerCli.Client().ServiceRemove(ctx, service.ID); err != nil {
+			fmt.Fprintf(dockerCli.Err(), "Failed to remove service %s: %s", service.ID, err)
+		}
+	}
+	return err != nil
+}
+
+func removeNetworks(
+	ctx context.Context,
+	dockerCli *command.DockerCli,
+	networks []types.NetworkResource,
+) bool {
+	var err error
+	for _, network := range networks {
+		fmt.Fprintf(dockerCli.Err(), "Removing network %s\n", network.Name)
+		if err = dockerCli.Client().NetworkRemove(ctx, network.ID); err != nil {
+			fmt.Fprintf(dockerCli.Err(), "Failed to remove network %s: %s", network.ID, err)
+		}
+	}
+	return err != nil
+}
+
+func removeSecrets(
+	ctx context.Context,
+	dockerCli *command.DockerCli,
+	secrets []swarm.Secret,
+) bool {
+	var err error
+	for _, secret := range secrets {
+		fmt.Fprintf(dockerCli.Err(), "Removing secret %s\n", secret.Spec.Name)
+		if err = dockerCli.Client().SecretRemove(ctx, secret.ID); err != nil {
+			fmt.Fprintf(dockerCli.Err(), "Failed to remove secret %s: %s", secret.ID, err)
+		}
+	}
+	return err != nil
+}

+ 27 - 3
integration-cli/docker_cli_stack_test.go

@@ -5,13 +5,14 @@ import (
 	"io/ioutil"
 	"os"
 	"sort"
+	"strings"
 
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
 )
 
-func (s *DockerSwarmSuite) TestStackRemove(c *check.C) {
+func (s *DockerSwarmSuite) TestStackRemoveUnknown(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
 	stackArgs := append([]string{"stack", "remove", "UNKNOWN_STACK"})
@@ -21,7 +22,7 @@ func (s *DockerSwarmSuite) TestStackRemove(c *check.C) {
 	c.Assert(out, check.Equals, "Nothing found in stack: UNKNOWN_STACK\n")
 }
 
-func (s *DockerSwarmSuite) TestStackTasks(c *check.C) {
+func (s *DockerSwarmSuite) TestStackPSUnknown(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
 	stackArgs := append([]string{"stack", "ps", "UNKNOWN_STACK"})
@@ -31,7 +32,7 @@ func (s *DockerSwarmSuite) TestStackTasks(c *check.C) {
 	c.Assert(out, check.Equals, "Nothing found in stack: UNKNOWN_STACK\n")
 }
 
-func (s *DockerSwarmSuite) TestStackServices(c *check.C) {
+func (s *DockerSwarmSuite) TestStackServicesUnknown(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
 	stackArgs := append([]string{"stack", "services", "UNKNOWN_STACK"})
@@ -99,6 +100,29 @@ func (s *DockerSwarmSuite) TestStackDeployWithSecretsTwice(c *check.C) {
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 }
 
+func (s *DockerSwarmSuite) TestStackRemove(c *check.C) {
+	d := s.AddDaemon(c, true, true)
+
+	stackName := "testdeploy"
+	stackArgs := []string{
+		"stack", "deploy",
+		"--compose-file", "fixtures/deploy/remove.yaml",
+		stackName,
+	}
+	out, err := d.Cmd(stackArgs...)
+	c.Assert(err, checker.IsNil, check.Commentf(out))
+
+	out, err = d.Cmd("stack", "ps", stackName)
+	c.Assert(err, checker.IsNil)
+	c.Assert(strings.Split(strings.TrimSpace(out), "\n"), checker.HasLen, 2)
+
+	out, err = d.Cmd("stack", "rm", stackName)
+	c.Assert(err, checker.IsNil, check.Commentf(out))
+	c.Assert(out, checker.Contains, "Removing service testdeploy_web")
+	c.Assert(out, checker.Contains, "Removing network testdeploy_default")
+	c.Assert(out, checker.Contains, "Removing secret testdeploy_special")
+}
+
 type sortSecrets []swarm.SecretReference
 
 func (s sortSecrets) Len() int           { return len(s) }

+ 11 - 0
integration-cli/fixtures/deploy/remove.yaml

@@ -0,0 +1,11 @@
+
+version: "3.1"
+services:
+  web:
+    image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0
+    command: top
+    secrets:
+      - special
+secrets:
+  special:
+    file: fixtures/secrets/default