diff --git a/docs/en/cue/basic.md b/docs/en/cue/basic.md index 77dc064f8..c14fb68c0 100644 --- a/docs/en/cue/basic.md +++ b/docs/en/cue/basic.md @@ -380,9 +380,10 @@ output: { ### Import Kube Package -KubeVela generate a cue package named “kube” by reading K8s openapi from K8s cluster. +KubeVela automatically generates a cue package named `kube` as internal packages by reading K8s openapi from the +installed K8s cluster. -You can use package "kube" in CUE Template of kubevela +You can use package `kube` in CUE Template of KubeVela just like the same way with the CUE internal packages. ```cue import ("kube") diff --git a/docs/examples/dry-run/README.md b/docs/examples/dry-run/README.md new file mode 100644 index 000000000..6462f1ce8 --- /dev/null +++ b/docs/examples/dry-run/README.md @@ -0,0 +1,71 @@ +# Vela Dry run + +```shell +$ vela system dry-run -f docs/examples/dry-run/app.yaml -d docs/examples/dry-run/definitions +--- +# App application-sample -- Comopnent myweb +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.oam.dev/component: myweb + app.oam.dev/name: application-sample + workload.oam.dev/type: myworker +spec: + selector: + matchLabels: + app.oam.dev/component: myweb + template: + metadata: + labels: + app.oam.dev/component: myweb + spec: + containers: + - command: + - sleep + - "1000" + image: busybox + name: myweb + +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.oam.dev/component: myweb + app.oam.dev/name: application-sample + trait.oam.dev/resource: service + trait.oam.dev/type: myingress + name: myweb +spec: + ports: + - port: 80 + targetPort: 80 + selector: + app.oam.dev/component: myweb + +--- +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + labels: + app.oam.dev/component: myweb + app.oam.dev/name: application-sample + trait.oam.dev/resource: ingress + trait.oam.dev/type: myingress + name: myweb +spec: + rules: + - host: www.example.com + http: + paths: + - backend: + serviceName: myweb + servicePort: 80 + path: / + +--- + +``` \ No newline at end of file diff --git a/docs/examples/dry-run/app.yaml b/docs/examples/dry-run/app.yaml new file mode 100644 index 000000000..4f187df77 --- /dev/null +++ b/docs/examples/dry-run/app.yaml @@ -0,0 +1,21 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: Application +metadata: + name: application-sample +spec: + components: + - name: myweb + type: myworker + settings: + image: "busybox" + cmd: + - sleep + - "1000" + lives: "3" + enemies: "alien" + traits: + - name: myingress + properties: + domain: "www.example.com" + http: + "/": 80 \ No newline at end of file diff --git a/docs/examples/dry-run/definitions/myingress.yaml b/docs/examples/dry-run/definitions/myingress.yaml new file mode 100644 index 000000000..a20908f87 --- /dev/null +++ b/docs/examples/dry-run/definitions/myingress.yaml @@ -0,0 +1,66 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: TraitDefinition +metadata: + name: myingress +spec: + status: + customStatus: |- + if len(context.outputs.ingress.status.loadBalancer.ingress) > 0 { + message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + context.outputs.ingress.status.loadBalancer.ingress[0].ip + } + if len(context.outputs.ingress.status.loadBalancer.ingress) == 0 { + message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + " --route'\n" + } + healthPolicy: | + isHealth: len(context.outputs.service.spec.clusterIP) > 0 + appliesToWorkloads: + - myworker + schematic: + cue: + template: | + parameter: { + domain: string + http: [string]: int + } + + // trait template can have multiple outputs in one trait + outputs: service: { + apiVersion: "v1" + kind: "Service" + metadata: + name: context.name + spec: { + selector: + "app.oam.dev/component": context.name + ports: [ + for k, v in parameter.http { + port: v + targetPort: v + }, + ] + } + } + + outputs: ingress: { + apiVersion: "networking.k8s.io/v1beta1" + kind: "Ingress" + metadata: + name: context.name + spec: { + rules: [{ + host: parameter.domain + http: { + paths: [ + for k, v in parameter.http { + path: k + backend: { + serviceName: context.name + servicePort: v + } + }, + ] + } + }] + } + } + diff --git a/docs/examples/dry-run/definitions/myworker.yaml b/docs/examples/dry-run/definitions/myworker.yaml new file mode 100644 index 000000000..df4c7d5e2 --- /dev/null +++ b/docs/examples/dry-run/definitions/myworker.yaml @@ -0,0 +1,45 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: WorkloadDefinition +metadata: + name: myworker +spec: + definitionRef: + name: deployments.apps + schematic: + cue: + template: | + output: { + apiVersion: "apps/v1" + kind: "Deployment" + spec: { + selector: matchLabels: { + "app.oam.dev/component": context.name + } + + template: { + metadata: labels: { + "app.oam.dev/component": context.name + } + + spec: { + containers: [{ + name: context.name + image: parameter.image + + if parameter["cmd"] != _|_ { + command: parameter.cmd + } + }] + } + } + } + } + + parameter: { + // +usage=Which image would you like to use for your service + // +short=i + image: string + // +usage=Commands to run in the container + cmd?: [...string] + } + diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go b/pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go index ad1c2c085..e08c2ca0a 100644 --- a/pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go +++ b/pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go @@ -177,7 +177,7 @@ func (r *Reconciler) UpdateStatus(ctx context.Context, app *v1alpha2.Application // Setup adds a controller that reconciles AppRollout. func Setup(mgr ctrl.Manager, _ core.Args, _ logging.Logger) error { dm, err := discoverymapper.New(mgr.GetConfig()) - if err := definition.AddImportFromCluster(mgr.GetConfig()); err != nil { + if err := definition.AddKubeCUEPackagesFromCluster(mgr.GetConfig()); err != nil { ctrl.Log.Error(err, "use kubernetes cluster openAPI as rendering package") } if err != nil { diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/suite_test.go b/pkg/controller/core.oam.dev/v1alpha2/application/suite_test.go index 21884ef19..6760b6a3e 100644 --- a/pkg/controller/core.oam.dev/v1alpha2/application/suite_test.go +++ b/pkg/controller/core.oam.dev/v1alpha2/application/suite_test.go @@ -145,7 +145,7 @@ var _ = BeforeSuite(func(done Done) { Expect(err).NotTo(HaveOccurred()) definitonNs := corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}} Expect(k8sClient.Create(context.Background(), definitonNs.DeepCopy())).Should(BeNil()) - Expect(definition.AddImportFromCluster(cfg)).Should(BeNil()) + Expect(definition.AddKubeCUEPackagesFromCluster(cfg)).Should(BeNil()) // start the controller in the background so that new componentRevisions are created go func() { err = ctlManager.Start(stop) diff --git a/pkg/dsl/definition/package.go b/pkg/dsl/definition/package.go index 66c243b8b..60ec3685a 100644 --- a/pkg/dsl/definition/package.go +++ b/pkg/dsl/definition/package.go @@ -19,12 +19,13 @@ import ( var velaBuiltinPkgs []*build.Instance -func addImportsFor(bi *build.Instance) { +// AddVelaInternalPackagesFor will add KubeVela built-in packages into your CUE instance +func AddVelaInternalPackagesFor(bi *build.Instance) { bi.Imports = append(bi.Imports, velaBuiltinPkgs...) } -// AddImportFromCluster use K8s native API and CRD definition as a reference package in template rendering -func AddImportFromCluster(config *rest.Config) error { +// AddKubeCUEPackagesFromCluster use K8s native API and CRD definition as a reference package in template rendering +func AddKubeCUEPackagesFromCluster(config *rest.Config) error { copyConfig := *config apiSchema, err := getClusterOpenAPI(©Config) if err != nil { @@ -146,7 +147,6 @@ func (pkg *pkgInstance) addOpenAPI(apiSchema string) error { if v.Group != "" { apiversion = v.Group + "/" + apiversion } - def := fmt.Sprintf(`%s: { kind: "%s" apiVersion: "%s", diff --git a/pkg/dsl/definition/package_suit_test.go b/pkg/dsl/definition/package_suit_test.go new file mode 100644 index 000000000..2d1616b05 --- /dev/null +++ b/pkg/dsl/definition/package_suit_test.go @@ -0,0 +1,31 @@ +/* +Copyright 2021 The KubeVela Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package definition + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Package discovery resources for definition from K8s APIServer", func() { + + It("discovery built-in k8s resource", func() { + Expect(AddKubeCUEPackagesFromCluster(cfg)).Should(BeNil()) + + }) + +}) diff --git a/pkg/dsl/definition/package_test.go b/pkg/dsl/definition/package_test.go index c63710951..cb160e2d5 100644 --- a/pkg/dsl/definition/package_test.go +++ b/pkg/dsl/definition/package_test.go @@ -319,7 +319,7 @@ func TestPackage(t *testing.T) { assert.NilError(t, pkg.addOpenAPI(openAPISchema)) pkg.mount() bi := build.NewContext().NewInstance("", nil) - addImportsFor(bi) + AddVelaInternalPackagesFor(bi) bi.AddFile("-", ` import "oss" output: oss.#Bucket diff --git a/pkg/dsl/definition/suit_test.go b/pkg/dsl/definition/suit_test.go new file mode 100644 index 000000000..a89a89b96 --- /dev/null +++ b/pkg/dsl/definition/suit_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2021 The KubeVela Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package definition + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var scheme = runtime.NewScheme() + +func TestDefinition(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Test Definition Suite", + []Reporter{printer.NewlineReporter{}}) +} + +var _ = BeforeSuite(func(done Done) { + By("Bootstrapping test environment") + testEnv = &envtest.Environment{ + UseExistingCluster: pointer.BoolPtr(false), + } + var err error + cfg, err = testEnv.Start() + Expect(err).ToNot(HaveOccurred()) + Expect(cfg).ToNot(BeNil()) + Expect(clientgoscheme.AddToScheme(scheme)).Should(BeNil()) + Expect(crdv1.AddToScheme(scheme)).Should(BeNil()) + // +kubebuilder:scaffold:scheme + By("Create the k8s client") + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).ToNot(HaveOccurred()) + Expect(k8sClient).ToNot(BeNil()) + + close(done) +}, 60) + +var _ = AfterSuite(func() { + By("Tearing down the test environment") + err := testEnv.Stop() + Expect(err).ToNot(HaveOccurred()) +}) diff --git a/pkg/dsl/definition/template.go b/pkg/dsl/definition/template.go index 07970ff3a..9de136e39 100644 --- a/pkg/dsl/definition/template.go +++ b/pkg/dsl/definition/template.go @@ -89,7 +89,7 @@ func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string) er if err := bi.AddFile("-", ctx.BaseContextFile()); err != nil { return err } - addImportsFor(bi) + AddVelaInternalPackagesFor(bi) instances := cue.Build([]*build.Instance{bi}) for _, inst := range instances { @@ -271,7 +271,7 @@ func (td *traitDef) Complete(ctx process.Context, abstractTemplate string) error if err := bi.AddFile("context", ctx.BaseContextFile()); err != nil { return errors.WithMessagef(err, "invalid context of trait %s", td.name) } - addImportsFor(bi) + AddVelaInternalPackagesFor(bi) instances := cue.Build([]*build.Instance{bi}) for _, inst := range instances { diff --git a/pkg/utils/common/common.go b/pkg/utils/common/common.go index fabd70b55..da73b1fe5 100644 --- a/pkg/utils/common/common.go +++ b/pkg/utils/common/common.go @@ -16,6 +16,7 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/encoding/openapi" "github.com/AlecAivazis/survey/v2" + "github.com/ghodss/yaml" certmanager "github.com/wonderflow/cert-manager-api/pkg/apis/certmanager/v1" k8sruntime "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -157,3 +158,12 @@ func AskToChooseOneService(svcNames []string) (string, error) { } return svcName, nil } + +// ReadYamlToObject will read a yaml K8s object to runtime.Object +func ReadYamlToObject(path string, object k8sruntime.Object) error { + data, err := ioutil.ReadFile(filepath.Clean(path)) + if err != nil { + return err + } + return yaml.Unmarshal(data, object) +} diff --git a/references/appfile/run.go b/references/appfile/run.go index 142aa2689..a657f2332 100644 --- a/references/appfile/run.go +++ b/references/appfile/run.go @@ -34,7 +34,10 @@ func CreateOrUpdateObjects(ctx context.Context, client client.Client, objects [] err := client.Get(ctx, key, u) if err == nil { obj.SetResourceVersion(u.GetResourceVersion()) - return client.Update(ctx, obj) + if err = client.Update(ctx, obj); err != nil { + return err + } + continue } if !apierrors.IsNotFound(err) { return err diff --git a/references/cli/dryrun.go b/references/cli/dryrun.go index 7c86eb4cf..cc408ccbe 100644 --- a/references/cli/dryrun.go +++ b/references/cli/dryrun.go @@ -1,26 +1,36 @@ package cli import ( + "bytes" "context" "encoding/json" + "fmt" "io/ioutil" + "os" "path/filepath" "github.com/pkg/errors" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" corev1alpha2 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2" "github.com/oam-dev/kubevela/apis/types" "github.com/oam-dev/kubevela/pkg/appfile" + "github.com/oam-dev/kubevela/pkg/dsl/definition" + "github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/oam/discoverymapper" oamutil "github.com/oam-dev/kubevela/pkg/oam/util" + "github.com/oam-dev/kubevela/pkg/utils/common" cmdutil "github.com/oam-dev/kubevela/pkg/utils/util" + appfile2 "github.com/oam-dev/kubevela/references/appfile" ) type dryRunOptions struct { cmdutil.IOStreams applicationFile string + definitionFile string } // NewDryRunCommand creates `dry-run` command @@ -29,8 +39,8 @@ func NewDryRunCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command cmd := &cobra.Command{ Use: "dry-run", DisableFlagsInUseLine: true, - Short: "Dry Run an application, and output the conversion result to stdout", - Long: "Dry Run an application, and output the conversion result to stdout", + Short: "Dry Run an application, and output the K8s resources as result to stdout", + Long: "Dry Run an application, and output the K8s resources as result to stdout, only CUE template supported for now", Example: "vela dry-run", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { return c.SetConfig() @@ -41,6 +51,27 @@ func NewDryRunCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command return err } + velaEnv, err := GetEnv(cmd) + if err != nil { + return err + } + if o.definitionFile != "" { + objs, err := ReadObjectsFromFile(o.definitionFile) + if err != nil { + return err + } + for _, obj := range objs { + if obj.GetNamespace() == "" { + obj.SetNamespace(velaEnv.Namespace) + } + } + if err = appfile2.CreateOrUpdateObjects(context.TODO(), newClient, objs); err != nil { + return err + } + } + if err := definition.AddKubeCUEPackagesFromCluster(c.Config); err != nil { + return err + } dm, err := discoverymapper.New(c.Config) if err != nil { return err @@ -53,11 +84,6 @@ func NewDryRunCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command parser := appfile.NewApplicationParser(newClient, dm) - velaEnv, err := GetEnv(cmd) - if err != nil { - return err - } - ctx := oamutil.SetNamespaceInCtx(context.Background(), velaEnv.Namespace) appFile, err := parser.GenerateAppFile(ctx, app.Name, app) @@ -69,26 +95,75 @@ func NewDryRunCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command if err != nil { return errors.WithMessage(err, "generate OAM objects") } - - var outs = []interface{}{ac} - for index := range comps { - outs = append(outs, comps[index]) + var buff = bytes.Buffer{} + var components = make(map[string]runtime.RawExtension) + for _, comp := range comps { + components[comp.Name] = comp.Spec.Workload } - - result, err := yaml.Marshal(outs) - if err != nil { - return errors.WithMessage(err, "marshal result object in yaml format") + for _, c := range ac.Spec.Components { + buff.Write([]byte(fmt.Sprintf("---\n# Application(%s) -- Comopnent(%s) \n---\n\n", ac.Name, c.ComponentName))) + result, err := yaml.Marshal(components[c.ComponentName]) + if err != nil { + return errors.WithMessage(err, "marshal result for component "+c.ComponentName+" object in yaml format") + } + buff.Write(result) + buff.Write([]byte("\n---\n")) + for _, t := range c.Traits { + result, err := yaml.Marshal(t.Trait) + if err != nil { + return errors.WithMessage(err, "marshal result for component "+c.ComponentName+" object in yaml format") + } + buff.Write(result) + buff.Write([]byte("\n---\n")) + } + buff.Write([]byte("\n")) } - o.Info(string(result)) + o.Info(buff.String()) return nil }, } cmd.Flags().StringVarP(&o.applicationFile, "file", "f", "./app.yaml", "application file name") + cmd.Flags().StringVarP(&o.definitionFile, "definition", "d", "", "specify a definition file or directory, it will automatically applied to the K8s cluster") cmd.SetOut(ioStreams.Out) return cmd } +// ReadObjectsFromFile will read objects from file or dir in the format of yaml +func ReadObjectsFromFile(path string) ([]oam.Object, error) { + fi, err := os.Stat(path) + if err != nil { + return nil, err + } + if !fi.IsDir() { + obj := &unstructured.Unstructured{} + err = common.ReadYamlToObject(path, obj) + if err != nil { + return nil, err + } + return []oam.Object{obj}, nil + } + + var objs []oam.Object + //nolint:gosec + fis, err := ioutil.ReadDir(path) + if err != nil { + return nil, err + } + for _, fi := range fis { + if fi.IsDir() { + continue + } + obj := &unstructured.Unstructured{} + err = common.ReadYamlToObject(filepath.Join(path, fi.Name()), obj) + if err != nil { + return nil, err + } + objs = append(objs, obj) + } + return objs, nil +} + func readApplicationFromFile(filename string) (*corev1alpha2.Application, error) { fileContent, err := ioutil.ReadFile(filepath.Clean(filename)) diff --git a/test/e2e-test/component_version_test.go b/test/e2e-test/component_version_test.go index 27fdbf7e8..1cd4f3f03 100644 --- a/test/e2e-test/component_version_test.go +++ b/test/e2e-test/component_version_test.go @@ -4,13 +4,11 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/ghodss/yaml" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -21,6 +19,7 @@ import ( "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2" "github.com/oam-dev/kubevela/pkg/oam/util" + "github.com/oam-dev/kubevela/pkg/utils/common" ) var _ = Describe("Versioning mechanism of components", func() { @@ -307,7 +306,7 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create trait definition") var td v1alpha2.TraitDefinition - Expect(readYaml("testdata/revision/trait-def.yaml", &td)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/trait-def.yaml", &td)).Should(BeNil()) var gtd v1alpha2.TraitDefinition if err := k8sClient.Get(ctx, client.ObjectKey{Name: td.Name, Namespace: td.Namespace}, >d); err != nil { @@ -319,12 +318,12 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create Component v1") var comp1 v1alpha2.Component - Expect(readYaml("testdata/revision/comp-v1.yaml", &comp1)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/comp-v1.yaml", &comp1)).Should(BeNil()) Expect(k8sClient.Create(ctx, &comp1)).Should(Succeed()) By("Create AppConfig with component") var appconfig v1alpha2.ApplicationConfiguration - Expect(readYaml("testdata/revision/app.yaml", &appconfig)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/app.yaml", &appconfig)).Should(BeNil()) Expect(k8sClient.Create(ctx, &appconfig)).Should(Succeed()) By("Get Component latest status after ControllerRevision created") @@ -351,7 +350,7 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create Component v2") var comp2 v1alpha2.Component - Expect(readYaml("testdata/revision/comp-v2.yaml", &comp2)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/comp-v2.yaml", &comp2)).Should(BeNil()) comp2.ResourceVersion = comp1.ResourceVersion Expect(k8sClient.Update(ctx, &comp2)).Should(Succeed()) @@ -411,7 +410,7 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create trait definition") var td v1alpha2.TraitDefinition - Expect(readYaml("testdata/revision/trait-def-no-revision.yaml", &td)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/trait-def-no-revision.yaml", &td)).Should(BeNil()) var gtd v1alpha2.TraitDefinition if err := k8sClient.Get(ctx, client.ObjectKey{Name: td.Name, Namespace: td.Namespace}, >d); err != nil { Expect(k8sClient.Create(ctx, &td)).Should(Succeed()) @@ -422,12 +421,12 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create Component v1") var comp1 v1alpha2.Component - Expect(readYaml("testdata/revision/comp-v1.yaml", &comp1)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/comp-v1.yaml", &comp1)).Should(BeNil()) Expect(k8sClient.Create(ctx, &comp1)).Should(Succeed()) By("Create AppConfig with component") var appconfig v1alpha2.ApplicationConfiguration - Expect(readYaml("testdata/revision/app.yaml", &appconfig)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/app.yaml", &appconfig)).Should(BeNil()) Expect(k8sClient.Create(ctx, &appconfig)).Should(Succeed()) By("Workload created with component name") @@ -445,7 +444,7 @@ var _ = Describe("Versioning mechanism of components", func() { By("Create Component v2") var comp2 v1alpha2.Component - Expect(readYaml("testdata/revision/comp-v2.yaml", &comp2)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/comp-v2.yaml", &comp2)).Should(BeNil()) Eventually(func() error { tmp := &v1alpha2.Component{} k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: componentName}, tmp) @@ -486,14 +485,6 @@ var _ = Describe("Versioning mechanism of components", func() { }) }) -func readYaml(path string, object runtime.Object) error { - data, err := ioutil.ReadFile(path) - if err != nil { - return err - } - return yaml.Unmarshal(data, object) -} - var _ = Describe("Component revision", func() { ctx := context.Background() apiVersion := "core.oam.dev/v1alpha2" diff --git a/test/e2e-test/rollout_plan_test.go b/test/e2e-test/rollout_plan_test.go index fadeaee2b..3294cf0e8 100644 --- a/test/e2e-test/rollout_plan_test.go +++ b/test/e2e-test/rollout_plan_test.go @@ -21,6 +21,7 @@ import ( "github.com/oam-dev/kubevela/pkg/controller/utils" "github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/oam/util" + "github.com/oam-dev/kubevela/pkg/utils/common" ) var _ = Describe("Cloneset based rollout tests", func() { @@ -64,7 +65,7 @@ var _ = Describe("Cloneset based rollout tests", func() { CreateClonesetDef := func() { By("Install CloneSet based componentDefinition") var cd v1alpha2.ComponentDefinition - Expect(readYaml("testdata/rollout/cloneset/clonesetDefinition.yaml", &cd)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/clonesetDefinition.yaml", &cd)).Should(BeNil()) // create the componentDefinition if not exist Eventually( func() error { @@ -104,7 +105,7 @@ var _ = Describe("Cloneset based rollout tests", func() { ApplySourceApp := func() { By("Apply an application") var newApp v1alpha2.Application - Expect(readYaml("testdata/rollout/cloneset/app-source.yaml", &newApp)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-source.yaml", &newApp)).Should(BeNil()) newApp.Namespace = namespace Expect(k8sClient.Create(ctx, &newApp)).Should(Succeed()) @@ -141,7 +142,7 @@ var _ = Describe("Cloneset based rollout tests", func() { ApplyTargetApp := func() { By("Update the application to target spec during rolling") var targetApp v1alpha2.Application - Expect(readYaml("testdata/rollout/cloneset/app-target.yaml", &targetApp)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-target.yaml", &targetApp)).Should(BeNil()) Eventually( func() error { @@ -257,7 +258,7 @@ var _ = Describe("Cloneset based rollout tests", func() { By("Revert the application back to source") var sourceApp v1alpha2.Application - Expect(readYaml("testdata/rollout/cloneset/app-source.yaml", &sourceApp)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-source.yaml", &sourceApp)).Should(BeNil()) sourceApp.SetAnnotations(util.MergeMapOverrideWithDst(app.GetAnnotations(), map[string]string{oam.AnnotationRollingComponent: app.Spec.Components[0].Name, oam.AnnotationAppRollout: strconv.FormatBool(true)})) @@ -320,7 +321,7 @@ var _ = Describe("Cloneset based rollout tests", func() { ApplyTwoAppVersion() By("Apply the application rollout go directly to the target") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace newAppRollout.Spec.SourceAppRevisionName = "" Expect(k8sClient.Create(ctx, &newAppRollout)).Should(Succeed()) @@ -347,7 +348,7 @@ var _ = Describe("Cloneset based rollout tests", func() { By("Apply the application rollout that stops after the first batch") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace batchPartition := 0 newAppRollout.Spec.RolloutPlan.BatchPartition = pointer.Int32Ptr(int32(batchPartition)) @@ -407,7 +408,7 @@ var _ = Describe("Cloneset based rollout tests", func() { By("Apply the application rollout") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace Expect(k8sClient.Create(ctx, &newAppRollout)).Should(Succeed()) @@ -482,7 +483,7 @@ var _ = Describe("Cloneset based rollout tests", func() { By("Apply the application rollout") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace Expect(k8sClient.Create(ctx, &newAppRollout)).Should(Succeed()) By("Wait for the rollout phase change to rolling in batches") @@ -508,7 +509,7 @@ var _ = Describe("Cloneset based rollout tests", func() { By("Apply the application rollout that stops after the first batche") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace batchPartition := 1 newAppRollout.Spec.RolloutPlan.BatchPartition = pointer.Int32Ptr(int32(batchPartition)) @@ -565,7 +566,7 @@ var _ = Describe("Cloneset based rollout tests", func() { MarkAppRolling(1) By("Apply the definition change") var cd, newCD v1alpha2.ComponentDefinition - Expect(readYaml("testdata/rollout/cloneset/clonesetDefinitionModified.yaml.yaml", &newCD)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/clonesetDefinitionModified.yaml.yaml", &newCD)).Should(BeNil()) Eventually( func() error { k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: newCD.Name}, &cd) @@ -576,7 +577,7 @@ var _ = Describe("Cloneset based rollout tests", func() { VerifyAppConfigTemplated(2) By("Apply the application rollout") var newAppRollout v1alpha2.AppRollout - Expect(readYaml("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/rollout/cloneset/app-rollout.yaml", &newAppRollout)).Should(BeNil()) newAppRollout.Namespace = namespace newAppRollout.Spec.RolloutPlan.BatchPartition = pointer.Int32Ptr(int32(len(newAppRollout.Spec.RolloutPlan. RolloutBatches) - 1)) diff --git a/test/e2e-test/suite_test.go b/test/e2e-test/suite_test.go index 763aef19a..f4e6d2058 100644 --- a/test/e2e-test/suite_test.go +++ b/test/e2e-test/suite_test.go @@ -44,6 +44,7 @@ import ( core "github.com/oam-dev/kubevela/apis/core.oam.dev" "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2" "github.com/oam-dev/kubevela/pkg/oam/util" + "github.com/oam-dev/kubevela/pkg/utils/common" // +kubebuilder:scaffold:imports ) @@ -100,15 +101,15 @@ var _ = BeforeSuite(func(done Done) { // TODO: Remove this after we get rid of the integration test dir By("Applying CRD of ComponentDefinition, WorkloadDefinition and TraitDefinition") var componentDefinitionCRD crdv1.CustomResourceDefinition - Expect(readYaml("../../charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml", &componentDefinitionCRD)).Should(BeNil()) + Expect(common.ReadYamlToObject("../../charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml", &componentDefinitionCRD)).Should(BeNil()) Expect(k8sClient.Create(context.Background(), &componentDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) var workloadDefinitionCRD crdv1.CustomResourceDefinition - Expect(readYaml("../../charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml", &workloadDefinitionCRD)).Should(BeNil()) + Expect(common.ReadYamlToObject("../../charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml", &workloadDefinitionCRD)).Should(BeNil()) Expect(k8sClient.Create(context.Background(), &workloadDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) var traitDefinitionCRD crdv1.CustomResourceDefinition - Expect(readYaml("../../charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml", &traitDefinitionCRD)).Should(BeNil()) + Expect(common.ReadYamlToObject("../../charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml", &traitDefinitionCRD)).Should(BeNil()) Expect(k8sClient.Create(context.Background(), &traitDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) By("Finished setting up test environment") @@ -275,7 +276,7 @@ var _ = BeforeSuite(func(done Done) { By("Create workload definition for revision mechanism test") var nwd v1alpha2.WorkloadDefinition - Expect(readYaml("testdata/revision/workload-def.yaml", &nwd)).Should(BeNil()) + Expect(common.ReadYamlToObject("testdata/revision/workload-def.yaml", &nwd)).Should(BeNil()) Eventually( func() error { return k8sClient.Create(context.Background(), &nwd)