Merge pull request #15842 from ashley-cui/seclabels

Add labels to secrets
This commit is contained in:
OpenShift Merge Robot
2022-09-21 13:15:28 +02:00
committed by GitHub
12 changed files with 103 additions and 15 deletions

View File

@ -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"
@ -31,6 +32,7 @@ var (
var (
createOpts = entities.SecretCreateOptions{}
env = false
labels []string
)
func init() {
@ -38,21 +40,24 @@ func init() {
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 {
@ -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

View File

@ -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
```

View File

@ -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)

View File

@ -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
}
@ -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)

View File

@ -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

View File

@ -22,4 +22,5 @@ type CreateOptions struct {
Name *string
Driver *string
DriverOpts map[string]string
Labels map[string]string
}

View File

@ -61,3 +61,18 @@ func (o *CreateOptions) GetDriverOpts() map[string]string {
}
return o.DriverOpts
}
// WithLabels set field Labels to given value
func (o *CreateOptions) WithLabels(value map[string]string) *CreateOptions {
o.Labels = value
return o
}
// GetLabels returns value of field Labels
func (o *CreateOptions) GetLabels() map[string]string {
if o.Labels == nil {
var z map[string]string
return z
}
return o.Labels
}

View File

@ -13,6 +13,7 @@ type SecretCreateReport struct {
type SecretCreateOptions struct {
Driver string
DriverOpts map[string]string
Labels map[string]string
}
type SecretListRequest struct {
@ -55,6 +56,7 @@ type SecretVersion struct {
type SecretSpec struct {
Name string
Driver SecretDriverSpec
Labels map[string]string
}
type SecretDriverSpec struct {
@ -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

View File

@ -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)
@ -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,
@ -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)

View File

@ -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

View File

@ -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
@ -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

View File

@ -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[]"))
})
})