diff options
author | Jakub Guzik <jakubmguzik@gmail.com> | 2021-09-02 23:01:37 +0200 |
---|---|---|
committer | Jakub Guzik <jakubmguzik@gmail.com> | 2021-09-03 10:29:31 +0200 |
commit | d346e6e734dbaac911de0d774a5d8703e2abc83d (patch) | |
tree | 0bd5ac510effcc97b70341b6a719cbfcfbc058bc /pkg | |
parent | 469900406ac51332785455bc8668bd1c053badd6 (diff) | |
download | podman-d346e6e734dbaac911de0d774a5d8703e2abc83d.tar.gz podman-d346e6e734dbaac911de0d774a5d8703e2abc83d.tar.bz2 podman-d346e6e734dbaac911de0d774a5d8703e2abc83d.zip |
Add filtering functionality to http api secrets list
Filtering is missing in both compat API and libpod API, while docker
has filtering functinality. This commit enables filtering option using
name and id in both libpod and http API.
Signed-off-by: Jakub Guzik <jakubmguzik@gmail.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/secrets.go | 22 | ||||
-rw-r--r-- | pkg/api/server/register_secrets.go | 16 | ||||
-rw-r--r-- | pkg/bindings/secrets/secrets.go | 6 | ||||
-rw-r--r-- | pkg/bindings/secrets/types.go | 1 | ||||
-rw-r--r-- | pkg/bindings/secrets/types_list_options.go | 16 | ||||
-rw-r--r-- | pkg/domain/entities/engine_container.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/secrets.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/secrets.go | 31 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/secrets.go | 5 | ||||
-rw-r--r-- | pkg/domain/utils/secrets_filters.go | 24 |
10 files changed, 94 insertions, 31 deletions
diff --git a/pkg/api/handlers/compat/secrets.go b/pkg/api/handlers/compat/secrets.go index 86e3887a4..7dd17ea94 100644 --- a/pkg/api/handlers/compat/secrets.go +++ b/pkg/api/handlers/compat/secrets.go @@ -11,31 +11,25 @@ import ( "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/infra/abi" - "github.com/gorilla/schema" + "github.com/containers/podman/v3/pkg/util" "github.com/pkg/errors" ) func ListSecrets(w http.ResponseWriter, r *http.Request) { var ( runtime = r.Context().Value("runtime").(*libpod.Runtime) - decoder = r.Context().Value("decoder").(*schema.Decoder) ) - query := struct { - Filters map[string][]string `schema:"filters"` - }{} - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + filtersMap, err := util.PrepareFilters(r) + if err != nil { + utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } - if len(query.Filters) > 0 { - utils.Error(w, "filters not supported", http.StatusBadRequest, - errors.Wrapf(errors.New("bad parameter"), "filters not supported")) - return - } ic := abi.ContainerEngine{Libpod: runtime} - reports, err := ic.SecretList(r.Context()) + listOptions := entities.SecretListRequest{ + Filters: *filtersMap, + } + reports, err := ic.SecretList(r.Context(), listOptions) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index ca9790e93..129912179 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -44,6 +44,14 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - secrets // summary: List secrets // description: Returns a list of secrets + // parameters: + // - in: query + // name: filters + // type: string + // description: | + // JSON encoded value of the filters (a `map[string][]string`) to process on the secrets list. Currently available filters: + // - `name=[name]` Matches secrets name (accepts regex). + // - `id=[id]` Matches for full or partial ID. // produces: // - application/json // parameters: @@ -110,6 +118,14 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - secrets (compat) // summary: List secrets // description: Returns a list of secrets + // parameters: + // - in: query + // name: filters + // type: string + // description: | + // JSON encoded value of the filters (a `map[string][]string`) to process on the secrets list. Currently available filters: + // - `name=[name]` Matches secrets name (accepts regex). + // - `id=[id]` Matches for full or partial ID. // produces: // - application/json // parameters: diff --git a/pkg/bindings/secrets/secrets.go b/pkg/bindings/secrets/secrets.go index b741d3e5c..c439971c9 100644 --- a/pkg/bindings/secrets/secrets.go +++ b/pkg/bindings/secrets/secrets.go @@ -18,7 +18,11 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.SecretInfoRepo if err != nil { return nil, err } - response, err := conn.DoRequest(nil, http.MethodGet, "/secrets/json", nil, nil) + params, err := options.ToParams() + if err != nil { + return nil, err + } + response, err := conn.DoRequest(nil, http.MethodGet, "/secrets/json", params, nil) if err != nil { return secrs, err } diff --git a/pkg/bindings/secrets/types.go b/pkg/bindings/secrets/types.go index a64dea1b4..01c3c248d 100644 --- a/pkg/bindings/secrets/types.go +++ b/pkg/bindings/secrets/types.go @@ -3,6 +3,7 @@ package secrets //go:generate go run ../generator/generator.go ListOptions // ListOptions are optional options for inspecting secrets type ListOptions struct { + Filters map[string][]string } //go:generate go run ../generator/generator.go InspectOptions diff --git a/pkg/bindings/secrets/types_list_options.go b/pkg/bindings/secrets/types_list_options.go index 568e021a8..e4501dde8 100644 --- a/pkg/bindings/secrets/types_list_options.go +++ b/pkg/bindings/secrets/types_list_options.go @@ -19,3 +19,19 @@ func (o *ListOptions) Changed(fieldName string) bool { func (o *ListOptions) ToParams() (url.Values, error) { return util.ToParams(o) } + +// WithFilters +func (o *ListOptions) WithFilters(value map[string][]string) *ListOptions { + v := value + o.Filters = v + return o +} + +// GetFilters +func (o *ListOptions) GetFilters() map[string][]string { + var filters map[string][]string + if o.Filters == nil { + return filters + } + return o.Filters +} diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index bd011d309..d03e2f719 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -85,7 +85,7 @@ type ContainerEngine interface { 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) - SecretList(ctx context.Context) ([]*SecretInfoReport, error) + SecretList(ctx context.Context, opts SecretListRequest) ([]*SecretInfoReport, error) SecretRm(ctx context.Context, nameOrID []string, opts SecretRmOptions) ([]*SecretRmReport, error) Shutdown(ctx context.Context) SystemDf(ctx context.Context, options SystemDfOptions) (*SystemDfReport, error) diff --git a/pkg/domain/entities/secrets.go b/pkg/domain/entities/secrets.go index 56a1465b7..55b470d7b 100644 --- a/pkg/domain/entities/secrets.go +++ b/pkg/domain/entities/secrets.go @@ -16,7 +16,7 @@ type SecretCreateOptions struct { } type SecretListRequest struct { - Filters map[string]string + Filters map[string][]string } type SecretListReport struct { diff --git a/pkg/domain/infra/abi/secrets.go b/pkg/domain/infra/abi/secrets.go index 0bdb4ce60..2bf8eaae3 100644 --- a/pkg/domain/infra/abi/secrets.go +++ b/pkg/domain/infra/abi/secrets.go @@ -7,6 +7,7 @@ import ( "path/filepath" "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/pkg/domain/utils" "github.com/pkg/errors" ) @@ -84,7 +85,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string return reports, errs, nil } -func (ic *ContainerEngine) SecretList(ctx context.Context) ([]*entities.SecretInfoReport, error) { +func (ic *ContainerEngine) SecretList(ctx context.Context, opts entities.SecretListRequest) ([]*entities.SecretInfoReport, error) { manager, err := ic.Libpod.SecretsManager() if err != nil { return nil, err @@ -95,19 +96,25 @@ func (ic *ContainerEngine) SecretList(ctx context.Context) ([]*entities.SecretIn } report := make([]*entities.SecretInfoReport, 0, len(secretList)) for _, secret := range secretList { - reportItem := entities.SecretInfoReport{ - ID: secret.ID, - CreatedAt: secret.CreatedAt, - UpdatedAt: secret.CreatedAt, - Spec: entities.SecretSpec{ - Name: secret.Name, - Driver: entities.SecretDriverSpec{ - Name: secret.Driver, - Options: secret.DriverOptions, + result, err := utils.IfPassesSecretsFilter(secret, opts.Filters) + if err != nil { + return nil, err + } + if result { + reportItem := entities.SecretInfoReport{ + ID: secret.ID, + CreatedAt: secret.CreatedAt, + UpdatedAt: secret.CreatedAt, + Spec: entities.SecretSpec{ + Name: secret.Name, + Driver: entities.SecretDriverSpec{ + Name: secret.Driver, + Options: secret.DriverOptions, + }, }, - }, + } + report = append(report, &reportItem) } - report = append(report, &reportItem) } return report, nil } diff --git a/pkg/domain/infra/tunnel/secrets.go b/pkg/domain/infra/tunnel/secrets.go index ecbb80931..6337c7fbe 100644 --- a/pkg/domain/infra/tunnel/secrets.go +++ b/pkg/domain/infra/tunnel/secrets.go @@ -43,8 +43,9 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string return allInspect, errs, nil } -func (ic *ContainerEngine) SecretList(ctx context.Context) ([]*entities.SecretInfoReport, error) { - secrs, _ := secrets.List(ic.ClientCtx, nil) +func (ic *ContainerEngine) SecretList(ctx context.Context, opts entities.SecretListRequest) ([]*entities.SecretInfoReport, error) { + options := new(secrets.ListOptions).WithFilters(opts.Filters) + secrs, _ := secrets.List(ic.ClientCtx, options) return secrs, nil } diff --git a/pkg/domain/utils/secrets_filters.go b/pkg/domain/utils/secrets_filters.go new file mode 100644 index 000000000..3ff7c7530 --- /dev/null +++ b/pkg/domain/utils/secrets_filters.go @@ -0,0 +1,24 @@ +package utils + +import ( + "strings" + + "github.com/containers/common/pkg/secrets" + "github.com/containers/podman/v3/pkg/util" + "github.com/pkg/errors" +) + +func IfPassesSecretsFilter(s secrets.Secret, filters map[string][]string) (bool, error) { + result := true + for key, filterValues := range filters { + switch strings.ToLower(key) { + case "name": + result = util.StringMatchRegexSlice(s.Name, filterValues) + case "id": + result = util.StringMatchRegexSlice(s.ID, filterValues) + default: + return false, errors.Errorf("invalid filter %q", key) + } + } + return result, nil +} |