@@ -7,31 +7,21 @@ import (
77 "strings"
88
99 "github.com/platform-mesh/golang-commons/logger"
10- apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
11- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1210
1311 "k8s.io/apimachinery/pkg/api/meta"
14- "k8s.io/apimachinery/pkg/runtime/schema"
1512 "k8s.io/client-go/discovery"
1613 "k8s.io/client-go/openapi"
1714 "k8s.io/kube-openapi/pkg/validation/spec"
1815)
1916
2017var (
21- ErrInvalidPath = errors .New ("path doesn't contain the / separator" )
22- ErrNotPreferred = errors .New ("path ApiGroup does not belong to the server preferred APIs" )
23- ErrGVKNotPreferred = errors .New ("failed to find CRD GVK in API preferred resources" )
24- ErrGetServerPreferred = errors .New ("failed to get server preferred resources" )
25- ErrFilterPreferredResources = errors .New ("failed to filter server preferred resources" )
26- ErrGetSchemaForPath = errors .New ("failed to get schema for path" )
27- ErrUnmarshalSchemaForPath = errors .New ("failed to unmarshal schema for path" )
18+ ErrInvalidPath = errors .New ("path doesn't contain the / separator" )
19+ ErrNotPreferred = errors .New ("path ApiGroup does not belong to the server preferred APIs" )
20+ ErrGetServerPreferred = errors .New ("failed to get server preferred resources" )
21+ ErrGetSchemaForPath = errors .New ("failed to get schema for path" )
22+ ErrUnmarshalSchemaForPath = errors .New ("failed to unmarshal schema for path" )
2823)
2924
30- type GroupKindVersions struct {
31- * metav1.GroupKind
32- Versions []string
33- }
34-
3525type CRDResolver struct {
3626 discovery.DiscoveryInterface
3727 meta.RESTMapper
@@ -51,126 +41,6 @@ func (cr *CRDResolver) Resolve(dc discovery.DiscoveryInterface, rm meta.RESTMapp
5141 return cr .resolveSchema (dc , rm )
5242}
5343
54- func (cr * CRDResolver ) ResolveApiSchema (crd * apiextensionsv1.CustomResourceDefinition ) ([]byte , error ) {
55- gkv := getCRDGroupKindVersions (crd .Spec )
56-
57- apiResLists , err := cr .ServerPreferredResources ()
58- if err != nil {
59- cr .log .Error ().Err (err ).
60- Str ("crdName" , crd .Name ).
61- Str ("group" , gkv .Group ).
62- Str ("kind" , gkv .Kind ).
63- Msg ("failed to get server preferred resources" )
64- return nil , errors .Join (ErrGetServerPreferred , err )
65- }
66-
67- preferredApiGroups , err := cr .errorIfCRDNotInPreferredApiGroups (gkv , apiResLists )
68- if err != nil {
69- cr .log .Error ().Err (err ).
70- Str ("crdName" , crd .Name ).
71- Str ("group" , gkv .Group ).
72- Str ("kind" , gkv .Kind ).
73- Msg ("failed to filter preferred resources" )
74- return nil , errors .Join (ErrFilterPreferredResources , err )
75- }
76-
77- result , err := NewSchemaBuilder (cr .OpenAPIV3 (), preferredApiGroups , cr .log ).
78- WithScope (cr .RESTMapper ).
79- WithPreferredVersions (apiResLists ).
80- WithCRDCategories (crd ).
81- WithRelationships ().
82- Complete ()
83-
84- if err != nil {
85- cr .log .Error ().Err (err ).
86- Str ("crdName" , crd .Name ).
87- Int ("preferredApiGroupsCount" , len (preferredApiGroups )).
88- Msg ("failed to complete schema building" )
89- return nil , err
90- }
91-
92- cr .log .Debug ().
93- Str ("crdName" , crd .Name ).
94- Str ("group" , gkv .Group ).
95- Str ("kind" , gkv .Kind ).
96- Msg ("successfully resolved API schema" )
97-
98- return result , nil
99- }
100-
101- func (cr * CRDResolver ) errorIfCRDNotInPreferredApiGroups (gkv * GroupKindVersions , apiResLists []* metav1.APIResourceList ) ([]string , error ) {
102- isKindFound := false
103- preferredApiGroups := make ([]string , 0 , len (apiResLists ))
104-
105- for _ , apiResources := range apiResLists {
106- gv , err := schema .ParseGroupVersion (apiResources .GroupVersion )
107- if err != nil {
108- cr .log .Error ().Err (err ).
109- Str ("groupVersion" , apiResources .GroupVersion ).
110- Str ("targetGroup" , gkv .Group ).
111- Str ("targetKind" , gkv .Kind ).
112- Msg ("failed to parse group version" )
113- continue
114- }
115-
116- isGroupFound := gkv .Group == gv .Group
117- isVersionFound := slices .Contains (gkv .Versions , gv .Version )
118-
119- if isGroupFound && isVersionFound && ! isKindFound {
120- isKindFound = isCRDKindIncluded (gkv , apiResources )
121- cr .log .Debug ().
122- Str ("groupVersion" , apiResources .GroupVersion ).
123- Str ("targetGroup" , gkv .Group ).
124- Str ("targetKind" , gkv .Kind ).
125- Bool ("kindFound" , isKindFound ).
126- Msg ("checking if CRD kind is included in preferred APIs" )
127- }
128-
129- preferredApiGroups = append (preferredApiGroups , apiResources .GroupVersion )
130- }
131-
132- if ! isKindFound {
133- cr .log .Warn ().
134- Str ("group" , gkv .Group ).
135- Str ("kind" , gkv .Kind ).
136- Strs ("versions" , gkv .Versions ).
137- Int ("checkedApiGroups" , len (preferredApiGroups )).
138- Msg ("CRD kind not found in preferred API resources" )
139- return nil , ErrGVKNotPreferred
140- }
141-
142- cr .log .Debug ().
143- Str ("group" , gkv .Group ).
144- Str ("kind" , gkv .Kind ).
145- Int ("preferredApiGroupsCount" , len (preferredApiGroups )).
146- Msg ("successfully found CRD in preferred API groups" )
147-
148- return preferredApiGroups , nil
149- }
150-
151- func isCRDKindIncluded (gvk * GroupKindVersions , apiResources * metav1.APIResourceList ) bool {
152- for _ , res := range apiResources .APIResources {
153- if res .Kind == gvk .Kind {
154- return true
155- }
156- }
157- return false
158- }
159-
160- func getCRDGroupKindVersions (spec apiextensionsv1.CustomResourceDefinitionSpec ) * GroupKindVersions {
161- versions := make ([]string , 0 , len (spec .Versions ))
162- for _ , v := range spec .Versions {
163- versions = append (versions , v .Name )
164- }
165- return & GroupKindVersions {
166- GroupKind : & metav1.GroupKind {
167- Group : spec .Group ,
168- Kind : spec .Names .Kind ,
169- },
170- Versions : versions ,
171- }
172- }
173-
17444func getSchemaForPath (preferredApiGroups []string , path string , gv openapi.GroupVersion ) (map [string ]* spec.Schema , error ) {
17545 if ! strings .Contains (path , separator ) {
17646 return nil , ErrInvalidPath
0 commit comments