mirror of
https://github.com/containers/podman.git
synced 2025-05-21 00:56:36 +08:00
Merge pull request #15842 from ashley-cui/seclabels
Add labels to secrets
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
||||
```
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -22,4 +22,5 @@ type CreateOptions struct {
|
||||
Name *string
|
||||
Driver *string
|
||||
DriverOpts map[string]string
|
||||
Labels map[string]string
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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[]"))
|
||||
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user