diff --git a/go.mod b/go.mod index 0be8403c412..13230dbd52b 100644 --- a/go.mod +++ b/go.mod @@ -137,7 +137,7 @@ require ( golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 // indirect golang.org/x/text v0.3.7 - golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect + golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 google.golang.org/genproto v0.0.0-20210916144049-3192f974c780 google.golang.org/grpc v1.40.0 google.golang.org/protobuf v1.27.1 diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/model.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/model.go index 3ebb1791368..bbe2789973b 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/model.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/model.go @@ -14,11 +14,15 @@ package charts -import "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" +import ( + "github.com/erda-project/erda-infra/providers/component-protocol/cptype" + "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" +) type Charts struct { Type string `json:"type"` Props Props `json:"props"` + *cptype.SDK base.DefaultProvider } diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/render.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/render.go index 83b1a60a354..cc392b8944b 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/render.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/charts/render.go @@ -17,17 +17,144 @@ package charts import ( "context" + "github.com/pkg/errors" + "github.com/rancher/wrangler/pkg/data" + "k8s.io/apimachinery/pkg/api/resource" + "github.com/erda-project/erda-infra/base/servicehub" "github.com/erda-project/erda-infra/providers/component-protocol/cptype" + "github.com/erda-project/erda-infra/providers/component-protocol/utils/cputil" + "github.com/erda-project/erda/apistructs" + "github.com/erda-project/erda/modules/cmp" + "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common" + "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/chart" + cputil2 "github.com/erda-project/erda/modules/cmp/component-protocol/cputil" + "github.com/erda-project/erda/modules/cmp/metrics" "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" ) -func (chart Charts) Render(ctx context.Context, c *cptype.Component, scenario cptype.Scenario, event cptype.ComponentEvent, gs *cptype.GlobalStateData) error { - chart.Props = Props{ +var steveServer cmp.SteveServer +var mServer metrics.Interface + +func (cht *Charts) Init(ctx servicehub.Context) error { + server, ok := ctx.Service("cmp").(cmp.SteveServer) + if !ok { + return errors.New("failed to init component, cmp service in ctx is not a steveServer") + } + mserver, ok := ctx.Service("cmp").(metrics.Interface) + if !ok { + return errors.New("failed to init component, cmp service in ctx is not a metrics server") + } + steveServer = server + mServer = mserver + return cht.DefaultProvider.Init(ctx) +} +func (cht Charts) Render(ctx context.Context, c *cptype.Component, scenario cptype.Scenario, event cptype.ComponentEvent, gs *cptype.GlobalStateData) error { + var podsMap = make(map[string][]data.Object) + cht.Props = Props{ ContentSetting: "between", SpaceSize: "big", } - c.Props = chart.Props + c.Props = cht.Props + cht.SDK = cputil.SDK(ctx) + podReq := &apistructs.SteveRequest{} + podReq.OrgID = cht.SDK.Identity.OrgID + podReq.UserID = cht.SDK.Identity.UserID + podReq.Type = apistructs.K8SPod + + if cht.SDK.InParams["clusterName"] != nil { + podReq.ClusterName = cht.SDK.InParams["clusterName"].(string) + } else { + return common.ClusterNotFoundErr + } + resp, err := steveServer.ListSteveResource(ctx, podReq) + if err != nil { + return err + } + for _, pod := range resp { + nodeName := pod.Data().StringSlice("metadata", "fields")[6] + podsMap[nodeName] = append(podsMap[nodeName], pod.Data()) + } + nodes := (*gs)["nodes"].([]data.Object) + resourceNames := []string{chart.CPU, chart.Memory, chart.Pods} + for _, resourceName := range resourceNames { + resourceType := resource.DecimalSI + if resourceName == chart.Memory { + resourceType = resource.BinarySI + } + requestQuantity := resource.NewQuantity(0, resourceType) + unAllocatableQuantity := resource.NewQuantity(0, resourceType) + leftQuantity := resource.NewQuantity(0, resourceType) + if len(nodes) == 0 { + (*gs)[resourceName+"Chart"] = []chart.DataItem{} + } + for _, node := range nodes { + nodeName := node.StringSlice("metadata", "fields")[0] + cpu, mem, pod := cputil2.GetNodeAllocatedRes(nodeName, podsMap[nodeName]) + switch resourceName { + case chart.CPU: + unallocatedCPU, _, leftCPU, _, _ := cputil2.CalculateNodeRes(node, cpu, 0, 0) + unAllocatableQuantity.Add(*resource.NewMilliQuantity(unallocatedCPU, resource.DecimalSI)) + leftQuantity.Add(*resource.NewMilliQuantity(leftCPU, resource.DecimalSI)) + requestQuantity.Add(*resource.NewMilliQuantity(cpu, resource.DecimalSI)) + case chart.Memory: + _, unallocatedMem, _, leftMem, _ := cputil2.CalculateNodeRes(node, 0, mem, 0) + unAllocatableQuantity.Add(*resource.NewQuantity(unallocatedMem, resource.BinarySI)) + leftQuantity.Add(*resource.NewQuantity(leftMem, resource.BinarySI)) + requestQuantity.Add(*resource.NewQuantity(mem, resource.BinarySI)) + case chart.Pods: + _, _, _, _, leftPods := cputil2.CalculateNodeRes(node, 0, 0, pod) + leftQuantity.Add(*resource.NewQuantity(leftPods, resource.DecimalSI)) + requestQuantity.Add(*resource.NewQuantity(pod, resource.DecimalSI)) + } + } + var requestStr, leftStr, unAllocatableStr string + var requestValue, leftValue, unAllocatableValue float64 + switch resourceName { + case chart.CPU: + requestStr = cputil2.ResourceToString(cht.SDK, float64(requestQuantity.MilliValue()), resource.DecimalSI) + leftStr = cputil2.ResourceToString(cht.SDK, float64(leftQuantity.MilliValue()), resource.DecimalSI) + unAllocatableStr = cputil2.ResourceToString(cht.SDK, float64(unAllocatableQuantity.MilliValue()), resource.DecimalSI) + case chart.Memory: + requestStr = cputil2.ResourceToString(cht.SDK, float64(requestQuantity.Value()), resource.BinarySI) + leftStr = cputil2.ResourceToString(cht.SDK, float64(leftQuantity.Value()), resource.BinarySI) + unAllocatableStr = cputil2.ResourceToString(cht.SDK, float64(unAllocatableQuantity.Value()), resource.BinarySI) + case chart.Pods: + requestStr = cputil2.ResourceToString(cht.SDK, float64(requestQuantity.Value()), "") + leftStr = cputil2.ResourceToString(cht.SDK, float64(leftQuantity.Value()), "") + unAllocatableStr = cputil2.ResourceToString(cht.SDK, float64(unAllocatableQuantity.Value()), "") + } + requestValue = float64(requestQuantity.MilliValue()) / 1000 + leftValue = float64(leftQuantity.MilliValue()) / 1000 + unAllocatableValue = float64(unAllocatableQuantity.MilliValue()) / 1000 + var di []chart.DataItem + var distributedDesc, freeDesc, lockedDesc string + if requestValue != 0 { + distributedDesc = chart.DefaultFormat + requestStr + di = append(di, chart.DataItem{ + Value: requestValue, + Name: cht.SDK.I18n(chart.Allocated), + Label: chart.Label{Formatter: distributedDesc}, + }) + } + if leftValue != 0 { + freeDesc = chart.DefaultFormat + leftStr + di = append(di, chart.DataItem{ + Value: leftValue, + Name: cht.SDK.I18n(chart.Free_Allocate), + Label: chart.Label{Formatter: freeDesc}, + }) + } + if unAllocatableValue != 0 { + lockedDesc = chart.DefaultFormat + unAllocatableStr + di = append(di, chart.DataItem{ + Value: unAllocatableValue, + Name: cht.SDK.I18n(chart.Cannot_Allocate), + Label: chart.Label{Formatter: lockedDesc}, + }) + } + (*gs)[resourceName+"Chart"] = di + } return nil } func init() { diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/chart/model.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/chart/model.go index 01e0592aa0e..1d19f08530b 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/chart/model.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/chart/model.go @@ -16,9 +16,7 @@ package chart import ( "context" - "fmt" - "github.com/rancher/wrangler/pkg/data" "k8s.io/apimachinery/pkg/api/resource" "github.com/erda-project/erda-infra/providers/component-protocol/cptype" @@ -34,9 +32,9 @@ var ( Free_Allocate = "Free-Allocate" Cannot_Allocate = "Cannot-Allocate" - Memory = "Memory" - CPU = "CPU" - Pods = "Pods" + Memory = "memory" + CPU = "cpu" + Pods = "pods" DefaultFormat = "{d}%\n" ) @@ -53,72 +51,6 @@ type ChartInterface interface { ChartRender(ctx context.Context, c *cptype.Component, scenario cptype.Scenario, event cptype.ComponentEvent, gs *cptype.GlobalStateData) error } -func (cht Chart) setData(nodes []data.Object, resourceName string) []DataItem { - //var allocatableTotal, capacityTotal, unAllocatableTotal float64 - resourceType := resource.DecimalSI - if resourceName == Memory { - resourceType = resource.BinarySI - } - allocatableQuantity := resource.NewQuantity(0, resourceType) - capacityQuantity := resource.NewQuantity(0, resourceType) - unAllocatableQuantity := resource.NewQuantity(0, resourceType) - if len(nodes) == 0 { - return []DataItem{} - } - for _, node := range nodes { - allocatableQuantity.Add(*parseResource(node.String("extra", "parsedResource", "allocated", resourceName), resourceType)) - capacityQuantity.Add(*parseResource(node.String("extra", "parsedResource", "capacity", resourceName), resourceType)) - unAllocatableQuantity.Add(*parseResource(node.String("extra", "parsedResource", "unallocatable", resourceName), resourceType)) - } - allocatableQuantity.ToUnstructured() - capacityQuantity.Sub(*unAllocatableQuantity) - capacityQuantity.Sub(*allocatableQuantity) - - allocatableQuantityValue := float64(allocatableQuantity.Value()) - capacityQuantityValue := float64(capacityQuantity.Value()) - unAllocatableQuantityValue := float64(unAllocatableQuantity.Value()) - - allocatableStr, unAllocatableStr, capacityStr := GetScaleValue(allocatableQuantity, unAllocatableQuantity, capacityQuantity) - if resourceName == CPU { - allocatableStr = fmt.Sprintf("%.1f"+cht.SDK.I18n("cores"), allocatableQuantityValue/1000) - capacityStr = fmt.Sprintf("%.1f"+cht.SDK.I18n("cores"), capacityQuantityValue/1000) - unAllocatableStr = fmt.Sprintf("%.1f"+cht.SDK.I18n("cores"), unAllocatableQuantityValue/1000) - } - - var di []DataItem - distributedDesc := DefaultFormat + allocatableStr - if allocatableQuantity.Value() == 0 { - distributedDesc = "" - } else { - di = append(di, DataItem{ - Value: allocatableQuantityValue, - Name: cht.SDK.I18n(Allocated), - Label: Label{Formatter: distributedDesc}, - }) - } - freeDesc := DefaultFormat + capacityStr - if capacityQuantity.Value() == 0 { - freeDesc = "" - } else { - di = append(di, DataItem{ - Value: capacityQuantityValue, - Name: cht.SDK.I18n(Free_Allocate), - Label: Label{Formatter: freeDesc}, - }) - } - lockedDesc := DefaultFormat + unAllocatableStr - if unAllocatableQuantity.Value() == 0 { - lockedDesc = "" - } else { - di = append(di, DataItem{ - Value: unAllocatableQuantityValue, - Name: cht.SDK.I18n(Cannot_Allocate), - Label: Label{Formatter: lockedDesc}, - }) - } - return di -} - func GetScaleValue(quantity1 *resource.Quantity, quantity2 *resource.Quantity, quantity3 *resource.Quantity) (string, string, string) { factor := 10 for ; (quantity1.Value() != 0 && quantity1.Value() > int64(1< int64(1< int64(1< b.FieldByName(sortColumn).String() @@ -605,9 +626,9 @@ func SortByString(data []RowItem, sortColumn string, asc bool) { } // SortByNode sort by node struct -func SortByNode(data []RowItem, _ string, asc bool) { +func SortByNode(data []RowItem, _ string, ascend bool) { sort.Slice(data, func(i, j int) bool { - if asc { + if ascend { return data[i].Node.Renders[0].([]interface{})[0].(NodeLink).Value < data[j].Node.Renders[0].([]interface{})[0].(NodeLink).Value } return data[i].Node.Renders[0].([]interface{})[0].(NodeLink).Value > data[j].Node.Renders[0].([]interface{})[0].(NodeLink).Value @@ -615,13 +636,13 @@ func SortByNode(data []RowItem, _ string, asc bool) { } // SortByDistribution sort by percent -func SortByDistribution(data []RowItem, sortColumn string, asc bool) { +func SortByDistribution(data []RowItem, sortColumn string, ascend bool) { sort.Slice(data, func(i, j int) bool { a := reflect.ValueOf(data[i]) b := reflect.ValueOf(data[j]) aValue := cast.ToFloat64(a.FieldByName(sortColumn).FieldByName("Value").String()) bValue := cast.ToFloat64(b.FieldByName(sortColumn).FieldByName("Value").String()) - if asc { + if ascend { return aValue < bValue } return aValue > bValue @@ -641,7 +662,7 @@ func SortByStatus(data []RowItem, _ string, asc bool) { type State struct { //PageNo int `json:"pageNo,omitempty"` //PageSize int `json:"pageSize,omitempty"` - //Total int `json:"total,omitempty"` + //Left int `json:"total,omitempty"` SelectedRowKeys []string `json:"selectedRowKeys,omitempty"` Sorter Sorter `json:"sorterData,omitempty"` Values filter.Values `json:"values"` diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table/table_test.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table/table_test.go index b1c7d691ae8..ad03d82c11b 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table/table_test.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table/table_test.go @@ -21,7 +21,6 @@ import ( "github.com/erda-project/erda-infra/providers/component-protocol/cptype" "github.com/erda-project/erda/modules/cmp" - "github.com/erda-project/erda/modules/cmp/metrics" "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" ) @@ -319,7 +318,7 @@ func TestTable_GetUnusedRate(t1 *testing.T) { type fields struct { } type args struct { - metricsData *metrics.MetricsData + a, b float64 resourceType TableType } tests := []struct { @@ -333,8 +332,8 @@ func TestTable_GetUnusedRate(t1 *testing.T) { name: "text", fields: fields{}, args: args{ - metricsData: &metrics.MetricsData{Used: 1, Request: 1.2, - Total: 10}, + a: 0.2, + b: 1.2, resourceType: Cpu, }, want: DistributionValue{"0.200/1.200", "16.7"}, @@ -343,8 +342,8 @@ func TestTable_GetUnusedRate(t1 *testing.T) { name: "text", fields: fields{}, args: args{ - metricsData: &metrics.MetricsData{Used: 1, Request: 1.2, - Total: 10}, + a: 0.2, + b: 1.2, resourceType: Memory, }, want: DistributionValue{"0.2/1.2", "16.7"}, @@ -353,7 +352,7 @@ func TestTable_GetUnusedRate(t1 *testing.T) { for _, tt := range tests { t1.Run(tt.name, func(t1 *testing.T) { t := &Table{} - if got := t.GetUnusedRate(tt.args.metricsData, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { + if got := t.GetUnusedRate(tt.args.a, tt.args.b, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { t1.Errorf("GetUnusedRate() = %v, want %v", got, tt.want) } }) @@ -373,7 +372,7 @@ func TestTable_GetDistributionValue(t1 *testing.T) { State State } type args struct { - metricsData *metrics.MetricsData + a, b float64 resourceType TableType } tests := []struct { @@ -385,7 +384,8 @@ func TestTable_GetDistributionValue(t1 *testing.T) { { name: "1", args: args{ - metricsData: &metrics.MetricsData{1, 2, 3}, + a: 2, + b: 3, resourceType: Pod, }, want: DistributionValue{ @@ -397,7 +397,7 @@ func TestTable_GetDistributionValue(t1 *testing.T) { for _, tt := range tests { t1.Run(tt.name, func(t1 *testing.T) { t := &Table{} - if got := t.GetDistributionValue(tt.args.metricsData, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { + if got := t.GetDistributionValue(tt.args.a, tt.args.b, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { t1.Errorf("GetDistributionValue() = %v, want %v", got, tt.want) } }) @@ -417,7 +417,7 @@ func TestTable_GetUsageValue(t1 *testing.T) { State State } type args struct { - metricsData *metrics.MetricsData + a, b float64 resourceType TableType } tests := []struct { @@ -429,7 +429,8 @@ func TestTable_GetUsageValue(t1 *testing.T) { { name: "1", args: args{ - metricsData: &metrics.MetricsData{1, 2, 3}, + a: 1, + b: 3, resourceType: Pod, }, want: DistributionValue{ @@ -441,7 +442,7 @@ func TestTable_GetUsageValue(t1 *testing.T) { for _, tt := range tests { t1.Run(tt.name, func(t1 *testing.T) { t := &Table{} - if got := t.GetUsageValue(tt.args.metricsData, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { + if got := t.GetUsageValue(tt.args.a, tt.args.b, tt.args.resourceType); !reflect.DeepEqual(got, tt.want) { t1.Errorf("GetUsageValue() = %v, want %v", got, tt.want) } }) diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/cpuTable/render.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/cpuTable/render.go index 1fa987092b3..d8bd24b23bc 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/cpuTable/render.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/cpuTable/render.go @@ -31,6 +31,7 @@ import ( "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/tableTabs" + cputil2 "github.com/erda-project/erda/modules/cmp/component-protocol/cputil" "github.com/erda-project/erda/modules/cmp/metrics" "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" ) @@ -104,7 +105,11 @@ func (ct *CpuInfoTable) Render(ctx context.Context, c *cptype.Component, s cptyp if err != nil { return err } - if err = ct.RenderList(c, table.Cpu, nodes); err != nil { + podsMap, err := ct.GetPods(ctx) + if err != nil { + return err + } + if err = ct.RenderList(c, table.Cpu, nodes, podsMap); err != nil { return err } if err = ct.SetComponentValue(c); err != nil { @@ -138,7 +143,7 @@ func (ct *CpuInfoTable) getProps() { ct.Props = props } -func (ct *CpuInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType) ([]table.RowItem, error) { +func (ct *CpuInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType, podsMap map[string][]data.Object) ([]table.RowItem, error) { var ( err error status *table.SteveStatus @@ -170,16 +175,14 @@ func (ct *CpuInfoTable) GetRowItems(nodes []data.Object, tableType table.TableTy return nil, err } //request := c.Map("status", "allocatable").String("cpu") - limitStr := c.Map("extra", "parsedResource", "capacity").String("CPU") - limitQuantity, _ := resource.ParseQuantity(limitStr) - requestStr := c.Map("extra", "parsedResource", "allocated").String("CPU") - requestQuantity, _ := resource.ParseQuantity(requestStr) + nodeName := c.StringSlice("metadata", "fields")[0] + cpuRequest, _, _ := cputil2.GetNodeAllocatedRes(nodeName, podsMap[nodeName]) + requestQty, _ := resource.ParseQuantity(c.String("status", "allocatable", "cpu")) + key := req.NodeRequests[i].CacheKey() - resp[key].Total = float64(limitQuantity.Value()) / 1000 - resp[key].Request = float64(requestQuantity.Value()) / 1000 - distribution = ct.GetDistributionValue(resp[key], table.Cpu) - usage = ct.GetUsageValue(resp[key], table.Cpu) - dr = ct.GetUnusedRate(resp[key], table.Cpu) + distribution = ct.GetDistributionValue(float64(cpuRequest), float64(requestQty.ScaledValue(resource.Milli)), table.Cpu) + usage = ct.GetUsageValue(resp[key].Used, float64(requestQty.Value()), table.Cpu) + dr = ct.GetUnusedRate(float64(cpuRequest)-resp[key].Used*1000, float64(cpuRequest), table.Cpu) role := c.StringSlice("metadata", "fields")[2] ip := c.StringSlice("metadata", "fields")[5] if role == "" { diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/memTable/render.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/memTable/render.go index 44c8a598505..59ab7a0928f 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/memTable/render.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/memTable/render.go @@ -26,12 +26,13 @@ import ( "github.com/erda-project/erda-infra/base/servicehub" "github.com/erda-project/erda-infra/providers/component-protocol/cptype" "github.com/erda-project/erda-infra/providers/component-protocol/utils/cputil" - "github.com/erda-project/erda/modules/cmp" "github.com/erda-project/erda/apistructs" + "github.com/erda-project/erda/modules/cmp" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/tableTabs" + cputil2 "github.com/erda-project/erda/modules/cmp/component-protocol/cputil" "github.com/erda-project/erda/modules/cmp/metrics" "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" ) @@ -103,7 +104,11 @@ func (mt *MemInfoTable) Render(ctx context.Context, c *cptype.Component, s cptyp if err != nil { return err } - if err = mt.RenderList(c, table.Memory, nodes); err != nil { + podsMap, err := mt.GetPods(ctx) + if err != nil { + return err + } + if err = mt.RenderList(c, table.Memory, nodes, podsMap); err != nil { return err } if err = mt.SetComponentValue(c); err != nil { @@ -112,7 +117,7 @@ func (mt *MemInfoTable) Render(ctx context.Context, c *cptype.Component, s cptyp return nil } -func (mt *MemInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType) ([]table.RowItem, error) { +func (mt *MemInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType, podsMap map[string][]data.Object) ([]table.RowItem, error) { var ( err error status *table.SteveStatus @@ -120,6 +125,7 @@ func (mt *MemInfoTable) GetRowItems(nodes []data.Object, tableType table.TableTy resp map[string]*metrics.MetricsData items []table.RowItem ) + req := &metrics.MetricsRequest{ Cluster: mt.SDK.InParams["clusterName"].(string), Type: metrics.Memory, @@ -139,17 +145,14 @@ func (mt *MemInfoTable) GetRowItems(nodes []data.Object, tableType table.TableTy if status, err = mt.GetItemStatus(c); err != nil { return nil, err } + nodeName := c.StringSlice("metadata", "fields")[0] + _, memRequest, _ := cputil2.GetNodeAllocatedRes(nodeName, podsMap[nodeName]) + requestQty, _ := resource.ParseQuantity(c.String("status", "allocatable", "memory")) - limitStr := c.Map("extra", "parsedResource", "capacity").String("Memory") - limitQuantity, _ := resource.ParseQuantity(limitStr) - requestStr := c.Map("extra", "parsedResource", "allocated").String("Memory") - requestQuantity, _ := resource.ParseQuantity(requestStr) key := req.NodeRequests[i].CacheKey() - resp[key].Total = float64(limitQuantity.Value()) - resp[key].Request = float64(requestQuantity.Value()) - distribution = mt.GetDistributionValue(resp[key], table.Memory) - usage = mt.GetUsageValue(resp[key], table.Memory) - dr = mt.GetUnusedRate(resp[key], table.Memory) + distribution = mt.GetDistributionValue(float64(memRequest), float64(requestQty.Value()), table.Memory) + usage = mt.GetUsageValue(resp[key].Used, float64(requestQty.Value()), table.Memory) + dr = mt.GetUnusedRate(float64(memRequest)-resp[key].Used, float64(memRequest), table.Memory) role := c.StringSlice("metadata", "fields")[2] ip := c.StringSlice("metadata", "fields")[5] if role == "" { diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/nodeFilter/render.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/nodeFilter/render.go index da59ddabcb2..a446f1fbe3f 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/nodeFilter/render.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/nodeFilter/render.go @@ -49,7 +49,9 @@ func (nf *NodeFilter) Render(ctx context.Context, c *cptype.Component, scenario nf.CtxBdl = ctx.Value(types.GlobalCtxKeyBundle).(*bundle.Bundle) nf.SDK = sdk nf.Operations = getFilterOperation() - var nodes []data.Object + var ( + nodeList, nodes []data.Object + ) // Get all nodes by cluster name nodeReq := &apistructs.SteveRequest{} nodeReq.OrgID = sdk.Identity.OrgID @@ -65,7 +67,7 @@ func (nf *NodeFilter) Render(ctx context.Context, c *cptype.Component, scenario if err != nil { return err } - var nodeList []data.Object + for _, item := range resp { nodeList = append(nodeList, item.Data()) } diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/podTable/render.go b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/podTable/render.go index 6cb0bced3e5..48113f7b279 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-nodes/podTable/render.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-nodes/podTable/render.go @@ -21,7 +21,7 @@ import ( "github.com/pkg/errors" "github.com/rancher/wrangler/pkg/data" "github.com/sirupsen/logrus" - "github.com/spf13/cast" + "k8s.io/apimachinery/pkg/api/resource" "github.com/erda-project/erda-infra/base/servicehub" "github.com/erda-project/erda-infra/providers/component-protocol/cptype" @@ -31,6 +31,7 @@ import ( "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/common/table" "github.com/erda-project/erda/modules/cmp/component-protocol/components/cmp-dashboard-nodes/tableTabs" + cputil2 "github.com/erda-project/erda/modules/cmp/component-protocol/cputil" "github.com/erda-project/erda/modules/openapi/component-protocol/components/base" ) @@ -98,7 +99,11 @@ func (pt *PodInfoTable) Render(ctx context.Context, c *cptype.Component, s cptyp if err != nil { return err } - if err = pt.RenderList(c, table.Pod, nodes); err != nil { + podsMap, err := pt.GetPods(ctx) + if err != nil { + return err + } + if err = pt.RenderList(c, table.Pod, nodes, podsMap); err != nil { return err } if err = pt.SetComponentValue(c); err != nil { @@ -130,25 +135,26 @@ func (pt *PodInfoTable) getProps() { pt.Props = p } -func (pt *PodInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType) ([]table.RowItem, error) { +func (pt *PodInfoTable) GetRowItems(nodes []data.Object, tableType table.TableType, podsMap map[string][]data.Object) ([]table.RowItem, error) { var ( - err error status *table.SteveStatus items []table.RowItem + err error ) - for _, node := range nodes { - status, err = pt.GetItemStatus(node) + for _, c := range nodes { + status, err = pt.GetItemStatus(c) if err != nil { return nil, err } - if status, err = pt.GetItemStatus(node); err != nil { + if status, err = pt.GetItemStatus(c); err != nil { return nil, err } - allocatable := cast.ToFloat64(node.String("extra", "parsedResource", "allocated", "Pods")) - capacity := cast.ToFloat64(node.String("extra", "parsedResource", "capacity", "Pods")) - ur := table.DistributionValue{Percent: common.GetPercent(allocatable, capacity)} - role := node.StringSlice("metadata", "fields")[2] - ip := node.StringSlice("metadata", "fields")[5] + nodeName := c.StringSlice("metadata", "fields")[0] + _, _, pod := cputil2.GetNodeAllocatedRes(nodeName, podsMap[nodeName]) + capacityPodsQty, _ := resource.ParseQuantity(c.String("status", "allocatable", "pods")) + ur := table.DistributionValue{Percent: common.GetPercent(float64(pod), float64(capacityPodsQty.Value()))} + role := c.StringSlice("metadata", "fields")[2] + ip := c.StringSlice("metadata", "fields")[5] if role == "" { role = "worker" } @@ -161,22 +167,22 @@ func (pt *PodInfoTable) GetRowItems(nodes []data.Object, tableType table.TableTy } } items = append(items, table.RowItem{ - ID: node.String("metadata", "name"), + ID: c.String("metadata", "name"), IP: ip, - Version: node.String("status", "nodeInfo", "kubeletVersion"), + Version: c.String("status", "nodeInfo", "kubeletVersion"), Role: role, Node: table.Node{ RenderType: "multiple", - Renders: pt.GetRenders(node.String("metadata", "name"), ip, node.Map("metadata", "labels")), + Renders: pt.GetRenders(c.String("metadata", "name"), ip, c.Map("metadata", "labels")), }, Status: *status, Usage: table.Distribution{ RenderType: "progress", Value: ur.Percent, Status: table.GetDistributionStatus(ur.Percent), - Tip: pt.GetScaleValue(allocatable, capacity, table.Pod), + Tip: pt.GetScaleValue(float64(pod), float64(capacityPodsQty.Value()), table.Pod), }, - Operate: pt.GetOperate(node.String("metadata", "name")), + Operate: pt.GetOperate(c.String("metadata", "name")), BatchOperations: batchOperations, }) } diff --git a/modules/cmp/component-protocol/components/cmp-dashboard-pods/common/table/table.go b/modules/cmp/component-protocol/components/cmp-dashboard-pods/common/table/table.go index 7267401ca3e..0d461c6cffb 100644 --- a/modules/cmp/component-protocol/components/cmp-dashboard-pods/common/table/table.go +++ b/modules/cmp/component-protocol/components/cmp-dashboard-pods/common/table/table.go @@ -178,8 +178,8 @@ type RowItem struct { func (t *Table) GetUsageValue(metricsData metrics.MetricsData) *DistributionValue { return &DistributionValue{ - Text: fmt.Sprintf("%.1f/%.1f", metricsData.Used, metricsData.Total), - Percent: common.GetPercent(metricsData.Used, metricsData.Total), + Text: fmt.Sprintf("%.1f/%.1f", metricsData.Used, metricsData.Left), + Percent: common.GetPercent(metricsData.Used, metricsData.Left), } } @@ -201,13 +201,6 @@ func getColor(percent float64) string { return common.ColorMap["green"] } -func (t *Table) GetDistributionRate(metricsData metrics.MetricsData) *DistributionValue { - return &DistributionValue{ - Text: fmt.Sprintf("%f/%f", metricsData.Used, metricsData.Request), - Percent: common.GetPercent(metricsData.Request, metricsData.Total), - } -} - // SetComponentValue mapping CpuInfoTable properties to Component func (t *Table) SetComponentValue(c *cptype.Component) error { var ( diff --git a/modules/cmp/component-protocol/cputil/util.go b/modules/cmp/component-protocol/cputil/util.go index 6b41af67163..9663221ab53 100644 --- a/modules/cmp/component-protocol/cputil/util.go +++ b/modules/cmp/component-protocol/cputil/util.go @@ -146,7 +146,7 @@ func ResourceToString(sdk *cptype.SDK, res float64, format resource.Format) stri } return fmt.Sprintf("%s%s", strconv.FormatFloat(setPrec(res, 3), 'f', -1, 64), units[i]) default: - return "" + return fmt.Sprintf("%d", int64(res)) } } @@ -179,7 +179,7 @@ func GetNodeAllocatedRes(nodeName string, pods []data.Object) (cpu, mem, podNum *requestsMem, _ = resource.ParseQuantity(requests) } cpuQty.Add(*requestsCPU) - cpuQty.Add(*requestsMem) + memQty.Add(*requestsMem) } } return cpuQty.MilliValue(), memQty.Value(), podNum diff --git a/modules/cmp/metrics/metrics.go b/modules/cmp/metrics/metrics.go index 01f4acee741..4c86cc268ac 100644 --- a/modules/cmp/metrics/metrics.go +++ b/modules/cmp/metrics/metrics.go @@ -40,7 +40,7 @@ const ( NodeResourceUsageSelectStatement = `SELECT last(mem_used::field) as memRate , last(cpu_cores_usage::field) as cpuRate , host_ip::tag FROM host_summary WHERE cluster_name::tag=$cluster_name GROUP BY host_ip::tag` //NodeResourceUsageSelectStatement = `SELECT mem_usage::field ,cpu_cores_usage::field, host_ip FROM host_summary WHERE cluster_name::tag=$cluster_name GROUP BY host_ip::tag` //PodCpuUsageSelectStatement = `SELECT SUM(cpu_allocation::field) * 100 / SUM(cpu_limit::field) as cpuRate, pod_name FROM docker_container_summary WHERE pod_namespace::tag=$pod_namespace and podsandbox != true GROUP BY pod_name::tag` - PodResourceUsageSelectStatement = `SELECT round_float(SUM(mem_usage::field) * 100 / SUM(mem_limit::field),2) as memoryRate,round_float(SUM(cpu_allocation::field) * 100 / SUM(cpu_limit::field),2) as cpuRate ,pod_name::tag FROM docker_container_summary WHERE pod_namespace::tag=$pod_namespace and cluster_name::tag=$cluster_name and podsandbox != true GROUP BY pod_name::tag` + PodResourceUsageSelectStatement = `SELECT round_float(SUM(mem_usage::field) * 100 / SUM(mem_limit::field),2) as memoryRate,round_float(SUM(cpu_usage_percent::field),2) as cpuRate ,pod_name::tag FROM docker_container_summary WHERE pod_namespace::tag=$pod_namespace and cluster_name::tag=$cluster_name and podsandbox != true GROUP BY pod_name::tag` Memory = "memory" Cpu = "cpu" @@ -337,8 +337,8 @@ func ToInfluxReq(req *MetricsRequest, kind string) (map[string][]*MetricsReq, ma logrus.Errorf("try find cache error ,%v", err) } noNeed[key] = resp + logrus.Infof("%v cache hit,isExpired %v", key, expired) if !expired { - logrus.Infof("%v cache hit", key) continue } } diff --git a/modules/cmp/metrics/metricsReq.go b/modules/cmp/metrics/metricsReq.go index fb259308f2d..121b7cdd862 100644 --- a/modules/cmp/metrics/metricsReq.go +++ b/modules/cmp/metrics/metricsReq.go @@ -139,7 +139,7 @@ func (m *MetricsNodeRequest) IP() string { type MetricsData struct { // if qurey pod resource, used means usedPercent. request and total are useless. - Used float64 `json:"used"` - Request float64 `json:"request"` - Total float64 `json:"total"` + Used float64 `json:"used"` + Unallocate float64 `json:"unallocate"` + Left float64 `json:"left"` } diff --git a/modules/cmp/metrics/metrics_test.go b/modules/cmp/metrics/metrics_test.go index 0f98c1d853b..a12ed3893a3 100644 --- a/modules/cmp/metrics/metrics_test.go +++ b/modules/cmp/metrics/metrics_test.go @@ -177,14 +177,14 @@ func TestMetric_Store(t *testing.T) { res := map[string]*MetricsData{} res["111cpu"] = &MetricsData{ - Used: 1, - Request: 0, - Total: 0, + Used: 1, + Unallocate: 0, + Left: 0, } res["111memory"] = &MetricsData{ - Used: 2, - Request: 0, - Total: 0, + Used: 2, + Unallocate: 0, + Left: 0, } metricsReq := &pb.QueryWithInfluxFormatRequest{} queryReq := &pb.QueryWithInfluxFormatRequest{}