mirror of
https://github.com/lxc/incus.git
synced 2026-02-05 09:46:19 +01:00
Merge pull request #2015 from rahafjrw/filter_incus_project_list
Add server-side filtering for `incus project list`
This commit is contained in:
@@ -44,6 +44,26 @@ func (r *ProtocolIncus) GetProjects() ([]api.Project, error) {
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetProjectsWithFilter returns a filtered list of projects as Project structs.
|
||||
func (r *ProtocolIncus) GetProjectsWithFilter(filters []string) ([]api.Project, error) {
|
||||
if !r.HasExtension("projects") {
|
||||
return nil, fmt.Errorf("The server is missing the required \"projects\" API extension")
|
||||
}
|
||||
|
||||
projects := []api.Project{}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("recursion", "1")
|
||||
v.Set("filter", parseFilters(filters))
|
||||
|
||||
_, err := r.queryStruct("GET", fmt.Sprintf("/projects?%s", v.Encode()), nil, "", &projects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetProject returns a Project entry for the provided name.
|
||||
func (r *ProtocolIncus) GetProject(name string) (*api.Project, string, error) {
|
||||
if !r.HasExtension("projects") {
|
||||
|
||||
@@ -305,6 +305,7 @@ type InstanceServer interface {
|
||||
// Project functions
|
||||
GetProjectNames() (names []string, err error)
|
||||
GetProjects() (projects []api.Project, err error)
|
||||
GetProjectsWithFilter(filters []string) (projects []api.Project, err error)
|
||||
GetProject(name string) (project *api.Project, ETag string, err error)
|
||||
GetProjectState(name string) (project *api.ProjectState, err error)
|
||||
GetProjectAccess(name string) (access api.Access, err error)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -523,7 +524,7 @@ type cmdProjectList struct {
|
||||
// Command returns a cobra.Command for use with (*cobra.Command).AddCommand.
|
||||
func (c *cmdProjectList) Command() *cobra.Command {
|
||||
cmd := &cobra.Command{}
|
||||
cmd.Use = usage("list", i18n.G("[<remote>:]"))
|
||||
cmd.Use = usage("list", i18n.G("[<remote>:] [<filter>...]"))
|
||||
cmd.Aliases = []string{"ls"}
|
||||
cmd.Short = i18n.G("List projects")
|
||||
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
|
||||
@@ -692,8 +693,16 @@ func (c *cmdProjectList) Run(cmd *cobra.Command, args []string) error {
|
||||
|
||||
resource := resources[0]
|
||||
|
||||
// Process the filters
|
||||
filters := []string{}
|
||||
if len(args) > 1 {
|
||||
filters = append(filters, args[1:]...)
|
||||
}
|
||||
|
||||
filters = prepareProjectServerFilters(filters, api.Project{})
|
||||
|
||||
// List projects
|
||||
projects, err := resource.server.GetProjects()
|
||||
projects, err := resource.server.GetProjectsWithFilter(filters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1231,3 +1240,36 @@ func (c *cmdProjectGetCurrent) Run(cmd *cobra.Command, args []string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareProjectServerFilter processes and formats filter criteria
|
||||
// for projects, ensuring they are in a format that the server can interpret.
|
||||
func prepareProjectServerFilters(filters []string, i any) []string {
|
||||
formattedFilters := []string{}
|
||||
|
||||
for _, filter := range filters {
|
||||
membs := strings.SplitN(filter, "=", 2)
|
||||
key := membs[0]
|
||||
|
||||
if len(membs) == 1 {
|
||||
regexpValue := key
|
||||
if !strings.Contains(key, "^") && !strings.Contains(key, "$") {
|
||||
regexpValue = "^" + regexpValue + "$"
|
||||
}
|
||||
|
||||
filter = fmt.Sprintf("name=(%s|^%s.*)", regexpValue, key)
|
||||
} else {
|
||||
firstPart := key
|
||||
if strings.Contains(key, ".") {
|
||||
firstPart = strings.Split(key, ".")[0]
|
||||
}
|
||||
|
||||
if !structHasField(reflect.TypeOf(i), firstPart) {
|
||||
filter = fmt.Sprintf("config.%s", filter)
|
||||
}
|
||||
}
|
||||
|
||||
formattedFilters = append(formattedFilters, filter)
|
||||
}
|
||||
|
||||
return formattedFilters
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user