From 66d0bdb61bd3dd4ca44131a3dd0294606f5ae63c Mon Sep 17 00:00:00 2001 From: zzxwill Date: Thu, 23 Jul 2020 21:39:12 +0800 Subject: [PATCH 1/2] Implement list applications List appliations and support --application/-a to filter applicatin lists --- README.md | 12 +++++ cmd/rudrx/main.go | 1 + pkg/cmd/apps.go | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 pkg/cmd/apps.go diff --git a/README.md b/README.md index d5dae5b92..1e79665f5 100644 --- a/README.md +++ b/README.md @@ -127,4 +127,16 @@ status: apiVersion: core.oam.dev/v1alpha2 kind: ContainerizedWorkload name: poc +``` + +- list all applications +```shell script +$ rudr apps +NAME WORKLOAD TRAITS STATUS CREATE-TIME +app ContainerizedWorkload True 2020-07-22 11:23:21 +0800 CST +example-deployment-appconfig Deployment ManualScalerTrait False 2020-07-21 20:00:24 +0800 CST + +$ rudr apps -a app +NAME WORKLOAD TRAITS STATUS CREATE-TIME +app ContainerizedWorkload True 2020-07-22 11:23:21 +0800 CST ``` \ No newline at end of file diff --git a/cmd/rudrx/main.go b/cmd/rudrx/main.go index fb3925b3f..c7d341528 100644 --- a/cmd/rudrx/main.go +++ b/cmd/rudrx/main.go @@ -85,6 +85,7 @@ func newCommand(args []string) *cobra.Command { cmd.NewRunCommand(f, client, ioStream, args), cmd.NewTraitsCommand(f, client, ioStream, args), cmd.NewBindCommand(f, client, ioStream, args), + cmd.NewAppsCommand(f, client, ioStream), NewVersionCommand(), ) diff --git a/pkg/cmd/apps.go b/pkg/cmd/apps.go new file mode 100644 index 000000000..666cb4e87 --- /dev/null +++ b/pkg/cmd/apps.go @@ -0,0 +1,116 @@ +package cmd + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util" + corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2" + "github.com/gosuri/uitable" + "github.com/spf13/cobra" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func NewAppsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { + ctx := context.Background() + cmd := &cobra.Command{ + Use: "apps", + DisableFlagsInUseLine: true, + Short: "List apps", + Long: "List apps", + Example: `rudr apps`, + Run: func(cmd *cobra.Command, args []string) { + workloadName := cmd.Flag("application").Value.String() + printApplicationList(ctx, c, workloadName) + }, + } + + cmd.PersistentFlags().StringP("application", "a", "", "Application name") + return cmd +} + +func printApplicationList(ctx context.Context, c client.Client, appName string) { + applicationMetaList, err := RetrieveApplicationsByApplicationName(ctx, c, appName) + + table := uitable.New() + table.MaxColWidth = 60 + + if err != nil { + fmt.Errorf("listing Trait Definition hit an issue: %s", err) + } + + table.AddRow("NAME", "WORKLOAD", "TRAITS", "STATUS", "CREATE-TIME") + for _, a := range applicationMetaList { + traitNames := strings.Join(a.Traits, ",") + table.AddRow(a.Name, a.Workload, traitNames, a.Status, a.CreatedTime) + } + fmt.Print(table.String()) +} + +type ApplicationMeta struct { + Name string `json:"name"` + Workload string `json:"workload,omitempty"` + Traits []string `json:"traits,omitempty"` + Status string `json:"status,omitempty"` + CreatedTime string `json:"created,omitempty"` +} + +/* + Get application list by optional filter `applicationName` + Application name is equal to Component name as currently rudrx only supports one component exists in one application +*/ +func RetrieveApplicationsByApplicationName(ctx context.Context, c client.Client, workloadName string) ([]ApplicationMeta, error) { + var applicationMetaList []ApplicationMeta + namespace := "default" + + var applicationList corev1alpha2.ApplicationConfigurationList + + if workloadName != "" { + var application corev1alpha2.ApplicationConfiguration + err := c.Get(ctx, client.ObjectKey{Name: workloadName, Namespace: namespace}, &application) + + if err != nil { + return applicationMetaList, err + } + + applicationList.Items = append(applicationList.Items, application) + } else { + err := c.List(ctx, &applicationList) + if err != nil { + return applicationMetaList, err + } + } + + for _, a := range applicationList.Items { + componentName := a.Spec.Components[0].ComponentName + + var component corev1alpha2.Component + err := c.Get(ctx, client.ObjectKey{Name: componentName, Namespace: namespace}, &component) + if err != nil { + return applicationMetaList, err + } + + var workload corev1alpha2.WorkloadDefinition + json.Unmarshal(component.Spec.Workload.Raw, &workload) + workloadName := workload.TypeMeta.Kind + + var traitNames []string + for _, t := range a.Spec.Components[0].Traits { + var trait corev1alpha2.TraitDefinition + json.Unmarshal(t.Trait.Raw, &trait) + traitNames = append(traitNames, trait.Kind) + } + + applicationMetaList = append(applicationMetaList, ApplicationMeta{ + Name: a.Name, + Workload: workloadName, + Traits: traitNames, + Status: string(a.Status.Conditions[0].Status), + CreatedTime: a.ObjectMeta.CreationTimestamp.String(), + }) + } + + return applicationMetaList, nil +} From e4500771bc365bfd170d20f5c8c07f7dc383d790 Mon Sep 17 00:00:00 2001 From: zzxwill Date: Fri, 24 Jul 2020 10:46:11 +0800 Subject: [PATCH 2/2] address advices from wonderflow --- pkg/cmd/apps.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/pkg/cmd/apps.go b/pkg/cmd/apps.go index 666cb4e87..652f37dcf 100644 --- a/pkg/cmd/apps.go +++ b/pkg/cmd/apps.go @@ -18,21 +18,22 @@ func NewAppsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStre cmd := &cobra.Command{ Use: "apps", DisableFlagsInUseLine: true, - Short: "List apps", - Long: "List apps", + Short: "List applications", + Long: "List applications with workloads, traits, status and created time", Example: `rudr apps`, Run: func(cmd *cobra.Command, args []string) { - workloadName := cmd.Flag("application").Value.String() - printApplicationList(ctx, c, workloadName) + workloadName := cmd.Flag("name").Value.String() + namespace := cmd.Flag("namespace").Value.String() + printApplicationList(ctx, c, workloadName, namespace) }, } - cmd.PersistentFlags().StringP("application", "a", "", "Application name") + cmd.PersistentFlags().String("name", "", "Application name") return cmd } -func printApplicationList(ctx context.Context, c client.Client, appName string) { - applicationMetaList, err := RetrieveApplicationsByApplicationName(ctx, c, appName) +func printApplicationList(ctx context.Context, c client.Client, appName string, namespace string) { + applicationMetaList, err := RetrieveApplicationsByApplicationName(ctx, c, appName, namespace) table := uitable.New() table.MaxColWidth = 60 @@ -41,7 +42,7 @@ func printApplicationList(ctx context.Context, c client.Client, appName string) fmt.Errorf("listing Trait Definition hit an issue: %s", err) } - table.AddRow("NAME", "WORKLOAD", "TRAITS", "STATUS", "CREATE-TIME") + table.AddRow("NAME", "WORKLOAD", "TRAITS", "STATUS", "CREATED-TIME") for _, a := range applicationMetaList { traitNames := strings.Join(a.Traits, ",") table.AddRow(a.Name, a.Workload, traitNames, a.Status, a.CreatedTime) @@ -61,9 +62,12 @@ type ApplicationMeta struct { Get application list by optional filter `applicationName` Application name is equal to Component name as currently rudrx only supports one component exists in one application */ -func RetrieveApplicationsByApplicationName(ctx context.Context, c client.Client, workloadName string) ([]ApplicationMeta, error) { +func RetrieveApplicationsByApplicationName(ctx context.Context, c client.Client, workloadName string, namespace string) ([]ApplicationMeta, error) { var applicationMetaList []ApplicationMeta - namespace := "default" + + if namespace == "" { + namespace = "default" + } var applicationList corev1alpha2.ApplicationConfigurationList