Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add labels to secrets #15842

Merged
merged 1 commit into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions cmd/podman/secrets/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/parse"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/spf13/cobra"
Expand All @@ -31,28 +32,32 @@ var (
var (
createOpts = entities.SecretCreateOptions{}
env = false
labels []string
)

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: createCmd,
Parent: secretCmd,
})
cfg := registry.PodmanConfig()

flags := createCmd.Flags()

driverFlagName := "driver"
optsFlagName := "driver-opts"

cfg := registry.PodmanConfig()

flags.StringVarP(&createOpts.Driver, driverFlagName, "d", cfg.Secrets.Driver, "Specify secret driver")
flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options")
_ = createCmd.RegisterFlagCompletionFunc(driverFlagName, completion.AutocompleteNone)

optsFlagName := "driver-opts"
flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options")
_ = createCmd.RegisterFlagCompletionFunc(optsFlagName, completion.AutocompleteNone)

envFlagName := "env"
flags.BoolVar(&env, envFlagName, false, "Read secret data from environment variable")

labelFlagName := "label"
flags.StringArrayVarP(&labels, labelFlagName, "l", nil, "Specify labels on the secret")
_ = createCmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
}

func create(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -87,6 +92,11 @@ func create(cmd *cobra.Command, args []string) error {
reader = file
}

createOpts.Labels, err = parse.GetAllLabels([]string{}, labels)
if err != nil {
return fmt.Errorf("unable to process labels: %w", err)
}

report, err := registry.ContainerEngine().SecretCreate(context.Background(), name, reader, createOpts)
if err != nil {
return err
Expand Down
8 changes: 6 additions & 2 deletions docs/source/markdown/podman-secret-create.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ Specify the secret driver (default **file**, which is unencrypted).

#### **--driver-opts**=*key1=val1,key2=val2*

Specify driver specific options
Specify driver specific options.

#### **--env**=*false*

Read secret data from environment variable
Read secret data from environment variable.

#### **--help**

Print usage statement.

#### **--label**, **-l**=*key=val1,key2=val2*

Add label to secret. These labels can be viewed in podman secrete inspect or ls.

## EXAMPLES

```
Expand Down
5 changes: 1 addition & 4 deletions pkg/api/handlers/compat/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,11 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("Decode(): %w", err))
return
}
if len(createParams.Labels) > 0 {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("labels not supported: %w", errors.New("bad parameter")))
return
}

decoded, _ := base64.StdEncoding.DecodeString(createParams.Data)
reader := bytes.NewReader(decoded)
opts.Driver = createParams.Driver.Name
opts.Labels = createParams.Labels

ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.SecretCreate(r.Context(), createParams.Name, reader, opts)
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/handlers/libpod/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) {
Name string `schema:"name"`
Driver string `schema:"driver"`
DriverOpts map[string]string `schema:"driveropts"`
Labels map[string]string `schema:"labels"`
}{
// override any golang type defaults
}
Expand All @@ -33,6 +34,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) {

opts.Driver = query.Driver
opts.DriverOpts = query.DriverOpts
opts.Labels = query.Labels

ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.SecretCreate(r.Context(), query.Name, r.Body, opts)
Expand Down
8 changes: 8 additions & 0 deletions pkg/api/server/register_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error {
// type: string
// description: Secret driver
// default: "file"
// - in: query
// name: driveropts
// type: string
// description: Secret driver options
// - in: query
// name: labels
// type: string
// description: Labels on the secret
// - in: body
// name: request
// description: Secret
Expand Down
1 change: 1 addition & 0 deletions pkg/bindings/secrets/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ type CreateOptions struct {
Name *string
Driver *string
DriverOpts map[string]string
Labels map[string]string
}
15 changes: 15 additions & 0 deletions pkg/bindings/secrets/types_create_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/domain/entities/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type SecretCreateReport struct {
type SecretCreateOptions struct {
Driver string
DriverOpts map[string]string
Labels map[string]string
}

type SecretListRequest struct {
Expand Down Expand Up @@ -55,6 +56,7 @@ type SecretVersion struct {
type SecretSpec struct {
Name string
Driver SecretDriverSpec
Labels map[string]string
}

type SecretDriverSpec struct {
Expand All @@ -70,6 +72,8 @@ type SecretCreateRequest struct {
Data string
// Driver represents a driver (default "file")
Driver SecretDriverSpec
// Labels are labels on the secret
Labels map[string]string
}

// Secret create response
Expand Down
5 changes: 5 additions & 0 deletions pkg/domain/infra/abi/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader

storeOpts := secrets.StoreOptions{
DriverOpts: options.DriverOpts,
Labels: options.Labels,
}

secretID, err := manager.Store(name, data, options.Driver, storeOpts)
Expand Down Expand Up @@ -74,6 +75,9 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string
return nil, nil, fmt.Errorf("inspecting secret %s: %w", nameOrID, err)
}
}
if secret.Labels == nil {
secret.Labels = make(map[string]string)
}
report := &entities.SecretInfoReport{
ID: secret.ID,
CreatedAt: secret.CreatedAt,
Expand All @@ -84,6 +88,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string
Name: secret.Driver,
Options: secret.DriverOptions,
},
Labels: secret.Labels,
},
}
reports = append(reports, report)
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/infra/tunnel/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
opts := new(secrets.CreateOptions).
WithDriver(options.Driver).
WithDriverOpts(options.DriverOpts).
WithName(name)
WithName(name).
WithLabels(options.Labels)
created, err := secrets.Create(ic.ClientCtx, reader, opts)
if err != nil {
return nil, err
Expand Down
10 changes: 7 additions & 3 deletions test/apiv2/50-secrets.at
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
t POST secrets/create Name=mysecret Data=c2VjcmV0 200\
.ID~.* \

# secret create unsupported labels
t POST secrets/create Name=mysecret Data=c2VjcmV0 Labels='{"fail":"fail"}' 400

# secret create name already in use
t POST secrets/create Name=mysecret Data=c2VjcmV0 409

Expand Down Expand Up @@ -59,8 +56,15 @@ t GET libpod/secrets/json?filters='garb1age}' 500 \
t GET libpod/secrets/json?filters='{"label":["testl' 500 \
.cause="unexpected end of JSON input"

# secret with labels
t POST secrets/create Name=labeledsecret Data=c2VjcmV0 Labels='{"foo":"bar"}' 200
t GET secrets/labeledsecret 200 \
.Spec.Labels.foo=bar

# secret rm
t DELETE secrets/mysecret 204
t DELETE secrets/labeledsecret 204

# secret rm non-existent secret
t DELETE secrets/bogus 404

Expand Down
37 changes: 37 additions & 0 deletions test/e2e/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,41 @@ var _ = Describe("Podman secret", func() {
Expect(inspect.OutputToString()).To(Equal(secrID))
})

It("podman secret with labels", func() {
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755)
Expect(err).To(BeNil())

session := podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "a", secretFilePath})
ashley-cui marked this conversation as resolved.
Show resolved Hide resolved
session.WaitWithDefaultTimeout()
secrID := session.OutputToString()
Expect(session).Should(Exit(0))

inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar"))

session = podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "--label", "a:b", "b", secretFilePath})
session.WaitWithDefaultTimeout()
secrID = session.OutputToString()
Expect(session).Should(Exit(0))

inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar"))
Expect(inspect.OutputToString()).To(ContainSubstring("a:b"))

session = podmanTest.Podman([]string{"secret", "create", "c", secretFilePath})
session.WaitWithDefaultTimeout()
secrID = session.OutputToString()
Expect(session).Should(Exit(0))

inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(Equal("map[]"))

})
})