github.com/kubevela/workflow@v0.6.0/pkg/cue/package_suit_test.go (about)

     1  /*
     2  Copyright 2022 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cue
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"strings"
    23  	"time"
    24  
    25  	. "github.com/onsi/ginkgo"
    26  	. "github.com/onsi/gomega"
    27  
    28  	"cuelang.org/go/cue/build"
    29  	"github.com/google/go-cmp/cmp"
    30  	admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
    31  	appsv1 "k8s.io/api/apps/v1"
    32  	batchv1 "k8s.io/api/batch/v1"
    33  	certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
    34  	coordinationv1 "k8s.io/api/coordination/v1"
    35  	corev1 "k8s.io/api/core/v1"
    36  	discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
    37  	networkingv1 "k8s.io/api/networking/v1"
    38  	policyv1beta1 "k8s.io/api/policy/v1beta1"
    39  	rbacv1 "k8s.io/api/rbac/v1"
    40  	crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    41  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    42  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    43  	"k8s.io/apimachinery/pkg/runtime"
    44  	"k8s.io/utils/pointer"
    45  
    46  	"github.com/kubevela/workflow/pkg/cue/model"
    47  	"github.com/kubevela/workflow/pkg/utils"
    48  )
    49  
    50  var _ = Describe("Package discovery resources for definition from K8s APIServer", func() {
    51  	PIt("check that all built-in k8s resource are registered", func() {
    52  		var localSchemeBuilder = runtime.SchemeBuilder{
    53  			admissionregistrationv1.AddToScheme,
    54  			appsv1.AddToScheme,
    55  			batchv1.AddToScheme,
    56  			certificatesv1beta1.AddToScheme,
    57  			coordinationv1.AddToScheme,
    58  			corev1.AddToScheme,
    59  			discoveryv1beta1.AddToScheme,
    60  			networkingv1.AddToScheme,
    61  			policyv1beta1.AddToScheme,
    62  			rbacv1.AddToScheme,
    63  		}
    64  
    65  		var localScheme = runtime.NewScheme()
    66  		err := localSchemeBuilder.AddToScheme(localScheme)
    67  		Expect(err).Should(BeNil())
    68  		types := localScheme.AllKnownTypes()
    69  		for typ := range types {
    70  			if strings.HasSuffix(typ.Kind, "List") {
    71  				continue
    72  			}
    73  			if strings.HasSuffix(typ.Kind, "Options") {
    74  				continue
    75  			}
    76  			switch typ.Kind {
    77  			case "WatchEvent":
    78  				continue
    79  			case "APIGroup", "APIVersions":
    80  				continue
    81  			case "RangeAllocation", "ComponentStatus", "Status":
    82  				continue
    83  			case "SerializedReference", "EndpointSlice":
    84  				continue
    85  			case "PodStatusResult", "EphemeralContainers":
    86  				continue
    87  			}
    88  
    89  			Expect(pd.Exist(metav1.GroupVersionKind{
    90  				Group:   typ.Group,
    91  				Version: typ.Version,
    92  				Kind:    typ.Kind,
    93  			})).Should(BeTrue(), typ.String())
    94  		}
    95  	})
    96  
    97  	// nolint:staticcheck
    98  	PIt("discovery built-in k8s resource with kube prefix", func() {
    99  
   100  		By("test ingress in kube package")
   101  		bi := build.NewContext().NewInstance("", nil)
   102  		err := bi.AddFile("-", `
   103  import (
   104  	kube	"kube/networking.k8s.io/v1beta1"
   105  )
   106  output: kube.#Ingress
   107  output: {
   108  	apiVersion: "networking.k8s.io/v1beta1"
   109  	kind:       "Ingress"
   110  	metadata: name: "myapp"
   111  	spec: {
   112  		rules: [{
   113  			host: parameter.domain
   114  			http: {
   115  				paths: [
   116  					for k, v in parameter.http {
   117  						path: k
   118  						backend: {
   119  							serviceName: "myname"
   120  							servicePort: v
   121  						}
   122  					},
   123  				]
   124  			}
   125  		}]
   126  	}
   127  }
   128  parameter: {
   129  	domain: "abc.com"
   130  	http: {
   131  		"/": 80
   132  	}
   133  }`)
   134  		Expect(err).ToNot(HaveOccurred())
   135  		inst, err := pd.ImportPackagesAndBuildInstance(bi)
   136  		Expect(err).Should(BeNil())
   137  		base, err := model.NewBase(inst.Lookup("output"))
   138  		Expect(err).Should(BeNil())
   139  		data, err := base.Unstructured()
   140  		Expect(err).Should(BeNil())
   141  
   142  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   143  			"kind":       "Ingress",
   144  			"apiVersion": "networking.k8s.io/v1beta1",
   145  			"metadata":   map[string]interface{}{"name": "myapp"},
   146  			"spec": map[string]interface{}{
   147  				"rules": []interface{}{
   148  					map[string]interface{}{
   149  						"host": "abc.com",
   150  						"http": map[string]interface{}{
   151  							"paths": []interface{}{
   152  								map[string]interface{}{
   153  									"path": "/",
   154  									"backend": map[string]interface{}{
   155  										"serviceName": "myname",
   156  										"servicePort": int64(80),
   157  									}}}}}}}},
   158  		})).Should(BeEquivalentTo(""))
   159  		By("test Invalid Import path")
   160  		bi = build.NewContext().NewInstance("", nil)
   161  		err = bi.AddFile("-", `
   162  import (
   163  	kube	"kube/networking.k8s.io/v1"
   164  )
   165  output: kube.#Deployment
   166  output: {
   167  	metadata: {
   168  		"name": parameter.name
   169  	}
   170  	spec: template: spec: {
   171  		containers: [{
   172  			name:"invalid-path",
   173  			image: parameter.image
   174  		}]
   175  	}
   176  }
   177  
   178  parameter: {
   179  	name:  "myapp"
   180  	image: "nginx"
   181  }`)
   182  		Expect(err).Should(BeNil())
   183  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   184  		Expect(err).Should(BeNil())
   185  		_, err = model.NewBase(inst.Lookup("output"))
   186  		Expect(err).ShouldNot(BeNil())
   187  		Expect(err.Error()).Should(Equal("_|_ // undefined field \"#Deployment\""))
   188  
   189  		By("test Deployment in kube package")
   190  		bi = build.NewContext().NewInstance("", nil)
   191  		err = bi.AddFile("-", `
   192  import (
   193  	kube	"kube/apps/v1"
   194  )
   195  output: kube.#Deployment
   196  output: {
   197  	metadata: {
   198  		"name": parameter.name
   199  	}
   200  	spec: template: spec: {
   201  		containers: [{
   202  			name:"test",
   203  			image: parameter.image
   204  		}]
   205  	}
   206  }
   207  parameter: {
   208  	name:  "myapp"
   209  	image: "nginx"
   210  }`)
   211  		Expect(err).ShouldNot(BeNil())
   212  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   213  		Expect(err).Should(BeNil())
   214  		base, err = model.NewBase(inst.Lookup("output"))
   215  		Expect(err).Should(BeNil())
   216  		data, err = base.Unstructured()
   217  		Expect(err).Should(BeNil())
   218  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   219  			"kind":       "Deployment",
   220  			"apiVersion": "apps/v1",
   221  			"metadata":   map[string]interface{}{"name": "myapp"},
   222  			"spec": map[string]interface{}{
   223  				"selector": map[string]interface{}{},
   224  				"template": map[string]interface{}{
   225  					"spec": map[string]interface{}{
   226  						"containers": []interface{}{
   227  							map[string]interface{}{
   228  								"name":  "test",
   229  								"image": "nginx"}}}}}},
   230  		})).Should(BeEquivalentTo(""))
   231  
   232  		By("test Secret in kube package")
   233  		bi = build.NewContext().NewInstance("", nil)
   234  		err = bi.AddFile("-", `
   235  import (
   236  	kube "kube/v1"
   237  )
   238  output: kube.#Secret
   239  output: {
   240  	metadata: {
   241  		"name": parameter.name
   242  	}
   243  	type:"kubevela"
   244  }
   245  parameter: {
   246  	name:  "myapp"
   247  }`)
   248  		Expect(err).Should(BeNil())
   249  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   250  		Expect(err).Should(BeNil())
   251  		base, err = model.NewBase(inst.Lookup("output"))
   252  		Expect(err).Should(BeNil())
   253  		data, err = base.Unstructured()
   254  		Expect(err).Should(BeNil())
   255  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   256  			"kind":       "Secret",
   257  			"apiVersion": "v1",
   258  			"metadata":   map[string]interface{}{"name": "myapp"},
   259  			"type":       "kubevela"}})).Should(BeEquivalentTo(""))
   260  
   261  		By("test Service in kube package")
   262  		bi = build.NewContext().NewInstance("", nil)
   263  		err = bi.AddFile("-", `
   264  import (
   265  	kube "kube/v1"
   266  )
   267  output: kube.#Service
   268  output: {
   269  	metadata: {
   270  		"name": parameter.name
   271  	}
   272  	spec: type: "ClusterIP",
   273  }
   274  parameter: {
   275  	name:  "myapp"
   276  }`)
   277  		Expect(err).Should(BeNil())
   278  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   279  		Expect(err).Should(BeNil())
   280  		base, err = model.NewBase(inst.Lookup("output"))
   281  		Expect(err).Should(BeNil())
   282  		data, err = base.Unstructured()
   283  		Expect(err).Should(BeNil())
   284  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   285  			"kind":       "Service",
   286  			"apiVersion": "v1",
   287  			"metadata":   map[string]interface{}{"name": "myapp"},
   288  			"spec": map[string]interface{}{
   289  				"type": "ClusterIP"}},
   290  		})).Should(BeEquivalentTo(""))
   291  		Expect(pd.Exist(metav1.GroupVersionKind{
   292  			Group:   "",
   293  			Version: "v1",
   294  			Kind:    "Service",
   295  		})).Should(Equal(true))
   296  
   297  		By("Check newly added CRD refreshed and could be used in CUE package")
   298  		crd1 := crdv1.CustomResourceDefinition{
   299  			ObjectMeta: metav1.ObjectMeta{
   300  				Name: "foo.example.com",
   301  			},
   302  			Spec: crdv1.CustomResourceDefinitionSpec{
   303  				Group: "example.com",
   304  				Names: crdv1.CustomResourceDefinitionNames{
   305  					Kind:     "Foo",
   306  					ListKind: "FooList",
   307  					Plural:   "foo",
   308  					Singular: "foo",
   309  				},
   310  				Versions: []crdv1.CustomResourceDefinitionVersion{{
   311  					Name:         "v1",
   312  					Served:       true,
   313  					Storage:      true,
   314  					Subresources: &crdv1.CustomResourceSubresources{Status: &crdv1.CustomResourceSubresourceStatus{}},
   315  					Schema: &crdv1.CustomResourceValidation{
   316  						OpenAPIV3Schema: &crdv1.JSONSchemaProps{
   317  							Type: "object",
   318  							Properties: map[string]crdv1.JSONSchemaProps{
   319  								"spec": {
   320  									Type:                   "object",
   321  									XPreserveUnknownFields: pointer.BoolPtr(true),
   322  									Properties: map[string]crdv1.JSONSchemaProps{
   323  										"key": {Type: "string"},
   324  									}},
   325  								"status": {
   326  									Type:                   "object",
   327  									XPreserveUnknownFields: pointer.BoolPtr(true),
   328  									Properties: map[string]crdv1.JSONSchemaProps{
   329  										"key":      {Type: "string"},
   330  										"app-hash": {Type: "string"},
   331  									}}}}}},
   332  				},
   333  				Scope: crdv1.NamespaceScoped,
   334  			},
   335  		}
   336  		Expect(k8sClient.Create(context.Background(), &crd1)).Should(SatisfyAny(BeNil(), &utils.AlreadyExistMatcher{}))
   337  
   338  		Expect(pd.Exist(metav1.GroupVersionKind{
   339  			Group:   "example.com",
   340  			Version: "v1",
   341  			Kind:    "Foo",
   342  		})).Should(Equal(false))
   343  
   344  		By("test new added CRD in kube package")
   345  		Eventually(func() error {
   346  			if err := pd.RefreshKubePackagesFromCluster(); err != nil {
   347  				return err
   348  			}
   349  			if !pd.Exist(metav1.GroupVersionKind{
   350  				Group:   "example.com",
   351  				Version: "v1",
   352  				Kind:    "Foo",
   353  			}) {
   354  				return errors.New("crd(example.com/v1.Foo) not register to openAPI")
   355  			}
   356  			return nil
   357  		}, time.Second*30, time.Millisecond*300).Should(BeNil())
   358  
   359  		bi = build.NewContext().NewInstance("", nil)
   360  		err = bi.AddFile("-", `
   361  import (
   362  	kv1 "kube/example.com/v1"
   363  )
   364  output: kv1.#Foo
   365  output: {
   366  	spec: key: "test1"
   367      status: key: "test2"
   368  }
   369  `)
   370  		Expect(err).Should(BeNil())
   371  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   372  		Expect(err).Should(BeNil())
   373  		base, err = model.NewBase(inst.Lookup("output"))
   374  		Expect(err).Should(BeNil())
   375  		data, err = base.Unstructured()
   376  		Expect(err).Should(BeNil())
   377  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   378  			"kind":       "Foo",
   379  			"apiVersion": "example.com/v1",
   380  			"spec": map[string]interface{}{
   381  				"key": "test1"},
   382  			"status": map[string]interface{}{
   383  				"key": "test2"}},
   384  		})).Should(BeEquivalentTo(""))
   385  
   386  	})
   387  
   388  	// nolint:staticcheck
   389  	PIt("discovery built-in k8s resource with third-party path", func() {
   390  
   391  		By("test ingress in kube package")
   392  		bi := build.NewContext().NewInstance("", nil)
   393  		err := bi.AddFile("-", `
   394  import (
   395  	network "k8s.io/networking/v1beta1"
   396  )
   397  output: network.#Ingress
   398  output: {
   399  	metadata: name: "myapp"
   400  	spec: {
   401  		rules: [{
   402  			host: parameter.domain
   403  			http: {
   404  				paths: [
   405  					for k, v in parameter.http {
   406  						path: k
   407  						backend: {
   408  							serviceName: "myname"
   409  							servicePort: v
   410  						}
   411  					},
   412  				]
   413  			}
   414  		}]
   415  	}
   416  }
   417  parameter: {
   418  	domain: "abc.com"
   419  	http: {
   420  		"/": 80
   421  	}
   422  }`)
   423  		Expect(err).ToNot(HaveOccurred())
   424  		inst, err := pd.ImportPackagesAndBuildInstance(bi)
   425  		Expect(err).Should(BeNil())
   426  		base, err := model.NewBase(inst.Lookup("output"))
   427  		Expect(err).Should(BeNil())
   428  		data, err := base.Unstructured()
   429  		Expect(err).Should(BeNil())
   430  
   431  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   432  			"kind":       "Ingress",
   433  			"apiVersion": "networking.k8s.io/v1beta1",
   434  			"metadata":   map[string]interface{}{"name": "myapp"},
   435  			"spec": map[string]interface{}{
   436  				"rules": []interface{}{
   437  					map[string]interface{}{
   438  						"host": "abc.com",
   439  						"http": map[string]interface{}{
   440  							"paths": []interface{}{
   441  								map[string]interface{}{
   442  									"path": "/",
   443  									"backend": map[string]interface{}{
   444  										"serviceName": "myname",
   445  										"servicePort": int64(80),
   446  									}}}}}}}},
   447  		})).Should(BeEquivalentTo(""))
   448  		By("test Invalid Import path")
   449  		bi = build.NewContext().NewInstance("", nil)
   450  		err = bi.AddFile("-", `
   451  import (
   452  	"k8s.io/networking/v1"
   453  )
   454  output: v1.#Deployment
   455  output: {
   456  	metadata: {
   457  		"name": parameter.name
   458  	}
   459  	spec: template: spec: {
   460  		containers: [{
   461  			name:"invalid-path",
   462  			image: parameter.image
   463  		}]
   464  	}
   465  }
   466  
   467  parameter: {
   468  	name:  "myapp"
   469  	image: "nginx"
   470  }`)
   471  		Expect(err).Should(BeNil())
   472  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   473  		Expect(err).Should(BeNil())
   474  		_, err = model.NewBase(inst.Lookup("output"))
   475  		Expect(err).ShouldNot(BeNil())
   476  		Expect(err.Error()).Should(Equal("_|_ // undefined field \"#Deployment\""))
   477  
   478  		By("test Deployment in kube package")
   479  		bi = build.NewContext().NewInstance("", nil)
   480  		err = bi.AddFile("-", `
   481  import (
   482  	apps "k8s.io/apps/v1"
   483  )
   484  output: apps.#Deployment
   485  output: {
   486  	metadata: {
   487  		"name": parameter.name
   488  	}
   489  	spec: template: spec: {
   490  		containers: [{
   491  			name:"test",
   492  			image: parameter.image
   493  		}]
   494  	}
   495  }
   496  parameter: {
   497  	name:  "myapp"
   498  	image: "nginx"
   499  }`)
   500  		Expect(err).Should(BeNil())
   501  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   502  		Expect(err).Should(BeNil())
   503  		base, err = model.NewBase(inst.Lookup("output"))
   504  		Expect(err).Should(BeNil())
   505  		data, err = base.Unstructured()
   506  		Expect(err).Should(BeNil())
   507  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   508  			"kind":       "Deployment",
   509  			"apiVersion": "apps/v1",
   510  			"metadata":   map[string]interface{}{"name": "myapp"},
   511  			"spec": map[string]interface{}{
   512  				"selector": map[string]interface{}{},
   513  				"template": map[string]interface{}{
   514  					"spec": map[string]interface{}{
   515  						"containers": []interface{}{
   516  							map[string]interface{}{
   517  								"name":  "test",
   518  								"image": "nginx"}}}}}},
   519  		})).Should(BeEquivalentTo(""))
   520  
   521  		By("test Secret in kube package")
   522  		bi = build.NewContext().NewInstance("", nil)
   523  		err = bi.AddFile("-", `
   524  import (
   525  	"k8s.io/core/v1"
   526  )
   527  output: v1.#Secret
   528  output: {
   529  	metadata: {
   530  		"name": parameter.name
   531  	}
   532  	type:"kubevela"
   533  }
   534  parameter: {
   535  	name:  "myapp"
   536  }`)
   537  		Expect(err).Should(BeNil())
   538  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   539  		Expect(err).Should(BeNil())
   540  		base, err = model.NewBase(inst.Lookup("output"))
   541  		Expect(err).Should(BeNil())
   542  		data, err = base.Unstructured()
   543  		Expect(err).Should(BeNil())
   544  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   545  			"kind":       "Secret",
   546  			"apiVersion": "v1",
   547  			"metadata":   map[string]interface{}{"name": "myapp"},
   548  			"type":       "kubevela"}})).Should(BeEquivalentTo(""))
   549  
   550  		By("test Service in kube package")
   551  		bi = build.NewContext().NewInstance("", nil)
   552  		err = bi.AddFile("-", `
   553  import (
   554  	"k8s.io/core/v1"
   555  )
   556  output: v1.#Service
   557  output: {
   558  	metadata: {
   559  		"name": parameter.name
   560  	}
   561  	spec: type: "ClusterIP",
   562  }
   563  parameter: {
   564  	name:  "myapp"
   565  }`)
   566  		Expect(err).Should(BeNil())
   567  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   568  		Expect(err).Should(BeNil())
   569  		base, err = model.NewBase(inst.Lookup("output"))
   570  		Expect(err).Should(BeNil())
   571  		data, err = base.Unstructured()
   572  		Expect(err).Should(BeNil())
   573  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   574  			"kind":       "Service",
   575  			"apiVersion": "v1",
   576  			"metadata":   map[string]interface{}{"name": "myapp"},
   577  			"spec": map[string]interface{}{
   578  				"type": "ClusterIP"}},
   579  		})).Should(BeEquivalentTo(""))
   580  		Expect(pd.Exist(metav1.GroupVersionKind{
   581  			Group:   "",
   582  			Version: "v1",
   583  			Kind:    "Service",
   584  		})).Should(Equal(true))
   585  
   586  		By("Check newly added CRD refreshed and could be used in CUE package")
   587  		crd1 := crdv1.CustomResourceDefinition{
   588  			ObjectMeta: metav1.ObjectMeta{
   589  				Name: "bar.example.com",
   590  			},
   591  			Spec: crdv1.CustomResourceDefinitionSpec{
   592  				Group: "example.com",
   593  				Names: crdv1.CustomResourceDefinitionNames{
   594  					Kind:     "Bar",
   595  					ListKind: "BarList",
   596  					Plural:   "bar",
   597  					Singular: "bar",
   598  				},
   599  				Versions: []crdv1.CustomResourceDefinitionVersion{{
   600  					Name:         "v1",
   601  					Served:       true,
   602  					Storage:      true,
   603  					Subresources: &crdv1.CustomResourceSubresources{Status: &crdv1.CustomResourceSubresourceStatus{}},
   604  					Schema: &crdv1.CustomResourceValidation{
   605  						OpenAPIV3Schema: &crdv1.JSONSchemaProps{
   606  							Type: "object",
   607  							Properties: map[string]crdv1.JSONSchemaProps{
   608  								"spec": {
   609  									Type:                   "object",
   610  									XPreserveUnknownFields: pointer.BoolPtr(true),
   611  									Properties: map[string]crdv1.JSONSchemaProps{
   612  										"key": {Type: "string"},
   613  									}},
   614  								"status": {
   615  									Type:                   "object",
   616  									XPreserveUnknownFields: pointer.BoolPtr(true),
   617  									Properties: map[string]crdv1.JSONSchemaProps{
   618  										"key":      {Type: "string"},
   619  										"app-hash": {Type: "string"},
   620  									}}}}}},
   621  				},
   622  				Scope: crdv1.NamespaceScoped,
   623  			},
   624  		}
   625  		Expect(k8sClient.Create(context.Background(), &crd1)).Should(SatisfyAny(BeNil(), &utils.AlreadyExistMatcher{}))
   626  
   627  		Expect(pd.Exist(metav1.GroupVersionKind{
   628  			Group:   "example.com",
   629  			Version: "v1",
   630  			Kind:    "Bar",
   631  		})).Should(Equal(false))
   632  
   633  		By("test new added CRD in kube package")
   634  		Eventually(func() error {
   635  			if err := pd.RefreshKubePackagesFromCluster(); err != nil {
   636  				return err
   637  			}
   638  			if !pd.Exist(metav1.GroupVersionKind{
   639  				Group:   "example.com",
   640  				Version: "v1",
   641  				Kind:    "Bar",
   642  			}) {
   643  				return errors.New("crd(example.com/v1.Bar) not register to openAPI")
   644  			}
   645  			return nil
   646  		}, time.Second*30, time.Millisecond*300).Should(BeNil())
   647  
   648  		bi = build.NewContext().NewInstance("", nil)
   649  		err = bi.AddFile("-", `
   650  import (
   651  	ev1 "example.com/v1"
   652  )
   653  output: ev1.#Bar
   654  output: {
   655  	spec: key: "test1"
   656      status: key: "test2"
   657  }
   658  `)
   659  		Expect(err).Should(BeNil())
   660  		inst, err = pd.ImportPackagesAndBuildInstance(bi)
   661  		Expect(err).Should(BeNil())
   662  		base, err = model.NewBase(inst.Lookup("output"))
   663  		Expect(err).Should(BeNil())
   664  		data, err = base.Unstructured()
   665  		Expect(err).Should(BeNil())
   666  		Expect(cmp.Diff(data, &unstructured.Unstructured{Object: map[string]interface{}{
   667  			"kind":       "Bar",
   668  			"apiVersion": "example.com/v1",
   669  			"spec": map[string]interface{}{
   670  				"key": "test1"},
   671  			"status": map[string]interface{}{
   672  				"key": "test2"}},
   673  		})).Should(BeEquivalentTo(""))
   674  	})
   675  })