From 0753734372fb5f232900af39d22b9a73a8a1fc74 Mon Sep 17 00:00:00 2001 From: wangyuan249 <35907099+wangyuan249@users.noreply.github.com> Date: Wed, 26 May 2021 21:16:40 +0800 Subject: [PATCH] vela show support show the parameters of KUBE model ComponentDefinition (#1693) * vela show support show the paramters of KUBE model ComponentDefinition * fix * fix fix * enchance test case and add function in show -web fmt and vet fix fix522 * add resolve for kubedef type trait in reconcil process * fix StoreOpenAPISchema args para and ret para * fix GetCapabilityObject uncover --- apis/types/capability.go | 7 ++ e2e/plugin/plugin_suit_test.go | 12 +++ e2e/plugin/plugin_test.go | 92 +++++++++++++++++++ .../traitdefinition_controller.go | 6 +- pkg/controller/utils/capability.go | 45 +++++++-- references/cli/show.go | 7 +- references/plugins/cluster.go | 8 +- references/plugins/cluster_test.go | 42 ++++++++- references/plugins/reference_test.go | 4 +- references/plugins/references.go | 58 ++++++++---- references/plugins/testdata/kube-worker.yaml | 40 ++++++++ references/plugins/testdata/svcTraitDef.yaml | 30 ++++++ 12 files changed, 311 insertions(+), 40 deletions(-) create mode 100644 references/plugins/testdata/kube-worker.yaml create mode 100644 references/plugins/testdata/svcTraitDef.yaml diff --git a/apis/types/capability.go b/apis/types/capability.go index 58a128088..a9ba3d623 100644 --- a/apis/types/capability.go +++ b/apis/types/capability.go @@ -22,6 +22,9 @@ import ( "cuelang.org/go/cue" "github.com/google/go-cmp/cmp" "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/oam-dev/kubevela/apis/core.oam.dev/common" ) // Source record the source of Capability @@ -62,6 +65,10 @@ type Capability struct { // Terraform TerraformConfiguration string `json:"terraformConfiguration,omitempty"` + + // KubeTemplate + KubeTemplate runtime.RawExtension `json:"kubetemplate,omitempty"` + KubeParameter []common.KubeParameter `json:"kubeparameter,omitempty"` } // Chart defines all necessary information to install a whole chart diff --git a/e2e/plugin/plugin_suit_test.go b/e2e/plugin/plugin_suit_test.go index 0e2cffb8e..74ebe9dbb 100644 --- a/e2e/plugin/plugin_suit_test.go +++ b/e2e/plugin/plugin_suit_test.go @@ -45,7 +45,9 @@ var testShowCdDef v1beta1.ComponentDefinition var testShowTdDef v1beta1.TraitDefinition var testCdDef v1beta1.ComponentDefinition var testCdDefWithHelm v1beta1.ComponentDefinition +var testCdDefWithKube v1beta1.ComponentDefinition var testTdDef v1beta1.TraitDefinition +var testTdDefWithKube v1beta1.TraitDefinition func TestKubectlPlugin(t *testing.T) { RegisterFailHandler(Fail) @@ -82,10 +84,18 @@ var _ = BeforeSuite(func(done Done) { err = k8sClient.Create(ctx, &testCdDefWithHelm) Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + Expect(yaml.Unmarshal([]byte(componentDefWithKube), &testCdDefWithKube)).Should(BeNil()) + err = k8sClient.Create(ctx, &testCdDefWithKube) + Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + Expect(yaml.Unmarshal([]byte(traitDef), &testTdDef)).Should(BeNil()) err = k8sClient.Create(ctx, &testTdDef) Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + Expect(yaml.Unmarshal([]byte(traitDefWithKube), &testTdDefWithKube)).Should(BeNil()) + err = k8sClient.Create(ctx, &testTdDefWithKube) + Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + Expect(yaml.Unmarshal([]byte(testShowComponentDef), &testShowCdDef)).Should(BeNil()) err = k8sClient.Create(ctx, &testShowCdDef) Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) @@ -111,7 +121,9 @@ var _ = AfterSuite(func() { Expect(k8sClient.Delete(ctx, &app)).Should(BeNil()) Expect(k8sClient.Delete(ctx, &testCdDef)).Should(BeNil()) Expect(k8sClient.Delete(ctx, &testCdDefWithHelm)).Should(BeNil()) + Expect(k8sClient.Delete(ctx, &testCdDefWithKube)).Should(BeNil()) Expect(k8sClient.Delete(ctx, &testTdDef)).Should(BeNil()) + Expect(k8sClient.Delete(ctx, &testTdDefWithKube)).Should(BeNil()) Expect(k8sClient.Delete(ctx, &testShowCdDef)).Should(BeNil()) Expect(k8sClient.Delete(ctx, &testShowTdDef)).Should(BeNil()) }) diff --git a/e2e/plugin/plugin_test.go b/e2e/plugin/plugin_test.go index ce7c493f9..5a3e5d5c0 100644 --- a/e2e/plugin/plugin_test.go +++ b/e2e/plugin/plugin_test.go @@ -124,6 +124,22 @@ var _ = Describe("Test Kubectl Plugin", func() { Expect(err).NotTo(HaveOccurred()) Expect(output).Should(ContainSubstring("Properties")) }) + It("Test show componentDefinition def with raw Kube mode", func() { + cdName := "kube-worker" + output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", cdName)) + Expect(err).NotTo(HaveOccurred()) + Expect(output).Should(ContainSubstring("image")) + Expect(output).Should(ContainSubstring("The value will be applied to fields: [spec.template.spec.containers[0].image].")) + Expect(output).Should(ContainSubstring("port")) + Expect(output).Should(ContainSubstring("the specific container port num which can accept external request.")) + }) + It("Test show traitDefinition def with raw Kube mode", func() { + tdName := "service-kube" + output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName)) + Expect(err).NotTo(HaveOccurred()) + Expect(output).Should(ContainSubstring("targetPort")) + Expect(output).Should(ContainSubstring("target port num for service provider.")) + }) }) Context("Test kubectl vela comp discover", func() { @@ -430,6 +446,49 @@ spec: url: "http://oam.dev/catalog/" ` +var componentDefWithKube = ` +apiVersion: core.oam.dev/v1beta1 +kind: ComponentDefinition +metadata: + name: kube-worker + namespace: default +spec: + workload: + definition: + apiVersion: apps/v1 + kind: Deployment + schematic: + kube: + template: + apiVersion: apps/v1 + kind: Deployment + spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + ports: + - containerPort: 80 + parameters: + - name: image + required: true + type: string + fieldPaths: + - "spec.template.spec.containers[0].image" + - name: port + required: true + type: string + fieldPaths: + - "spec.template.spec.containers[0].ports[0].containerPort" + description: "the specific container port num which can accept external request." +` + var traitDef = ` apiVersion: core.oam.dev/v1beta1 kind: TraitDefinition @@ -505,6 +564,39 @@ spec: ` +var traitDefWithKube = ` +apiVersion: core.oam.dev/v1beta1 +kind: TraitDefinition +metadata: + name: service-kube + namespace: default +spec: + appliesToWorkloads: + - webservice + - worker + - backend + podDisruptive: true + schematic: + kube: + template: + apiVersion: v1 + kind: Service + metadata: + name: my-service + spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + parameters: + - name: targetPort + required: true + type: number + fieldPaths: + - "spec.template.spec.ports[0].targetPort" + description: "target port num for service provider." +` + var dryRunResult = `--- # Application(test-vela-app) -- Comopnent(express-server) --- diff --git a/pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition/traitdefinition_controller.go b/pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition/traitdefinition_controller.go index 237de5f26..4e28e3e78 100644 --- a/pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition/traitdefinition_controller.go +++ b/pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition/traitdefinition_controller.go @@ -109,10 +109,8 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { return ctrl.Result{}, nil } - def := utils.CapabilityTraitDefinition{ - Name: traitdefinition.Name, - TraitDefinition: traitdefinition, - } + def := utils.NewCapabilityTraitDef(&traitdefinition) + def.Name = req.NamespacedName.Name // Store the parameter of traitDefinition to configMap cmName, err := def.StoreOpenAPISchema(ctx, r.Client, r.pd, req.Namespace, req.Name, defRev.Name) diff --git a/pkg/controller/utils/capability.go b/pkg/controller/utils/capability.go index 5d7e9202d..317799b97 100644 --- a/pkg/controller/utils/capability.go +++ b/pkg/controller/utils/capability.go @@ -95,8 +95,8 @@ func (def *CapabilityComponentDefinition) GetOpenAPISchema(pd *definition.Packag return getOpenAPISchema(capability, pd) } -// GetKubeSchematicOpenAPISchema gets OpenAPI v3 schema based on kube schematic parameters -func (def *CapabilityComponentDefinition) GetKubeSchematicOpenAPISchema(params []commontypes.KubeParameter) ([]byte, error) { +// GetKubeSchematicOpenAPISchema gets OpenAPI v3 schema based on kube schematic parameters for component and trait definition +func GetKubeSchematicOpenAPISchema(params []commontypes.KubeParameter) ([]byte, error) { required := []string{} properties := map[string]*openapi3.Schema{} for _, p := range params { @@ -114,10 +114,12 @@ func (def *CapabilityComponentDefinition) GetKubeSchematicOpenAPISchema(params [ if p.Required != nil && *p.Required { required = append(required, p.Name) } - // save FieldPaths into description - tmp.Description = fmt.Sprintf("The value will be applied to fields: [%s].", strings.Join(p.FieldPaths, ",")) + if p.Description != nil { - tmp.Description = fmt.Sprintf("%s\n %s", tmp.Description, *p.Description) + tmp.Description = fmt.Sprintf("%s %s", tmp.Description, *p.Description) + } else { + // save FieldPaths into description + tmp.Description = fmt.Sprintf("The value will be applied to fields: [%s].", strings.Join(p.FieldPaths, ",")) } properties[p.Name] = tmp } @@ -141,7 +143,7 @@ func (def *CapabilityComponentDefinition) StoreOpenAPISchema(ctx context.Context case util.HELMDef: jsonSchema, err = helm.GetChartValuesJSONSchema(ctx, def.Helm) case util.KubeDef: - jsonSchema, err = def.GetKubeSchematicOpenAPISchema(def.Kube.Parameters) + jsonSchema, err = GetKubeSchematicOpenAPISchema(def.Kube.Parameters) default: jsonSchema, err = def.GetOpenAPISchema(pd, name) } @@ -173,9 +175,26 @@ func (def *CapabilityComponentDefinition) StoreOpenAPISchema(ctx context.Context type CapabilityTraitDefinition struct { Name string `json:"name"` TraitDefinition v1beta1.TraitDefinition `json:"traitDefinition"` + + DefCategoryType util.WorkloadType `json:"defCategoryType"` + + Kube *commontypes.Kube `json:"kube"` + CapabilityBaseDefinition } +// NewCapabilityTraitDef will create a CapabilityTraitDefinition +func NewCapabilityTraitDef(traitdefinition *v1beta1.TraitDefinition) CapabilityTraitDefinition { + var def CapabilityTraitDefinition + def.Name = traitdefinition.Name // or def.Name = req.NamespacedName.Name + if traitdefinition.Spec.Schematic != nil && traitdefinition.Spec.Schematic.KUBE != nil { + def.DefCategoryType = util.KubeDef + def.Kube = traitdefinition.Spec.Schematic.KUBE + } + def.TraitDefinition = *traitdefinition.DeepCopy() + return def +} + // GetOpenAPISchema gets OpenAPI v3 schema by TraitDefinition name func (def *CapabilityTraitDefinition) GetOpenAPISchema(pd *definition.PackageDiscover, name string) ([]byte, error) { capability, err := appfile.ConvertTemplateJSON2Object(name, def.TraitDefinition.Spec.Extension, def.TraitDefinition.Spec.Schematic) @@ -186,11 +205,17 @@ func (def *CapabilityTraitDefinition) GetOpenAPISchema(pd *definition.PackageDis } // StoreOpenAPISchema stores OpenAPI v3 schema from TraitDefinition in ConfigMap -func (def *CapabilityTraitDefinition) StoreOpenAPISchema(ctx context.Context, k8sClient client.Client, - pd *definition.PackageDiscover, namespace, name, revName string) (string, error) { - jsonSchema, err := def.GetOpenAPISchema(pd, name) +func (def *CapabilityTraitDefinition) StoreOpenAPISchema(ctx context.Context, k8sClient client.Client, pd *definition.PackageDiscover, namespace, name string, revName string) (string, error) { + var jsonSchema []byte + var err error + switch def.DefCategoryType { + case util.KubeDef: // Kube template + jsonSchema, err = GetKubeSchematicOpenAPISchema(def.Kube.Parameters) + default: // CUE template + jsonSchema, err = def.GetOpenAPISchema(pd, name) + } if err != nil { - return "", fmt.Errorf(util.ErrGenerateOpenAPIV2JSONSchemaForCapability, def.Name, err) + return "", fmt.Errorf("failed to generate OpenAPI v3 JSON schema for capability %s: %w", def.Name, err) } traitDefinition := def.TraitDefinition diff --git a/references/cli/show.go b/references/cli/show.go index f6c6060e8..ed1080fbc 100644 --- a/references/cli/show.go +++ b/references/cli/show.go @@ -366,7 +366,12 @@ func ShowReferenceConsole(ctx context.Context, c common.Args, ioStreams cmdutil. var propertyConsole []plugins.ConsoleReference switch capability.Category { case types.HelmCategory: - _, propertyConsole, err = ref.GenerateHELMProperties(ctx, capability) + _, propertyConsole, err = ref.GenerateHelmAndKubeProperties(ctx, capability) + if err != nil { + return err + } + case types.KubeCategory: + _, propertyConsole, err = ref.GenerateHelmAndKubeProperties(ctx, capability) if err != nil { return err } diff --git a/references/plugins/cluster.go b/references/plugins/cluster.go index 77fe42ce2..6c9f3e7da 100644 --- a/references/plugins/cluster.go +++ b/references/plugins/cluster.go @@ -245,6 +245,12 @@ func HandleTemplate(in *runtime.RawExtension, schematic *commontypes.Schematic, tmp.TerraformConfiguration = schematic.Terraform.Configuration return tmp, nil } + if schematic.KUBE != nil { + tmp.Category = types.KubeCategory + tmp.KubeTemplate = schematic.KUBE.Template + tmp.KubeParameter = schematic.KUBE.Parameters + return tmp, nil + } } if tmp.CueTemplateURI != "" { b, err := common.HTTPGet(context.Background(), tmp.CueTemplateURI) @@ -325,7 +331,7 @@ func GetCapabilityByName(ctx context.Context, c common.Args, capabilityName stri } return capability, nil } - return nil, fmt.Errorf("cloud not find %s is namespace %s, or %s", capabilityName, ns, types.DefaultKubeVelaNS) + return nil, fmt.Errorf("could not find %s in namespace %s, or %s", capabilityName, ns, types.DefaultKubeVelaNS) } // GetCapabilityByComponentDefinitionObject gets capability by ComponentDefinition object diff --git a/references/plugins/cluster_test.go b/references/plugins/cluster_test.go index 11d001e2f..0d0417a82 100644 --- a/references/plugins/cluster_test.go +++ b/references/plugins/cluster_test.go @@ -18,6 +18,7 @@ package plugins import ( "context" + "encoding/json" "fmt" "io/ioutil" @@ -145,12 +146,16 @@ var _ = Describe("test GetCapabilityByName", func() { defaultNS string cd1 corev1beta1.ComponentDefinition cd2 corev1beta1.ComponentDefinition + cd3 corev1beta1.ComponentDefinition td1 corev1beta1.TraitDefinition td2 corev1beta1.TraitDefinition + td3 corev1beta1.TraitDefinition component1 string component2 string + component3 string trait1 string trait2 string + trait3 string ) BeforeEach(func() { c = common.Args{ @@ -159,12 +164,15 @@ var _ = Describe("test GetCapabilityByName", func() { Schema: scheme, } ctx = context.Background() - ns = "cluster-test-ns" + ns = "cluster-test-ns-suffix" defaultNS = types.DefaultKubeVelaNS component1 = "cd1" component2 = "cd2" + component3 = "cd3" + trait1 = "td1" trait2 = "td2" + trait3 = "td3" By("create namespace") Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) @@ -174,6 +182,8 @@ var _ = Describe("test GetCapabilityByName", func() { data, _ := ioutil.ReadFile("testdata/componentDef.yaml") yaml.Unmarshal(data, &cd1) yaml.Unmarshal(data, &cd2) + data2, _ := ioutil.ReadFile("testdata/kube-worker.yaml") + yaml.Unmarshal(data2, &cd3) cd1.Namespace = ns cd1.Name = component1 Expect(k8sClient.Create(ctx, &cd1)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) @@ -182,10 +192,16 @@ var _ = Describe("test GetCapabilityByName", func() { cd2.Name = component2 Expect(k8sClient.Create(ctx, &cd2)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + cd3.Namespace = ns + cd3.Name = component3 + Expect(k8sClient.Create(ctx, &cd3)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + By("create TraitDefinition") data, _ = ioutil.ReadFile("testdata/manualscalars.yaml") yaml.Unmarshal(data, &td1) yaml.Unmarshal(data, &td2) + data3, _ := ioutil.ReadFile("testdata/svcTraitDef.yaml") + yaml.Unmarshal(data3, &td3) td1.Namespace = ns td1.Name = trait1 Expect(k8sClient.Create(ctx, &td1)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) @@ -194,6 +210,10 @@ var _ = Describe("test GetCapabilityByName", func() { td2.Name = trait2 Expect(k8sClient.Create(ctx, &td2)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + td3.Namespace = ns + td3.Name = trait3 + Expect(k8sClient.Create(ctx, &td3)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) + }) It("get capability", func() { @@ -205,15 +225,33 @@ var _ = Describe("test GetCapabilityByName", func() { _, err := GetCapabilityByName(ctx, c, component2, ns) Expect(err).Should(BeNil()) }) + Context("ComponentDefinition is in the default namespace", func() { + cap, err := GetCapabilityByName(ctx, c, component3, ns) + Expect(err).Should(BeNil()) + jsontmp, err := json.Marshal(cap.KubeParameter) + Expect(err).Should(BeNil()) + Expect(string(jsontmp)).Should(ContainSubstring("image")) + Expect(string(jsontmp)).Should(ContainSubstring("spec.template.spec.containers[0].image")) + Expect(string(jsontmp)).Should(ContainSubstring("port")) + Expect(string(jsontmp)).Should(ContainSubstring("the specific container port num which can accept external request.")) + }) Context("TraitDefinition is in the current namespace", func() { _, err := GetCapabilityByName(ctx, c, trait1, ns) Expect(err).Should(BeNil()) }) - Context("TraitDefinitionDefinition is in the default namespace", func() { + Context("TraitDefinition is in the default namespace", func() { _, err := GetCapabilityByName(ctx, c, trait2, ns) Expect(err).Should(BeNil()) }) + Context("TraitDefinition is in the default namespace", func() { + cap, err := GetCapabilityByName(ctx, c, trait3, ns) + Expect(err).Should(BeNil()) + jsontmp, err := json.Marshal(cap.KubeParameter) + Expect(err).Should(BeNil()) + Expect(string(jsontmp)).Should(ContainSubstring("targetPort")) + Expect(string(jsontmp)).Should(ContainSubstring("target port num for service provider.")) + }) Context("capability cloud not be found", func() { _, err := GetCapabilityByName(ctx, c, "a-component-definition-not-existed", ns) diff --git a/references/plugins/reference_test.go b/references/plugins/reference_test.go index 5f1ecbee6..465d3e793 100644 --- a/references/plugins/reference_test.go +++ b/references/plugins/reference_test.go @@ -337,14 +337,14 @@ func TestWalkParameterSchema(t *testing.T) { }, } for _, cases := range testcases { - helmRefs = make([]HELMReference, 0) + commonRefs = make([]CommonReference, 0) parameterJSON := fmt.Sprintf(BaseOpenAPIV3Template, cases.data) swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(json.RawMessage(parameterJSON)) assert.Equal(t, nil, err) parameters := swagger.Components.Schemas["parameter"].Value WalkParameterSchema(parameters, "Properties", 0) refs := make(map[string]map[string]ReferenceParameter) - for _, items := range helmRefs { + for _, items := range commonRefs { refs[items.Name] = make(map[string]ReferenceParameter) for _, item := range items.Parameters { refs[items.Name][item.Name] = item diff --git a/references/plugins/references.go b/references/plugins/references.go index dc7723c2d..0a54a904f 100644 --- a/references/plugins/references.go +++ b/references/plugins/references.go @@ -347,7 +347,7 @@ var refContent string var recurseDepth *int var propertyConsole []ConsoleReference var displayFormat *string -var helmRefs []HELMReference +var commonRefs []CommonReference func setDisplayFormat(format string) { displayFormat = &format @@ -416,13 +416,21 @@ func (ref *MarkdownReference) CreateMarkdown(ctx context.Context, caps []types.C return err } case types.HelmCategory: - properties, _, err := ref.GenerateHELMProperties(ctx, &caps[i]) + properties, _, err := ref.GenerateHelmAndKubeProperties(ctx, &caps[i]) if err != nil { return fmt.Errorf("failed to retrieve `parameters` value from %s with err: %w", c.Name, err) } for _, property := range properties { refContent += ref.prepareParameter("#"+property.Name, property.Parameters, types.HelmCategory) } + case types.KubeCategory: + properties, _, err := ref.GenerateHelmAndKubeProperties(ctx, &caps[i]) + if err != nil { + return fmt.Errorf("failed to retrieve `parameters` value from %s with err: %w", c.Name, err) + } + for _, property := range properties { + refContent += ref.prepareParameter("#"+property.Name, property.Parameters, types.KubeCategory) + } case types.TerraformCategory: refContent, err = ref.GenerateTerraformCapabilityProperties(c) if err != nil { @@ -468,9 +476,14 @@ func (ref *MarkdownReference) prepareParameter(tableName string, parameterList [ } case types.HelmCategory: for _, p := range parameterList { - printableDefaultValue := ref.getHELMPrintableDefaultValue(p.JSONType, p.Default) + printableDefaultValue := ref.getJSONPrintableDefaultValue(p.JSONType, p.Default) refContent += fmt.Sprintf(" %s | %s | %s | %t | %s \n", p.Name, strings.ReplaceAll(p.Usage, "\n", ""), p.PrintableType, p.Required, printableDefaultValue) } + case types.KubeCategory: + for _, p := range parameterList { + // Kubeparameter doesn't have default value + refContent += fmt.Sprintf(" %s | %s | %s | %t | %s \n", p.Name, strings.ReplaceAll(p.Usage, "\n", ""), p.PrintableType, p.Required, "") + } case types.TerraformCategory: // Terraform doesn't have default value for _, p := range parameterList { @@ -494,9 +507,14 @@ func (ref *ParseReference) prepareParameter(tableName string, parameterList []Re } case types.HelmCategory: for _, p := range parameterList { - printableDefaultValue := ref.getHELMPrintableDefaultValue(p.JSONType, p.Default) + printableDefaultValue := ref.getJSONPrintableDefaultValue(p.JSONType, p.Default) table.Append([]string{p.Name, p.Usage, p.PrintableType, strconv.FormatBool(p.Required), printableDefaultValue}) } + case types.KubeCategory: + for _, p := range parameterList { + printableDefaultValue := ref.getJSONPrintableDefaultValue(p.JSONType, p.Default) + refContent += fmt.Sprintf(" %s | %s | %s | %t | %s \n", p.Name, strings.ReplaceAll(p.Usage, "\n", ""), p.PrintableType, p.Required, printableDefaultValue) + } case types.TerraformCategory: // Terraform doesn't have default value for _, p := range parameterList { @@ -622,7 +640,7 @@ func (ref *ParseReference) getCUEPrintableDefaultValue(v interface{}) string { return "" } -func (ref *ParseReference) getHELMPrintableDefaultValue(dataType string, value interface{}) string { +func (ref *ParseReference) getJSONPrintableDefaultValue(dataType string, value interface{}) string { if value != nil { return strings.TrimSpace(fmt.Sprintf("%v", value)) } @@ -676,24 +694,24 @@ func (ref *ConsoleReference) GenerateCUETemplateProperties(capability *types.Cap return propertyConsole, nil } -// HELMReference contains parameters info of HelmCategory type capability -type HELMReference struct { +// CommonReference contains parameters info of HelmCategory and KubuCategory type capability at present +type CommonReference struct { Name string Parameters []ReferenceParameter Depth int } -// HELMSchema is a struct contains *openapi3.Schema style parameter -type HELMSchema struct { +// CommonSchema is a struct contains *openapi3.Schema style parameter +type CommonSchema struct { Name string Schemas *openapi3.Schema } -// GenerateHELMProperties get all properties of a HelmCategory type capability -func (ref *ParseReference) GenerateHELMProperties(ctx context.Context, capability *types.Capability) ([]HELMReference, []ConsoleReference, error) { +// GenerateHelmAndKubeProperties get all properties of a Helm/Kube Category type capability +func (ref *ParseReference) GenerateHelmAndKubeProperties(ctx context.Context, capability *types.Capability) ([]CommonReference, []ConsoleReference, error) { cmName := fmt.Sprintf("%s%s", types.CapabilityConfigMapNamePrefix, capability.Name) var cm v1.ConfigMap - helmRefs = make([]HELMReference, 0) + commonRefs = make([]CommonReference, 0) if err := ref.Client.Get(ctx, client.ObjectKey{Namespace: capability.Namespace, Name: cmName}, &cm); err != nil { return nil, nil, err } @@ -710,10 +728,10 @@ func (ref *ParseReference) GenerateHELMProperties(ctx context.Context, capabilit WalkParameterSchema(parameters, "Properties", 0) var consoleRefs []ConsoleReference - for _, item := range helmRefs { + for _, item := range commonRefs { consoleRefs = append(consoleRefs, ref.prepareParameter(item.Name, item.Parameters, types.HelmCategory)) } - return helmRefs, consoleRefs, err + return commonRefs, consoleRefs, err } // GenerateTerraformCapabilityProperties generates Capability properties for Terraform ComponentDefinition @@ -781,8 +799,8 @@ func WalkParameterSchema(parameters *openapi3.Schema, name string, depth int) { if parameters == nil { return } - var schemas []HELMSchema - var helmParameters []ReferenceParameter + var schemas []CommonSchema + var commonParameters []ReferenceParameter for k, v := range parameters.Properties { p := ReferenceParameter{ Parameter: types.Parameter{ @@ -803,19 +821,19 @@ func WalkParameterSchema(parameters *openapi3.Schema, name string, depth int) { p.Required = required if v.Value.Type == "object" { if v.Value.Properties != nil { - schemas = append(schemas, HELMSchema{ + schemas = append(schemas, CommonSchema{ Name: k, Schemas: v.Value, }) } p.PrintableType = fmt.Sprintf("[%s](#%s)", k, k) } - helmParameters = append(helmParameters, p) + commonParameters = append(commonParameters, p) } - helmRefs = append(helmRefs, HELMReference{ + commonRefs = append(commonRefs, CommonReference{ Name: fmt.Sprintf("%s %s", strings.Repeat("#", depth+1), name), - Parameters: helmParameters, + Parameters: commonParameters, Depth: depth + 1, }) diff --git a/references/plugins/testdata/kube-worker.yaml b/references/plugins/testdata/kube-worker.yaml new file mode 100644 index 000000000..9bc2e150d --- /dev/null +++ b/references/plugins/testdata/kube-worker.yaml @@ -0,0 +1,40 @@ +apiVersion: core.oam.dev/v1beta1 +kind: ComponentDefinition +metadata: + name: kube-worker + namespace: default +spec: + workload: + definition: + apiVersion: apps/v1 + kind: Deployment + schematic: + kube: + template: + apiVersion: apps/v1 + kind: Deployment + spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + ports: + - containerPort: 80 + parameters: + - name: image + required: true + type: string + fieldPaths: + - "spec.template.spec.containers[0].image" + - name: port + required: true + type: string + fieldPaths: + - "spec.template.spec.containers[0].ports[0].containerPort" + description: "the specific container port num which can accept external request." diff --git a/references/plugins/testdata/svcTraitDef.yaml b/references/plugins/testdata/svcTraitDef.yaml new file mode 100644 index 000000000..900a91eb5 --- /dev/null +++ b/references/plugins/testdata/svcTraitDef.yaml @@ -0,0 +1,30 @@ +apiVersion: core.oam.dev/v1beta1 +kind: TraitDefinition +metadata: + name: service-kube + namespace: default +spec: + appliesToWorkloads: + - webservice + - worker + - backend + podDisruptive: true + schematic: + kube: + template: + apiVersion: v1 + kind: Service + metadata: + name: my-service + spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + parameters: + - name: targetPort + required: true + type: number + fieldPaths: + - "spec.template.spec.ports[0].targetPort" + description: "target port num for service provider."