Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions cmd/harbor/root/project/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ func ListProjectCommand() *cobra.Command {
allProjects []*models.Project
err error
// For querying, opts.Q
fuzzy []string
match []string
ranges []string
fuzzy []string
match []string
ranges []string
and []string
or []string
validKeys = []string{"name", "project_id", "public", "creation_time", "owner_id"}
)

cmd := &cobra.Command{
Use: "list",
Short: "List projects",
Expand Down Expand Up @@ -72,9 +76,7 @@ func ListProjectCommand() *cobra.Command {
}

if len(fuzzy) != 0 || len(match) != 0 || len(ranges) != 0 { // Only Building Query if a param exists
q, qErr := utils.BuildQueryParam(fuzzy, match, ranges,
[]string{"name", "project_id", "public", "creation_time", "owner_id"},
)
q, qErr := utils.BuildQueryParam(fuzzy, match, ranges, validKeys)
if qErr != nil {
return qErr
}
Expand Down Expand Up @@ -108,16 +110,23 @@ func ListProjectCommand() *cobra.Command {
},
}

// Adding Query Description
var qDesc string
if cmd.Long != "" {
qDesc = "\n\n" + utils.GenerateQueryDocs(validKeys)
} else {
qDesc = utils.GenerateQueryDocs(validKeys)
}
cmd.Long += qDesc

flags := cmd.Flags()
flags.StringVarP(&opts.Name, "name", "", "", "Name of the project")
flags.Int64VarP(&opts.Page, "page", "", 1, "Page number")
flags.Int64VarP(&opts.PageSize, "page-size", "", 0, "Size of per page (0 to fetch all)")
flags.BoolVarP(&private, "private", "", false, "Show only private projects")
flags.BoolVarP(&public, "public", "", false, "Show only public projects")
flags.StringVarP(&opts.Sort, "sort", "", "", "Sort the resource list in ascending or descending order")
flags.StringSliceVar(&fuzzy, "fuzzy", nil, "Fuzzy match filter (key=value)")
flags.StringSliceVar(&match, "match", nil, "exact match filter (key=value)")
flags.StringSliceVar(&ranges, "range", nil, "range filter (key=min~max)")
utils.SetQueryFlags(flags, &match, &fuzzy, &ranges, &and, &or) // Adds the 5 query flags

return cmd
}
Expand Down
51 changes: 51 additions & 0 deletions pkg/utils/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package utils
import (
"fmt"
"strings"

"github.com/spf13/pflag"
)

// Builds the `q` param for List API's
Expand Down Expand Up @@ -73,6 +75,55 @@ func BuildQueryParam(fuzzy, match, ranges []string, validKeys []string) (string,
return strings.Join(parts, ","), nil
}

func GenerateQueryDocs(validKeys []string) string {
keys := strings.Join(validKeys, ", ")

doc := fmt.Sprintf(`
Query Filters

The following flags can be used to filter results.

Supported query types:

--exact key=value
Match an exact value.

--fuzzy key=value
Perform a fuzzy match (partial match).

--range key=min:max
Match values within a range.

--all key=v1,v2
Match resources that contain ALL specified values.

--any key=v1,v2
Match resources that contain ANY of the specified values.

Examples:

--exact project_id=12
--fuzzy name=test
--range update_time=2024-01-01:2024-02-01
--any tag=v1,v2
--all label=prod,stable

Valid keys for this command:

%s
`, keys)

return strings.TrimSpace(doc)
}

func SetQueryFlags(f *pflag.FlagSet, match, fuzzy, ranges, and, or *[]string) {
f.StringSliceVar(fuzzy, "fuzzy", nil, "Fuzzy match filter (key=value)")
f.StringSliceVar(match, "match", nil, "exact match filter (key=value)")
f.StringSliceVar(ranges, "range", nil, "range filter (key=min~max)")
f.StringSliceVar(and, "all", nil, "match-all filter (key=v1,v2,v3)")
f.StringSliceVar(or, "any", nil, "match-any filter (key=v1,v2,v3)")
}

// Validates Key provided by user for ListFlags.Q
func validateKey(key string, validKeys []string) error {
found := false
Expand Down
Loading