@@ -19,21 +19,23 @@ package envtest
19
19
import (
20
20
"bufio"
21
21
"bytes"
22
+ "context"
22
23
"io"
23
24
"io/ioutil"
24
25
"os"
25
26
"path/filepath"
26
27
"time"
27
28
28
- apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
29
29
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
30
30
apierrors "k8s.io/apimachinery/pkg/api/errors"
31
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
32
+ "k8s.io/apimachinery/pkg/runtime"
32
33
"k8s.io/apimachinery/pkg/runtime/schema"
33
34
"k8s.io/apimachinery/pkg/util/sets"
34
35
"k8s.io/apimachinery/pkg/util/wait"
35
36
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
36
37
"k8s.io/client-go/rest"
38
+ "sigs.k8s.io/controller-runtime/pkg/client"
37
39
"sigs.k8s.io/yaml"
38
40
)
39
41
@@ -43,7 +45,7 @@ type CRDInstallOptions struct {
43
45
Paths []string
44
46
45
47
// CRDs is a list of CRDs to install
46
- CRDs []* apiextensionsv1beta1. CustomResourceDefinition
48
+ CRDs []runtime. Object
47
49
48
50
// ErrorIfPathMissing will cause an error if a Path does not exist
49
51
ErrorIfPathMissing bool
@@ -64,7 +66,7 @@ const defaultPollInterval = 100 * time.Millisecond
64
66
const defaultMaxWait = 10 * time .Second
65
67
66
68
// InstallCRDs installs a collection of CRDs into a cluster by reading the crd yaml files from a directory
67
- func InstallCRDs (config * rest.Config , options CRDInstallOptions ) ([]* apiextensionsv1beta1. CustomResourceDefinition , error ) {
69
+ func InstallCRDs (config * rest.Config , options CRDInstallOptions ) ([]runtime. Object , error ) {
68
70
defaultCRDOptions (& options )
69
71
70
72
// Read the CRD yamls into options.CRDs
@@ -109,27 +111,57 @@ func defaultCRDOptions(o *CRDInstallOptions) {
109
111
}
110
112
111
113
// WaitForCRDs waits for the CRDs to appear in discovery
112
- func WaitForCRDs (config * rest.Config , crds []* apiextensionsv1beta1. CustomResourceDefinition , options CRDInstallOptions ) error {
114
+ func WaitForCRDs (config * rest.Config , crds []runtime. Object , options CRDInstallOptions ) error {
113
115
// Add each CRD to a map of GroupVersion to Resource
114
116
waitingFor := map [schema.GroupVersion ]* sets.String {}
115
- for _ , crd := range crds {
117
+ for _ , crd := range runtimeListToUnstructured ( crds ) {
116
118
gvs := []schema.GroupVersion {}
117
- if crd .Spec .Version != "" {
118
- gvs = append (gvs , schema.GroupVersion {Group : crd .Spec .Group , Version : crd .Spec .Version })
119
+ crdGroup , _ , err := unstructured .NestedString (crd .Object , "spec" , "group" )
120
+ if err != nil {
121
+ return err
122
+ }
123
+ crdPlural , _ , err := unstructured .NestedString (crd .Object , "spec" , "names" , "plural" )
124
+ if err != nil {
125
+ return err
126
+ }
127
+ crdVersion , _ , err := unstructured .NestedString (crd .Object , "spec" , "version" )
128
+ if err != nil {
129
+ return err
130
+ }
131
+ if crdVersion != "" {
132
+ gvs = append (gvs , schema.GroupVersion {Group : crdGroup , Version : crdVersion })
133
+ }
134
+
135
+ versions , _ , err := unstructured .NestedSlice (crd .Object , "spec" , "versions" )
136
+ if err != nil {
137
+ return err
119
138
}
120
- for _ , ver := range crd .Spec .Versions {
121
- if ver .Served {
122
- gvs = append (gvs , schema.GroupVersion {Group : crd .Spec .Group , Version : ver .Name })
139
+ for _ , version := range versions {
140
+ versionMap , ok := version .(map [string ]interface {})
141
+ if ! ok {
142
+ continue
143
+ }
144
+ served , _ , err := unstructured .NestedBool (versionMap , "served" )
145
+ if err != nil {
146
+ return err
147
+ }
148
+ if served {
149
+ versionName , _ , err := unstructured .NestedString (versionMap , "name" )
150
+ if err != nil {
151
+ return err
152
+ }
153
+ gvs = append (gvs , schema.GroupVersion {Group : crdGroup , Version : versionName })
123
154
}
124
155
}
156
+
125
157
for _ , gv := range gvs {
126
158
log .V (1 ).Info ("adding API in waitlist" , "GV" , gv )
127
159
if _ , found := waitingFor [gv ]; ! found {
128
160
// Initialize the set
129
161
waitingFor [gv ] = & sets.String {}
130
162
}
131
163
// Add the Resource
132
- waitingFor [gv ].Insert (crd . Spec . Names . Plural )
164
+ waitingFor [gv ].Insert (crdPlural )
133
165
}
134
166
}
135
167
@@ -192,15 +224,15 @@ func UninstallCRDs(config *rest.Config, options CRDInstallOptions) error {
192
224
}
193
225
194
226
// Delete the CRDs from the apiserver
195
- cs , err := clientset . NewForConfig (config )
227
+ cs , err := client . New (config , client. Options {} )
196
228
if err != nil {
197
229
return err
198
230
}
199
231
200
232
// Uninstall each CRD
201
- for _ , crd := range options .CRDs {
202
- log .V (1 ).Info ("uninstalling CRD" , "crd" , crd .Name )
203
- if err := cs .ApiextensionsV1beta1 (). CustomResourceDefinitions (). Delete ( crd . Name , & metav1. DeleteOptions {} ); err != nil {
233
+ for _ , crd := range runtimeListToUnstructured ( options .CRDs ) {
234
+ log .V (1 ).Info ("uninstalling CRD" , "crd" , crd .GetName () )
235
+ if err := cs .Delete ( context . TODO (), crd ); err != nil {
204
236
// If CRD is not found, we can consider success
205
237
if ! apierrors .IsNotFound (err ) {
206
238
return err
@@ -212,28 +244,28 @@ func UninstallCRDs(config *rest.Config, options CRDInstallOptions) error {
212
244
}
213
245
214
246
// CreateCRDs creates the CRDs
215
- func CreateCRDs (config * rest.Config , crds []* apiextensionsv1beta1. CustomResourceDefinition ) error {
216
- cs , err := clientset . NewForConfig (config )
247
+ func CreateCRDs (config * rest.Config , crds []runtime. Object ) error {
248
+ cs , err := client . New (config , client. Options {} )
217
249
if err != nil {
218
250
return err
219
251
}
220
252
221
253
// Create each CRD
222
- for _ , crd := range crds {
223
- log .V (1 ).Info ("installing CRD" , "crd" , crd .Name )
224
- if _ , err := cs .ApiextensionsV1beta1 (). CustomResourceDefinitions (). Create ( crd ); err != nil {
254
+ for _ , crd := range runtimeListToUnstructured ( crds ) {
255
+ log .V (1 ).Info ("installing CRD" , "crd" , crd .GetName () )
256
+ if err := cs .Create ( context . TODO (), crd ); err != nil {
225
257
return err
226
258
}
227
259
}
228
260
return nil
229
261
}
230
262
231
263
// renderCRDs iterate through options.Paths and extract all CRD files.
232
- func renderCRDs (options * CRDInstallOptions ) ([]* apiextensionsv1beta1. CustomResourceDefinition , error ) {
264
+ func renderCRDs (options * CRDInstallOptions ) ([]runtime. Object , error ) {
233
265
var (
234
266
err error
235
267
info os.FileInfo
236
- crds []* apiextensionsv1beta1. CustomResourceDefinition
268
+ crds []* unstructured. Unstructured
237
269
files []os.FileInfo
238
270
)
239
271
@@ -263,18 +295,18 @@ func renderCRDs(options *CRDInstallOptions) ([]*apiextensionsv1beta1.CustomResou
263
295
}
264
296
265
297
// If CRD already in the list, skip it.
266
- if existsCRDs (crds , crdList ) {
298
+ if existsUnstructured (crds , crdList ) {
267
299
continue
268
300
}
269
301
crds = append (crds , crdList ... )
270
302
}
271
303
272
- return crds , nil
304
+ return unstructuredListToRuntime ( crds ) , nil
273
305
}
274
306
275
307
// readCRDs reads the CRDs from files and Unmarshals them into structs
276
- func readCRDs (basePath string , files []os.FileInfo ) ([]* apiextensionsv1beta1. CustomResourceDefinition , error ) {
277
- var crds []* apiextensionsv1beta1. CustomResourceDefinition
308
+ func readCRDs (basePath string , files []os.FileInfo ) ([]* unstructured. Unstructured , error ) {
309
+ var crds []* unstructured. Unstructured
278
310
279
311
// White list the file extensions that may contain CRDs
280
312
crdExts := sets .NewString (".json" , ".yaml" , ".yml" )
@@ -292,13 +324,22 @@ func readCRDs(basePath string, files []os.FileInfo) ([]*apiextensionsv1beta1.Cus
292
324
}
293
325
294
326
for _ , doc := range docs {
295
- crd := & apiextensionsv1beta1. CustomResourceDefinition {}
327
+ crd := & unstructured. Unstructured {}
296
328
if err = yaml .Unmarshal (doc , crd ); err != nil {
297
329
return nil , err
298
330
}
299
331
300
332
// Check that it is actually a CRD
301
- if crd .Spec .Names .Kind == "" || crd .Spec .Group == "" {
333
+ crdKind , _ , err := unstructured .NestedString (crd .Object , "spec" , "names" , "kind" )
334
+ if err != nil {
335
+ return nil , err
336
+ }
337
+ crdGroup , _ , err := unstructured .NestedString (crd .Object , "spec" , "group" )
338
+ if err != nil {
339
+ return nil , err
340
+ }
341
+
342
+ if crd .GetKind () != "CustomResourceDefinition" || crdKind == "" || crdGroup == "" {
302
343
continue
303
344
}
304
345
crds = append (crds , crd )
0 commit comments