github.com/oam-dev/kubevela@v1.9.11/references/cli/top/model/application.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package model 18 19 import ( 20 "context" 21 "fmt" 22 23 workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" 24 "sigs.k8s.io/controller-runtime/pkg/client" 25 26 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 27 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 28 "github.com/oam-dev/kubevela/pkg/velaql/providers/query" 29 "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types" 30 clicommon "github.com/oam-dev/kubevela/references/common" 31 ) 32 33 // Application is the application resource object 34 type Application struct { 35 name string 36 namespace string 37 phase string 38 service string 39 workflow string 40 workflowMode string 41 createTime string 42 } 43 44 // ApplicationList is application resource list 45 type ApplicationList []Application 46 47 // ToTableBody generate body of table in application view 48 func (l ApplicationList) ToTableBody() [][]string { 49 data := make([][]string, len(l)) 50 for index, app := range l { 51 data[index] = []string{app.name, app.namespace, app.phase, app.workflowMode, app.workflow, app.service, app.createTime} 52 } 53 return data 54 } 55 56 // ListApplications list all apps in all namespaces 57 func ListApplications(ctx context.Context, c client.Client) (ApplicationList, error) { 58 apps := v1beta1.ApplicationList{} 59 namespace := ctx.Value(&CtxKeyNamespace).(string) 60 61 if err := c.List(ctx, &apps, client.InNamespace(namespace)); err != nil { 62 return ApplicationList{}, err 63 } 64 appList := make(ApplicationList, len(apps.Items)) 65 for index, app := range apps.Items { 66 appList[index] = Application{name: app.Name, namespace: app.Namespace, phase: string(app.Status.Phase), createTime: app.CreationTimestamp.String()} 67 appList[index].service = serviceNum(app) 68 appList[index].workflow = workflowStepNum(app) 69 appList[index].workflowMode = workflowMode(app) 70 } 71 return appList, nil 72 } 73 74 // LoadApplication load the corresponding application according to name and namespace 75 func LoadApplication(c client.Client, name, ns string) (*v1beta1.Application, error) { 76 app := new(v1beta1.Application) 77 err := c.Get(context.Background(), client.ObjectKey{ 78 Name: name, 79 Namespace: ns, 80 }, app) 81 if err != nil { 82 return nil, err 83 } 84 return app, nil 85 } 86 87 // ApplicationResourceTopology return the applied resource of the app in tree form 88 func ApplicationResourceTopology(c client.Client, name, ns string) ([]*types.AppliedResource, error) { 89 opt := query.Option{ 90 Name: name, 91 Namespace: ns, 92 WithStatus: true, 93 WithTree: true, 94 } 95 collector := query.NewAppCollector(c, opt) 96 app := new(v1beta1.Application) 97 appKey := client.ObjectKey{Name: opt.Name, Namespace: opt.Namespace} 98 if err := c.Get(context.Background(), appKey, app); err != nil { 99 return nil, err 100 } 101 appResList, err := collector.ListApplicationResources(context.Background(), app) 102 if err != nil { 103 return nil, err 104 } 105 return appResList, nil 106 } 107 108 // applicationNum return the num of application 109 func applicationNum(ctx context.Context, c client.Client) (int, error) { 110 apps := v1beta1.ApplicationList{} 111 if err := c.List(ctx, &apps); err != nil { 112 return 0, err 113 } 114 return len(apps.Items), nil 115 } 116 117 // runningApplicationNum return the num of running application 118 func runningApplicationNum(ctx context.Context, c client.Client) (int, error) { 119 num := 0 120 apps := v1beta1.ApplicationList{} 121 if err := c.List(ctx, &apps); err != nil { 122 return num, err 123 } 124 for _, app := range apps.Items { 125 if app.Status.Phase == common.ApplicationRunning { 126 num++ 127 } 128 } 129 return num, nil 130 } 131 132 func serviceNum(app v1beta1.Application) string { 133 total, healthy := len(app.Status.Services), 0 134 for _, service := range app.Status.Services { 135 if service.Healthy { 136 healthy++ 137 } 138 } 139 return fmt.Sprintf("%d/%d", healthy, total) 140 } 141 142 func workflowMode(app v1beta1.Application) string { 143 if app.Status.Workflow == nil { 144 return Unknown 145 } 146 return app.Status.Workflow.Mode 147 } 148 149 func workflowStepNum(app v1beta1.Application) string { 150 if app.Status.Workflow == nil { 151 return clicommon.MetricsNA 152 } 153 total, succeed := len(app.Status.Workflow.Steps), 0 154 for _, step := range app.Status.Workflow.Steps { 155 if step.Phase == workflowv1alpha1.WorkflowStepPhaseSucceeded { 156 succeed++ 157 } 158 } 159 return fmt.Sprintf("%d/%d", succeed, total) 160 }