mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 12:06:38 +00:00
support vela cap:remove
This commit is contained in:
+13
-12
@@ -28,17 +28,18 @@ import (
|
||||
)
|
||||
|
||||
type Source struct {
|
||||
RepoName string `json:"repoName"`
|
||||
RepoName string `json:"repoName"`
|
||||
ChartName string `json:"chartName,omitempty"`
|
||||
}
|
||||
|
||||
// Capability defines the content of a capability
|
||||
type Capability struct {
|
||||
Name string `json:"name"`
|
||||
Type DefinitionType `json:"type"`
|
||||
CueTemplate string `json:"template,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
DefinitionPath string `json:"definition"`
|
||||
CrdName string `json:"crdName,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type CapType `json:"type"`
|
||||
CueTemplate string `json:"template,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
DefinitionPath string `json:"definition"`
|
||||
CrdName string `json:"crdName,omitempty"`
|
||||
|
||||
//trait only
|
||||
AppliesTo []string `json:"appliesTo,omitempty"`
|
||||
@@ -56,15 +57,15 @@ type Chart struct {
|
||||
}
|
||||
|
||||
type Installation struct {
|
||||
Helm []Chart `json:"helm"`
|
||||
Helm Chart `json:"helm"`
|
||||
}
|
||||
|
||||
type DefinitionType string
|
||||
type CapType string
|
||||
|
||||
const (
|
||||
TypeWorkload DefinitionType = "workload"
|
||||
TypeTrait DefinitionType = "trait"
|
||||
TypeScope DefinitionType = "scope"
|
||||
TypeWorkload CapType = "workload"
|
||||
TypeTrait CapType = "trait"
|
||||
TypeScope CapType = "scope"
|
||||
)
|
||||
|
||||
type Parameter struct {
|
||||
|
||||
@@ -156,6 +156,7 @@ func PrintHelpByTag(cmd *cobra.Command, all []*cobra.Command, tag string) {
|
||||
}
|
||||
}
|
||||
cmd.Println(table.String())
|
||||
cmd.Println(" <use 'vela refresh' to sync from cluster or install by `vela cap` >")
|
||||
cmd.Println()
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,10 @@ spec:
|
||||
extension:
|
||||
install:
|
||||
helm:
|
||||
- repo: stable
|
||||
name: nginx-ingress
|
||||
version: 1.41.2
|
||||
repo: stable
|
||||
name: nginx-ingress
|
||||
url: https://kubernetes-charts.storage.googleapis.com/
|
||||
version: 1.41.2
|
||||
template: |
|
||||
#Template: {
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
|
||||
@@ -6,6 +6,7 @@ require (
|
||||
cuelang.org/go v0.2.2
|
||||
github.com/crossplane/crossplane-runtime v0.8.0
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.8
|
||||
github.com/gertd/go-pluralize v0.1.7
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
@@ -17,8 +18,8 @@ require (
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
go.uber.org/zap v1.10.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gotest.tools v2.2.0+incompatible
|
||||
helm.sh/helm/v3 v3.2.4
|
||||
k8s.io/api v0.18.6
|
||||
|
||||
+117
-23
@@ -5,9 +5,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -33,6 +38,7 @@ func CapabilityCommandGroup(parentCmd *cobra.Command, c types.Args, ioStream cmd
|
||||
NewCapListCommand(ioStream),
|
||||
NewCapCenterSyncCommand(ioStream),
|
||||
NewCapAddCommand(c, ioStream),
|
||||
NewCapRemoveCommand(c, ioStream),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -70,7 +76,13 @@ func NewCapCenterConfigCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
if err = plugins.StoreRepos(repos); err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Info(fmt.Sprintf("Successfully configured capability center: %s, please use 'vela cap:center:sync %s' to sync capabilities", args[0], args[0]))
|
||||
ioStreams.Info(fmt.Sprintf("Successfully configured capability center: %s, start to sync from remote", args[0]))
|
||||
client, err := plugins.NewCenterClient(context.Background(), config.Name, config.Address, config.Token)
|
||||
err = client.SyncCapabilityFromCenter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Info("sync finished")
|
||||
return nil
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
@@ -112,6 +124,38 @@ func NewCapAddCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCapRemoveCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cap:remove <name>",
|
||||
Short: "Remove capability from cluster",
|
||||
Long: "Remove capability from cluster",
|
||||
Example: `vela cap:remove route`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return errors.New("you must specify <name> for capability you want to remove")
|
||||
}
|
||||
newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := args[0]
|
||||
if strings.Contains(name, "/") {
|
||||
l := strings.Split(name, "/")
|
||||
if len(l) > 2 {
|
||||
return fmt.Errorf("invalid format '%s', you can't contain more than one / in name", name)
|
||||
}
|
||||
name = l[1]
|
||||
}
|
||||
return RemoveCapability(newClient, name, ioStreams)
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
types.TagCommandType: types.TypeOthers,
|
||||
},
|
||||
}
|
||||
cmd.PersistentFlags().StringP("token", "t", "", "Github Repo token")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCapCenterSyncCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cap:center:sync [centerName]",
|
||||
@@ -151,6 +195,7 @@ func NewCapCenterSyncCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ioStreams.Info("sync finished")
|
||||
return nil
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
@@ -176,7 +221,7 @@ func NewCapListCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
table := uitable.New()
|
||||
table.AddRow("NAME", "TYPE", "DEFINITION", "STATUS", "APPLIES-TO")
|
||||
table.AddRow("NAME", "CENTER", "TYPE", "DEFINITION", "STATUS", "APPLIES-TO")
|
||||
if repoName != "" {
|
||||
if err = ListCenterCapabilities(table, filepath.Join(dir, repoName), ioStreams); err != nil {
|
||||
return err
|
||||
@@ -188,7 +233,6 @@ func NewCapListCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, dd := range dirs {
|
||||
if !dd.IsDir() {
|
||||
continue
|
||||
@@ -207,6 +251,53 @@ func NewCapListCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RemoveCapability(client client.Client, capabilityName string, ioStreams cmdutil.IOStreams) error {
|
||||
// TODO(wonderflow): make sure no apps is using this capability
|
||||
caps, err := plugins.LoadAllInstalledCapability()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, w := range caps {
|
||||
if w.Name == capabilityName {
|
||||
return UninstallCap(client, w, ioStreams)
|
||||
}
|
||||
}
|
||||
return errors.New(capabilityName + " not exist")
|
||||
}
|
||||
|
||||
func UninstallCap(client client.Client, cap types.Capability, ioStreams cmdutil.IOStreams) error {
|
||||
// 1. Remove WorkloadDefinition or TraitDefinition
|
||||
ctx := context.Background()
|
||||
var obj runtime.Object
|
||||
switch cap.Type {
|
||||
case types.TypeTrait:
|
||||
obj = &v1alpha2.TraitDefinition{ObjectMeta: v1.ObjectMeta{Name: cap.CrdName, Namespace: types.DefaultOAMNS}}
|
||||
case types.TypeWorkload:
|
||||
obj = &v1alpha2.WorkloadDefinition{ObjectMeta: v1.ObjectMeta{Name: cap.CrdName, Namespace: types.DefaultOAMNS}}
|
||||
}
|
||||
if err := client.Delete(ctx, obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cap.Install != nil && cap.Install.Helm.Name != "" {
|
||||
// 2. Remove Helm chart if there is
|
||||
if err := HelmUninstall(ioStreams, cap.Install.Helm.Name, cap.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Remove local capability file
|
||||
capdir, _ := system.GetCapabilityDir()
|
||||
switch cap.Type {
|
||||
case types.TypeTrait:
|
||||
return os.Remove(filepath.Join(capdir, "traits", cap.Name))
|
||||
case types.TypeWorkload:
|
||||
return os.Remove(filepath.Join(capdir, "workloads", cap.Name))
|
||||
}
|
||||
ioStreams.Infof("%s removed successfully", cap.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func InstallCapability(client client.Client, centerName, capabilityName string, ioStreams cmdutil.IOStreams) error {
|
||||
dir, _ := system.GetCapCenterDir()
|
||||
repoDir := filepath.Join(dir, centerName)
|
||||
@@ -218,7 +309,6 @@ func InstallCapability(client client.Client, centerName, capabilityName string,
|
||||
defDir, _ := system.GetCapabilityDir()
|
||||
switch tp.Type {
|
||||
case types.TypeWorkload:
|
||||
defDir = filepath.Join(defDir, "workloads")
|
||||
var wd v1alpha2.WorkloadDefinition
|
||||
workloadData, err := ioutil.ReadFile(filepath.Join(repoDir, tp.CrdName+".yaml"))
|
||||
if err != nil {
|
||||
@@ -230,6 +320,7 @@ func InstallCapability(client client.Client, centerName, capabilityName string,
|
||||
wd.Namespace = types.DefaultOAMNS
|
||||
ioStreams.Info("Installing workload capability " + wd.Name)
|
||||
if tp.Install != nil {
|
||||
tp.Source.ChartName = tp.Install.Helm.Name
|
||||
if err = InstallHelmChart(ioStreams, tp.Install.Helm); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -238,7 +329,6 @@ func InstallCapability(client client.Client, centerName, capabilityName string,
|
||||
return err
|
||||
}
|
||||
case types.TypeTrait:
|
||||
defDir = filepath.Join(defDir, "traits")
|
||||
var td v1alpha2.TraitDefinition
|
||||
traitdata, err := ioutil.ReadFile(filepath.Join(repoDir, tp.CrdName+".yaml"))
|
||||
if err != nil {
|
||||
@@ -250,6 +340,7 @@ func InstallCapability(client client.Client, centerName, capabilityName string,
|
||||
td.Namespace = types.DefaultOAMNS
|
||||
ioStreams.Info("Installing trait capability " + td.Name)
|
||||
if tp.Install != nil {
|
||||
tp.Source.ChartName = tp.Install.Helm.Name
|
||||
if err = InstallHelmChart(ioStreams, tp.Install.Helm); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -268,19 +359,14 @@ func InstallCapability(client client.Client, centerName, capabilityName string,
|
||||
return nil
|
||||
}
|
||||
|
||||
func InstallHelmChart(ioStreams cmdutil.IOStreams, charts []types.Chart) error {
|
||||
for _, c := range charts {
|
||||
if err := HelmInstall(ioStreams, c.Repo, c.URl, c.Name, c.Version, c.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func InstallHelmChart(ioStreams cmdutil.IOStreams, c types.Chart) error {
|
||||
return HelmInstall(ioStreams, c.Repo, c.URl, c.Name, c.Version, c.Name)
|
||||
}
|
||||
|
||||
func GetSyncedCapabilities(repoName, addonName string) (types.Capability, error) {
|
||||
dir, _ := system.GetCapCenterDir()
|
||||
repoDir := filepath.Join(dir, repoName)
|
||||
templates, err := plugins.LoadCapabilityFromLocal(repoDir)
|
||||
templates, err := plugins.LoadCapabilityFromSyncedCenter(repoDir)
|
||||
if err != nil {
|
||||
return types.Capability{}, err
|
||||
}
|
||||
@@ -293,7 +379,7 @@ func GetSyncedCapabilities(repoName, addonName string) (types.Capability, error)
|
||||
}
|
||||
|
||||
func ListCenterCapabilities(table *uitable.Table, repoDir string, ioStreams cmdutil.IOStreams) error {
|
||||
templates, err := plugins.LoadCapabilityFromLocal(repoDir)
|
||||
templates, err := plugins.LoadCapabilityFromSyncedCenter(repoDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -301,23 +387,31 @@ func ListCenterCapabilities(table *uitable.Table, repoDir string, ioStreams cmdu
|
||||
return nil
|
||||
}
|
||||
baseDir := filepath.Base(repoDir)
|
||||
workloads := GatherWorkloads(templates)
|
||||
for _, p := range templates {
|
||||
status := CheckInstallStatus(baseDir, p)
|
||||
table.AddRow(baseDir+"/"+p.Name, p.Type, p.Type, status, p.AppliesTo)
|
||||
convertedApplyTo := ConvertApplyTo(p.AppliesTo, workloads)
|
||||
table.AddRow(p.Name, baseDir, p.Type, p.CrdName, status, convertedApplyTo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GatherWorkloads(templates []types.Capability) []types.Capability {
|
||||
workloads, err := plugins.LoadInstalledCapabilityWithType(types.TypeWorkload)
|
||||
if err != nil {
|
||||
workloads = make([]types.Capability, 0)
|
||||
}
|
||||
for _, t := range templates {
|
||||
if t.Type == types.TypeWorkload {
|
||||
workloads = append(workloads, t)
|
||||
}
|
||||
}
|
||||
return workloads
|
||||
}
|
||||
|
||||
func CheckInstallStatus(repoName string, tmp types.Capability) string {
|
||||
var status = "uninstalled"
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
switch tmp.Type {
|
||||
case types.TypeTrait:
|
||||
dir = filepath.Join(dir, "traits")
|
||||
case types.TypeWorkload:
|
||||
dir = filepath.Join(dir, "workloads")
|
||||
}
|
||||
installed, _ := plugins.LoadTempFromLocal(dir)
|
||||
installed, _ := plugins.LoadInstalledCapabilityWithType(tmp.Type)
|
||||
for _, i := range installed {
|
||||
if i.Source != nil && i.Source.RepoName == repoName && i.Name == tmp.Name && i.CrdName == tmp.CrdName {
|
||||
return "installed"
|
||||
|
||||
+4
-9
@@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
@@ -43,10 +42,8 @@ func RefreshDefinitions(ctx context.Context, c client.Client, ioStreams cmdutil.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
workloadDir := filepath.Join(dir, "workloads")
|
||||
system.StatAndCreate(workloadDir)
|
||||
ioStreams.Infof("get %d workload definitions from cluster, syncing to %s...", len(templates), workloadDir)
|
||||
successNum := plugins.SinkTemp2Local(templates, workloadDir)
|
||||
ioStreams.Infof("get %d workload definitions from cluster, syncing...", len(templates))
|
||||
successNum := plugins.SinkTemp2Local(templates, dir)
|
||||
ioStreams.Infof("%d workload definitions successfully synced\n", successNum)
|
||||
|
||||
ioStreams.Info("syncing trait definitions from cluster...")
|
||||
@@ -54,10 +51,8 @@ func RefreshDefinitions(ctx context.Context, c client.Client, ioStreams cmdutil.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
traitDir := filepath.Join(dir, "traits")
|
||||
system.StatAndCreate(traitDir)
|
||||
ioStreams.Infof("get %d trait definitions from cluster, syncing to %s...", len(templates), traitDir)
|
||||
successNum = plugins.SinkTemp2Local(templates, traitDir)
|
||||
ioStreams.Infof("get %d trait definitions from cluster, syncing...", len(templates))
|
||||
successNum = plugins.SinkTemp2Local(templates, dir)
|
||||
ioStreams.Infof("%d trait definitions successfully synced\n", successNum)
|
||||
return nil
|
||||
}
|
||||
|
||||
+30
-2
@@ -220,9 +220,24 @@ func HelmInstall(ioStreams cmdutil.IOStreams, repoName, repoUrl, chartName, vers
|
||||
return nil
|
||||
}
|
||||
|
||||
func HelmUninstall(ioStreams cmdutil.IOStreams, chartName, releaseName string) error {
|
||||
if !IsHelmReleaseRunning(releaseName, chartName, ioStreams) {
|
||||
return nil
|
||||
}
|
||||
uninstall, err := NewHelmUninstall()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = uninstall.Run(releaseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Infof("Successfully removed %s with release name %s\n", chartName, releaseName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewHelmInstall(version, releaseName string, ioStreams cmdutil.IOStreams) (*action.Install, error) {
|
||||
actionConfig := new(action.Configuration)
|
||||
|
||||
if err := actionConfig.Init(
|
||||
kube.GetConfig(cmdutil.GetKubeConfig(), "", types.DefaultOAMNS),
|
||||
types.DefaultOAMNS,
|
||||
@@ -233,12 +248,25 @@ func NewHelmInstall(version, releaseName string, ioStreams cmdutil.IOStreams) (*
|
||||
}
|
||||
|
||||
client := action.NewInstall(actionConfig)
|
||||
client.Namespace = types.DefaultOAMNS
|
||||
client.ReleaseName = releaseName
|
||||
client.Version = version
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func NewHelmUninstall() (*action.Uninstall, error) {
|
||||
actionConfig := new(action.Configuration)
|
||||
|
||||
if err := actionConfig.Init(
|
||||
kube.GetConfig(cmdutil.GetKubeConfig(), "", types.DefaultOAMNS),
|
||||
types.DefaultOAMNS,
|
||||
os.Getenv("HELM_DRIVER"),
|
||||
debug,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return action.NewUninstall(actionConfig), nil
|
||||
}
|
||||
|
||||
func debug(format string, v ...interface{}) {
|
||||
if settings.Debug {
|
||||
format = fmt.Sprintf("[debug] %s\n", format)
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -13,8 +12,6 @@ import (
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/utils/system"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/plugins"
|
||||
@@ -45,8 +42,7 @@ func NewCommandOptions(ioStreams cmdutil.IOStreams) *commandOptions {
|
||||
}
|
||||
|
||||
func AddTraitCommands(parentCmd *cobra.Command, c types.Args, ioStreams cmdutil.IOStreams) error {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
templates, err := plugins.LoadTempFromLocal(filepath.Join(dir, "traits"))
|
||||
templates, err := plugins.LoadInstalledCapabilityWithType(types.TypeTrait)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -172,8 +168,7 @@ func (o *commandOptions) Complete(cmd *cobra.Command, args []string, ctx context
|
||||
}
|
||||
|
||||
func AddTraitDetachCommands(parentCmd *cobra.Command, c types.Args, ioStreams cmdutil.IOStreams) error {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
templates, err := plugins.LoadTempFromLocal(filepath.Join(dir, "traits"))
|
||||
templates, err := plugins.LoadInstalledCapabilityWithType(types.TypeTrait)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+18
-7
@@ -1,15 +1,14 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/plugins"
|
||||
"github.com/cloud-native-application/rudrx/pkg/utils/system"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
plur "github.com/gertd/go-pluralize"
|
||||
"github.com/gosuri/uitable"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -23,12 +22,11 @@ func NewTraitsCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
Long: "List traits",
|
||||
Example: `vela traits`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
templates, err := plugins.LoadTempFromLocal(filepath.Join(dir, "traits"))
|
||||
templates, err := plugins.LoadInstalledCapabilityWithType(types.TypeTrait)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
workloads, err := plugins.LoadTempFromLocal(filepath.Join(dir, "workloads"))
|
||||
workloads, err := plugins.LoadInstalledCapabilityWithType(types.TypeWorkload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -83,9 +81,22 @@ func ConvertApplyTo(applyTo []string, workloads []types.Capability) []string {
|
||||
return converted
|
||||
}
|
||||
|
||||
func check(crdname string, workloads []types.Capability) (string, bool) {
|
||||
func parse(applyTo string) string {
|
||||
l := strings.Split(applyTo, "/")
|
||||
if len(l) != 2 {
|
||||
return applyTo
|
||||
}
|
||||
apigroup, versionKind := l[0], l[1]
|
||||
l = strings.Split(versionKind, ".")
|
||||
if len(l) != 2 {
|
||||
return applyTo
|
||||
}
|
||||
return plur.NewClient().Plural(strings.ToLower(l[1])) + "." + apigroup
|
||||
}
|
||||
|
||||
func check(applyto string, workloads []types.Capability) (string, bool) {
|
||||
for _, v := range workloads {
|
||||
if crdname == v.CrdName {
|
||||
if parse(applyto) == v.CrdName {
|
||||
return v.Name, true
|
||||
}
|
||||
}
|
||||
|
||||
+12
-5
@@ -15,13 +15,15 @@ import (
|
||||
func Test_printTraitList(t *testing.T) {
|
||||
traits := []types.Capability{
|
||||
{
|
||||
Name: "route",
|
||||
CrdName: "routes.oam.dev",
|
||||
AppliesTo: []string{"deployments.apps", "clonsets.alibaba"},
|
||||
Name: "route",
|
||||
CrdName: "routes.oam.dev",
|
||||
// This format is currently OAM spec standard
|
||||
AppliesTo: []string{"apps/v1.Deployment", "alibaba/v1.Clonset"},
|
||||
},
|
||||
{
|
||||
Name: "scaler",
|
||||
CrdName: "scaler.oam.dev",
|
||||
Name: "scaler",
|
||||
CrdName: "scaler.oam.dev",
|
||||
// This format is also reasonable, it's align with oam definition name, so we also support here
|
||||
AppliesTo: []string{"deployments.apps"},
|
||||
},
|
||||
}
|
||||
@@ -86,3 +88,8 @@ func Test_printTraitList(t *testing.T) {
|
||||
assert.Equal(t, c.ExpectedString, b.String(), cname)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
assert.Equal(t, "containerizedworkloads.core.oam.dev", parse("core.oam.dev/v1alpha2.ContainerizedWorkload"))
|
||||
assert.Equal(t, "containerizedworkloads.core.oam.dev", parse("containerizedworkloads.core.oam.dev"))
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ func newRunOptions(ioStreams cmdutil.IOStreams) *runOptions {
|
||||
}
|
||||
|
||||
func AddWorkloadCommands(parentCmd *cobra.Command, c types.Args, ioStreams cmdutil.IOStreams) error {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
templates, err := plugins.LoadTempFromLocal(filepath.Join(dir, "workloads"))
|
||||
templates, err := plugins.LoadInstalledCapabilityWithType(types.TypeWorkload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/plugins"
|
||||
"github.com/cloud-native-application/rudrx/pkg/utils/system"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/gosuri/uitable"
|
||||
@@ -21,8 +18,7 @@ func NewWorkloadsCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
Long: "List workloads",
|
||||
Example: `vela workloads`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
workloads, err := plugins.LoadTempFromLocal(filepath.Join(dir, "workloads"))
|
||||
workloads, err := plugins.LoadInstalledCapabilityWithType(types.TypeWorkload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func GetTraitsFromCluster(ctx context.Context, namespace string, c client.Client
|
||||
return templates, nil
|
||||
}
|
||||
|
||||
func HandleDefinition(name, syncDir, crdName string, extention *runtime.RawExtension, tp types.DefinitionType, applyTo []string) (types.Capability, error) {
|
||||
func HandleDefinition(name, syncDir, crdName string, extention *runtime.RawExtension, tp types.CapType, applyTo []string) (types.Capability, error) {
|
||||
var tmp types.Capability
|
||||
tmp, err := HandleTemplate(extention, name, syncDir)
|
||||
if err != nil {
|
||||
|
||||
+79
-57
@@ -10,73 +10,34 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/api/types"
|
||||
"github.com/cloud-native-application/rudrx/pkg/utils/system"
|
||||
)
|
||||
|
||||
func GetDefFromLocal(dir string, defType types.DefinitionType) ([]types.Capability, error) {
|
||||
temps, err := LoadTempFromLocal(dir)
|
||||
func LoadAllInstalledCapability() ([]types.Capability, error) {
|
||||
workloads, err := LoadInstalledCapabilityWithType(types.TypeWorkload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var defs []types.Capability
|
||||
for _, t := range temps {
|
||||
if t.Type != defType {
|
||||
continue
|
||||
}
|
||||
defs = append(defs, t)
|
||||
}
|
||||
return defs, nil
|
||||
}
|
||||
|
||||
func SinkTemp2Local(templates []types.Capability, dir string) int {
|
||||
success := 0
|
||||
for _, tmp := range templates {
|
||||
data, err := json.Marshal(tmp)
|
||||
if err != nil {
|
||||
fmt.Printf("sync %s err: %v\n", tmp.Name, err)
|
||||
continue
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(dir, tmp.Name), data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("sync %s err: %v\n", tmp.Name, err)
|
||||
continue
|
||||
}
|
||||
success++
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
func LoadCapabilityFromLocal(dir string) ([]types.Capability, error) {
|
||||
var tmps []types.Capability
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
traits, err := LoadInstalledCapabilityWithType(types.TypeTrait)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(f.Name(), ".cue") {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
|
||||
if err != nil {
|
||||
fmt.Printf("read file %s err %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
tmp, err := ParseAndSyncCapability(data, filepath.Join(dir, ".tmp"))
|
||||
if err != nil {
|
||||
fmt.Printf("get definition of %s err %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
tmps = append(tmps, tmp)
|
||||
}
|
||||
return tmps, nil
|
||||
workloads = append(workloads, traits...)
|
||||
return workloads, nil
|
||||
}
|
||||
|
||||
func LoadTempFromLocal(dir string) ([]types.Capability, error) {
|
||||
func LoadInstalledCapabilityWithType(capT types.CapType) ([]types.Capability, error) {
|
||||
dir, _ := system.GetCapabilityDir()
|
||||
return loadInstalledCapabilityWithType(dir, capT)
|
||||
}
|
||||
|
||||
// leave dir as argument for test convenience
|
||||
func loadInstalledCapabilityWithType(dir string, capT types.CapType) ([]types.Capability, error) {
|
||||
dir = GetSubDir(dir, capT)
|
||||
return loadInstalledCapability(dir)
|
||||
}
|
||||
|
||||
func loadInstalledCapability(dir string) ([]types.Capability, error) {
|
||||
var tmps []types.Capability
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
@@ -108,3 +69,64 @@ func LoadTempFromLocal(dir string) ([]types.Capability, error) {
|
||||
}
|
||||
return tmps, nil
|
||||
}
|
||||
|
||||
func GetSubDir(dir string, capT types.CapType) string {
|
||||
switch capT {
|
||||
case types.TypeWorkload:
|
||||
return filepath.Join(dir, "workloads")
|
||||
case types.TypeTrait:
|
||||
return filepath.Join(dir, "traits")
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
func SinkTemp2Local(templates []types.Capability, dir string) int {
|
||||
success := 0
|
||||
for _, tmp := range templates {
|
||||
subDir := GetSubDir(dir, tmp.Type)
|
||||
system.StatAndCreate(subDir)
|
||||
data, err := json.Marshal(tmp)
|
||||
if err != nil {
|
||||
fmt.Printf("sync %s err: %v\n", tmp.Name, err)
|
||||
continue
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(subDir, tmp.Name), data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("sync %s err: %v\n", tmp.Name, err)
|
||||
continue
|
||||
}
|
||||
success++
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
func LoadCapabilityFromSyncedCenter(dir string) ([]types.Capability, error) {
|
||||
var tmps []types.Capability
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(f.Name(), ".cue") {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
|
||||
if err != nil {
|
||||
fmt.Printf("read file %s err %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
tmp, err := ParseAndSyncCapability(data, filepath.Join(dir, ".tmp"))
|
||||
if err != nil {
|
||||
fmt.Printf("get definition of %s err %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
tmps = append(tmps, tmp)
|
||||
}
|
||||
return tmps, nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestLocalSink(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
dir string
|
||||
tmps []types.Capability
|
||||
Type types.DefinitionType
|
||||
Type types.CapType
|
||||
expDef []types.Capability
|
||||
err error
|
||||
}{
|
||||
@@ -91,21 +91,14 @@ func TestLocalSink(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testInDir(t *testing.T, casename, dir string, tmps, defexp []types.Capability, Type types.DefinitionType, err1 error) {
|
||||
func testInDir(t *testing.T, casename, dir string, tmps, defexp []types.Capability, Type types.CapType, err1 error) {
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
assert.NoError(t, err, casename)
|
||||
defer os.RemoveAll(dir)
|
||||
number := SinkTemp2Local(tmps, dir)
|
||||
assert.Equal(t, len(tmps), number)
|
||||
gottmps, err := LoadTempFromLocal(dir)
|
||||
if err1 != nil {
|
||||
assert.Equal(t, err1, err)
|
||||
} else {
|
||||
assert.NoError(t, err, casename)
|
||||
}
|
||||
assert.Equal(t, tmps, gottmps, casename)
|
||||
if Type != "" {
|
||||
gotDef, err := GetDefFromLocal(dir, Type)
|
||||
gotDef, err := loadInstalledCapabilityWithType(dir, Type)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, defexp, gotDef, casename)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user