mirror of https://github.com/k3s-io/k3s
Merge pull request #42225 from nikhiljindal/DisableAlphaAPIs
Automatic merge from submit-queue (batch tested with PRs 44019, 42225) federation: Fixing runtime-config support for federation-apiserver Fixes https://github.com/kubernetes/kubernetes/issues/42587 Ref https://github.com/kubernetes/kubernetes/issues/38593 Fixing the broken `--runtime-config` flag support in federation-apiserver. Fixing the bugs and using it to disable batch and autoscaling groups. Users can enable them by passing `--runtime-config=apis/all=true` to federation-apiserver. ~This also includes a bug fix to kube-apiserver registry that allows users to disable api/v1 resources~ cc @kubernetes/sig-federation-pr-reviewspull/6/head
commit
e18843d353
|
@ -15,6 +15,7 @@ go_library(
|
|||
"core.go",
|
||||
"extensions.go",
|
||||
"federation.go",
|
||||
"install.go",
|
||||
"plugins.go",
|
||||
"server.go",
|
||||
],
|
||||
|
@ -25,16 +26,21 @@ go_library(
|
|||
"//federation/apis/core/v1:go_default_library",
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/apis/federation/install:go_default_library",
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/cmd/federation-apiserver/app/options:go_default_library",
|
||||
"//federation/registry/cluster/etcd:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/autoscaling:go_default_library",
|
||||
"//pkg/apis/autoscaling/install:go_default_library",
|
||||
"//pkg/apis/autoscaling/v1:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//pkg/apis/batch/v1:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//pkg/apis/extensions/v1beta1:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/cloudprovider/providers:go_default_library",
|
||||
|
|
|
@ -21,24 +21,34 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||
autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1"
|
||||
hpastorage "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/storage"
|
||||
)
|
||||
|
||||
func installAutoscalingAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
|
||||
hpaStorage, hpaStatusStorage := hpastorage.NewREST(optsGetter)
|
||||
|
||||
autoscalingResources := map[string]rest.Storage{
|
||||
"horizontalpodautoscalers": hpaStorage,
|
||||
"horizontalpodautoscalers/status": hpaStatusStorage,
|
||||
func installAutoscalingAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
|
||||
hpaStorageFn := func() map[string]rest.Storage {
|
||||
hpaStorage, hpaStatusStorage := hpastorage.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"horizontalpodautoscalers": hpaStorage,
|
||||
"horizontalpodautoscalers/status": hpaStatusStorage,
|
||||
}
|
||||
}
|
||||
resourcesStorageMap := map[string]getResourcesStorageFunc{
|
||||
"horizontalpodautoscalers": hpaStorageFn,
|
||||
}
|
||||
shouldInstallGroup, resources := enabledResources(autoscalingv1.SchemeGroupVersion, resourcesStorageMap, apiResourceConfigSource)
|
||||
if !shouldInstallGroup {
|
||||
return
|
||||
}
|
||||
autoscalingGroupMeta := api.Registry.GroupOrDie(autoscaling.GroupName)
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *autoscalingGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1": autoscalingResources,
|
||||
"v1": resources,
|
||||
},
|
||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
|
|
|
@ -21,24 +21,34 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||
batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
|
||||
jobstorage "k8s.io/kubernetes/pkg/registry/batch/job/storage"
|
||||
)
|
||||
|
||||
func installBatchAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
|
||||
jobStorage := jobstorage.NewStorage(optsGetter)
|
||||
|
||||
batchResources := map[string]rest.Storage{
|
||||
"jobs": jobStorage.Job,
|
||||
"jobs/status": jobStorage.Status,
|
||||
func installBatchAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
|
||||
jobsStorageFn := func() map[string]rest.Storage {
|
||||
jobStorage := jobstorage.NewStorage(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"jobs": jobStorage.Job,
|
||||
"jobs/status": jobStorage.Status,
|
||||
}
|
||||
}
|
||||
resourcesStorageMap := map[string]getResourcesStorageFunc{
|
||||
"jobs": jobsStorageFn,
|
||||
}
|
||||
shouldInstallGroup, resources := enabledResources(batchv1.SchemeGroupVersion, resourcesStorageMap, apiResourceConfigSource)
|
||||
if !shouldInstallGroup {
|
||||
return
|
||||
}
|
||||
batchGroupMeta := api.Registry.GroupOrDie(batch.GroupName)
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *batchGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1": batchResources,
|
||||
"v1": resources,
|
||||
},
|
||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
|
|
|
@ -29,9 +29,10 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/federation/apis/core"
|
||||
_ "k8s.io/kubernetes/federation/apis/core/install"
|
||||
"k8s.io/kubernetes/federation/apis/core/v1"
|
||||
corev1 "k8s.io/kubernetes/federation/apis/core/v1"
|
||||
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage"
|
||||
|
@ -41,28 +42,56 @@ import (
|
|||
servicestore "k8s.io/kubernetes/pkg/registry/core/service/storage"
|
||||
)
|
||||
|
||||
func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
|
||||
serviceStore, serviceStatusStore := servicestore.NewREST(optsGetter)
|
||||
namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespacestore.NewREST(optsGetter)
|
||||
secretStore := secretstore.NewREST(optsGetter)
|
||||
configMapStore := configmapstore.NewREST(optsGetter)
|
||||
eventStore := eventstore.NewREST(optsGetter, uint64(s.EventTTL.Seconds()))
|
||||
|
||||
coreResources := map[string]rest.Storage{
|
||||
"secrets": secretStore,
|
||||
"services": serviceStore,
|
||||
"services/status": serviceStatusStore,
|
||||
"namespaces": namespaceStore,
|
||||
"namespaces/status": namespaceStatusStore,
|
||||
"namespaces/finalize": namespaceFinalizeStore,
|
||||
"events": eventStore,
|
||||
"configmaps": configMapStore,
|
||||
func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
|
||||
servicesStorageFn := func() map[string]rest.Storage {
|
||||
serviceStore, serviceStatusStore := servicestore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"services": serviceStore,
|
||||
"services/status": serviceStatusStore,
|
||||
}
|
||||
}
|
||||
namespacesStorageFn := func() map[string]rest.Storage {
|
||||
namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespacestore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"namespaces": namespaceStore,
|
||||
"namespaces/status": namespaceStatusStore,
|
||||
"namespaces/finalize": namespaceFinalizeStore,
|
||||
}
|
||||
}
|
||||
secretsStorageFn := func() map[string]rest.Storage {
|
||||
secretStore := secretstore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"secrets": secretStore,
|
||||
}
|
||||
}
|
||||
configmapsStorageFn := func() map[string]rest.Storage {
|
||||
configMapStore := configmapstore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"configmaps": configMapStore,
|
||||
}
|
||||
}
|
||||
eventsStorageFn := func() map[string]rest.Storage {
|
||||
eventStore := eventstore.NewREST(optsGetter, uint64(s.EventTTL.Seconds()))
|
||||
return map[string]rest.Storage{
|
||||
"events": eventStore,
|
||||
}
|
||||
}
|
||||
resourcesStorageMap := map[string]getResourcesStorageFunc{
|
||||
"services": servicesStorageFn,
|
||||
"namespaces": namespacesStorageFn,
|
||||
"secrets": secretsStorageFn,
|
||||
"configmaps": configmapsStorageFn,
|
||||
"events": eventsStorageFn,
|
||||
}
|
||||
shouldInstallGroup, resources := enabledResources(corev1.SchemeGroupVersion, resourcesStorageMap, apiResourceConfigSource)
|
||||
if !shouldInstallGroup {
|
||||
return
|
||||
}
|
||||
coreGroupMeta := api.Registry.GroupOrDie(core.GroupName)
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *coreGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
v1.SchemeGroupVersion.Version: coreResources,
|
||||
corev1.SchemeGroupVersion.Version: resources,
|
||||
},
|
||||
OptionsExternalVersion: &api.Registry.GroupOrDie(core.GroupName).GroupVersion,
|
||||
Scheme: core.Scheme,
|
||||
|
|
|
@ -21,39 +21,64 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
daemonsetstore "k8s.io/kubernetes/pkg/registry/extensions/daemonset/storage"
|
||||
deploymentstore "k8s.io/kubernetes/pkg/registry/extensions/deployment/storage"
|
||||
ingressstore "k8s.io/kubernetes/pkg/registry/extensions/ingress/storage"
|
||||
replicasetstore "k8s.io/kubernetes/pkg/registry/extensions/replicaset/storage"
|
||||
)
|
||||
|
||||
func installExtensionsAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
|
||||
replicaSetStorage := replicasetstore.NewStorage(optsGetter)
|
||||
deploymentStorage := deploymentstore.NewStorage(optsGetter)
|
||||
ingressStorage, ingressStatusStorage := ingressstore.NewREST(optsGetter)
|
||||
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(optsGetter)
|
||||
|
||||
extensionsResources := map[string]rest.Storage{
|
||||
"replicasets": replicaSetStorage.ReplicaSet,
|
||||
"replicasets/status": replicaSetStorage.Status,
|
||||
"replicasets/scale": replicaSetStorage.Scale,
|
||||
"ingresses": ingressStorage,
|
||||
"ingresses/status": ingressStatusStorage,
|
||||
"daemonsets": daemonSetStorage,
|
||||
"daemonsets/status": daemonSetStatusStorage,
|
||||
"deployments": deploymentStorage.Deployment,
|
||||
"deployments/status": deploymentStorage.Status,
|
||||
"deployments/scale": deploymentStorage.Scale,
|
||||
"deployments/rollback": deploymentStorage.Rollback,
|
||||
func installExtensionsAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
|
||||
replicasetsStorageFn := func() map[string]rest.Storage {
|
||||
replicaSetStorage := replicasetstore.NewStorage(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"replicasets": replicaSetStorage.ReplicaSet,
|
||||
"replicasets/status": replicaSetStorage.Status,
|
||||
"replicasets/scale": replicaSetStorage.Scale,
|
||||
}
|
||||
}
|
||||
deploymentsStorageFn := func() map[string]rest.Storage {
|
||||
deploymentStorage := deploymentstore.NewStorage(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"deployments": deploymentStorage.Deployment,
|
||||
"deployments/status": deploymentStorage.Status,
|
||||
"deployments/scale": deploymentStorage.Scale,
|
||||
"deployments/rollback": deploymentStorage.Rollback,
|
||||
}
|
||||
}
|
||||
ingressesStorageFn := func() map[string]rest.Storage {
|
||||
ingressStorage, ingressStatusStorage := ingressstore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"ingresses": ingressStorage,
|
||||
"ingresses/status": ingressStatusStorage,
|
||||
}
|
||||
}
|
||||
daemonsetsStorageFn := func() map[string]rest.Storage {
|
||||
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"daemonsets": daemonSetStorage,
|
||||
"daemonsets/status": daemonSetStatusStorage,
|
||||
}
|
||||
}
|
||||
resourcesStorageMap := map[string]getResourcesStorageFunc{
|
||||
"replicasets": replicasetsStorageFn,
|
||||
"deployments": deploymentsStorageFn,
|
||||
"ingresses": ingressesStorageFn,
|
||||
"daemonsets": daemonsetsStorageFn,
|
||||
}
|
||||
shouldInstallGroup, resources := enabledResources(extensionsv1beta1.SchemeGroupVersion, resourcesStorageMap, apiResourceConfigSource)
|
||||
if !shouldInstallGroup {
|
||||
return
|
||||
}
|
||||
extensionsGroupMeta := api.Registry.GroupOrDie(extensions.GroupName)
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *extensionsGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1beta1": extensionsResources,
|
||||
"v1beta1": resources,
|
||||
},
|
||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
|
|
|
@ -22,24 +22,35 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
|
||||
_ "k8s.io/kubernetes/federation/apis/federation/install"
|
||||
fedv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
clusteretcd "k8s.io/kubernetes/federation/registry/cluster/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func installFederationAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
|
||||
clusterStorage, clusterStatusStorage := clusteretcd.NewREST(optsGetter)
|
||||
federationResources := map[string]rest.Storage{
|
||||
"clusters": clusterStorage,
|
||||
"clusters/status": clusterStatusStorage,
|
||||
func installFederationAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
|
||||
groupName := federation.GroupName
|
||||
clustersStorageFn := func() map[string]rest.Storage {
|
||||
clusterStorage, clusterStatusStorage := clusteretcd.NewREST(optsGetter)
|
||||
return map[string]rest.Storage{
|
||||
"clusters": clusterStorage,
|
||||
"clusters/status": clusterStatusStorage,
|
||||
}
|
||||
}
|
||||
federationGroupMeta := api.Registry.GroupOrDie(federation.GroupName)
|
||||
resourcesStorageMap := map[string]getResourcesStorageFunc{
|
||||
"clusters": clustersStorageFn,
|
||||
}
|
||||
shouldInstallGroup, resources := enabledResources(fedv1beta1.SchemeGroupVersion, resourcesStorageMap, apiResourceConfigSource)
|
||||
if !shouldInstallGroup {
|
||||
return
|
||||
}
|
||||
federationGroupMeta := api.Registry.GroupOrDie(groupName)
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *federationGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1beta1": federationResources,
|
||||
"v1beta1": resources,
|
||||
},
|
||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2017 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 app
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/apiserver/pkg/server/storage"
|
||||
)
|
||||
|
||||
// Function to get a map of resources and the corresponding storages.
|
||||
type getResourcesStorageFunc func() map[string]rest.Storage
|
||||
|
||||
// Filters the resources from the given resources storage map to those that are enabled in the given apiResourceConfigSource.
|
||||
// resourcesStorageMap is expected to contain all resources in a group version.
|
||||
// Returns false if none of the resources are enabled and hence the whole group version should be disabled.
|
||||
func enabledResources(groupVersion schema.GroupVersion, resourcesStorageMap map[string]getResourcesStorageFunc, apiResourceConfigSource storage.APIResourceConfigSource) (bool, map[string]rest.Storage) {
|
||||
enabledResources := map[string]rest.Storage{}
|
||||
groupName := groupVersion.Group
|
||||
if !apiResourceConfigSource.AnyResourcesForGroupEnabled(groupName) {
|
||||
glog.V(1).Infof("Skipping disabled API group %q", groupName)
|
||||
return false, enabledResources
|
||||
}
|
||||
for resource, fn := range resourcesStorageMap {
|
||||
if apiResourceConfigSource.ResourceEnabled(groupVersion.WithResource(resource)) {
|
||||
resources := fn()
|
||||
for k, v := range resources {
|
||||
enabledResources[k] = v
|
||||
}
|
||||
} else {
|
||||
glog.V(1).Infof("Skipping disabled resource %s in API group %q", resource, groupName)
|
||||
}
|
||||
}
|
||||
if len(enabledResources) == 0 {
|
||||
glog.V(1).Infof("Skipping API group %q since there is no enabled resource", groupName)
|
||||
return false, enabledResources
|
||||
}
|
||||
return true, enabledResources
|
||||
}
|
|
@ -38,8 +38,11 @@ import (
|
|||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/filters"
|
||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
extensionsapiv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||
|
@ -124,8 +127,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: register cluster federation resources here.
|
||||
resourceConfig := serverstorage.NewResourceConfig()
|
||||
resourceConfig := defaultResourceConfig()
|
||||
|
||||
if s.Etcd.StorageConfig.DeserializationCacheSize == 0 {
|
||||
// When size of cache is not explicitly set, set it to 50000
|
||||
|
@ -230,13 +232,12 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||
routes.UIRedirect{}.Install(m.FallThroughHandler)
|
||||
routes.Logs{}.Install(m.HandlerContainer)
|
||||
|
||||
installFederationAPIs(m, genericConfig.RESTOptionsGetter)
|
||||
installCoreAPIs(s, m, genericConfig.RESTOptionsGetter)
|
||||
installExtensionsAPIs(m, genericConfig.RESTOptionsGetter)
|
||||
// Disable half-baked APIs for 1.6.
|
||||
// TODO: Uncomment this once 1.6 is released.
|
||||
// installBatchAPIs(m, genericConfig.RESTOptionsGetter)
|
||||
// installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter)
|
||||
apiResourceConfigSource := storageFactory.APIResourceConfigSource
|
||||
installFederationAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||
installCoreAPIs(s, m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||
installExtensionsAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||
installBatchAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||
installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||
|
||||
// run the insecure server now
|
||||
if insecureServingOptions != nil {
|
||||
|
@ -253,6 +254,31 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func defaultResourceConfig() *serverstorage.ResourceConfig {
|
||||
rc := serverstorage.NewResourceConfig()
|
||||
|
||||
rc.EnableVersions(
|
||||
federationv1beta1.SchemeGroupVersion,
|
||||
)
|
||||
|
||||
// All core resources except these are disabled by default.
|
||||
rc.EnableResources(
|
||||
apiv1.SchemeGroupVersion.WithResource("secrets"),
|
||||
apiv1.SchemeGroupVersion.WithResource("services"),
|
||||
apiv1.SchemeGroupVersion.WithResource("namespaces"),
|
||||
apiv1.SchemeGroupVersion.WithResource("events"),
|
||||
apiv1.SchemeGroupVersion.WithResource("configmaps"),
|
||||
)
|
||||
// All extension resources except these are disabled by default.
|
||||
rc.EnableResources(
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("daemonsets"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("deployments"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicasets"),
|
||||
)
|
||||
return rc
|
||||
}
|
||||
|
||||
// PostProcessSpec adds removed definitions for backward compatibility
|
||||
func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swagger, error) {
|
||||
compatibilityMap := map[string]string{
|
||||
|
|
|
@ -35,18 +35,29 @@ import (
|
|||
"k8s.io/kubernetes/test/integration/federation/framework"
|
||||
)
|
||||
|
||||
var groupVersions = []schema.GroupVersion{
|
||||
// List of group versions that are enabled by default.
|
||||
var enabledGroupVersions = []schema.GroupVersion{
|
||||
fed_v1b1.SchemeGroupVersion,
|
||||
ext_v1b1.SchemeGroupVersion,
|
||||
// batch_v1.SchemeGroupVersion,
|
||||
// autoscaling_v1.SchemeGroupVersion,
|
||||
}
|
||||
|
||||
type apiTestFunc func(t *testing.T, host string)
|
||||
// List of group versions that are disabled by default.
|
||||
var disabledGroupVersions = []schema.GroupVersion{
|
||||
batch_v1.SchemeGroupVersion,
|
||||
autoscaling_v1.SchemeGroupVersion,
|
||||
}
|
||||
|
||||
func TestFederationAPI(t *testing.T) {
|
||||
type apiTestFunc func(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion)
|
||||
|
||||
func testFederationAPI(t *testing.T, runtimeConfig string, expectedGroupVersions []schema.GroupVersion) {
|
||||
f := &framework.FederationAPIFixture{}
|
||||
f.SetUp(t)
|
||||
if runtimeConfig == "" {
|
||||
f.SetUp(t)
|
||||
} else {
|
||||
runOptions := framework.GetRunOptions()
|
||||
runOptions.APIEnablement.RuntimeConfig.Set(runtimeConfig)
|
||||
f.SetUpWithRunOptions(t, runOptions)
|
||||
}
|
||||
defer f.TearDown(t)
|
||||
|
||||
testCases := map[string]apiTestFunc{
|
||||
|
@ -58,11 +69,23 @@ func TestFederationAPI(t *testing.T) {
|
|||
}
|
||||
for testName, testFunc := range testCases {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
testFunc(t, f.Host)
|
||||
testFunc(t, f.Host, expectedGroupVersions)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that only default APIs are enabled when no runtime config is set.
|
||||
func TestDefaultRun(t *testing.T) {
|
||||
testFederationAPI(t, "", enabledGroupVersions)
|
||||
}
|
||||
|
||||
// Verifies that all APIs are enabled when runtime config is set to all.
|
||||
func TestRunWithRuntimeConfigAll(t *testing.T) {
|
||||
expectedGroupVersions := enabledGroupVersions
|
||||
expectedGroupVersions = append(enabledGroupVersions, disabledGroupVersions...)
|
||||
testFederationAPI(t, "api/all=true", expectedGroupVersions)
|
||||
}
|
||||
|
||||
func readResponse(serverURL string) ([]byte, error) {
|
||||
response, err := http.Get(serverURL)
|
||||
if err != nil {
|
||||
|
@ -79,7 +102,7 @@ func readResponse(serverURL string) ([]byte, error) {
|
|||
return contents, nil
|
||||
}
|
||||
|
||||
func testSwaggerSpec(t *testing.T, host string) {
|
||||
func testSwaggerSpec(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||
serverURL := host + "/swaggerapi"
|
||||
_, err := readResponse(serverURL)
|
||||
if err != nil {
|
||||
|
@ -87,7 +110,7 @@ func testSwaggerSpec(t *testing.T, host string) {
|
|||
}
|
||||
}
|
||||
|
||||
func testSupport(t *testing.T, host string) {
|
||||
func testSupport(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||
serverURL := host + "/version"
|
||||
_, err := readResponse(serverURL)
|
||||
if err != nil {
|
||||
|
@ -104,9 +127,9 @@ func findGroup(groups []metav1.APIGroup, groupName string) *metav1.APIGroup {
|
|||
return nil
|
||||
}
|
||||
|
||||
func testAPIGroupList(t *testing.T, host string) {
|
||||
func testAPIGroupList(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||
groupVersionForDiscoveryMap := make(map[string]metav1.GroupVersionForDiscovery)
|
||||
for _, groupVersion := range groupVersions {
|
||||
for _, groupVersion := range expectedGroupVersions {
|
||||
groupVersionForDiscoveryMap[groupVersion.Group] = metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: groupVersion.String(),
|
||||
Version: groupVersion.Version,
|
||||
|
@ -124,7 +147,8 @@ func testAPIGroupList(t *testing.T, host string) {
|
|||
t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err)
|
||||
}
|
||||
|
||||
for _, groupVersion := range groupVersions {
|
||||
assert.Equal(t, len(apiGroupList.Groups), len(expectedGroupVersions), "expected: %v, actual: %v", expectedGroupVersions, apiGroupList.Groups)
|
||||
for _, groupVersion := range expectedGroupVersions {
|
||||
found := findGroup(apiGroupList.Groups, groupVersion.Group)
|
||||
assert.NotNil(t, found)
|
||||
assert.Equal(t, groupVersion.Group, found.Name)
|
||||
|
@ -135,8 +159,8 @@ func testAPIGroupList(t *testing.T, host string) {
|
|||
}
|
||||
}
|
||||
|
||||
func testAPIGroup(t *testing.T, host string) {
|
||||
for _, groupVersion := range groupVersions {
|
||||
func testAPIGroup(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||
for _, groupVersion := range expectedGroupVersions {
|
||||
serverURL := host + "/apis/" + groupVersion.Group
|
||||
contents, err := readResponse(serverURL)
|
||||
if err != nil {
|
||||
|
@ -188,12 +212,25 @@ func findResource(resources []metav1.APIResource, resourceName string) *metav1.A
|
|||
return nil
|
||||
}
|
||||
|
||||
func testAPIResourceList(t *testing.T, host string) {
|
||||
func testAPIResourceList(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||
testFederationResourceList(t, host)
|
||||
testCoreResourceList(t, host)
|
||||
testExtensionsResourceList(t, host)
|
||||
// testBatchResourceList(t, host)
|
||||
// testAutoscalingResourceList(t, host)
|
||||
if contains(expectedGroupVersions, batch_v1.SchemeGroupVersion) {
|
||||
testBatchResourceList(t, host)
|
||||
}
|
||||
if contains(expectedGroupVersions, autoscaling_v1.SchemeGroupVersion) {
|
||||
testAutoscalingResourceList(t, host)
|
||||
}
|
||||
}
|
||||
|
||||
func contains(gvs []schema.GroupVersion, requiredGV schema.GroupVersion) bool {
|
||||
for _, gv := range gvs {
|
||||
if gv.String() == requiredGV.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func testFederationResourceList(t *testing.T, host string) {
|
||||
|
@ -233,8 +270,7 @@ func testCoreResourceList(t *testing.T, host string) {
|
|||
}
|
||||
assert.Equal(t, "", apiResourceList.APIVersion)
|
||||
assert.Equal(t, v1.SchemeGroupVersion.String(), apiResourceList.GroupVersion)
|
||||
// Assert that there are exactly 7 resources.
|
||||
assert.Equal(t, 8, len(apiResourceList.APIResources))
|
||||
assert.Equal(t, 8, len(apiResourceList.APIResources), "ResourceList: %v", apiResourceList.APIResources)
|
||||
|
||||
// Verify services.
|
||||
found := findResource(apiResourceList.APIResources, "services")
|
||||
|
|
|
@ -33,7 +33,8 @@ import (
|
|||
|
||||
const apiNoun = "federation apiserver"
|
||||
|
||||
func getRunOptions() *options.ServerRunOptions {
|
||||
// GetRunOptions returns the default run options that can be used to run a test federation apiserver.
|
||||
func GetRunOptions() *options.ServerRunOptions {
|
||||
r := options.NewServerRunOptions()
|
||||
r.Etcd.StorageConfig.ServerList = []string{framework.GetEtcdURLFromEnv()}
|
||||
// Use a unique prefix to ensure isolation from other tests using the same etcd instance
|
||||
|
@ -49,7 +50,14 @@ type FederationAPIFixture struct {
|
|||
stopChan chan struct{}
|
||||
}
|
||||
|
||||
// SetUp runs federation apiserver with default run options.
|
||||
func (f *FederationAPIFixture) SetUp(t *testing.T) {
|
||||
f.SetUpWithRunOptions(t, GetRunOptions())
|
||||
}
|
||||
|
||||
// SetUpWithRunOptions runs federation apiserver with the given run options.
|
||||
// Uses default run options if runOptions is nil.
|
||||
func (f *FederationAPIFixture) SetUpWithRunOptions(t *testing.T, runOptions *options.ServerRunOptions) {
|
||||
if f.stopChan != nil {
|
||||
t.Fatal("SetUp() already called")
|
||||
}
|
||||
|
@ -57,8 +65,6 @@ func (f *FederationAPIFixture) SetUp(t *testing.T) {
|
|||
|
||||
f.stopChan = make(chan struct{})
|
||||
|
||||
runOptions := getRunOptions()
|
||||
|
||||
err := startServer(t, runOptions, f.stopChan)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
Loading…
Reference in New Issue