mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-19 04:26:39 +00:00
refactor rudr run to rudr <workload>:run
This commit is contained in:
@@ -24,12 +24,6 @@ jobs:
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
|
||||
- name: Run Make
|
||||
run: make
|
||||
|
||||
- name: Run Make test
|
||||
run: make test
|
||||
|
||||
- name: Install ginkgo
|
||||
run: |
|
||||
sudo apt-get update
|
||||
@@ -40,6 +34,12 @@ jobs:
|
||||
with:
|
||||
version: "v0.7.0"
|
||||
|
||||
- name: Run Make
|
||||
run: make
|
||||
|
||||
- name: Run Make test
|
||||
run: make test
|
||||
|
||||
- name: Run e2e tests
|
||||
run: |
|
||||
make e2e-setup
|
||||
|
||||
@@ -14,30 +14,31 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// TemplateSpec defines the desired state of Template
|
||||
// Template defines the content of a plugin
|
||||
type Template struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Object unstructured.Unstructured `json:"object,omitempty"`
|
||||
LastCommandParam string `json:"lastCommandParam,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type DefinitionType `json:"type"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Object map[string]interface{} `json:"object,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
type DefinitionType string
|
||||
|
||||
const (
|
||||
TypeWorkload DefinitionType = "workload"
|
||||
TypeTrait DefinitionType = "trait"
|
||||
)
|
||||
|
||||
type Parameter struct {
|
||||
Name string `json:"name"`
|
||||
Short string `json:"short,omitempty"`
|
||||
@@ -0,0 +1,10 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
DefaultOAMNS = "oam-system"
|
||||
DefaultOAMReleaseName = "core-runtime"
|
||||
DefaultOAMChartName = "crossplane-master/oam-kubernetes-runtime"
|
||||
DefaultOAMRepoName = "crossplane-master"
|
||||
DefaultOAMRepoUrl = "https://charts.crossplane.io/master"
|
||||
DefaultOAMVersion = ">0.0.0-0"
|
||||
)
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v1alpha2 contains API Schema definitions for the core.oam.dev v1alpha2 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=admin.oam.dev
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "admin.oam.dev", Version: "v1alpha2"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
+6
-4
@@ -7,6 +7,8 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/cmd/workload"
|
||||
|
||||
"github.com/crossplane/oam-kubernetes-runtime/apis/core"
|
||||
"github.com/spf13/cobra"
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -14,7 +16,6 @@ import (
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
coreoamdevv1alpha2 "github.com/cloud-native-application/rudrx/api/v1alpha2"
|
||||
"github.com/cloud-native-application/rudrx/pkg/cmd"
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/cloud-native-application/rudrx/pkg/utils/logs"
|
||||
@@ -38,8 +39,6 @@ var (
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
|
||||
_ = coreoamdevv1alpha2.AddToScheme(scheme)
|
||||
|
||||
_ = core.AddToScheme(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
@@ -82,7 +81,6 @@ func newCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
cmds.AddCommand(
|
||||
cmd.NewRunCommand(f, client, ioStream, os.Args[1:]),
|
||||
cmd.NewTraitsCommand(f, client, ioStream, []string{}),
|
||||
cmd.NewWorkloadsCommand(f, client, ioStream, os.Args[1:]),
|
||||
cmd.NewBindCommand(f, client, ioStream, []string{}),
|
||||
@@ -95,6 +93,10 @@ func newCommand() *cobra.Command {
|
||||
cmd.NewEnvCommand(f, ioStream),
|
||||
NewVersionCommand(),
|
||||
)
|
||||
if err = workload.AddPlugins(cmds, client, ioStream); err != nil {
|
||||
fmt.Println("Add plugins from workloadDefinition err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return cmds
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ spec:
|
||||
- containerPort: 6379
|
||||
protocol: TCP
|
||||
name: tbd # TODO(zzxwill) A temporary workaround for ContainerizedWorkload
|
||||
lastCommandParam: image
|
||||
parameters:
|
||||
- name: image
|
||||
short: i
|
||||
|
||||
@@ -20,7 +20,6 @@ spec:
|
||||
- containerPort: 6379
|
||||
protocol: TCP
|
||||
name: tbd # TODO(zzxwill) A temporary workaround for ContainerizedWorkload
|
||||
lastCommandParam: image
|
||||
parameters:
|
||||
- name: image
|
||||
short: i
|
||||
|
||||
@@ -5,6 +5,7 @@ go 1.13
|
||||
require (
|
||||
github.com/crossplane/crossplane-runtime v0.8.0
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.8
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-logr/logr v0.1.0
|
||||
github.com/gosuri/uitable v0.0.4
|
||||
github.com/onsi/ginkgo v1.11.0
|
||||
|
||||
@@ -185,6 +185,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/gertd/go-pluralize v0.1.7 h1:RgvJTJ5W7olOoAks97BOwOlekBFsLEyh00W48Z6ZEZY=
|
||||
github.com/gertd/go-pluralize v0.1.7/go.mod h1:O4eNeeIf91MHh1GJ2I47DNtaesm66NYvjYgAahcqSDQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
|
||||
+7
-5
@@ -8,6 +8,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
@@ -18,7 +20,7 @@ import (
|
||||
|
||||
type commandOptions struct {
|
||||
Env *EnvMeta
|
||||
Template cmdutil.Template
|
||||
Template types.Template
|
||||
Component corev1alpha2.Component
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
Client client.Client
|
||||
@@ -62,8 +64,8 @@ func NewBindCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStre
|
||||
}
|
||||
|
||||
for _, t := range traitDefinitions.Items {
|
||||
var traitTemplate cmdutil.Template
|
||||
traitTemplate, err := cmdutil.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
var traitTemplate types.Template
|
||||
traitTemplate, err := types.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
if err != nil {
|
||||
fmt.Printf("extract template from traitDefinition %v err: %v, ignore it\n", t.Name, err)
|
||||
continue
|
||||
@@ -142,13 +144,13 @@ func (o *commandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
cmdutil.PrintErrorMessage(errMsg, 1)
|
||||
}
|
||||
|
||||
traitTemplate, err := cmdutil.ConvertTemplateJson2Object(traitDefinition.Spec.Extension)
|
||||
traitTemplate, err := types.ConvertTemplateJson2Object(traitDefinition.Spec.Extension)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("attaching the trait hit an issue: %s", err)
|
||||
}
|
||||
|
||||
pvd := fieldpath.Pave(traitTemplate.Object.Object)
|
||||
pvd := fieldpath.Pave(traitTemplate.Object)
|
||||
for _, v := range traitTemplate.Parameters {
|
||||
flagSet := cmd.Flag(v.Name)
|
||||
for _, path := range v.FieldPaths {
|
||||
|
||||
+25
-32
@@ -1,13 +1,11 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/v1alpha2"
|
||||
"github.com/crossplane/oam-kubernetes-runtime/apis/core"
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
)
|
||||
@@ -18,37 +16,33 @@ var (
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = v1alpha2.AddToScheme(scheme)
|
||||
_ = core.AddToScheme(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
// used in testing
|
||||
var (
|
||||
workloadTemplateExample = &util.Template{
|
||||
workloadTemplateExample = &types.Template{
|
||||
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ContainerizedWorkload",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"containers": "",
|
||||
},
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ContainerizedWorkload",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"containers": "",
|
||||
},
|
||||
},
|
||||
LastCommandParam: "image",
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
Parameters: []types.Parameter{
|
||||
types.Parameter{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
Type: "string",
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
util.Parameter{
|
||||
types.Parameter{
|
||||
Name: "port",
|
||||
Short: "p",
|
||||
Required: false,
|
||||
@@ -58,22 +52,21 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
traitTemplateExample = &util.Template{
|
||||
traitTemplateExample = &types.Template{
|
||||
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ManualScalerTrait",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"replicaCount": "2",
|
||||
},
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ManualScalerTrait",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"replicaCount": "2",
|
||||
},
|
||||
},
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
|
||||
Parameters: []types.Parameter{
|
||||
types.Parameter{
|
||||
Name: "replicaCount",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
|
||||
+13
-20
@@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -50,15 +52,6 @@ type initCmd struct {
|
||||
version string
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultOAMNS = "oam-system"
|
||||
DefaultOAMReleaseName = "core-runtime"
|
||||
DefaultOAMChartName = "crossplane-master/oam-kubernetes-runtime"
|
||||
DefaultOAMRepoName = "crossplane-master"
|
||||
DefaultOAMRepoUrl = "https://charts.crossplane.io/master"
|
||||
DefaultOAMVersion = ">0.0.0-0"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultObject = []interface{}{
|
||||
&oamv1.WorkloadDefinition{},
|
||||
@@ -92,7 +85,7 @@ func NewInitCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStre
|
||||
Long: initDesc,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
i.client = c
|
||||
i.namespace = DefaultOAMNS
|
||||
i.namespace = types.DefaultOAMNS
|
||||
return i.run(ioStreams)
|
||||
},
|
||||
}
|
||||
@@ -109,8 +102,8 @@ func (i *initCmd) run(ioStreams cmdutil.IOStreams) error {
|
||||
return fmt.Errorf("could not get kubernetes client: %s", err)
|
||||
}
|
||||
|
||||
if !cmdutil.IsNamespaceExist(i.client, DefaultOAMNS) {
|
||||
if err := cmdutil.NewNamespace(i.client, DefaultOAMNS); err != nil {
|
||||
if !cmdutil.IsNamespaceExist(i.client, types.DefaultOAMNS) {
|
||||
if err := cmdutil.NewNamespace(i.client, types.DefaultOAMNS); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -143,8 +136,8 @@ func (i *initCmd) IsOamRuntimeExist() bool {
|
||||
|
||||
func InstallOamRuntime(ioStreams cmdutil.IOStreams, version string) error {
|
||||
|
||||
if !IsHelmRepositoryExist(DefaultOAMRepoName, DefaultOAMRepoUrl) {
|
||||
err := AddHelmRepository(DefaultOAMRepoName, DefaultOAMRepoUrl,
|
||||
if !IsHelmRepositoryExist(types.DefaultOAMRepoName, types.DefaultOAMRepoUrl) {
|
||||
err := AddHelmRepository(types.DefaultOAMRepoName, types.DefaultOAMRepoUrl,
|
||||
"", "", "", "", "", false, ioStreams.Out)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -156,7 +149,7 @@ func InstallOamRuntime(ioStreams cmdutil.IOStreams, version string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
chartRequested, err := GetChart(chartClient, DefaultOAMChartName)
|
||||
chartRequested, err := GetChart(chartClient, types.DefaultOAMChartName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -174,8 +167,8 @@ func NewHelmInstall(version string, ioStreams cmdutil.IOStreams) (*action.Instal
|
||||
actionConfig := new(action.Configuration)
|
||||
|
||||
if err := actionConfig.Init(
|
||||
kube.GetConfig(cmdutil.GetKubeConfig(), "", DefaultOAMNS),
|
||||
DefaultOAMNS,
|
||||
kube.GetConfig(cmdutil.GetKubeConfig(), "", types.DefaultOAMNS),
|
||||
types.DefaultOAMNS,
|
||||
os.Getenv("HELM_DRIVER"),
|
||||
ioStreams.Infof,
|
||||
); err != nil {
|
||||
@@ -183,14 +176,14 @@ func NewHelmInstall(version string, ioStreams cmdutil.IOStreams) (*action.Instal
|
||||
}
|
||||
|
||||
client := action.NewInstall(actionConfig)
|
||||
client.Namespace = DefaultOAMNS
|
||||
client.ReleaseName = DefaultOAMReleaseName
|
||||
client.Namespace = types.DefaultOAMNS
|
||||
client.ReleaseName = types.DefaultOAMReleaseName
|
||||
|
||||
if len(version) > 0 {
|
||||
client.Version = version
|
||||
return client, nil
|
||||
}
|
||||
client.Version = DefaultOAMVersion
|
||||
client.Version = types.DefaultOAMVersion
|
||||
return client, nil
|
||||
}
|
||||
|
||||
|
||||
-204
@@ -1,204 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
)
|
||||
|
||||
type runOptions struct {
|
||||
Template cmdutil.Template
|
||||
Env *EnvMeta
|
||||
Component corev1alpha2.Component
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
client client.Client
|
||||
cmdutil.IOStreams
|
||||
}
|
||||
|
||||
func newRunOptions(ioStreams cmdutil.IOStreams) *runOptions {
|
||||
return &runOptions{IOStreams: ioStreams}
|
||||
}
|
||||
|
||||
// NewRunCommand init new command
|
||||
func NewRunCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command {
|
||||
cmd := newRunCommand()
|
||||
// flags pass to new command directly
|
||||
cmd.DisableFlagParsing = true
|
||||
cmd.SetArgs(args)
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return runSubRunCommand(cmd, f, c, ioStreams, args)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// runSubRunCommand is init a new command and run independent
|
||||
func runSubRunCommand(parentCmd *cobra.Command, f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) error {
|
||||
ctx := context.Background()
|
||||
workloadNames := []string{}
|
||||
o := newRunOptions(ioStreams)
|
||||
o.client = c
|
||||
o.Env, _ = GetEnv()
|
||||
|
||||
// init fake command and pass args to fake command
|
||||
// flags and subcommand append to fake comand and parent command
|
||||
// run fake command only, show tips in parent command only
|
||||
fakeCommand := newRunCommand()
|
||||
fakeCommand.SilenceUsage = true
|
||||
fakeCommand.SilenceErrors = true
|
||||
fakeCommand.DisableAutoGenTag = true
|
||||
fakeCommand.DisableFlagsInUseLine = true
|
||||
fakeCommand.DisableSuggestions = true
|
||||
|
||||
// set args from parent
|
||||
if len(args) > 0 {
|
||||
fakeCommand.SetArgs(args)
|
||||
} else {
|
||||
fakeCommand.SetArgs([]string{})
|
||||
}
|
||||
fakeCommand.SetOut(o.Out)
|
||||
fakeCommand.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return errors.New("You must specify a workload, like " + strings.Join(workloadNames, ", ") +
|
||||
"\nSee 'rudr run -h' for help and examples")
|
||||
}
|
||||
fakeCommand.PersistentFlags().StringP("namespace", "n", "default", "namespace for apps")
|
||||
parentCmd.PersistentFlags().StringP("namespace", "n", "default", "namespace for apps")
|
||||
|
||||
var workloadDefs corev1alpha2.WorkloadDefinitionList
|
||||
err := c.List(ctx, &workloadDefs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("listing Workload definition hit an issue: %s", err)
|
||||
}
|
||||
|
||||
for _, wd := range workloadDefs.Items {
|
||||
var tmp cmdutil.Template
|
||||
tmp, err := cmdutil.ConvertTemplateJson2Object(wd.Spec.Extension)
|
||||
if err != nil {
|
||||
fmt.Printf("extract template from traitDefinition %v err: %v, ignore it\n", wd.Name, err)
|
||||
continue
|
||||
}
|
||||
name := tmp.Alias
|
||||
workloadNames = append(workloadNames, name)
|
||||
|
||||
subcmd := &cobra.Command{
|
||||
Use: name + " [args]",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Run " + name + " workloads",
|
||||
Long: "Run " + name + " workloads",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := o.Complete(f, cmd, args, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return o.Run(f, cmd)
|
||||
},
|
||||
}
|
||||
subcmd.SetOut(o.Out)
|
||||
for _, v := range tmp.Parameters {
|
||||
if tmp.LastCommandParam != v.Name {
|
||||
subcmd.PersistentFlags().StringP(v.Name, v.Short, v.Default, v.Usage)
|
||||
}
|
||||
}
|
||||
|
||||
// Comment this line as template content will get mixed when there are more than two WorkloadDefinitions
|
||||
// tmp.DeepCopyInto(&o.Template)
|
||||
o.Template = tmp
|
||||
fakeCommand.AddCommand(subcmd)
|
||||
parentCmd.AddCommand(subcmd)
|
||||
}
|
||||
|
||||
return fakeCommand.Execute()
|
||||
}
|
||||
|
||||
func (o *runOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, ctx context.Context) error {
|
||||
|
||||
argsLength := len(args)
|
||||
lastCommandParam := o.Template.LastCommandParam
|
||||
|
||||
if argsLength < 1 {
|
||||
return errors.New("must specify name for workload")
|
||||
} else if argsLength >= 1 {
|
||||
workloadName := args[0]
|
||||
|
||||
switch {
|
||||
case argsLength < 2 && lastCommandParam != "":
|
||||
// TODO(zzxwill): Could not determine whether the argument is the workload name or image name if without image tag
|
||||
return fmt.Errorf("You must specify `%s` as the last command.\nSee 'rudr run -h' for help and examples",
|
||||
lastCommandParam)
|
||||
case argsLength == 2:
|
||||
workloadTemplate := o.Template
|
||||
pvd := fieldpath.Pave(workloadTemplate.Object.Object)
|
||||
for _, v := range workloadTemplate.Parameters {
|
||||
lastCommandValue := args[argsLength-1]
|
||||
var paraV string
|
||||
if v.Name == lastCommandParam {
|
||||
paraV = lastCommandValue
|
||||
} else {
|
||||
flagSet := cmd.Flag(v.Name)
|
||||
paraV = flagSet.Value.String()
|
||||
}
|
||||
|
||||
if paraV == "" {
|
||||
return fmt.Errorf("Flag `%s` is NOT set, please check and try again. \nSee 'rudr run -h' for help and examples", v.Name)
|
||||
}
|
||||
|
||||
for _, path := range v.FieldPaths {
|
||||
if v.Type == "int" {
|
||||
portValue, _ := strconv.ParseFloat(paraV, 64)
|
||||
pvd.SetNumber(path, portValue)
|
||||
break
|
||||
}
|
||||
pvd.SetString(path, paraV)
|
||||
}
|
||||
}
|
||||
|
||||
pvd.SetString("metadata.name", strings.ToLower(workloadName))
|
||||
namespace := o.Env.Namespace
|
||||
o.Component.Spec.Workload.Object = &unstructured.Unstructured{Object: pvd.UnstructuredContent()}
|
||||
o.Component.Name = args[0]
|
||||
o.Component.Namespace = namespace
|
||||
o.AppConfig.Name = args[0]
|
||||
o.AppConfig.Namespace = namespace
|
||||
o.AppConfig.Spec.Components = append(o.AppConfig.Spec.Components, corev1alpha2.ApplicationConfigurationComponent{ComponentName: args[0]})
|
||||
|
||||
case argsLength > 2:
|
||||
return fmt.Errorf("there are more commands than needed, please try again")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *runOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
o.Infof("Creating AppConfig %s\n", o.AppConfig.Name)
|
||||
err := o.client.Create(context.Background(), &o.Component)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create component err: %s", err)
|
||||
}
|
||||
err = o.client.Create(context.Background(), &o.AppConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create appconfig err %s", err)
|
||||
}
|
||||
o.Info("SUCCEED")
|
||||
return nil
|
||||
}
|
||||
|
||||
func newRunCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "run [WORKLOAD_KIND] [args]",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Run OAM workloads",
|
||||
Long: "Create and Run one Workload one AppConfig OAM APP",
|
||||
Example: `
|
||||
rudr run containerized frontend -p 80 oam-dev/demo:v1
|
||||
`}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
@@ -172,7 +174,7 @@ func GetTraitDefinitionByAlias(ctx context.Context, c client.Client, traitAlias
|
||||
err := c.List(ctx, &traitDefinitionList)
|
||||
if err == nil {
|
||||
for _, t := range traitDefinitionList.Items {
|
||||
template, err := ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
template, err := types.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
if err == nil && strings.EqualFold(template.Alias, traitAlias) {
|
||||
traitDefinition = t
|
||||
break
|
||||
@@ -190,14 +192,14 @@ func GetTraitNameAliasKind(ctx context.Context, c client.Client, namespace strin
|
||||
t, err := GetTraitDefinitionByName(ctx, c, namespace, name)
|
||||
|
||||
if err == nil {
|
||||
template, err := ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
template, err := types.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
if err == nil {
|
||||
tName, tAlias = t.Name, template.Alias
|
||||
}
|
||||
} else {
|
||||
t, err := GetTraitDefinitionByAlias(ctx, c, name)
|
||||
if err == nil {
|
||||
template, err := ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
template, err := types.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
if err == nil {
|
||||
tName, tAlias = t.Name, template.Alias
|
||||
}
|
||||
@@ -230,15 +232,15 @@ func GetWorkloadNameAliasKind(ctx context.Context, c client.Client, namespace st
|
||||
w, err := GetWorkloadDefinitionByName(ctx, c, namespace, workloadName)
|
||||
|
||||
if err == nil { // workloadName is complete name
|
||||
var workloadTemplate Template
|
||||
workloadTemplate, err := ConvertTemplateJson2Object(w.Spec.Extension)
|
||||
var workloadTemplate types.Template
|
||||
workloadTemplate, err := types.ConvertTemplateJson2Object(w.Spec.Extension)
|
||||
if err == nil {
|
||||
name, alias = w.Name, workloadTemplate.Alias
|
||||
}
|
||||
} else { // workloadName is alias or kind
|
||||
w, err := GetWorkloadDefinitionByAlias(ctx, c, name)
|
||||
if err == nil {
|
||||
workloadTemplate, err := ConvertTemplateJson2Object(w.Spec.Extension)
|
||||
workloadTemplate, err := types.ConvertTemplateJson2Object(w.Spec.Extension)
|
||||
if err == nil {
|
||||
name, alias, kind = w.Name, workloadTemplate.Alias, w.Kind
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/plugins"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/cmd"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
)
|
||||
|
||||
type runOptions struct {
|
||||
Template types.Template
|
||||
Env *cmd.EnvMeta
|
||||
Component corev1alpha2.Component
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
client client.Client
|
||||
cmdutil.IOStreams
|
||||
}
|
||||
|
||||
func newRunOptions(ioStreams cmdutil.IOStreams) *runOptions {
|
||||
return &runOptions{IOStreams: ioStreams}
|
||||
}
|
||||
|
||||
func AddPlugins(parentCmd *cobra.Command, c client.Client, ioStreams cmdutil.IOStreams) error {
|
||||
templates, err := plugins.GetWorkloadsFromCluster(context.TODO(), types.DefaultOAMNS, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, tmp := range templates {
|
||||
var name string
|
||||
if tmp.Alias != "" {
|
||||
name = tmp.Alias
|
||||
}
|
||||
o := newRunOptions(ioStreams)
|
||||
o.client = c
|
||||
o.Env, _ = cmd.GetEnv()
|
||||
pluginCmd := &cobra.Command{
|
||||
Use: name + ":run [args]",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Run " + name + " workloads",
|
||||
Long: "Run " + name + " workloads",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := o.Complete(cmd, args, context.TODO()); err != nil {
|
||||
return err
|
||||
}
|
||||
return o.Run(cmd)
|
||||
},
|
||||
}
|
||||
pluginCmd.SetOut(o.Out)
|
||||
for _, v := range tmp.Parameters {
|
||||
pluginCmd.Flags().StringP(v.Name, v.Short, v.Default, v.Usage)
|
||||
if v.Required {
|
||||
pluginCmd.MarkFlagRequired(v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
o.Template = tmp
|
||||
parentCmd.AddCommand(pluginCmd)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *runOptions) Complete(cmd *cobra.Command, args []string, ctx context.Context) error {
|
||||
|
||||
argsLength := len(args)
|
||||
|
||||
if argsLength < 1 {
|
||||
return errors.New("must specify name for workload")
|
||||
}
|
||||
|
||||
workloadName := args[0]
|
||||
|
||||
workloadTemplate := o.Template
|
||||
pvd := fieldpath.Pave(workloadTemplate.Object)
|
||||
for _, v := range workloadTemplate.Parameters {
|
||||
var paraV string
|
||||
|
||||
flagSet := cmd.Flag(v.Name)
|
||||
paraV = flagSet.Value.String()
|
||||
|
||||
if paraV == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, path := range v.FieldPaths {
|
||||
if v.Type == "int" {
|
||||
portValue, _ := strconv.ParseFloat(paraV, 64)
|
||||
pvd.SetNumber(path, portValue)
|
||||
break
|
||||
}
|
||||
pvd.SetString(path, paraV)
|
||||
}
|
||||
}
|
||||
|
||||
pvd.SetString("metadata.name", strings.ToLower(workloadName))
|
||||
namespace := o.Env.Namespace
|
||||
o.Component.Spec.Workload.Object = &unstructured.Unstructured{Object: pvd.UnstructuredContent()}
|
||||
o.Component.Name = args[0]
|
||||
o.Component.Namespace = namespace
|
||||
o.AppConfig.Name = args[0]
|
||||
o.AppConfig.Namespace = namespace
|
||||
o.AppConfig.Spec.Components = append(o.AppConfig.Spec.Components, corev1alpha2.ApplicationConfigurationComponent{ComponentName: args[0]})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *runOptions) Run(cmd *cobra.Command) error {
|
||||
o.Infof("Creating AppConfig %s\n", o.AppConfig.Name)
|
||||
err := o.client.Create(context.Background(), &o.Component)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create component err: %s", err)
|
||||
}
|
||||
err = o.client.Create(context.Background(), &o.AppConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create appconfig err %s", err)
|
||||
}
|
||||
o.Info("SUCCEED")
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cmd
|
||||
package workload
|
||||
|
||||
/*
|
||||
func TestNewRunCommand(t *testing.T) {
|
||||
@@ -0,0 +1,68 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func GetTemplatesFromCluster(ctx context.Context, namespace string, c client.Client) ([]types.Template, error) {
|
||||
workloads, err := GetWorkloadsFromCluster(ctx, namespace, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
traits, err := GetTraitsFromCluster(ctx, namespace, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workloads = append(workloads, traits...)
|
||||
return workloads, nil
|
||||
}
|
||||
|
||||
func GetWorkloadsFromCluster(ctx context.Context, namespace string, c client.Client) ([]types.Template, error) {
|
||||
var templates []types.Template
|
||||
var workloadDefs corev1alpha2.WorkloadDefinitionList
|
||||
err := c.List(ctx, &workloadDefs, &client.ListOptions{Namespace: namespace})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list WorkloadDefinition err: %s", err)
|
||||
}
|
||||
|
||||
for _, wd := range workloadDefs.Items {
|
||||
var tmp types.Template
|
||||
tmp, err := types.ConvertTemplateJson2Object(wd.Spec.Extension)
|
||||
if err != nil {
|
||||
fmt.Printf("extract template from workloadDefinition %v err: %v, ignore it\n", wd.Name, err)
|
||||
continue
|
||||
}
|
||||
tmp.Type = types.TypeWorkload
|
||||
tmp.Name = wd.Name
|
||||
templates = append(templates, tmp)
|
||||
}
|
||||
return templates, nil
|
||||
}
|
||||
|
||||
func GetTraitsFromCluster(ctx context.Context, namespace string, c client.Client) ([]types.Template, error) {
|
||||
var templates []types.Template
|
||||
var traitDefs corev1alpha2.TraitDefinitionList
|
||||
err := c.List(ctx, &traitDefs, &client.ListOptions{Namespace: namespace})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list TraitDefinition err: %s", err)
|
||||
}
|
||||
|
||||
for _, td := range traitDefs.Items {
|
||||
var tmp types.Template
|
||||
tmp, err := types.ConvertTemplateJson2Object(td.Spec.Extension)
|
||||
if err != nil {
|
||||
fmt.Printf("extract template from workloadDefinition %v err: %v, ignore it\n", td.Name, err)
|
||||
continue
|
||||
}
|
||||
tmp.Type = types.TypeTrait
|
||||
tmp.Name = td.Name
|
||||
templates = append(templates, tmp)
|
||||
}
|
||||
return templates, nil
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util"
|
||||
)
|
||||
|
||||
var _ = Describe("DefinitionFiles", func() {
|
||||
ctx := context.Background()
|
||||
route := types.Template{
|
||||
Name: "routes.extend.oam.dev",
|
||||
Type: types.TypeTrait,
|
||||
Alias: "route",
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "extend.oam.dev/v1alpha2",
|
||||
"kind": "Route",
|
||||
},
|
||||
Parameters: []types.Parameter{
|
||||
{
|
||||
Name: "domain",
|
||||
Short: "d",
|
||||
Required: true,
|
||||
FieldPaths: []string{"spec.domain"},
|
||||
},
|
||||
},
|
||||
}
|
||||
deployment := types.Template{
|
||||
Name: "deployments.testapps",
|
||||
Type: types.TypeWorkload,
|
||||
Alias: "deployment",
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "Deployment",
|
||||
},
|
||||
Parameters: []types.Parameter{
|
||||
{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: DefinitionNamespace}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
traitdata, err := ioutil.ReadFile("testdata/traitDef.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
var td v1alpha2.TraitDefinition
|
||||
Expect(yaml.Unmarshal(traitdata, &td)).Should(BeNil())
|
||||
|
||||
td.Namespace = DefinitionNamespace
|
||||
logf.Log.Info("Creating trait definition", "data", td)
|
||||
Expect(k8sClient.Create(ctx, &td)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
workloaddata, err := ioutil.ReadFile("testdata/workloadDef.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
var wd v1alpha2.WorkloadDefinition
|
||||
Expect(yaml.Unmarshal(workloaddata, &wd)).Should(BeNil())
|
||||
|
||||
wd.Namespace = DefinitionNamespace
|
||||
logf.Log.Info("Creating workload definition", "data", wd)
|
||||
Expect(k8sClient.Create(ctx, &wd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
})
|
||||
|
||||
// Notice!! Definition 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)
|
||||
Expect(err).Should(BeNil())
|
||||
logf.Log.Info(fmt.Sprintf("Getting trait definitions %v", traitDefs))
|
||||
|
||||
Expect(traitDefs).Should(Equal([]types.Template{route}))
|
||||
})
|
||||
// Notice!! Definition 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)
|
||||
Expect(err).Should(BeNil())
|
||||
logf.Log.Info(fmt.Sprintf("Getting workload definitions %v", workloadDefs))
|
||||
|
||||
Expect(workloadDefs).Should(Equal([]types.Template{deployment}))
|
||||
})
|
||||
It("getall", func() {
|
||||
alldef, err := GetTemplatesFromCluster(context.Background(), DefinitionNamespace, k8sClient)
|
||||
Expect(err).Should(BeNil())
|
||||
logf.Log.Info(fmt.Sprintf("Getting all definitions %v", alldef))
|
||||
|
||||
Expect(alldef).Should(Equal([]types.Template{deployment, route}))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,61 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
)
|
||||
|
||||
func GetDefFromLocal(dir string, defType types.DefinitionType) ([]types.Template, error) {
|
||||
temps, err := LoadTempFromLocal(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var defs []types.Template
|
||||
for _, t := range temps {
|
||||
if t.Type != defType {
|
||||
continue
|
||||
}
|
||||
defs = append(defs, t)
|
||||
}
|
||||
return defs, nil
|
||||
}
|
||||
|
||||
func SinkTemp2Local(templates []types.Template, dir string) error {
|
||||
for _, tmp := range templates {
|
||||
data, err := json.Marshal(tmp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(dir, tmp.Name), data, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadTempFromLocal(dir string) ([]types.Template, error) {
|
||||
var tmps []types.Template
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tmp types.Template
|
||||
if err = json.Unmarshal(data, &tmp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmps = append(tmps, tmp)
|
||||
}
|
||||
return tmps, nil
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLocalSink(t *testing.T) {
|
||||
deployment := types.Template{
|
||||
Name: "deployment",
|
||||
Type: types.TypeWorkload,
|
||||
Alias: "deployment",
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
},
|
||||
Parameters: []types.Parameter{
|
||||
{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
},
|
||||
}
|
||||
statefulset := types.Template{
|
||||
Name: "statefulset",
|
||||
Type: types.TypeWorkload,
|
||||
Alias: "stateful",
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Statefulset",
|
||||
},
|
||||
Parameters: []types.Parameter{
|
||||
{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
},
|
||||
}
|
||||
route := types.Template{
|
||||
Name: "route",
|
||||
Type: types.TypeTrait,
|
||||
Alias: "route",
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Route",
|
||||
},
|
||||
Parameters: []types.Parameter{
|
||||
{
|
||||
Name: "domain",
|
||||
Short: "d",
|
||||
Required: true,
|
||||
FieldPaths: []string{"spec.domain"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
dir string
|
||||
tmps []types.Template
|
||||
Type types.DefinitionType
|
||||
expDef []types.Template
|
||||
}{
|
||||
"Test No Templates": {
|
||||
dir: "rudrx-test1",
|
||||
tmps: nil,
|
||||
},
|
||||
"Test Only Workload": {
|
||||
dir: "rudrx-test2",
|
||||
tmps: []types.Template{deployment, statefulset},
|
||||
Type: types.TypeWorkload,
|
||||
expDef: []types.Template{deployment, statefulset},
|
||||
},
|
||||
"Test Only Trait": {
|
||||
dir: "rudrx-test3",
|
||||
tmps: []types.Template{route},
|
||||
Type: types.TypeTrait,
|
||||
expDef: []types.Template{route},
|
||||
},
|
||||
"Test Only Workload But want trait": {
|
||||
dir: "rudrx-test3",
|
||||
tmps: []types.Template{deployment, statefulset},
|
||||
Type: types.TypeTrait,
|
||||
expDef: nil,
|
||||
},
|
||||
"Test Both have Workload and trait But want Workload": {
|
||||
dir: "rudrx-test4",
|
||||
tmps: []types.Template{deployment, route, statefulset},
|
||||
Type: types.TypeWorkload,
|
||||
expDef: []types.Template{deployment, statefulset},
|
||||
},
|
||||
"Test Both have Workload and trait But want Trait": {
|
||||
dir: "rudrx-test5",
|
||||
tmps: []types.Template{deployment, route, statefulset},
|
||||
Type: types.TypeTrait,
|
||||
expDef: []types.Template{route},
|
||||
},
|
||||
}
|
||||
for name, c := range cases {
|
||||
testInDir(t, name, c.dir, c.tmps, c.expDef, c.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func testInDir(t *testing.T, casename, dir string, tmps, defexp []types.Template, Type types.DefinitionType) {
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
assert.NoError(t, err, casename)
|
||||
defer os.RemoveAll(dir)
|
||||
err = SinkTemp2Local(tmps, dir)
|
||||
assert.NoError(t, err, casename)
|
||||
gottmps, err := LoadTempFromLocal(dir)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, tmps, gottmps, casename)
|
||||
if Type != "" {
|
||||
gotDef, err := GetDefFromLocal(dir, Type)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, defexp, gotDef, casename)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam/util"
|
||||
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
||||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
|
||||
func TestAPIs(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
|
||||
RunSpecsWithDefaultAndCustomReporters(t,
|
||||
"CLI Suite",
|
||||
[]Reporter{printer.NewlineReporter{}})
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
|
||||
|
||||
By("bootstrapping test environment")
|
||||
useExistCluster := true
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
UseExistingCluster: &useExistCluster,
|
||||
}
|
||||
|
||||
var err error
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cfg).ToNot(BeNil())
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), &crd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
close(done)
|
||||
}, 60)
|
||||
|
||||
var DefinitionNamespace = "testdef"
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
k8sClient.Delete(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: DefinitionNamespace}})
|
||||
|
||||
err := testEnv.Stop()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
name: routes.extend.oam.dev
|
||||
spec:
|
||||
definitionRef:
|
||||
name: routes.extend.oam.dev
|
||||
extension:
|
||||
alias: route
|
||||
object:
|
||||
apiVersion: extend.oam.dev/v1alpha2
|
||||
kind: Route
|
||||
parameters:
|
||||
- name: domain
|
||||
required: true
|
||||
short: d
|
||||
fieldPaths:
|
||||
- "spec.domain"
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
metadata:
|
||||
name: deployments.testapps
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.testapps
|
||||
extension:
|
||||
alias: deployment
|
||||
object:
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Deployment
|
||||
parameters:
|
||||
- name: image
|
||||
short: i
|
||||
required: true
|
||||
fieldPaths:
|
||||
- "spec.containers[0].image"
|
||||
Reference in New Issue
Block a user