Skip to content

Commit

Permalink
Merge pull request #15842 from ashley-cui/seclabels
Browse files Browse the repository at this point in the history
Add labels to secrets
  • Loading branch information
openshift-merge-robot authored Sep 21, 2022
2 parents fea3253 + 9bb51e8 commit ffa73c5
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 15 deletions.
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})
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[]"))

})
})

0 comments on commit ffa73c5

Please sign in to comment.