mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 05:36:12 +00:00
TRICKY: dependencies: pkg/quota
This commit is contained in:
@@ -30,11 +30,11 @@ go_library(
|
|||||||
"//pkg/api/resource:go_default_library",
|
"//pkg/api/resource:go_default_library",
|
||||||
"//pkg/api/unversioned:go_default_library",
|
"//pkg/api/unversioned:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
"//pkg/client/clientset_generated/release_1_5:go_default_library",
|
||||||
"//pkg/controller/informers:go_default_library",
|
"//pkg/controller/informers:go_default_library",
|
||||||
"//pkg/kubelet/qos:go_default_library",
|
"//pkg/kubelet/qos:go_default_library",
|
||||||
"//pkg/quota:go_default_library",
|
"//pkg/quotainternal:go_default_library",
|
||||||
"//pkg/quota/generic:go_default_library",
|
"//pkg/quotainternal/generic:go_default_library",
|
||||||
"//pkg/runtime:go_default_library",
|
"//pkg/runtime:go_default_library",
|
||||||
"//pkg/util/sets:go_default_library",
|
"//pkg/util/sets:go_default_library",
|
||||||
"//pkg/util/validation/field:go_default_library",
|
"//pkg/util/validation/field:go_default_library",
|
||||||
@@ -54,7 +54,7 @@ go_test(
|
|||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/resource:go_default_library",
|
"//pkg/api/resource:go_default_library",
|
||||||
"//pkg/api/unversioned:go_default_library",
|
"//pkg/api/unversioned:go_default_library",
|
||||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
"//pkg/client/clientset_generated/release_1_5/fake:go_default_library",
|
||||||
"//pkg/quota:go_default_library",
|
"//pkg/quotainternal:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@@ -19,7 +19,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/admission"
|
"k8s.io/kubernetes/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -38,7 +39,7 @@ func NewConfigMapEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||||||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||||
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceConfigMaps),
|
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceConfigMaps),
|
||||||
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceConfigMaps),
|
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceConfigMaps),
|
||||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().ConfigMaps(namespace).List(options)
|
itemList, err := kubeClient.Core().ConfigMaps(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -24,7 +24,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
@@ -37,7 +38,7 @@ func listPersistentVolumeClaimsByNamespaceFuncUsingClient(kubeClient clientset.I
|
|||||||
// TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this.
|
// TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this.
|
||||||
// unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require
|
// unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require
|
||||||
// structured objects.
|
// structured objects.
|
||||||
return func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().PersistentVolumeClaims(namespace).List(options)
|
itemList, err := kubeClient.Core().PersistentVolumeClaims(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -75,13 +76,21 @@ func NewPersistentVolumeClaimEvaluator(kubeClient clientset.Interface, f informe
|
|||||||
|
|
||||||
// PersistentVolumeClaimUsageFunc knows how to measure usage associated with persistent volume claims
|
// PersistentVolumeClaimUsageFunc knows how to measure usage associated with persistent volume claims
|
||||||
func PersistentVolumeClaimUsageFunc(object runtime.Object) api.ResourceList {
|
func PersistentVolumeClaimUsageFunc(object runtime.Object) api.ResourceList {
|
||||||
pvc, ok := object.(*api.PersistentVolumeClaim)
|
|
||||||
if !ok {
|
|
||||||
return api.ResourceList{}
|
|
||||||
}
|
|
||||||
result := api.ResourceList{}
|
result := api.ResourceList{}
|
||||||
|
var found bool
|
||||||
|
var request resource.Quantity
|
||||||
|
|
||||||
|
switch t := object.(type) {
|
||||||
|
case *v1.PersistentVolumeClaim:
|
||||||
|
request, found = t.Spec.Resources.Requests[v1.ResourceStorage]
|
||||||
|
case *api.PersistentVolumeClaim:
|
||||||
|
request, found = t.Spec.Resources.Requests[api.ResourceStorage]
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("expect *api.PersistenVolumeClaim or *v1.PersistentVolumeClaim, got %v", t))
|
||||||
|
}
|
||||||
|
|
||||||
result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1")
|
result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1")
|
||||||
if request, found := pvc.Spec.Resources.Requests[api.ResourceStorage]; found {
|
if found {
|
||||||
result[api.ResourceRequestsStorage] = request
|
result[api.ResourceRequestsStorage] = request
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@@ -22,7 +22,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -24,8 +24,9 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
@@ -40,7 +41,7 @@ func listPodsByNamespaceFuncUsingClient(kubeClient clientset.Interface) generic.
|
|||||||
// TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this.
|
// TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this.
|
||||||
// unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require
|
// unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require
|
||||||
// structured objects.
|
// structured objects.
|
||||||
return func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().Pods(namespace).List(options)
|
itemList, err := kubeClient.Core().Pods(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -163,23 +164,32 @@ func podUsageHelper(requests api.ResourceList, limits api.ResourceList) api.Reso
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodUsageFunc knows how to measure usage associated with pods
|
func toInternalPodOrDie(obj runtime.Object) *api.Pod {
|
||||||
func PodUsageFunc(object runtime.Object) api.ResourceList {
|
pod := &api.Pod{}
|
||||||
pod, ok := object.(*api.Pod)
|
switch t := obj.(type) {
|
||||||
if !ok {
|
case *v1.Pod:
|
||||||
return api.ResourceList{}
|
if err := v1.Convert_v1_Pod_To_api_Pod(t, pod, nil); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
case *api.Pod:
|
||||||
|
pod = t
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("expect *api.Pod or *v1.Pod, got %v", t))
|
||||||
|
}
|
||||||
|
return pod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodUsageFunc knows how to measure usage associated with pods
|
||||||
|
func PodUsageFunc(obj runtime.Object) api.ResourceList {
|
||||||
|
pod := toInternalPodOrDie(obj)
|
||||||
// by convention, we do not quota pods that have reached an end-of-life state
|
// by convention, we do not quota pods that have reached an end-of-life state
|
||||||
if !QuotaPod(pod) {
|
if !QuotaPod(pod) {
|
||||||
return api.ResourceList{}
|
return api.ResourceList{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix this when we have pod level cgroups
|
|
||||||
// when we have pod level cgroups, we can just read pod level requests/limits
|
|
||||||
requests := api.ResourceList{}
|
requests := api.ResourceList{}
|
||||||
limits := api.ResourceList{}
|
limits := api.ResourceList{}
|
||||||
|
// TODO: fix this when we have pod level cgroups
|
||||||
|
// when we have pod level cgroups, we can just read pod level requests/limits
|
||||||
for i := range pod.Spec.Containers {
|
for i := range pod.Spec.Containers {
|
||||||
requests = quota.Add(requests, pod.Spec.Containers[i].Resources.Requests)
|
requests = quota.Add(requests, pod.Spec.Containers[i].Resources.Requests)
|
||||||
limits = quota.Add(limits, pod.Spec.Containers[i].Resources.Limits)
|
limits = quota.Add(limits, pod.Spec.Containers[i].Resources.Limits)
|
||||||
@@ -197,10 +207,7 @@ func PodUsageFunc(object runtime.Object) api.ResourceList {
|
|||||||
|
|
||||||
// PodMatchesScopeFunc is a function that knows how to evaluate if a pod matches a scope
|
// PodMatchesScopeFunc is a function that knows how to evaluate if a pod matches a scope
|
||||||
func PodMatchesScopeFunc(scope api.ResourceQuotaScope, object runtime.Object) bool {
|
func PodMatchesScopeFunc(scope api.ResourceQuotaScope, object runtime.Object) bool {
|
||||||
pod, ok := object.(*api.Pod)
|
pod := toInternalPodOrDie(object)
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
switch scope {
|
switch scope {
|
||||||
case api.ResourceQuotaScopeTerminating:
|
case api.ResourceQuotaScopeTerminating:
|
||||||
return isTerminating(pod)
|
return isTerminating(pod)
|
||||||
@@ -215,7 +222,7 @@ func PodMatchesScopeFunc(scope api.ResourceQuotaScope, object runtime.Object) bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isBestEffort(pod *api.Pod) bool {
|
func isBestEffort(pod *api.Pod) bool {
|
||||||
return qos.GetPodQOS(pod) == qos.BestEffort
|
return qos.InternalGetPodQOS(pod) == qos.BestEffort
|
||||||
}
|
}
|
||||||
|
|
||||||
func isTerminating(pod *api.Pod) bool {
|
func isTerminating(pod *api.Pod) bool {
|
||||||
@@ -228,7 +235,11 @@ func isTerminating(pod *api.Pod) bool {
|
|||||||
// QuotaPod returns true if the pod is eligible to track against a quota
|
// QuotaPod returns true if the pod is eligible to track against a quota
|
||||||
// if it's not in a terminal state according to its phase.
|
// if it's not in a terminal state according to its phase.
|
||||||
func QuotaPod(pod *api.Pod) bool {
|
func QuotaPod(pod *api.Pod) bool {
|
||||||
// see GetPhase in kubelet.go for details on how it covers all restart policy conditions
|
|
||||||
// https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kubelet.go#L3001
|
|
||||||
return !(api.PodFailed == pod.Status.Phase || api.PodSucceeded == pod.Status.Phase)
|
return !(api.PodFailed == pod.Status.Phase || api.PodSucceeded == pod.Status.Phase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuotaV1Pod returns true if the pod is eligible to track against a quota
|
||||||
|
// if it's not in a terminal state according to its phase.
|
||||||
|
func QuotaV1Pod(pod *v1.Pod) bool {
|
||||||
|
return !(v1.PodFailed == pod.Status.Phase || v1.PodSucceeded == pod.Status.Phase)
|
||||||
|
}
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
|
@@ -19,7 +19,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/admission"
|
"k8s.io/kubernetes/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -38,7 +39,7 @@ func NewReplicationControllerEvaluator(kubeClient clientset.Interface) quota.Eva
|
|||||||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||||
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceReplicationControllers),
|
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceReplicationControllers),
|
||||||
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceReplicationControllers),
|
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceReplicationControllers),
|
||||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().ReplicationControllers(namespace).List(options)
|
itemList, err := kubeClient.Core().ReplicationControllers(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -19,7 +19,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/admission"
|
"k8s.io/kubernetes/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -38,7 +39,7 @@ func NewResourceQuotaEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||||||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||||
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceQuotas),
|
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceQuotas),
|
||||||
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceQuotas),
|
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceQuotas),
|
||||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().ResourceQuotas(namespace).List(options)
|
itemList, err := kubeClient.Core().ResourceQuotas(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -19,7 +19,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/admission"
|
"k8s.io/kubernetes/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -38,7 +39,7 @@ func NewSecretEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||||||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||||
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceSecrets),
|
ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceSecrets),
|
||||||
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceSecrets),
|
UsageFunc: generic.ObjectCountUsageFunc(api.ResourceSecrets),
|
||||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().Secrets(namespace).List(options)
|
itemList, err := kubeClient.Core().Secrets(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -23,7 +23,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/admission"
|
"k8s.io/kubernetes/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/generic"
|
"k8s.io/kubernetes/pkg/quota/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -48,7 +49,7 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||||||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||||
ConstraintsFunc: ServiceConstraintsFunc,
|
ConstraintsFunc: ServiceConstraintsFunc,
|
||||||
UsageFunc: ServiceUsageFunc,
|
UsageFunc: ServiceUsageFunc,
|
||||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
itemList, err := kubeClient.Core().Services(namespace).List(options)
|
itemList, err := kubeClient.Core().Services(namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -65,42 +66,54 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||||||
// ServiceUsageFunc knows how to measure usage associated with services
|
// ServiceUsageFunc knows how to measure usage associated with services
|
||||||
func ServiceUsageFunc(object runtime.Object) api.ResourceList {
|
func ServiceUsageFunc(object runtime.Object) api.ResourceList {
|
||||||
result := api.ResourceList{}
|
result := api.ResourceList{}
|
||||||
if service, ok := object.(*api.Service); ok {
|
var serviceType api.ServiceType
|
||||||
|
var ports int
|
||||||
|
|
||||||
|
switch t := object.(type) {
|
||||||
|
case *v1.Service:
|
||||||
|
serviceType = api.ServiceType(t.Spec.Type)
|
||||||
|
ports = len(t.Spec.Ports)
|
||||||
|
case *api.Service:
|
||||||
|
serviceType = t.Spec.Type
|
||||||
|
ports = len(t.Spec.Ports)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("expect *api.Service or *v1.Service, got %v", t))
|
||||||
|
}
|
||||||
|
|
||||||
// default service usage
|
// default service usage
|
||||||
result[api.ResourceServices] = resource.MustParse("1")
|
result[api.ResourceServices] = resource.MustParse("1")
|
||||||
result[api.ResourceServicesLoadBalancers] = resource.MustParse("0")
|
result[api.ResourceServicesLoadBalancers] = resource.MustParse("0")
|
||||||
result[api.ResourceServicesNodePorts] = resource.MustParse("0")
|
result[api.ResourceServicesNodePorts] = resource.MustParse("0")
|
||||||
switch service.Spec.Type {
|
switch serviceType {
|
||||||
case api.ServiceTypeNodePort:
|
case api.ServiceTypeNodePort:
|
||||||
// node port services need to count node ports
|
// node port services need to count node ports
|
||||||
value := resource.NewQuantity(int64(len(service.Spec.Ports)), resource.DecimalSI)
|
value := resource.NewQuantity(int64(ports), resource.DecimalSI)
|
||||||
result[api.ResourceServicesNodePorts] = *value
|
result[api.ResourceServicesNodePorts] = *value
|
||||||
case api.ServiceTypeLoadBalancer:
|
case api.ServiceTypeLoadBalancer:
|
||||||
// load balancer services need to count load balancers
|
// load balancer services need to count load balancers
|
||||||
result[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
|
result[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuotaServiceType returns true if the service type is eligible to track against a quota
|
// QuotaServiceType returns true if the service type is eligible to track against a quota
|
||||||
func QuotaServiceType(service *api.Service) bool {
|
func QuotaServiceType(service *v1.Service) bool {
|
||||||
switch service.Spec.Type {
|
switch service.Spec.Type {
|
||||||
case api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer:
|
case v1.ServiceTypeNodePort, v1.ServiceTypeLoadBalancer:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetQuotaServiceType returns ServiceType if the service type is eligible to track against a quota, nor return ""
|
//GetQuotaServiceType returns ServiceType if the service type is eligible to track against a quota, nor return ""
|
||||||
func GetQuotaServiceType(service *api.Service) api.ServiceType {
|
func GetQuotaServiceType(service *v1.Service) v1.ServiceType {
|
||||||
switch service.Spec.Type {
|
switch service.Spec.Type {
|
||||||
case api.ServiceTypeNodePort:
|
case v1.ServiceTypeNodePort:
|
||||||
return api.ServiceTypeNodePort
|
return v1.ServiceTypeNodePort
|
||||||
case api.ServiceTypeLoadBalancer:
|
case v1.ServiceTypeLoadBalancer:
|
||||||
return api.ServiceTypeLoadBalancer
|
return v1.ServiceTypeLoadBalancer
|
||||||
}
|
}
|
||||||
return api.ServiceType("")
|
return v1.ServiceType("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceConstraintsFunc verifies that all required resources are captured in service usage.
|
// ServiceConstraintsFunc verifies that all required resources are captured in service usage.
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ go_library(
|
|||||||
"//pkg/api/unversioned:go_default_library",
|
"//pkg/api/unversioned:go_default_library",
|
||||||
"//pkg/controller/informers:go_default_library",
|
"//pkg/controller/informers:go_default_library",
|
||||||
"//pkg/labels:go_default_library",
|
"//pkg/labels:go_default_library",
|
||||||
"//pkg/quota:go_default_library",
|
"//pkg/quotainternal:go_default_library",
|
||||||
"//pkg/runtime:go_default_library",
|
"//pkg/runtime:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
@@ -31,12 +32,16 @@ import (
|
|||||||
|
|
||||||
// ListResourceUsingInformerFunc returns a listing function based on the shared informer factory for the specified resource.
|
// ListResourceUsingInformerFunc returns a listing function based on the shared informer factory for the specified resource.
|
||||||
func ListResourceUsingInformerFunc(f informers.SharedInformerFactory, groupResource unversioned.GroupResource) ListFuncByNamespace {
|
func ListResourceUsingInformerFunc(f informers.SharedInformerFactory, groupResource unversioned.GroupResource) ListFuncByNamespace {
|
||||||
return func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) {
|
||||||
|
labelSelector, err := labels.Parse(options.LabelSelector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
informer, err := f.ForResource(groupResource)
|
informer, err := f.ForResource(groupResource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return informer.Lister().ByNamespace(namespace).List(options.LabelSelector)
|
return informer.Lister().ByNamespace(namespace).List(labelSelector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +52,7 @@ type ConstraintsFunc func(required []api.ResourceName, item runtime.Object) erro
|
|||||||
type GetFuncByNamespace func(namespace, name string) (runtime.Object, error)
|
type GetFuncByNamespace func(namespace, name string) (runtime.Object, error)
|
||||||
|
|
||||||
// ListFuncByNamespace knows how to list resources in a namespace
|
// ListFuncByNamespace knows how to list resources in a namespace
|
||||||
type ListFuncByNamespace func(namespace string, options api.ListOptions) ([]runtime.Object, error)
|
type ListFuncByNamespace func(namespace string, options v1.ListOptions) ([]runtime.Object, error)
|
||||||
|
|
||||||
// MatchesScopeFunc knows how to evaluate if an object matches a scope
|
// MatchesScopeFunc knows how to evaluate if an object matches a scope
|
||||||
type MatchesScopeFunc func(scope api.ResourceQuotaScope, object runtime.Object) bool
|
type MatchesScopeFunc func(scope api.ResourceQuotaScope, object runtime.Object) bool
|
||||||
@@ -183,8 +188,8 @@ func (g *GenericEvaluator) UsageStats(options quota.UsageStatsOptions) (quota.Us
|
|||||||
for _, resourceName := range g.MatchedResourceNames {
|
for _, resourceName := range g.MatchedResourceNames {
|
||||||
result.Used[resourceName] = resource.MustParse("0")
|
result.Used[resourceName] = resource.MustParse("0")
|
||||||
}
|
}
|
||||||
items, err := g.ListFuncByNamespace(options.Namespace, api.ListOptions{
|
items, err := g.ListFuncByNamespace(options.Namespace, v1.ListOptions{
|
||||||
LabelSelector: labels.Everything(),
|
LabelSelector: labels.Everything().String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("%s: Failed to list %v: %v", g.Name, g.GroupKind(), err)
|
return result, fmt.Errorf("%s: Failed to list %v: %v", g.Name, g.GroupKind(), err)
|
||||||
|
@@ -15,9 +15,9 @@ go_library(
|
|||||||
srcs = ["registry.go"],
|
srcs = ["registry.go"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
"//pkg/client/clientset_generated/release_1_5:go_default_library",
|
||||||
"//pkg/controller/informers:go_default_library",
|
"//pkg/controller/informers:go_default_library",
|
||||||
"//pkg/quota:go_default_library",
|
"//pkg/quotainternal:go_default_library",
|
||||||
"//pkg/quota/evaluator/core:go_default_library",
|
"//pkg/quotainternal/evaluator/core:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
package install
|
package install
|
||||||
|
|
||||||
import (
|
import (
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
"k8s.io/kubernetes/pkg/quota/evaluator/core"
|
"k8s.io/kubernetes/pkg/quota/evaluator/core"
|
||||||
|
@@ -19,6 +19,7 @@ package quota
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,6 +46,29 @@ func Equals(a api.ResourceList, b api.ResourceList) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// V1Equals returns true if the two lists are equivalent
|
||||||
|
func V1Equals(a v1.ResourceList, b v1.ResourceList) bool {
|
||||||
|
for key, value1 := range a {
|
||||||
|
value2, found := b[key]
|
||||||
|
if !found {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if value1.Cmp(value2) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for key, value1 := range b {
|
||||||
|
value2, found := a[key]
|
||||||
|
if !found {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if value1.Cmp(value2) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// LessThanOrEqual returns true if a < b for each key in b
|
// LessThanOrEqual returns true if a < b for each key in b
|
||||||
// If false, it returns the keys in a that exceeded b
|
// If false, it returns the keys in a that exceeded b
|
||||||
func LessThanOrEqual(a api.ResourceList, b api.ResourceList) (bool, []api.ResourceName) {
|
func LessThanOrEqual(a api.ResourceList, b api.ResourceList) (bool, []api.ResourceName) {
|
||||||
|
Reference in New Issue
Block a user