1
16
17 package crd
18
19 import (
20 "context"
21 "fmt"
22
23 "k8s.io/utils/pointer"
24
25 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
26 crdclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
27 "k8s.io/apiextensions-apiserver/test/integration/fixtures"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/runtime/schema"
30 "k8s.io/client-go/dynamic"
31 "k8s.io/kubernetes/test/e2e/framework"
32 )
33
34
35 type CleanCrdFn func(ctx context.Context) error
36
37
38 type TestCrd struct {
39 APIExtensionClient *crdclientset.Clientset
40 Crd *apiextensionsv1.CustomResourceDefinition
41 DynamicClients map[string]dynamic.ResourceInterface
42 CleanUp CleanCrdFn
43 }
44
45
46 type Option func(crd *apiextensionsv1.CustomResourceDefinition)
47
48
49 func CreateMultiVersionTestCRD(f *framework.Framework, group string, opts ...Option) (*TestCrd, error) {
50 suffix := framework.RandomSuffix()
51 name := fmt.Sprintf("e2e-test-%s-%s-crd", f.BaseName, suffix)
52 kind := fmt.Sprintf("e2e-test-%s-%s-crd", f.BaseName, suffix)
53 testcrd := &TestCrd{}
54
55
56 config, err := framework.LoadConfig()
57 if err != nil {
58 framework.Failf("failed to load config: %v", err)
59 return nil, err
60 }
61 apiExtensionClient, err := crdclientset.NewForConfig(config)
62 if err != nil {
63 framework.Failf("failed to initialize apiExtensionClient: %v", err)
64 return nil, err
65 }
66 dynamicClient, err := dynamic.NewForConfig(config)
67 if err != nil {
68 framework.Failf("failed to initialize dynamic client: %v", err)
69 return nil, err
70 }
71
72 crd := &apiextensionsv1.CustomResourceDefinition{
73 ObjectMeta: metav1.ObjectMeta{Name: name + "s." + group},
74 Spec: apiextensionsv1.CustomResourceDefinitionSpec{
75 Group: group,
76 Names: apiextensionsv1.CustomResourceDefinitionNames{
77 Plural: name + "s",
78 Singular: name,
79 Kind: kind,
80 ListKind: kind + "List",
81 },
82 Scope: apiextensionsv1.NamespaceScoped,
83 },
84 }
85 for _, opt := range opts {
86 opt(crd)
87 }
88 if len(crd.Spec.Versions) == 0 {
89 crd.Spec.Versions = []apiextensionsv1.CustomResourceDefinitionVersion{{
90 Served: true,
91 Storage: true,
92 Name: "v1",
93 Schema: fixtures.AllowAllSchema(),
94 }}
95 }
96
97
98 crd, err = fixtures.CreateNewV1CustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient)
99 if err != nil {
100 framework.Failf("failed to create CustomResourceDefinition: %v", err)
101 return nil, err
102 }
103
104 resourceClients := map[string]dynamic.ResourceInterface{}
105 for _, v := range crd.Spec.Versions {
106 if v.Served {
107 gvr := schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Spec.Names.Plural}
108 resourceClients[v.Name] = dynamicClient.Resource(gvr).Namespace(f.Namespace.Name)
109 }
110 }
111
112 testcrd.APIExtensionClient = apiExtensionClient
113 testcrd.Crd = crd
114 testcrd.DynamicClients = resourceClients
115 testcrd.CleanUp = func(ctx context.Context) error {
116 err := fixtures.DeleteV1CustomResourceDefinition(crd, apiExtensionClient)
117 if err != nil {
118 framework.Failf("failed to delete CustomResourceDefinition(%s): %v", name, err)
119 }
120 return err
121 }
122 return testcrd, nil
123 }
124
125
126 func CreateTestCRD(f *framework.Framework, opts ...Option) (*TestCrd, error) {
127 group := fmt.Sprintf("%s.example.com", f.BaseName)
128 return CreateMultiVersionTestCRD(f, group, append([]Option{func(crd *apiextensionsv1.CustomResourceDefinition) {
129 crd.Spec.Versions = []apiextensionsv1.CustomResourceDefinitionVersion{
130 {
131 Name: "v1",
132 Served: true,
133 Storage: true,
134 Schema: &apiextensionsv1.CustomResourceValidation{
135 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
136 XPreserveUnknownFields: pointer.BoolPtr(true),
137 Type: "object",
138 },
139 },
140 },
141 }
142 }}, opts...)...)
143 }
144
View as plain text