From fe46c62362b6e070ffe029c144dec47f80742a8d Mon Sep 17 00:00:00 2001 From: Josh Hawn Date: Tue, 22 Nov 2016 11:03:23 -0800 Subject: [PATCH 1/2] Add SecretUpdate method to client closes #28678 Docker-DCO-1.1-Signed-off-by: Josh Hawn (github: jlhawn) Update cli/command/service/update_test.go Fixes test build error: secretAPIClientMock does not implement "github.com/docker/docker/client".SecretAPIClient (missing SecretUpdate method) Docker-DCO-1.1-Signed-off-by: Josh Hawn (github: jlhawn) Upstream-commit: 77b8465d7e68ca102d7aae839c7b3fe0ecd28398 Component: engine --- .../engine/cli/command/service/update_test.go | 3 ++ components/engine/client/interface.go | 1 + components/engine/client/secret_update.go | 19 +++++++ .../engine/client/secret_update_test.go | 49 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 components/engine/client/secret_update.go create mode 100644 components/engine/client/secret_update_test.go diff --git a/components/engine/cli/command/service/update_test.go b/components/engine/cli/command/service/update_test.go index a6df6b985e..bb931929c0 100644 --- a/components/engine/cli/command/service/update_test.go +++ b/components/engine/cli/command/service/update_test.go @@ -401,6 +401,9 @@ func (s secretAPIClientMock) SecretRemove(ctx context.Context, id string) error func (s secretAPIClientMock) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) { return swarm.Secret{}, []byte{}, nil } +func (s secretAPIClientMock) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error { + return nil +} // TestUpdateSecretUpdateInPlace tests the ability to update the "target" of an secret with "docker service update" // by combining "--secret-rm" and "--secret-add" for the same secret. diff --git a/components/engine/client/interface.go b/components/engine/client/interface.go index 00b9adea32..924b22bc04 100644 --- a/components/engine/client/interface.go +++ b/components/engine/client/interface.go @@ -166,4 +166,5 @@ type SecretAPIClient interface { SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) SecretRemove(ctx context.Context, id string) error SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) + SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error } diff --git a/components/engine/client/secret_update.go b/components/engine/client/secret_update.go new file mode 100644 index 0000000000..b94e24aab0 --- /dev/null +++ b/components/engine/client/secret_update.go @@ -0,0 +1,19 @@ +package client + +import ( + "net/url" + "strconv" + + "github.com/docker/docker/api/types/swarm" + "golang.org/x/net/context" +) + +// SecretUpdate updates a Secret. Currently, the only part of a secret spec +// which can be updated is Labels. +func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error { + query := url.Values{} + query.Set("version", strconv.FormatUint(version.Index, 10)) + resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil) + ensureReaderClosed(resp) + return err +} diff --git a/components/engine/client/secret_update_test.go b/components/engine/client/secret_update_test.go new file mode 100644 index 0000000000..c620985bd5 --- /dev/null +++ b/components/engine/client/secret_update_test.go @@ -0,0 +1,49 @@ +package client + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "strings" + "testing" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/types/swarm" +) + +func TestSecretUpdateError(t *testing.T) { + client := &Client{ + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), + } + + err := client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{}) + if err == nil || err.Error() != "Error response from daemon: Server error" { + t.Fatalf("expected a Server Error, got %v", err) + } +} + +func TestSecretUpdate(t *testing.T) { + expectedURL := "/secrets/secret_id/update" + + client := &Client{ + client: newMockClient(func(req *http.Request) (*http.Response, error) { + if !strings.HasPrefix(req.URL.Path, expectedURL) { + return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) + } + if req.Method != "POST" { + return nil, fmt.Errorf("expected POST method, got %s", req.Method) + } + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } + + err := client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{}) + if err != nil { + t.Fatal(err) + } +} From 29e36c572d57138f0925fe0b8238067f5df63a1e Mon Sep 17 00:00:00 2001 From: Josh Hawn Date: Tue, 29 Nov 2016 17:33:45 -0800 Subject: [PATCH 2/2] Add SecretUpdate docs to api/swagger.yaml Docker-DCO-1.1-Signed-off-by: Josh Hawn (github: jlhawn) Upstream-commit: 1cd5af59bffb6ee38f3599443abdcc30359bd521 Component: engine --- components/engine/api/swagger.yaml | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/components/engine/api/swagger.yaml b/components/engine/api/swagger.yaml index b7500bbf83..688a138968 100644 --- a/components/engine/api/swagger.yaml +++ b/components/engine/api/swagger.yaml @@ -7770,3 +7770,36 @@ paths: type: "string" description: "ID of the secret" tags: ["Secret"] + /secrets/{id}/update: + post: + summary: "Update a Secret" + operationId: "SecretUpdate" + responses: + 200: + description: "no error" + 404: + description: "no such secret" + schema: + $ref: "#/definitions/ErrorResponse" + 500: + description: "server error" + schema: + $ref: "#/definitions/ErrorResponse" + parameters: + - name: "id" + in: "path" + description: "The ID of the secret" + type: "string" + required: true + - name: "body" + in: "body" + schema: + $ref: "#/definitions/SecretSpec" + description: "The spec of the secret to update. Currently, only the Labels field can be updated. All other fields must remain unchanged from the [SecretInspect endpoint](#operation/SecretInspect) response values." + - name: "version" + in: "query" + description: "The version number of the secret object being updated. This is required to avoid conflicting writes." + type: "integer" + format: "int64" + required: true + tags: ["Secret"]