Merge pull request #107993 from deads2k/simplify

prevent enabling beta by default for new api groups
This commit is contained in:
Kubernetes Prow Robot 2022-02-23 16:03:35 -08:00 committed by GitHub
commit 2fcdbd098c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 335 additions and 151 deletions

View File

@ -27,6 +27,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions" apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -146,7 +147,7 @@ func createAggregatorServer(aggregatorConfig *aggregatorapiserver.Config, delega
// let the CRD controller process the initial set of CRDs before starting the autoregistration controller. // let the CRD controller process the initial set of CRDs before starting the autoregistration controller.
// this prevents the autoregistration controller's initial sync from deleting APIServices for CRDs that still exist. // this prevents the autoregistration controller's initial sync from deleting APIServices for CRDs that still exist.
// we only need to do this if CRDs are enabled on this server. We can't use discovery because we are the source for discovery. // we only need to do this if CRDs are enabled on this server. We can't use discovery because we are the source for discovery.
if aggregatorConfig.GenericConfig.MergedResourceConfig.AnyResourceForGroupEnabled("apiextensions.k8s.io") { if aggregatorConfig.GenericConfig.MergedResourceConfig.ResourceEnabled(apiextensionsv1.SchemeGroupVersion.WithResource("customresourcedefinitions")) {
crdRegistrationController.WaitForInitialSync() crdRegistrationController.WaitForInitialSync()
} }
autoRegistrationController.Run(5, context.StopCh) autoRegistrationController.Run(5, context.StopCh)

View File

@ -55,6 +55,7 @@ import (
storageapiv1alpha1 "k8s.io/api/storage/v1alpha1" storageapiv1alpha1 "k8s.io/api/storage/v1alpha1"
storageapiv1beta1 "k8s.io/api/storage/v1beta1" storageapiv1beta1 "k8s.io/api/storage/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
utilnet "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
@ -549,7 +550,7 @@ func (m *Instance) InstallLegacyAPI(c *completedConfig, restOptionsGetter generi
// RESTStorageProvider is a factory type for REST storage. // RESTStorageProvider is a factory type for REST storage.
type RESTStorageProvider interface { type RESTStorageProvider interface {
GroupName() string GroupName() string
NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error)
} }
// InstallAPIs will install the APIs for the restStorageProviders if they are enabled. // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
@ -564,16 +565,14 @@ func (m *Instance) InstallAPIs(apiResourceConfigSource serverstorage.APIResource
for _, restStorageBuilder := range restStorageProviders { for _, restStorageBuilder := range restStorageProviders {
groupName := restStorageBuilder.GroupName() groupName := restStorageBuilder.GroupName()
if !apiResourceConfigSource.AnyResourceForGroupEnabled(groupName) { apiGroupInfo, err := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
klog.V(1).Infof("Skipping disabled API group %q.", groupName)
continue
}
apiGroupInfo, enabled, err := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
if err != nil { if err != nil {
return fmt.Errorf("problem initializing API group %q : %v", groupName, err) return fmt.Errorf("problem initializing API group %q : %v", groupName, err)
} }
if !enabled { if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
klog.Warningf("API group %q is not enabled, skipping.", groupName) // If we have no storage for any resource configured, this API group is effectively disabled.
// This can happen when an entire API group, version, or development-stage (alpha, beta, GA) is disabled.
klog.Infof("API group %q is not enabled, skipping.", groupName)
continue continue
} }
@ -640,11 +639,9 @@ func (n nodeAddressProvider) externalAddresses() ([]string, error) {
return addrs, nil return addrs, nil
} }
// DefaultAPIResourceConfigSource returns default configuration for an APIResource. var (
func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig { // stableAPIGroupVersionsEnabledByDefault is a list of our stable versions.
ret := serverstorage.NewResourceConfig() stableAPIGroupVersionsEnabledByDefault = []schema.GroupVersion{
// NOTE: GroupVersions listed here will be enabled by default. Don't put alpha versions in the list.
ret.EnableVersions(
admissionregistrationv1.SchemeGroupVersion, admissionregistrationv1.SchemeGroupVersion,
apiv1.SchemeGroupVersion, apiv1.SchemeGroupVersion,
appsv1.SchemeGroupVersion, appsv1.SchemeGroupVersion,
@ -652,34 +649,73 @@ func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
authorizationapiv1.SchemeGroupVersion, authorizationapiv1.SchemeGroupVersion,
autoscalingapiv1.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion,
autoscalingapiv2.SchemeGroupVersion, autoscalingapiv2.SchemeGroupVersion,
autoscalingapiv2beta1.SchemeGroupVersion,
autoscalingapiv2beta2.SchemeGroupVersion,
batchapiv1.SchemeGroupVersion, batchapiv1.SchemeGroupVersion,
batchapiv1beta1.SchemeGroupVersion,
certificatesapiv1.SchemeGroupVersion, certificatesapiv1.SchemeGroupVersion,
coordinationapiv1.SchemeGroupVersion, coordinationapiv1.SchemeGroupVersion,
discoveryv1.SchemeGroupVersion, discoveryv1.SchemeGroupVersion,
discoveryv1beta1.SchemeGroupVersion,
eventsv1.SchemeGroupVersion, eventsv1.SchemeGroupVersion,
eventsv1beta1.SchemeGroupVersion,
networkingapiv1.SchemeGroupVersion, networkingapiv1.SchemeGroupVersion,
nodev1.SchemeGroupVersion, nodev1.SchemeGroupVersion,
nodev1beta1.SchemeGroupVersion, // remove in 1.26
policyapiv1.SchemeGroupVersion, policyapiv1.SchemeGroupVersion,
policyapiv1beta1.SchemeGroupVersion,
rbacv1.SchemeGroupVersion, rbacv1.SchemeGroupVersion,
storageapiv1.SchemeGroupVersion, storageapiv1.SchemeGroupVersion,
storageapiv1beta1.SchemeGroupVersion,
schedulingapiv1.SchemeGroupVersion, schedulingapiv1.SchemeGroupVersion,
flowcontrolv1beta2.SchemeGroupVersion, }
// legacyBetaEnabledByDefaultResources is the list of beta resources we enable. You may only add to this list
// if your resource is already enabled by default in a beta level we still serve AND there is no stable API for it.
// see https://github.com/kubernetes/enhancements/tree/master/keps/sig-architecture/3136-beta-apis-off-by-default
// for more details.
legacyBetaEnabledByDefaultResources = []schema.GroupVersionResource{
autoscalingapiv2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"), // remove in 1.25
autoscalingapiv2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"), // remove in 1.26
batchapiv1beta1.SchemeGroupVersion.WithResource("cronjobs"), // remove in 1.25
discoveryv1beta1.SchemeGroupVersion.WithResource("endpointslices"), // remove in 1.25
eventsv1beta1.SchemeGroupVersion.WithResource("events"), // remove in 1.25
nodev1beta1.SchemeGroupVersion.WithResource("runtimeclasses"), // remove in 1.25
policyapiv1beta1.SchemeGroupVersion.WithResource("poddisruptionbudgets"), // remove in 1.25
policyapiv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"), // remove in 1.25
storageapiv1beta1.SchemeGroupVersion.WithResource("csinodes"), // remove in 1.25
storageapiv1beta1.SchemeGroupVersion.WithResource("csistoragecapacities"), // remove in 1.27
flowcontrolv1beta1.SchemeGroupVersion.WithResource("flowschemas"), // remove in 1.26
flowcontrolv1beta1.SchemeGroupVersion.WithResource("prioritylevelconfigurations"), // remove in 1.26
flowcontrolv1beta2.SchemeGroupVersion.WithResource("flowschemas"), // remove in 1.29
flowcontrolv1beta2.SchemeGroupVersion.WithResource("prioritylevelconfigurations"), // remove in 1.29
}
// betaAPIGroupVersionsDisabledByDefault is for all future beta groupVersions.
betaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
autoscalingapiv2beta1.SchemeGroupVersion,
autoscalingapiv2beta2.SchemeGroupVersion,
batchapiv1beta1.SchemeGroupVersion,
discoveryv1beta1.SchemeGroupVersion,
eventsv1beta1.SchemeGroupVersion,
nodev1beta1.SchemeGroupVersion, // remove in 1.26
policyapiv1beta1.SchemeGroupVersion,
storageapiv1beta1.SchemeGroupVersion,
flowcontrolv1beta1.SchemeGroupVersion, flowcontrolv1beta1.SchemeGroupVersion,
) flowcontrolv1beta2.SchemeGroupVersion,
// disable alpha versions explicitly so we have a full list of what's possible to serve }
ret.DisableVersions(
// alphaAPIGroupVersionsDisabledByDefault holds the alpha APIs we have. They are always disabled by default.
alphaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
apiserverinternalv1alpha1.SchemeGroupVersion, apiserverinternalv1alpha1.SchemeGroupVersion,
storageapiv1alpha1.SchemeGroupVersion, storageapiv1alpha1.SchemeGroupVersion,
flowcontrolv1alpha1.SchemeGroupVersion, flowcontrolv1alpha1.SchemeGroupVersion,
) }
)
// DefaultAPIResourceConfigSource returns default configuration for an APIResource.
func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
ret := serverstorage.NewResourceConfig()
// NOTE: GroupVersions listed here will be enabled by default. Don't put alpha or beta versions in the list.
ret.EnableVersions(stableAPIGroupVersionsEnabledByDefault...)
// disable alpha and beta versions explicitly so we have a full list of what's possible to serve
ret.DisableVersions(betaAPIGroupVersionsDisabledByDefault...)
ret.DisableVersions(alphaAPIGroupVersionsDisabledByDefault...)
// enable the legacy beta resources that were present before stopped serving new beta APIs by default.
ret.EnableResources(legacyBetaEnabledByDefaultResources...)
return ret return ret
} }

View File

@ -28,8 +28,16 @@ import (
"strings" "strings"
"testing" "testing"
autoscalingapiv2beta1 "k8s.io/api/autoscaling/v2beta1"
autoscalingapiv2beta2 "k8s.io/api/autoscaling/v2beta2"
batchapiv1beta1 "k8s.io/api/batch/v1beta1"
certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1" certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
apiv1 "k8s.io/api/core/v1" apiv1 "k8s.io/api/core/v1"
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
eventsv1beta1 "k8s.io/api/events/v1beta1"
nodev1beta1 "k8s.io/api/node/v1beta1"
policyapiv1beta1 "k8s.io/api/policy/v1beta1"
storageapiv1beta1 "k8s.io/api/storage/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilnet "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net"
@ -50,6 +58,7 @@ import (
kubeversion "k8s.io/component-base/version" kubeversion "k8s.io/component-base/version"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
flowcontrolv1beta2 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2"
"k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/apis/networking"
apisstorage "k8s.io/kubernetes/pkg/apis/storage" apisstorage "k8s.io/kubernetes/pkg/apis/storage"
"k8s.io/kubernetes/pkg/controlplane/reconcilers" "k8s.io/kubernetes/pkg/controlplane/reconcilers"
@ -173,7 +182,7 @@ func TestCertificatesRestStorageStrategies(t *testing.T) {
defer etcdserver.Terminate(t) defer etcdserver.Terminate(t)
certStorageProvider := certificatesrest.RESTStorageProvider{} certStorageProvider := certificatesrest.RESTStorageProvider{}
apiGroupInfo, _, err := certStorageProvider.NewRESTStorage(apiserverCfg.ExtraConfig.APIResourceConfigSource, apiserverCfg.GenericConfig.RESTOptionsGetter) apiGroupInfo, err := certStorageProvider.NewRESTStorage(apiserverCfg.ExtraConfig.APIResourceConfigSource, apiserverCfg.GenericConfig.RESTOptionsGetter)
if err != nil { if err != nil {
t.Fatalf("unexpected error from REST storage: %v", err) t.Fatalf("unexpected error from REST storage: %v", err)
} }
@ -460,3 +469,56 @@ func TestNoAlphaVersionsEnabledByDefault(t *testing.T) {
} }
} }
} }
func TestNoBetaVersionsEnabledByDefault(t *testing.T) {
config := DefaultAPIResourceConfigSource()
for gv, enable := range config.GroupVersionConfigs {
if enable && strings.Contains(gv.Version, "beta") {
t.Errorf("Beta API version %s enabled by default", gv.String())
}
}
}
func TestNewBetaResourcesEnabledByDefault(t *testing.T) {
// legacyEnabledBetaResources is nearly a duplication from elsewhere. This is intentional. These types already have
// GA equivalents available and should therefore never have a beta enabled by default again.
legacyEnabledBetaResources := map[schema.GroupVersionResource]bool{
autoscalingapiv2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): true,
autoscalingapiv2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): true,
batchapiv1beta1.SchemeGroupVersion.WithResource("cronjobs"): true,
discoveryv1beta1.SchemeGroupVersion.WithResource("endpointslices"): true,
eventsv1beta1.SchemeGroupVersion.WithResource("events"): true,
nodev1beta1.SchemeGroupVersion.WithResource("runtimeclasses"): true,
policyapiv1beta1.SchemeGroupVersion.WithResource("poddisruptionbudgets"): true,
policyapiv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"): true,
storageapiv1beta1.SchemeGroupVersion.WithResource("csinodes"): true,
storageapiv1beta1.SchemeGroupVersion.WithResource("csistoragecapacities"): true,
}
// legacyBetaResourcesWithoutStableEquivalents contains those groupresources that were enabled by default as beta
// before we changed that policy and do not have stable versions. These resources are allowed to have additional
// beta versions enabled by default. Nothing new should be added here. There are no future exceptions because there
// are no more beta resources enabled by default.
legacyBetaResourcesWithoutStableEquivalents := map[schema.GroupResource]bool{
storageapiv1beta1.SchemeGroupVersion.WithResource("csistoragecapacities").GroupResource(): true,
flowcontrolv1beta2.SchemeGroupVersion.WithResource("flowschemas").GroupResource(): true,
flowcontrolv1beta2.SchemeGroupVersion.WithResource("prioritylevelconfigurations").GroupResource(): true,
}
config := DefaultAPIResourceConfigSource()
for gvr, enable := range config.ResourceConfigs {
if !strings.Contains(gvr.Version, "beta") {
continue // only check beta things
}
if !enable {
continue // only check things that are enabled
}
if legacyEnabledBetaResources[gvr] {
continue // this is a legacy beta resource
}
if legacyBetaResourcesWithoutStableEquivalents[gvr.GroupResource()] {
continue // this is another beta of a legacy beta resource with no stable equivalent
}
t.Errorf("no new beta resources can be enabled by default, see https://github.com/kubernetes/enhancements/blob/0ad0fc8269165ca300d05ca51c7ce190a79976a5/keps/sig-architecture/3136-beta-apis-off-by-default/README.md: %v", gvr)
}
}

View File

@ -30,17 +30,17 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(admissionregistration.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(admissionregistration.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[admissionregistrationv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[admissionregistrationv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -31,16 +31,16 @@ import (
type StorageProvider struct{} type StorageProvider struct{}
// NewRESTStorage returns a StorageProvider // NewRESTStorage returns a StorageProvider
func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiserverinternal.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiserverinternal.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
if storageMap, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[apiserverv1alpha1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[apiserverv1alpha1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p StorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p StorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -35,18 +35,18 @@ import (
type StorageProvider struct{} type StorageProvider struct{}
// NewRESTStorage returns APIGroupInfo object. // NewRESTStorage returns APIGroupInfo object.
func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[appsapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[appsapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p StorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p StorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -33,7 +33,7 @@ type RESTStorageProvider struct {
APIAudiences authenticator.Audiences APIAudiences authenticator.Audiences
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
// TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled. // TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled.
// if p.Authenticator == nil { // if p.Authenticator == nil {
// return genericapiserver.APIGroupInfo{}, false // return genericapiserver.APIGroupInfo{}, false
@ -47,7 +47,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
apiGroupInfo.VersionedResourcesStorageMap[authenticationv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[authenticationv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {

View File

@ -36,9 +36,9 @@ type RESTStorageProvider struct {
RuleResolver authorizer.RuleResolver RuleResolver authorizer.RuleResolver
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
if p.Authorizer == nil { if p.Authorizer == nil {
return genericapiserver.APIGroupInfo{}, false, nil return genericapiserver.APIGroupInfo{}, nil
} }
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(authorization.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(authorization.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
@ -49,7 +49,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
apiGroupInfo.VersionedResourcesStorageMap[authorizationv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[authorizationv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {

View File

@ -32,36 +32,36 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v2beta2Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v2beta2Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2beta2.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2beta2.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v2Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v2Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v2beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v2beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv2beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -31,24 +31,24 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[batchapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[batchapiv1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[batchapiv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[batchapiv1beta1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -29,18 +29,18 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -29,17 +29,17 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(coordination.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(coordination.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[coordinationv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[coordinationv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -32,24 +32,24 @@ import (
type StorageProvider struct{} type StorageProvider struct{}
// NewRESTStorage returns a new storage provider. // NewRESTStorage returns a new storage provider.
func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p StorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(discovery.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(discovery.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[discoveryv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[discoveryv1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[discoveryv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[discoveryv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p StorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p StorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -34,24 +34,24 @@ type RESTStorageProvider struct {
TTL time.Duration TTL time.Duration
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(events.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(events.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[eventsapiv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[eventsapiv1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[eventsapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[eventsapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -54,28 +54,28 @@ type RESTStorageProvider struct {
const PostStartHookName = "priority-and-fairness-config-producer" const PostStartHookName = "priority-and-fairness-config-producer"
// NewRESTStorage creates a new rest storage for flow-control api models. // NewRESTStorage creates a new rest storage for flow-control api models.
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(flowcontrol.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(flowcontrol.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1alpha1.SchemeGroupVersion); err != nil { if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1alpha1.SchemeGroupVersion); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1alpha1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1alpha1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1beta1.SchemeGroupVersion); err != nil { if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1beta1.SchemeGroupVersion); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1beta2.SchemeGroupVersion); err != nil { if storageMap, err := p.storage(apiResourceConfigSource, restOptionsGetter, flowcontrolapisv1beta2.SchemeGroupVersion); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1beta2.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[flowcontrolapisv1beta2.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, groupVersion schema.GroupVersion) (map[string]rest.Storage, error) { func (p RESTStorageProvider) storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, groupVersion schema.GroupVersion) (map[string]rest.Storage, error) {

View File

@ -31,18 +31,18 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(networking.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(networking.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[networkingapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[networkingapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -32,23 +32,23 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
// NewRESTStorage returns a RESTStorageProvider // NewRESTStorage returns a RESTStorageProvider
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(nodeinternal.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(nodeinternal.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
// remove in 1.26 // remove in 1.26
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[nodev1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[nodev1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[nodev1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[nodev1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -31,24 +31,24 @@ import (
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(policy.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(policy.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[policyapiv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[policyapiv1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[policyapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[policyapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -65,18 +65,18 @@ type RESTStorageProvider struct {
var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{} var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(rbac.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(rbac.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.storage(rbacapiv1.SchemeGroupVersion, apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.storage(rbacapiv1.SchemeGroupVersion, apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[rbacapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[rbacapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) storage(version schema.GroupVersion, apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) storage(version schema.GroupVersion, apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -44,16 +44,16 @@ type RESTStorageProvider struct{}
var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{} var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(scheduling.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(scheduling.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[schedulingapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[schedulingapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -36,28 +36,28 @@ import (
type RESTStorageProvider struct { type RESTStorageProvider struct {
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(storageapi.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(storageapi.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo // TODO refactor the plumbing to provide the information in the APIGroupInfo
if storageMap, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[storageapiv1alpha1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[storageapiv1alpha1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[storageapiv1beta1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[storageapiv1beta1.SchemeGroupVersion.Version] = storageMap
} }
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
return genericapiserver.APIGroupInfo{}, false, err return genericapiserver.APIGroupInfo{}, err
} else if len(storageMap) > 0 { } else if len(storageMap) > 0 {
apiGroupInfo.VersionedResourcesStorageMap[storageapiv1.SchemeGroupVersion.Version] = storageMap apiGroupInfo.VersionedResourcesStorageMap[storageapiv1.SchemeGroupVersion.Version] = storageMap
} }
return apiGroupInfo, true, nil return apiGroupInfo, nil
} }
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {

View File

@ -76,25 +76,8 @@ var (
} }
groupVersionMatchersOrder = []string{APIAll, APIGA, APIBeta, APIAlpha} groupVersionMatchersOrder = []string{APIAll, APIGA, APIBeta, APIAlpha}
groupVersionResourceMatchers = map[string]func(gvr schema.GroupVersionResource) bool{
// allows users to address all api versions
APIAll: func(gvr schema.GroupVersionResource) bool { return true },
// allows users to address all api versions in the form v[0-9]+
APIGA: func(gvr schema.GroupVersionResource) bool { return gaPattern.MatchString(gvr.Version) },
// allows users to address all beta api versions
APIBeta: func(gvr schema.GroupVersionResource) bool { return betaPattern.MatchString(gvr.Version) },
// allows users to address all alpha api versions
APIAlpha: func(gvr schema.GroupVersionResource) bool { return alphaPattern.MatchString(gvr.Version) },
}
) )
func resourceMatcherForVersion(gv schema.GroupVersion) func(gvr schema.GroupVersionResource) bool {
return func(gvr schema.GroupVersionResource) bool {
return gv == gvr.GroupVersion()
}
}
// MergeAPIResourceConfigs merges the given defaultAPIResourceConfig with the given resourceConfigOverrides. // MergeAPIResourceConfigs merges the given defaultAPIResourceConfig with the given resourceConfigOverrides.
// Exclude the groups not registered in registry, and check if version is // Exclude the groups not registered in registry, and check if version is
// not registered in group, then it will fail. // not registered in group, then it will fail.
@ -115,8 +98,6 @@ func MergeAPIResourceConfigs(
} else { } else {
return nil, fmt.Errorf("invalid value %v=%v", flag, value) return nil, fmt.Errorf("invalid value %v=%v", flag, value)
} }
// remove individual resource preferences that were hardcoded into the default. The override trumps those settings.
resourceConfig.RemoveMatchingResourcePreferences(groupVersionResourceMatchers[flag])
} }
} }
@ -187,8 +168,6 @@ func MergeAPIResourceConfigs(
// apply version preferences first, so that we can remove the hardcoded resource preferences that are being overridden // apply version preferences first, so that we can remove the hardcoded resource preferences that are being overridden
for _, versionPreference := range versionPreferences { for _, versionPreference := range versionPreferences {
// if a user has expressed a preference about a version, that preference takes priority over the hardcoded resources
resourceConfig.RemoveMatchingResourcePreferences(resourceMatcherForVersion(versionPreference.groupVersion))
if versionPreference.enabled { if versionPreference.enabled {
// enable the groupVersion for "group/version=true" // enable the groupVersion for "group/version=true"
resourceConfig.EnableVersions(versionPreference.groupVersion) resourceConfig.EnableVersions(versionPreference.groupVersion)

View File

@ -80,7 +80,14 @@ func TestParseRuntimeConfig(t *testing.T) {
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion) config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
return config return config
}, },
expectedEnabledAPIs: defaultFakeEnabledResources(), expectedEnabledAPIs: map[schema.GroupVersionResource]bool{
extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"): false, // this becomes false because the DisableVersions set in the defaultConfig is now order dependent.
extensionsapiv1beta1.SchemeGroupVersion.WithResource("deployments"): false,
extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicasets"): false,
extensionsapiv1beta1.SchemeGroupVersion.WithResource("daemonsets"): false,
appsv1.SchemeGroupVersion.WithResource("deployments"): true,
apiv1.SchemeGroupVersion.WithResource("pods"): true,
},
err: false, err: false,
}, },
{ {
@ -147,8 +154,6 @@ func TestParseRuntimeConfig(t *testing.T) {
expectedAPIConfig: func() *serverstore.ResourceConfig { expectedAPIConfig: func() *serverstore.ResourceConfig {
config := newFakeAPIResourceConfigSource() config := newFakeAPIResourceConfigSource()
config.EnableVersions(scheme.PrioritizedVersionsAllGroups()...) config.EnableVersions(scheme.PrioritizedVersionsAllGroups()...)
// disabling groups of APIs removes the individual resource preferences from the default
config.RemoveMatchingResourcePreferences(matchAllExplicitResourcesForFake)
return config return config
}, },
expectedEnabledAPIs: map[schema.GroupVersionResource]bool{ expectedEnabledAPIs: map[schema.GroupVersionResource]bool{
@ -174,8 +179,6 @@ func TestParseRuntimeConfig(t *testing.T) {
config := newFakeAPIResourceConfigSource() config := newFakeAPIResourceConfigSource()
config.DisableVersions(appsv1.SchemeGroupVersion) config.DisableVersions(appsv1.SchemeGroupVersion)
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion) config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
// disabling groups of APIs removes the individual resource preferences from the default
config.RemoveMatchingResourcePreferences(matchAllExplicitResourcesForFake)
return config return config
}, },
expectedEnabledAPIs: map[schema.GroupVersionResource]bool{ expectedEnabledAPIs: map[schema.GroupVersionResource]bool{
@ -243,8 +246,6 @@ func TestParseRuntimeConfig(t *testing.T) {
expectedAPIConfig: func() *serverstore.ResourceConfig { expectedAPIConfig: func() *serverstore.ResourceConfig {
config := newFakeAPIResourceConfigSource() config := newFakeAPIResourceConfigSource()
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion) config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
// disabling groups of APIs removes the individual resource preferences from the default
config.RemoveMatchingResourcePreferences(matchAllExplicitResourcesForFake)
return config return config
}, },
expectedEnabledAPIs: map[schema.GroupVersionResource]bool{ expectedEnabledAPIs: map[schema.GroupVersionResource]bool{
@ -290,8 +291,6 @@ func TestParseRuntimeConfig(t *testing.T) {
expectedAPIConfig: func() *serverstore.ResourceConfig { expectedAPIConfig: func() *serverstore.ResourceConfig {
config := newFakeAPIResourceConfigSource() config := newFakeAPIResourceConfigSource()
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion) config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
// disabling groups of APIs removes the individual resource preferences from the default
config.RemoveMatchingResourcePreferences(matchAllExplicitResourcesForFake)
return config return config
}, },
expectedEnabledAPIs: map[schema.GroupVersionResource]bool{ expectedEnabledAPIs: map[schema.GroupVersionResource]bool{
@ -568,17 +567,6 @@ func newFakeAPIResourceConfigSource() *serverstore.ResourceConfig {
return ret return ret
} }
func matchAllExplicitResourcesForFake(gvr schema.GroupVersionResource) bool {
switch gvr {
case extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"),
extensionsapiv1beta1.SchemeGroupVersion.WithResource("deployments"),
extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicasets"),
extensionsapiv1beta1.SchemeGroupVersion.WithResource("daemonsets"):
return true
}
return false
}
// apiResourcesToCheck are the apis we use in this set of unit tests. They will be check for enable/disable status // apiResourcesToCheck are the apis we use in this set of unit tests. They will be check for enable/disable status
func apiResourcesToCheck() []schema.GroupVersionResource { func apiResourcesToCheck() []schema.GroupVersionResource {
return []schema.GroupVersionResource{ return []schema.GroupVersionResource{

View File

@ -37,27 +37,38 @@ func NewResourceConfig() *ResourceConfig {
return &ResourceConfig{GroupVersionConfigs: map[schema.GroupVersion]bool{}, ResourceConfigs: map[schema.GroupVersionResource]bool{}} return &ResourceConfig{GroupVersionConfigs: map[schema.GroupVersion]bool{}, ResourceConfigs: map[schema.GroupVersionResource]bool{}}
} }
// DisableMatchingVersions disables all group/versions for which the matcher function returns true. It does not modify individual resource enablement/disablement. // DisableMatchingVersions disables all group/versions for which the matcher function returns true.
// This will remove any preferences previously set on individual resources.
func (o *ResourceConfig) DisableMatchingVersions(matcher func(gv schema.GroupVersion) bool) { func (o *ResourceConfig) DisableMatchingVersions(matcher func(gv schema.GroupVersion) bool) {
for k := range o.GroupVersionConfigs { for version := range o.GroupVersionConfigs {
if matcher(k) { if matcher(version) {
o.GroupVersionConfigs[k] = false o.GroupVersionConfigs[version] = false
o.removeMatchingResourcePreferences(resourceMatcherForVersion(version))
} }
} }
} }
// EnableMatchingVersions enables all group/versions for which the matcher function returns true. It does not modify individual resource enablement/disablement. // EnableMatchingVersions enables all group/versions for which the matcher function returns true.
// This will remove any preferences previously set on individual resources.
func (o *ResourceConfig) EnableMatchingVersions(matcher func(gv schema.GroupVersion) bool) { func (o *ResourceConfig) EnableMatchingVersions(matcher func(gv schema.GroupVersion) bool) {
for k := range o.GroupVersionConfigs { for version := range o.GroupVersionConfigs {
if matcher(k) { if matcher(version) {
o.GroupVersionConfigs[k] = true o.GroupVersionConfigs[version] = true
o.removeMatchingResourcePreferences(resourceMatcherForVersion(version))
} }
} }
} }
// RemoveMatchingResourcePreferences removes individual resource preferences that match. This is useful when an override of a version or level enablement should // resourceMatcherForVersion matches resources in the specified version
func resourceMatcherForVersion(gv schema.GroupVersion) func(gvr schema.GroupVersionResource) bool {
return func(gvr schema.GroupVersionResource) bool {
return gv == gvr.GroupVersion()
}
}
// removeMatchingResourcePreferences removes individual resource preferences that match. This is useful when an override of a version or level enablement should
// override the previously individual preferences. // override the previously individual preferences.
func (o *ResourceConfig) RemoveMatchingResourcePreferences(matcher func(gvr schema.GroupVersionResource) bool) { func (o *ResourceConfig) removeMatchingResourcePreferences(matcher func(gvr schema.GroupVersionResource) bool) {
keysToRemove := []schema.GroupVersionResource{} keysToRemove := []schema.GroupVersionResource{}
for k := range o.ResourceConfigs { for k := range o.ResourceConfigs {
if matcher(k) { if matcher(k) {
@ -70,20 +81,30 @@ func (o *ResourceConfig) RemoveMatchingResourcePreferences(matcher func(gvr sche
} }
// DisableVersions disables the versions entirely. // DisableVersions disables the versions entirely.
// This will remove any preferences previously set on individual resources.
func (o *ResourceConfig) DisableVersions(versions ...schema.GroupVersion) { func (o *ResourceConfig) DisableVersions(versions ...schema.GroupVersion) {
for _, version := range versions { for _, version := range versions {
o.GroupVersionConfigs[version] = false o.GroupVersionConfigs[version] = false
// a preference about a version takes priority over the previously set resources
o.removeMatchingResourcePreferences(resourceMatcherForVersion(version))
} }
} }
// EnableVersions enables all resources in a given groupVersion.
// This will remove any preferences previously set on individual resources.
func (o *ResourceConfig) EnableVersions(versions ...schema.GroupVersion) { func (o *ResourceConfig) EnableVersions(versions ...schema.GroupVersion) {
for _, version := range versions { for _, version := range versions {
o.GroupVersionConfigs[version] = true o.GroupVersionConfigs[version] = true
// a preference about a version takes priority over the previously set resources
o.removeMatchingResourcePreferences(resourceMatcherForVersion(version))
} }
} }
// TODO this must be removed and we enable/disable individual resources. // TODO this must be removed and we enable/disable individual resources.
func (o *ResourceConfig) VersionEnabled(version schema.GroupVersion) bool { func (o *ResourceConfig) versionEnabled(version schema.GroupVersion) bool {
enabled, _ := o.GroupVersionConfigs[version] enabled, _ := o.GroupVersionConfigs[version]
return enabled return enabled
} }
@ -107,7 +128,7 @@ func (o *ResourceConfig) ResourceEnabled(resource schema.GroupVersionResource) b
return resourceEnabled return resourceEnabled
} }
if !o.VersionEnabled(resource.GroupVersion()) { if !o.versionEnabled(resource.GroupVersion()) {
return false return false
} }
// they are enabled by default. // they are enabled by default.
@ -117,7 +138,7 @@ func (o *ResourceConfig) ResourceEnabled(resource schema.GroupVersionResource) b
func (o *ResourceConfig) AnyResourceForGroupEnabled(group string) bool { func (o *ResourceConfig) AnyResourceForGroupEnabled(group string) bool {
for version := range o.GroupVersionConfigs { for version := range o.GroupVersionConfigs {
if version.Group == group { if version.Group == group {
if o.VersionEnabled(version) { if o.versionEnabled(version) {
return true return true
} }
} }

View File

@ -32,13 +32,13 @@ func TestDisabledVersion(t *testing.T) {
config.DisableVersions(g1v1) config.DisableVersions(g1v1)
config.EnableVersions(g1v2, g2v1) config.EnableVersions(g1v2, g2v1)
if config.VersionEnabled(g1v1) { if config.versionEnabled(g1v1) {
t.Errorf("expected disabled for %v, from %v", g1v1, config) t.Errorf("expected disabled for %v, from %v", g1v1, config)
} }
if !config.VersionEnabled(g1v2) { if !config.versionEnabled(g1v2) {
t.Errorf("expected enabled for %v, from %v", g1v1, config) t.Errorf("expected enabled for %v, from %v", g1v1, config)
} }
if !config.VersionEnabled(g2v1) { if !config.versionEnabled(g2v1) {
t.Errorf("expected enabled for %v, from %v", g1v1, config) t.Errorf("expected enabled for %v, from %v", g1v1, config)
} }
} }

View File

@ -240,6 +240,7 @@ func getAllResourcesAlias(resource schema.GroupResource) schema.GroupResource {
func (s *DefaultStorageFactory) getStorageGroupResource(groupResource schema.GroupResource) schema.GroupResource { func (s *DefaultStorageFactory) getStorageGroupResource(groupResource schema.GroupResource) schema.GroupResource {
for _, potentialStorageResource := range s.Overrides[groupResource].cohabitatingResources { for _, potentialStorageResource := range s.Overrides[groupResource].cohabitatingResources {
// TODO deads2k or liggitt determine if have ever stored any of our cohabitating resources in a different location on new clusters
if s.APIResourceConfigSource.AnyResourceForGroupEnabled(potentialStorageResource.Group) { if s.APIResourceConfigSource.AnyResourceForGroupEnabled(potentialStorageResource.Group) {
return potentialStorageResource return potentialStorageResource
} }

View File

@ -0,0 +1,96 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiserver
import (
"strings"
"testing"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestNoNewBetaAPIsByDefault(t *testing.T) {
// yes, this *is* a copy/paste from somewhere else. We really do mean it when we say you shouldn't be modifying
// this list and this test was created to make it more painful.
// legacyBetaEnabledByDefaultResources is the list of beta resources we enable. You may not add to this list
legacyBetaEnabledByDefaultResources := map[schema.GroupVersionResource]bool{
gvr("autoscaling", "v2beta1", "horizontalpodautoscalers"): true, // remove in 1.25
gvr("autoscaling", "v2beta2", "horizontalpodautoscalers"): true, // remove in 1.26
gvr("batch", "v1beta1", "jobtemplates"): true, // remove in 1.25
gvr("batch", "v1beta1", "cronjobs"): true, // remove in 1.25
gvr("discovery.k8s.io", "v1beta1", "endpointslices"): true, // remove in 1.25
gvr("events.k8s.io", "v1beta1", "events"): true, // remove in 1.25
gvr("node.k8s.io", "v1beta1", "runtimeclasses"): true, // remove in 1.25
gvr("policy", "v1beta1", "poddisruptionbudgets"): true, // remove in 1.25
gvr("policy", "v1beta1", "podsecuritypolicies"): true, // remove in 1.25
gvr("storage.k8s.io", "v1beta1", "csinodes"): true, // remove in 1.25
gvr("storage.k8s.io", "v1beta1", "csistoragecapacities"): true, // remove in 1.27
gvr("flowcontrol.apiserver.k8s.io", "v1beta1", "flowschemas"): true, // remove in 1.26
gvr("flowcontrol.apiserver.k8s.io", "v1beta1", "prioritylevelconfigurations"): true, // remove in 1.26
gvr("flowcontrol.apiserver.k8s.io", "v1beta2", "flowschemas"): true, // remove in 1.29
gvr("flowcontrol.apiserver.k8s.io", "v1beta2", "prioritylevelconfigurations"): true, // remove in 1.29
}
// legacyBetaResourcesWithoutStableEquivalents contains those groupresources that were enabled by default as beta
// before we changed that policy and do not have stable versions. These resources are allowed to have additional
// beta versions enabled by default. Nothing new should be added here. There are no future exceptions because there
// are no more beta resources enabled by default.
legacyBetaResourcesWithoutStableEquivalents := map[schema.GroupResource]bool{
gvr("storage.k8s.io", "v1beta1", "csistoragecapacities").GroupResource(): true,
gvr("flowcontrol.apiserver.k8s.io", "v1beta1", "flowschemas").GroupResource(): true,
gvr("flowcontrol.apiserver.k8s.io", "v1beta1", "prioritylevelconfigurations").GroupResource(): true,
}
// if you found this because you want to create an integration test for your new beta API, the method you're looking for
// is this setupWithResources method and you need to pass the resource you want to enable into it.
_, kubeClient, closeFn := setupWithResources(t,
[]schema.GroupVersion{},
[]schema.GroupVersionResource{},
)
defer closeFn()
_, allResourceLists, err := kubeClient.Discovery().ServerGroupsAndResources()
if err != nil {
t.Error(err)
}
for _, currResourceList := range allResourceLists {
for _, currResource := range currResourceList.APIResources {
if !strings.Contains(currResource.Version, "beta") {
continue // skip non-beta apis
}
if strings.Contains(currResource.Name, "/") {
continue // skip subresources
}
enabledGVR := schema.GroupVersionResource{
Group: currResource.Group,
Version: currResource.Version,
Resource: currResource.Name,
}
if legacyBetaEnabledByDefaultResources[enabledGVR] {
continue
}
if legacyBetaResourcesWithoutStableEquivalents[enabledGVR.GroupResource()] {
continue
}
t.Errorf("%v is a new beta API. New beta APIs may not be enabled by default. "+
"See https://github.com/kubernetes/enhancements/blob/0ad0fc8269165ca300d05ca51c7ce190a79976a5/keps/sig-architecture/3136-beta-apis-off-by-default/README.md "+
"for more details.", enabledGVR)
}
}
}