func getResourceRequirements(cpu, memory resource.Quantity) current.ResourceRequirements { res := current.ResourceRequirements{} res.Limits = current.ResourceList{} if cpu.Value() > 0 { res.Limits[current.ResourceCPU] = util.NewIntOrStringFromInt(int(cpu.Value())) } if memory.Value() > 0 { res.Limits[current.ResourceMemory] = util.NewIntOrStringFromInt(int(memory.Value())) } return res }
// syncResourceQuota runs a complete sync of current status func (rm *ResourceQuotaController) syncResourceQuota(quota api.ResourceQuota) (err error) { // quota is dirty if any part of spec hard limits differs from the status hard limits dirty := !api.Semantic.DeepEqual(quota.Spec.Hard, quota.Status.Hard) // dirty tracks if the usage status differs from the previous sync, // if so, we send a new usage with latest status // if this is our first sync, it will be dirty by default, since we need track usage dirty = dirty || (quota.Status.Hard == nil || quota.Status.Used == nil) // Create a usage object that is based on the quota resource version usage := api.ResourceQuota{ ObjectMeta: api.ObjectMeta{ Name: quota.Name, Namespace: quota.Namespace, ResourceVersion: quota.ResourceVersion, Labels: quota.Labels, Annotations: quota.Annotations}, Status: api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, }, } // set the hard values supported on the quota for k, v := range quota.Spec.Hard { usage.Status.Hard[k] = *v.Copy() } // set any last known observed status values for usage for k, v := range quota.Status.Used { usage.Status.Used[k] = *v.Copy() } set := map[api.ResourceName]bool{} for k := range usage.Status.Hard { set[k] = true } pods := &api.PodList{} if set[api.ResourcePods] || set[api.ResourceMemory] || set[api.ResourceCPU] { pods, err = rm.kubeClient.Pods(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } } filteredPods := FilterQuotaPods(pods.Items) // iterate over each resource, and update observation for k := range usage.Status.Hard { // look if there is a used value, if none, we are definitely dirty prevQuantity, found := usage.Status.Used[k] if !found { dirty = true } var value *resource.Quantity switch k { case api.ResourcePods: value = resource.NewQuantity(int64(len(filteredPods)), resource.DecimalSI) case api.ResourceMemory: val := int64(0) for _, pod := range filteredPods { val = val + PodMemory(pod).Value() } value = resource.NewQuantity(int64(val), resource.DecimalSI) case api.ResourceCPU: val := int64(0) for _, pod := range filteredPods { val = val + PodCPU(pod).MilliValue() } value = resource.NewMilliQuantity(int64(val), resource.DecimalSI) case api.ResourceServices: items, err := rm.kubeClient.Services(usage.Namespace).List(labels.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourceReplicationControllers: items, err := rm.kubeClient.ReplicationControllers(usage.Namespace).List(labels.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourceQuotas: items, err := rm.kubeClient.ResourceQuotas(usage.Namespace).List(labels.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourceSecrets: items, err := rm.kubeClient.Secrets(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourcePersistentVolumeClaims: items, err := rm.kubeClient.PersistentVolumeClaims(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) } // ignore fields we do not understand (assume another controller is tracking it) if value != nil { // see if the value has changed dirty = dirty || (value.Value() != prevQuantity.Value()) // just update the value usage.Status.Used[k] = *value } } // update the usage only if it changed if dirty { _, err = rm.kubeClient.ResourceQuotas(usage.Namespace).UpdateStatus(&usage) return err } return nil }
func validateBasicResource(quantity resource.Quantity) errs.ValidationErrorList { if quantity.Value() < 0 { return errs.ValidationErrorList{fmt.Errorf("%v is not a valid resource quantity", quantity.Value())} } return errs.ValidationErrorList{} }