Skip to content

Commit

Permalink
Merge pull request #131 from ninech/allow-to-list-specific-resources
Browse files Browse the repository at this point in the history
allow to list only certain resource types
  • Loading branch information
thirdeyenick committed Jul 23, 2024
2 parents c29ba6a + 2daaa85 commit 5e997cd
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 21 deletions.
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
}
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

0 comments on commit 5e997cd

Please sign in to comment.