@@ -12,6 +12,7 @@ import (
1212 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1313
1414 "k8s.io/apimachinery/pkg/api/meta"
15+ "k8s.io/apimachinery/pkg/runtime/schema"
1516 "k8s.io/client-go/discovery"
1617 "k8s.io/client-go/openapi"
1718 "k8s.io/kube-openapi/pkg/validation/spec"
2324 ErrGVKNotPreferred = errors .New ("failed to find CRD GVK in API preferred resources" )
2425)
2526
27+ type GroupKindVersions struct {
28+ * metav1.GroupKind
29+ Versions []string
30+ }
31+
2632type CRDResolver struct {
2733 * discovery.DiscoveryClient
2834 meta.RESTMapper
@@ -33,44 +39,44 @@ func (cr *CRDResolver) Resolve() ([]byte, error) {
3339}
3440
3541func (cr * CRDResolver ) ResolveApiSchema (crd * apiextensionsv1.CustomResourceDefinition ) ([]byte , error ) {
36- gvk , err := getCRDGroupVersionKind (crd .Spec )
37- if err != nil {
38- return nil , fmt .Errorf ("failed to get CRD GVK: %w" , err )
39- }
42+ gkv := getCRDGroupKindVersions (crd .Spec )
4043
4144 apiResLists , err := cr .ServerPreferredResources ()
4245 if err != nil {
4346 return nil , fmt .Errorf ("failed to get server preferred resources: %w" , err )
4447 }
4548
46- preferredApiGroups , err := errorIfCRDNotInPreferredApiGroups (gvk , apiResLists )
49+ preferredApiGroups , err := errorIfCRDNotInPreferredApiGroups (gkv , apiResLists )
4750 if err != nil {
4851 return nil , fmt .Errorf ("failed to filter server preferred resources: %w" , err )
4952 }
5053
5154 return resolveForPaths (cr .OpenAPIV3 (), preferredApiGroups , cr .RESTMapper )
5255}
5356
54- func errorIfCRDNotInPreferredApiGroups (gvk * metav1.GroupVersionKind , apiResLists []* metav1.APIResourceList ) ([]string , error ) {
55- targetGV := gvk .Group + "/" + gvk .Version
56- isGVFound := false
57+ func errorIfCRDNotInPreferredApiGroups (gkv * GroupKindVersions , apiResLists []* metav1.APIResourceList ) ([]string , error ) {
58+ isKindFound := false
5759 preferredApiGroups := make ([]string , 0 , len (apiResLists ))
5860 for _ , apiResources := range apiResLists {
59- gv := apiResources .GroupVersion
60- isGVFound = gv == targetGV
61- if isGVFound && ! isCRDKindIncluded (gvk , apiResources ) {
62- return nil , ErrGVKNotPreferred
61+ gv , err := schema .ParseGroupVersion (apiResources .GroupVersion )
62+ if err != nil {
63+ //TODO: debug log?
64+ continue
65+ }
66+ isGroupFound := gkv .Group == gv .Group
67+ isVersionFound := slices .Contains (gkv .Versions , gv .Version )
68+ if isGroupFound && isVersionFound && ! isKindFound {
69+ isKindFound = isCRDKindIncluded (gkv , apiResources )
6370 }
64- preferredApiGroups = append (preferredApiGroups , gv )
71+ preferredApiGroups = append (preferredApiGroups , apiResources . GroupVersion )
6572 }
66-
67- if ! isGVFound {
73+ if ! isKindFound {
6874 return nil , ErrGVKNotPreferred
6975 }
7076 return preferredApiGroups , nil
7177}
7278
73- func isCRDKindIncluded (gvk * metav1. GroupVersionKind , apiResources * metav1.APIResourceList ) bool {
79+ func isCRDKindIncluded (gvk * GroupKindVersions , apiResources * metav1.APIResourceList ) bool {
7480 for _ , res := range apiResources .APIResources {
7581 if res .Kind == gvk .Kind {
7682 return true
@@ -79,17 +85,18 @@ func isCRDKindIncluded(gvk *metav1.GroupVersionKind, apiResources *metav1.APIRes
7985 return false
8086}
8187
82- func getCRDGroupVersionKind (spec apiextensionsv1.CustomResourceDefinitionSpec ) (* metav1.GroupVersionKind , error ) {
88+ func getCRDGroupKindVersions (spec apiextensionsv1.CustomResourceDefinitionSpec ) * GroupKindVersions {
89+ versions := make ([]string , 0 , len (spec .Versions ))
8390 for _ , v := range spec .Versions {
84- if v .Storage {
85- return & metav1.GroupVersionKind {
86- Group : spec .Group ,
87- Version : v .Name ,
88- Kind : spec .Names .Kind ,
89- }, nil
90- }
91+ versions = append (versions , v .Name )
92+ }
93+ return & GroupKindVersions {
94+ GroupKind : & metav1.GroupKind {
95+ Group : spec .Group ,
96+ Kind : spec .Names .Kind ,
97+ },
98+ Versions : versions ,
9199 }
92- return nil , errors .New ("failed to find storage version" )
93100}
94101
95102func getSchemaForPath (preferredApiGroups []string , path string , gv openapi.GroupVersion ) (map [string ]* spec.Schema , error ) {
0 commit comments