/
resources.go
119 lines (105 loc) ยท 4.14 KB
/
resources.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2022 The kubegems.io Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package statistics
import (
"context"
"strings"
corev1 "k8s.io/api/core/v1"
gemsv1beta1 "kubegems.io/kubegems/pkg/apis/gems/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
const ResourceLimitsPrefix = "limits."
type ClusterResourceStatistics struct {
// ้็พค่ตๆบ็ๆปๅฎน้๏ผๅณ็ฉ็่ตๆบๆป้
Capacity corev1.ResourceList `json:"capacity"`
// ้็พค่ตๆบ็็ๅฎไฝฟ็จ้
Used corev1.ResourceList `json:"used"`
// ้็พคไธ็็งๆท่ตๆบๅ้
ๆป้
TenantAllocated corev1.ResourceList `json:"tenantAllocated"`
}
func GetClusterResourceStatistics(ctx context.Context, cli client.Client) ClusterResourceStatistics {
nodelist := &corev1.NodeList{}
_ = cli.List(ctx, nodelist)
allcapacity := corev1.ResourceList{}
allfree := corev1.ResourceList{}
// all node capacity and free
for _, node := range nodelist.Items {
AddResourceList(allcapacity, node.Status.Capacity)
AddResourceList(allfree, node.Status.Allocatable)
}
// calculate used
allPodUsed, _ := GetAllPodResourceStatistics(ctx, cli)
allTenantAllocated, _ := GetClusterTenantResourceQuotaLimits(ctx, cli)
// back compat
if val, ok := allTenantAllocated["requests.storage"]; ok {
allTenantAllocated["limits.storage"] = val.DeepCopy()
}
allTenantAllocated = FilterResourceName(allTenantAllocated, func(name corev1.ResourceName) bool {
return strings.HasPrefix(string(name), ResourceLimitsPrefix)
})
// tenaut allocated has resource name with limit. prefix
// we add limit. prefix for capacity and used
allcapacity = AppendResourceNamePrefix(ResourceLimitsPrefix, allcapacity)
allused := AppendResourceNamePrefix(ResourceLimitsPrefix, allPodUsed.Limit)
return ClusterResourceStatistics{
Capacity: allcapacity,
Used: allused,
TenantAllocated: allTenantAllocated,
}
}
func GetClusterTenantResourceQuotaLimits(ctx context.Context, cli client.Client) (corev1.ResourceList, error) {
tenantResourceQuotaList := &gemsv1beta1.TenantResourceQuotaList{}
if err := cli.List(ctx, tenantResourceQuotaList); err != nil {
return nil, err
}
total := corev1.ResourceList{}
for _, tquota := range tenantResourceQuotaList.Items {
AddResourceList(total, tquota.Spec.Hard)
}
return total, nil
}
type ClusterPodResourceStatistics struct {
Limit corev1.ResourceList `json:"limit"`
Request corev1.ResourceList `json:"request"`
Nodes map[string]corev1.ResourceRequirements `json:"nodes"`
}
func GetAllPodResourceStatistics(ctx context.Context, cli client.Client) (ClusterPodResourceStatistics, error) {
podList := &corev1.PodList{}
if err := cli.List(ctx, podList); err != nil {
return ClusterPodResourceStatistics{}, err
}
limitResource := corev1.ResourceList{}
requestResource := corev1.ResourceList{}
nodes := map[string]corev1.ResourceRequirements{}
for _, pod := range podList.Items {
if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodFailed {
continue
}
for _, container := range pod.Spec.Containers {
AddResourceList(limitResource, container.Resources.Limits)
AddResourceList(requestResource, container.Resources.Requests)
if node := pod.Spec.NodeName; node != "" {
if _, ok := nodes[node]; !ok {
nodes[node] = corev1.ResourceRequirements{
Limits: corev1.ResourceList{},
Requests: corev1.ResourceList{},
}
}
AddResourceList(nodes[node].Limits, container.Resources.Limits)
AddResourceList(nodes[node].Requests, container.Resources.Requests)
}
}
}
return ClusterPodResourceStatistics{Limit: limitResource, Request: requestResource, Nodes: nodes}, nil
}