Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -203,11 +203,11 @@ type VolumeAPIClient interface {
|
| 203 | 203 |
|
| 204 | 204 |
// SecretAPIClient defines API client methods for secrets |
| 205 | 205 |
type SecretAPIClient interface {
|
| 206 |
- SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) |
|
| 207 |
- SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) |
|
| 208 |
- SecretRemove(ctx context.Context, id string) error |
|
| 209 |
- SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) |
|
| 210 |
- SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error |
|
| 206 |
+ SecretList(ctx context.Context, options SecretListOptions) (SecretListResult, error) |
|
| 207 |
+ SecretCreate(ctx context.Context, options SecretCreateOptions) (SecretCreateResult, error) |
|
| 208 |
+ SecretRemove(ctx context.Context, id string, options SecretRemoveOptions) (SecretRemoveResult, error) |
|
| 209 |
+ SecretInspect(ctx context.Context, id string, options SecretInspectOptions) (SecretInspectResult, error) |
|
| 210 |
+ SecretUpdate(ctx context.Context, id string, options SecretUpdateOptions) (SecretUpdateResult, error) |
|
| 211 | 211 |
} |
| 212 | 212 |
|
| 213 | 213 |
// ConfigAPIClient defines API client methods for configs |
| ... | ... |
@@ -7,15 +7,28 @@ import ( |
| 7 | 7 |
"github.com/moby/moby/api/types/swarm" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
+// SecretCreateOptions holds options for creating a secret. |
|
| 11 |
+type SecretCreateOptions struct {
|
|
| 12 |
+ Spec swarm.SecretSpec |
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// SecretCreateResult holds the result from the [Client.SecretCreate] method. |
|
| 16 |
+type SecretCreateResult struct {
|
|
| 17 |
+ ID string |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 10 | 20 |
// SecretCreate creates a new secret. |
| 11 |
-func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) {
|
|
| 12 |
- resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil) |
|
| 21 |
+func (cli *Client) SecretCreate(ctx context.Context, options SecretCreateOptions) (SecretCreateResult, error) {
|
|
| 22 |
+ resp, err := cli.post(ctx, "/secrets/create", nil, options.Spec, nil) |
|
| 13 | 23 |
defer ensureReaderClosed(resp) |
| 14 | 24 |
if err != nil {
|
| 15 |
- return swarm.SecretCreateResponse{}, err
|
|
| 25 |
+ return SecretCreateResult{}, err
|
|
| 16 | 26 |
} |
| 17 | 27 |
|
| 18 |
- var response swarm.SecretCreateResponse |
|
| 19 |
- err = json.NewDecoder(resp.Body).Decode(&response) |
|
| 20 |
- return response, err |
|
| 28 |
+ var out swarm.ConfigCreateResponse |
|
| 29 |
+ err = json.NewDecoder(resp.Body).Decode(&out) |
|
| 30 |
+ if err != nil {
|
|
| 31 |
+ return SecretCreateResult{}, err
|
|
| 32 |
+ } |
|
| 33 |
+ return SecretCreateResult{ID: out.ID}, nil
|
|
| 21 | 34 |
} |
| ... | ... |
@@ -17,7 +17,7 @@ import ( |
| 17 | 17 |
func TestSecretCreateError(t *testing.T) {
|
| 18 | 18 |
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) |
| 19 | 19 |
assert.NilError(t, err) |
| 20 |
- _, err = client.SecretCreate(context.Background(), swarm.SecretSpec{})
|
|
| 20 |
+ _, err = client.SecretCreate(context.Background(), SecretCreateOptions{})
|
|
| 21 | 21 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) |
| 22 | 22 |
} |
| 23 | 23 |
|
| ... | ... |
@@ -40,7 +40,7 @@ func TestSecretCreate(t *testing.T) {
|
| 40 | 40 |
})) |
| 41 | 41 |
assert.NilError(t, err) |
| 42 | 42 |
|
| 43 |
- r, err := client.SecretCreate(context.Background(), swarm.SecretSpec{})
|
|
| 43 |
+ r, err := client.SecretCreate(context.Background(), SecretCreateOptions{})
|
|
| 44 | 44 |
assert.NilError(t, err) |
| 45 | 45 |
assert.Check(t, is.Equal(r.ID, "test_secret")) |
| 46 | 46 |
} |
| ... | ... |
@@ -1,34 +1,35 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "bytes" |
|
| 5 | 4 |
"context" |
| 6 |
- "encoding/json" |
|
| 7 |
- "io" |
|
| 8 | 5 |
|
| 9 | 6 |
"github.com/moby/moby/api/types/swarm" |
| 10 | 7 |
) |
| 11 | 8 |
|
| 12 |
-// SecretInspectWithRaw returns the secret information with raw data |
|
| 13 |
-func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
|
|
| 9 |
+// SecretInspectOptions holds options for inspecting a secret. |
|
| 10 |
+type SecretInspectOptions struct {
|
|
| 11 |
+ // Add future optional parameters here |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// SecretInspectResult holds the result from the [Client.SecretInspect]. method. |
|
| 15 |
+type SecretInspectResult struct {
|
|
| 16 |
+ Secret swarm.Secret |
|
| 17 |
+ Raw []byte |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+// SecretInspect returns the secret information with raw data. |
|
| 21 |
+func (cli *Client) SecretInspect(ctx context.Context, id string, options SecretInspectOptions) (SecretInspectResult, error) {
|
|
| 14 | 22 |
id, err := trimID("secret", id)
|
| 15 | 23 |
if err != nil {
|
| 16 |
- return swarm.Secret{}, nil, err
|
|
| 24 |
+ return SecretInspectResult{}, err
|
|
| 17 | 25 |
} |
| 18 | 26 |
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil) |
| 19 | 27 |
defer ensureReaderClosed(resp) |
| 20 | 28 |
if err != nil {
|
| 21 |
- return swarm.Secret{}, nil, err
|
|
| 29 |
+ return SecretInspectResult{}, err
|
|
| 22 | 30 |
} |
| 23 | 31 |
|
| 24 |
- body, err := io.ReadAll(resp.Body) |
|
| 25 |
- if err != nil {
|
|
| 26 |
- return swarm.Secret{}, nil, err
|
|
| 27 |
- } |
|
| 28 |
- |
|
| 29 |
- var secret swarm.Secret |
|
| 30 |
- rdr := bytes.NewReader(body) |
|
| 31 |
- err = json.NewDecoder(rdr).Decode(&secret) |
|
| 32 |
- |
|
| 33 |
- return secret, body, err |
|
| 32 |
+ var out SecretInspectResult |
|
| 33 |
+ out.Raw, err = decodeWithRaw(resp, &out.Secret) |
|
| 34 |
+ return out, err |
|
| 34 | 35 |
} |
| ... | ... |
@@ -19,7 +19,7 @@ func TestSecretInspectError(t *testing.T) {
|
| 19 | 19 |
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) |
| 20 | 20 |
assert.NilError(t, err) |
| 21 | 21 |
|
| 22 |
- _, _, err = client.SecretInspectWithRaw(context.Background(), "nothing") |
|
| 22 |
+ _, err = client.SecretInspect(context.Background(), "nothing", SecretInspectOptions{})
|
|
| 23 | 23 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) |
| 24 | 24 |
} |
| 25 | 25 |
|
| ... | ... |
@@ -27,7 +27,7 @@ func TestSecretInspectSecretNotFound(t *testing.T) {
|
| 27 | 27 |
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusNotFound, "Server error"))) |
| 28 | 28 |
assert.NilError(t, err) |
| 29 | 29 |
|
| 30 |
- _, _, err = client.SecretInspectWithRaw(context.Background(), "unknown") |
|
| 30 |
+ _, err = client.SecretInspect(context.Background(), "unknown", SecretInspectOptions{})
|
|
| 31 | 31 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) |
| 32 | 32 |
} |
| 33 | 33 |
|
| ... | ... |
@@ -36,11 +36,11 @@ func TestSecretInspectWithEmptyID(t *testing.T) {
|
| 36 | 36 |
return nil, errors.New("should not make request")
|
| 37 | 37 |
})) |
| 38 | 38 |
assert.NilError(t, err) |
| 39 |
- _, _, err = client.SecretInspectWithRaw(context.Background(), "") |
|
| 39 |
+ _, err = client.SecretInspect(context.Background(), "", SecretInspectOptions{})
|
|
| 40 | 40 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 41 | 41 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 42 | 42 |
|
| 43 |
- _, _, err = client.SecretInspectWithRaw(context.Background(), " ") |
|
| 43 |
+ _, err = client.SecretInspect(context.Background(), " ", SecretInspectOptions{})
|
|
| 44 | 44 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 45 | 45 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 46 | 46 |
} |
| ... | ... |
@@ -64,7 +64,7 @@ func TestSecretInspect(t *testing.T) {
|
| 64 | 64 |
})) |
| 65 | 65 |
assert.NilError(t, err) |
| 66 | 66 |
|
| 67 |
- secretInspect, _, err := client.SecretInspectWithRaw(context.Background(), "secret_id") |
|
| 67 |
+ res, err := client.SecretInspect(context.Background(), "secret_id", SecretInspectOptions{})
|
|
| 68 | 68 |
assert.NilError(t, err) |
| 69 |
- assert.Check(t, is.Equal(secretInspect.ID, "secret_id")) |
|
| 69 |
+ assert.Check(t, is.Equal(res.Secret.ID, "secret_id")) |
|
| 70 | 70 |
} |
| ... | ... |
@@ -8,18 +8,31 @@ import ( |
| 8 | 8 |
"github.com/moby/moby/api/types/swarm" |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 |
+// SecretListOptions holds parameters to list secrets |
|
| 12 |
+type SecretListOptions struct {
|
|
| 13 |
+ Filters Filters |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+// SecretListResult holds the result from the [client.SecretList] method. |
|
| 17 |
+type SecretListResult struct {
|
|
| 18 |
+ Items []swarm.Secret |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 11 | 21 |
// SecretList returns the list of secrets. |
| 12 |
-func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
|
|
| 22 |
+func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) (SecretListResult, error) {
|
|
| 13 | 23 |
query := url.Values{}
|
| 14 |
- |
|
| 15 | 24 |
options.Filters.updateURLValues(query) |
| 25 |
+ |
|
| 16 | 26 |
resp, err := cli.get(ctx, "/secrets", query, nil) |
| 17 | 27 |
defer ensureReaderClosed(resp) |
| 18 | 28 |
if err != nil {
|
| 19 |
- return nil, err |
|
| 29 |
+ return SecretListResult{}, err
|
|
| 20 | 30 |
} |
| 21 | 31 |
|
| 22 |
- var secrets []swarm.Secret |
|
| 23 |
- err = json.NewDecoder(resp.Body).Decode(&secrets) |
|
| 24 |
- return secrets, err |
|
| 32 |
+ var out SecretListResult |
|
| 33 |
+ err = json.NewDecoder(resp.Body).Decode(&out.Items) |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ return SecretListResult{}, err
|
|
| 36 |
+ } |
|
| 37 |
+ return out, nil |
|
| 25 | 38 |
} |
| ... | ... |
@@ -75,8 +75,8 @@ func TestSecretList(t *testing.T) {
|
| 75 | 75 |
})) |
| 76 | 76 |
assert.NilError(t, err) |
| 77 | 77 |
|
| 78 |
- secrets, err := client.SecretList(context.Background(), listCase.options) |
|
| 78 |
+ res, err := client.SecretList(context.Background(), listCase.options) |
|
| 79 | 79 |
assert.NilError(t, err) |
| 80 |
- assert.Check(t, is.Len(secrets, 2)) |
|
| 80 |
+ assert.Check(t, is.Len(res.Items, 2)) |
|
| 81 | 81 |
} |
| 82 | 82 |
} |
| ... | ... |
@@ -2,13 +2,24 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import "context" |
| 4 | 4 |
|
| 5 |
+type SecretRemoveOptions struct {
|
|
| 6 |
+ // Add future optional parameters here |
|
| 7 |
+} |
|
| 8 |
+ |
|
| 9 |
+type SecretRemoveResult struct {
|
|
| 10 |
+ // Add future fields here |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 5 | 13 |
// SecretRemove removes a secret. |
| 6 |
-func (cli *Client) SecretRemove(ctx context.Context, id string) error {
|
|
| 14 |
+func (cli *Client) SecretRemove(ctx context.Context, id string, options SecretRemoveOptions) (SecretRemoveResult, error) {
|
|
| 7 | 15 |
id, err := trimID("secret", id)
|
| 8 | 16 |
if err != nil {
|
| 9 |
- return err |
|
| 17 |
+ return SecretRemoveResult{}, err
|
|
| 10 | 18 |
} |
| 11 | 19 |
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil) |
| 12 | 20 |
defer ensureReaderClosed(resp) |
| 13 |
- return err |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return SecretRemoveResult{}, err
|
|
| 23 |
+ } |
|
| 24 |
+ return SecretRemoveResult{}, nil
|
|
| 14 | 25 |
} |
| ... | ... |
@@ -16,14 +16,14 @@ func TestSecretRemoveError(t *testing.T) {
|
| 16 | 16 |
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) |
| 17 | 17 |
assert.NilError(t, err) |
| 18 | 18 |
|
| 19 |
- err = client.SecretRemove(context.Background(), "secret_id") |
|
| 19 |
+ _, err = client.SecretRemove(context.Background(), "secret_id", SecretRemoveOptions{})
|
|
| 20 | 20 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) |
| 21 | 21 |
|
| 22 |
- err = client.SecretRemove(context.Background(), "") |
|
| 22 |
+ _, err = client.SecretRemove(context.Background(), "", SecretRemoveOptions{})
|
|
| 23 | 23 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 24 | 24 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 25 | 25 |
|
| 26 |
- err = client.SecretRemove(context.Background(), " ") |
|
| 26 |
+ _, err = client.SecretRemove(context.Background(), " ", SecretRemoveOptions{})
|
|
| 27 | 27 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 28 | 28 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 29 | 29 |
} |
| ... | ... |
@@ -42,6 +42,6 @@ func TestSecretRemove(t *testing.T) {
|
| 42 | 42 |
})) |
| 43 | 43 |
assert.NilError(t, err) |
| 44 | 44 |
|
| 45 |
- err = client.SecretRemove(context.Background(), "secret_id") |
|
| 45 |
+ _, err = client.SecretRemove(context.Background(), "secret_id", SecretRemoveOptions{})
|
|
| 46 | 46 |
assert.NilError(t, err) |
| 47 | 47 |
} |
| ... | ... |
@@ -7,15 +7,26 @@ import ( |
| 7 | 7 |
"github.com/moby/moby/api/types/swarm" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
+// SecretUpdateOptions holds options for updating a secret. |
|
| 11 |
+type SecretUpdateOptions struct {
|
|
| 12 |
+ Version swarm.Version |
|
| 13 |
+ Spec swarm.SecretSpec |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+type SecretUpdateResult struct{}
|
|
| 17 |
+ |
|
| 10 | 18 |
// SecretUpdate attempts to update a secret. |
| 11 |
-func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
|
|
| 19 |
+func (cli *Client) SecretUpdate(ctx context.Context, id string, options SecretUpdateOptions) (SecretUpdateResult, error) {
|
|
| 12 | 20 |
id, err := trimID("secret", id)
|
| 13 | 21 |
if err != nil {
|
| 14 |
- return err |
|
| 22 |
+ return SecretUpdateResult{}, err
|
|
| 15 | 23 |
} |
| 16 | 24 |
query := url.Values{}
|
| 17 |
- query.Set("version", version.String())
|
|
| 18 |
- resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil) |
|
| 25 |
+ query.Set("version", options.Version.String())
|
|
| 26 |
+ resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, options.Spec, nil) |
|
| 19 | 27 |
defer ensureReaderClosed(resp) |
| 20 |
- return err |
|
| 28 |
+ if err != nil {
|
|
| 29 |
+ return SecretUpdateResult{}, err
|
|
| 30 |
+ } |
|
| 31 |
+ return SecretUpdateResult{}, nil
|
|
| 21 | 32 |
} |
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"testing" |
| 9 | 9 |
|
| 10 | 10 |
cerrdefs "github.com/containerd/errdefs" |
| 11 |
- "github.com/moby/moby/api/types/swarm" |
|
| 12 | 11 |
"gotest.tools/v3/assert" |
| 13 | 12 |
is "gotest.tools/v3/assert/cmp" |
| 14 | 13 |
) |
| ... | ... |
@@ -17,14 +16,14 @@ func TestSecretUpdateError(t *testing.T) {
|
| 17 | 17 |
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) |
| 18 | 18 |
assert.NilError(t, err) |
| 19 | 19 |
|
| 20 |
- err = client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{})
|
|
| 20 |
+ _, err = client.SecretUpdate(context.Background(), "secret_id", SecretUpdateOptions{})
|
|
| 21 | 21 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) |
| 22 | 22 |
|
| 23 |
- err = client.SecretUpdate(context.Background(), "", swarm.Version{}, swarm.SecretSpec{})
|
|
| 23 |
+ _, err = client.SecretUpdate(context.Background(), "", SecretUpdateOptions{})
|
|
| 24 | 24 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 25 | 25 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 26 | 26 |
|
| 27 |
- err = client.SecretUpdate(context.Background(), " ", swarm.Version{}, swarm.SecretSpec{})
|
|
| 27 |
+ _, err = client.SecretUpdate(context.Background(), " ", SecretUpdateOptions{})
|
|
| 28 | 28 |
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
| 29 | 29 |
assert.Check(t, is.ErrorContains(err, "value is empty")) |
| 30 | 30 |
} |
| ... | ... |
@@ -43,6 +42,6 @@ func TestSecretUpdate(t *testing.T) {
|
| 43 | 43 |
})) |
| 44 | 44 |
assert.NilError(t, err) |
| 45 | 45 |
|
| 46 |
- err = client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{})
|
|
| 46 |
+ _, err = client.SecretUpdate(context.Background(), "secret_id", SecretUpdateOptions{})
|
|
| 47 | 47 |
assert.NilError(t, err) |
| 48 | 48 |
} |
| ... | ... |
@@ -12,6 +12,7 @@ import ( |
| 12 | 12 |
"github.com/moby/moby/api/types/container" |
| 13 | 13 |
"github.com/moby/moby/api/types/mount" |
| 14 | 14 |
"github.com/moby/moby/api/types/swarm" |
| 15 |
+ "github.com/moby/moby/client" |
|
| 15 | 16 |
"github.com/moby/moby/v2/integration-cli/checker" |
| 16 | 17 |
"github.com/moby/moby/v2/internal/testutil" |
| 17 | 18 |
"gotest.tools/v3/assert" |
| ... | ... |
@@ -71,16 +72,20 @@ func (s *DockerSwarmSuite) TestServiceCreateMountVolume(c *testing.T) {
|
| 71 | 71 |
func (s *DockerSwarmSuite) TestServiceCreateWithSecretSimple(c *testing.T) {
|
| 72 | 72 |
ctx := testutil.GetContext(c) |
| 73 | 73 |
d := s.AddDaemon(ctx, c, true, true) |
| 74 |
+ apiClient := d.NewClientT(c) |
|
| 74 | 75 |
|
| 75 | 76 |
serviceName := "test-service-secret" |
| 76 | 77 |
testName := "test_secret" |
| 77 |
- id := d.CreateSecret(c, swarm.SecretSpec{
|
|
| 78 |
- Annotations: swarm.Annotations{
|
|
| 79 |
- Name: testName, |
|
| 78 |
+ scr, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 79 |
+ Spec: swarm.SecretSpec{
|
|
| 80 |
+ Annotations: swarm.Annotations{
|
|
| 81 |
+ Name: testName, |
|
| 82 |
+ }, |
|
| 83 |
+ Data: []byte("TESTINGDATA"),
|
|
| 80 | 84 |
}, |
| 81 |
- Data: []byte("TESTINGDATA"),
|
|
| 82 | 85 |
}) |
| 83 |
- assert.Assert(c, id != "", "secrets: %s", id) |
|
| 86 |
+ assert.NilError(c, err) |
|
| 87 |
+ assert.Assert(c, scr.ID != "", "secrets: %s", scr.ID) |
|
| 84 | 88 |
|
| 85 | 89 |
out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--secret", testName, "busybox", "top")
|
| 86 | 90 |
assert.NilError(c, err, out) |
| ... | ... |
@@ -100,7 +105,8 @@ func (s *DockerSwarmSuite) TestServiceCreateWithSecretSimple(c *testing.T) {
|
| 100 | 100 |
|
| 101 | 101 |
out, err = d.Cmd("service", "rm", serviceName)
|
| 102 | 102 |
assert.NilError(c, err, out) |
| 103 |
- d.DeleteSecret(c, testName) |
|
| 103 |
+ _, err = apiClient.SecretRemove(c.Context(), testName, client.SecretRemoveOptions{})
|
|
| 104 |
+ assert.NilError(c, err) |
|
| 104 | 105 |
} |
| 105 | 106 |
|
| 106 | 107 |
func (s *DockerSwarmSuite) TestServiceCreateWithSecretSourceTargetPaths(c *testing.T) {
|
| ... | ... |
@@ -116,15 +122,18 @@ func (s *DockerSwarmSuite) TestServiceCreateWithSecretSourceTargetPaths(c *testi |
| 116 | 116 |
|
| 117 | 117 |
var secretFlags []string |
| 118 | 118 |
|
| 119 |
+ apiClient := d.NewClientT(c) |
|
| 119 | 120 |
for testName, testTarget := range testPaths {
|
| 120 |
- id := d.CreateSecret(c, swarm.SecretSpec{
|
|
| 121 |
- Annotations: swarm.Annotations{
|
|
| 122 |
- Name: testName, |
|
| 121 |
+ scr, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 122 |
+ Spec: swarm.SecretSpec{
|
|
| 123 |
+ Annotations: swarm.Annotations{
|
|
| 124 |
+ Name: testName, |
|
| 125 |
+ }, |
|
| 126 |
+ Data: []byte("TESTINGDATA " + testName + " " + testTarget),
|
|
| 123 | 127 |
}, |
| 124 |
- Data: []byte("TESTINGDATA " + testName + " " + testTarget),
|
|
| 125 | 128 |
}) |
| 126 |
- assert.Assert(c, id != "", "secrets: %s", id) |
|
| 127 |
- |
|
| 129 |
+ assert.NilError(c, err) |
|
| 130 |
+ assert.Assert(c, scr.ID != "", "secrets: %s", scr.ID) |
|
| 128 | 131 |
secretFlags = append(secretFlags, "--secret", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
|
| 129 | 132 |
} |
| 130 | 133 |
|
| ... | ... |
@@ -174,13 +183,17 @@ func (s *DockerSwarmSuite) TestServiceCreateWithSecretReferencedTwice(c *testing |
| 174 | 174 |
ctx := testutil.GetContext(c) |
| 175 | 175 |
d := s.AddDaemon(ctx, c, true, true) |
| 176 | 176 |
|
| 177 |
- id := d.CreateSecret(c, swarm.SecretSpec{
|
|
| 178 |
- Annotations: swarm.Annotations{
|
|
| 179 |
- Name: "mysecret", |
|
| 177 |
+ apiClient := d.NewClientT(c) |
|
| 178 |
+ scr, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 179 |
+ Spec: swarm.SecretSpec{
|
|
| 180 |
+ Annotations: swarm.Annotations{
|
|
| 181 |
+ Name: "mysecret", |
|
| 182 |
+ }, |
|
| 183 |
+ Data: []byte("TESTINGDATA"),
|
|
| 180 | 184 |
}, |
| 181 |
- Data: []byte("TESTINGDATA"),
|
|
| 182 | 185 |
}) |
| 183 |
- assert.Assert(c, id != "", "secrets: %s", id) |
|
| 186 |
+ assert.NilError(c, err) |
|
| 187 |
+ assert.Assert(c, scr.ID != "", "secrets: %s", scr.ID) |
|
| 184 | 188 |
|
| 185 | 189 |
serviceName := "svc" |
| 186 | 190 |
out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--secret", "source=mysecret,target=target1", "--secret", "source=mysecret,target=target2", "busybox", "top")
|
| ... | ... |
@@ -21,6 +21,7 @@ import ( |
| 21 | 21 |
"github.com/cloudflare/cfssl/helpers" |
| 22 | 22 |
"github.com/moby/moby/api/types/swarm" |
| 23 | 23 |
"github.com/moby/moby/api/types/versions" |
| 24 |
+ "github.com/moby/moby/client" |
|
| 24 | 25 |
"github.com/moby/moby/v2/daemon/libnetwork/driverapi" |
| 25 | 26 |
"github.com/moby/moby/v2/daemon/libnetwork/ipamapi" |
| 26 | 27 |
remoteipam "github.com/moby/moby/v2/daemon/libnetwork/ipams/remote/api" |
| ... | ... |
@@ -1985,20 +1986,27 @@ func (s *DockerSwarmSuite) TestSwarmClusterEventsNetwork(c *testing.T) {
|
| 1985 | 1985 |
func (s *DockerSwarmSuite) TestSwarmClusterEventsSecret(c *testing.T) {
|
| 1986 | 1986 |
ctx := testutil.GetContext(c) |
| 1987 | 1987 |
d := s.AddDaemon(ctx, c, true, true) |
| 1988 |
+ apiClient := d.NewClientT(c) |
|
| 1988 | 1989 |
|
| 1989 | 1990 |
testName := "test_secret" |
| 1990 |
- id := d.CreateSecret(c, swarm.SecretSpec{
|
|
| 1991 |
- Annotations: swarm.Annotations{
|
|
| 1992 |
- Name: testName, |
|
| 1991 |
+ scr, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 1992 |
+ Spec: swarm.SecretSpec{
|
|
| 1993 |
+ Annotations: swarm.Annotations{
|
|
| 1994 |
+ Name: testName, |
|
| 1995 |
+ }, |
|
| 1996 |
+ Data: []byte("TESTINGDATA"),
|
|
| 1993 | 1997 |
}, |
| 1994 |
- Data: []byte("TESTINGDATA"),
|
|
| 1995 | 1998 |
}) |
| 1996 |
- assert.Assert(c, id != "", "secrets: %s", id) |
|
| 1999 |
+ assert.NilError(c, err) |
|
| 2000 |
+ assert.Assert(c, scr.ID != "", "secrets: %s", scr.ID) |
|
| 2001 |
+ id := scr.ID |
|
| 1997 | 2002 |
|
| 1998 | 2003 |
waitForEvent(c, d, "0", "-f scope=swarm", "secret create "+id, defaultRetryCount) |
| 1999 | 2004 |
|
| 2000 | 2005 |
t1 := daemonUnixTime(c) |
| 2001 |
- d.DeleteSecret(c, id) |
|
| 2006 |
+ _, err = apiClient.SecretRemove(c.Context(), id, client.SecretRemoveOptions{})
|
|
| 2007 |
+ assert.NilError(c, err) |
|
| 2008 |
+ |
|
| 2002 | 2009 |
// filtered by secret |
| 2003 | 2010 |
waitForEvent(c, d, t1, "-f type=secret", "secret remove "+id, defaultRetryCount) |
| 2004 | 2011 |
} |
| ... | ... |
@@ -236,7 +236,9 @@ func TestTemplatedConfig(t *testing.T) {
|
| 236 | 236 |
}, |
| 237 | 237 |
Data: []byte("this is a secret"),
|
| 238 | 238 |
} |
| 239 |
- referencedSecret, err := c.SecretCreate(ctx, referencedSecretSpec) |
|
| 239 |
+ referencedSecret, err := c.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 240 |
+ Spec: referencedSecretSpec, |
|
| 241 |
+ }) |
|
| 240 | 242 |
assert.Check(t, err) |
| 241 | 243 |
|
| 242 | 244 |
referencedConfigName := "referencedconfig-" + t.Name() |
| ... | ... |
@@ -32,14 +32,14 @@ func TestSecretInspect(t *testing.T) {
|
| 32 | 32 |
testName := t.Name() |
| 33 | 33 |
secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
|
| 34 | 34 |
|
| 35 |
- insp, body, err := c.SecretInspectWithRaw(ctx, secretID) |
|
| 35 |
+ result, err := c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 36 | 36 |
assert.NilError(t, err) |
| 37 |
- assert.Check(t, is.Equal(insp.Spec.Name, testName)) |
|
| 37 |
+ assert.Check(t, is.Equal(result.Secret.Spec.Name, testName)) |
|
| 38 | 38 |
|
| 39 | 39 |
var secret swarmtypes.Secret |
| 40 |
- err = json.Unmarshal(body, &secret) |
|
| 40 |
+ err = json.Unmarshal(result.Raw, &secret) |
|
| 41 | 41 |
assert.NilError(t, err) |
| 42 |
- assert.Check(t, is.DeepEqual(secret, insp)) |
|
| 42 |
+ assert.Check(t, is.DeepEqual(secret, result.Secret)) |
|
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 | 45 |
func TestSecretList(t *testing.T) {
|
| ... | ... |
@@ -51,12 +51,12 @@ func TestSecretList(t *testing.T) {
|
| 51 | 51 |
c := d.NewClientT(t) |
| 52 | 52 |
defer c.Close() |
| 53 | 53 |
|
| 54 |
- configs, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 54 |
+ result, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 55 | 55 |
assert.NilError(t, err) |
| 56 |
- assert.Check(t, is.Equal(len(configs), 0)) |
|
| 56 |
+ assert.Check(t, is.Equal(len(result.Items), 0)) |
|
| 57 | 57 |
|
| 58 |
- testName0 := "test0_" + t.Name() |
|
| 59 |
- testName1 := "test1_" + t.Name() |
|
| 58 |
+ testName0 := "test0-" + t.Name() |
|
| 59 |
+ testName1 := "test1-" + t.Name() |
|
| 60 | 60 |
testNames := []string{testName0, testName1}
|
| 61 | 61 |
sort.Strings(testNames) |
| 62 | 62 |
|
| ... | ... |
@@ -67,58 +67,66 @@ func TestSecretList(t *testing.T) {
|
| 67 | 67 |
secret1ID := createSecret(ctx, t, c, testName1, []byte("TESTINGDATA1"), map[string]string{"type": "production"})
|
| 68 | 68 |
|
| 69 | 69 |
// test by `secret ls` |
| 70 |
- entries, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 70 |
+ res, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 71 | 71 |
assert.NilError(t, err) |
| 72 |
- assert.Check(t, is.DeepEqual(secretNamesFromList(entries), testNames)) |
|
| 72 |
+ assert.Check(t, is.DeepEqual(namesFromList(res.Items), testNames)) |
|
| 73 | 73 |
|
| 74 | 74 |
testCases := []struct {
|
| 75 |
+ desc string |
|
| 75 | 76 |
filters client.Filters |
| 76 | 77 |
expected []string |
| 77 | 78 |
}{
|
| 78 |
- // test filter by name `secret ls --filter name=xxx` |
|
| 79 | 79 |
{
|
| 80 |
+ desc: "test filter by name", |
|
| 80 | 81 |
filters: make(client.Filters).Add("name", testName0),
|
| 81 | 82 |
expected: []string{testName0},
|
| 82 | 83 |
}, |
| 83 |
- // test filter by id `secret ls --filter id=xxx` |
|
| 84 | 84 |
{
|
| 85 |
+ desc: "test filter by id", |
|
| 85 | 86 |
filters: make(client.Filters).Add("id", secret1ID),
|
| 86 | 87 |
expected: []string{testName1},
|
| 87 | 88 |
}, |
| 88 |
- // test filter by label `secret ls --filter label=xxx` |
|
| 89 | 89 |
{
|
| 90 |
+ desc: "test filter by label key only", |
|
| 90 | 91 |
filters: make(client.Filters).Add("label", "type"),
|
| 91 | 92 |
expected: testNames, |
| 92 | 93 |
}, |
| 93 | 94 |
{
|
| 95 |
+ desc: "test filter by label key=value " + testName0, |
|
| 94 | 96 |
filters: make(client.Filters).Add("label", "type=test"),
|
| 95 | 97 |
expected: []string{testName0},
|
| 96 | 98 |
}, |
| 97 | 99 |
{
|
| 100 |
+ desc: "test filter by label key=value " + testName1, |
|
| 98 | 101 |
filters: make(client.Filters).Add("label", "type=production"),
|
| 99 | 102 |
expected: []string{testName1},
|
| 100 | 103 |
}, |
| 101 | 104 |
} |
| 102 | 105 |
for _, tc := range testCases {
|
| 103 |
- entries, err = c.SecretList(ctx, client.SecretListOptions{
|
|
| 104 |
- Filters: tc.filters, |
|
| 106 |
+ t.Run(tc.desc, func(t *testing.T) {
|
|
| 107 |
+ ctx := testutil.StartSpan(ctx, t) |
|
| 108 |
+ res, err = c.SecretList(ctx, client.SecretListOptions{
|
|
| 109 |
+ Filters: tc.filters, |
|
| 110 |
+ }) |
|
| 111 |
+ assert.NilError(t, err) |
|
| 112 |
+ assert.Check(t, is.DeepEqual(namesFromList(res.Items), tc.expected)) |
|
| 105 | 113 |
}) |
| 106 |
- assert.NilError(t, err) |
|
| 107 |
- assert.Check(t, is.DeepEqual(secretNamesFromList(entries), tc.expected)) |
|
| 108 | 114 |
} |
| 109 | 115 |
} |
| 110 | 116 |
|
| 111 |
-func createSecret(ctx context.Context, t *testing.T, client client.APIClient, name string, data []byte, labels map[string]string) string {
|
|
| 112 |
- secret, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{
|
|
| 113 |
- Annotations: swarmtypes.Annotations{
|
|
| 114 |
- Name: name, |
|
| 115 |
- Labels: labels, |
|
| 117 |
+func createSecret(ctx context.Context, t *testing.T, apiClient client.APIClient, name string, data []byte, labels map[string]string) string {
|
|
| 118 |
+ result, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 119 |
+ Spec: swarmtypes.SecretSpec{
|
|
| 120 |
+ Annotations: swarmtypes.Annotations{
|
|
| 121 |
+ Name: name, |
|
| 122 |
+ Labels: labels, |
|
| 123 |
+ }, |
|
| 124 |
+ Data: data, |
|
| 116 | 125 |
}, |
| 117 |
- Data: data, |
|
| 118 | 126 |
}) |
| 119 | 127 |
assert.NilError(t, err) |
| 120 |
- assert.Check(t, secret.ID != "") |
|
| 121 |
- return secret.ID |
|
| 128 |
+ assert.Check(t, result.ID != "") |
|
| 129 |
+ return result.ID |
|
| 122 | 130 |
} |
| 123 | 131 |
|
| 124 | 132 |
func TestSecretsCreateAndDelete(t *testing.T) {
|
| ... | ... |
@@ -134,23 +142,25 @@ func TestSecretsCreateAndDelete(t *testing.T) {
|
| 134 | 134 |
secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
|
| 135 | 135 |
|
| 136 | 136 |
// create an already existing secret, daemon should return a status code of 409 |
| 137 |
- _, err := c.SecretCreate(ctx, swarmtypes.SecretSpec{
|
|
| 138 |
- Annotations: swarmtypes.Annotations{
|
|
| 139 |
- Name: testName, |
|
| 137 |
+ _, err := c.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 138 |
+ Spec: swarmtypes.SecretSpec{
|
|
| 139 |
+ Annotations: swarmtypes.Annotations{
|
|
| 140 |
+ Name: testName, |
|
| 141 |
+ }, |
|
| 142 |
+ Data: []byte("TESTINGDATA"),
|
|
| 140 | 143 |
}, |
| 141 |
- Data: []byte("TESTINGDATA"),
|
|
| 142 | 144 |
}) |
| 143 | 145 |
assert.Check(t, cerrdefs.IsConflict(err)) |
| 144 | 146 |
assert.Check(t, is.ErrorContains(err, testName)) |
| 145 | 147 |
|
| 146 |
- err = c.SecretRemove(ctx, secretID) |
|
| 148 |
+ _, err = c.SecretRemove(ctx, secretID, client.SecretRemoveOptions{})
|
|
| 147 | 149 |
assert.NilError(t, err) |
| 148 | 150 |
|
| 149 |
- _, _, err = c.SecretInspectWithRaw(ctx, secretID) |
|
| 151 |
+ _, err = c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 150 | 152 |
assert.Check(t, cerrdefs.IsNotFound(err)) |
| 151 | 153 |
assert.Check(t, is.ErrorContains(err, secretID)) |
| 152 | 154 |
|
| 153 |
- err = c.SecretRemove(ctx, "non-existing") |
|
| 155 |
+ _, err = c.SecretRemove(ctx, "non-existing", client.SecretRemoveOptions{})
|
|
| 154 | 156 |
assert.Check(t, cerrdefs.IsNotFound(err)) |
| 155 | 157 |
assert.Check(t, is.ErrorContains(err, "non-existing")) |
| 156 | 158 |
|
| ... | ... |
@@ -160,12 +170,12 @@ func TestSecretsCreateAndDelete(t *testing.T) {
|
| 160 | 160 |
"key2": "value2", |
| 161 | 161 |
}) |
| 162 | 162 |
|
| 163 |
- insp, _, err := c.SecretInspectWithRaw(ctx, secretID) |
|
| 163 |
+ result, err := c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 164 | 164 |
assert.NilError(t, err) |
| 165 |
- assert.Check(t, is.Equal(insp.Spec.Name, testName)) |
|
| 166 |
- assert.Check(t, is.Equal(len(insp.Spec.Labels), 2)) |
|
| 167 |
- assert.Check(t, is.Equal(insp.Spec.Labels["key1"], "value1")) |
|
| 168 |
- assert.Check(t, is.Equal(insp.Spec.Labels["key2"], "value2")) |
|
| 165 |
+ assert.Check(t, is.Equal(result.Secret.Spec.Name, testName)) |
|
| 166 |
+ assert.Check(t, is.Equal(len(result.Secret.Spec.Labels), 2)) |
|
| 167 |
+ assert.Check(t, is.Equal(result.Secret.Spec.Labels["key1"], "value1")) |
|
| 168 |
+ assert.Check(t, is.Equal(result.Secret.Spec.Labels["key2"], "value2")) |
|
| 169 | 169 |
} |
| 170 | 170 |
|
| 171 | 171 |
func TestSecretsUpdate(t *testing.T) {
|
| ... | ... |
@@ -180,41 +190,53 @@ func TestSecretsUpdate(t *testing.T) {
|
| 180 | 180 |
testName := "test_secret_" + t.Name() |
| 181 | 181 |
secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
|
| 182 | 182 |
|
| 183 |
- insp, _, err := c.SecretInspectWithRaw(ctx, secretID) |
|
| 183 |
+ insp, err := c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 184 | 184 |
assert.NilError(t, err) |
| 185 |
- assert.Check(t, is.Equal(insp.ID, secretID)) |
|
| 185 |
+ assert.Check(t, is.Equal(insp.Secret.ID, secretID)) |
|
| 186 | 186 |
|
| 187 | 187 |
// test UpdateSecret with full ID |
| 188 |
- insp.Spec.Labels = map[string]string{"test": "test1"}
|
|
| 189 |
- err = c.SecretUpdate(ctx, secretID, insp.Version, insp.Spec) |
|
| 188 |
+ insp.Secret.Spec.Labels = map[string]string{"test": "test1"}
|
|
| 189 |
+ _, err = c.SecretUpdate(ctx, secretID, client.SecretUpdateOptions{
|
|
| 190 |
+ Version: insp.Secret.Version, |
|
| 191 |
+ Spec: insp.Secret.Spec, |
|
| 192 |
+ }) |
|
| 190 | 193 |
assert.NilError(t, err) |
| 191 | 194 |
|
| 192 |
- insp, _, err = c.SecretInspectWithRaw(ctx, secretID) |
|
| 195 |
+ insp, err = c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 193 | 196 |
assert.NilError(t, err) |
| 194 |
- assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test1")) |
|
| 197 |
+ assert.Check(t, is.Equal(insp.Secret.Spec.Labels["test"], "test1")) |
|
| 195 | 198 |
|
| 196 | 199 |
// test UpdateSecret with full name |
| 197 |
- insp.Spec.Labels = map[string]string{"test": "test2"}
|
|
| 198 |
- err = c.SecretUpdate(ctx, testName, insp.Version, insp.Spec) |
|
| 200 |
+ insp.Secret.Spec.Labels = map[string]string{"test": "test2"}
|
|
| 201 |
+ _, err = c.SecretUpdate(ctx, testName, client.SecretUpdateOptions{
|
|
| 202 |
+ Version: insp.Secret.Version, |
|
| 203 |
+ Spec: insp.Secret.Spec, |
|
| 204 |
+ }) |
|
| 199 | 205 |
assert.NilError(t, err) |
| 200 | 206 |
|
| 201 |
- insp, _, err = c.SecretInspectWithRaw(ctx, secretID) |
|
| 207 |
+ insp, err = c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 202 | 208 |
assert.NilError(t, err) |
| 203 |
- assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test2")) |
|
| 209 |
+ assert.Check(t, is.Equal(insp.Secret.Spec.Labels["test"], "test2")) |
|
| 204 | 210 |
|
| 205 | 211 |
// test UpdateSecret with prefix ID |
| 206 |
- insp.Spec.Labels = map[string]string{"test": "test3"}
|
|
| 207 |
- err = c.SecretUpdate(ctx, secretID[:1], insp.Version, insp.Spec) |
|
| 212 |
+ insp.Secret.Spec.Labels = map[string]string{"test": "test3"}
|
|
| 213 |
+ _, err = c.SecretUpdate(ctx, secretID[:1], client.SecretUpdateOptions{
|
|
| 214 |
+ Version: insp.Secret.Version, |
|
| 215 |
+ Spec: insp.Secret.Spec, |
|
| 216 |
+ }) |
|
| 208 | 217 |
assert.NilError(t, err) |
| 209 | 218 |
|
| 210 |
- insp, _, err = c.SecretInspectWithRaw(ctx, secretID) |
|
| 219 |
+ insp, err = c.SecretInspect(ctx, secretID, client.SecretInspectOptions{})
|
|
| 211 | 220 |
assert.NilError(t, err) |
| 212 |
- assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test3")) |
|
| 221 |
+ assert.Check(t, is.Equal(insp.Secret.Spec.Labels["test"], "test3")) |
|
| 213 | 222 |
|
| 214 | 223 |
// test UpdateSecret in updating Data which is not supported in daemon |
| 215 | 224 |
// this test will produce an error in func UpdateSecret |
| 216 |
- insp.Spec.Data = []byte("TESTINGDATA2")
|
|
| 217 |
- err = c.SecretUpdate(ctx, secretID, insp.Version, insp.Spec) |
|
| 225 |
+ insp.Secret.Spec.Data = []byte("TESTINGDATA2")
|
|
| 226 |
+ _, err = c.SecretUpdate(ctx, secretID, client.SecretUpdateOptions{
|
|
| 227 |
+ Version: insp.Secret.Version, |
|
| 228 |
+ Spec: insp.Secret.Spec, |
|
| 229 |
+ }) |
|
| 218 | 230 |
assert.Check(t, cerrdefs.IsInvalidArgument(err)) |
| 219 | 231 |
assert.Check(t, is.ErrorContains(err, "only updates to Labels are allowed")) |
| 220 | 232 |
} |
| ... | ... |
@@ -236,7 +258,9 @@ func TestTemplatedSecret(t *testing.T) {
|
| 236 | 236 |
}, |
| 237 | 237 |
Data: []byte("this is a secret"),
|
| 238 | 238 |
} |
| 239 |
- referencedSecret, err := c.SecretCreate(ctx, referencedSecretSpec) |
|
| 239 |
+ referencedSecret, err := c.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 240 |
+ Spec: referencedSecretSpec, |
|
| 241 |
+ }) |
|
| 240 | 242 |
assert.Check(t, err) |
| 241 | 243 |
|
| 242 | 244 |
referencedConfigName := "referencedconfig_" + t.Name() |
| ... | ... |
@@ -259,12 +283,15 @@ func TestTemplatedSecret(t *testing.T) {
|
| 259 | 259 |
Templating: &swarmtypes.Driver{
|
| 260 | 260 |
Name: "golang", |
| 261 | 261 |
}, |
| 262 |
- Data: []byte("SERVICE_NAME={{.Service.Name}}\n" +
|
|
| 263 |
- "{{secret \"referencedsecrettarget\"}}\n" +
|
|
| 264 |
- "{{config \"referencedconfigtarget\"}}\n"),
|
|
| 262 |
+ Data: []byte(`SERVICE_NAME={{.Service.Name}}
|
|
| 263 |
+{{secret "referencedsecrettarget"}}
|
|
| 264 |
+{{config "referencedconfigtarget"}}
|
|
| 265 |
+`), |
|
| 265 | 266 |
} |
| 266 | 267 |
|
| 267 |
- templatedSecret, err := c.SecretCreate(ctx, secretSpec) |
|
| 268 |
+ templatedSecret, err := c.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 269 |
+ Spec: secretSpec, |
|
| 270 |
+ }) |
|
| 268 | 271 |
assert.Check(t, err) |
| 269 | 272 |
|
| 270 | 273 |
const serviceName = "svc_templated_secret" |
| ... | ... |
@@ -356,39 +383,39 @@ func TestSecretCreateResolve(t *testing.T) {
|
| 356 | 356 |
fakeName := secretID |
| 357 | 357 |
fakeID := createSecret(ctx, t, c, fakeName, []byte("fake foo"), nil)
|
| 358 | 358 |
|
| 359 |
- entries, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 359 |
+ res, err := c.SecretList(ctx, client.SecretListOptions{})
|
|
| 360 | 360 |
assert.NilError(t, err) |
| 361 |
- assert.Check(t, is.Contains(secretNamesFromList(entries), testName)) |
|
| 362 |
- assert.Check(t, is.Contains(secretNamesFromList(entries), fakeName)) |
|
| 361 |
+ assert.Check(t, is.Contains(namesFromList(res.Items), testName)) |
|
| 362 |
+ assert.Check(t, is.Contains(namesFromList(res.Items), fakeName)) |
|
| 363 | 363 |
|
| 364 |
- err = c.SecretRemove(ctx, secretID) |
|
| 364 |
+ _, err = c.SecretRemove(ctx, secretID, client.SecretRemoveOptions{})
|
|
| 365 | 365 |
assert.NilError(t, err) |
| 366 | 366 |
|
| 367 | 367 |
// Fake one will remain |
| 368 |
- entries, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 368 |
+ res, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 369 | 369 |
assert.NilError(t, err) |
| 370 |
- assert.Assert(t, is.DeepEqual(secretNamesFromList(entries), []string{fakeName}))
|
|
| 370 |
+ assert.Assert(t, is.DeepEqual(namesFromList(res.Items), []string{fakeName}))
|
|
| 371 | 371 |
|
| 372 | 372 |
// Remove based on name prefix of the fake one should not work |
| 373 | 373 |
// as search is only done based on: |
| 374 | 374 |
// - Full ID |
| 375 | 375 |
// - Full Name |
| 376 | 376 |
// - Partial ID (prefix) |
| 377 |
- err = c.SecretRemove(ctx, fakeName[:5]) |
|
| 377 |
+ _, err = c.SecretRemove(ctx, fakeName[:5], client.SecretRemoveOptions{})
|
|
| 378 | 378 |
assert.Assert(t, err != nil) |
| 379 |
- entries, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 379 |
+ res, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 380 | 380 |
assert.NilError(t, err) |
| 381 |
- assert.Assert(t, is.DeepEqual(secretNamesFromList(entries), []string{fakeName}))
|
|
| 381 |
+ assert.Assert(t, is.DeepEqual(namesFromList(res.Items), []string{fakeName}))
|
|
| 382 | 382 |
|
| 383 | 383 |
// Remove based on ID prefix of the fake one should succeed |
| 384 |
- err = c.SecretRemove(ctx, fakeID[:5]) |
|
| 384 |
+ _, err = c.SecretRemove(ctx, fakeID[:5], client.SecretRemoveOptions{})
|
|
| 385 | 385 |
assert.NilError(t, err) |
| 386 |
- entries, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 386 |
+ res, err = c.SecretList(ctx, client.SecretListOptions{})
|
|
| 387 | 387 |
assert.NilError(t, err) |
| 388 |
- assert.Assert(t, is.Equal(0, len(entries))) |
|
| 388 |
+ assert.Assert(t, is.Equal(0, len(res.Items))) |
|
| 389 | 389 |
} |
| 390 | 390 |
|
| 391 |
-func secretNamesFromList(entries []swarmtypes.Secret) []string {
|
|
| 391 |
+func namesFromList(entries []swarmtypes.Secret) []string {
|
|
| 392 | 392 |
var values []string |
| 393 | 393 |
for _, entry := range entries {
|
| 394 | 394 |
values = append(values, entry.Spec.Name) |
| ... | ... |
@@ -199,11 +199,13 @@ func TestCreateServiceSecretFileMode(t *testing.T) {
|
| 199 | 199 |
defer apiClient.Close() |
| 200 | 200 |
|
| 201 | 201 |
secretName := "TestSecret_" + t.Name() |
| 202 |
- secretResp, err := apiClient.SecretCreate(ctx, swarmtypes.SecretSpec{
|
|
| 203 |
- Annotations: swarmtypes.Annotations{
|
|
| 204 |
- Name: secretName, |
|
| 202 |
+ secretResp, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 203 |
+ Spec: swarmtypes.SecretSpec{
|
|
| 204 |
+ Annotations: swarmtypes.Annotations{
|
|
| 205 |
+ Name: secretName, |
|
| 206 |
+ }, |
|
| 207 |
+ Data: []byte("TESTSECRET"),
|
|
| 205 | 208 |
}, |
| 206 |
- Data: []byte("TESTSECRET"),
|
|
| 207 | 209 |
}) |
| 208 | 210 |
assert.NilError(t, err) |
| 209 | 211 |
|
| ... | ... |
@@ -242,7 +244,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) {
|
| 242 | 242 |
assert.NilError(t, err) |
| 243 | 243 |
poll.WaitOn(t, swarm.NoTasksForService(ctx, apiClient, serviceID), swarm.ServicePoll) |
| 244 | 244 |
|
| 245 |
- err = apiClient.SecretRemove(ctx, secretName) |
|
| 245 |
+ _, err = apiClient.SecretRemove(ctx, secretName, client.SecretRemoveOptions{})
|
|
| 246 | 246 |
assert.NilError(t, err) |
| 247 | 247 |
} |
| 248 | 248 |
|
| ... | ... |
@@ -83,11 +83,13 @@ func TestServiceUpdateSecrets(t *testing.T) {
|
| 83 | 83 |
|
| 84 | 84 |
secretName := "TestSecret_" + t.Name() |
| 85 | 85 |
secretTarget := "targetName" |
| 86 |
- secretResp, err := apiClient.SecretCreate(ctx, swarmtypes.SecretSpec{
|
|
| 87 |
- Annotations: swarmtypes.Annotations{
|
|
| 88 |
- Name: secretName, |
|
| 86 |
+ secretResp, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
|
|
| 87 |
+ Spec: swarmtypes.SecretSpec{
|
|
| 88 |
+ Annotations: swarmtypes.Annotations{
|
|
| 89 |
+ Name: secretName, |
|
| 90 |
+ }, |
|
| 91 |
+ Data: []byte("TESTINGDATA"),
|
|
| 89 | 92 |
}, |
| 90 |
- Data: []byte("TESTINGDATA"),
|
|
| 91 | 93 |
}) |
| 92 | 94 |
assert.NilError(t, err) |
| 93 | 95 |
assert.Check(t, secretResp.ID != "") |
| 94 | 96 |
deleted file mode 100644 |
| ... | ... |
@@ -1,74 +0,0 @@ |
| 1 |
-package daemon |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "context" |
|
| 5 |
- "testing" |
|
| 6 |
- |
|
| 7 |
- "github.com/moby/moby/api/types/swarm" |
|
| 8 |
- "github.com/moby/moby/client" |
|
| 9 |
- "gotest.tools/v3/assert" |
|
| 10 |
-) |
|
| 11 |
- |
|
| 12 |
-// SecretConstructor defines a swarm secret constructor |
|
| 13 |
-type SecretConstructor func(*swarm.Secret) |
|
| 14 |
- |
|
| 15 |
-// CreateSecret creates a secret given the specified spec |
|
| 16 |
-func (d *Daemon) CreateSecret(t testing.TB, secretSpec swarm.SecretSpec) string {
|
|
| 17 |
- t.Helper() |
|
| 18 |
- cli := d.NewClientT(t) |
|
| 19 |
- defer cli.Close() |
|
| 20 |
- |
|
| 21 |
- scr, err := cli.SecretCreate(context.Background(), secretSpec) |
|
| 22 |
- assert.NilError(t, err) |
|
| 23 |
- |
|
| 24 |
- return scr.ID |
|
| 25 |
-} |
|
| 26 |
- |
|
| 27 |
-// ListSecrets returns the list of the current swarm secrets |
|
| 28 |
-func (d *Daemon) ListSecrets(t testing.TB) []swarm.Secret {
|
|
| 29 |
- t.Helper() |
|
| 30 |
- cli := d.NewClientT(t) |
|
| 31 |
- defer cli.Close() |
|
| 32 |
- |
|
| 33 |
- secrets, err := cli.SecretList(context.Background(), client.SecretListOptions{})
|
|
| 34 |
- assert.NilError(t, err) |
|
| 35 |
- return secrets |
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 |
-// GetSecret returns a swarm secret identified by the specified id |
|
| 39 |
-func (d *Daemon) GetSecret(t testing.TB, id string) *swarm.Secret {
|
|
| 40 |
- t.Helper() |
|
| 41 |
- cli := d.NewClientT(t) |
|
| 42 |
- defer cli.Close() |
|
| 43 |
- |
|
| 44 |
- secret, _, err := cli.SecretInspectWithRaw(context.Background(), id) |
|
| 45 |
- assert.NilError(t, err) |
|
| 46 |
- return &secret |
|
| 47 |
-} |
|
| 48 |
- |
|
| 49 |
-// DeleteSecret removes the swarm secret identified by the specified id |
|
| 50 |
-func (d *Daemon) DeleteSecret(t testing.TB, id string) {
|
|
| 51 |
- t.Helper() |
|
| 52 |
- cli := d.NewClientT(t) |
|
| 53 |
- defer cli.Close() |
|
| 54 |
- |
|
| 55 |
- err := cli.SecretRemove(context.Background(), id) |
|
| 56 |
- assert.NilError(t, err) |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-// UpdateSecret updates the swarm secret identified by the specified id |
|
| 60 |
-// Currently, only label update is supported. |
|
| 61 |
-func (d *Daemon) UpdateSecret(t testing.TB, id string, f ...SecretConstructor) {
|
|
| 62 |
- t.Helper() |
|
| 63 |
- cli := d.NewClientT(t) |
|
| 64 |
- defer cli.Close() |
|
| 65 |
- |
|
| 66 |
- secret := d.GetSecret(t, id) |
|
| 67 |
- for _, fn := range f {
|
|
| 68 |
- fn(secret) |
|
| 69 |
- } |
|
| 70 |
- |
|
| 71 |
- err := cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec) |
|
| 72 |
- |
|
| 73 |
- assert.NilError(t, err) |
|
| 74 |
-} |
| ... | ... |
@@ -203,11 +203,11 @@ type VolumeAPIClient interface {
|
| 203 | 203 |
|
| 204 | 204 |
// SecretAPIClient defines API client methods for secrets |
| 205 | 205 |
type SecretAPIClient interface {
|
| 206 |
- SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) |
|
| 207 |
- SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) |
|
| 208 |
- SecretRemove(ctx context.Context, id string) error |
|
| 209 |
- SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) |
|
| 210 |
- SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error |
|
| 206 |
+ SecretList(ctx context.Context, options SecretListOptions) (SecretListResult, error) |
|
| 207 |
+ SecretCreate(ctx context.Context, options SecretCreateOptions) (SecretCreateResult, error) |
|
| 208 |
+ SecretRemove(ctx context.Context, id string, options SecretRemoveOptions) (SecretRemoveResult, error) |
|
| 209 |
+ SecretInspect(ctx context.Context, id string, options SecretInspectOptions) (SecretInspectResult, error) |
|
| 210 |
+ SecretUpdate(ctx context.Context, id string, options SecretUpdateOptions) (SecretUpdateResult, error) |
|
| 211 | 211 |
} |
| 212 | 212 |
|
| 213 | 213 |
// ConfigAPIClient defines API client methods for configs |
| ... | ... |
@@ -7,15 +7,28 @@ import ( |
| 7 | 7 |
"github.com/moby/moby/api/types/swarm" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
+// SecretCreateOptions holds options for creating a secret. |
|
| 11 |
+type SecretCreateOptions struct {
|
|
| 12 |
+ Spec swarm.SecretSpec |
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// SecretCreateResult holds the result from the [Client.SecretCreate] method. |
|
| 16 |
+type SecretCreateResult struct {
|
|
| 17 |
+ ID string |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 10 | 20 |
// SecretCreate creates a new secret. |
| 11 |
-func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) {
|
|
| 12 |
- resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil) |
|
| 21 |
+func (cli *Client) SecretCreate(ctx context.Context, options SecretCreateOptions) (SecretCreateResult, error) {
|
|
| 22 |
+ resp, err := cli.post(ctx, "/secrets/create", nil, options.Spec, nil) |
|
| 13 | 23 |
defer ensureReaderClosed(resp) |
| 14 | 24 |
if err != nil {
|
| 15 |
- return swarm.SecretCreateResponse{}, err
|
|
| 25 |
+ return SecretCreateResult{}, err
|
|
| 16 | 26 |
} |
| 17 | 27 |
|
| 18 |
- var response swarm.SecretCreateResponse |
|
| 19 |
- err = json.NewDecoder(resp.Body).Decode(&response) |
|
| 20 |
- return response, err |
|
| 28 |
+ var out swarm.ConfigCreateResponse |
|
| 29 |
+ err = json.NewDecoder(resp.Body).Decode(&out) |
|
| 30 |
+ if err != nil {
|
|
| 31 |
+ return SecretCreateResult{}, err
|
|
| 32 |
+ } |
|
| 33 |
+ return SecretCreateResult{ID: out.ID}, nil
|
|
| 21 | 34 |
} |
| ... | ... |
@@ -1,34 +1,35 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "bytes" |
|
| 5 | 4 |
"context" |
| 6 |
- "encoding/json" |
|
| 7 |
- "io" |
|
| 8 | 5 |
|
| 9 | 6 |
"github.com/moby/moby/api/types/swarm" |
| 10 | 7 |
) |
| 11 | 8 |
|
| 12 |
-// SecretInspectWithRaw returns the secret information with raw data |
|
| 13 |
-func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
|
|
| 9 |
+// SecretInspectOptions holds options for inspecting a secret. |
|
| 10 |
+type SecretInspectOptions struct {
|
|
| 11 |
+ // Add future optional parameters here |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// SecretInspectResult holds the result from the [Client.SecretInspect]. method. |
|
| 15 |
+type SecretInspectResult struct {
|
|
| 16 |
+ Secret swarm.Secret |
|
| 17 |
+ Raw []byte |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+// SecretInspect returns the secret information with raw data. |
|
| 21 |
+func (cli *Client) SecretInspect(ctx context.Context, id string, options SecretInspectOptions) (SecretInspectResult, error) {
|
|
| 14 | 22 |
id, err := trimID("secret", id)
|
| 15 | 23 |
if err != nil {
|
| 16 |
- return swarm.Secret{}, nil, err
|
|
| 24 |
+ return SecretInspectResult{}, err
|
|
| 17 | 25 |
} |
| 18 | 26 |
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil) |
| 19 | 27 |
defer ensureReaderClosed(resp) |
| 20 | 28 |
if err != nil {
|
| 21 |
- return swarm.Secret{}, nil, err
|
|
| 29 |
+ return SecretInspectResult{}, err
|
|
| 22 | 30 |
} |
| 23 | 31 |
|
| 24 |
- body, err := io.ReadAll(resp.Body) |
|
| 25 |
- if err != nil {
|
|
| 26 |
- return swarm.Secret{}, nil, err
|
|
| 27 |
- } |
|
| 28 |
- |
|
| 29 |
- var secret swarm.Secret |
|
| 30 |
- rdr := bytes.NewReader(body) |
|
| 31 |
- err = json.NewDecoder(rdr).Decode(&secret) |
|
| 32 |
- |
|
| 33 |
- return secret, body, err |
|
| 32 |
+ var out SecretInspectResult |
|
| 33 |
+ out.Raw, err = decodeWithRaw(resp, &out.Secret) |
|
| 34 |
+ return out, err |
|
| 34 | 35 |
} |
| ... | ... |
@@ -8,18 +8,31 @@ import ( |
| 8 | 8 |
"github.com/moby/moby/api/types/swarm" |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 |
+// SecretListOptions holds parameters to list secrets |
|
| 12 |
+type SecretListOptions struct {
|
|
| 13 |
+ Filters Filters |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+// SecretListResult holds the result from the [client.SecretList] method. |
|
| 17 |
+type SecretListResult struct {
|
|
| 18 |
+ Items []swarm.Secret |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 11 | 21 |
// SecretList returns the list of secrets. |
| 12 |
-func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
|
|
| 22 |
+func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) (SecretListResult, error) {
|
|
| 13 | 23 |
query := url.Values{}
|
| 14 |
- |
|
| 15 | 24 |
options.Filters.updateURLValues(query) |
| 25 |
+ |
|
| 16 | 26 |
resp, err := cli.get(ctx, "/secrets", query, nil) |
| 17 | 27 |
defer ensureReaderClosed(resp) |
| 18 | 28 |
if err != nil {
|
| 19 |
- return nil, err |
|
| 29 |
+ return SecretListResult{}, err
|
|
| 20 | 30 |
} |
| 21 | 31 |
|
| 22 |
- var secrets []swarm.Secret |
|
| 23 |
- err = json.NewDecoder(resp.Body).Decode(&secrets) |
|
| 24 |
- return secrets, err |
|
| 32 |
+ var out SecretListResult |
|
| 33 |
+ err = json.NewDecoder(resp.Body).Decode(&out.Items) |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ return SecretListResult{}, err
|
|
| 36 |
+ } |
|
| 37 |
+ return out, nil |
|
| 25 | 38 |
} |
| ... | ... |
@@ -2,13 +2,24 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import "context" |
| 4 | 4 |
|
| 5 |
+type SecretRemoveOptions struct {
|
|
| 6 |
+ // Add future optional parameters here |
|
| 7 |
+} |
|
| 8 |
+ |
|
| 9 |
+type SecretRemoveResult struct {
|
|
| 10 |
+ // Add future fields here |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 5 | 13 |
// SecretRemove removes a secret. |
| 6 |
-func (cli *Client) SecretRemove(ctx context.Context, id string) error {
|
|
| 14 |
+func (cli *Client) SecretRemove(ctx context.Context, id string, options SecretRemoveOptions) (SecretRemoveResult, error) {
|
|
| 7 | 15 |
id, err := trimID("secret", id)
|
| 8 | 16 |
if err != nil {
|
| 9 |
- return err |
|
| 17 |
+ return SecretRemoveResult{}, err
|
|
| 10 | 18 |
} |
| 11 | 19 |
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil) |
| 12 | 20 |
defer ensureReaderClosed(resp) |
| 13 |
- return err |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return SecretRemoveResult{}, err
|
|
| 23 |
+ } |
|
| 24 |
+ return SecretRemoveResult{}, nil
|
|
| 14 | 25 |
} |
| ... | ... |
@@ -7,15 +7,26 @@ import ( |
| 7 | 7 |
"github.com/moby/moby/api/types/swarm" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
+// SecretUpdateOptions holds options for updating a secret. |
|
| 11 |
+type SecretUpdateOptions struct {
|
|
| 12 |
+ Version swarm.Version |
|
| 13 |
+ Spec swarm.SecretSpec |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+type SecretUpdateResult struct{}
|
|
| 17 |
+ |
|
| 10 | 18 |
// SecretUpdate attempts to update a secret. |
| 11 |
-func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
|
|
| 19 |
+func (cli *Client) SecretUpdate(ctx context.Context, id string, options SecretUpdateOptions) (SecretUpdateResult, error) {
|
|
| 12 | 20 |
id, err := trimID("secret", id)
|
| 13 | 21 |
if err != nil {
|
| 14 |
- return err |
|
| 22 |
+ return SecretUpdateResult{}, err
|
|
| 15 | 23 |
} |
| 16 | 24 |
query := url.Values{}
|
| 17 |
- query.Set("version", version.String())
|
|
| 18 |
- resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil) |
|
| 25 |
+ query.Set("version", options.Version.String())
|
|
| 26 |
+ resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, options.Spec, nil) |
|
| 19 | 27 |
defer ensureReaderClosed(resp) |
| 20 |
- return err |
|
| 28 |
+ if err != nil {
|
|
| 29 |
+ return SecretUpdateResult{}, err
|
|
| 30 |
+ } |
|
| 31 |
+ return SecretUpdateResult{}, nil
|
|
| 21 | 32 |
} |