@@ -3,6 +3,7 @@ package kube_janitor
33import (
44 "context"
55 "fmt"
6+ "slices"
67 "strings"
78 "time"
89
@@ -21,6 +22,93 @@ const (
2122 KubeSelectorNone = "<none>"
2223)
2324
25+ type (
26+ KubeServerGvrList []metav1.GroupVersionKind
27+ )
28+
29+ func (j * Janitor ) kubeDiscoverGVKs () (KubeServerGvrList , error ) {
30+ cacheKey := "kube.servergroups"
31+
32+ // from cache
33+ if val , ok := j .cache .Get (cacheKey ); ok {
34+ if v , ok := val .(KubeServerGvrList ); ok {
35+ return v , nil
36+ }
37+ }
38+
39+ ret := KubeServerGvrList {}
40+
41+ groupsResult , resourcesResult , err := j .kubeClient .Discovery ().ServerGroupsAndResources ()
42+ if err != nil {
43+ return nil , err
44+ }
45+
46+ // build GVK list
47+ for _ , serverGroup := range groupsResult {
48+ for _ , resourceGroup := range resourcesResult {
49+ if resourceGroup .GroupVersion == serverGroup .PreferredVersion .GroupVersion {
50+ for _ , resource := range resourceGroup .APIResources {
51+ if slices .Contains ([]string (resource .Verbs ), "list" ) && slices .Contains ([]string (resource .Verbs ), "delete" ) {
52+ ret = append (ret , metav1.GroupVersionKind {
53+ Group : serverGroup .Name ,
54+ Version : serverGroup .PreferredVersion .Version ,
55+ Kind : resource .Name ,
56+ })
57+ }
58+ }
59+ }
60+ }
61+ }
62+
63+ j .cache .SetDefault (cacheKey , ret )
64+
65+ return ret , nil
66+ }
67+
68+ func (j * Janitor ) kubeLookupGvrs (list ConfigResourceList ) (ConfigResourceList , error ) {
69+ var (
70+ gvrList KubeServerGvrList
71+ err error
72+ )
73+ ret := []* ConfigResource {}
74+
75+ for _ , resource := range list {
76+ if resource .Group == "*" || resource .Version == "*" || resource .Kind == "*" {
77+ // lookup possible types
78+ if gvrList == nil {
79+ gvrList , err = j .kubeDiscoverGVKs ()
80+ if err != nil {
81+ return nil , err
82+ }
83+ }
84+
85+ for _ , row := range gvrList {
86+ if resource .Group != "*" && ! strings .EqualFold (resource .Group , row .Group ) {
87+ continue
88+ }
89+ if resource .Version != "*" && ! strings .EqualFold (resource .Version , row .Version ) {
90+ continue
91+ }
92+ if resource .Kind != "*" && ! strings .EqualFold (resource .Kind , row .Kind ) {
93+ continue
94+ }
95+
96+ clone := resource .Clone ()
97+ clone .Group = row .Group
98+ clone .Version = row .Version
99+ clone .Kind = row .Kind
100+
101+ ret = append (ret , clone )
102+ }
103+ } else {
104+ // no lookup needed
105+ ret = append (ret , resource )
106+ }
107+ }
108+
109+ return ret , nil
110+ }
111+
24112func (j * Janitor ) kubeBuildLabelSelector (selector * metav1.LabelSelector ) (string , error ) {
25113 // no selector
26114 if selector == nil {
0 commit comments