mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
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-reviews
This commit is contained in:
commit
e18843d353
@ -15,6 +15,7 @@ go_library(
|
|||||||
"core.go",
|
"core.go",
|
||||||
"extensions.go",
|
"extensions.go",
|
||||||
"federation.go",
|
"federation.go",
|
||||||
|
"install.go",
|
||||||
"plugins.go",
|
"plugins.go",
|
||||||
"server.go",
|
"server.go",
|
||||||
],
|
],
|
||||||
@ -25,16 +26,21 @@ go_library(
|
|||||||
"//federation/apis/core/v1:go_default_library",
|
"//federation/apis/core/v1:go_default_library",
|
||||||
"//federation/apis/federation:go_default_library",
|
"//federation/apis/federation:go_default_library",
|
||||||
"//federation/apis/federation/install: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/cmd/federation-apiserver/app/options:go_default_library",
|
||||||
"//federation/registry/cluster/etcd:go_default_library",
|
"//federation/registry/cluster/etcd:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/install:go_default_library",
|
"//pkg/api/install:go_default_library",
|
||||||
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/apis/autoscaling:go_default_library",
|
"//pkg/apis/autoscaling:go_default_library",
|
||||||
"//pkg/apis/autoscaling/install: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:go_default_library",
|
||||||
"//pkg/apis/batch/install: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:go_default_library",
|
||||||
"//pkg/apis/extensions/install: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/clientset_generated/internalclientset:go_default_library",
|
||||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||||
"//pkg/cloudprovider/providers: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/generic"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||||
|
autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1"
|
||||||
hpastorage "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/storage"
|
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) {
|
||||||
hpaStorage, hpaStatusStorage := hpastorage.NewREST(optsGetter)
|
hpaStorageFn := func() map[string]rest.Storage {
|
||||||
|
hpaStorage, hpaStatusStorage := hpastorage.NewREST(optsGetter)
|
||||||
autoscalingResources := map[string]rest.Storage{
|
return map[string]rest.Storage{
|
||||||
"horizontalpodautoscalers": hpaStorage,
|
"horizontalpodautoscalers": hpaStorage,
|
||||||
"horizontalpodautoscalers/status": hpaStatusStorage,
|
"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)
|
autoscalingGroupMeta := api.Registry.GroupOrDie(autoscaling.GroupName)
|
||||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *autoscalingGroupMeta,
|
GroupMeta: *autoscalingGroupMeta,
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||||
"v1": autoscalingResources,
|
"v1": resources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||||
Scheme: api.Scheme,
|
Scheme: api.Scheme,
|
||||||
|
@ -21,24 +21,34 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/generic"
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/apis/batch"
|
"k8s.io/kubernetes/pkg/apis/batch"
|
||||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||||
|
batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
|
||||||
jobstorage "k8s.io/kubernetes/pkg/registry/batch/job/storage"
|
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) {
|
||||||
jobStorage := jobstorage.NewStorage(optsGetter)
|
jobsStorageFn := func() map[string]rest.Storage {
|
||||||
|
jobStorage := jobstorage.NewStorage(optsGetter)
|
||||||
batchResources := map[string]rest.Storage{
|
return map[string]rest.Storage{
|
||||||
"jobs": jobStorage.Job,
|
"jobs": jobStorage.Job,
|
||||||
"jobs/status": jobStorage.Status,
|
"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)
|
batchGroupMeta := api.Registry.GroupOrDie(batch.GroupName)
|
||||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *batchGroupMeta,
|
GroupMeta: *batchGroupMeta,
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||||
"v1": batchResources,
|
"v1": resources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||||
Scheme: api.Scheme,
|
Scheme: api.Scheme,
|
||||||
|
@ -29,9 +29,10 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/generic"
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/kubernetes/federation/apis/core"
|
"k8s.io/kubernetes/federation/apis/core"
|
||||||
_ "k8s.io/kubernetes/federation/apis/core/install"
|
_ "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/federation/cmd/federation-apiserver/app/options"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage"
|
configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage"
|
||||||
@ -41,28 +42,56 @@ import (
|
|||||||
servicestore "k8s.io/kubernetes/pkg/registry/core/service/storage"
|
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) {
|
||||||
serviceStore, serviceStatusStore := servicestore.NewREST(optsGetter)
|
servicesStorageFn := func() map[string]rest.Storage {
|
||||||
namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespacestore.NewREST(optsGetter)
|
serviceStore, serviceStatusStore := servicestore.NewREST(optsGetter)
|
||||||
secretStore := secretstore.NewREST(optsGetter)
|
return map[string]rest.Storage{
|
||||||
configMapStore := configmapstore.NewREST(optsGetter)
|
"services": serviceStore,
|
||||||
eventStore := eventstore.NewREST(optsGetter, uint64(s.EventTTL.Seconds()))
|
"services/status": serviceStatusStore,
|
||||||
|
}
|
||||||
coreResources := map[string]rest.Storage{
|
}
|
||||||
"secrets": secretStore,
|
namespacesStorageFn := func() map[string]rest.Storage {
|
||||||
"services": serviceStore,
|
namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespacestore.NewREST(optsGetter)
|
||||||
"services/status": serviceStatusStore,
|
return map[string]rest.Storage{
|
||||||
"namespaces": namespaceStore,
|
"namespaces": namespaceStore,
|
||||||
"namespaces/status": namespaceStatusStore,
|
"namespaces/status": namespaceStatusStore,
|
||||||
"namespaces/finalize": namespaceFinalizeStore,
|
"namespaces/finalize": namespaceFinalizeStore,
|
||||||
"events": eventStore,
|
}
|
||||||
"configmaps": configMapStore,
|
}
|
||||||
|
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)
|
coreGroupMeta := api.Registry.GroupOrDie(core.GroupName)
|
||||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *coreGroupMeta,
|
GroupMeta: *coreGroupMeta,
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||||
v1.SchemeGroupVersion.Version: coreResources,
|
corev1.SchemeGroupVersion.Version: resources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: &api.Registry.GroupOrDie(core.GroupName).GroupVersion,
|
OptionsExternalVersion: &api.Registry.GroupOrDie(core.GroupName).GroupVersion,
|
||||||
Scheme: core.Scheme,
|
Scheme: core.Scheme,
|
||||||
|
@ -21,39 +21,64 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/generic"
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||||
|
extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
daemonsetstore "k8s.io/kubernetes/pkg/registry/extensions/daemonset/storage"
|
daemonsetstore "k8s.io/kubernetes/pkg/registry/extensions/daemonset/storage"
|
||||||
deploymentstore "k8s.io/kubernetes/pkg/registry/extensions/deployment/storage"
|
deploymentstore "k8s.io/kubernetes/pkg/registry/extensions/deployment/storage"
|
||||||
ingressstore "k8s.io/kubernetes/pkg/registry/extensions/ingress/storage"
|
ingressstore "k8s.io/kubernetes/pkg/registry/extensions/ingress/storage"
|
||||||
replicasetstore "k8s.io/kubernetes/pkg/registry/extensions/replicaset/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) {
|
||||||
replicaSetStorage := replicasetstore.NewStorage(optsGetter)
|
replicasetsStorageFn := func() map[string]rest.Storage {
|
||||||
deploymentStorage := deploymentstore.NewStorage(optsGetter)
|
replicaSetStorage := replicasetstore.NewStorage(optsGetter)
|
||||||
ingressStorage, ingressStatusStorage := ingressstore.NewREST(optsGetter)
|
return map[string]rest.Storage{
|
||||||
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(optsGetter)
|
"replicasets": replicaSetStorage.ReplicaSet,
|
||||||
|
"replicasets/status": replicaSetStorage.Status,
|
||||||
extensionsResources := map[string]rest.Storage{
|
"replicasets/scale": replicaSetStorage.Scale,
|
||||||
"replicasets": replicaSetStorage.ReplicaSet,
|
}
|
||||||
"replicasets/status": replicaSetStorage.Status,
|
}
|
||||||
"replicasets/scale": replicaSetStorage.Scale,
|
deploymentsStorageFn := func() map[string]rest.Storage {
|
||||||
"ingresses": ingressStorage,
|
deploymentStorage := deploymentstore.NewStorage(optsGetter)
|
||||||
"ingresses/status": ingressStatusStorage,
|
return map[string]rest.Storage{
|
||||||
"daemonsets": daemonSetStorage,
|
"deployments": deploymentStorage.Deployment,
|
||||||
"daemonsets/status": daemonSetStatusStorage,
|
"deployments/status": deploymentStorage.Status,
|
||||||
"deployments": deploymentStorage.Deployment,
|
"deployments/scale": deploymentStorage.Scale,
|
||||||
"deployments/status": deploymentStorage.Status,
|
"deployments/rollback": deploymentStorage.Rollback,
|
||||||
"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)
|
extensionsGroupMeta := api.Registry.GroupOrDie(extensions.GroupName)
|
||||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *extensionsGroupMeta,
|
GroupMeta: *extensionsGroupMeta,
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||||
"v1beta1": extensionsResources,
|
"v1beta1": resources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||||
Scheme: api.Scheme,
|
Scheme: api.Scheme,
|
||||||
|
@ -22,24 +22,35 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/generic"
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/kubernetes/federation/apis/federation"
|
"k8s.io/kubernetes/federation/apis/federation"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
|
|
||||||
_ "k8s.io/kubernetes/federation/apis/federation/install"
|
_ "k8s.io/kubernetes/federation/apis/federation/install"
|
||||||
|
fedv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||||
clusteretcd "k8s.io/kubernetes/federation/registry/cluster/etcd"
|
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) {
|
||||||
clusterStorage, clusterStatusStorage := clusteretcd.NewREST(optsGetter)
|
groupName := federation.GroupName
|
||||||
federationResources := map[string]rest.Storage{
|
clustersStorageFn := func() map[string]rest.Storage {
|
||||||
"clusters": clusterStorage,
|
clusterStorage, clusterStatusStorage := clusteretcd.NewREST(optsGetter)
|
||||||
"clusters/status": clusterStatusStorage,
|
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{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *federationGroupMeta,
|
GroupMeta: *federationGroupMeta,
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||||
"v1beta1": federationResources,
|
"v1beta1": resources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
OptionsExternalVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||||
Scheme: api.Scheme,
|
Scheme: api.Scheme,
|
||||||
|
55
federation/cmd/federation-apiserver/app/install.go
Normal file
55
federation/cmd/federation-apiserver/app/install.go
Normal 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
|
||||||
|
}
|
@ -38,8 +38,11 @@ import (
|
|||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/filters"
|
"k8s.io/apiserver/pkg/server/filters"
|
||||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
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/federation/cmd/federation-apiserver/app/options"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"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"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||||
@ -124,8 +127,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: register cluster federation resources here.
|
resourceConfig := defaultResourceConfig()
|
||||||
resourceConfig := serverstorage.NewResourceConfig()
|
|
||||||
|
|
||||||
if s.Etcd.StorageConfig.DeserializationCacheSize == 0 {
|
if s.Etcd.StorageConfig.DeserializationCacheSize == 0 {
|
||||||
// When size of cache is not explicitly set, set it to 50000
|
// 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.UIRedirect{}.Install(m.FallThroughHandler)
|
||||||
routes.Logs{}.Install(m.HandlerContainer)
|
routes.Logs{}.Install(m.HandlerContainer)
|
||||||
|
|
||||||
installFederationAPIs(m, genericConfig.RESTOptionsGetter)
|
apiResourceConfigSource := storageFactory.APIResourceConfigSource
|
||||||
installCoreAPIs(s, m, genericConfig.RESTOptionsGetter)
|
installFederationAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
installExtensionsAPIs(m, genericConfig.RESTOptionsGetter)
|
installCoreAPIs(s, m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
// Disable half-baked APIs for 1.6.
|
installExtensionsAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
// TODO: Uncomment this once 1.6 is released.
|
installBatchAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
// installBatchAPIs(m, genericConfig.RESTOptionsGetter)
|
installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
// installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter)
|
|
||||||
|
|
||||||
// run the insecure server now
|
// run the insecure server now
|
||||||
if insecureServingOptions != nil {
|
if insecureServingOptions != nil {
|
||||||
@ -253,6 +254,31 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
return err
|
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
|
// PostProcessSpec adds removed definitions for backward compatibility
|
||||||
func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swagger, error) {
|
func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swagger, error) {
|
||||||
compatibilityMap := map[string]string{
|
compatibilityMap := map[string]string{
|
||||||
|
@ -35,18 +35,29 @@ import (
|
|||||||
"k8s.io/kubernetes/test/integration/federation/framework"
|
"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,
|
fed_v1b1.SchemeGroupVersion,
|
||||||
ext_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 := &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)
|
defer f.TearDown(t)
|
||||||
|
|
||||||
testCases := map[string]apiTestFunc{
|
testCases := map[string]apiTestFunc{
|
||||||
@ -58,11 +69,23 @@ func TestFederationAPI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, testFunc := range testCases {
|
for testName, testFunc := range testCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
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) {
|
func readResponse(serverURL string) ([]byte, error) {
|
||||||
response, err := http.Get(serverURL)
|
response, err := http.Get(serverURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,7 +102,7 @@ func readResponse(serverURL string) ([]byte, error) {
|
|||||||
return contents, nil
|
return contents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSwaggerSpec(t *testing.T, host string) {
|
func testSwaggerSpec(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||||
serverURL := host + "/swaggerapi"
|
serverURL := host + "/swaggerapi"
|
||||||
_, err := readResponse(serverURL)
|
_, err := readResponse(serverURL)
|
||||||
if err != nil {
|
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"
|
serverURL := host + "/version"
|
||||||
_, err := readResponse(serverURL)
|
_, err := readResponse(serverURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,9 +127,9 @@ func findGroup(groups []metav1.APIGroup, groupName string) *metav1.APIGroup {
|
|||||||
return nil
|
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)
|
groupVersionForDiscoveryMap := make(map[string]metav1.GroupVersionForDiscovery)
|
||||||
for _, groupVersion := range groupVersions {
|
for _, groupVersion := range expectedGroupVersions {
|
||||||
groupVersionForDiscoveryMap[groupVersion.Group] = metav1.GroupVersionForDiscovery{
|
groupVersionForDiscoveryMap[groupVersion.Group] = metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: groupVersion.String(),
|
GroupVersion: groupVersion.String(),
|
||||||
Version: groupVersion.Version,
|
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)
|
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)
|
found := findGroup(apiGroupList.Groups, groupVersion.Group)
|
||||||
assert.NotNil(t, found)
|
assert.NotNil(t, found)
|
||||||
assert.Equal(t, groupVersion.Group, found.Name)
|
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) {
|
func testAPIGroup(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||||
for _, groupVersion := range groupVersions {
|
for _, groupVersion := range expectedGroupVersions {
|
||||||
serverURL := host + "/apis/" + groupVersion.Group
|
serverURL := host + "/apis/" + groupVersion.Group
|
||||||
contents, err := readResponse(serverURL)
|
contents, err := readResponse(serverURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -188,12 +212,25 @@ func findResource(resources []metav1.APIResource, resourceName string) *metav1.A
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAPIResourceList(t *testing.T, host string) {
|
func testAPIResourceList(t *testing.T, host string, expectedGroupVersions []schema.GroupVersion) {
|
||||||
testFederationResourceList(t, host)
|
testFederationResourceList(t, host)
|
||||||
testCoreResourceList(t, host)
|
testCoreResourceList(t, host)
|
||||||
testExtensionsResourceList(t, host)
|
testExtensionsResourceList(t, host)
|
||||||
// testBatchResourceList(t, host)
|
if contains(expectedGroupVersions, batch_v1.SchemeGroupVersion) {
|
||||||
// testAutoscalingResourceList(t, host)
|
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) {
|
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, "", apiResourceList.APIVersion)
|
||||||
assert.Equal(t, v1.SchemeGroupVersion.String(), apiResourceList.GroupVersion)
|
assert.Equal(t, v1.SchemeGroupVersion.String(), apiResourceList.GroupVersion)
|
||||||
// Assert that there are exactly 7 resources.
|
assert.Equal(t, 8, len(apiResourceList.APIResources), "ResourceList: %v", apiResourceList.APIResources)
|
||||||
assert.Equal(t, 8, len(apiResourceList.APIResources))
|
|
||||||
|
|
||||||
// Verify services.
|
// Verify services.
|
||||||
found := findResource(apiResourceList.APIResources, "services")
|
found := findResource(apiResourceList.APIResources, "services")
|
||||||
|
@ -33,7 +33,8 @@ import (
|
|||||||
|
|
||||||
const apiNoun = "federation apiserver"
|
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 := options.NewServerRunOptions()
|
||||||
r.Etcd.StorageConfig.ServerList = []string{framework.GetEtcdURLFromEnv()}
|
r.Etcd.StorageConfig.ServerList = []string{framework.GetEtcdURLFromEnv()}
|
||||||
// Use a unique prefix to ensure isolation from other tests using the same etcd instance
|
// 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{}
|
stopChan chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUp runs federation apiserver with default run options.
|
||||||
func (f *FederationAPIFixture) SetUp(t *testing.T) {
|
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 {
|
if f.stopChan != nil {
|
||||||
t.Fatal("SetUp() already called")
|
t.Fatal("SetUp() already called")
|
||||||
}
|
}
|
||||||
@ -57,8 +65,6 @@ func (f *FederationAPIFixture) SetUp(t *testing.T) {
|
|||||||
|
|
||||||
f.stopChan = make(chan struct{})
|
f.stopChan = make(chan struct{})
|
||||||
|
|
||||||
runOptions := getRunOptions()
|
|
||||||
|
|
||||||
err := startServer(t, runOptions, f.stopChan)
|
err := startServer(t, runOptions, f.stopChan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user