mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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())
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
---
|
||||
|
||||
+2
-4
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
|
||||
+40
@@ -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."
|
||||
+30
@@ -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."
|
||||
Reference in New Issue
Block a user