forked from rancher/rancher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
quota_validate.go
89 lines (79 loc) · 2.24 KB
/
quota_validate.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
package resourcequota
import (
"sort"
"strings"
"sync"
"time"
"github.com/rancher/norman/types/convert"
v3 "github.com/rancher/types/apis/management.cattle.io/v3"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/cache"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/quota"
)
var (
projectLockCache = cache.NewLRUExpireCache(1000)
)
func GetProjectLock(projectID string) *sync.Mutex {
val, ok := projectLockCache.Get(projectID)
if !ok {
projectLockCache.Add(projectID, &sync.Mutex{}, time.Hour)
val, _ = projectLockCache.Get(projectID)
}
mu := val.(*sync.Mutex)
return mu
}
func IsQuotaFit(nsLimit *v3.ResourceQuotaLimit, nsLimits []*v3.ResourceQuotaLimit, projectLimit *v3.ResourceQuotaLimit) (bool, string, error) {
nssResourceList := api.ResourceList{}
nsResourceList, err := ConvertLimitToResourceList(nsLimit)
if err != nil {
return false, "", err
}
nssResourceList = quota.Add(nssResourceList, nsResourceList)
for _, nsLimit := range nsLimits {
nsResourceList, err := ConvertLimitToResourceList(nsLimit)
if err != nil {
return false, "", err
}
nssResourceList = quota.Add(nssResourceList, nsResourceList)
}
projectResourceList, err := ConvertLimitToResourceList(projectLimit)
if err != nil {
return false, "", err
}
allowed, exceeded := quota.LessThanOrEqual(nssResourceList, projectResourceList)
if allowed {
return true, "", nil
}
failedHard := quota.Mask(nssResourceList, exceeded)
return false, prettyPrint(failedHard), nil
}
func ConvertLimitToResourceList(limit *v3.ResourceQuotaLimit) (api.ResourceList, error) {
toReturn := api.ResourceList{}
converted, err := convert.EncodeToMap(limit)
if err != nil {
return nil, err
}
for key, value := range converted {
q, err := resource.ParseQuantity(convert.ToString(value))
if err != nil {
return nil, err
}
toReturn[api.ResourceName(key)] = q
}
return toReturn, nil
}
func prettyPrint(item api.ResourceList) string {
parts := []string{}
keys := []string{}
for key := range item {
keys = append(keys, string(key))
}
sort.Strings(keys)
for _, key := range keys {
value := item[api.ResourceName(key)]
constraint := key + "=" + value.String()
parts = append(parts, constraint)
}
return strings.Join(parts, ",")
}