added unit tests for package cli/command/secret

Signed-off-by: Arash Deshmeh <adeshmeh@ca.ibm.com>
This commit is contained in:
Arash Deshmeh 2017-04-01 03:07:22 -04:00
parent f6b7dc9837
commit 243a8e69ff
20 changed files with 694 additions and 8 deletions

View file

@ -0,0 +1,44 @@
package secret
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"golang.org/x/net/context"
)
type fakeClient struct {
client.Client
secretCreateFunc func(swarm.SecretSpec) (types.SecretCreateResponse, error)
secretInspectFunc func(string) (swarm.Secret, []byte, error)
secretListFunc func(types.SecretListOptions) ([]swarm.Secret, error)
secretRemoveFunc func(string) error
}
func (c *fakeClient) SecretCreate(ctx context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if c.secretCreateFunc != nil {
return c.secretCreateFunc(spec)
}
return types.SecretCreateResponse{}, nil
}
func (c *fakeClient) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
if c.secretInspectFunc != nil {
return c.secretInspectFunc(id)
}
return swarm.Secret{}, nil, nil
}
func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if c.secretListFunc != nil {
return c.secretListFunc(options)
}
return []swarm.Secret{}, nil
}
func (c *fakeClient) SecretRemove(ctx context.Context, name string) error {
if c.secretRemoveFunc != nil {
return c.secretRemoveFunc(name)
}
return nil
}

View file

@ -22,7 +22,7 @@ type createOptions struct {
labels opts.ListOpts
}
func newSecretCreateCommand(dockerCli *command.DockerCli) *cobra.Command {
func newSecretCreateCommand(dockerCli command.Cli) *cobra.Command {
createOpts := createOptions{
labels: opts.NewListOpts(opts.ValidateEnv),
}
@ -43,7 +43,7 @@ func newSecretCreateCommand(dockerCli *command.DockerCli) *cobra.Command {
return cmd
}
func runSecretCreate(dockerCli *command.DockerCli, options createOptions) error {
func runSecretCreate(dockerCli command.Cli, options createOptions) error {
client := dockerCli.Client()
ctx := context.Background()

View file

@ -0,0 +1,126 @@
package secret
import (
"bytes"
"io/ioutil"
"path/filepath"
"strings"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/cli/internal/test"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/docker/docker/pkg/testutil/golden"
"github.com/pkg/errors"
)
const secretDataFile = "secret-create-with-name.golden"
func TestSecretCreateErrors(t *testing.T) {
testCases := []struct {
args []string
secretCreateFunc func(swarm.SecretSpec) (types.SecretCreateResponse, error)
expectedError string
}{
{
args: []string{"too_few"},
expectedError: "requires exactly 2 argument(s)",
},
{args: []string{"too", "many", "arguments"},
expectedError: "requires exactly 2 argument(s)",
},
{
args: []string{"name", filepath.Join("testdata", secretDataFile)},
secretCreateFunc: func(secretSpec swarm.SecretSpec) (types.SecretCreateResponse, error) {
return types.SecretCreateResponse{}, errors.Errorf("error creating secret")
},
expectedError: "error creating secret",
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretCreateCommand(
test.NewFakeCli(&fakeClient{
secretCreateFunc: tc.secretCreateFunc,
}, buf),
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
func TestSecretCreateWithName(t *testing.T) {
name := "foo"
buf := new(bytes.Buffer)
var actual []byte
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
actual = spec.Data
return types.SecretCreateResponse{
ID: "ID-" + spec.Name,
}, nil
},
}, buf)
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", secretDataFile)})
assert.NilError(t, cmd.Execute())
expected := golden.Get(t, actual, secretDataFile)
assert.Equal(t, string(actual), string(expected))
assert.Equal(t, strings.TrimSpace(buf.String()), "ID-"+name)
}
func TestSecretCreateWithLabels(t *testing.T) {
expectedLabels := map[string]string{
"lbl1": "Label-foo",
"lbl2": "Label-bar",
}
name := "foo"
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
if !compareMap(spec.Labels, expectedLabels) {
return types.SecretCreateResponse{}, errors.Errorf("expected labels %v, got %v", expectedLabels, spec.Labels)
}
return types.SecretCreateResponse{
ID: "ID-" + spec.Name,
}, nil
},
}, buf)
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", secretDataFile)})
cmd.Flags().Set("label", "lbl1=Label-foo")
cmd.Flags().Set("label", "lbl2=Label-bar")
assert.NilError(t, cmd.Execute())
assert.Equal(t, strings.TrimSpace(buf.String()), "ID-"+name)
}
func compareMap(actual map[string]string, expected map[string]string) bool {
if len(actual) != len(expected) {
return false
}
for key, value := range actual {
if expectedValue, ok := expected[key]; ok {
if expectedValue != value {
return false
}
} else {
return false
}
}
return true
}

View file

@ -13,7 +13,7 @@ type inspectOptions struct {
format string
}
func newSecretInspectCommand(dockerCli *command.DockerCli) *cobra.Command {
func newSecretInspectCommand(dockerCli command.Cli) *cobra.Command {
opts := inspectOptions{}
cmd := &cobra.Command{
Use: "inspect [OPTIONS] SECRET [SECRET...]",
@ -29,7 +29,7 @@ func newSecretInspectCommand(dockerCli *command.DockerCli) *cobra.Command {
return cmd
}
func runSecretInspect(dockerCli *command.DockerCli, opts inspectOptions) error {
func runSecretInspect(dockerCli command.Cli, opts inspectOptions) error {
client := dockerCli.Client()
ctx := context.Background()

View file

@ -0,0 +1,149 @@
package secret
import (
"bytes"
"fmt"
"io/ioutil"
"testing"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/cli/internal/test"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/docker/cli/internal/test/builders"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/docker/docker/pkg/testutil/golden"
)
func TestSecretInspectErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
secretInspectFunc func(secretID string) (swarm.Secret, []byte, error)
expectedError string
}{
{
expectedError: "requires at least 1 argument",
},
{
args: []string{"foo"},
secretInspectFunc: func(secretID string) (swarm.Secret, []byte, error) {
return swarm.Secret{}, nil, errors.Errorf("error while inspecting the secret")
},
expectedError: "error while inspecting the secret",
},
{
args: []string{"foo"},
flags: map[string]string{
"format": "{{invalid format}}",
},
expectedError: "Template parsing error",
},
{
args: []string{"foo", "bar"},
secretInspectFunc: func(secretID string) (swarm.Secret, []byte, error) {
if secretID == "foo" {
return *Secret(SecretName("foo")), nil, nil
}
return swarm.Secret{}, nil, errors.Errorf("error while inspecting the secret")
},
expectedError: "error while inspecting the secret",
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretInspectCommand(
test.NewFakeCli(&fakeClient{
secretInspectFunc: tc.secretInspectFunc,
}, buf),
)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
func TestSecretInspectWithoutFormat(t *testing.T) {
testCases := []struct {
name string
args []string
secretInspectFunc func(secretID string) (swarm.Secret, []byte, error)
}{
{
name: "single-secret",
args: []string{"foo"},
secretInspectFunc: func(name string) (swarm.Secret, []byte, error) {
if name != "foo" {
return swarm.Secret{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
}
return *Secret(SecretID("ID-foo"), SecretName("foo")), nil, nil
},
},
{
name: "multiple-secrets-with-labels",
args: []string{"foo", "bar"},
secretInspectFunc: func(name string) (swarm.Secret, []byte, error) {
return *Secret(SecretID("ID-"+name), SecretName(name), SecretLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
},
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretInspectCommand(
test.NewFakeCli(&fakeClient{
secretInspectFunc: tc.secretInspectFunc,
}, buf),
)
cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), fmt.Sprintf("secret-inspect-without-format.%s.golden", tc.name))
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
}
func TestSecretInspectWithFormat(t *testing.T) {
secretInspectFunc := func(name string) (swarm.Secret, []byte, error) {
return *Secret(SecretName("foo"), SecretLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
}
testCases := []struct {
name string
format string
args []string
secretInspectFunc func(name string) (swarm.Secret, []byte, error)
}{
{
name: "simple-template",
format: "{{.Spec.Name}}",
args: []string{"foo"},
secretInspectFunc: secretInspectFunc,
},
{
name: "json-template",
format: "{{json .Spec.Labels}}",
args: []string{"foo"},
secretInspectFunc: secretInspectFunc,
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretInspectCommand(
test.NewFakeCli(&fakeClient{
secretInspectFunc: tc.secretInspectFunc,
}, buf),
)
cmd.SetArgs(tc.args)
cmd.Flags().Set("format", tc.format)
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
}

View file

@ -16,7 +16,7 @@ type listOptions struct {
filter opts.FilterOpt
}
func newSecretListCommand(dockerCli *command.DockerCli) *cobra.Command {
func newSecretListCommand(dockerCli command.Cli) *cobra.Command {
opts := listOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
@ -37,7 +37,7 @@ func newSecretListCommand(dockerCli *command.DockerCli) *cobra.Command {
return cmd
}
func runSecretList(dockerCli *command.DockerCli, opts listOptions) error {
func runSecretList(dockerCli command.Cli, opts listOptions) error {
client := dockerCli.Client()
ctx := context.Background()

View file

@ -0,0 +1,172 @@
package secret
import (
"bytes"
"io/ioutil"
"testing"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/cli/config/configfile"
"github.com/docker/docker/cli/internal/test"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/docker/cli/internal/test/builders"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/docker/docker/pkg/testutil/golden"
)
func TestSecretListErrors(t *testing.T) {
testCases := []struct {
args []string
secretListFunc func(types.SecretListOptions) ([]swarm.Secret, error)
expectedError string
}{
{
args: []string{"foo"},
expectedError: "accepts no argument",
},
{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{}, errors.Errorf("error listing secrets")
},
expectedError: "error listing secrets",
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretListCommand(
test.NewFakeCli(&fakeClient{
secretListFunc: tc.secretListFunc,
}, buf),
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
func TestSecretList(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"),
SecretName("foo"),
SecretVersion(swarm.Version{Index: 10}),
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*Secret(SecretID("ID-bar"),
SecretName("bar"),
SecretVersion(swarm.Version{Index: 11}),
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
),
}, nil
},
}, buf)
cli.SetConfigfile(&configfile.ConfigFile{})
cmd := newSecretListCommand(cli)
cmd.SetOutput(buf)
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), "secret-list.golden")
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
func TestSecretListWithQuietOption(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
"label": "label-bar",
})),
}, nil
},
}, buf)
cli.SetConfigfile(&configfile.ConfigFile{})
cmd := newSecretListCommand(cli)
cmd.Flags().Set("quiet", "true")
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), "secret-list-with-quiet-option.golden")
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
func TestSecretListWithConfigFormat(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
"label": "label-bar",
})),
}, nil
},
}, buf)
cli.SetConfigfile(&configfile.ConfigFile{
SecretFormat: "{{ .Name }} {{ .Labels }}",
})
cmd := newSecretListCommand(cli)
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), "secret-list-with-config-format.golden")
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
func TestSecretListWithFormat(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
"label": "label-bar",
})),
}, nil
},
}, buf)
cmd := newSecretListCommand(cli)
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), "secret-list-with-format.golden")
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}
func TestSecretListWithFilter(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
assert.Equal(t, options.Filters.Get("name")[0], "foo")
assert.Equal(t, options.Filters.Get("label")[0], "lbl1=Label-bar")
return []swarm.Secret{
*Secret(SecretID("ID-foo"),
SecretName("foo"),
SecretVersion(swarm.Version{Index: 10}),
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*Secret(SecretID("ID-bar"),
SecretName("bar"),
SecretVersion(swarm.Version{Index: 11}),
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
),
}, nil
},
}, buf)
cli.SetConfigfile(&configfile.ConfigFile{})
cmd := newSecretListCommand(cli)
cmd.Flags().Set("filter", "name=foo")
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
assert.NilError(t, cmd.Execute())
actual := buf.String()
expected := golden.Get(t, []byte(actual), "secret-list-with-filter.golden")
assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected))
}

View file

@ -15,7 +15,7 @@ type removeOptions struct {
names []string
}
func newSecretRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
func newSecretRemoveCommand(dockerCli command.Cli) *cobra.Command {
return &cobra.Command{
Use: "rm SECRET [SECRET...]",
Aliases: []string{"remove"},
@ -30,7 +30,7 @@ func newSecretRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
}
}
func runSecretRemove(dockerCli *command.DockerCli, opts removeOptions) error {
func runSecretRemove(dockerCli command.Cli, opts removeOptions) error {
client := dockerCli.Client()
ctx := context.Background()

View file

@ -0,0 +1,81 @@
package secret
import (
"bytes"
"io/ioutil"
"strings"
"testing"
"github.com/docker/docker/cli/internal/test"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/pkg/errors"
)
func TestSecretRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
secretRemoveFunc func(string) error
expectedError string
}{
{
args: []string{},
expectedError: "requires at least 1 argument(s).",
},
{
args: []string{"foo"},
secretRemoveFunc: func(name string) error {
return errors.Errorf("error removing secret")
},
expectedError: "error removing secret",
},
}
for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newSecretRemoveCommand(
test.NewFakeCli(&fakeClient{
secretRemoveFunc: tc.secretRemoveFunc,
}, buf),
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
func TestSecretRemoveWithName(t *testing.T) {
names := []string{"foo", "bar"}
buf := new(bytes.Buffer)
var removedSecrets []string
cli := test.NewFakeCli(&fakeClient{
secretRemoveFunc: func(name string) error {
removedSecrets = append(removedSecrets, name)
return nil
},
}, buf)
cmd := newSecretRemoveCommand(cli)
cmd.SetArgs(names)
assert.NilError(t, cmd.Execute())
assert.EqualStringSlice(t, strings.Split(strings.TrimSpace(buf.String()), "\n"), names)
assert.EqualStringSlice(t, removedSecrets, names)
}
func TestSecretRemoveContinueAfterError(t *testing.T) {
names := []string{"foo", "bar"}
buf := new(bytes.Buffer)
var removedSecrets []string
cli := test.NewFakeCli(&fakeClient{
secretRemoveFunc: func(name string) error {
removedSecrets = append(removedSecrets, name)
if name == "foo" {
return errors.Errorf("error removing secret: %s", name)
}
return nil
},
}, buf)
cmd := newSecretRemoveCommand(cli)
cmd.SetArgs(names)
assert.Error(t, cmd.Execute(), "error removing secret: foo")
assert.EqualStringSlice(t, removedSecrets, names)
}

View file

@ -0,0 +1 @@
secret_foo_bar

View file

@ -0,0 +1 @@
{"label1":"label-foo"}

View file

@ -0,0 +1 @@
foo

View file

@ -0,0 +1,26 @@
[
{
"ID": "ID-foo",
"Version": {},
"CreatedAt": "0001-01-01T00:00:00Z",
"UpdatedAt": "0001-01-01T00:00:00Z",
"Spec": {
"Name": "foo",
"Labels": {
"label1": "label-foo"
}
}
},
{
"ID": "ID-bar",
"Version": {},
"CreatedAt": "0001-01-01T00:00:00Z",
"UpdatedAt": "0001-01-01T00:00:00Z",
"Spec": {
"Name": "bar",
"Labels": {
"label1": "label-foo"
}
}
}
]

View file

@ -0,0 +1,12 @@
[
{
"ID": "ID-foo",
"Version": {},
"CreatedAt": "0001-01-01T00:00:00Z",
"UpdatedAt": "0001-01-01T00:00:00Z",
"Spec": {
"Name": "foo",
"Labels": null
}
}
]

View file

@ -0,0 +1,2 @@
foo
bar label=label-bar

View file

@ -0,0 +1,3 @@
ID NAME CREATED UPDATED
ID-foo foo 2 hours ago About an hour ago
ID-bar bar 2 hours ago About an hour ago

View file

@ -0,0 +1,2 @@
foo
bar label=label-bar

View file

@ -0,0 +1,2 @@
ID-foo
ID-bar

View file

@ -0,0 +1,3 @@
ID NAME CREATED UPDATED
ID-foo foo 2 hours ago About an hour ago
ID-bar bar 2 hours ago About an hour ago

View file

@ -0,0 +1,61 @@
package builders
import (
"time"
"github.com/docker/docker/api/types/swarm"
)
// Secret creates a secret with default values.
// Any number of secret builder functions can be passed to augment it.
func Secret(builders ...func(secret *swarm.Secret)) *swarm.Secret {
secret := &swarm.Secret{}
for _, builder := range builders {
builder(secret)
}
return secret
}
// SecretLabels sets the secret's labels
func SecretLabels(labels map[string]string) func(secret *swarm.Secret) {
return func(secret *swarm.Secret) {
secret.Spec.Labels = labels
}
}
// SecretName sets the secret's name
func SecretName(name string) func(secret *swarm.Secret) {
return func(secret *swarm.Secret) {
secret.Spec.Name = name
}
}
// SecretID sets the secret's ID
func SecretID(ID string) func(secret *swarm.Secret) {
return func(secret *swarm.Secret) {
secret.ID = ID
}
}
// SecretVersion sets the version for the secret
func SecretVersion(v swarm.Version) func(*swarm.Secret) {
return func(secret *swarm.Secret) {
secret.Version = v
}
}
// SecretCreatedAt sets the creation time for the secret
func SecretCreatedAt(t time.Time) func(*swarm.Secret) {
return func(secret *swarm.Secret) {
secret.CreatedAt = t
}
}
// SecretUpdatedAt sets the update time for the secret
func SecretUpdatedAt(t time.Time) func(*swarm.Secret) {
return func(secret *swarm.Secret) {
secret.UpdatedAt = t
}
}