mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +00:00 
			
		
		
		
	refactor quota calculation for re-use
This commit is contained in:
		| @@ -275,12 +275,22 @@ func (rq *ResourceQuotaController) syncResourceQuota(resourceQuota api.ResourceQ | ||||
| 	// if this is our first sync, it will be dirty by default, since we need track usage | ||||
| 	dirty = dirty || (resourceQuota.Status.Hard == nil || resourceQuota.Status.Used == nil) | ||||
|  | ||||
| 	used := api.ResourceList{} | ||||
| 	if resourceQuota.Status.Used != nil { | ||||
| 		used = quota.Add(api.ResourceList{}, resourceQuota.Status.Used) | ||||
| 	} | ||||
| 	hardLimits := quota.Add(api.ResourceList{}, resourceQuota.Spec.Hard) | ||||
|  | ||||
| 	newUsage, err := quota.CalculateUsage(resourceQuota.Namespace, resourceQuota.Spec.Scopes, hardLimits, rq.registry) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for key, value := range newUsage { | ||||
| 		used[key] = value | ||||
| 	} | ||||
|  | ||||
| 	// Create a usage object that is based on the quota resource version that will handle updates | ||||
| 	// by default, we preserve the past usage observation, and set hard to the current spec | ||||
| 	previousUsed := api.ResourceList{} | ||||
| 	if resourceQuota.Status.Used != nil { | ||||
| 		previousUsed = quota.Add(api.ResourceList{}, resourceQuota.Status.Used) | ||||
| 	} | ||||
| 	usage := api.ResourceQuota{ | ||||
| 		ObjectMeta: api.ObjectMeta{ | ||||
| 			Name:            resourceQuota.Name, | ||||
| @@ -289,45 +299,11 @@ func (rq *ResourceQuotaController) syncResourceQuota(resourceQuota api.ResourceQ | ||||
| 			Labels:          resourceQuota.Labels, | ||||
| 			Annotations:     resourceQuota.Annotations}, | ||||
| 		Status: api.ResourceQuotaStatus{ | ||||
| 			Hard: quota.Add(api.ResourceList{}, resourceQuota.Spec.Hard), | ||||
| 			Used: previousUsed, | ||||
| 			Hard: hardLimits, | ||||
| 			Used: used, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	// find the intersection between the hard resources on the quota | ||||
| 	// and the resources this controller can track to know what we can | ||||
| 	// look to measure updated usage stats for | ||||
| 	hardResources := quota.ResourceNames(usage.Status.Hard) | ||||
| 	potentialResources := []api.ResourceName{} | ||||
| 	evaluators := rq.registry.Evaluators() | ||||
| 	for _, evaluator := range evaluators { | ||||
| 		potentialResources = append(potentialResources, evaluator.MatchesResources()...) | ||||
| 	} | ||||
| 	matchedResources := quota.Intersection(hardResources, potentialResources) | ||||
|  | ||||
| 	// sum the observed usage from each evaluator | ||||
| 	newUsage := api.ResourceList{} | ||||
| 	usageStatsOptions := quota.UsageStatsOptions{Namespace: resourceQuota.Namespace, Scopes: resourceQuota.Spec.Scopes} | ||||
| 	for _, evaluator := range evaluators { | ||||
| 		// only trigger the evaluator if it matches a resource in the quota, otherwise, skip calculating anything | ||||
| 		if intersection := quota.Intersection(evaluator.MatchesResources(), matchedResources); len(intersection) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		stats, err := evaluator.UsageStats(usageStatsOptions) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		newUsage = quota.Add(newUsage, stats.Used) | ||||
| 	} | ||||
|  | ||||
| 	// mask the observed usage to only the set of resources tracked by this quota | ||||
| 	// merge our observed usage with the quota usage status | ||||
| 	// if the new usage is different than the last usage, we will need to do an update | ||||
| 	newUsage = quota.Mask(newUsage, matchedResources) | ||||
| 	for key, value := range newUsage { | ||||
| 		usage.Status.Used[key] = value | ||||
| 	} | ||||
|  | ||||
| 	dirty = dirty || !quota.Equals(usage.Status.Used, resourceQuota.Status.Used) | ||||
|  | ||||
| 	// there was a change observed by this controller that requires we update quota | ||||
|   | ||||
| @@ -177,3 +177,38 @@ func ToSet(resourceNames []api.ResourceName) sets.String { | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // CalculateUsage calculates and returns the requested ResourceList usage | ||||
| func CalculateUsage(namespaceName string, scopes []api.ResourceQuotaScope, hardLimits api.ResourceList, registry Registry) (api.ResourceList, error) { | ||||
| 	// find the intersection between the hard resources on the quota | ||||
| 	// and the resources this controller can track to know what we can | ||||
| 	// look to measure updated usage stats for | ||||
| 	hardResources := ResourceNames(hardLimits) | ||||
| 	potentialResources := []api.ResourceName{} | ||||
| 	evaluators := registry.Evaluators() | ||||
| 	for _, evaluator := range evaluators { | ||||
| 		potentialResources = append(potentialResources, evaluator.MatchesResources()...) | ||||
| 	} | ||||
| 	matchedResources := Intersection(hardResources, potentialResources) | ||||
|  | ||||
| 	// sum the observed usage from each evaluator | ||||
| 	newUsage := api.ResourceList{} | ||||
| 	usageStatsOptions := UsageStatsOptions{Namespace: namespaceName, Scopes: scopes} | ||||
| 	for _, evaluator := range evaluators { | ||||
| 		// only trigger the evaluator if it matches a resource in the quota, otherwise, skip calculating anything | ||||
| 		if intersection := Intersection(evaluator.MatchesResources(), matchedResources); len(intersection) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		stats, err := evaluator.UsageStats(usageStatsOptions) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		newUsage = Add(newUsage, stats.Used) | ||||
| 	} | ||||
|  | ||||
| 	// mask the observed usage to only the set of resources tracked by this quota | ||||
| 	// merge our observed usage with the quota usage status | ||||
| 	// if the new usage is different than the last usage, we will need to do an update | ||||
| 	newUsage = Mask(newUsage, matchedResources) | ||||
| 	return newUsage, nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 deads2k
					deads2k