From 40ab610a8e171d6cd6dd3425149f58fd15586020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=85=83?= Date: Thu, 12 Nov 2020 12:04:08 +0800 Subject: [PATCH 1/2] remove annotation for apiversion and kind, use discoverymapper instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 天元 --- api/types/types.go | 2 - .../templates/definitions/healthscopes.yaml | 3 - .../templates/defwithtemplate/autoscale.yaml | 2 - .../defwithtemplate/manualscale.yaml | 2 - .../templates/defwithtemplate/metrics.yaml | 2 - .../templates/defwithtemplate/route.yaml | 2 - .../templates/defwithtemplate/task.yaml | 2 - .../templates/defwithtemplate/webservice.yaml | 2 - .../templates/defwithtemplate/worker.yaml | 2 - docs/en/platform-engineers/trait.md | 2 - docs/examples/kubecondemo/script/def_db.yaml | 2 - .../kubecondemo/script/webservice.yaml | 2 - .../traitdefinition_autoscalers.yaml | 3 - .../samples/route-demo/definition.yaml | 4 -- .../vela-templates/definitions/autoscale.yaml | 2 - .../definitions/manualscale.yaml | 2 - hack/vela-templates/definitions/metrics.yaml | 2 - hack/vela-templates/definitions/route.yaml | 2 - hack/vela-templates/definitions/task.yaml | 2 - .../definitions/webservice.yaml | 2 - hack/vela-templates/definitions/worker.yaml | 2 - pkg/commands/capability.go | 6 ++ pkg/commands/refresh.go | 4 +- pkg/commands/util/helpers.go | 10 ---- pkg/oam/capability.go | 34 ++++++----- pkg/plugins/cluster.go | 56 +++++++++++++------ pkg/plugins/testdata/manualscalars.yaml | 3 - 27 files changed, 68 insertions(+), 91 deletions(-) diff --git a/api/types/types.go b/api/types/types.go index a02ecd5ea..7f0b2efdf 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -11,8 +11,6 @@ const ( ) const ( - AnnAPIVersion = "definition.oam.dev/apiVersion" - AnnKind = "definition.oam.dev/kind" AnnDescription = "definition.oam.dev/description" LabelPodSpecable = "workload.oam.dev/podspecable" diff --git a/charts/vela-core/templates/definitions/healthscopes.yaml b/charts/vela-core/templates/definitions/healthscopes.yaml index 87c1d8505..deb33f737 100644 --- a/charts/vela-core/templates/definitions/healthscopes.yaml +++ b/charts/vela-core/templates/definitions/healthscopes.yaml @@ -2,9 +2,6 @@ apiVersion: core.oam.dev/v1alpha2 kind: ScopeDefinition metadata: name: healthscopes.core.oam.dev - annotations: - definition.oam.dev/apiVersion: core.oam.dev/v1alpha2 - definition.oam.dev/kind: HealthScope namespace: default spec: workloadRefsPath: spec.workloadRefs diff --git a/charts/vela-core/templates/defwithtemplate/autoscale.yaml b/charts/vela-core/templates/defwithtemplate/autoscale.yaml index 50f1cc917..36d71b8d7 100644 --- a/charts/vela-core/templates/defwithtemplate/autoscale.yaml +++ b/charts/vela-core/templates/defwithtemplate/autoscale.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: autoscale annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Autoscaler definition.oam.dev/description: "Automatically scale workloads" spec: appliesToWorkloads: diff --git a/charts/vela-core/templates/defwithtemplate/manualscale.yaml b/charts/vela-core/templates/defwithtemplate/manualscale.yaml index f4af690d3..67ba35e66 100644 --- a/charts/vela-core/templates/defwithtemplate/manualscale.yaml +++ b/charts/vela-core/templates/defwithtemplate/manualscale.yaml @@ -2,8 +2,6 @@ apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata: annotations: - definition.oam.dev/apiVersion: core.oam.dev/v1alpha2 - definition.oam.dev/kind: ManualScalerTrait definition.oam.dev/description: "Scale replica for workload" name: scaler spec: diff --git a/charts/vela-core/templates/defwithtemplate/metrics.yaml b/charts/vela-core/templates/defwithtemplate/metrics.yaml index 1b93fc2a0..e917a027b 100644 --- a/charts/vela-core/templates/defwithtemplate/metrics.yaml +++ b/charts/vela-core/templates/defwithtemplate/metrics.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: metric annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: MetricsTrait definition.oam.dev/description: "Add metric monitoring for workload" spec: appliesToWorkloads: diff --git a/charts/vela-core/templates/defwithtemplate/route.yaml b/charts/vela-core/templates/defwithtemplate/route.yaml index 9a8cf077f..339c64508 100644 --- a/charts/vela-core/templates/defwithtemplate/route.yaml +++ b/charts/vela-core/templates/defwithtemplate/route.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: route annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Route definition.oam.dev/description: "Add a route for workload" spec: appliesToWorkloads: diff --git a/charts/vela-core/templates/defwithtemplate/task.yaml b/charts/vela-core/templates/defwithtemplate/task.yaml index 42cad82f5..da3ca1748 100644 --- a/charts/vela-core/templates/defwithtemplate/task.yaml +++ b/charts/vela-core/templates/defwithtemplate/task.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: task annotations: - definition.oam.dev/apiVersion: "v1" - definition.oam.dev/kind: "Job" definition.oam.dev/description: "One-time task/job" spec: definitionRef: diff --git a/charts/vela-core/templates/defwithtemplate/webservice.yaml b/charts/vela-core/templates/defwithtemplate/webservice.yaml index 9077d146e..0b6697016 100644 --- a/charts/vela-core/templates/defwithtemplate/webservice.yaml +++ b/charts/vela-core/templates/defwithtemplate/webservice.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: webservice annotations: - definition.oam.dev/apiVersion: "apps/v1" - definition.oam.dev/kind: "Deployment" definition.oam.dev/description: "Long running service with network routes" spec: definitionRef: diff --git a/charts/vela-core/templates/defwithtemplate/worker.yaml b/charts/vela-core/templates/defwithtemplate/worker.yaml index 7c5937796..f90052ed8 100644 --- a/charts/vela-core/templates/defwithtemplate/worker.yaml +++ b/charts/vela-core/templates/defwithtemplate/worker.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: worker annotations: - definition.oam.dev/apiVersion: "apps/v1" - definition.oam.dev/kind: "Deployment" definition.oam.dev/description: "Backend worker without ports exposed" spec: definitionRef: diff --git a/docs/en/platform-engineers/trait.md b/docs/en/platform-engineers/trait.md index b05984c74..02a7f896f 100644 --- a/docs/en/platform-engineers/trait.md +++ b/docs/en/platform-engineers/trait.md @@ -25,8 +25,6 @@ kind: TraitDefinition metadata: name: kubewatch annotations: - definition.oam.dev/apiVersion: labs.bitnami.com/v1alpha1 - definition.oam.dev/kind: KubeWatch definition.oam.dev/description: "Add a watch for resource" spec: appliesToWorkloads: diff --git a/docs/examples/kubecondemo/script/def_db.yaml b/docs/examples/kubecondemo/script/def_db.yaml index b8a42fa81..a4f01a5e3 100644 --- a/docs/examples/kubecondemo/script/def_db.yaml +++ b/docs/examples/kubecondemo/script/def_db.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: rds annotations: - definition.oam.dev/apiVersion: "database.example.org/v1alpha1" - definition.oam.dev/kind: "PostgreSQLInstance" definition.oam.dev/description: "RDS on Ali Cloud" spec: definitionRef: diff --git a/docs/examples/kubecondemo/script/webservice.yaml b/docs/examples/kubecondemo/script/webservice.yaml index 4596425ed..bfd3f836f 100644 --- a/docs/examples/kubecondemo/script/webservice.yaml +++ b/docs/examples/kubecondemo/script/webservice.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: webservice annotations: - definition.oam.dev/apiVersion: "standard.oam.dev/v1alpha1" - definition.oam.dev/kind: "PodSpecWorkload" definition.oam.dev/description: "Flight tracker web ui" spec: definitionRef: diff --git a/e2e/raw-objects/samples/autoscalers/traitdefinition_autoscalers.yaml b/e2e/raw-objects/samples/autoscalers/traitdefinition_autoscalers.yaml index 3bcac6e57..55e9dd4de 100644 --- a/e2e/raw-objects/samples/autoscalers/traitdefinition_autoscalers.yaml +++ b/e2e/raw-objects/samples/autoscalers/traitdefinition_autoscalers.yaml @@ -2,9 +2,6 @@ apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata: name: autoscalers.standard.oam.dev - annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Autoscaler spec: appliesToWorkloads: - webservice diff --git a/e2e/raw-objects/samples/route-demo/definition.yaml b/e2e/raw-objects/samples/route-demo/definition.yaml index c1dd83832..0e9d73e4c 100644 --- a/e2e/raw-objects/samples/route-demo/definition.yaml +++ b/e2e/raw-objects/samples/route-demo/definition.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: route annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Route definition.oam.dev/description: "Add a route for workload" spec: appliesToWorkloads: @@ -21,8 +19,6 @@ kind: WorkloadDefinition metadata: name: webservice annotations: - definition.oam.dev/apiVersion: "standard.oam.dev/v1alpha1" - definition.oam.dev/kind: "PodSpecWorkload" definition.oam.dev/description: "Long running service with ports exposed" spec: definitionRef: diff --git a/hack/vela-templates/definitions/autoscale.yaml b/hack/vela-templates/definitions/autoscale.yaml index c4b1a058b..e62de391f 100644 --- a/hack/vela-templates/definitions/autoscale.yaml +++ b/hack/vela-templates/definitions/autoscale.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: autoscale annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Autoscaler definition.oam.dev/description: "Automatically scale workloads" spec: appliesToWorkloads: diff --git a/hack/vela-templates/definitions/manualscale.yaml b/hack/vela-templates/definitions/manualscale.yaml index 5ea4165b3..68ec2907d 100644 --- a/hack/vela-templates/definitions/manualscale.yaml +++ b/hack/vela-templates/definitions/manualscale.yaml @@ -2,8 +2,6 @@ apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata: annotations: - definition.oam.dev/apiVersion: core.oam.dev/v1alpha2 - definition.oam.dev/kind: ManualScalerTrait definition.oam.dev/description: "Scale replica for workload" name: scaler spec: diff --git a/hack/vela-templates/definitions/metrics.yaml b/hack/vela-templates/definitions/metrics.yaml index 6226e9742..a5c3a2e7f 100644 --- a/hack/vela-templates/definitions/metrics.yaml +++ b/hack/vela-templates/definitions/metrics.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: metric annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: MetricsTrait definition.oam.dev/description: "Add metric monitoring for workload" spec: appliesToWorkloads: diff --git a/hack/vela-templates/definitions/route.yaml b/hack/vela-templates/definitions/route.yaml index 2e680dbcf..e3d02742d 100644 --- a/hack/vela-templates/definitions/route.yaml +++ b/hack/vela-templates/definitions/route.yaml @@ -3,8 +3,6 @@ kind: TraitDefinition metadata: name: route annotations: - definition.oam.dev/apiVersion: standard.oam.dev/v1alpha1 - definition.oam.dev/kind: Route definition.oam.dev/description: "Add a route for workload" spec: appliesToWorkloads: diff --git a/hack/vela-templates/definitions/task.yaml b/hack/vela-templates/definitions/task.yaml index 8839221f1..9c20939c8 100644 --- a/hack/vela-templates/definitions/task.yaml +++ b/hack/vela-templates/definitions/task.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: task annotations: - definition.oam.dev/apiVersion: "v1" - definition.oam.dev/kind: "Job" definition.oam.dev/description: "One-time task/job" spec: definitionRef: diff --git a/hack/vela-templates/definitions/webservice.yaml b/hack/vela-templates/definitions/webservice.yaml index a7c93be8c..dfe49575f 100644 --- a/hack/vela-templates/definitions/webservice.yaml +++ b/hack/vela-templates/definitions/webservice.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: webservice annotations: - definition.oam.dev/apiVersion: "apps/v1" - definition.oam.dev/kind: "Deployment" definition.oam.dev/description: "Long running service with network routes" spec: definitionRef: diff --git a/hack/vela-templates/definitions/worker.yaml b/hack/vela-templates/definitions/worker.yaml index ab92b1b0f..1ebc45c2c 100644 --- a/hack/vela-templates/definitions/worker.yaml +++ b/hack/vela-templates/definitions/worker.yaml @@ -3,8 +3,6 @@ kind: WorkloadDefinition metadata: name: worker annotations: - definition.oam.dev/apiVersion: "apps/v1" - definition.oam.dev/kind: "Deployment" definition.oam.dev/description: "Backend worker without ports exposed" spec: definitionRef: diff --git a/pkg/commands/capability.go b/pkg/commands/capability.go index b22541241..235af7618 100644 --- a/pkg/commands/capability.go +++ b/pkg/commands/capability.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" + "github.com/gosuri/uitable" "github.com/spf13/cobra" "sigs.k8s.io/controller-runtime/pkg/client" @@ -94,6 +96,10 @@ func NewCapInstallCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Comm if err != nil { return err } + mapper, err := discoverymapper.New(c.Config) + if err != nil { + return err + } if _, err = oam.AddCapabilityIntoCluster(newClient, args[0]); err != nil { return err } diff --git a/pkg/commands/refresh.go b/pkg/commands/refresh.go index ca1a90203..71dfbc22c 100644 --- a/pkg/commands/refresh.go +++ b/pkg/commands/refresh.go @@ -9,8 +9,6 @@ import ( cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" "github.com/oam-dev/kubevela/pkg/plugins" "github.com/oam-dev/kubevela/pkg/utils/system" - - "sigs.k8s.io/controller-runtime/pkg/client" ) type refreshStatus string @@ -22,7 +20,7 @@ const ( deleted refreshStatus = "Deleted" ) -func RefreshDefinitions(ctx context.Context, c client.Client, ioStreams cmdutil.IOStreams, silentOutput bool) error { +func RefreshDefinitions(ctx context.Context, c types.Args, ioStreams cmdutil.IOStreams, silentOutput bool) error { dir, _ := system.GetCapabilityDir() oldCaps, err := plugins.LoadAllInstalledCapability() diff --git a/pkg/commands/util/helpers.go b/pkg/commands/util/helpers.go index 1b7d6e572..63cff2749 100644 --- a/pkg/commands/util/helpers.go +++ b/pkg/commands/util/helpers.go @@ -6,8 +6,6 @@ import ( "os" "strings" - "github.com/oam-dev/kubevela/api/types" - "github.com/AlecAivazis/survey/v2" corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2" "github.com/spf13/cobra" @@ -63,14 +61,6 @@ func GetComponent(ctx context.Context, c client.Client, componentName string, na return component, err } -func GetAPIVersionKindFromTrait(td corev1alpha2.TraitDefinition) (string, string) { - return td.Annotations[types.AnnAPIVersion], td.Annotations[types.AnnKind] -} - -func GetAPIVersionKindFromWorkload(td corev1alpha2.WorkloadDefinition) (string, string) { - return td.Annotations[types.AnnAPIVersion], td.Annotations[types.AnnKind] -} - func PrintFlags(cmd *cobra.Command, subcmds []*cobra.Command) { cmd.Println("Flags:") for _, sub := range subcmds { diff --git a/pkg/oam/capability.go b/pkg/oam/capability.go index 9b97363c8..cd39f3f84 100644 --- a/pkg/oam/capability.go +++ b/pkg/oam/capability.go @@ -9,6 +9,10 @@ import ( "path/filepath" "strings" + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util" + + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" + "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2" "github.com/ghodss/yaml" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -59,7 +63,7 @@ func SyncCapabilityFromCenter(capName, capURL, capToken string) error { return client.SyncCapabilityFromCenter() } -func AddCapabilityIntoCluster(c client.Client, capability string) (string, error) { +func AddCapabilityIntoCluster(c client.Client, mapper discoverymapper.DiscoveryMapper, capability string) (string, error) { ss := strings.Split(capability, "/") if len(ss) < 2 { return "", errors.New("invalid format for " + capability + ", please follow format
/") @@ -67,13 +71,13 @@ func AddCapabilityIntoCluster(c client.Client, capability string) (string, error repoName := ss[0] name := ss[1] ioStreams := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} - if err := InstallCapability(c, repoName, name, ioStreams); err != nil { + if err := InstallCapability(c, mapper, repoName, name, ioStreams); err != nil { return "", err } return fmt.Sprintf("Successfully installed capability %s from %s", name, repoName), nil } -func InstallCapability(client client.Client, centerName, capabilityName string, ioStreams cmdutil.IOStreams) error { +func InstallCapability(client client.Client, mapper discoverymapper.DiscoveryMapper, centerName, capabilityName string, ioStreams cmdutil.IOStreams) error { dir, _ := system.GetCapCenterDir() repoDir := filepath.Join(dir, centerName) tp, err := GetSyncedCapabilities(centerName, capabilityName) @@ -100,11 +104,13 @@ func InstallCapability(client client.Client, centerName, capabilityName string, return err } } - if apiVerion, kind := cmdutil.GetAPIVersionKindFromWorkload(wd); apiVerion != "" && kind != "" { - tp.CrdInfo = &types.CrdInfo{ - APIVersion: apiVerion, - Kind: kind, - } + gvk, err := util.GetGVKFromDefinition(mapper, wd.Spec.Reference) + if err != nil { + return err + } + tp.CrdInfo = &types.CrdInfo{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, } if err = client.Create(context.Background(), &wd); err != nil && !apierrors.IsAlreadyExists(err) { return err @@ -126,11 +132,13 @@ func InstallCapability(client client.Client, centerName, capabilityName string, return err } } - if apiVerion, kind := cmdutil.GetAPIVersionKindFromTrait(td); apiVerion != "" && kind != "" { - tp.CrdInfo = &types.CrdInfo{ - APIVersion: apiVerion, - Kind: kind, - } + gvk, err := util.GetGVKFromDefinition(mapper, td.Spec.Reference) + if err != nil { + return err + } + tp.CrdInfo = &types.CrdInfo{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, } if err = client.Create(context.Background(), &td); err != nil && !apierrors.IsAlreadyExists(err) { return err diff --git a/pkg/plugins/cluster.go b/pkg/plugins/cluster.go index 5409e6f41..60831b1b2 100644 --- a/pkg/plugins/cluster.go +++ b/pkg/plugins/cluster.go @@ -7,8 +7,11 @@ import ( "net/http" "path/filepath" + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util" + + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" + "github.com/oam-dev/kubevela/api/types" - cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" "github.com/oam-dev/kubevela/pkg/cue" "github.com/oam-dev/kubevela/pkg/utils/system" "github.com/pkg/errors" @@ -21,7 +24,7 @@ import ( const DescriptionUndefined = "description not defined" -func GetCapabilitiesFromCluster(ctx context.Context, namespace string, c client.Client, syncDir string, selector labels.Selector) ([]types.Capability, error) { +func GetCapabilitiesFromCluster(ctx context.Context, namespace string, c types.Args, syncDir string, selector labels.Selector) ([]types.Capability, error) { workloads, _, err := GetWorkloadsFromCluster(ctx, namespace, c, syncDir, selector) if err != nil { return nil, err @@ -34,10 +37,19 @@ func GetCapabilitiesFromCluster(ctx context.Context, namespace string, c client. return workloads, nil } -func GetWorkloadsFromCluster(ctx context.Context, namespace string, c client.Client, syncDir string, selector labels.Selector) ([]types.Capability, []error, error) { +func GetWorkloadsFromCluster(ctx context.Context, namespace string, c types.Args, syncDir string, selector labels.Selector) ([]types.Capability, []error, error) { + newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema}) + if err != nil { + return nil, nil, err + } + dm, err := discoverymapper.New(c.Config) + if err != nil { + return nil, nil, err + } + var templates []types.Capability var workloadDefs corev1alpha2.WorkloadDefinitionList - err := c.List(ctx, &workloadDefs, &client.ListOptions{Namespace: namespace, LabelSelector: selector}) + err = newClient.List(ctx, &workloadDefs, &client.ListOptions{Namespace: namespace, LabelSelector: selector}) if err != nil { return nil, nil, fmt.Errorf("list WorkloadDefinition err: %s", err) } @@ -49,21 +61,31 @@ func GetWorkloadsFromCluster(ctx context.Context, namespace string, c client.Cli templateErrors = append(templateErrors, errors.Wrapf(err, "handle workload template `%s` failed", wd.Name)) continue } - if apiVersion, kind := cmdutil.GetAPIVersionKindFromWorkload(wd); apiVersion != "" && kind != "" { - tmp.CrdInfo = &types.CrdInfo{ - APIVersion: apiVersion, - Kind: kind, - } + gvk, err := util.GetGVKFromDefinition(dm, wd.Spec.Reference) + if err != nil { + return nil, nil, err + } + tmp.CrdInfo = &types.CrdInfo{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, } templates = append(templates, tmp) } return templates, templateErrors, nil } -func GetTraitsFromCluster(ctx context.Context, namespace string, c client.Client, syncDir string, selector labels.Selector) ([]types.Capability, []error, error) { +func GetTraitsFromCluster(ctx context.Context, namespace string, c types.Args, syncDir string, selector labels.Selector) ([]types.Capability, []error, error) { + newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema}) + if err != nil { + return nil, nil, err + } + dm, err := discoverymapper.New(c.Config) + if err != nil { + return nil, nil, err + } var templates []types.Capability var traitDefs corev1alpha2.TraitDefinitionList - err := c.List(ctx, &traitDefs, &client.ListOptions{Namespace: namespace, LabelSelector: selector}) + err = newClient.List(ctx, &traitDefs, &client.ListOptions{Namespace: namespace, LabelSelector: selector}) if err != nil { return nil, nil, fmt.Errorf("list TraitDefinition err: %s", err) } @@ -75,11 +97,13 @@ func GetTraitsFromCluster(ctx context.Context, namespace string, c client.Client templateErrors = append(templateErrors, errors.Wrapf(err, "handle trait template `%s` failed\n", td.Name)) continue } - if apiVersion, kind := cmdutil.GetAPIVersionKindFromTrait(td); apiVersion != "" && kind != "" { - tmp.CrdInfo = &types.CrdInfo{ - APIVersion: apiVersion, - Kind: kind, - } + gvk, err := util.GetGVKFromDefinition(dm, td.Spec.Reference) + if err != nil { + return nil, nil, err + } + tmp.CrdInfo = &types.CrdInfo{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, } templates = append(templates, tmp) } diff --git a/pkg/plugins/testdata/manualscalars.yaml b/pkg/plugins/testdata/manualscalars.yaml index 1d3666442..915b87088 100644 --- a/pkg/plugins/testdata/manualscalars.yaml +++ b/pkg/plugins/testdata/manualscalars.yaml @@ -1,9 +1,6 @@ apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata: - annotations: - definition.oam.dev/apiVersion: core.oam.dev/v1alpha2 - definition.oam.dev/kind: ManualScalerTrait name: scaler namespace: default spec: From d67ce4d2a1912e9c79802d8e56d8e5878b5c67dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=85=83?= Date: Thu, 12 Nov 2020 13:25:06 +0800 Subject: [PATCH 2/2] refactor server and fix CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 天元 --- pkg/commands/capability.go | 2 +- pkg/commands/dashboard.go | 15 +- pkg/commands/env.go | 2 +- pkg/commands/system.go | 57 ++++++-- pkg/commands/traits.go | 7 +- pkg/commands/workloads.go | 7 +- pkg/oam/capability.go | 6 +- pkg/oam/common.go | 9 +- pkg/oam/trait.go | 58 -------- pkg/plugins/cluster_test.go | 25 +++- pkg/plugins/suit_test.go | 51 +------ pkg/plugins/testdata/traitDef.yaml | 4 +- pkg/plugins/testdata/websvcWorkloadDef.yaml | 2 +- pkg/plugins/testdata/workloadDef.yaml | 2 +- pkg/server/api-server.go | 31 +++- pkg/server/{handler => }/appHandlers.go | 24 ++- .../{handler => }/capabilityHandlers.go | 23 ++- pkg/server/{handler => }/componentHandlers.go | 13 +- pkg/server/{handler => }/envHandlers.go | 29 ++-- pkg/server/handler/scopeHandlers.go | 19 --- pkg/server/handler/traitHandler.go | 79 ---------- pkg/server/main/startAPIServer.go | 14 +- pkg/server/{handler => }/miscHandlers.go | 4 +- pkg/server/route.go | 95 ++++++------ pkg/server/scopeHandlers.go | 19 +++ pkg/server/traitHandler.go | 138 ++++++++++++++++++ pkg/server/{handler => }/workloadHandler.go | 16 +- 27 files changed, 372 insertions(+), 379 deletions(-) rename pkg/server/{handler => }/appHandlers.go (72%) rename pkg/server/{handler => }/capabilityHandlers.go (75%) rename pkg/server/{handler => }/componentHandlers.go (75%) rename pkg/server/{handler => }/envHandlers.go (79%) delete mode 100644 pkg/server/handler/scopeHandlers.go delete mode 100644 pkg/server/handler/traitHandler.go rename pkg/server/{handler => }/miscHandlers.go (80%) create mode 100644 pkg/server/scopeHandlers.go create mode 100644 pkg/server/traitHandler.go rename pkg/server/{handler => }/workloadHandler.go (86%) diff --git a/pkg/commands/capability.go b/pkg/commands/capability.go index 235af7618..01fab4acb 100644 --- a/pkg/commands/capability.go +++ b/pkg/commands/capability.go @@ -100,7 +100,7 @@ func NewCapInstallCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Comm if err != nil { return err } - if _, err = oam.AddCapabilityIntoCluster(newClient, args[0]); err != nil { + if _, err = oam.AddCapabilityIntoCluster(newClient, mapper, args[0]); err != nil { return err } return nil diff --git a/pkg/commands/dashboard.go b/pkg/commands/dashboard.go index 2b2aee722..85bfa26c3 100644 --- a/pkg/commands/dashboard.go +++ b/pkg/commands/dashboard.go @@ -51,7 +51,7 @@ func NewDashboardCommand(c types.Args, ioStreams cmdutil.IOStreams, frontendSour if !runtimeReady { return nil } - return SetupAPIServer(newClient, cmd, o) + return SetupAPIServer(c, cmd, o) }, Annotations: map[string]string{ types.TagCommandType: types.TypeSystem, @@ -124,8 +124,7 @@ func (o *Options) GetStaticPath() error { return nil } -func SetupAPIServer(kubeClient client.Client, cmd *cobra.Command, o Options) error { - +func SetupAPIServer(c types.Args, cmd *cobra.Command, o Options) error { // setup logging var w io.Writer if len(o.logFilePath) > 0 { @@ -154,12 +153,14 @@ func SetupAPIServer(kubeClient client.Client, cmd *cobra.Command, o Options) err } //Setup RESTful server - server := server.APIServer{} - + server, err := server.New(c, o.port, o.staticPath) + if err != nil { + return err + } errCh := make(chan error, 1) cmd.Printf("Serving at %v\nstatic dir is %v", o.port, o.staticPath) - server.Launch(kubeClient, o.port, o.staticPath, errCh) + server.Launch(errCh) select { case err = <-errCh: return err @@ -207,5 +208,5 @@ func CheckVelaRuntimeInstalledAndReady(ioStreams cmdutil.IOStreams, c client.Cli white.Sprint("vela install --help"))) return false, nil } - return PrintTrackVelaRuntimeStatus(context.Background(), c, ioStreams) + return PrintTrackVelaRuntimeStatus(context.Background(), c, ioStreams, 5*time.Minute) } diff --git a/pkg/commands/env.go b/pkg/commands/env.go index 8490ed5ea..5644d2387 100644 --- a/pkg/commands/env.go +++ b/pkg/commands/env.go @@ -65,7 +65,7 @@ func NewEnvInitCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command return err } if syncCluster { - if err := RefreshDefinitions(ctx, newClient, ioStreams, true); err != nil { + if err := RefreshDefinitions(ctx, c, ioStreams, true); err != nil { return err } } diff --git a/pkg/commands/system.go b/pkg/commands/system.go index 048a716cb..63b0d6837 100644 --- a/pkg/commands/system.go +++ b/pkg/commands/system.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "io/ioutil" + "os" "time" "github.com/openservicemesh/osm/pkg/cli" @@ -17,6 +19,7 @@ import ( "github.com/oam-dev/kubevela/api/types" cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" + "github.com/oam-dev/kubevela/pkg/plugins" "github.com/oam-dev/kubevela/pkg/utils/helm" ) @@ -35,7 +38,8 @@ type initCmd struct { client client.Client chartPath string chartArgs chartArgs - waitReady bool + waitReady string + c types.Args } type chartArgs struct { @@ -103,6 +107,7 @@ func NewInstallCommand(c types.Args, chartContent string, ioStreams cmdutil.IOSt } i.client = newClient i.namespace = types.DefaultOAMNS + i.c = c return i.run(ioStreams, chartContent) }, Annotations: map[string]string{ @@ -115,12 +120,17 @@ func NewInstallCommand(c types.Args, chartContent string, ioStreams cmdutil.IOSt flag.StringVarP(&i.chartArgs.imagePullPolicy, "image-pull-policy", "", "IfNotPresent", "vela core image pull policy, this will align to chart value image.pullPolicy") flag.StringVarP(&i.chartArgs.imageRepo, "image-repo", "", "oamdev/vela-core", "vela core image repo, this will align to chart value image.repo") flag.StringVarP(&i.chartArgs.imageTag, "image-tag", "", "latest", "vela core image repo, this will align to chart value image.tag") - flag.BoolVarP(&i.waitReady, "wait", "w", false, "wait until vela-core is ready to serve") + flag.StringVarP(&i.waitReady, "wait", "w", "0s", "wait until vela-core is ready to serve, default will not wait") return cmd } func (i *initCmd) run(ioStreams cmdutil.IOStreams, chartSource string) error { + waitDuration, err := time.ParseDuration(i.waitReady) + if err != nil { + return fmt.Errorf("invalid wait timeoout duration %v, should use '120s', '5m' like format", err) + } + ioStreams.Info("- Installing Vela Core Chart:") exist, err := cmdutil.DoesNamespaceExist(i.client, types.DefaultOAMNS) if err != nil { @@ -145,14 +155,16 @@ func (i *initCmd) run(ioStreams cmdutil.IOStreams, chartSource string) error { return err } } - - if err := RefreshDefinitions(context.Background(), i.client, ioStreams, false); err != nil { + if err = CheckCapabilityReady(context.Background(), i.c, waitDuration); err != nil { + return err + } + if err := RefreshDefinitions(context.Background(), i.c, ioStreams, false); err != nil { return err } ioStreams.Info("- Finished successfully.") - if i.waitReady { - _, err := PrintTrackVelaRuntimeStatus(context.Background(), i.client, ioStreams) + if waitDuration > 0 { + _, err := PrintTrackVelaRuntimeStatus(context.Background(), i.client, ioStreams, waitDuration) if err != nil { return err } @@ -160,6 +172,34 @@ func (i *initCmd) run(ioStreams cmdutil.IOStreams, chartSource string) error { return nil } +// MUST wait to install capability succeed +func CheckCapabilityReady(ctx context.Context, c types.Args, timeout time.Duration) error { + if timeout < 2*time.Minute { + timeout = 2 * time.Minute + } + tmpdir, err := ioutil.TempDir(".", "tmpcap") + if err != nil { + return err + } + defer os.RemoveAll(tmpdir) + + start := time.Now() + spiner := newTrackingSpinner("Waiting Capability ready to install ...") + spiner.Start() + defer spiner.Stop() + + for { + _, err = plugins.GetCapabilitiesFromCluster(ctx, types.DefaultOAMNS, c, tmpdir, nil) + if err == nil { + return nil + } + if time.Since(start) > timeout { + return fmt.Errorf("timeout checking capability ready: %v", err) + } + time.Sleep(5 * time.Second) + } +} + func (i *initCmd) resolveValues() (map[string]interface{}, error) { finalValues := map[string]interface{}{} valuesConfig := []string{ @@ -222,9 +262,8 @@ func GetOAMReleaseVersion(ns string) (string, error) { return "", errors.New("oam-kubernetes-runtime not found in your kubernetes cluster, try `vela install` to install") } -func PrintTrackVelaRuntimeStatus(ctx context.Context, c client.Client, ioStreams cmdutil.IOStreams) (bool, error) { - trackTimeout := 5 * time.Minute - trackInterval := 2 * time.Second +func PrintTrackVelaRuntimeStatus(ctx context.Context, c client.Client, ioStreams cmdutil.IOStreams, trackTimeout time.Duration) (bool, error) { + trackInterval := 5 * time.Second ioStreams.Info("\nIt may take 1-2 minutes before KubeVela runtime is ready.") start := time.Now() diff --git a/pkg/commands/traits.go b/pkg/commands/traits.go index be94835b5..e0aa943be 100644 --- a/pkg/commands/traits.go +++ b/pkg/commands/traits.go @@ -10,7 +10,6 @@ import ( "github.com/gosuri/uitable" cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" "github.com/spf13/cobra" - "sigs.k8s.io/controller-runtime/pkg/client" ) func NewTraitsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command { @@ -25,11 +24,7 @@ func NewTraitsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command Example: `vela traits`, RunE: func(cmd *cobra.Command, args []string) error { if syncCluster { - newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema}) - if err != nil { - return err - } - if err := RefreshDefinitions(ctx, newClient, ioStreams, true); err != nil { + if err := RefreshDefinitions(ctx, c, ioStreams, true); err != nil { return err } } diff --git a/pkg/commands/workloads.go b/pkg/commands/workloads.go index 2c6489a72..d81bfc692 100644 --- a/pkg/commands/workloads.go +++ b/pkg/commands/workloads.go @@ -9,7 +9,6 @@ import ( "github.com/gosuri/uitable" "github.com/spf13/cobra" - "sigs.k8s.io/controller-runtime/pkg/client" ) func NewWorkloadsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command { @@ -23,11 +22,7 @@ func NewWorkloadsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Comma Example: `vela workloads`, RunE: func(cmd *cobra.Command, args []string) error { if syncCluster { - newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema}) - if err != nil { - return err - } - if err := RefreshDefinitions(ctx, newClient, ioStreams, true); err != nil { + if err := RefreshDefinitions(ctx, c, ioStreams, true); err != nil { return err } } diff --git a/pkg/oam/capability.go b/pkg/oam/capability.go index cd39f3f84..b247047fb 100644 --- a/pkg/oam/capability.go +++ b/pkg/oam/capability.go @@ -9,11 +9,9 @@ import ( "path/filepath" "strings" - "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util" - - "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" - "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2" + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util" "github.com/ghodss/yaml" apierrors "k8s.io/apimachinery/pkg/api/errors" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/oam/common.go b/pkg/oam/common.go index 9b4fa4104..0d28757f6 100644 --- a/pkg/oam/common.go +++ b/pkg/oam/common.go @@ -7,7 +7,6 @@ import ( "github.com/crossplane/oam-kubernetes-runtime/apis/core" certmanager "github.com/wonderflow/cert-manager-api/pkg/apis/certmanager/v1" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/oam-dev/kubevela/api/types" "github.com/oam-dev/kubevela/api/v1alpha1" @@ -27,17 +26,15 @@ func init() { // +kubebuilder:scaffold:scheme } -func InitKubeClient() (client.Client, error) { +func InitArgs() (types.Args, error) { restConf, err := config.GetConfig() if err != nil { fmt.Println("get kubeConfig err", err) os.Exit(1) } - commandArgs := types.Args{ + return types.Args{ Config: restConf, Schema: Scheme, - } - - return client.New(commandArgs.Config, client.Options{Scheme: commandArgs.Schema}) + }, nil } diff --git a/pkg/oam/trait.go b/pkg/oam/trait.go index ca37fb14a..46cf704e2 100644 --- a/pkg/oam/trait.go +++ b/pkg/oam/trait.go @@ -3,13 +3,10 @@ package oam import ( "context" "fmt" - "os" - "strconv" "strings" "cuelang.org/go/cue" plur "github.com/gertd/go-pluralize" - "github.com/gin-gonic/gin" "github.com/spf13/pflag" "sigs.k8s.io/controller-runtime/pkg/client" @@ -18,7 +15,6 @@ import ( cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" "github.com/oam-dev/kubevela/pkg/plugins" "github.com/oam-dev/kubevela/pkg/server/apis" - env2 "github.com/oam-dev/kubevela/pkg/utils/env" ) func ListTraitDefinitions(workloadName *string) ([]types.Capability, error) { @@ -198,41 +194,6 @@ func AddOrUpdateTrait(env *types.EnvMeta, appName string, componentName string, return app, app.Save(env.Name) } -func AttachTrait(c *gin.Context, body apis.TraitBody) (string, error) { - // Prepare - var appObj *application.Application - fs := pflag.NewFlagSet("trait", pflag.ContinueOnError) - for _, f := range body.Flags { - fs.String(f.Name, f.Value, "") - } - var staging = false - var err error - if body.Staging != "" { - staging, err = strconv.ParseBool(body.Staging) - if err != nil { - return "", err - } - } - traitAlias := body.Name - template, err := plugins.GetInstalledCapabilityWithCapAlias(types.TypeTrait, traitAlias) - if err != nil { - return "", err - } - // Run step - env, err := env2.GetEnvByName(body.EnvName) - if err != nil { - return "", err - } - - appObj, err = AddOrUpdateTrait(env, body.AppName, body.ComponentName, fs, template) - if err != nil { - return "", err - } - kubeClient := c.MustGet("KubeClient") - io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} - return TraitOperationRun(c, kubeClient.(client.Client), env, appObj, staging, io) -} - func TraitOperationRun(ctx context.Context, c client.Client, env *types.EnvMeta, appObj *application.Application, staging bool, io cmdutil.IOStreams) (string, error) { if staging { @@ -260,22 +221,3 @@ func PrepareDetachTrait(envName string, traitType string, componentName string, } return appObj, appObj.Save(envName) } - -func DetachTrait(c *gin.Context, envName string, traitType string, componentName string, appName string, staging bool) (string, error) { - var appObj *application.Application - var err error - if appName == "" { - appName = componentName - } - if appObj, err = PrepareDetachTrait(envName, traitType, componentName, appName); err != nil { - return "", err - } - // Run - env, err := env2.GetEnvByName(envName) - if err != nil { - return "", err - } - kubeClient := c.MustGet("KubeClient") - io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} - return TraitOperationRun(c, kubeClient.(client.Client), env, appObj, staging, io) -} diff --git a/pkg/plugins/cluster_test.go b/pkg/plugins/cluster_test.go index ed3030829..360e3f22b 100644 --- a/pkg/plugins/cluster_test.go +++ b/pkg/plugins/cluster_test.go @@ -16,7 +16,6 @@ import ( ) var _ = Describe("DefinitionFiles", func() { - route := types.Capability{ Name: "routes.test", Type: types.TypeTrait, @@ -29,13 +28,17 @@ var _ = Describe("DefinitionFiles", func() { }, }, Description: "description not defined", - CrdName: "routes.test", + CrdName: "routes.standard.oam.dev", + CrdInfo: &types.CrdInfo{ + APIVersion: "standard.oam.dev/v1alpha1", + Kind: "Route", + }, } deployment := types.Capability{ Name: "deployments.testapps", Type: types.TypeWorkload, - CrdName: "deployments.testapps", + CrdName: "deployments.apps", Description: "description not defined", Parameters: []types.Parameter{ { @@ -58,6 +61,10 @@ var _ = Describe("DefinitionFiles", func() { Usage: "Which port do you want customer traffic sent to", }, }, + CrdInfo: &types.CrdInfo{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, } websvc := types.Capability{ @@ -80,7 +87,11 @@ var _ = Describe("DefinitionFiles", func() { Default: int64(6379), Usage: "Which port do you want customer traffic sent to", }}, - CrdName: "webservice.testapps", + CrdName: "deployments.apps", + CrdInfo: &types.CrdInfo{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, } req, _ := labels.NewRequirement("usecase", selection.Equals, []string{"forplugintest"}) @@ -89,7 +100,7 @@ var _ = Describe("DefinitionFiles", func() { // Notice!! DefinitionPath Object is Cluster Scope object // which means objects created in other DefinitionNamespace will also affect here. It("gettrait", func() { - traitDefs, _, err := GetTraitsFromCluster(context.Background(), DefinitionNamespace, k8sClient, definitionDir, selector) + traitDefs, _, err := GetTraitsFromCluster(context.Background(), DefinitionNamespace, types.Args{Config: cfg, Schema: scheme}, definitionDir, selector) Expect(err).Should(BeNil()) logf.Log.Info(fmt.Sprintf("Getting trait definitions %v", traitDefs)) for i := range traitDefs { @@ -105,7 +116,7 @@ var _ = Describe("DefinitionFiles", func() { // Notice!! DefinitionPath Object is Cluster Scope object // which means objects created in other DefinitionNamespace will also affect here. It("getworkload", func() { - workloadDefs, _, err := GetWorkloadsFromCluster(context.Background(), DefinitionNamespace, k8sClient, definitionDir, selector) + workloadDefs, _, err := GetWorkloadsFromCluster(context.Background(), DefinitionNamespace, types.Args{Config: cfg, Schema: scheme}, definitionDir, selector) Expect(err).Should(BeNil()) logf.Log.Info(fmt.Sprintf("Getting workload definitions %v", workloadDefs)) for i := range workloadDefs { @@ -118,7 +129,7 @@ var _ = Describe("DefinitionFiles", func() { Expect(workloadDefs).Should(Equal([]types.Capability{deployment, websvc})) }) It("getall", func() { - alldef, err := GetCapabilitiesFromCluster(context.Background(), DefinitionNamespace, k8sClient, definitionDir, selector) + alldef, err := GetCapabilitiesFromCluster(context.Background(), DefinitionNamespace, types.Args{Config: cfg, Schema: scheme}, definitionDir, selector) Expect(err).Should(BeNil()) logf.Log.Info(fmt.Sprintf("Getting all definitions %v", alldef)) for i := range alldef { diff --git a/pkg/plugins/suit_test.go b/pkg/plugins/suit_test.go index 5359748f0..a78e04c71 100644 --- a/pkg/plugins/suit_test.go +++ b/pkg/plugins/suit_test.go @@ -33,6 +33,7 @@ import ( // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. var cfg *rest.Config +var scheme *runtime.Scheme var k8sClient client.Client var testEnv *envtest.Environment var definitionDir string @@ -53,7 +54,7 @@ var _ = BeforeSuite(func(done Done) { By("bootstrapping test environment") useExistCluster := false testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "charts", "vela-core", "crds")}, UseExistingCluster: &useExistCluster, } @@ -61,63 +62,17 @@ var _ = BeforeSuite(func(done Done) { cfg, err = testEnv.Start() Expect(err).ToNot(HaveOccurred()) Expect(cfg).ToNot(BeNil()) - scheme := runtime.NewScheme() + scheme = runtime.NewScheme() Expect(corev1alpha2.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(clientgoscheme.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(v1beta1.AddToScheme(scheme)).NotTo(HaveOccurred()) - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) Expect(err).ToNot(HaveOccurred()) Expect(k8sClient).ToNot(BeNil()) - crd := v1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "traitdefinitions.core.oam.dev", - }, - Spec: v1beta1.CustomResourceDefinitionSpec{ - Group: "core.oam.dev", - Names: v1beta1.CustomResourceDefinitionNames{ - Kind: "TraitDefinition", - ListKind: "TraitDefinitionList", - Plural: "traitdefinitions", - Singular: "traitdefinition", - }, - Versions: []v1beta1.CustomResourceDefinitionVersion{ - { - Name: "v1alpha2", - Served: true, - Storage: true, - }, - }, - }, - } - Expect(k8sClient.Create(context.Background(), &crd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) - - crd = v1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "workloaddefinitions.core.oam.dev", - }, - Spec: v1beta1.CustomResourceDefinitionSpec{ - Group: "core.oam.dev", - Names: v1beta1.CustomResourceDefinitionNames{ - Kind: "WorkloadDefinition", - ListKind: "WorkloadDefinitionList", - Plural: "workloaddefinitions", - Singular: "workloaddefinition", - }, - Versions: []v1beta1.CustomResourceDefinitionVersion{ - { - Name: "v1alpha2", - Served: true, - Storage: true, - }, - }, - }, - } definitionDir, err = system.GetCapabilityDir() Expect(err).Should(BeNil()) Expect(os.MkdirAll(definitionDir, 0755)).Should(BeNil()) - Expect(k8sClient.Create(context.Background(), &crd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: DefinitionNamespace}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) diff --git a/pkg/plugins/testdata/traitDef.yaml b/pkg/plugins/testdata/traitDef.yaml index 070ee434a..d5569fb21 100644 --- a/pkg/plugins/testdata/traitDef.yaml +++ b/pkg/plugins/testdata/traitDef.yaml @@ -6,12 +6,10 @@ metadata: usecase: forplugintest spec: definitionRef: - name: routes.test + name: routes.standard.oam.dev extension: template: | output: { - apiVersion: "apps/v1" - kind: "Route" spec: { domain: parameter.domain } diff --git a/pkg/plugins/testdata/websvcWorkloadDef.yaml b/pkg/plugins/testdata/websvcWorkloadDef.yaml index 234e18fb2..30a0f6925 100644 --- a/pkg/plugins/testdata/websvcWorkloadDef.yaml +++ b/pkg/plugins/testdata/websvcWorkloadDef.yaml @@ -6,7 +6,7 @@ metadata: usecase: forplugintest spec: definitionRef: - name: webservice.testapps + name: deployments.apps extension: template: | output: { diff --git a/pkg/plugins/testdata/workloadDef.yaml b/pkg/plugins/testdata/workloadDef.yaml index c008caf1e..9f4f7d8e7 100644 --- a/pkg/plugins/testdata/workloadDef.yaml +++ b/pkg/plugins/testdata/workloadDef.yaml @@ -6,7 +6,7 @@ metadata: usecase: forplugintest spec: definitionRef: - name: deployments.testapps + name: deployments.apps extension: template: | output: { diff --git a/pkg/server/api-server.go b/pkg/server/api-server.go index 313adf15b..0677b5682 100644 --- a/pkg/server/api-server.go +++ b/pkg/server/api-server.go @@ -5,23 +5,44 @@ import ( "net/http" "time" + "github.com/oam-dev/kubevela/api/types" + + "github.com/crossplane/oam-kubernetes-runtime/pkg/oam/discoverymapper" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) type APIServer struct { - server *http.Server + server *http.Server + KubeClient client.Client + dm discoverymapper.DiscoveryMapper } -func (s *APIServer) Launch(kubeClient client.Client, port, staticPath string, errChan chan<- error) { - s.server = &http.Server{ +func New(c types.Args, port, staticPath string) (*APIServer, error) { + newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema}) + if err != nil { + return nil, err + } + dm, err := discoverymapper.New(c.Config) + if err != nil { + return nil, err + } + s := &APIServer{ + KubeClient: newClient, + dm: dm, + } + server := &http.Server{ Addr: port, - Handler: setupRoute(kubeClient, staticPath), + Handler: s.setupRoute(staticPath), ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } - s.server.SetKeepAlivesEnabled(true) + server.SetKeepAlivesEnabled(true) + s.server = server + return s, nil +} +func (s *APIServer) Launch(errChan chan<- error) { go func() { err := s.server.ListenAndServe() if err != nil && err != http.ErrServerClosed { diff --git a/pkg/server/handler/appHandlers.go b/pkg/server/appHandlers.go similarity index 72% rename from pkg/server/handler/appHandlers.go rename to pkg/server/appHandlers.go index 81e21966d..54c33e07a 100644 --- a/pkg/server/handler/appHandlers.go +++ b/pkg/server/appHandlers.go @@ -1,21 +1,17 @@ -package handler +package server import ( + "github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/server/util" "github.com/oam-dev/kubevela/pkg/utils/env" - "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/gin-gonic/gin" - - "github.com/oam-dev/kubevela/pkg/oam" ) -func UpdateApps(c *gin.Context) { +func (s *APIServer) UpdateApps(c *gin.Context) { } -func GetApp(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) GetApp(c *gin.Context) { envName := c.Param("envName") envMeta, err := env.GetEnvByName(envName) if err != nil { @@ -25,7 +21,7 @@ func GetApp(c *gin.Context) { namespace := envMeta.Namespace appName := c.Param("appName") ctx := util.GetContext(c) - applicationMeta, err := oam.RetrieveApplicationStatusByName(ctx, kubeClient.(client.Client), appName, namespace) + applicationMeta, err := oam.RetrieveApplicationStatusByName(ctx, s.KubeClient, appName, namespace) if err != nil { util.HandleError(c, util.StatusInternalServerError, err) return @@ -33,8 +29,7 @@ func GetApp(c *gin.Context) { util.AssembleResponse(c, applicationMeta, nil) } -func ListApps(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) ListApps(c *gin.Context) { envName := c.Param("envName") envMeta, err := env.GetEnvByName(envName) if err != nil { @@ -44,7 +39,7 @@ func ListApps(c *gin.Context) { namespace := envMeta.Namespace ctx := util.GetContext(c) - applicationMetaList, err := oam.ListApplications(ctx, kubeClient.(client.Client), oam.Option{Namespace: namespace}) + applicationMetaList, err := oam.ListApplications(ctx, s.KubeClient, oam.Option{Namespace: namespace}) if err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) return @@ -52,8 +47,7 @@ func ListApps(c *gin.Context) { util.AssembleResponse(c, applicationMetaList, nil) } -func DeleteApps(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) DeleteApps(c *gin.Context) { envName := c.Param("envName") envMeta, err := env.GetEnvByName(envName) if err != nil { @@ -63,7 +57,7 @@ func DeleteApps(c *gin.Context) { appName := c.Param("appName") o := oam.DeleteOptions{ - Client: kubeClient.(client.Client), + Client: s.KubeClient, Env: envMeta, AppName: appName, } diff --git a/pkg/server/handler/capabilityHandlers.go b/pkg/server/capabilityHandlers.go similarity index 75% rename from pkg/server/handler/capabilityHandlers.go rename to pkg/server/capabilityHandlers.go index fd9a26366..ec7657baa 100644 --- a/pkg/server/handler/capabilityHandlers.go +++ b/pkg/server/capabilityHandlers.go @@ -1,4 +1,4 @@ -package handler +package server import ( "github.com/oam-dev/kubevela/pkg/oam" @@ -6,10 +6,9 @@ import ( "github.com/oam-dev/kubevela/pkg/server/util" "github.com/gin-gonic/gin" - "sigs.k8s.io/controller-runtime/pkg/client" ) -func AddCapabilityCenter(c *gin.Context) { +func (s *APIServer) AddCapabilityCenter(c *gin.Context) { var body plugins.CapCenterConfig if err := c.ShouldBindJSON(&body); err != nil { util.HandleError(c, util.StatusInternalServerError, "the add capability center request body is invalid") @@ -22,7 +21,7 @@ func AddCapabilityCenter(c *gin.Context) { util.AssembleResponse(c, "Successfully configured capability center and synchronized from remote", nil) } -func ListCapabilityCenters(c *gin.Context) { +func (s *APIServer) ListCapabilityCenters(c *gin.Context) { capabilityCenterList, err := oam.ListCapabilityCenters() if err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) @@ -31,7 +30,7 @@ func ListCapabilityCenters(c *gin.Context) { util.AssembleResponse(c, capabilityCenterList, nil) } -func SyncCapabilityCenter(c *gin.Context) { +func (s *APIServer) SyncCapabilityCenter(c *gin.Context) { capabilityCenterName := c.Param("capabilityCenterName") if err := oam.SyncCapabilityCenter(capabilityCenterName); err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) @@ -40,10 +39,9 @@ func SyncCapabilityCenter(c *gin.Context) { util.AssembleResponse(c, "sync finished", nil) } -func AddCapabilityIntoCluster(c *gin.Context) { +func (s *APIServer) AddCapabilityIntoCluster(c *gin.Context) { cap := c.Param("capabilityCenterName") + "/" + c.Param("capabilityName") - kubeClient := c.MustGet("KubeClient") - msg, err := oam.AddCapabilityIntoCluster(kubeClient.(client.Client), cap) + msg, err := oam.AddCapabilityIntoCluster(s.KubeClient, s.dm, cap) if err != nil { util.HandleError(c, util.StatusInternalServerError) return @@ -51,16 +49,15 @@ func AddCapabilityIntoCluster(c *gin.Context) { util.AssembleResponse(c, msg, nil) } -func DeleteCapabilityCenter(c *gin.Context) { +func (s *APIServer) DeleteCapabilityCenter(c *gin.Context) { capabilityCenterName := c.Param("capabilityCenterName") msg, err := oam.RemoveCapabilityCenter(capabilityCenterName) util.AssembleResponse(c, msg, err) } -func RemoveCapabilityFromCluster(c *gin.Context) { +func (s *APIServer) RemoveCapabilityFromCluster(c *gin.Context) { capabilityCenterName := c.Param("capabilityName") - kubeClient := c.MustGet("KubeClient") - msg, err := oam.RemoveCapabilityFromCluster(kubeClient.(client.Client), capabilityCenterName) + msg, err := oam.RemoveCapabilityFromCluster(s.KubeClient, capabilityCenterName) if err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) return @@ -68,7 +65,7 @@ func RemoveCapabilityFromCluster(c *gin.Context) { util.AssembleResponse(c, msg, nil) } -func ListCapabilities(c *gin.Context) { +func (s *APIServer) ListCapabilities(c *gin.Context) { capabilityCenterName := c.Param("capabilityName") capabilityList, err := oam.ListCapabilities(capabilityCenterName) if err != nil { diff --git a/pkg/server/handler/componentHandlers.go b/pkg/server/componentHandlers.go similarity index 75% rename from pkg/server/handler/componentHandlers.go rename to pkg/server/componentHandlers.go index 9c3a71aa4..a3a9e1a2d 100644 --- a/pkg/server/handler/componentHandlers.go +++ b/pkg/server/componentHandlers.go @@ -1,10 +1,9 @@ -package handler +package server import ( "os" "github.com/gin-gonic/gin" - "sigs.k8s.io/controller-runtime/pkg/client" cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" "github.com/oam-dev/kubevela/pkg/oam" @@ -12,8 +11,7 @@ import ( "github.com/oam-dev/kubevela/pkg/utils/env" ) -func GetComponent(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) GetComponent(c *gin.Context) { envName := c.Param("envName") envMeta, err := env.GetEnvByName(envName) if err != nil { @@ -24,7 +22,7 @@ func GetComponent(c *gin.Context) { applicationName := c.Param("appName") componentName := c.Param("compName") ctx := util.GetContext(c) - componentMeta, err := oam.RetrieveComponent(ctx, kubeClient.(client.Client), applicationName, componentName, namespace) + componentMeta, err := oam.RetrieveComponent(ctx, s.KubeClient, applicationName, componentName, namespace) if err != nil { util.HandleError(c, util.StatusInternalServerError, err) return @@ -32,8 +30,7 @@ func GetComponent(c *gin.Context) { util.AssembleResponse(c, componentMeta, nil) } -func DeleteComponent(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) DeleteComponent(c *gin.Context) { envName := c.Param("envName") envMeta, err := env.GetEnvByName(envName) if err != nil { @@ -44,7 +41,7 @@ func DeleteComponent(c *gin.Context) { componentName := c.Param("compName") o := oam.DeleteOptions{ - Client: kubeClient.(client.Client), + Client: s.KubeClient, Env: envMeta, AppName: appName, CompName: componentName} diff --git a/pkg/server/handler/envHandlers.go b/pkg/server/envHandlers.go similarity index 79% rename from pkg/server/handler/envHandlers.go rename to pkg/server/envHandlers.go index a8ff87ab5..f1c225b0e 100644 --- a/pkg/server/handler/envHandlers.go +++ b/pkg/server/envHandlers.go @@ -1,20 +1,17 @@ -package handler +package server import ( "github.com/gin-gonic/gin" + ctrl "sigs.k8s.io/controller-runtime" "github.com/oam-dev/kubevela/api/types" - "github.com/oam-dev/kubevela/pkg/utils/env" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/oam-dev/kubevela/pkg/server/apis" "github.com/oam-dev/kubevela/pkg/server/util" + "github.com/oam-dev/kubevela/pkg/utils/env" ) // environment related handlers -func CreateEnv(c *gin.Context) { +func (s *APIServer) CreateEnv(c *gin.Context) { var environment apis.Environment if err := c.ShouldBindJSON(&environment); err != nil { util.HandleError(c, util.InvalidArgument, "the create environment request body is invalid") @@ -28,8 +25,7 @@ func CreateEnv(c *gin.Context) { } ctx := util.GetContext(c) - kubeClient := c.MustGet("KubeClient") - message, err := env.CreateEnv(ctx, kubeClient.(client.Client), name, &types.EnvMeta{ + message, err := env.CreateEnv(ctx, s.KubeClient, name, &types.EnvMeta{ Name: name, Current: environment.Current, Namespace: namespace, @@ -39,7 +35,7 @@ func CreateEnv(c *gin.Context) { util.AssembleResponse(c, message, err) } -func UpdateEnv(c *gin.Context) { +func (s *APIServer) UpdateEnv(c *gin.Context) { envName := c.Param("envName") ctrl.Log.Info("Put a update environment request", "envName", envName) var environmentBody apis.EnvironmentBody @@ -48,12 +44,11 @@ func UpdateEnv(c *gin.Context) { return } ctx := util.GetContext(c) - kubeClient := c.MustGet("KubeClient") - message, err := env.UpdateEnv(ctx, kubeClient.(client.Client), envName, environmentBody.Namespace) + message, err := env.UpdateEnv(ctx, s.KubeClient, envName, environmentBody.Namespace) util.AssembleResponse(c, message, err) } -func GetEnv(c *gin.Context) { +func (s *APIServer) GetEnv(c *gin.Context) { envName := c.Param("envName") ctrl.Log.Info("Get a get environment request", "envName", envName) envList, err := env.ListEnvs(envName) @@ -69,18 +64,18 @@ func GetEnv(c *gin.Context) { util.AssembleResponse(c, environmentList, err) } -func ListEnv(c *gin.Context) { - GetEnv(c) +func (s *APIServer) ListEnv(c *gin.Context) { + s.GetEnv(c) } -func DeleteEnv(c *gin.Context) { +func (s *APIServer) DeleteEnv(c *gin.Context) { envName := c.Param("envName") ctrl.Log.Info("Delete a delete environment request", "envName", envName) msg, err := env.DeleteEnv(envName) util.AssembleResponse(c, msg, err) } -func SetEnv(c *gin.Context) { +func (s *APIServer) SetEnv(c *gin.Context) { envName := c.Param("envName") ctrl.Log.Info("Patch a set environment request", "envName", envName) msg, err := env.SetEnv(envName) diff --git a/pkg/server/handler/scopeHandlers.go b/pkg/server/handler/scopeHandlers.go deleted file mode 100644 index e7ca4d31c..000000000 --- a/pkg/server/handler/scopeHandlers.go +++ /dev/null @@ -1,19 +0,0 @@ -package handler - -import "github.com/gin-gonic/gin" - -// Scope related handlers -func CreateScope(c *gin.Context) { -} - -func UpdateScope(c *gin.Context) { -} - -func GetScope(c *gin.Context) { -} - -func ListScope(c *gin.Context) { -} - -func DeleteScope(c *gin.Context) { -} diff --git a/pkg/server/handler/traitHandler.go b/pkg/server/handler/traitHandler.go deleted file mode 100644 index d3aab520e..000000000 --- a/pkg/server/handler/traitHandler.go +++ /dev/null @@ -1,79 +0,0 @@ -package handler - -import ( - "strconv" - - "github.com/gin-gonic/gin" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/oam-dev/kubevela/api/types" - "github.com/oam-dev/kubevela/pkg/oam" - "github.com/oam-dev/kubevela/pkg/server/apis" - "github.com/oam-dev/kubevela/pkg/server/util" -) - -// Trait related handlers -func AttachTrait(c *gin.Context) { - var body apis.TraitBody - body.EnvName = c.Param("envName") - body.AppName = c.Param("appName") - body.ComponentName = c.Param("compName") - - if err := c.ShouldBindJSON(&body); err != nil { - util.HandleError(c, util.InvalidArgument, "the trait attach request body is invalid") - return - } - ctrl.Log.Info("request parameters body:", "body", body) - msg, err := oam.AttachTrait(c, body) - if err != nil { - util.HandleError(c, util.StatusInternalServerError, err.Error()) - return - } - util.AssembleResponse(c, msg, nil) -} - -func GetTrait(c *gin.Context) { - var traitType = c.Param("traitName") - var workloadType string - var capability types.Capability - var err error - - if capability, err = oam.GetTraitDefinition(&workloadType, traitType); err != nil { - util.HandleError(c, util.StatusInternalServerError, err) - return - } - util.AssembleResponse(c, capability, err) -} - -func ListTrait(c *gin.Context) { - var traitList []types.Capability - var workloadName string - var err error - if traitList, err = oam.ListTraitDefinitions(&workloadName); err != nil { - util.HandleError(c, util.StatusInternalServerError, err) - return - } - util.AssembleResponse(c, traitList, err) -} - -func DetachTrait(c *gin.Context) { - envName := c.Param("envName") - traitType := c.Param("traitName") - componentName := c.Param("compName") - applicationName := c.Param("appName") - - var staging = false - var err error - if stagingStr := c.Param("staging"); stagingStr != "" { - if staging, err = strconv.ParseBool(stagingStr); err != nil { - util.HandleError(c, util.StatusInternalServerError, err.Error()) - return - } - } - msg, err := oam.DetachTrait(c, envName, traitType, componentName, applicationName, staging) - if err != nil { - util.HandleError(c, util.StatusInternalServerError, err.Error()) - return - } - util.AssembleResponse(c, msg, nil) -} diff --git a/pkg/server/main/startAPIServer.go b/pkg/server/main/startAPIServer.go index 26e1c459d..e0227a784 100644 --- a/pkg/server/main/startAPIServer.go +++ b/pkg/server/main/startAPIServer.go @@ -26,14 +26,20 @@ func main() { o.Development = development o.DestWritter = w })) - apiServer := server.APIServer{} - kubeClient, err := oam.InitKubeClient() + + c, err := oam.InitArgs() if err != nil { - ctrl.Log.Error(err, "failed to init an Kubernetes client") + ctrl.Log.Error(err, "failed to init Kubernetes Config") os.Exit(1) } + apiServer, err := server.New(c, util.DefaultAPIServerPort, "") + if err != nil { + ctrl.Log.Error(err, "failed to init dashboard server") + os.Exit(1) + } + errCh := make(chan error, 1) - apiServer.Launch(kubeClient, util.DefaultAPIServerPort, "", errCh) + apiServer.Launch(errCh) err = <-errCh if err != nil { ctrl.Log.Error(err, "failed to launch API server") diff --git a/pkg/server/handler/miscHandlers.go b/pkg/server/miscHandlers.go similarity index 80% rename from pkg/server/handler/miscHandlers.go rename to pkg/server/miscHandlers.go index a918ca164..bbe802b7e 100644 --- a/pkg/server/handler/miscHandlers.go +++ b/pkg/server/miscHandlers.go @@ -1,4 +1,4 @@ -package handler +package server import ( "net/http" @@ -9,7 +9,7 @@ import ( "github.com/oam-dev/kubevela/version" ) -func GetVersion(c *gin.Context) { +func (s *APIServer) GetVersion(c *gin.Context) { c.JSON(http.StatusOK, apis.Response{ Code: http.StatusOK, Data: map[string]string{"version": version.VelaVersion}, diff --git a/pkg/server/route.go b/pkg/server/route.go index 4add0ef9e..2c011ce98 100644 --- a/pkg/server/route.go +++ b/pkg/server/route.go @@ -7,15 +7,13 @@ import ( "github.com/gin-contrib/static" "github.com/gin-gonic/gin" - "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/oam-dev/kubevela/pkg/server/handler" "github.com/oam-dev/kubevela/pkg/server/util" ) // setup the gin http server handler -func setupRoute(kubeClient client.Client, staticPath string) http.Handler { +func (s *APIServer) setupRoute(staticPath string) http.Handler { // if deploying static Dashboard, set the mode to `release`, or to `debug` if staticPath != "" { gin.SetMode(gin.ReleaseMode) @@ -46,44 +44,41 @@ func setupRoute(kubeClient client.Client, staticPath string) http.Handler { router.Use(util.SetContext()) router.Use(gin.Recovery()) router.Use(util.ValidateHeaders()) - //Store kubernetes client which could be retrieved by handlers - router.Use(util.StoreClient(kubeClient)) // all requests start with /api api := router.Group(util.RootPath) // env related operation envs := api.Group(util.EnvironmentPath) { - envs.POST("/", handler.CreateEnv) - envs.PUT("/:envName", handler.UpdateEnv) - envs.GET("/:envName", handler.GetEnv) - envs.GET("/", handler.ListEnv) + envs.POST("/", s.CreateEnv) + envs.PUT("/:envName", s.UpdateEnv) + envs.GET("/:envName", s.GetEnv) + envs.GET("/", s.ListEnv) // Allow levaing out `/` to make API more friendly - envs.GET("", handler.ListEnv) - envs.DELETE("/:envName", handler.DeleteEnv) - envs.PATCH("/:envName", handler.SetEnv) + envs.GET("", s.ListEnv) + envs.DELETE("/:envName", s.DeleteEnv) + envs.PATCH("/:envName", s.SetEnv) // app related operation apps := envs.Group("/:envName/apps") { - //apps.POST("/", handler.CreateApps) - apps.GET("/:appName", handler.GetApp) - apps.PUT("/:appName", handler.UpdateApps) - apps.GET("/", handler.ListApps) - apps.GET("", handler.ListApps) - apps.DELETE("/:appName", handler.DeleteApps) + apps.GET("/:appName", s.GetApp) + apps.PUT("/:appName", s.UpdateApps) + apps.GET("/", s.ListApps) + apps.GET("", s.ListApps) + apps.DELETE("/:appName", s.DeleteApps) // component related operation components := apps.Group("/:appName/components") { - components.GET("/:compName", handler.GetComponent) - components.PUT("/:compName", handler.GetComponent) - components.GET("/", handler.GetApp) - components.GET("", handler.GetApp) - components.DELETE("/:compName", handler.DeleteComponent) + components.GET("/:compName", s.GetComponent) + components.PUT("/:compName", s.GetComponent) + components.GET("/", s.GetApp) + components.GET("", s.GetApp) + components.DELETE("/:compName", s.DeleteComponent) traitWorkload := components.Group("/:compName/" + util.TraitDefinitionPath) { - traitWorkload.POST("/", handler.AttachTrait) - traitWorkload.DELETE("/:traitName", handler.DetachTrait) + traitWorkload.POST("/", s.AttachTrait) + traitWorkload.DELETE("/:traitName", s.DetachTrait) } } } @@ -91,56 +86,56 @@ func setupRoute(kubeClient client.Client, staticPath string) http.Handler { // workload related api workload := api.Group(util.WorkloadDefinitionPath) { - workload.POST("/", handler.CreateWorkload) - workload.GET("/:workloadName", handler.GetWorkload) - workload.PUT("/:workloadName", handler.UpdateWorkload) - workload.GET("/", handler.ListWorkload) - workload.GET("", handler.ListWorkload) + workload.POST("/", s.CreateWorkload) + workload.GET("/:workloadName", s.GetWorkload) + workload.PUT("/:workloadName", s.UpdateWorkload) + workload.GET("/", s.ListWorkload) + workload.GET("", s.ListWorkload) } // trait related api trait := api.Group(util.TraitDefinitionPath) { - trait.GET("/:traitName", handler.GetTrait) - trait.GET("/", handler.ListTrait) - trait.GET("", handler.ListTrait) + trait.GET("/:traitName", s.GetTrait) + trait.GET("/", s.ListTrait) + trait.GET("", s.ListTrait) } // scope related api scopes := api.Group(util.ScopeDefinitionPath) { - scopes.POST("/", handler.CreateScope) - scopes.GET("/:scopeName", handler.GetScope) - scopes.PUT("/:scopeName", handler.UpdateScope) - scopes.GET("/", handler.ListScope) - scopes.GET("", handler.ListScope) - scopes.DELETE("/:scopeName", handler.DeleteScope) + scopes.POST("/", s.CreateScope) + scopes.GET("/:scopeName", s.GetScope) + scopes.PUT("/:scopeName", s.UpdateScope) + scopes.GET("/", s.ListScope) + scopes.GET("", s.ListScope) + scopes.DELETE("/:scopeName", s.DeleteScope) } // capability center related api capCenters := api.Group(util.CapabilityCenterPath) { - capCenters.PUT("/", handler.AddCapabilityCenter) - capCenters.GET("/", handler.ListCapabilityCenters) - capCenters.GET("", handler.ListCapabilityCenters) - capCenters.DELETE("/:capabilityCenterName", handler.DeleteCapabilityCenter) + capCenters.PUT("/", s.AddCapabilityCenter) + capCenters.GET("/", s.ListCapabilityCenters) + capCenters.GET("", s.ListCapabilityCenters) + capCenters.DELETE("/:capabilityCenterName", s.DeleteCapabilityCenter) caps := capCenters.Group("/:capabilityCenterName" + util.CapabilityPath) { - caps.PUT("/", handler.SyncCapabilityCenter) - caps.PUT("/:capabilityName", handler.AddCapabilityIntoCluster) + caps.PUT("/", s.SyncCapabilityCenter) + caps.PUT("/:capabilityName", s.AddCapabilityIntoCluster) } } // capability related api caps := api.Group(util.CapabilityPath) { - caps.DELETE("/:capabilityName", handler.RemoveCapabilityFromCluster) - caps.DELETE("/", handler.RemoveCapabilityFromCluster) - caps.GET("/", handler.ListCapabilities) - caps.GET("", handler.ListCapabilities) + caps.DELETE("/:capabilityName", s.RemoveCapabilityFromCluster) + caps.DELETE("/", s.RemoveCapabilityFromCluster) + caps.GET("/", s.ListCapabilities) + caps.GET("", s.ListCapabilities) } // version - api.GET(util.VersionPath, handler.GetVersion) + api.GET(util.VersionPath, s.GetVersion) // default router.NoRoute(util.NoRoute()) diff --git a/pkg/server/scopeHandlers.go b/pkg/server/scopeHandlers.go new file mode 100644 index 000000000..f8fd4e9ab --- /dev/null +++ b/pkg/server/scopeHandlers.go @@ -0,0 +1,19 @@ +package server + +import "github.com/gin-gonic/gin" + +// Scope related handlers +func (s *APIServer) CreateScope(c *gin.Context) { +} + +func (s *APIServer) UpdateScope(c *gin.Context) { +} + +func (s *APIServer) GetScope(c *gin.Context) { +} + +func (s *APIServer) ListScope(c *gin.Context) { +} + +func (s *APIServer) DeleteScope(c *gin.Context) { +} diff --git a/pkg/server/traitHandler.go b/pkg/server/traitHandler.go new file mode 100644 index 000000000..0e7963cc1 --- /dev/null +++ b/pkg/server/traitHandler.go @@ -0,0 +1,138 @@ +package server + +import ( + "os" + "strconv" + + "github.com/oam-dev/kubevela/pkg/application" + util2 "github.com/oam-dev/kubevela/pkg/commands/util" + "github.com/oam-dev/kubevela/pkg/plugins" + env2 "github.com/oam-dev/kubevela/pkg/utils/env" + "github.com/spf13/pflag" + + "github.com/gin-gonic/gin" + ctrl "sigs.k8s.io/controller-runtime" + + "github.com/oam-dev/kubevela/api/types" + "github.com/oam-dev/kubevela/pkg/oam" + "github.com/oam-dev/kubevela/pkg/server/apis" + "github.com/oam-dev/kubevela/pkg/server/util" +) + +// Trait related handlers +func (s *APIServer) AttachTrait(c *gin.Context) { + var body apis.TraitBody + body.EnvName = c.Param("envName") + body.AppName = c.Param("appName") + body.ComponentName = c.Param("compName") + + if err := c.ShouldBindJSON(&body); err != nil { + util.HandleError(c, util.InvalidArgument, "the trait attach request body is invalid") + return + } + ctrl.Log.Info("request parameters body:", "body", body) + msg, err := s.DoAttachTrait(c, body) + if err != nil { + util.HandleError(c, util.StatusInternalServerError, err.Error()) + return + } + util.AssembleResponse(c, msg, nil) +} + +func (s *APIServer) GetTrait(c *gin.Context) { + var traitType = c.Param("traitName") + var workloadType string + var capability types.Capability + var err error + + if capability, err = oam.GetTraitDefinition(&workloadType, traitType); err != nil { + util.HandleError(c, util.StatusInternalServerError, err) + return + } + util.AssembleResponse(c, capability, err) +} + +func (s *APIServer) ListTrait(c *gin.Context) { + var traitList []types.Capability + var workloadName string + var err error + if traitList, err = oam.ListTraitDefinitions(&workloadName); err != nil { + util.HandleError(c, util.StatusInternalServerError, err) + return + } + util.AssembleResponse(c, traitList, err) +} + +func (s *APIServer) DetachTrait(c *gin.Context) { + envName := c.Param("envName") + traitType := c.Param("traitName") + componentName := c.Param("compName") + applicationName := c.Param("appName") + + var staging = false + var err error + if stagingStr := c.Param("staging"); stagingStr != "" { + if staging, err = strconv.ParseBool(stagingStr); err != nil { + util.HandleError(c, util.StatusInternalServerError, err.Error()) + return + } + } + msg, err := s.DoDetachTrait(c, envName, traitType, componentName, applicationName, staging) + if err != nil { + util.HandleError(c, util.StatusInternalServerError, err.Error()) + return + } + util.AssembleResponse(c, msg, nil) +} + +func (s *APIServer) DoAttachTrait(c *gin.Context, body apis.TraitBody) (string, error) { + // Prepare + var appObj *application.Application + fs := pflag.NewFlagSet("trait", pflag.ContinueOnError) + for _, f := range body.Flags { + fs.String(f.Name, f.Value, "") + } + var staging = false + var err error + if body.Staging != "" { + staging, err = strconv.ParseBool(body.Staging) + if err != nil { + return "", err + } + } + traitAlias := body.Name + template, err := plugins.GetInstalledCapabilityWithCapAlias(types.TypeTrait, traitAlias) + if err != nil { + return "", err + } + // Run step + env, err := env2.GetEnvByName(body.EnvName) + if err != nil { + return "", err + } + + appObj, err = oam.AddOrUpdateTrait(env, body.AppName, body.ComponentName, fs, template) + if err != nil { + return "", err + } + io := util2.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} + return oam.TraitOperationRun(c, s.KubeClient, env, appObj, staging, io) +} + +func (s *APIServer) DoDetachTrait(c *gin.Context, envName string, traitType string, componentName string, appName string, staging bool) (string, error) { + var appObj *application.Application + var err error + if appName == "" { + appName = componentName + } + if appObj, err = oam.PrepareDetachTrait(envName, traitType, componentName, appName); err != nil { + return "", err + } + // Run + env, err := env2.GetEnvByName(envName) + if err != nil { + return "", err + } + io := util2.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} + return oam.TraitOperationRun(c, s.KubeClient, env, appObj, staging, io) +} diff --git a/pkg/server/handler/workloadHandler.go b/pkg/server/workloadHandler.go similarity index 86% rename from pkg/server/handler/workloadHandler.go rename to pkg/server/workloadHandler.go index 5c18b9be1..71815d20f 100644 --- a/pkg/server/handler/workloadHandler.go +++ b/pkg/server/workloadHandler.go @@ -1,11 +1,10 @@ -package handler +package server import ( "os" "github.com/gin-gonic/gin" "github.com/spf13/pflag" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/oam-dev/kubevela/api/types" cmdutil "github.com/oam-dev/kubevela/pkg/commands/util" @@ -17,8 +16,7 @@ import ( ) // Workload related handlers -func CreateWorkload(c *gin.Context) { - kubeClient := c.MustGet("KubeClient") +func (s *APIServer) CreateWorkload(c *gin.Context) { var body apis.WorkloadRunBody if err := c.ShouldBindJSON(&body); err != nil { util.HandleError(c, util.InvalidArgument, "the workload run request body is invalid") @@ -41,7 +39,7 @@ func CreateWorkload(c *gin.Context) { return } io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} - msg, err := oam.BaseRun(body.Staging, appObj, kubeClient.(client.Client), env, io) + msg, err := oam.BaseRun(body.Staging, appObj, s.KubeClient, env, io) if err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) return @@ -52,7 +50,7 @@ func CreateWorkload(c *gin.Context) { for _, t := range body.Traits { t.AppName = body.AppName t.ComponentName = body.WorkloadName - msg, err = oam.AttachTrait(c, t) + msg, err = s.DoAttachTrait(c, t) if err != nil { util.HandleError(c, util.StatusInternalServerError, err.Error()) return @@ -62,10 +60,10 @@ func CreateWorkload(c *gin.Context) { } } -func UpdateWorkload(c *gin.Context) { +func (s *APIServer) UpdateWorkload(c *gin.Context) { } -func GetWorkload(c *gin.Context) { +func (s *APIServer) GetWorkload(c *gin.Context) { var workloadType = c.Param("workloadName") var capability types.Capability var err error @@ -77,7 +75,7 @@ func GetWorkload(c *gin.Context) { util.AssembleResponse(c, capability, err) } -func ListWorkload(c *gin.Context) { +func (s *APIServer) ListWorkload(c *gin.Context) { var workloadDefinitionList []apis.WorkloadMeta workloads, err := plugins.LoadInstalledCapabilityWithType(types.TypeWorkload) if err != nil {