Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to list only certain resource types #131

Merged
merged 1 commit into from
Jul 23, 2024
Merged
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
35 changes: 30 additions & 5 deletions get/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (
type allCmd struct {
out io.Writer
stdErr io.Writer
IncludeNineResources bool `help:"show resources which are owned by Nine" default:"false"`
Kinds []string `help:"specify the kind of resources which should be listed"`
IncludeNineResources bool `help:"show resources which are owned by Nine" default:"false"`
}

func (cmd *allCmd) Run(ctx context.Context, client *api.Client, get *Cmd) error {
Expand All @@ -35,7 +36,7 @@ func (cmd *allCmd) Run(ctx context.Context, client *api.Client, get *Cmd) error
return err
}

items, warnings, err := getProjectContent(ctx, client, projectNames(projectList), cmd.IncludeNineResources)
items, warnings, err := cmd.getProjectContent(ctx, client, projectNames(projectList))
if err != nil {
return err
}
Expand Down Expand Up @@ -70,11 +71,15 @@ func projectNames(projects []management.Project) []string {
return result
}

func getProjectContent(ctx context.Context, client *api.Client, projNames []string, includeNineOwned bool) ([]*unstructured.Unstructured, []string, error) {
func (cmd *allCmd) getProjectContent(ctx context.Context, client *api.Client, projNames []string) ([]*unstructured.Unstructured, []string, error) {
var warnings []string
var result []*unstructured.Unstructured
listTypes, err := filteredListTypes(client.Scheme(), cmd.Kinds)
if err != nil {
return nil, nil, err
}
for _, project := range projNames {
for _, listType := range nineListTypes(client.Scheme()) {
for _, listType := range listTypes {
u := &unstructured.UnstructuredList{}
u.SetGroupVersionKind(listType)
// if we get any errors during the listing of certain
Expand All @@ -89,7 +94,7 @@ func getProjectContent(ctx context.Context, client *api.Client, projNames []stri
// filter nine owned resources if needed
for _, item := range u.Items {
item := item
if includeNineOwned {
if cmd.IncludeNineResources {
result = append(result, &item)
continue
}
Expand Down Expand Up @@ -134,6 +139,26 @@ func printItems(items []*unstructured.Unstructured, get Cmd, out io.Writer, head
return w.Flush()
}

func filteredListTypes(s *runtime.Scheme, kinds []string) ([]schema.GroupVersionKind, error) {
result := []schema.GroupVersionKind{}
lists := nineListTypes(s)
if len(kinds) == 0 {
return lists, nil
}
OUTER:
for _, kind := range kinds {
for _, list := range lists {
if !strings.EqualFold(kind+"list", list.GroupKind().Kind) {
continue
}
result = append(result, list)
continue OUTER
thirdeyenick marked this conversation as resolved.
Show resolved Hide resolved
}
return []schema.GroupVersionKind{}, fmt.Errorf("kind %s does not seem to be part of any nine.ch API", kind)
}
return result, nil
}

func nineListTypes(s *runtime.Scheme) []schema.GroupVersionKind {
var lists []schema.GroupVersionKind
for gvk := range s.AllKnownTypes() {
Expand Down
78 changes: 62 additions & 16 deletions get/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ func TestAllContent(t *testing.T) {
outputFormat output
allProjects bool
includeNineResources bool
kinds []string
output string
errorExpected bool
}{
"all resources from one project, full format": {
projects: test.Projects(organization, "dev", "staging", "prod"),
Expand Down Expand Up @@ -64,32 +66,32 @@ dev pear Release apps.nine.ch
objects: []client.Object{
testApplication("banana", "dev"), testRelease("pear", "dev"),
testApplication("apple", "staging"), testRelease("melon", "staging"),
testCluster("organge", "prod"),
testCluster("orange", "prod"),
},
outputFormat: full,
allProjects: true,
output: `PROJECT NAME KIND GROUP
dev banana Application apps.nine.ch
dev pear Release apps.nine.ch
prod organge KubernetesCluster infrastructure.nine.ch
staging apple Application apps.nine.ch
staging melon Release apps.nine.ch
output: `PROJECT NAME KIND GROUP
dev banana Application apps.nine.ch
dev pear Release apps.nine.ch
prod orange KubernetesCluster infrastructure.nine.ch
staging apple Application apps.nine.ch
staging melon Release apps.nine.ch
`,
},
"all projects, no headers format": {
projects: test.Projects(organization, "dev", "staging", "prod"),
objects: []client.Object{
testApplication("banana", "dev"), testRelease("pear", "dev"),
testApplication("apple", "staging"), testRelease("melon", "staging"),
testCluster("organge", "prod"),
testCluster("orange", "prod"),
},
outputFormat: noHeader,
allProjects: true,
output: `dev banana Application apps.nine.ch
dev pear Release apps.nine.ch
prod organge KubernetesCluster infrastructure.nine.ch
staging apple Application apps.nine.ch
staging melon Release apps.nine.ch
output: `dev banana Application apps.nine.ch
dev pear Release apps.nine.ch
prod orange KubernetesCluster infrastructure.nine.ch
staging apple Application apps.nine.ch
staging melon Release apps.nine.ch
`,
},
"empty resources of a specific project, full format": {
Expand Down Expand Up @@ -156,6 +158,47 @@ staging cherry Release apps.nine.ch
staging melon Release apps.nine.ch
`,
},
"only certain kind": {
projects: test.Projects(organization, "dev", "staging", "prod"),
objects: []client.Object{
testApplication("banana", "dev"), testRelease("pear", "dev"),
testApplication("apple", "staging"), testRelease("melon", "staging"), testRelease("cherry", "staging"),
testCluster("orange", "prod"),
},
outputFormat: full,
allProjects: true,
kinds: []string{"application"},
output: `PROJECT NAME KIND GROUP
dev banana Application apps.nine.ch
staging apple Application apps.nine.ch
`,
},
"multiple certain kinds, no header format": {
projects: test.Projects(organization, "dev", "staging", "prod"),
objects: []client.Object{
testApplication("banana", "dev"), testRelease("pear", "dev"),
testApplication("apple", "staging"), testRelease("melon", "staging"), testRelease("cherry", "staging"),
testCluster("orange", "prod"),
testCluster("dragonfruit", "dev"),
},
outputFormat: noHeader,
allProjects: true,
kinds: []string{"release", "kubernetescluster"},
output: `dev dragonfruit KubernetesCluster infrastructure.nine.ch
dev pear Release apps.nine.ch
prod orange KubernetesCluster infrastructure.nine.ch
staging cherry Release apps.nine.ch
staging melon Release apps.nine.ch
`,
},
"not known kind leads to an error": {
projects: test.Projects(organization, "dev", "staging", "prod"),
objects: []client.Object{},
outputFormat: noHeader,
allProjects: true,
kinds: []string{"jackofalltrades"},
errorExpected: true,
},
} {
t.Run(name, func(t *testing.T) {
testCase := testCase
Expand Down Expand Up @@ -186,12 +229,15 @@ staging melon Release apps.nine.ch
cmd := allCmd{
out: outputBuffer,
IncludeNineResources: testCase.includeNineResources,
Kinds: testCase.kinds,
}

if err := cmd.Run(ctx, apiClient, get); err != nil {
t.Fatal(err)
err = cmd.Run(ctx, apiClient, get)
if testCase.errorExpected {
require.Error(t, err)
return
}

require.NoError(t, err)
assert.Equal(t, testCase.output, outputBuffer.String())
})
}
Expand Down