提交 5c322256 编写于 作者: J Jeff 提交者: zryfish

add quota left to namespace quota

上级 322ba8be
......@@ -180,6 +180,7 @@ func addWebService(c *restful.Container) error {
webservice.Route(webservice.GET("/quotas").
To(quotas.GetClusterQuotas).
Deprecate().
Doc("get whole cluster's resource usage").
Writes(models.ResourceQuota{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
......
......@@ -37,18 +37,33 @@ const (
servicesKey = "count/services"
statefulsetsKey = "count/statefulsets.apps"
persistentvolumeclaimsKey = "persistentvolumeclaims"
storageClassesKey = "count/storageClass"
namespaceKey = "count/namespace"
jobsKey = "count/jobs.batch"
cronJobsKey = "count/cronjobs.batch"
)
type NamespacedResourceQuota struct {
Namespace string `json:"namespace,omitempty"`
Data struct {
v1.ResourceQuotaStatus
// quota left status, do the math on the side, cause it's
// a lot easier with go-client library
Left v1.ResourceList `json:"left,omitempty"`
} `json:"data,omitempty"`
}
var (
resourceMap = map[string]string{daemonsetsKey: resources.DaemonSets, deploymentsKey: resources.Deployments,
ingressKey: resources.Ingresses, servicesKey: resources.Services,
statefulsetsKey: resources.StatefulSets, persistentvolumeclaimsKey: resources.PersistentVolumeClaims, podsKey: resources.Pods,
namespaceKey: resources.Namespaces, storageClassesKey: resources.StorageClasses,
jobsKey: resources.Jobs, cronJobsKey: resources.CronJobs}
resourceMap = map[string]string{
daemonsetsKey: resources.DaemonSets,
deploymentsKey: resources.Deployments,
ingressKey: resources.Ingresses,
servicesKey: resources.Services,
statefulsetsKey: resources.StatefulSets,
persistentvolumeclaimsKey: resources.PersistentVolumeClaims,
podsKey: resources.Pods,
jobsKey: resources.Jobs,
cronJobsKey: resources.CronJobs}
)
func getUsage(namespace, resource string) (int, error) {
......@@ -61,12 +76,14 @@ func getUsage(namespace, resource string) (int, error) {
}
if err != nil {
glog.Error(err)
return 0, err
}
return result.TotalCount, nil
}
// no one use this api anymore, marked as deprecated
func GetClusterQuotas() (*models.ResourceQuota, error) {
quota := v1.ResourceQuotaStatus{Hard: make(v1.ResourceList), Used: make(v1.ResourceList)}
......@@ -85,7 +102,7 @@ func GetClusterQuotas() (*models.ResourceQuota, error) {
}
func GetNamespaceQuotas(namespace string) (*models.ResourceQuota, error) {
func GetNamespaceQuotas(namespace string) (*NamespacedResourceQuota, error) {
quota, err := getNamespaceResourceQuota(namespace)
if err != nil {
glog.Error(err)
......@@ -95,23 +112,43 @@ func GetNamespaceQuotas(namespace string) (*models.ResourceQuota, error) {
quota = &v1.ResourceQuotaStatus{Hard: make(v1.ResourceList), Used: make(v1.ResourceList)}
}
for k, v := range resourceMap {
if _, exist := quota.Used[v1.ResourceName(k)]; !exist {
if k == namespaceKey || k == storageClassesKey {
continue
var resourceQuotaLeft = v1.ResourceList{}
for key, hardLimit := range quota.Hard {
if used, ok := quota.Used[key]; ok {
left := hardLimit.DeepCopy()
left.Sub(used)
if hardLimit.Cmp(used) < 0 {
left = resource.MustParse("0")
}
used, err := getUsage(namespace, v)
resourceQuotaLeft[key] = left
}
}
// add extra quota usage, cause user may not specify them
for key, val := range resourceMap {
// only add them when they don't exist in quotastatus
if _, ok := quota.Used[v1.ResourceName(key)]; !ok {
used, err := getUsage(namespace, val)
if err != nil {
glog.Error(err)
return nil, err
}
var quantity resource.Quantity
quantity.Set(int64(used))
quota.Used[v1.ResourceName(k)] = quantity
quota.Used[v1.ResourceName(key)] = *(resource.NewQuantity(int64(used), resource.DecimalSI))
}
}
return &models.ResourceQuota{Namespace: namespace, Data: *quota}, nil
var result = NamespacedResourceQuota{
Namespace: namespace,
}
result.Data.Hard = quota.Hard
result.Data.Used = quota.Used
result.Data.Left = resourceQuotaLeft
return &result, nil
}
func updateNamespaceQuota(tmpResourceList, resourceList v1.ResourceList) {
......@@ -127,14 +164,16 @@ func updateNamespaceQuota(tmpResourceList, resourceList v1.ResourceList) {
tmpResourceList[res] = usage
}
}
}
func getNamespaceResourceQuota(namespace string) (*v1.ResourceQuotaStatus, error) {
resourceQuotaLister := informers.SharedInformerFactory().Core().V1().ResourceQuotas().Lister()
quotaList, err := resourceQuotaLister.ResourceQuotas(namespace).List(labels.Everything())
if err != nil || len(quotaList) == 0 {
if err != nil {
glog.Error(err)
return nil, err
} else if len(quotaList) == 0 {
return nil, nil
}
quotaStatus := v1.ResourceQuotaStatus{Hard: make(v1.ResourceList), Used: make(v1.ResourceList)}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册