github.com/oam-dev/kubevela@v1.9.11/references/cli/top/model/pod.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  	"strconv"
    23  	"time"
    24  
    25  	v1 "k8s.io/api/core/v1"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/client-go/rest"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  
    30  	"github.com/oam-dev/kubevela/pkg/velaql/providers/query"
    31  	"github.com/oam-dev/kubevela/references/cli/top/utils"
    32  	clicommon "github.com/oam-dev/kubevela/references/common"
    33  )
    34  
    35  // Pod represent the k8s pod resource instance
    36  type Pod struct {
    37  	Name      string
    38  	Namespace string
    39  	Cluster   string
    40  	Ready     string
    41  	Status    string
    42  	CPU       string
    43  	Mem       string
    44  	CPUR      string
    45  	CPUL      string
    46  	MemR      string
    47  	MemL      string
    48  	IP        string
    49  	NodeName  string
    50  	Age       string
    51  }
    52  
    53  // PodList is pod list
    54  type PodList []Pod
    55  
    56  // ListPods return pod list of component
    57  func ListPods(ctx context.Context, cfg *rest.Config, c client.Client) (PodList, error) {
    58  	appName := ctx.Value(&CtxKeyAppName).(string)
    59  	appNamespace := ctx.Value(&CtxKeyNamespace).(string)
    60  	compCluster := ctx.Value(&CtxKeyCluster).(string)
    61  	compNamespace := ctx.Value(&CtxKeyClusterNamespace).(string)
    62  	compName := ctx.Value(&CtxKeyComponentName).(string)
    63  
    64  	opt := query.Option{
    65  		Name:      appName,
    66  		Namespace: appNamespace,
    67  		Filter: query.FilterOption{
    68  			Cluster:          compCluster,
    69  			ClusterNamespace: compNamespace,
    70  			Components:       []string{compName},
    71  			APIVersion:       "v1",
    72  			Kind:             "Pod",
    73  		},
    74  		WithTree: true,
    75  	}
    76  	resource, err := clicommon.CollectApplicationResource(ctx, c, opt)
    77  
    78  	if err != nil {
    79  		return PodList{}, err
    80  	}
    81  	list := make(PodList, len(resource))
    82  	for index, object := range resource {
    83  		pod := &v1.Pod{}
    84  		err = runtime.DefaultUnstructuredConverter.FromUnstructured(object.UnstructuredContent(), pod)
    85  		if err != nil {
    86  			continue
    87  		}
    88  		list[index] = LoadPodDetail(c, cfg, pod, compCluster)
    89  	}
    90  	return list, nil
    91  }
    92  
    93  // LoadPodDetail gather the pod detail info
    94  func LoadPodDetail(c client.Client, cfg *rest.Config, pod *v1.Pod, componentCluster string) Pod {
    95  	podInfo := Pod{
    96  		Name:      pod.Name,
    97  		Namespace: pod.Namespace,
    98  		Cluster:   componentCluster,
    99  		Ready:     readyContainerNum(pod),
   100  		Status:    string(pod.Status.Phase),
   101  		CPU:       clicommon.MetricsNA,
   102  		Mem:       clicommon.MetricsNA,
   103  		CPUR:      clicommon.MetricsNA,
   104  		MemR:      clicommon.MetricsNA,
   105  		CPUL:      clicommon.MetricsNA,
   106  		MemL:      clicommon.MetricsNA,
   107  		IP:        pod.Status.PodIP,
   108  		NodeName:  pod.Spec.NodeName,
   109  		Age:       utils.TimeFormat(time.Since(pod.CreationTimestamp.Time)),
   110  	}
   111  	metric, err := clicommon.GetPodMetrics(cfg, pod.Name, pod.Namespace, componentCluster)
   112  	if err == nil {
   113  		spec, usage := clicommon.GetPodResourceSpecAndUsage(c, pod, metric)
   114  		podInfo.CPU, podInfo.Mem = strconv.FormatInt(usage.CPU, 10), strconv.FormatInt(usage.Mem/(1024*1024), 10)
   115  		podInfo.CPUL, podInfo.MemL = clicommon.ToPercentageStr(usage.CPU, spec.Lcpu), clicommon.ToPercentageStr(usage.Mem, spec.Lmem)
   116  		podInfo.CPUR, podInfo.MemR = clicommon.ToPercentageStr(usage.CPU, spec.Rcpu), clicommon.ToPercentageStr(usage.Mem, spec.Rmem)
   117  	}
   118  	return podInfo
   119  }
   120  
   121  func readyContainerNum(pod *v1.Pod) string {
   122  	total := len(pod.Status.ContainerStatuses)
   123  	ready := 0
   124  	for _, c := range pod.Status.ContainerStatuses {
   125  		if c.Ready {
   126  			ready++
   127  		}
   128  	}
   129  	return fmt.Sprintf("%d/%d", ready, total)
   130  }
   131  
   132  // ToTableBody generate body of table in pod view
   133  func (l PodList) ToTableBody() [][]string {
   134  	data := make([][]string, len(l))
   135  	for index, pod := range l {
   136  		data[index] = []string{pod.Name, pod.Namespace, pod.Cluster, pod.Ready, pod.Status, pod.CPU, pod.Mem, pod.CPUR, pod.MemR, pod.CPUL, pod.MemL, pod.IP, pod.NodeName, pod.Age}
   137  	}
   138  	return data
   139  }