Skip to content

Commit 8be24ba

Browse files
Bugfix: Listener: Do not use storage version as preferred server version for CRDs (#101)
* use server preferred version instead of storage version for CRDs * apply review suggestion: avoid string manipulations * ci: change action trigger * ci: trigger push event only on main branch * fix missing labelSelector schema --------- Co-authored-by: aaronschweig <[email protected]>
1 parent 5d5414a commit 8be24ba

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

.github/workflows/pipeline.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
name: ci
2-
on: [push]
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
types:
8+
- opened
9+
- synchronize
310

411
jobs:
512
pipe:

listener/apischema/crd_resolver.go

+32-25
Original file line numberDiff line numberDiff line change
@@ -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"
@@ -23,6 +24,11 @@ var (
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+
2632
type CRDResolver struct {
2733
*discovery.DiscoveryClient
2834
meta.RESTMapper
@@ -33,44 +39,44 @@ func (cr *CRDResolver) Resolve() ([]byte, error) {
3339
}
3440

3541
func (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

95102
func getSchemaForPath(preferredApiGroups []string, path string, gv openapi.GroupVersion) (map[string]*spec.Schema, error) {

listener/apischema/scope_resolver.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ type GroupVersionKind struct {
2222
}
2323

2424
func addScopeInfo(schemas map[string]*spec.Schema, rm meta.RESTMapper) (map[string]*spec.Schema, error) {
25-
scopedSchemas := make(map[string]*spec.Schema)
26-
for name, schema := range schemas {
25+
for _, schema := range schemas {
2726
//skip resources that do not have the GVK extension:
2827
//assumption: sub-resources do not have GVKs
2928
if schema.VendorExtensible.Extensions == nil {
30-
scopedSchemas[name] = schema
3129
continue
3230
}
3331
var gvksVal any
@@ -70,7 +68,6 @@ func addScopeInfo(schemas map[string]*spec.Schema, rm meta.RESTMapper) (map[stri
7068
schema.VendorExtensible.AddExtension(scopeExtensionKey, apiextensionsv1.ClusterScoped)
7169
}
7270

73-
scopedSchemas[name] = schema
7471
}
75-
return scopedSchemas, nil
72+
return schemas, nil
7673
}

0 commit comments

Comments
 (0)