Merge pull request #113542 from ardaguclu/fix-shortname-disperancy

Set singular names for core types to pass to discovery
This commit is contained in:
Kubernetes Prow Robot 2023-01-03 09:29:43 -08:00 committed by GitHub
commit 12c71fdf1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 586 additions and 188 deletions

View File

@ -41,7 +41,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*admissionregistration.MutatingWebhookConfiguration).Name, nil return obj.(*admissionregistration.MutatingWebhookConfiguration).Name, nil
}, },
DefaultQualifiedResource: admissionregistration.Resource("mutatingwebhookconfigurations"), DefaultQualifiedResource: admissionregistration.Resource("mutatingwebhookconfigurations"),
SingularQualifiedResource: admissionregistration.Resource("mutatingwebhookconfiguration"),
CreateStrategy: mutatingwebhookconfiguration.Strategy, CreateStrategy: mutatingwebhookconfiguration.Strategy,
UpdateStrategy: mutatingwebhookconfiguration.Strategy, UpdateStrategy: mutatingwebhookconfiguration.Strategy,

View File

@ -47,7 +47,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter, authorizer authorizer.Authori
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*admissionregistration.ValidatingAdmissionPolicy).Name, nil return obj.(*admissionregistration.ValidatingAdmissionPolicy).Name, nil
}, },
DefaultQualifiedResource: groupResource, DefaultQualifiedResource: groupResource,
SingularQualifiedResource: admissionregistration.Resource("validatingadmissionpolicy"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -50,7 +50,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter, authorizer authorizer.Authori
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*admissionregistration.ValidatingAdmissionPolicyBinding).Name, nil return obj.(*admissionregistration.ValidatingAdmissionPolicyBinding).Name, nil
}, },
DefaultQualifiedResource: groupResource, DefaultQualifiedResource: groupResource,
SingularQualifiedResource: admissionregistration.Resource("validatingadmissionpolicybinding"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -41,7 +41,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*admissionregistration.ValidatingWebhookConfiguration).Name, nil return obj.(*admissionregistration.ValidatingWebhookConfiguration).Name, nil
}, },
DefaultQualifiedResource: admissionregistration.Resource("validatingwebhookconfigurations"), DefaultQualifiedResource: admissionregistration.Resource("validatingwebhookconfigurations"),
SingularQualifiedResource: admissionregistration.Resource("validatingwebhookconfiguration"),
CreateStrategy: validatingwebhookconfiguration.Strategy, CreateStrategy: validatingwebhookconfiguration.Strategy,
UpdateStrategy: validatingwebhookconfiguration.Strategy, UpdateStrategy: validatingwebhookconfiguration.Strategy,

View File

@ -45,7 +45,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*apiserverinternal.StorageVersion).Name, nil return obj.(*apiserverinternal.StorageVersion).Name, nil
}, },
DefaultQualifiedResource: apiserverinternal.Resource("storageversions"), DefaultQualifiedResource: apiserverinternal.Resource("storageversions"),
SingularQualifiedResource: apiserverinternal.Resource("storageversion"),
CreateStrategy: strategy.Strategy, CreateStrategy: strategy.Strategy,
UpdateStrategy: strategy.Strategy, UpdateStrategy: strategy.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work with ControllerRevision objects. // NewREST returns a RESTStorage object that will work with ControllerRevision objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apps.ControllerRevision{} }, NewFunc: func() runtime.Object { return &apps.ControllerRevision{} },
NewListFunc: func() runtime.Object { return &apps.ControllerRevisionList{} }, NewListFunc: func() runtime.Object { return &apps.ControllerRevisionList{} },
DefaultQualifiedResource: apps.Resource("controllerrevisions"), DefaultQualifiedResource: apps.Resource("controllerrevisions"),
SingularQualifiedResource: apps.Resource("controllerrevision"),
CreateStrategy: controllerrevision.Strategy, CreateStrategy: controllerrevision.Strategy,
UpdateStrategy: controllerrevision.Strategy, UpdateStrategy: controllerrevision.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against DaemonSets. // NewREST returns a RESTStorage object that will work against DaemonSets.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apps.DaemonSet{} }, NewFunc: func() runtime.Object { return &apps.DaemonSet{} },
NewListFunc: func() runtime.Object { return &apps.DaemonSetList{} }, NewListFunc: func() runtime.Object { return &apps.DaemonSetList{} },
DefaultQualifiedResource: apps.Resource("daemonsets"), DefaultQualifiedResource: apps.Resource("daemonsets"),
SingularQualifiedResource: apps.Resource("daemonset"),
CreateStrategy: daemonset.Strategy, CreateStrategy: daemonset.Strategy,
UpdateStrategy: daemonset.Strategy, UpdateStrategy: daemonset.Strategy,

View File

@ -92,9 +92,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against deployments. // NewREST returns a RESTStorage object that will work against deployments.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *RollbackREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *RollbackREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apps.Deployment{} }, NewFunc: func() runtime.Object { return &apps.Deployment{} },
NewListFunc: func() runtime.Object { return &apps.DeploymentList{} }, NewListFunc: func() runtime.Object { return &apps.DeploymentList{} },
DefaultQualifiedResource: apps.Resource("deployments"), DefaultQualifiedResource: apps.Resource("deployments"),
SingularQualifiedResource: apps.Resource("deployment"),
CreateStrategy: deployment.Strategy, CreateStrategy: deployment.Strategy,
UpdateStrategy: deployment.Strategy, UpdateStrategy: deployment.Strategy,

View File

@ -86,10 +86,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ReplicaSet. // NewREST returns a RESTStorage object that will work against ReplicaSet.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apps.ReplicaSet{} }, NewFunc: func() runtime.Object { return &apps.ReplicaSet{} },
NewListFunc: func() runtime.Object { return &apps.ReplicaSetList{} }, NewListFunc: func() runtime.Object { return &apps.ReplicaSetList{} },
PredicateFunc: replicaset.MatchReplicaSet, PredicateFunc: replicaset.MatchReplicaSet,
DefaultQualifiedResource: apps.Resource("replicasets"), DefaultQualifiedResource: apps.Resource("replicasets"),
SingularQualifiedResource: apps.Resource("replicaset"),
CreateStrategy: replicaset.Strategy, CreateStrategy: replicaset.Strategy,
UpdateStrategy: replicaset.Strategy, UpdateStrategy: replicaset.Strategy,

View File

@ -84,9 +84,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against statefulsets. // NewREST returns a RESTStorage object that will work against statefulsets.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apps.StatefulSet{} }, NewFunc: func() runtime.Object { return &apps.StatefulSet{} },
NewListFunc: func() runtime.Object { return &apps.StatefulSetList{} }, NewListFunc: func() runtime.Object { return &apps.StatefulSetList{} },
DefaultQualifiedResource: apps.Resource("statefulsets"), DefaultQualifiedResource: apps.Resource("statefulsets"),
SingularQualifiedResource: apps.Resource("statefulset"),
CreateStrategy: statefulset.Strategy, CreateStrategy: statefulset.Strategy,
UpdateStrategy: statefulset.Strategy, UpdateStrategy: statefulset.Strategy,

View File

@ -93,3 +93,9 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
return selfSAR, nil return selfSAR, nil
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "selfsubjectrulesreview"
}

View File

@ -60,6 +60,12 @@ func (r *REST) Destroy() {
// here explicitly. // here explicitly.
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "tokenreview"
}
func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
tokenReview, ok := obj.(*authentication.TokenReview) tokenReview, ok := obj.(*authentication.TokenReview)
if !ok { if !ok {

View File

@ -53,6 +53,12 @@ func (r *REST) Destroy() {
// here explicitly. // here explicitly.
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "localsubjectaccessreview"
}
func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
localSubjectAccessReview, ok := obj.(*authorizationapi.LocalSubjectAccessReview) localSubjectAccessReview, ok := obj.(*authorizationapi.LocalSubjectAccessReview)
if !ok { if !ok {

View File

@ -53,6 +53,12 @@ func (r *REST) Destroy() {
// here explicitly. // here explicitly.
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "selfsubjectaccessreview"
}
func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
selfSAR, ok := obj.(*authorizationapi.SelfSubjectAccessReview) selfSAR, ok := obj.(*authorizationapi.SelfSubjectAccessReview)
if !ok { if !ok {

View File

@ -95,6 +95,12 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
return ret, nil return ret, nil
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "selfsubjectrulesreview"
}
func getResourceRules(infos []authorizer.ResourceRuleInfo) []authorizationapi.ResourceRule { func getResourceRules(infos []authorizer.ResourceRuleInfo) []authorizationapi.ResourceRule {
rules := make([]authorizationapi.ResourceRule, len(infos)) rules := make([]authorizationapi.ResourceRule, len(infos))
for i, info := range infos { for i, info := range infos {

View File

@ -52,6 +52,12 @@ func (r *REST) Destroy() {
// here explicitly. // here explicitly.
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return "subjectaccessreview"
}
func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview) subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview)
if !ok { if !ok {

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscaler{} }, NewFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscaler{} },
NewListFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscalerList{} }, NewListFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscalerList{} },
DefaultQualifiedResource: autoscaling.Resource("horizontalpodautoscalers"), DefaultQualifiedResource: autoscaling.Resource("horizontalpodautoscalers"),
SingularQualifiedResource: autoscaling.Resource("horizontalpodautoscaler"),
CreateStrategy: horizontalpodautoscaler.Strategy, CreateStrategy: horizontalpodautoscaler.Strategy,
UpdateStrategy: horizontalpodautoscaler.Strategy, UpdateStrategy: horizontalpodautoscaler.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against CronJobs. // NewREST returns a RESTStorage object that will work against CronJobs.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &batch.CronJob{} }, NewFunc: func() runtime.Object { return &batch.CronJob{} },
NewListFunc: func() runtime.Object { return &batch.CronJobList{} }, NewListFunc: func() runtime.Object { return &batch.CronJobList{} },
DefaultQualifiedResource: batch.Resource("cronjobs"), DefaultQualifiedResource: batch.Resource("cronjobs"),
SingularQualifiedResource: batch.Resource("cronjob"),
CreateStrategy: cronjob.Strategy, CreateStrategy: cronjob.Strategy,
UpdateStrategy: cronjob.Strategy, UpdateStrategy: cronjob.Strategy,

View File

@ -64,10 +64,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against Jobs. // NewREST returns a RESTStorage object that will work against Jobs.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &batch.Job{} }, NewFunc: func() runtime.Object { return &batch.Job{} },
NewListFunc: func() runtime.Object { return &batch.JobList{} }, NewListFunc: func() runtime.Object { return &batch.JobList{} },
PredicateFunc: job.MatchJob, PredicateFunc: job.MatchJob,
DefaultQualifiedResource: batch.Resource("jobs"), DefaultQualifiedResource: batch.Resource("jobs"),
SingularQualifiedResource: batch.Resource("job"),
CreateStrategy: job.Strategy, CreateStrategy: job.Strategy,
UpdateStrategy: job.Strategy, UpdateStrategy: job.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a registry which will store CertificateSigningRequest in the given helper. // NewREST returns a registry which will store CertificateSigningRequest in the given helper.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *ApprovalREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *ApprovalREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &certificates.CertificateSigningRequest{} }, NewFunc: func() runtime.Object { return &certificates.CertificateSigningRequest{} },
NewListFunc: func() runtime.Object { return &certificates.CertificateSigningRequestList{} }, NewListFunc: func() runtime.Object { return &certificates.CertificateSigningRequestList{} },
DefaultQualifiedResource: certificates.Resource("certificatesigningrequests"), DefaultQualifiedResource: certificates.Resource("certificatesigningrequests"),
SingularQualifiedResource: certificates.Resource("certificatesigningrequest"),
CreateStrategy: csrregistry.Strategy, CreateStrategy: csrregistry.Strategy,
UpdateStrategy: csrregistry.Strategy, UpdateStrategy: csrregistry.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against leases. // NewREST returns a RESTStorage object that will work against leases.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &coordinationapi.Lease{} }, NewFunc: func() runtime.Object { return &coordinationapi.Lease{} },
NewListFunc: func() runtime.Object { return &coordinationapi.LeaseList{} }, NewListFunc: func() runtime.Object { return &coordinationapi.LeaseList{} },
DefaultQualifiedResource: coordinationapi.Resource("leases"), DefaultQualifiedResource: coordinationapi.Resource("leases"),
SingularQualifiedResource: coordinationapi.Resource("lease"),
CreateStrategy: lease.Strategy, CreateStrategy: lease.Strategy,
UpdateStrategy: lease.Strategy, UpdateStrategy: lease.Strategy,

View File

@ -58,6 +58,12 @@ func (rs *REST) New() runtime.Object {
return &api.ComponentStatus{} return &api.ComponentStatus{}
} }
var _ rest.SingularNameProvider = &REST{}
func (rs *REST) GetSingularName() string {
return "componentstatus"
}
// Destroy cleans up resources on shutdown. // Destroy cleans up resources on shutdown.
func (r *REST) Destroy() { func (r *REST) Destroy() {
// Given no underlying store, we don't destroy anything // Given no underlying store, we don't destroy anything

View File

@ -37,10 +37,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work with ConfigMap objects. // NewREST returns a RESTStorage object that will work with ConfigMap objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ConfigMap{} }, NewFunc: func() runtime.Object { return &api.ConfigMap{} },
NewListFunc: func() runtime.Object { return &api.ConfigMapList{} }, NewListFunc: func() runtime.Object { return &api.ConfigMapList{} },
PredicateFunc: configmap.Matcher, PredicateFunc: configmap.Matcher,
DefaultQualifiedResource: api.Resource("configmaps"), DefaultQualifiedResource: api.Resource("configmaps"),
SingularQualifiedResource: api.Resource("configmap"),
CreateStrategy: configmap.Strategy, CreateStrategy: configmap.Strategy,
UpdateStrategy: configmap.Strategy, UpdateStrategy: configmap.Strategy,

View File

@ -36,9 +36,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against endpoints. // NewREST returns a RESTStorage object that will work against endpoints.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Endpoints{} }, NewFunc: func() runtime.Object { return &api.Endpoints{} },
NewListFunc: func() runtime.Object { return &api.EndpointsList{} }, NewListFunc: func() runtime.Object { return &api.EndpointsList{} },
DefaultQualifiedResource: api.Resource("endpoints"), DefaultQualifiedResource: api.Resource("endpoints"),
SingularQualifiedResource: api.Resource("endpoints"),
CreateStrategy: endpoint.Strategy, CreateStrategy: endpoint.Strategy,
UpdateStrategy: endpoint.Strategy, UpdateStrategy: endpoint.Strategy,

View File

@ -42,7 +42,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter, ttl uint64) (*REST, error) {
TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) { TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) {
return ttl, nil return ttl, nil
}, },
DefaultQualifiedResource: api.Resource("events"), DefaultQualifiedResource: api.Resource("events"),
SingularQualifiedResource: api.Resource("event"),
CreateStrategy: event.Strategy, CreateStrategy: event.Strategy,
UpdateStrategy: event.Strategy, UpdateStrategy: event.Strategy,

View File

@ -33,9 +33,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against limit ranges. // NewREST returns a RESTStorage object that will work against limit ranges.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.LimitRange{} }, NewFunc: func() runtime.Object { return &api.LimitRange{} },
NewListFunc: func() runtime.Object { return &api.LimitRangeList{} }, NewListFunc: func() runtime.Object { return &api.LimitRangeList{} },
DefaultQualifiedResource: api.Resource("limitranges"), DefaultQualifiedResource: api.Resource("limitranges"),
SingularQualifiedResource: api.Resource("limitrange"),
CreateStrategy: limitrange.Strategy, CreateStrategy: limitrange.Strategy,
UpdateStrategy: limitrange.Strategy, UpdateStrategy: limitrange.Strategy,

View File

@ -59,10 +59,11 @@ type FinalizeREST struct {
// NewREST returns a RESTStorage object that will work against namespaces. // NewREST returns a RESTStorage object that will work against namespaces.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *FinalizeREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *FinalizeREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Namespace{} }, NewFunc: func() runtime.Object { return &api.Namespace{} },
NewListFunc: func() runtime.Object { return &api.NamespaceList{} }, NewListFunc: func() runtime.Object { return &api.NamespaceList{} },
PredicateFunc: namespace.MatchNamespace, PredicateFunc: namespace.MatchNamespace,
DefaultQualifiedResource: api.Resource("namespaces"), DefaultQualifiedResource: api.Resource("namespaces"),
SingularQualifiedResource: api.Resource("namespace"),
CreateStrategy: namespace.Strategy, CreateStrategy: namespace.Strategy,
UpdateStrategy: namespace.Strategy, UpdateStrategy: namespace.Strategy,
@ -94,6 +95,12 @@ func (r *REST) NamespaceScoped() bool {
return r.store.NamespaceScoped() return r.store.NamespaceScoped()
} }
var _ rest.SingularNameProvider = &REST{}
func (r *REST) GetSingularName() string {
return r.store.GetSingularName()
}
func (r *REST) New() runtime.Object { func (r *REST) New() runtime.Object {
return r.store.New() return r.store.New()
} }

View File

@ -96,10 +96,11 @@ func (r *StatusREST) ConvertToTable(ctx context.Context, object runtime.Object,
// NewStorage returns a NodeStorage object that will work against nodes. // NewStorage returns a NodeStorage object that will work against nodes.
func NewStorage(optsGetter generic.RESTOptionsGetter, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Node{} }, NewFunc: func() runtime.Object { return &api.Node{} },
NewListFunc: func() runtime.Object { return &api.NodeList{} }, NewListFunc: func() runtime.Object { return &api.NodeList{} },
PredicateFunc: node.MatchNode, PredicateFunc: node.MatchNode,
DefaultQualifiedResource: api.Resource("nodes"), DefaultQualifiedResource: api.Resource("nodes"),
SingularQualifiedResource: api.Resource("node"),
CreateStrategy: node.Strategy, CreateStrategy: node.Strategy,
UpdateStrategy: node.Strategy, UpdateStrategy: node.Strategy,

View File

@ -40,10 +40,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against persistent volumes. // NewREST returns a RESTStorage object that will work against persistent volumes.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} }, NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} },
PredicateFunc: persistentvolume.MatchPersistentVolumes, PredicateFunc: persistentvolume.MatchPersistentVolumes,
DefaultQualifiedResource: api.Resource("persistentvolumes"), DefaultQualifiedResource: api.Resource("persistentvolumes"),
SingularQualifiedResource: api.Resource("persistentvolume"),
CreateStrategy: persistentvolume.Strategy, CreateStrategy: persistentvolume.Strategy,
UpdateStrategy: persistentvolume.Strategy, UpdateStrategy: persistentvolume.Strategy,

View File

@ -41,10 +41,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against persistent volume claims. // NewREST returns a RESTStorage object that will work against persistent volume claims.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} }, NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} },
PredicateFunc: persistentvolumeclaim.MatchPersistentVolumeClaim, PredicateFunc: persistentvolumeclaim.MatchPersistentVolumeClaim,
DefaultQualifiedResource: api.Resource("persistentvolumeclaims"), DefaultQualifiedResource: api.Resource("persistentvolumeclaims"),
SingularQualifiedResource: api.Resource("persistentvolumeclaim"),
CreateStrategy: persistentvolumeclaim.Strategy, CreateStrategy: persistentvolumeclaim.Strategy,
UpdateStrategy: persistentvolumeclaim.Strategy, UpdateStrategy: persistentvolumeclaim.Strategy,

View File

@ -73,10 +73,11 @@ type REST struct {
func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) (PodStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) (PodStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} }, NewListFunc: func() runtime.Object { return &api.PodList{} },
PredicateFunc: registrypod.MatchPod, PredicateFunc: registrypod.MatchPod,
DefaultQualifiedResource: api.Resource("pods"), DefaultQualifiedResource: api.Resource("pods"),
SingularQualifiedResource: api.Resource("pod"),
CreateStrategy: registrypod.Strategy, CreateStrategy: registrypod.Strategy,
UpdateStrategy: registrypod.Strategy, UpdateStrategy: registrypod.Strategy,
@ -288,6 +289,10 @@ func (r *LegacyBindingREST) Create(ctx context.Context, obj runtime.Object, crea
return r.bindingRest.Create(ctx, metadata.GetName(), obj, createValidation, options) return r.bindingRest.Create(ctx, metadata.GetName(), obj, createValidation, options)
} }
func (r *LegacyBindingREST) GetSingularName() string {
return "binding"
}
// StatusREST implements the REST endpoint for changing the status of a pod. // StatusREST implements the REST endpoint for changing the status of a pod.
type StatusREST struct { type StatusREST struct {
store *genericregistry.Store store *genericregistry.Store

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against pod templates. // NewREST returns a RESTStorage object that will work against pod templates.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PodTemplate{} }, NewFunc: func() runtime.Object { return &api.PodTemplate{} },
NewListFunc: func() runtime.Object { return &api.PodTemplateList{} }, NewListFunc: func() runtime.Object { return &api.PodTemplateList{} },
DefaultQualifiedResource: api.Resource("podtemplates"), DefaultQualifiedResource: api.Resource("podtemplates"),
SingularQualifiedResource: api.Resource("podtemplate"),
CreateStrategy: podtemplate.Strategy, CreateStrategy: podtemplate.Strategy,
UpdateStrategy: podtemplate.Strategy, UpdateStrategy: podtemplate.Strategy,

View File

@ -82,10 +82,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ReplicationController{} }, NewFunc: func() runtime.Object { return &api.ReplicationController{} },
NewListFunc: func() runtime.Object { return &api.ReplicationControllerList{} }, NewListFunc: func() runtime.Object { return &api.ReplicationControllerList{} },
PredicateFunc: replicationcontroller.MatchController, PredicateFunc: replicationcontroller.MatchController,
DefaultQualifiedResource: api.Resource("replicationcontrollers"), DefaultQualifiedResource: api.Resource("replicationcontrollers"),
SingularQualifiedResource: api.Resource("replicationcontroller"),
CreateStrategy: replicationcontroller.Strategy, CreateStrategy: replicationcontroller.Strategy,
UpdateStrategy: replicationcontroller.Strategy, UpdateStrategy: replicationcontroller.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against resource quotas. // NewREST returns a RESTStorage object that will work against resource quotas.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} }, NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} },
DefaultQualifiedResource: api.Resource("resourcequotas"), DefaultQualifiedResource: api.Resource("resourcequotas"),
SingularQualifiedResource: api.Resource("resourcequota"),
CreateStrategy: resourcequota.Strategy, CreateStrategy: resourcequota.Strategy,
UpdateStrategy: resourcequota.Strategy, UpdateStrategy: resourcequota.Strategy,

View File

@ -36,10 +36,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against secrets. // NewREST returns a RESTStorage object that will work against secrets.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Secret{} }, NewFunc: func() runtime.Object { return &api.Secret{} },
NewListFunc: func() runtime.Object { return &api.SecretList{} }, NewListFunc: func() runtime.Object { return &api.SecretList{} },
PredicateFunc: secret.Matcher, PredicateFunc: secret.Matcher,
DefaultQualifiedResource: api.Resource("secrets"), DefaultQualifiedResource: api.Resource("secrets"),
SingularQualifiedResource: api.Resource("secret"),
CreateStrategy: secret.Strategy, CreateStrategy: secret.Strategy,
UpdateStrategy: secret.Strategy, UpdateStrategy: secret.Strategy,

View File

@ -86,10 +86,11 @@ func NewREST(
proxyTransport http.RoundTripper) (*REST, *StatusREST, *svcreg.ProxyREST, error) { proxyTransport http.RoundTripper) (*REST, *StatusREST, *svcreg.ProxyREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Service{} }, NewFunc: func() runtime.Object { return &api.Service{} },
NewListFunc: func() runtime.Object { return &api.ServiceList{} }, NewListFunc: func() runtime.Object { return &api.ServiceList{} },
DefaultQualifiedResource: api.Resource("services"), DefaultQualifiedResource: api.Resource("services"),
ReturnDeletedObject: true, SingularQualifiedResource: api.Resource("service"),
ReturnDeletedObject: true,
CreateStrategy: svcreg.Strategy, CreateStrategy: svcreg.Strategy,
UpdateStrategy: svcreg.Strategy, UpdateStrategy: svcreg.Strategy,

View File

@ -41,9 +41,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against service accounts. // NewREST returns a RESTStorage object that will work against service accounts.
func NewREST(optsGetter generic.RESTOptionsGetter, issuer token.TokenGenerator, auds authenticator.Audiences, max time.Duration, podStorage, secretStorage *genericregistry.Store, extendExpiration bool) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter, issuer token.TokenGenerator, auds authenticator.Audiences, max time.Duration, podStorage, secretStorage *genericregistry.Store, extendExpiration bool) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewFunc: func() runtime.Object { return &api.ServiceAccount{} },
NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} }, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} },
DefaultQualifiedResource: api.Resource("serviceaccounts"), DefaultQualifiedResource: api.Resource("serviceaccounts"),
SingularQualifiedResource: api.Resource("serviceaccount"),
CreateStrategy: serviceaccount.Strategy, CreateStrategy: serviceaccount.Strategy,
UpdateStrategy: serviceaccount.Strategy, UpdateStrategy: serviceaccount.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against endpoint slices. // NewREST returns a RESTStorage object that will work against endpoint slices.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &discovery.EndpointSlice{} }, NewFunc: func() runtime.Object { return &discovery.EndpointSlice{} },
NewListFunc: func() runtime.Object { return &discovery.EndpointSliceList{} }, NewListFunc: func() runtime.Object { return &discovery.EndpointSliceList{} },
DefaultQualifiedResource: discovery.Resource("endpointslices"), DefaultQualifiedResource: discovery.Resource("endpointslices"),
SingularQualifiedResource: discovery.Resource("endpointslice"),
CreateStrategy: endpointslice.Strategy, CreateStrategy: endpointslice.Strategy,
UpdateStrategy: endpointslice.Strategy, UpdateStrategy: endpointslice.Strategy,

View File

@ -46,9 +46,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against flow schemas. // NewREST returns a RESTStorage object that will work against flow schemas.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &flowcontrol.FlowSchema{} }, NewFunc: func() runtime.Object { return &flowcontrol.FlowSchema{} },
NewListFunc: func() runtime.Object { return &flowcontrol.FlowSchemaList{} }, NewListFunc: func() runtime.Object { return &flowcontrol.FlowSchemaList{} },
DefaultQualifiedResource: flowcontrol.Resource("flowschemas"), DefaultQualifiedResource: flowcontrol.Resource("flowschemas"),
SingularQualifiedResource: flowcontrol.Resource("flowschema"),
CreateStrategy: flowschema.Strategy, CreateStrategy: flowschema.Strategy,
UpdateStrategy: flowschema.Strategy, UpdateStrategy: flowschema.Strategy,

View File

@ -46,9 +46,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against priority level configuration. // NewREST returns a RESTStorage object that will work against priority level configuration.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfiguration{} }, NewFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfiguration{} },
NewListFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfigurationList{} }, NewListFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfigurationList{} },
DefaultQualifiedResource: flowcontrol.Resource("prioritylevelconfigurations"), DefaultQualifiedResource: flowcontrol.Resource("prioritylevelconfigurations"),
SingularQualifiedResource: flowcontrol.Resource("prioritylevelconfiguration"),
CreateStrategy: prioritylevelconfiguration.Strategy, CreateStrategy: prioritylevelconfiguration.Strategy,
UpdateStrategy: prioritylevelconfiguration.Strategy, UpdateStrategy: prioritylevelconfiguration.Strategy,

View File

@ -36,9 +36,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ClusterCIDRs. // NewREST returns a RESTStorage object that will work against ClusterCIDRs.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &networkingapi.ClusterCIDR{} }, NewFunc: func() runtime.Object { return &networkingapi.ClusterCIDR{} },
NewListFunc: func() runtime.Object { return &networkingapi.ClusterCIDRList{} }, NewListFunc: func() runtime.Object { return &networkingapi.ClusterCIDRList{} },
DefaultQualifiedResource: networkingapi.Resource("clustercidrs"), DefaultQualifiedResource: networkingapi.Resource("clustercidrs"),
SingularQualifiedResource: networkingapi.Resource("clustercidr"),
CreateStrategy: clustercidr.Strategy, CreateStrategy: clustercidr.Strategy,
UpdateStrategy: clustercidr.Strategy, UpdateStrategy: clustercidr.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &networking.Ingress{} }, NewFunc: func() runtime.Object { return &networking.Ingress{} },
NewListFunc: func() runtime.Object { return &networking.IngressList{} }, NewListFunc: func() runtime.Object { return &networking.IngressList{} },
DefaultQualifiedResource: networking.Resource("ingresses"), DefaultQualifiedResource: networking.Resource("ingresses"),
SingularQualifiedResource: networking.Resource("ingress"),
CreateStrategy: ingress.Strategy, CreateStrategy: ingress.Strategy,
UpdateStrategy: ingress.Strategy, UpdateStrategy: ingress.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &networking.IngressClass{} }, NewFunc: func() runtime.Object { return &networking.IngressClass{} },
NewListFunc: func() runtime.Object { return &networking.IngressClassList{} }, NewListFunc: func() runtime.Object { return &networking.IngressClassList{} },
DefaultQualifiedResource: networking.Resource("ingressclasses"), DefaultQualifiedResource: networking.Resource("ingressclasses"),
SingularQualifiedResource: networking.Resource("ingressclass"),
CreateStrategy: ingressclass.Strategy, CreateStrategy: ingressclass.Strategy,
UpdateStrategy: ingressclass.Strategy, UpdateStrategy: ingressclass.Strategy,

View File

@ -41,9 +41,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against NetworkPolicies. // NewREST returns a RESTStorage object that will work against NetworkPolicies.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &networkingapi.NetworkPolicy{} }, NewFunc: func() runtime.Object { return &networkingapi.NetworkPolicy{} },
NewListFunc: func() runtime.Object { return &networkingapi.NetworkPolicyList{} }, NewListFunc: func() runtime.Object { return &networkingapi.NetworkPolicyList{} },
DefaultQualifiedResource: networkingapi.Resource("networkpolicies"), DefaultQualifiedResource: networkingapi.Resource("networkpolicies"),
SingularQualifiedResource: networkingapi.Resource("networkpolicy"),
CreateStrategy: networkpolicy.Strategy, CreateStrategy: networkpolicy.Strategy,
UpdateStrategy: networkpolicy.Strategy, UpdateStrategy: networkpolicy.Strategy,

View File

@ -40,7 +40,8 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*node.RuntimeClass).Name, nil return obj.(*node.RuntimeClass).Name, nil
}, },
DefaultQualifiedResource: node.Resource("runtimeclasses"), DefaultQualifiedResource: node.Resource("runtimeclasses"),
SingularQualifiedResource: node.Resource("runtimeclass"),
CreateStrategy: runtimeclass.Strategy, CreateStrategy: runtimeclass.Strategy,
UpdateStrategy: runtimeclass.Strategy, UpdateStrategy: runtimeclass.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against pod disruption budgets. // NewREST returns a RESTStorage object that will work against pod disruption budgets.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &policyapi.PodDisruptionBudget{} }, NewFunc: func() runtime.Object { return &policyapi.PodDisruptionBudget{} },
NewListFunc: func() runtime.Object { return &policyapi.PodDisruptionBudgetList{} }, NewListFunc: func() runtime.Object { return &policyapi.PodDisruptionBudgetList{} },
DefaultQualifiedResource: policyapi.Resource("poddisruptionbudgets"), DefaultQualifiedResource: policyapi.Resource("poddisruptionbudgets"),
SingularQualifiedResource: policyapi.Resource("poddisruptionbudget"),
CreateStrategy: poddisruptionbudget.Strategy, CreateStrategy: poddisruptionbudget.Strategy,
UpdateStrategy: poddisruptionbudget.Strategy, UpdateStrategy: poddisruptionbudget.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against PodSecurityPolicy objects. // NewREST returns a RESTStorage object that will work against PodSecurityPolicy objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &policy.PodSecurityPolicy{} }, NewFunc: func() runtime.Object { return &policy.PodSecurityPolicy{} },
NewListFunc: func() runtime.Object { return &policy.PodSecurityPolicyList{} }, NewListFunc: func() runtime.Object { return &policy.PodSecurityPolicyList{} },
DefaultQualifiedResource: policy.Resource("podsecuritypolicies"), DefaultQualifiedResource: policy.Resource("podsecuritypolicies"),
SingularQualifiedResource: policy.Resource("podsecuritypolicy"),
CreateStrategy: podsecuritypolicy.Strategy, CreateStrategy: podsecuritypolicy.Strategy,
UpdateStrategy: podsecuritypolicy.Strategy, UpdateStrategy: podsecuritypolicy.Strategy,

View File

@ -124,3 +124,13 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec
func hasAggregationRule(clusterRole *rbac.ClusterRole) bool { func hasAggregationRule(clusterRole *rbac.ClusterRole) bool {
return clusterRole.AggregationRule != nil && len(clusterRole.AggregationRule.ClusterRoleSelectors) > 0 return clusterRole.AggregationRule != nil && len(clusterRole.AggregationRule.ClusterRoleSelectors) > 0
} }
var _ rest.SingularNameProvider = &Storage{}
func (s *Storage) GetSingularName() string {
snp, ok := s.StandardStorage.(rest.SingularNameProvider)
if !ok {
return ""
}
return snp.GetSingularName()
}

View File

@ -33,9 +33,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ClusterRole objects. // NewREST returns a RESTStorage object that will work against ClusterRole objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &rbac.ClusterRole{} }, NewFunc: func() runtime.Object { return &rbac.ClusterRole{} },
NewListFunc: func() runtime.Object { return &rbac.ClusterRoleList{} }, NewListFunc: func() runtime.Object { return &rbac.ClusterRoleList{} },
DefaultQualifiedResource: rbac.Resource("clusterroles"), DefaultQualifiedResource: rbac.Resource("clusterroles"),
SingularQualifiedResource: rbac.Resource("clusterrole"),
CreateStrategy: clusterrole.Strategy, CreateStrategy: clusterrole.Strategy,
UpdateStrategy: clusterrole.Strategy, UpdateStrategy: clusterrole.Strategy,

View File

@ -127,3 +127,13 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec
return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options)
} }
var _ rest.SingularNameProvider = &Storage{}
func (s *Storage) GetSingularName() string {
snp, ok := s.StandardStorage.(rest.SingularNameProvider)
if !ok {
return ""
}
return snp.GetSingularName()
}

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ClusterRoleBinding objects. // NewREST returns a RESTStorage object that will work against ClusterRoleBinding objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &rbac.ClusterRoleBinding{} }, NewFunc: func() runtime.Object { return &rbac.ClusterRoleBinding{} },
NewListFunc: func() runtime.Object { return &rbac.ClusterRoleBindingList{} }, NewListFunc: func() runtime.Object { return &rbac.ClusterRoleBindingList{} },
DefaultQualifiedResource: rbac.Resource("clusterrolebindings"), DefaultQualifiedResource: rbac.Resource("clusterrolebindings"),
SingularQualifiedResource: rbac.Resource("clusterrolebinding"),
CreateStrategy: clusterrolebinding.Strategy, CreateStrategy: clusterrolebinding.Strategy,
UpdateStrategy: clusterrolebinding.Strategy, UpdateStrategy: clusterrolebinding.Strategy,

View File

@ -99,3 +99,13 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec
return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options)
} }
var _ rest.SingularNameProvider = &Storage{}
func (s *Storage) GetSingularName() string {
snp, ok := s.StandardStorage.(rest.SingularNameProvider)
if !ok {
return ""
}
return snp.GetSingularName()
}

View File

@ -33,9 +33,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against Role objects. // NewREST returns a RESTStorage object that will work against Role objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &rbac.Role{} }, NewFunc: func() runtime.Object { return &rbac.Role{} },
NewListFunc: func() runtime.Object { return &rbac.RoleList{} }, NewListFunc: func() runtime.Object { return &rbac.RoleList{} },
DefaultQualifiedResource: rbac.Resource("roles"), DefaultQualifiedResource: rbac.Resource("roles"),
SingularQualifiedResource: rbac.Resource("role"),
CreateStrategy: role.Strategy, CreateStrategy: role.Strategy,
UpdateStrategy: role.Strategy, UpdateStrategy: role.Strategy,

View File

@ -142,3 +142,13 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec
return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options)
} }
var _ rest.SingularNameProvider = &Storage{}
func (s *Storage) GetSingularName() string {
snp, ok := s.StandardStorage.(rest.SingularNameProvider)
if !ok {
return ""
}
return snp.GetSingularName()
}

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against RoleBinding objects. // NewREST returns a RESTStorage object that will work against RoleBinding objects.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &rbac.RoleBinding{} }, NewFunc: func() runtime.Object { return &rbac.RoleBinding{} },
NewListFunc: func() runtime.Object { return &rbac.RoleBindingList{} }, NewListFunc: func() runtime.Object { return &rbac.RoleBindingList{} },
DefaultQualifiedResource: rbac.Resource("rolebindings"), DefaultQualifiedResource: rbac.Resource("rolebindings"),
SingularQualifiedResource: rbac.Resource("rolebinding"),
CreateStrategy: rolebinding.Strategy, CreateStrategy: rolebinding.Strategy,
UpdateStrategy: rolebinding.Strategy, UpdateStrategy: rolebinding.Strategy,

View File

@ -40,10 +40,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against PodSchedulings. // NewREST returns a RESTStorage object that will work against PodSchedulings.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &resource.PodScheduling{} }, NewFunc: func() runtime.Object { return &resource.PodScheduling{} },
NewListFunc: func() runtime.Object { return &resource.PodSchedulingList{} }, NewListFunc: func() runtime.Object { return &resource.PodSchedulingList{} },
PredicateFunc: podscheduling.Match, PredicateFunc: podscheduling.Match,
DefaultQualifiedResource: resource.Resource("podschedulings"), DefaultQualifiedResource: resource.Resource("podschedulings"),
SingularQualifiedResource: resource.Resource("podscheduling"),
CreateStrategy: podscheduling.Strategy, CreateStrategy: podscheduling.Strategy,
UpdateStrategy: podscheduling.Strategy, UpdateStrategy: podscheduling.Strategy,

View File

@ -40,10 +40,11 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ResourceClaims. // NewREST returns a RESTStorage object that will work against ResourceClaims.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &resource.ResourceClaim{} }, NewFunc: func() runtime.Object { return &resource.ResourceClaim{} },
NewListFunc: func() runtime.Object { return &resource.ResourceClaimList{} }, NewListFunc: func() runtime.Object { return &resource.ResourceClaimList{} },
PredicateFunc: resourceclaim.Match, PredicateFunc: resourceclaim.Match,
DefaultQualifiedResource: resource.Resource("resourceclaims"), DefaultQualifiedResource: resource.Resource("resourceclaims"),
SingularQualifiedResource: resource.Resource("resourceclaim"),
CreateStrategy: resourceclaim.Strategy, CreateStrategy: resourceclaim.Strategy,
UpdateStrategy: resourceclaim.Strategy, UpdateStrategy: resourceclaim.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ResourceClass. // NewREST returns a RESTStorage object that will work against ResourceClass.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &resource.ResourceClaimTemplate{} }, NewFunc: func() runtime.Object { return &resource.ResourceClaimTemplate{} },
NewListFunc: func() runtime.Object { return &resource.ResourceClaimTemplateList{} }, NewListFunc: func() runtime.Object { return &resource.ResourceClaimTemplateList{} },
DefaultQualifiedResource: resource.Resource("resourceclaimtemplates"), DefaultQualifiedResource: resource.Resource("resourceclaimtemplates"),
SingularQualifiedResource: resource.Resource("resourceclaimtemplate"),
CreateStrategy: resourceclaimtemplate.Strategy, CreateStrategy: resourceclaimtemplate.Strategy,
UpdateStrategy: resourceclaimtemplate.Strategy, UpdateStrategy: resourceclaimtemplate.Strategy,

View File

@ -35,9 +35,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against ResourceClass. // NewREST returns a RESTStorage object that will work against ResourceClass.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &resource.ResourceClass{} }, NewFunc: func() runtime.Object { return &resource.ResourceClass{} },
NewListFunc: func() runtime.Object { return &resource.ResourceClassList{} }, NewListFunc: func() runtime.Object { return &resource.ResourceClassList{} },
DefaultQualifiedResource: resource.Resource("resourceclasses"), DefaultQualifiedResource: resource.Resource("resourceclasses"),
SingularQualifiedResource: resource.Resource("resourceclass"),
CreateStrategy: resourceclass.Strategy, CreateStrategy: resourceclass.Strategy,
UpdateStrategy: resourceclass.Strategy, UpdateStrategy: resourceclass.Strategy,

View File

@ -41,9 +41,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against priority classes. // NewREST returns a RESTStorage object that will work against priority classes.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &scheduling.PriorityClass{} }, NewFunc: func() runtime.Object { return &scheduling.PriorityClass{} },
NewListFunc: func() runtime.Object { return &scheduling.PriorityClassList{} }, NewListFunc: func() runtime.Object { return &scheduling.PriorityClassList{} },
DefaultQualifiedResource: scheduling.Resource("priorityclasses"), DefaultQualifiedResource: scheduling.Resource("priorityclasses"),
SingularQualifiedResource: scheduling.Resource("priorityclass"),
CreateStrategy: priorityclass.Strategy, CreateStrategy: priorityclass.Strategy,
UpdateStrategy: priorityclass.Strategy, UpdateStrategy: priorityclass.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against CSIDrivers // NewStorage returns a RESTStorage object that will work against CSIDrivers
func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSIDriverStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSIDriverStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &storageapi.CSIDriver{} }, NewFunc: func() runtime.Object { return &storageapi.CSIDriver{} },
NewListFunc: func() runtime.Object { return &storageapi.CSIDriverList{} }, NewListFunc: func() runtime.Object { return &storageapi.CSIDriverList{} },
DefaultQualifiedResource: storageapi.Resource("csidrivers"), DefaultQualifiedResource: storageapi.Resource("csidrivers"),
SingularQualifiedResource: storageapi.Resource("csidriver"),
CreateStrategy: csidriver.Strategy, CreateStrategy: csidriver.Strategy,
UpdateStrategy: csidriver.Strategy, UpdateStrategy: csidriver.Strategy,

View File

@ -40,9 +40,10 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against CSINodes // NewStorage returns a RESTStorage object that will work against CSINodes
func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSINodeStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSINodeStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &storageapi.CSINode{} }, NewFunc: func() runtime.Object { return &storageapi.CSINode{} },
NewListFunc: func() runtime.Object { return &storageapi.CSINodeList{} }, NewListFunc: func() runtime.Object { return &storageapi.CSINodeList{} },
DefaultQualifiedResource: storageapi.Resource("csinodes"), DefaultQualifiedResource: storageapi.Resource("csinodes"),
SingularQualifiedResource: storageapi.Resource("csinode"),
CreateStrategy: csinode.Strategy, CreateStrategy: csinode.Strategy,
UpdateStrategy: csinode.Strategy, UpdateStrategy: csinode.Strategy,

View File

@ -38,9 +38,10 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against CSIStorageCapacity // NewStorage returns a RESTStorage object that will work against CSIStorageCapacity
func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSIStorageCapacityStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter) (*CSIStorageCapacityStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &storageapi.CSIStorageCapacity{} }, NewFunc: func() runtime.Object { return &storageapi.CSIStorageCapacity{} },
NewListFunc: func() runtime.Object { return &storageapi.CSIStorageCapacityList{} }, NewListFunc: func() runtime.Object { return &storageapi.CSIStorageCapacityList{} },
DefaultQualifiedResource: storageapi.Resource("csistoragecapacities"), DefaultQualifiedResource: storageapi.Resource("csistoragecapacities"),
SingularQualifiedResource: storageapi.Resource("csistoragecapacity"),
TableConvertor: rest.NewDefaultTableConvertor(storageapi.Resource("csistoragecapacities")), TableConvertor: rest.NewDefaultTableConvertor(storageapi.Resource("csistoragecapacities")),

View File

@ -36,9 +36,10 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against storage classes. // NewREST returns a RESTStorage object that will work against storage classes.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &storageapi.StorageClass{} }, NewFunc: func() runtime.Object { return &storageapi.StorageClass{} },
NewListFunc: func() runtime.Object { return &storageapi.StorageClassList{} }, NewListFunc: func() runtime.Object { return &storageapi.StorageClassList{} },
DefaultQualifiedResource: storageapi.Resource("storageclasses"), DefaultQualifiedResource: storageapi.Resource("storageclasses"),
SingularQualifiedResource: storageapi.Resource("storageclass"),
CreateStrategy: storageclass.Strategy, CreateStrategy: storageclass.Strategy,
UpdateStrategy: storageclass.Strategy, UpdateStrategy: storageclass.Strategy,

View File

@ -46,9 +46,10 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against VolumeAttachments // NewStorage returns a RESTStorage object that will work against VolumeAttachments
func NewStorage(optsGetter generic.RESTOptionsGetter) (*VolumeAttachmentStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter) (*VolumeAttachmentStorage, error) {
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &storageapi.VolumeAttachment{} }, NewFunc: func() runtime.Object { return &storageapi.VolumeAttachment{} },
NewListFunc: func() runtime.Object { return &storageapi.VolumeAttachmentList{} }, NewListFunc: func() runtime.Object { return &storageapi.VolumeAttachmentList{} },
DefaultQualifiedResource: storageapi.Resource("volumeattachments"), DefaultQualifiedResource: storageapi.Resource("volumeattachments"),
SingularQualifiedResource: storageapi.Resource("volumeattachment"),
CreateStrategy: volumeattachment.Strategy, CreateStrategy: volumeattachment.Strategy,
UpdateStrategy: volumeattachment.Strategy, UpdateStrategy: volumeattachment.Strategy,

View File

@ -732,6 +732,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
parameterCodec := runtime.NewParameterCodec(parameterScheme) parameterCodec := runtime.NewParameterCodec(parameterScheme)
resource := schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Status.AcceptedNames.Plural} resource := schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Status.AcceptedNames.Plural}
singularResource := schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Status.AcceptedNames.Singular}
kind := schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.Kind} kind := schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.Kind}
equivalentResourceRegistry.RegisterKindFor(resource, "", kind) equivalentResourceRegistry.RegisterKindFor(resource, "", kind)
@ -801,6 +802,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
storages[v.Name] = customresource.NewStorage( storages[v.Name] = customresource.NewStorage(
resource.GroupResource(), resource.GroupResource(),
singularResource.GroupResource(),
kind, kind,
schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind}, schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind},
customresource.NewStrategy( customresource.NewStrategy(

View File

@ -41,7 +41,7 @@ type CustomResourceStorage struct {
Scale *ScaleREST Scale *ScaleREST
} }
func NewStorage(resource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor, replicasPathMapping fieldmanager.ResourcePathMappings) CustomResourceStorage { func NewStorage(resource schema.GroupResource, singularResource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor, replicasPathMapping fieldmanager.ResourcePathMappings) CustomResourceStorage {
var storage CustomResourceStorage var storage CustomResourceStorage
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { NewFunc: func() runtime.Object {
@ -56,8 +56,9 @@ func NewStorage(resource schema.GroupResource, kind, listKind schema.GroupVersio
ret.SetGroupVersionKind(listKind) ret.SetGroupVersionKind(listKind)
return ret return ret
}, },
PredicateFunc: strategy.MatchCustomResourceDefinitionStorage, PredicateFunc: strategy.MatchCustomResourceDefinitionStorage,
DefaultQualifiedResource: resource, DefaultQualifiedResource: resource,
SingularQualifiedResource: singularResource,
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -93,6 +93,7 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcd3testi
table, _ := tableconvertor.New(headers) table, _ := tableconvertor.New(headers)
storage := customresource.NewStorage( storage := customresource.NewStorage(
groupResource,
groupResource, groupResource,
kind, kind,
schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"}, schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"},

View File

@ -43,10 +43,11 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*RES
strategy := NewStrategy(scheme) strategy := NewStrategy(scheme)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apiextensions.CustomResourceDefinition{} }, NewFunc: func() runtime.Object { return &apiextensions.CustomResourceDefinition{} },
NewListFunc: func() runtime.Object { return &apiextensions.CustomResourceDefinitionList{} }, NewListFunc: func() runtime.Object { return &apiextensions.CustomResourceDefinitionList{} },
PredicateFunc: MatchCustomResourceDefinition, PredicateFunc: MatchCustomResourceDefinition,
DefaultQualifiedResource: apiextensions.Resource("customresourcedefinitions"), DefaultQualifiedResource: apiextensions.Resource("customresourcedefinitions"),
SingularQualifiedResource: apiextensions.Resource("customresourcedefinition"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -372,6 +372,10 @@ func (storage *SimpleRESTStorage) ConvertToTable(ctx context.Context, obj runtim
return rest.NewDefaultTableConvertor(schema.GroupResource{Resource: "simple"}).ConvertToTable(ctx, obj, tableOptions) return rest.NewDefaultTableConvertor(schema.GroupResource{Resource: "simple"}).ConvertToTable(ctx, obj, tableOptions)
} }
func (storate *SimpleRESTStorage) GetSingularName() string {
return "simple"
}
func (storage *SimpleRESTStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { func (storage *SimpleRESTStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
storage.checkContext(ctx) storage.checkContext(ctx)
result := &genericapitesting.SimpleList{ result := &genericapitesting.SimpleList{
@ -575,6 +579,10 @@ func (s *ConnecterRESTStorage) NewConnectOptions() (runtime.Object, bool, string
return s.emptyConnectOptions, false, "" return s.emptyConnectOptions, false, ""
} }
func (s *ConnecterRESTStorage) GetSingularName() string {
return "simple"
}
type MetadataRESTStorage struct { type MetadataRESTStorage struct {
*SimpleRESTStorage *SimpleRESTStorage
types []string types []string
@ -619,6 +627,10 @@ type GetWithOptionsRootRESTStorage struct {
takesPath string takesPath string
} }
func (r *GetWithOptionsRootRESTStorage) GetSingularName() string {
return "simple"
}
func (r *GetWithOptionsRootRESTStorage) NamespaceScoped() bool { func (r *GetWithOptionsRootRESTStorage) NamespaceScoped() bool {
return false return false
} }
@ -687,6 +699,10 @@ func (storage *SimpleTypedStorage) checkContext(ctx context.Context) {
storage.actualNamespace, storage.namespacePresent = request.NamespaceFrom(ctx) storage.actualNamespace, storage.namespacePresent = request.NamespaceFrom(ctx)
} }
func (storage *SimpleTypedStorage) GetSingularName() string {
return "simple"
}
func bodyOrDie(response *http.Response) string { func bodyOrDie(response *http.Response) string {
defer response.Body.Close() defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body) body, err := ioutil.ReadAll(response.Body)
@ -823,6 +839,10 @@ func (UnimplementedRESTStorage) New() runtime.Object {
func (UnimplementedRESTStorage) Destroy() { func (UnimplementedRESTStorage) Destroy() {
} }
func (UnimplementedRESTStorage) GetSingularName() string {
return ""
}
// TestUnimplementedRESTStorage ensures that if a rest.Storage does not implement a given // TestUnimplementedRESTStorage ensures that if a rest.Storage does not implement a given
// method, that it is literally not registered with the server. In the past, // method, that it is literally not registered with the server. In the past,
// we registered everything, and returned method not supported if it didn't support // we registered everything, and returned method not supported if it didn't support
@ -4289,6 +4309,10 @@ func (storage *SimpleXGSubresourceRESTStorage) GroupVersionKind(containingGV sch
return storage.itemGVK return storage.itemGVK
} }
func (storage *SimpleXGSubresourceRESTStorage) GetSingularName() string {
return "simple"
}
func TestXGSubresource(t *testing.T) { func TestXGSubresource(t *testing.T) {
container := restful.NewContainer() container := restful.NewContainer()
container.Router(restful.CurlyRouter{}) container.Router(restful.CurlyRouter{})

View File

@ -1080,6 +1080,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if categoriesProvider, ok := storage.(rest.CategoriesProvider); ok { if categoriesProvider, ok := storage.(rest.CategoriesProvider); ok {
apiResource.Categories = categoriesProvider.Categories() apiResource.Categories = categoriesProvider.Categories()
} }
if !isSubresource {
singularNameProvider, ok := storage.(rest.SingularNameProvider)
if !ok {
return nil, nil, fmt.Errorf("resource %s must implement SingularNameProvider", resource)
}
apiResource.SingularName = singularNameProvider.GetSingularName()
}
if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok { if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok {
gvk := gvkProvider.GroupVersionKind(a.group.GroupVersion) gvk := gvkProvider.GroupVersionKind(a.group.GroupVersion)
apiResource.Group = gvk.Group apiResource.Group = gvk.Group

View File

@ -110,6 +110,9 @@ type Store struct {
// See qualifiedResourceFromContext for details. // See qualifiedResourceFromContext for details.
DefaultQualifiedResource schema.GroupResource DefaultQualifiedResource schema.GroupResource
// SingularQualifiedResource is the singular name of the resource.
SingularQualifiedResource schema.GroupResource
// KeyRootFunc returns the root etcd key for this resource; should not // KeyRootFunc returns the root etcd key for this resource; should not
// include trailing "/". This is used for operations that work on the // include trailing "/". This is used for operations that work on the
// entire collection (listing and watching). // entire collection (listing and watching).
@ -229,6 +232,8 @@ var _ rest.StandardStorage = &Store{}
var _ rest.TableConvertor = &Store{} var _ rest.TableConvertor = &Store{}
var _ GenericStore = &Store{} var _ GenericStore = &Store{}
var _ rest.SingularNameProvider = &Store{}
const ( const (
OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again" OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again"
resourceCountPollPeriodJitter = 1.2 resourceCountPollPeriodJitter = 1.2
@ -1320,6 +1325,12 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error {
if e.DefaultQualifiedResource.Empty() { if e.DefaultQualifiedResource.Empty() {
return fmt.Errorf("store %#v must have a non-empty qualified resource", e) return fmt.Errorf("store %#v must have a non-empty qualified resource", e)
} }
if e.SingularQualifiedResource.Empty() {
return fmt.Errorf("store %#v must have a non-empty singular qualified resource", e)
}
if e.DefaultQualifiedResource.Group != e.SingularQualifiedResource.Group {
return fmt.Errorf("store for %#v, singular and plural qualified resource's group name's must match", e)
}
if e.NewFunc == nil { if e.NewFunc == nil {
return fmt.Errorf("store for %s must have NewFunc set", e.DefaultQualifiedResource.String()) return fmt.Errorf("store for %s must have NewFunc set", e.DefaultQualifiedResource.String())
} }
@ -1515,6 +1526,10 @@ func (e *Store) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
return e.ResetFieldsStrategy.GetResetFields() return e.ResetFieldsStrategy.GetResetFields()
} }
func (e *Store) GetSingularName() string {
return e.SingularQualifiedResource.Resource
}
// validateIndexers will check the prefix of indexers. // validateIndexers will check the prefix of indexers.
func validateIndexers(indexers *cache.Indexers) error { func validateIndexers(indexers *cache.Indexers) error {
if indexers == nil { if indexers == nil {

View File

@ -2339,12 +2339,13 @@ func newTestGenericStoreRegistry(t *testing.T, scheme *runtime.Scheme, hasCacheE
} }
return destroyFunc, &Store{ return destroyFunc, &Store{
NewFunc: func() runtime.Object { return &example.Pod{} }, NewFunc: func() runtime.Object { return &example.Pod{} },
NewListFunc: func() runtime.Object { return &example.PodList{} }, NewListFunc: func() runtime.Object { return &example.PodList{} },
DefaultQualifiedResource: example.Resource("pods"), DefaultQualifiedResource: example.Resource("pods"),
CreateStrategy: strategy, SingularQualifiedResource: example.Resource("pod"),
UpdateStrategy: strategy, CreateStrategy: strategy,
DeleteStrategy: strategy, UpdateStrategy: strategy,
DeleteStrategy: strategy,
KeyRootFunc: func(ctx context.Context) string { KeyRootFunc: func(ctx context.Context) string {
return podPrefix return podPrefix
}, },

View File

@ -89,6 +89,12 @@ type CategoriesProvider interface {
Categories() []string Categories() []string
} }
// SingularNameProvider returns singular name of resources. This is used by kubectl discovery to have singular
// name representation of resources. In case of shortcut conflicts(with CRD shortcuts) singular name should always map to this resource.
type SingularNameProvider interface {
GetSingularName() string
}
// GroupVersionKindProvider is used to specify a particular GroupVersionKind to discovery. This is used for polymorphic endpoints // GroupVersionKindProvider is used to specify a particular GroupVersionKind to discovery. This is used for polymorphic endpoints
// which generally point to foreign versions. Scale refers to Scale.v1beta1.extensions for instance. // which generally point to foreign versions. Scale refers to Scale.v1beta1.extensions for instance.
// This trumps KindProvider since it is capable of providing the information required. // This trumps KindProvider since it is capable of providing the information required.

View File

@ -551,6 +551,10 @@ func (p *testGetterStorage) Get(ctx context.Context, name string, options *metav
return nil, nil return nil, nil
} }
func (p *testGetterStorage) GetSingularName() string {
return "getter"
}
type testNoVerbsStorage struct { type testNoVerbsStorage struct {
Version string Version string
} }
@ -571,6 +575,10 @@ func (p *testNoVerbsStorage) New() runtime.Object {
func (p *testNoVerbsStorage) Destroy() { func (p *testNoVerbsStorage) Destroy() {
} }
func (p *testNoVerbsStorage) GetSingularName() string {
return "noverb"
}
func fakeVersion() version.Info { func fakeVersion() version.Info {
return version.Info{ return version.Info{
Major: "42", Major: "42",

View File

@ -41,10 +41,11 @@ type REST struct {
func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST { func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST {
strategy := apiservice.NewStrategy(scheme) strategy := apiservice.NewStrategy(scheme)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apiregistration.APIService{} }, NewFunc: func() runtime.Object { return &apiregistration.APIService{} },
NewListFunc: func() runtime.Object { return &apiregistration.APIServiceList{} }, NewListFunc: func() runtime.Object { return &apiregistration.APIServiceList{} },
PredicateFunc: apiservice.MatchAPIService, PredicateFunc: apiservice.MatchAPIService,
DefaultQualifiedResource: apiregistration.Resource("apiservices"), DefaultQualifiedResource: apiregistration.Resource("apiservices"),
SingularQualifiedResource: apiregistration.Resource("apiservice"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -30,10 +30,11 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*reg
strategy := NewStrategy(scheme) strategy := NewStrategy(scheme)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &wardle.Fischer{} }, NewFunc: func() runtime.Object { return &wardle.Fischer{} },
NewListFunc: func() runtime.Object { return &wardle.FischerList{} }, NewListFunc: func() runtime.Object { return &wardle.FischerList{} },
PredicateFunc: MatchFischer, PredicateFunc: MatchFischer,
DefaultQualifiedResource: wardle.Resource("fischers"), DefaultQualifiedResource: wardle.Resource("fischers"),
SingularQualifiedResource: wardle.Resource("fischer"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -30,10 +30,11 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*reg
strategy := NewStrategy(scheme) strategy := NewStrategy(scheme)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &wardle.Flunder{} }, NewFunc: func() runtime.Object { return &wardle.Flunder{} },
NewListFunc: func() runtime.Object { return &wardle.FlunderList{} }, NewListFunc: func() runtime.Object { return &wardle.FlunderList{} },
PredicateFunc: MatchFlunder, PredicateFunc: MatchFlunder,
DefaultQualifiedResource: wardle.Resource("flunders"), DefaultQualifiedResource: wardle.Resource("flunders"),
SingularQualifiedResource: wardle.Resource("flunder"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,

View File

@ -55,7 +55,152 @@ run_assert_short_name_tests() {
output_message=$(kubectl get --raw=/api/v1) output_message=$(kubectl get --raw=/api/v1)
## test if a short name is exported during discovery ## test if a short name is exported during discovery
kube::test::if_has_string "${output_message}" '{"name":"configmaps","singularName":"","namespaced":true,"kind":"ConfigMap","verbs":\["create","delete","deletecollection","get","list","patch","update","watch"\],"shortNames":\["cm"\],"storageVersionHash":' kube::test::if_has_string "${output_message}" '{"name":"configmaps","singularName":"configmap","namespaced":true,"kind":"ConfigMap","verbs":\["create","delete","deletecollection","get","list","patch","update","watch"\],"shortNames":\["cm"\],"storageVersionHash":'
# check that there is no pod with the name test-crd-example
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
kubectl create -f - << __EOF__
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: examples.test.com
spec:
group: test.com
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
test:
type: string
names:
plural: examples
singular: example
shortNames:
- pod
kind: Example
__EOF__
# Test that we can list this new custom resource
kube::test::wait_object_assert customresourcedefinitions "{{range.items}}{{if eq ${id_field:?} \"examples.test.com\"}}{{$id_field}}:{{end}}{{end}}" 'examples.test.com:'
kubectl create -f - << __EOF__
apiVersion: test.com/v1
kind: Example
metadata:
name: test-crd-example
spec:
test: test
__EOF__
# Test that we can list this new custom resource
kube::test::wait_object_assert examples "{{range.items}}{{${id_field:?}}}:{{end}}" 'test-crd-example:'
output_message=$(kubectl get examples)
kube::test::if_has_string "${output_message}" "test-crd-example"
# test that get pod returns v1/pod instead crd
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
# invalidate cache and assure that still correct resource is shown
kubectl api-resources
# retest the above cases after invalidating cache
output_message=$(kubectl get examples)
kube::test::if_has_string "${output_message}" "test-crd-example"
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
# Cleanup
kubectl delete examples/test-crd-example
kubectl delete customresourcedefinition examples.test.com
set +o nounset
set +o errexit
}
run_assert_singular_name_tests() {
set -o nounset
set -o errexit
create_and_use_new_namespace
kube::log::status "Testing assert singular name"
# check that there is no pod with the name test-crd-example
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
kubectl create -f - << __EOF__
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: examples.test.com
spec:
group: test.com
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
test:
type: string
names:
plural: examples
singular: pod
kind: Example
__EOF__
# Test that we can list this new custom resource
kube::test::wait_object_assert customresourcedefinitions "{{range.items}}{{if eq ${id_field:?} \"examples.test.com\"}}{{$id_field}}:{{end}}{{end}}" 'examples.test.com:'
kubectl create -f - << __EOF__
apiVersion: test.com/v1
kind: Example
metadata:
name: test-crd-example
spec:
test: test
__EOF__
# Test that we can list this new custom resource
kube::test::wait_object_assert examples "{{range.items}}{{$id_field}}:{{end}}" 'test-crd-example:'
output_message=$(kubectl get examples)
kube::test::if_has_string "${output_message}" "test-crd-example"
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
# invalidate cache and assure that still correct resource is shown
kubectl api-resources
output_message=$(kubectl get examples)
kube::test::if_has_string "${output_message}" "test-crd-example"
output_message=$(kubectl get pod)
kube::test::if_has_not_string "${output_message}" "test-crd-example"
# Cleanup
kubectl delete examples/test-crd-example
kubectl delete customresourcedefinition examples.test.com
set +o nounset set +o nounset
set +o errexit set +o errexit

View File

@ -504,7 +504,17 @@ runTests() {
# Assert short name # # Assert short name #
######################### #########################
record_command run_assert_short_name_tests if kube::test::if_supports_resource "${customresourcedefinitions}" && kube::test::if_supports_resource "${pods}" && kube::test::if_supports_resource "${configmaps}" ; then
record_command run_assert_short_name_tests
fi
#########################
# Assert singular name #
#########################
if kube::test::if_supports_resource "${customresourcedefinitions}" && kube::test::if_supports_resource "${pods}" ; then
record_command run_assert_singular_name_tests
fi
######################### #########################
# Assert categories # # Assert categories #

View File

@ -690,6 +690,33 @@ func TestGroupPriorty(t *testing.T) {
}) })
} }
func TestSingularNames(t *testing.T) {
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--runtime-config=api/all=true"}, framework.SharedEtcd())
t.Cleanup(server.TearDownFn)
kubeClientSet, err := kubernetes.NewForConfig(server.ClientConfig)
require.NoError(t, err)
_, resources, err := kubeClientSet.Discovery().ServerGroupsAndResources()
require.NoError(t, err)
for _, rr := range resources {
for _, r := range rr.APIResources {
if strings.Contains(r.Name, "/") {
continue
}
if r.SingularName == "" {
t.Errorf("missing singularName for resource %q in %q", r.Name, rr.GroupVersion)
continue
}
if r.SingularName != strings.ToLower(r.Kind) {
t.Errorf("expected singularName for resource %q in %q to be %q, got %q", r.Name, rr.GroupVersion, strings.ToLower(r.Kind), r.SingularName)
continue
}
}
}
}
func makeCRDSpec(group string, kind string, namespaced bool, versions []string, categories ...string) apiextensionsv1.CustomResourceDefinitionSpec { func makeCRDSpec(group string, kind string, namespaced bool, versions []string, categories ...string) apiextensionsv1.CustomResourceDefinitionSpec {
scope := apiextensionsv1.NamespaceScoped scope := apiextensionsv1.NamespaceScoped
if !namespaced { if !namespaced {