github.com/oam-dev/kubevela@v1.9.11/references/cli/top/model/info.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 "errors" 22 "fmt" 23 "runtime" 24 "strconv" 25 "strings" 26 27 v1 "k8s.io/api/core/v1" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "k8s.io/cli-runtime/pkg/genericclioptions" 30 "k8s.io/client-go/kubernetes" 31 "k8s.io/client-go/rest" 32 "k8s.io/client-go/tools/clientcmd/api" 33 "k8s.io/metrics/pkg/apis/metrics/v1beta1" 34 metrics "k8s.io/metrics/pkg/client/clientset/versioned" 35 "sigs.k8s.io/controller-runtime/pkg/client" 36 37 "github.com/oam-dev/kubevela/apis/types" 38 "github.com/oam-dev/kubevela/pkg/utils/common" 39 "github.com/oam-dev/kubevela/pkg/utils/helm" 40 clicommon "github.com/oam-dev/kubevela/references/common" 41 "github.com/oam-dev/kubevela/version" 42 ) 43 44 // Info is system info struct 45 type Info struct { 46 config *api.Config 47 } 48 49 const ( 50 // Unknown info 51 Unknown = "UNKNOWN" 52 // VelaSystemNS is the namespace of vela-system, which is the namespace of vela-core and vela-cluster-gateway 53 VelaSystemNS = "vela-system" 54 // VelaCoreAppName is the app name of vela-core 55 VelaCoreAppName = "app.kubernetes.io/name=vela-core" 56 // ClusterGatewayAppName is the app name of vela-core 57 ClusterGatewayAppName = "app.kubernetes.io/name=vela-core-cluster-gateway" 58 ) 59 60 // NewInfo return a new info struct 61 func NewInfo() *Info { 62 info := &Info{} 63 k := genericclioptions.NewConfigFlags(true) 64 rawConfig, err := k.ToRawKubeConfigLoader().RawConfig() 65 if err == nil { 66 info.config = &rawConfig 67 } 68 return info 69 } 70 71 // CurrentContext return current context info 72 func (i *Info) CurrentContext() string { 73 if i.config != nil { 74 return i.config.CurrentContext 75 } 76 return Unknown 77 } 78 79 // ClusterNum return cluster number 80 func (i *Info) ClusterNum() string { 81 if i.config != nil { 82 return strconv.Itoa(len(i.config.Clusters)) 83 } 84 return "0" 85 } 86 87 // K8SVersion return k8s version info 88 func K8SVersion(cfg *rest.Config) string { 89 c, err := kubernetes.NewForConfig(cfg) 90 if err != nil { 91 return Unknown 92 } 93 serverVersion, err := c.ServerVersion() 94 if err != nil { 95 return Unknown 96 } 97 vStr := fmt.Sprintf("%s.%s", serverVersion.Major, strings.Replace(serverVersion.Minor, "+", "", 1)) 98 return vStr 99 } 100 101 // VelaCLIVersion return vela cli version info 102 func VelaCLIVersion() string { 103 return version.VelaVersion 104 } 105 106 // VelaCoreVersion return vela core version info 107 func VelaCoreVersion() string { 108 results, err := helm.GetHelmRelease(types.DefaultKubeVelaNS) 109 if err != nil { 110 return Unknown 111 } 112 for _, result := range results { 113 if result.Chart.ChartFullPath() == types.DefaultKubeVelaChartName { 114 return result.Chart.AppVersion() 115 } 116 } 117 return Unknown 118 } 119 120 // GOLangVersion return golang version info 121 func GOLangVersion() string { 122 return runtime.Version() 123 } 124 125 // ApplicationRunningNum return the num of running application 126 func ApplicationRunningNum(cfg *rest.Config) string { 127 ctx := context.Background() 128 c, err := client.New(cfg, client.Options{Scheme: common.Scheme}) 129 if err != nil { 130 return clicommon.MetricsNA 131 } 132 appNum, err := applicationNum(ctx, c) 133 if err != nil { 134 return clicommon.MetricsNA 135 } 136 runningAppNum, err := runningApplicationNum(ctx, c) 137 if err != nil { 138 return clicommon.MetricsNA 139 } 140 return fmt.Sprintf("%d/%d", runningAppNum, appNum) 141 } 142 143 func velaCorePodUsage(cfg *rest.Config) (*v1beta1.PodMetrics, error) { 144 ctx := context.Background() 145 c, err := metrics.NewForConfig(cfg) 146 if err != nil { 147 return nil, err 148 } 149 metricsList, err := c.MetricsV1beta1().PodMetricses(VelaSystemNS).List(ctx, metav1.ListOptions{LabelSelector: VelaCoreAppName}) 150 if err != nil { 151 return nil, err 152 } 153 if len(metricsList.Items) != 1 { 154 return nil, errors.New("the num of vela core container isn't right") 155 } 156 return &metricsList.Items[0], nil 157 } 158 159 func velaCorePod(cfg *rest.Config) (*v1.Pod, error) { 160 ctx := context.Background() 161 pods := v1.PodList{} 162 c, err := client.New(cfg, client.Options{Scheme: common.Scheme}) 163 if err != nil { 164 return nil, err 165 } 166 opts := []client.ListOption{ 167 client.InNamespace(VelaSystemNS), 168 client.MatchingLabels{"app.kubernetes.io/name": "vela-core"}, 169 } 170 err = c.List(ctx, &pods, opts...) 171 if err != nil { 172 return nil, err 173 } 174 if len(pods.Items) != 1 { 175 return nil, errors.New("the num of vela core container isn't right") 176 } 177 return &pods.Items[0], nil 178 } 179 180 // VelaCoreRatio return the usage condition of vela-core pod 181 func VelaCoreRatio(c client.Client, cfg *rest.Config) (string, string, string, string) { 182 mtx, err := velaCorePodUsage(cfg) 183 if err != nil { 184 return clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA 185 } 186 pod, err := velaCorePod(cfg) 187 if err != nil { 188 return clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA 189 } 190 spec, usage := clicommon.GetPodResourceSpecAndUsage(c, pod, mtx) 191 cpuLRatio, memLRatio := clicommon.ToPercentageStr(usage.CPU, spec.Lcpu), clicommon.ToPercentageStr(usage.Mem, spec.Lmem) 192 cpuRRatio, memRRatio := clicommon.ToPercentageStr(usage.CPU, spec.Rcpu), clicommon.ToPercentageStr(usage.Mem, spec.Rmem) 193 return cpuLRatio, memLRatio, cpuRRatio, memRRatio 194 } 195 196 func velaCLusterGatewayPodUsage(cfg *rest.Config) (*v1beta1.PodMetrics, error) { 197 ctx := context.Background() 198 c, err := metrics.NewForConfig(cfg) 199 if err != nil { 200 return nil, err 201 } 202 metricsList, err := c.MetricsV1beta1().PodMetricses(VelaSystemNS).List(ctx, metav1.ListOptions{LabelSelector: ClusterGatewayAppName}) 203 if err != nil { 204 return nil, err 205 } 206 if len(metricsList.Items) != 1 || len(metricsList.Items[0].Containers) != 1 { 207 return nil, errors.New("the num of vela core cluster gateway container isn't right") 208 } 209 return &metricsList.Items[0], nil 210 } 211 212 func velaCLusterGatewayPod(cfg *rest.Config) (*v1.Pod, error) { 213 ctx := context.Background() 214 pods := v1.PodList{} 215 c, err := client.New(cfg, client.Options{Scheme: common.Scheme}) 216 if err != nil { 217 return nil, err 218 } 219 opts := []client.ListOption{ 220 client.InNamespace(VelaSystemNS), 221 client.MatchingLabels{"app.kubernetes.io/name": "vela-core-cluster-gateway"}, 222 } 223 err = c.List(ctx, &pods, opts...) 224 if err != nil { 225 return nil, err 226 } 227 if len(pods.Items) != 1 || len(pods.Items[0].Spec.Containers) != 1 { 228 return nil, errors.New("the num of vela core cluster gateway container isn't right") 229 } 230 return &pods.Items[0], nil 231 } 232 233 // CLusterGatewayRatio return the usage condition of vela-core cluster gateway pod 234 func CLusterGatewayRatio(c client.Client, cfg *rest.Config) (string, string, string, string) { 235 mtx, err := velaCLusterGatewayPodUsage(cfg) 236 if err != nil { 237 return clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA 238 } 239 pod, err := velaCLusterGatewayPod(cfg) 240 if err != nil { 241 return clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA, clicommon.MetricsNA 242 } 243 spec, usage := clicommon.GetPodResourceSpecAndUsage(c, pod, mtx) 244 cpuLRatio, memLRatio := clicommon.ToPercentageStr(usage.CPU, spec.Lcpu), clicommon.ToPercentageStr(usage.Mem, spec.Lmem) 245 cpuRRatio, memRRatio := clicommon.ToPercentageStr(usage.CPU, spec.Rcpu), clicommon.ToPercentageStr(usage.Mem, spec.Rmem) 246 return cpuLRatio, memLRatio, cpuRRatio, memRRatio 247 }