Updating federation-apiserver to support runtime config and using it to disable batch and autoscaling groups

This commit is contained in:
nikhiljindal 2017-02-27 21:55:28 -08:00
parent d043e20feb
commit e8fb6d1c47
7 changed files with 235 additions and 69 deletions

View File

@ -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) {
func installAutoscalingAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
hpaStorageFn := func() map[string]rest.Storage {
hpaStorage, hpaStatusStorage := hpastorage.NewREST(optsGetter)
autoscalingResources := map[string]rest.Storage{
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,

View File

@ -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) {
func installBatchAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
jobsStorageFn := func() map[string]rest.Storage {
jobStorage := jobstorage.NewStorage(optsGetter)
batchResources := map[string]rest.Storage{
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,

View File

@ -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) {
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)
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,
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,
"events": eventStore,
}
}
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,

View File

@ -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) {
func installExtensionsAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter, apiResourceConfigSource storage.APIResourceConfigSource) {
replicasetsStorageFn := func() map[string]rest.Storage {
replicaSetStorage := replicasetstore.NewStorage(optsGetter)
deploymentStorage := deploymentstore.NewStorage(optsGetter)
ingressStorage, ingressStatusStorage := ingressstore.NewREST(optsGetter)
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(optsGetter)
extensionsResources := map[string]rest.Storage{
return 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,
}
}
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,

View File

@ -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) {
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)
federationResources := map[string]rest.Storage{
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,

View File

@ -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
}

View File

@ -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{