From 29bb02b94bd16cf30b057ec346afe3e301075df5 Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Thu, 17 Feb 2022 15:18:43 +0800 Subject: [PATCH 1/2] Add FederatedResourceQuota API Signed-off-by: RainbowMango --- .../v1alpha1/federatedresourcequota_types.go | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 pkg/apis/policy/v1alpha1/federatedresourcequota_types.go diff --git a/pkg/apis/policy/v1alpha1/federatedresourcequota_types.go b/pkg/apis/policy/v1alpha1/federatedresourcequota_types.go new file mode 100644 index 000000000..849d52bdc --- /dev/null +++ b/pkg/apis/policy/v1alpha1/federatedresourcequota_types.go @@ -0,0 +1,95 @@ +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion + +// FederatedResourceQuota sets aggregate quota restrictions enforced per namespace across all clusters. +type FederatedResourceQuota struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired quota. + // +required + Spec FederatedResourceQuotaSpec `json:"spec"` + + // Status defines the actual enforced quota and its current usage. + // +optional + Status FederatedResourceQuotaStatus `json:"status,omitempty"` +} + +// FederatedResourceQuotaSpec defines the desired hard limits to enforce for Quota. +type FederatedResourceQuotaSpec struct { + // Overall is the set of desired hard limits for each named resource. + // +required + Overall corev1.ResourceList `json:"overall"` + + // StaticAssignments represents the subset of desired hard limits for each cluster. + // Note: for clusters not present in this list, Karmada will set an empty ResourceQuota to them, which means these + // clusters will have no quotas in the referencing namespace. + // +optional + StaticAssignments []StaticClusterAssignment `json:"staticAssignments,omitempty"` + + // DynamicAssignments represents the rule about how to assign and ensure the quota for each cluster. + // E.g. + // - The rule about how to assign the total amount of quotas(specified by Overall) to Clusters. + // - The rule about how to balance the quota between clusters in a dynamic way. + // - The rule about how to prevent workload from scheduling to cluster without quota. + // - The rule about how to prevent workload from creating to Karmada control plane. + // - The rule about how to cooperate with FederatedHPA to scale workloads. + // + // Note: We are in the progress of gathering user cases, if you are interested in + // this feature/capacity, please feel free to let us know. + // + // +optional + // DynamicAssignments []DynamicClusterAssignment `json:"dynamicAssignments,omitempty"` +} + +// StaticClusterAssignment represents the set of desired hard limits for a specific cluster. +type StaticClusterAssignment struct { + // ClusterName is the name of the cluster the limits enforce to. + // +required + ClusterName string `json:"clusterName"` + + // Hard is the set of desired hard limits for each named resource. + // +required + Hard corev1.ResourceList `json:"hard"` +} + +// FederatedResourceQuotaStatus defines the enforced hard limits and observed use. +type FederatedResourceQuotaStatus struct { + // Overall is the set of enforced hard limits for each named resource. + // +optional + Overall corev1.ResourceList `json:"overall,omitempty"` + + // OverallUsed is the current observed total usage of the resource in the namespace. + // +optional + OverallUsed corev1.ResourceList `json:"overallUsed,omitempty"` + + // AggregatedStatus is the observed quota usage of each cluster. + // +optional + AggregatedStatus []ClusterQuotaStatus `json:"aggregatedStatus,omitempty"` +} + +// ClusterQuotaStatus represents the set of desired limits and observed usage for a specific cluster. +type ClusterQuotaStatus struct { + // ClusterName is the name of the cluster the limits enforce to. + // +required + ClusterName string `json:"clusterName"` + + corev1.ResourceQuotaStatus `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// FederatedResourceQuotaList contains a list of FederatedResourceQuota. +type FederatedResourceQuotaList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []FederatedResourceQuota `json:"items"` +} From e102ad37bdb7dd4c29cb146c5bbcb91250fd433e Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Tue, 22 Feb 2022 15:27:17 +0800 Subject: [PATCH 2/2] Generates API files Signed-off-by: RainbowMango --- ...cy.karmada.io_federatedresourcequotas.yaml | 151 +++++++++++++++ .../policy/v1alpha1/zz_generated.deepcopy.go | 168 ++++++++++++++++ .../policy/v1alpha1/zz_generated.register.go | 2 + .../fake/fake_federatedresourcequota.go | 126 ++++++++++++ .../v1alpha1/fake/fake_policy_client.go | 4 + .../policy/v1alpha1/federatedresourcequota.go | 179 ++++++++++++++++++ .../policy/v1alpha1/generated_expansion.go | 2 + .../typed/policy/v1alpha1/policy_client.go | 5 + .../informers/externalversions/generic.go | 2 + .../policy/v1alpha1/federatedresourcequota.go | 74 ++++++++ .../policy/v1alpha1/interface.go | 7 + .../policy/v1alpha1/expansion_generated.go | 8 + .../policy/v1alpha1/federatedresourcequota.go | 83 ++++++++ 13 files changed, 811 insertions(+) create mode 100644 charts/_crds/bases/policy.karmada.io_federatedresourcequotas.yaml create mode 100644 pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_federatedresourcequota.go create mode 100644 pkg/generated/clientset/versioned/typed/policy/v1alpha1/federatedresourcequota.go create mode 100644 pkg/generated/informers/externalversions/policy/v1alpha1/federatedresourcequota.go create mode 100644 pkg/generated/listers/policy/v1alpha1/federatedresourcequota.go diff --git a/charts/_crds/bases/policy.karmada.io_federatedresourcequotas.yaml b/charts/_crds/bases/policy.karmada.io_federatedresourcequotas.yaml new file mode 100644 index 000000000..a425ae811 --- /dev/null +++ b/charts/_crds/bases/policy.karmada.io_federatedresourcequotas.yaml @@ -0,0 +1,151 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: federatedresourcequotas.policy.karmada.io +spec: + group: policy.karmada.io + names: + kind: FederatedResourceQuota + listKind: FederatedResourceQuotaList + plural: federatedresourcequotas + singular: federatedresourcequota + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: FederatedResourceQuota sets aggregate quota restrictions enforced + per namespace across all clusters. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired quota. + properties: + overall: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Overall is the set of desired hard limits for each named + resource. + type: object + staticAssignments: + description: 'StaticAssignments represents the subset of desired hard + limits for each cluster. Note: for clusters not present in this + list, Karmada will set an empty ResourceQuota to them, which means + these clusters will have no quotas in the referencing namespace.' + items: + description: StaticClusterAssignment represents the set of desired + hard limits for a specific cluster. + properties: + clusterName: + description: ClusterName is the name of the cluster the limits + enforce to. + type: string + hard: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Hard is the set of desired hard limits for each + named resource. + type: object + required: + - clusterName + - hard + type: object + type: array + required: + - overall + type: object + status: + description: Status defines the actual enforced quota and its current + usage. + properties: + aggregatedStatus: + description: AggregatedStatus is the observed quota usage of each + cluster. + items: + description: ClusterQuotaStatus represents the set of desired limits + and observed usage for a specific cluster. + properties: + clusterName: + description: ClusterName is the name of the cluster the limits + enforce to. + type: string + hard: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Hard is the set of enforced hard limits for each + named resource. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/' + type: object + used: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Used is the current observed total usage of the + resource in the namespace. + type: object + required: + - clusterName + type: object + type: array + overall: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Overall is the set of enforced hard limits for each named + resource. + type: object + overallUsed: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: OverallUsed is the current observed total usage of the + resource in the namespace. + type: object + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/apis/policy/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/policy/v1alpha1/zz_generated.deepcopy.go index d8e45bd31..10c324b99 100644 --- a/pkg/apis/policy/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/policy/v1alpha1/zz_generated.deepcopy.go @@ -190,6 +190,23 @@ func (in *ClusterPropagationPolicyList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterQuotaStatus) DeepCopyInto(out *ClusterQuotaStatus) { + *out = *in + in.ResourceQuotaStatus.DeepCopyInto(&out.ResourceQuotaStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterQuotaStatus. +func (in *ClusterQuotaStatus) DeepCopy() *ClusterQuotaStatus { + if in == nil { + return nil + } + out := new(ClusterQuotaStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommandArgsOverrider) DeepCopyInto(out *CommandArgsOverrider) { *out = *in @@ -211,6 +228,134 @@ func (in *CommandArgsOverrider) DeepCopy() *CommandArgsOverrider { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FederatedResourceQuota) DeepCopyInto(out *FederatedResourceQuota) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuota. +func (in *FederatedResourceQuota) DeepCopy() *FederatedResourceQuota { + if in == nil { + return nil + } + out := new(FederatedResourceQuota) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FederatedResourceQuota) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FederatedResourceQuotaList) DeepCopyInto(out *FederatedResourceQuotaList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FederatedResourceQuota, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaList. +func (in *FederatedResourceQuotaList) DeepCopy() *FederatedResourceQuotaList { + if in == nil { + return nil + } + out := new(FederatedResourceQuotaList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FederatedResourceQuotaList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FederatedResourceQuotaSpec) DeepCopyInto(out *FederatedResourceQuotaSpec) { + *out = *in + if in.Overall != nil { + in, out := &in.Overall, &out.Overall + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.StaticAssignments != nil { + in, out := &in.StaticAssignments, &out.StaticAssignments + *out = make([]StaticClusterAssignment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaSpec. +func (in *FederatedResourceQuotaSpec) DeepCopy() *FederatedResourceQuotaSpec { + if in == nil { + return nil + } + out := new(FederatedResourceQuotaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FederatedResourceQuotaStatus) DeepCopyInto(out *FederatedResourceQuotaStatus) { + *out = *in + if in.Overall != nil { + in, out := &in.Overall, &out.Overall + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.OverallUsed != nil { + in, out := &in.OverallUsed, &out.OverallUsed + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.AggregatedStatus != nil { + in, out := &in.AggregatedStatus, &out.AggregatedStatus + *out = make([]ClusterQuotaStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaStatus. +func (in *FederatedResourceQuotaStatus) DeepCopy() *FederatedResourceQuotaStatus { + if in == nil { + return nil + } + out := new(FederatedResourceQuotaStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FieldSelector) DeepCopyInto(out *FieldSelector) { *out = *in @@ -635,6 +780,29 @@ func (in *SpreadConstraint) DeepCopy() *SpreadConstraint { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StaticClusterAssignment) DeepCopyInto(out *StaticClusterAssignment) { + *out = *in + if in.Hard != nil { + in, out := &in.Hard, &out.Hard + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticClusterAssignment. +func (in *StaticClusterAssignment) DeepCopy() *StaticClusterAssignment { + if in == nil { + return nil + } + out := new(StaticClusterAssignment) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StaticClusterWeight) DeepCopyInto(out *StaticClusterWeight) { *out = *in diff --git a/pkg/apis/policy/v1alpha1/zz_generated.register.go b/pkg/apis/policy/v1alpha1/zz_generated.register.go index d836e24cf..b7048d8d6 100644 --- a/pkg/apis/policy/v1alpha1/zz_generated.register.go +++ b/pkg/apis/policy/v1alpha1/zz_generated.register.go @@ -46,6 +46,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ClusterOverridePolicyList{}, &ClusterPropagationPolicy{}, &ClusterPropagationPolicyList{}, + &FederatedResourceQuota{}, + &FederatedResourceQuotaList{}, &OverridePolicy{}, &OverridePolicyList{}, &PropagationPolicy{}, diff --git a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_federatedresourcequota.go b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_federatedresourcequota.go new file mode 100644 index 000000000..f1365f0f7 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_federatedresourcequota.go @@ -0,0 +1,126 @@ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeFederatedResourceQuotas implements FederatedResourceQuotaInterface +type FakeFederatedResourceQuotas struct { + Fake *FakePolicyV1alpha1 + ns string +} + +var federatedresourcequotasResource = schema.GroupVersionResource{Group: "policy.karmada.io", Version: "v1alpha1", Resource: "federatedresourcequotas"} + +var federatedresourcequotasKind = schema.GroupVersionKind{Group: "policy.karmada.io", Version: "v1alpha1", Kind: "FederatedResourceQuota"} + +// Get takes name of the federatedResourceQuota, and returns the corresponding federatedResourceQuota object, and an error if there is any. +func (c *FakeFederatedResourceQuotas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(federatedresourcequotasResource, c.ns, name), &v1alpha1.FederatedResourceQuota{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.FederatedResourceQuota), err +} + +// List takes label and field selectors, and returns the list of FederatedResourceQuotas that match those selectors. +func (c *FakeFederatedResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.FederatedResourceQuotaList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(federatedresourcequotasResource, federatedresourcequotasKind, c.ns, opts), &v1alpha1.FederatedResourceQuotaList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.FederatedResourceQuotaList{ListMeta: obj.(*v1alpha1.FederatedResourceQuotaList).ListMeta} + for _, item := range obj.(*v1alpha1.FederatedResourceQuotaList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested federatedResourceQuotas. +func (c *FakeFederatedResourceQuotas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(federatedresourcequotasResource, c.ns, opts)) + +} + +// Create takes the representation of a federatedResourceQuota and creates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any. +func (c *FakeFederatedResourceQuotas) Create(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.CreateOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(federatedresourcequotasResource, c.ns, federatedResourceQuota), &v1alpha1.FederatedResourceQuota{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.FederatedResourceQuota), err +} + +// Update takes the representation of a federatedResourceQuota and updates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any. +func (c *FakeFederatedResourceQuotas) Update(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(federatedresourcequotasResource, c.ns, federatedResourceQuota), &v1alpha1.FederatedResourceQuota{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.FederatedResourceQuota), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeFederatedResourceQuotas) UpdateStatus(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1alpha1.FederatedResourceQuota, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(federatedresourcequotasResource, "status", c.ns, federatedResourceQuota), &v1alpha1.FederatedResourceQuota{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.FederatedResourceQuota), err +} + +// Delete takes name of the federatedResourceQuota and deletes it. Returns an error if one occurs. +func (c *FakeFederatedResourceQuotas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(federatedresourcequotasResource, c.ns, name, opts), &v1alpha1.FederatedResourceQuota{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeFederatedResourceQuotas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(federatedresourcequotasResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.FederatedResourceQuotaList{}) + return err +} + +// Patch applies the patch and returns the patched federatedResourceQuota. +func (c *FakeFederatedResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.FederatedResourceQuota, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(federatedresourcequotasResource, c.ns, name, pt, data, subresources...), &v1alpha1.FederatedResourceQuota{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.FederatedResourceQuota), err +} diff --git a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_policy_client.go b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_policy_client.go index df0b85620..984c430f5 100644 --- a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_policy_client.go +++ b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/fake/fake_policy_client.go @@ -20,6 +20,10 @@ func (c *FakePolicyV1alpha1) ClusterPropagationPolicies() v1alpha1.ClusterPropag return &FakeClusterPropagationPolicies{c} } +func (c *FakePolicyV1alpha1) FederatedResourceQuotas(namespace string) v1alpha1.FederatedResourceQuotaInterface { + return &FakeFederatedResourceQuotas{c, namespace} +} + func (c *FakePolicyV1alpha1) OverridePolicies(namespace string) v1alpha1.OverridePolicyInterface { return &FakeOverridePolicies{c, namespace} } diff --git a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/federatedresourcequota.go b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/federatedresourcequota.go new file mode 100644 index 000000000..042bbd6d3 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/federatedresourcequota.go @@ -0,0 +1,179 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + scheme "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// FederatedResourceQuotasGetter has a method to return a FederatedResourceQuotaInterface. +// A group's client should implement this interface. +type FederatedResourceQuotasGetter interface { + FederatedResourceQuotas(namespace string) FederatedResourceQuotaInterface +} + +// FederatedResourceQuotaInterface has methods to work with FederatedResourceQuota resources. +type FederatedResourceQuotaInterface interface { + Create(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.CreateOptions) (*v1alpha1.FederatedResourceQuota, error) + Update(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1alpha1.FederatedResourceQuota, error) + UpdateStatus(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1alpha1.FederatedResourceQuota, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.FederatedResourceQuota, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.FederatedResourceQuotaList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.FederatedResourceQuota, err error) + FederatedResourceQuotaExpansion +} + +// federatedResourceQuotas implements FederatedResourceQuotaInterface +type federatedResourceQuotas struct { + client rest.Interface + ns string +} + +// newFederatedResourceQuotas returns a FederatedResourceQuotas +func newFederatedResourceQuotas(c *PolicyV1alpha1Client, namespace string) *federatedResourceQuotas { + return &federatedResourceQuotas{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the federatedResourceQuota, and returns the corresponding federatedResourceQuota object, and an error if there is any. +func (c *federatedResourceQuotas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + result = &v1alpha1.FederatedResourceQuota{} + err = c.client.Get(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of FederatedResourceQuotas that match those selectors. +func (c *federatedResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.FederatedResourceQuotaList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.FederatedResourceQuotaList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested federatedResourceQuotas. +func (c *federatedResourceQuotas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a federatedResourceQuota and creates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any. +func (c *federatedResourceQuotas) Create(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.CreateOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + result = &v1alpha1.FederatedResourceQuota{} + err = c.client.Post(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(federatedResourceQuota). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a federatedResourceQuota and updates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any. +func (c *federatedResourceQuotas) Update(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + result = &v1alpha1.FederatedResourceQuota{} + err = c.client.Put(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + Name(federatedResourceQuota.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(federatedResourceQuota). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *federatedResourceQuotas) UpdateStatus(ctx context.Context, federatedResourceQuota *v1alpha1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1alpha1.FederatedResourceQuota, err error) { + result = &v1alpha1.FederatedResourceQuota{} + err = c.client.Put(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + Name(federatedResourceQuota.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(federatedResourceQuota). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the federatedResourceQuota and deletes it. Returns an error if one occurs. +func (c *federatedResourceQuotas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *federatedResourceQuotas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("federatedresourcequotas"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched federatedResourceQuota. +func (c *federatedResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.FederatedResourceQuota, err error) { + result = &v1alpha1.FederatedResourceQuota{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("federatedresourcequotas"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/generated_expansion.go index 77cc117a1..a10ba49e9 100644 --- a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/generated_expansion.go @@ -6,6 +6,8 @@ type ClusterOverridePolicyExpansion interface{} type ClusterPropagationPolicyExpansion interface{} +type FederatedResourceQuotaExpansion interface{} + type OverridePolicyExpansion interface{} type PropagationPolicyExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/policy_client.go b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/policy_client.go index 07e4186f9..a1611d96c 100644 --- a/pkg/generated/clientset/versioned/typed/policy/v1alpha1/policy_client.go +++ b/pkg/generated/clientset/versioned/typed/policy/v1alpha1/policy_client.go @@ -14,6 +14,7 @@ type PolicyV1alpha1Interface interface { RESTClient() rest.Interface ClusterOverridePoliciesGetter ClusterPropagationPoliciesGetter + FederatedResourceQuotasGetter OverridePoliciesGetter PropagationPoliciesGetter } @@ -31,6 +32,10 @@ func (c *PolicyV1alpha1Client) ClusterPropagationPolicies() ClusterPropagationPo return newClusterPropagationPolicies(c) } +func (c *PolicyV1alpha1Client) FederatedResourceQuotas(namespace string) FederatedResourceQuotaInterface { + return newFederatedResourceQuotas(c, namespace) +} + func (c *PolicyV1alpha1Client) OverridePolicies(namespace string) OverridePolicyInterface { return newOverridePolicies(c, namespace) } diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index 27047aad4..cc5251808 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -53,6 +53,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().ClusterOverridePolicies().Informer()}, nil case policyv1alpha1.SchemeGroupVersion.WithResource("clusterpropagationpolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().ClusterPropagationPolicies().Informer()}, nil + case policyv1alpha1.SchemeGroupVersion.WithResource("federatedresourcequotas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().FederatedResourceQuotas().Informer()}, nil case policyv1alpha1.SchemeGroupVersion.WithResource("overridepolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().OverridePolicies().Informer()}, nil case policyv1alpha1.SchemeGroupVersion.WithResource("propagationpolicies"): diff --git a/pkg/generated/informers/externalversions/policy/v1alpha1/federatedresourcequota.go b/pkg/generated/informers/externalversions/policy/v1alpha1/federatedresourcequota.go new file mode 100644 index 000000000..01eb4b592 --- /dev/null +++ b/pkg/generated/informers/externalversions/policy/v1alpha1/federatedresourcequota.go @@ -0,0 +1,74 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + versioned "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" + internalinterfaces "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/karmada-io/karmada/pkg/generated/listers/policy/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// FederatedResourceQuotaInformer provides access to a shared informer and lister for +// FederatedResourceQuotas. +type FederatedResourceQuotaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.FederatedResourceQuotaLister +} + +type federatedResourceQuotaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewFederatedResourceQuotaInformer constructs a new informer for FederatedResourceQuota type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFederatedResourceQuotaInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredFederatedResourceQuotaInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredFederatedResourceQuotaInformer constructs a new informer for FederatedResourceQuota type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredFederatedResourceQuotaInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().FederatedResourceQuotas(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().FederatedResourceQuotas(namespace).Watch(context.TODO(), options) + }, + }, + &policyv1alpha1.FederatedResourceQuota{}, + resyncPeriod, + indexers, + ) +} + +func (f *federatedResourceQuotaInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredFederatedResourceQuotaInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *federatedResourceQuotaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyv1alpha1.FederatedResourceQuota{}, f.defaultInformer) +} + +func (f *federatedResourceQuotaInformer) Lister() v1alpha1.FederatedResourceQuotaLister { + return v1alpha1.NewFederatedResourceQuotaLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/policy/v1alpha1/interface.go b/pkg/generated/informers/externalversions/policy/v1alpha1/interface.go index 74e472f9d..2634d3298 100644 --- a/pkg/generated/informers/externalversions/policy/v1alpha1/interface.go +++ b/pkg/generated/informers/externalversions/policy/v1alpha1/interface.go @@ -12,6 +12,8 @@ type Interface interface { ClusterOverridePolicies() ClusterOverridePolicyInformer // ClusterPropagationPolicies returns a ClusterPropagationPolicyInformer. ClusterPropagationPolicies() ClusterPropagationPolicyInformer + // FederatedResourceQuotas returns a FederatedResourceQuotaInformer. + FederatedResourceQuotas() FederatedResourceQuotaInformer // OverridePolicies returns a OverridePolicyInformer. OverridePolicies() OverridePolicyInformer // PropagationPolicies returns a PropagationPolicyInformer. @@ -39,6 +41,11 @@ func (v *version) ClusterPropagationPolicies() ClusterPropagationPolicyInformer return &clusterPropagationPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// FederatedResourceQuotas returns a FederatedResourceQuotaInformer. +func (v *version) FederatedResourceQuotas() FederatedResourceQuotaInformer { + return &federatedResourceQuotaInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // OverridePolicies returns a OverridePolicyInformer. func (v *version) OverridePolicies() OverridePolicyInformer { return &overridePolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/generated/listers/policy/v1alpha1/expansion_generated.go b/pkg/generated/listers/policy/v1alpha1/expansion_generated.go index cc58c27c6..893988c8b 100644 --- a/pkg/generated/listers/policy/v1alpha1/expansion_generated.go +++ b/pkg/generated/listers/policy/v1alpha1/expansion_generated.go @@ -10,6 +10,14 @@ type ClusterOverridePolicyListerExpansion interface{} // ClusterPropagationPolicyLister. type ClusterPropagationPolicyListerExpansion interface{} +// FederatedResourceQuotaListerExpansion allows custom methods to be added to +// FederatedResourceQuotaLister. +type FederatedResourceQuotaListerExpansion interface{} + +// FederatedResourceQuotaNamespaceListerExpansion allows custom methods to be added to +// FederatedResourceQuotaNamespaceLister. +type FederatedResourceQuotaNamespaceListerExpansion interface{} + // OverridePolicyListerExpansion allows custom methods to be added to // OverridePolicyLister. type OverridePolicyListerExpansion interface{} diff --git a/pkg/generated/listers/policy/v1alpha1/federatedresourcequota.go b/pkg/generated/listers/policy/v1alpha1/federatedresourcequota.go new file mode 100644 index 000000000..3b65e4c8b --- /dev/null +++ b/pkg/generated/listers/policy/v1alpha1/federatedresourcequota.go @@ -0,0 +1,83 @@ +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// FederatedResourceQuotaLister helps list FederatedResourceQuotas. +// All objects returned here must be treated as read-only. +type FederatedResourceQuotaLister interface { + // List lists all FederatedResourceQuotas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.FederatedResourceQuota, err error) + // FederatedResourceQuotas returns an object that can list and get FederatedResourceQuotas. + FederatedResourceQuotas(namespace string) FederatedResourceQuotaNamespaceLister + FederatedResourceQuotaListerExpansion +} + +// federatedResourceQuotaLister implements the FederatedResourceQuotaLister interface. +type federatedResourceQuotaLister struct { + indexer cache.Indexer +} + +// NewFederatedResourceQuotaLister returns a new FederatedResourceQuotaLister. +func NewFederatedResourceQuotaLister(indexer cache.Indexer) FederatedResourceQuotaLister { + return &federatedResourceQuotaLister{indexer: indexer} +} + +// List lists all FederatedResourceQuotas in the indexer. +func (s *federatedResourceQuotaLister) List(selector labels.Selector) (ret []*v1alpha1.FederatedResourceQuota, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.FederatedResourceQuota)) + }) + return ret, err +} + +// FederatedResourceQuotas returns an object that can list and get FederatedResourceQuotas. +func (s *federatedResourceQuotaLister) FederatedResourceQuotas(namespace string) FederatedResourceQuotaNamespaceLister { + return federatedResourceQuotaNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// FederatedResourceQuotaNamespaceLister helps list and get FederatedResourceQuotas. +// All objects returned here must be treated as read-only. +type FederatedResourceQuotaNamespaceLister interface { + // List lists all FederatedResourceQuotas in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.FederatedResourceQuota, err error) + // Get retrieves the FederatedResourceQuota from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.FederatedResourceQuota, error) + FederatedResourceQuotaNamespaceListerExpansion +} + +// federatedResourceQuotaNamespaceLister implements the FederatedResourceQuotaNamespaceLister +// interface. +type federatedResourceQuotaNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all FederatedResourceQuotas in the indexer for a given namespace. +func (s federatedResourceQuotaNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.FederatedResourceQuota, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.FederatedResourceQuota)) + }) + return ret, err +} + +// Get retrieves the FederatedResourceQuota from the indexer for a given namespace and name. +func (s federatedResourceQuotaNamespaceLister) Get(name string) (*v1alpha1.FederatedResourceQuota, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("federatedresourcequota"), name) + } + return obj.(*v1alpha1.FederatedResourceQuota), nil +}