mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 20:17:04 +00:00
fix e2e_test
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: task
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes jobs that run code or a script to completion."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: jobs.batch
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: webservice
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: task
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes jobs that run code or a script to completion."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: jobs.batch
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: webservice
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -43,7 +43,7 @@ type Workload struct {
|
||||
CustomStatusFormat string
|
||||
|
||||
Helm *v1alpha2.Helm
|
||||
DefinitionReference v1alpha2.DefinitionReference
|
||||
DefinitionReference v1alpha2.WorkloadGVK
|
||||
}
|
||||
|
||||
// GetUserConfigName get user config from AppFile, it will contain config file in it.
|
||||
@@ -238,7 +238,7 @@ func (p *Parser) GenerateApplicationConfiguration(app *Appfile, ns string) (*v1a
|
||||
|
||||
switch wl.CapabilityCategory {
|
||||
case types.HelmCategory:
|
||||
comp, acComp, err = generateComponentFromHelmModule(p.client, p.dm, wl, app.Name, app.RevisionName, ns)
|
||||
comp, acComp, err = generateComponentFromHelmModule(p.client, wl, app.Name, app.RevisionName, ns)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -291,11 +291,12 @@ func generateComponentFromCUEModule(c client.Client, wl *Workload, appName, revi
|
||||
return comp, acComp, nil
|
||||
}
|
||||
|
||||
func generateComponentFromHelmModule(c client.Client, dm discoverymapper.DiscoveryMapper, wl *Workload, appName, revision, ns string) (*v1alpha2.Component, *v1alpha2.ApplicationConfigurationComponent, error) {
|
||||
targetWokrloadGVK, err := util.GetGVKFromDefinition(dm, wl.DefinitionReference)
|
||||
func generateComponentFromHelmModule(c client.Client, wl *Workload, appName, revision, ns string) (*v1alpha2.Component, *v1alpha2.ApplicationConfigurationComponent, error) {
|
||||
gv, err := schema.ParseGroupVersion(wl.DefinitionReference.APIVersion)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
targetWokrloadGVK := gv.WithKind(wl.DefinitionReference.Kind)
|
||||
|
||||
// NOTE this is a hack way to enable using CUE module capabilities on Helm module workload
|
||||
// construct an empty base workload according to its GVK
|
||||
|
||||
@@ -544,9 +544,9 @@ var _ = Describe("Test appfile parser to parse helm module", func() {
|
||||
"url": "http://oam.dev/catalog/",
|
||||
}),
|
||||
},
|
||||
DefinitionReference: v1alpha2.DefinitionReference{
|
||||
Name: "deployments.apps",
|
||||
Version: "v1",
|
||||
DefinitionReference: v1alpha2.WorkloadGVK{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+18
-36
@@ -26,10 +26,8 @@ import (
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/logging"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
@@ -67,14 +65,28 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// if Workload.Type is not empty, means componentdefinition refer to an already existing workloaddefinition
|
||||
if componentDefinition.Spec.Workload.Type != "" {
|
||||
return ctrl.Result{}, nil
|
||||
handler := handler{
|
||||
Client: r.Client,
|
||||
dm: r.dm,
|
||||
cd: &componentDefinition,
|
||||
}
|
||||
|
||||
workloadType, err := handler.CreateWorkloadDefinition(ctx)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot create converted WorkloadDefinition")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
cpv1alpha1.ReconcileError(fmt.Errorf(util.ErrCreateConvertedWorklaodDefinition, componentDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully create WorkloadDefinition", "name", componentDefinition.Name)
|
||||
|
||||
var def utils.CapabilityComponentDefinition
|
||||
def.Name = req.NamespacedName.Name
|
||||
err := def.StoreOpenAPISchema(ctx, r, req.Namespace, req.Name)
|
||||
def.WorkloadType = workloadType
|
||||
if workloadType == util.ReferWorkload {
|
||||
def.WorkloadDefName = componentDefinition.Spec.Workload.Type
|
||||
}
|
||||
err = def.StoreOpenAPISchema(ctx, r, req.Namespace, req.Name)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot store capability in ConfigMap")
|
||||
r.record.Event(&(def.ComponentDefinition), event.Warning("cannot store capability in ConfigMap", err))
|
||||
@@ -89,36 +101,6 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
}
|
||||
klog.Info("Successfully stored Capability Schema in ConfigMap")
|
||||
|
||||
// if Workload.Type is empty, we need create a WorkloadDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &v1alpha2.WorkloadDefinition{}); err == nil {
|
||||
klog.Infof("WorkloadDefinition: %s already exists", componentDefinition.Name)
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
workloadDefinition := new(v1alpha2.WorkloadDefinition)
|
||||
newCd := componentDefinition.DeepCopy()
|
||||
if err := util.ConvertComponentDef2WorkloadDef(newCd, workloadDefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot convert ComponentDefinition")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot convert ComponentDefinition", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
cpv1alpha1.ReconcileError(fmt.Errorf(util.ErrConvertComponentDefinition, componentDefinition.Name, err)))
|
||||
}
|
||||
owners := []metav1.OwnerReference{{
|
||||
APIVersion: v1alpha2.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha2.ComponentDefinitionKind,
|
||||
Name: componentDefinition.Name,
|
||||
UID: componentDefinition.UID,
|
||||
Controller: pointer.BoolPtr(true),
|
||||
}}
|
||||
workloadDefinition.SetOwnerReferences(owners)
|
||||
if err := r.Create(ctx, workloadDefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot create converted WorkloadDefinition")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot create converted Workload", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
cpv1alpha1.ReconcileError(fmt.Errorf(util.ErrCreateConvertedWorklaodDefinition, workloadDefinition.Name, err)))
|
||||
}
|
||||
|
||||
klog.InfoS("Successfully create WorkloadDefinition", "name", workloadDefinition.Name)
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
|
||||
+56
-7
@@ -46,7 +46,7 @@ var _ = Describe("Test ComponentDefinition Controller", func() {
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: wd-without-ready-ns
|
||||
name: cd-without-ready-ns
|
||||
namespace: ns-def
|
||||
annotations:
|
||||
definition.oam.dev/description: "test"
|
||||
@@ -410,9 +410,6 @@ spec:
|
||||
Expect(wd.Namespace).Should(Equal(def.Namespace))
|
||||
Expect(wd.Annotations).Should(Equal(def.Annotations))
|
||||
Expect(wd.Spec.Schematic).Should(Equal(def.Spec.Schematic))
|
||||
convertRef, err := util.ConvertWorkloadGVK2Definition(def.Spec.Workload.Definition)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(wd.Spec.Reference).Should(Equal(convertRef))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -422,17 +419,69 @@ spec:
|
||||
req := reconcile.Request{NamespacedName: client.ObjectKey{Name: componentDefinitionName, Namespace: namespace}}
|
||||
|
||||
It("Applying ComponentDefinition with Workload.Type", func() {
|
||||
By("Apply WorkloadDefinition")
|
||||
var taskWorkloadDefinition = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
|
||||
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]
|
||||
}
|
||||
`
|
||||
var task v1alpha2.WorkloadDefinition
|
||||
Expect(yaml.Unmarshal([]byte(taskWorkloadDefinition), &task)).Should(BeNil())
|
||||
task.Namespace = namespace
|
||||
Expect(k8sClient.Create(ctx, &task)).Should(Succeed())
|
||||
|
||||
By("Apply ComponentDefinition")
|
||||
var validComponentDefinition = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: cd-with-workload-type
|
||||
annotations:
|
||||
definition.oam.dev/description: "test"
|
||||
spec:
|
||||
workload:
|
||||
type: deployments.app
|
||||
type: worker
|
||||
`
|
||||
var def v1alpha2.ComponentDefinition
|
||||
Expect(yaml.Unmarshal([]byte(validComponentDefinition), &def)).Should(BeNil())
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
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 componentdefinition
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
client.Client
|
||||
dm discoverymapper.DiscoveryMapper
|
||||
cd *v1alpha2.ComponentDefinition
|
||||
}
|
||||
|
||||
func (h *handler) CreateWorkloadDefinition(ctx context.Context) (util.WorkloadType, error) {
|
||||
var workloadType = util.ComponentDef
|
||||
var workloadName = h.cd.Name
|
||||
if h.cd.Spec.Workload.Type != "" {
|
||||
workloadType = util.ReferWorkload
|
||||
workloadName = h.cd.Spec.Workload.Type
|
||||
}
|
||||
if h.cd.Spec.Schematic != nil && h.cd.Spec.Schematic.HELM != nil {
|
||||
workloadType = util.HELMDef
|
||||
}
|
||||
wd := new(v1alpha2.WorkloadDefinition)
|
||||
err := h.Get(ctx, client.ObjectKey{Namespace: h.cd.Namespace, Name: workloadName}, wd)
|
||||
if workloadType == util.ReferWorkload {
|
||||
if err != nil {
|
||||
klog.Infof("ComponentDefinition %s refer to wrong Workload", h.cd.Name)
|
||||
return workloadType, err
|
||||
}
|
||||
}
|
||||
if workloadType == util.ComponentDef || workloadType == util.HELMDef {
|
||||
if err == nil {
|
||||
return workloadType, nil
|
||||
}
|
||||
newCd := h.cd.DeepCopy()
|
||||
if err := util.ConvertComponentDef2WorkloadDef(h.dm, newCd, wd); err != nil {
|
||||
return workloadType, fmt.Errorf("convert WorkloadDefinition %s error %w", h.cd.Name, err)
|
||||
}
|
||||
owners := []metav1.OwnerReference{{
|
||||
APIVersion: v1alpha2.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha2.ComponentDefinitionKind,
|
||||
Name: h.cd.Name,
|
||||
UID: h.cd.UID,
|
||||
Controller: pointer.BoolPtr(true),
|
||||
}}
|
||||
wd.SetOwnerReferences(owners)
|
||||
if err := h.Create(ctx, wd); err != nil {
|
||||
return workloadType, fmt.Errorf("create converted WorkloadDefinition %s error %w", h.cd.Name, err)
|
||||
}
|
||||
}
|
||||
return workloadType, nil
|
||||
}
|
||||
@@ -55,6 +55,8 @@ type CapabilityDefinitionInterface interface {
|
||||
type CapabilityComponentDefinition struct {
|
||||
Name string `json:"name"`
|
||||
ComponentDefinition v1alpha2.ComponentDefinition `json:"componentDefinition"`
|
||||
WorkloadType util.WorkloadType `json:"workloadType"`
|
||||
WorkloadDefName string `json:"workloadDefName"`
|
||||
CapabilityBaseDefinition
|
||||
}
|
||||
|
||||
@@ -62,7 +64,6 @@ type CapabilityComponentDefinition struct {
|
||||
func (def *CapabilityComponentDefinition) GetCapabilityObject(ctx context.Context, k8sClient client.Client, namespace, name string) (*types.Capability, error) {
|
||||
var componentDefinition v1alpha2.ComponentDefinition
|
||||
var capability types.Capability
|
||||
capability.Name = def.Name
|
||||
objectKey := client.ObjectKey{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
@@ -72,9 +73,20 @@ func (def *CapabilityComponentDefinition) GetCapabilityObject(ctx context.Contex
|
||||
return nil, fmt.Errorf("failed to get ComponentDefinition %s: %w", def.Name, err)
|
||||
}
|
||||
def.ComponentDefinition = componentDefinition
|
||||
capability, err = util.ConvertTemplateJSON2Object(name, componentDefinition.Spec.Extension, componentDefinition.Spec.Schematic)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert ComponentDefinition to Capability Object")
|
||||
|
||||
switch def.WorkloadType {
|
||||
case util.ReferWorkload:
|
||||
var wd = new(v1alpha2.WorkloadDefinition)
|
||||
objectKey.Name = def.WorkloadDefName
|
||||
if err := k8sClient.Get(ctx, objectKey, wd); err != nil {
|
||||
return nil, fmt.Errorf("failed to get WorkloadDefinition that ComponentDefinition refers to")
|
||||
}
|
||||
capability, err = util.ConvertTemplateJSON2Object(name, wd.Spec.Extension, wd.Spec.Schematic)
|
||||
default:
|
||||
capability, err = util.ConvertTemplateJSON2Object(name, componentDefinition.Spec.Extension, componentDefinition.Spec.Schematic)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert ComponentDefinition to Capability Object")
|
||||
}
|
||||
}
|
||||
return &capability, err
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ type DiscoveryMapper interface {
|
||||
Refresh() (meta.RESTMapper, error)
|
||||
RESTMapping(gk schema.GroupKind, version ...string) (*meta.RESTMapping, error)
|
||||
KindsFor(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error)
|
||||
ResourcesFor(input schema.GroupVersionKind) (schema.GroupVersionResource, error)
|
||||
}
|
||||
|
||||
var _ DiscoveryMapper = &DefaultDiscoveryMapper{}
|
||||
@@ -89,3 +90,14 @@ func (d *DefaultDiscoveryMapper) KindsFor(input schema.GroupVersionResource) ([]
|
||||
}
|
||||
return mapping, err
|
||||
}
|
||||
|
||||
// ResourcesFor will get a resource from GroupVersionKind
|
||||
func (d *DefaultDiscoveryMapper) ResourcesFor(input schema.GroupVersionKind) (schema.GroupVersionResource, error) {
|
||||
var gvr schema.GroupVersionResource
|
||||
mapping, err := d.RESTMapping(input.GroupKind(), input.Version)
|
||||
if err != nil {
|
||||
return gvr, err
|
||||
}
|
||||
gvr = mapping.Resource
|
||||
return gvr, nil
|
||||
}
|
||||
|
||||
+19
-4
@@ -21,6 +21,9 @@ type RESTMapping func(gk schema.GroupKind, versions ...string) (*meta.RESTMappin
|
||||
// KindsFor is func type for mock convenience
|
||||
type KindsFor func(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error)
|
||||
|
||||
// ResourcesFor is func type for mock convenience
|
||||
type ResourcesFor func(input schema.GroupVersionKind) (schema.GroupVersionResource, error)
|
||||
|
||||
// NewMockDiscoveryMapper for unit test only
|
||||
func NewMockDiscoveryMapper() *DiscoveryMapper {
|
||||
return &DiscoveryMapper{
|
||||
@@ -56,10 +59,11 @@ func NewMockKindsFor(kind string, version ...string) KindsFor {
|
||||
|
||||
// DiscoveryMapper for unit test only, use GetMapper and refresh will panic
|
||||
type DiscoveryMapper struct {
|
||||
MockGetMapper GetMapper
|
||||
MockRefresh Refresh
|
||||
MockRESTMapping RESTMapping
|
||||
MockKindsFor KindsFor
|
||||
MockGetMapper GetMapper
|
||||
MockRefresh Refresh
|
||||
MockRESTMapping RESTMapping
|
||||
MockKindsFor KindsFor
|
||||
MockResourcesFor ResourcesFor
|
||||
}
|
||||
|
||||
// GetMapper for mock
|
||||
@@ -81,3 +85,14 @@ func (m *DiscoveryMapper) RESTMapping(gk schema.GroupKind, versions ...string) (
|
||||
func (m *DiscoveryMapper) KindsFor(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
|
||||
return m.MockKindsFor(input)
|
||||
}
|
||||
|
||||
// ResourcesFor for mock
|
||||
func (m *DiscoveryMapper) ResourcesFor(input schema.GroupVersionKind) (schema.GroupVersionResource, error) {
|
||||
var gvr schema.GroupVersionResource
|
||||
mapping, err := m.RESTMapping(input.GroupKind(), input.Version)
|
||||
if err != nil {
|
||||
return gvr, err
|
||||
}
|
||||
gvr = mapping.Resource
|
||||
return gvr, nil
|
||||
}
|
||||
|
||||
+24
-11
@@ -78,12 +78,24 @@ const (
|
||||
// ErrUpdateCapabilityInConfigMap is the error while creating or updating a capability
|
||||
ErrUpdateCapabilityInConfigMap = "cannot create or update capability %s in ConfigMap: %v"
|
||||
|
||||
// ErrConvertComponentDefinition is the error while convert a workloadDefinition from componentDefinition
|
||||
ErrConvertComponentDefinition = "cannot convert ComponentDefinition %s to WorkloadDefinition %v"
|
||||
// ErrCreateConvertedWorklaodDefinition is the error while apply a WorkloadDefinition
|
||||
ErrCreateConvertedWorklaodDefinition = "cannot create converted WorkloadDefinition %s: %v"
|
||||
)
|
||||
|
||||
// WorkloadType describe the workload type of ComponentDefinition
|
||||
type WorkloadType string
|
||||
|
||||
const (
|
||||
// ComponentDef describe a workload of Defined by ComponentDefinition
|
||||
ComponentDef WorkloadType = "ComponentDef"
|
||||
|
||||
// HELMDef describe a workload refer to HELM
|
||||
HELMDef WorkloadType = "HELMDef"
|
||||
|
||||
// ReferWorkload describe an existing workload
|
||||
ReferWorkload WorkloadType = "ReferWorkload"
|
||||
)
|
||||
|
||||
type namespaceContextKey int
|
||||
|
||||
const (
|
||||
@@ -421,19 +433,19 @@ func GetGVKFromDefinition(dm discoverymapper.DiscoveryMapper, definitionRef v1al
|
||||
}
|
||||
|
||||
// ConvertWorkloadGVK2Definition help convert a GVK to DefinitionReference
|
||||
func ConvertWorkloadGVK2Definition(def v1alpha2.WorkloadGVK) (v1alpha2.DefinitionReference, error) {
|
||||
func ConvertWorkloadGVK2Definition(dm discoverymapper.DiscoveryMapper, def v1alpha2.WorkloadGVK) (v1alpha2.DefinitionReference, error) {
|
||||
var reference v1alpha2.DefinitionReference
|
||||
gv, err := schema.ParseGroupVersion(def.APIVersion)
|
||||
if err != nil {
|
||||
return reference, err
|
||||
}
|
||||
resource := strings.ToLower(def.Kind) + "s"
|
||||
if gv.Group == "" {
|
||||
reference.Name = resource + "." + gv.Version
|
||||
} else {
|
||||
reference.Name = resource + "." + gv.Group
|
||||
reference.Version = gv.Version
|
||||
gvk := gv.WithKind(def.Kind)
|
||||
gvr, err := dm.ResourcesFor(gvk)
|
||||
if err != nil {
|
||||
return reference, err
|
||||
}
|
||||
reference.Version = gvr.Version
|
||||
reference.Name = gvr.GroupResource().String()
|
||||
return reference, nil
|
||||
}
|
||||
|
||||
@@ -635,12 +647,13 @@ func MergeMapOverrideWithDst(src, dst map[string]string) map[string]string {
|
||||
}
|
||||
|
||||
// ConvertComponentDef2WorkloadDef help convert a ComponentDefinition to WorkloadDefinition
|
||||
func ConvertComponentDef2WorkloadDef(componentDef *v1alpha2.ComponentDefinition, workloadDef *v1alpha2.WorkloadDefinition) error {
|
||||
func ConvertComponentDef2WorkloadDef(dm discoverymapper.DiscoveryMapper, componentDef *v1alpha2.ComponentDefinition,
|
||||
workloadDef *v1alpha2.WorkloadDefinition) error {
|
||||
if len(componentDef.Spec.Workload.Type) > 1 {
|
||||
return errors.New("No need to convert ComponentDefinition")
|
||||
}
|
||||
var reference v1alpha2.DefinitionReference
|
||||
reference, err := ConvertWorkloadGVK2Definition(componentDef.Spec.Workload.Definition)
|
||||
reference, err := ConvertWorkloadGVK2Definition(dm, componentDef.Spec.Workload.Definition)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create DefinitionReference fail %w", err)
|
||||
}
|
||||
|
||||
@@ -812,44 +812,14 @@ func TestGetGVKFromDef(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertWorkloadGVK2Def(t *testing.T) {
|
||||
type want struct {
|
||||
ref v1alpha2.DefinitionReference
|
||||
err error
|
||||
}
|
||||
convertErr := fmt.Errorf("unexpected GroupVersion string: %v", "apps/v1/")
|
||||
|
||||
cases := []struct {
|
||||
testName string
|
||||
workloadGVK v1alpha2.WorkloadGVK
|
||||
want want
|
||||
}{{
|
||||
testName: "expected GVK with version",
|
||||
workloadGVK: v1alpha2.WorkloadGVK{APIVersion: "apps/v1", Kind: "Deployment"},
|
||||
want: want{
|
||||
ref: v1alpha2.DefinitionReference{Name: "deployments.apps", Version: "v1"},
|
||||
err: nil,
|
||||
},
|
||||
}, {
|
||||
testName: "expected GVK without version",
|
||||
workloadGVK: v1alpha2.WorkloadGVK{APIVersion: "apps", Kind: "Deployment"},
|
||||
want: want{
|
||||
ref: v1alpha2.DefinitionReference{Name: "deployments.apps", Version: ""},
|
||||
err: nil,
|
||||
},
|
||||
}, {
|
||||
testName: "unexpected GVK",
|
||||
workloadGVK: v1alpha2.WorkloadGVK{APIVersion: "apps/v1/", Kind: "Deployment"},
|
||||
want: want{
|
||||
ref: v1alpha2.DefinitionReference{},
|
||||
err: convertErr,
|
||||
},
|
||||
}}
|
||||
for _, tc := range cases {
|
||||
ref, err := util.ConvertWorkloadGVK2Definition(tc.workloadGVK)
|
||||
t.Log(fmt.Sprint("Running test: ", tc.testName))
|
||||
assert.Equal(t, tc.want.err, err)
|
||||
assert.Equal(t, tc.want.ref, ref)
|
||||
}
|
||||
mapper := mock.NewMockDiscoveryMapper()
|
||||
mapper.MockRESTMapping = mock.NewMockRESTMapping("deployments")
|
||||
ref, err := util.ConvertWorkloadGVK2Definition(mapper, v1alpha2.WorkloadGVK{APIVersion: "apps/v1", Kind: "Deployment"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, v1alpha2.DefinitionReference{
|
||||
Name: "deployments.apps",
|
||||
Version: "v1",
|
||||
}, ref)
|
||||
}
|
||||
|
||||
func TestGenTraitName(t *testing.T) {
|
||||
|
||||
@@ -21,7 +21,7 @@ type Template struct {
|
||||
Health string
|
||||
CustomStatus string
|
||||
CapabilityCategory types.CapabilityCategory
|
||||
Reference v1alpha2.DefinitionReference
|
||||
Reference v1alpha2.WorkloadGVK
|
||||
Helm *v1alpha2.Helm
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func LoadTemplate(ctx context.Context, cli client.Reader, key string, kd types.C
|
||||
if tmpl == nil {
|
||||
return nil, errors.New("no template found in definition")
|
||||
}
|
||||
tmpl.Reference, err = ConvertWorkloadGVK2Definition(cd.Spec.Workload.Definition)
|
||||
tmpl.Reference = cd.Spec.Workload.Definition
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get DefinitionReference error %w", err)
|
||||
}
|
||||
@@ -80,7 +80,6 @@ func LoadTemplate(ctx context.Context, cli client.Reader, key string, kd types.C
|
||||
if tmpl == nil {
|
||||
return nil, errors.New("no template found in definition")
|
||||
}
|
||||
tmpl.Reference = td.Spec.Reference
|
||||
tmpl.CapabilityCategory = capabilityCategory
|
||||
return tmpl, nil
|
||||
case types.TypeScope:
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
)
|
||||
|
||||
func TestLoadWorkloadTemplate(t *testing.T) {
|
||||
func TestLoadComponentTemplate(t *testing.T) {
|
||||
cueTemplate := `
|
||||
context: {
|
||||
name: "test"
|
||||
@@ -60,17 +60,19 @@ func TestLoadWorkloadTemplate(t *testing.T) {
|
||||
}
|
||||
`
|
||||
|
||||
var workloadDefintion = `
|
||||
var componentDefintion = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
namespace: default
|
||||
annotations:
|
||||
definition.oam.dev/description: "Long-running scalable backend worker without network endpoint"
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
extension:
|
||||
template: |
|
||||
` + cueTemplate
|
||||
@@ -79,12 +81,12 @@ spec:
|
||||
tclient := test.MockClient{
|
||||
MockGet: func(ctx context.Context, key ktypes.NamespacedName, obj runtime.Object) error {
|
||||
switch o := obj.(type) {
|
||||
case *v1alpha2.WorkloadDefinition:
|
||||
wd, err := UnMarshalStringToWorkloadDefinition(workloadDefintion)
|
||||
case *v1alpha2.ComponentDefinition:
|
||||
cd, err := UnMarshalStringToComponentDefinition(componentDefintion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*o = *wd
|
||||
*o = *cd
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -145,19 +145,6 @@ func UnMarshalStringToComponentDefinition(s string) (*v1alpha2.ComponentDefiniti
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// UnMarshalStringToWorkloadDefinition parse a string to a workloadDefinition object
|
||||
func UnMarshalStringToWorkloadDefinition(s string) (*v1alpha2.WorkloadDefinition, error) {
|
||||
obj := &v1alpha2.WorkloadDefinition{}
|
||||
_body, err := yaml.YAMLToJSON([]byte(s))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(_body, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// UnMarshalStringToTraitDefinition parse a string to a traitDefinition object
|
||||
func UnMarshalStringToTraitDefinition(s string) (*v1alpha2.TraitDefinition, error) {
|
||||
obj := &v1alpha2.TraitDefinition{}
|
||||
|
||||
@@ -62,10 +62,10 @@ var _ = Describe("Cloneset based rollout tests", func() {
|
||||
}
|
||||
|
||||
CreateClonesetDef := func() {
|
||||
By("Install CloneSet based workloadDefinition")
|
||||
var cd v1alpha2.WorkloadDefinition
|
||||
By("Install CloneSet based componentDefinition")
|
||||
var cd v1alpha2.ComponentDefinition
|
||||
Expect(readYaml("testdata/rollout/cloneset/clonesetDefinition.yaml", &cd)).Should(BeNil())
|
||||
// create the workloadDefinition if not exist
|
||||
// create the componentDefinition if not exist
|
||||
Eventually(
|
||||
func() error {
|
||||
return k8sClient.Create(ctx, &cd)
|
||||
@@ -564,7 +564,7 @@ var _ = Describe("Cloneset based rollout tests", func() {
|
||||
ApplySourceApp()
|
||||
MarkAppRolling(1)
|
||||
By("Apply the definition change")
|
||||
var cd, newCD v1alpha2.WorkloadDefinition
|
||||
var cd, newCD v1alpha2.ComponentDefinition
|
||||
Expect(readYaml("testdata/rollout/cloneset/clonesetDefinitionModified.yaml.yaml", &newCD)).Should(BeNil())
|
||||
Eventually(
|
||||
func() error {
|
||||
|
||||
@@ -98,7 +98,11 @@ var _ = BeforeSuite(func(done Done) {
|
||||
}
|
||||
|
||||
// TODO: Remove this after we get rid of the integration test dir
|
||||
By("Applying CRD of WorkloadDefinition and TraitDefinition")
|
||||
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(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(k8sClient.Create(context.Background(), &workloadDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: clonesetservice
|
||||
namespace: vela-system
|
||||
@@ -8,8 +8,10 @@ metadata:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers.
|
||||
If workload type is skipped for any service defined in Appfile, it will be defaulted to `webservice` type."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: clonesets.apps.kruise.io
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps.kruise.io/v1alpha1
|
||||
kind: CloneSet
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: clonesetservice
|
||||
namespace: vela-system
|
||||
@@ -8,8 +8,10 @@ metadata:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers.
|
||||
If workload type is skipped for any service defined in Appfile, it will be defaulted to `webservice` type."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: clonesets.apps.kruise.io
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps.kruise.io/v1alpha1
|
||||
kind: CloneSet
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
|
||||
Reference in New Issue
Block a user