Skip to content

Commit

Permalink
Fix CRD handling in WaitForCRDs (#251)
Browse files Browse the repository at this point in the history
Signed-off-by: Alena Varkockova <[email protected]>
  • Loading branch information
alenkacz authored Nov 3, 2020
1 parent 35c874a commit e310360
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 28 deletions.
1 change: 1 addition & 0 deletions pkg/test/harness_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestHarnessRunIntegration(t *testing.T) {
"./test_data/",
},
StartControlPlane: true,
CRDDir: "./test_crds/",
},
T: t,
}
Expand Down
45 changes: 45 additions & 0 deletions pkg/test/test_crds/ourcrds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
creationTimestamp: null
name: ourcrds.kuttl.dev
spec:
group: kuttl.dev
names:
kind: Ourcrd
listKind: OurcrdList
plural: ourcrds
singular: ourcrds
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: Ourcrd is the Schema for the ourcrds API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: OurcrdSpec defines the desired state of Ourcrd.
type: object
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
56 changes: 38 additions & 18 deletions pkg/test/utils/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,10 @@ func NewPod(name, namespace string) runtime.Object {
// NewCRDv1 creates a new CRD object of version v1
func NewCRDv1(t *testing.T, name, group, resourceKind string, resourceVersions []string) runtime.Object {
crdVersions := []interface{}{}
served := true
for _, v := range resourceVersions {
crdVersions = append(crdVersions, interface{}(map[string]interface{}{"name": interface{}(v)}))
crdVersions = append(crdVersions, interface{}(map[string]interface{}{"name": interface{}(v), "served": interface{}(served)}))
served = false
}
return WithSpec(t, NewResource("apiextensions.k8s.io/v1", "CustomResourceDefinition", name, ""), map[string]interface{}{
"versions": crdVersions,
Expand Down Expand Up @@ -1280,25 +1282,43 @@ func ExtractGVKFromCRD(crds []runtime.Object) ([]schema.GroupVersionKind, error)
Kind: crd.Spec.Names.Kind,
})
case *unstructured.Unstructured:
spec, err := crd.Object["spec"].(map[string]interface{})
if err {
return nil, fmt.Errorf("the following unstructured object does not cast to a map: %v", crdObj)
// as a temporary fix until this whole method will be removed the code is inspired by controller-runtime implementation
// see https://github.com/kubernetes-sigs/controller-runtime/blame/f52b6180d515bca5f8faa551c3784fee5ce89a83/pkg/envtest/crd.go#L118
crdGroup, _, err := unstructured.NestedString(crd.Object, "spec", "group")
if err != nil {
return nil, fmt.Errorf("cannot read group of unstructured object. Error: %v. Object:%v", err, crdObj)
}
crdKind, _, err := unstructured.NestedString(crd.Object, "spec", "names", "kind")
if err != nil {
return nil, fmt.Errorf("cannot read group of unstructured object. Error: %v. Object:%v", err, crdObj)
}
crdVersion, _, err := unstructured.NestedString(crd.Object, "spec", "version")
if err != nil {
return nil, err
}
versions, found, err := unstructured.NestedSlice(crd.Object, "spec", "versions")
if err != nil {
return nil, err
}
if crdVersion != "" && !found {
gvks = append(gvks, schema.GroupVersionKind{Group: crdGroup, Version: crdVersion, Kind: crdKind})
}
switch {
case v1Kind:
for _, ver := range spec["versions"].([]interface{}) {
gvks = append(gvks, schema.GroupVersionKind{
Group: spec["group"].(string),
Version: ver.(map[string]interface{})["name"].(string),
Kind: spec["names"].(map[string]interface{})["kind"].(string),
})
for _, version := range versions {
versionMap, ok := version.(map[string]interface{})
if !ok {
continue
}
served, _, err := unstructured.NestedBool(versionMap, "served")
if err != nil {
return nil, err
}
if served {
versionName, _, err := unstructured.NestedString(versionMap, "name")
if err != nil {
return nil, err
}
gvks = append(gvks, schema.GroupVersionKind{Group: crdGroup, Version: versionName, Kind: crdKind})
}
case v1Beta1Kind:
gvks = append(gvks, schema.GroupVersionKind{
Group: spec["group"].(string),
Version: spec["version"].(string),
Kind: spec["names"].(map[string]interface{})["kind"].(string),
})
}
default:
return nil, fmt.Errorf("the following passed object is not a CRD: %v", crdObj)
Expand Down
18 changes: 8 additions & 10 deletions pkg/test/utils/kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,6 @@ func TestExtractGVKFromCRD(t *testing.T) {
Version: "v1alpha1",
Kind: "testresource",
},
{
Group: "test.net",
Version: "v1alpha2",
Kind: "testresource",
},
{
Group: "test.net",
Version: "v1beta1",
Expand All @@ -537,7 +532,7 @@ func TestExtractGVKFromCRD(t *testing.T) {
Kind: "testresource3",
},
},
shouldError: true,
shouldError: false,
},
{
name: "Structured CRDs",
Expand Down Expand Up @@ -599,11 +594,14 @@ func TestExtractGVKFromCRD(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
gotGVKs, err := ExtractGVKFromCRD(tt.inputCRDs)
if tt.shouldError {
assert.NotNil(t, err)
assert.Nil(t, gotGVKs)
if err == nil {
t.Errorf("%s: expecting err to be not nil but got nil", tt.name)
}
} else {
assert.Nil(t, err)
assert.Equal(t, tt.expectedGVKs, gotGVKs)
result := assert.Equal(t, tt.expectedGVKs, gotGVKs)
if !result {
t.Errorf("Test %s failed", tt.name)
}
}
})
}
Expand Down

0 comments on commit e310360

Please sign in to comment.