Skip to content

Commit

Permalink
Merge pull request #19011 from rhatdan/secret1
Browse files Browse the repository at this point in the history
Display secret to user in inspect
  • Loading branch information
openshift-merge-robot authored Jun 28, 2023
2 parents b2ce082 + bf60bb0 commit 455c7c8
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 14 deletions.
6 changes: 5 additions & 1 deletion cmd/podman/secrets/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Created at: {{.CreatedAt}}
Updated at: {{.UpdatedAt}}`
)

var inspectOpts = entities.SecretInspectOptions{}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: inspectCmd,
Expand All @@ -53,12 +55,14 @@ func init() {
flags.StringVarP(&format, formatFlagName, "f", "", "Format inspect output using Go template")
_ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.SecretInfoReport{}))

flags.BoolVar(&inspectOpts.ShowSecret, "showsecret", false, "Display the secret")

prettyFlagName := "pretty"
flags.BoolVar(&pretty, prettyFlagName, false, "Print inspect output in human-readable format")
}

func inspect(cmd *cobra.Command, args []string) error {
inspected, errs, _ := registry.ContainerEngine().SecretInspect(context.Background(), args)
inspected, errs, _ := registry.ContainerEngine().SecretInspect(context.Background(), args, inspectOpts)

// always print valid list
if len(inspected) == 0 {
Expand Down
5 changes: 5 additions & 0 deletions docs/source/markdown/podman-secret-inspect.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Format secret output using Go template.
|--------------------------|-------------------------------------------------------------------|
| .CreatedAt | When secret was created (relative timestamp, human-readable) |
| .ID | ID of secret |
| .SecretData | Secret Data (Displayed only with --showsecret option) |
| .Spec ... | Details of secret |
| .Spec.Driver | Driver info |
| .Spec.Driver.Name | Driver name (string) |
Expand All @@ -39,12 +40,16 @@ Print usage statement.

Print inspect output in human-readable format

#### **--showsecret**

Display secret data

## EXAMPLES

```
$ podman secret inspect mysecret
$ podman secret inspect --format "{{.Name} {{.Scope}}" mysecret
$ podman secret inspect --showsecret --format "{{.Name} {{.SecretData}}" mysecret
```

## SEE ALSO
Expand Down
1 change: 1 addition & 0 deletions docs/source/markdown/podman-secret-ls.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Valid placeholders for the Go template are listed below:
| ------------------------ | ----------------------------------------------------------------- |
| .CreatedAt | When secret was created (relative timestamp, human-readable) |
| .ID | ID of secret |
| .SecretData | Secret Data (Displayed only with --showsecret option) |
| .Spec ... | Details of secret |
| .Spec.Driver | Driver info |
| .Spec.Driver.Name | Driver name (string) |
Expand Down
17 changes: 16 additions & 1 deletion pkg/api/handlers/compat/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema"
)

func ListSecrets(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -51,11 +52,25 @@ func ListSecrets(w http.ResponseWriter, r *http.Request) {
}

func InspectSecret(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
name := utils.GetName(r)
names := []string{name}
query := struct {
ShowSecret bool `schema:"showsecret"`
}{
// override any golang type defaults
}

if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return
}
ic := abi.ContainerEngine{Libpod: runtime}
reports, errs, err := ic.SecretInspect(r.Context(), names)
opts := entities.SecretInspectOptions{}
opts.ShowSecret = query.ShowSecret

reports, errs, err := ic.SecretInspect(r.Context(), names, opts)
if err != nil {
utils.InternalServerError(w, err)
return
Expand Down
5 changes: 5 additions & 0 deletions pkg/api/server/register_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error {
// type: string
// required: true
// description: the name or ID of the secret
// - in: query
// name: showsecret
// type: boolean
// description: Display Secret
// default: false
// produces:
// - application/json
// responses:
Expand Down
10 changes: 8 additions & 2 deletions pkg/bindings/secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,25 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.SecretInfoRepo

// Inspect returns low-level information about a secret.
func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*entities.SecretInfoReport, error) {
if options == nil {
options = new(InspectOptions)
}
var (
inspect *entities.SecretInfoReport
)
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/secrets/%s/json", nil, nil, nameOrID)
params, err := options.ToParams()
if err != nil {
return nil, err
}
response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/secrets/%s/json", params, nil, nameOrID)
if err != nil {
return inspect, err
}
defer response.Body.Close()

return inspect, response.Process(&inspect)
}

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 @@ -11,6 +11,7 @@ type ListOptions struct {
//
//go:generate go run ../generator/generator.go InspectOptions
type InspectOptions struct {
ShowSecret *bool
}

// RemoveOptions are optional options for removing secrets
Expand Down
15 changes: 15 additions & 0 deletions pkg/bindings/secrets/types_inspect_options.go

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

2 changes: 1 addition & 1 deletion pkg/domain/entities/engine_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type ContainerEngine interface { //nolint:interfacebloat
PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
SetupRootless(ctx context.Context, noMoveProcess bool) error
SecretCreate(ctx context.Context, name string, reader io.Reader, options SecretCreateOptions) (*SecretCreateReport, error)
SecretInspect(ctx context.Context, nameOrIDs []string) ([]*SecretInfoReport, []error, error)
SecretInspect(ctx context.Context, nameOrIDs []string, options SecretInspectOptions) ([]*SecretInfoReport, []error, error)
SecretList(ctx context.Context, opts SecretListRequest) ([]*SecretInfoReport, error)
SecretRm(ctx context.Context, nameOrID []string, opts SecretRmOptions) ([]*SecretRmReport, error)
SecretExists(ctx context.Context, nameOrID string) (*BoolReport, error)
Expand Down
13 changes: 9 additions & 4 deletions pkg/domain/entities/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ type SecretCreateOptions struct {
Labels map[string]string
}

type SecretInspectOptions struct {
ShowSecret bool
}

type SecretListRequest struct {
Filters map[string][]string
}
Expand All @@ -38,10 +42,11 @@ type SecretRmReport struct {
}

type SecretInfoReport struct {
ID string
CreatedAt time.Time
UpdatedAt time.Time
Spec SecretSpec
ID string
CreatedAt time.Time
UpdatedAt time.Time
Spec SecretSpec
SecretData string `json:"SecretData,omitempty"`
}

type SecretInfoReportCompat struct {
Expand Down
13 changes: 11 additions & 2 deletions pkg/domain/infra/abi/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,23 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
}, nil
}

func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string) ([]*entities.SecretInfoReport, []error, error) {
func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string, options entities.SecretInspectOptions) ([]*entities.SecretInfoReport, []error, error) {
var (
secret *secrets.Secret
data []byte
)
manager, err := ic.Libpod.SecretsManager()
if err != nil {
return nil, nil, err
}
errs := make([]error, 0, len(nameOrIDs))
reports := make([]*entities.SecretInfoReport, 0, len(nameOrIDs))
for _, nameOrID := range nameOrIDs {
secret, err := manager.Lookup(nameOrID)
if options.ShowSecret {
secret, data, err = manager.LookupSecretData(nameOrID)
} else {
secret, err = manager.Lookup(nameOrID)
}
if err != nil {
if strings.Contains(err.Error(), "no such secret") {
errs = append(errs, err)
Expand All @@ -90,6 +98,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string
},
Labels: secret.Labels,
},
SecretData: string(data),
}
reports = append(reports, report)
}
Expand Down
7 changes: 5 additions & 2 deletions pkg/domain/infra/tunnel/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
return created, nil
}

func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string) ([]*entities.SecretInfoReport, []error, error) {
func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string, options entities.SecretInspectOptions) ([]*entities.SecretInfoReport, []error, error) {
allInspect := make([]*entities.SecretInfoReport, 0, len(nameOrIDs))
errs := make([]error, 0, len(nameOrIDs))
opts := new(secrets.InspectOptions).
WithShowSecret(options.ShowSecret)

for _, name := range nameOrIDs {
inspected, err := secrets.Inspect(ic.ClientCtx, name, nil)
inspected, err := secrets.Inspect(ic.ClientCtx, name, opts)
if err != nil {
errModel, ok := err.(*errorhandling.ErrorModel)
if !ok {
Expand Down
14 changes: 13 additions & 1 deletion test/e2e/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"path/filepath"

. "github.com/containers/podman/v4/test/utils"
"github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
Expand Down Expand Up @@ -48,8 +49,9 @@ var _ = Describe("Podman secret", func() {
})

It("podman secret inspect", func() {
random := stringid.GenerateRandomID()
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755)
err := os.WriteFile(secretFilePath, []byte(random), 0755)
Expect(err).ToNot(HaveOccurred())

session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath})
Expand All @@ -61,6 +63,16 @@ var _ = Describe("Podman secret", func() {
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(BeValidJSON())

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

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

It("podman secret inspect with --format", func() {
Expand Down

0 comments on commit 455c7c8

Please sign in to comment.