Merge pull request #15516 from nikhiljindal/runtimeConfig

Enable extensions/v1beta1 by default and allow runtimeConfig to support enabling/disabling specific resources
pull/6/head
Nikhil Jindal 2015-10-15 20:16:54 -07:00
commit c6b5f7ff5a
15 changed files with 4198 additions and 132 deletions

View File

@ -9,6 +9,14 @@
"path": "/api",
"description": "get available API versions"
},
{
"path": "/apis/extensions/v1beta1",
"description": "API at /apis/extensions/v1beta1"
},
{
"path": "/apis/extensions/",
"description": "get information of a group"
},
{
"path": "/apis",
"description": "get available API versions"

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,14 @@ function verify-prereqs {
fi
fi
fi
if [[ "${ENABLE_DEPLOYMENTS}" == "true" ]]; then
if [[ -z "${RUNTIME_CONFIG}" ]]; then
RUNTIME_CONFIG="extensions/v1beta1/deployments=true"
else
RUNTIME_CONFIG="${RUNTIME_CONFIG},extensions/v1beta1/deployments=true"
fi
fi
local cmd
for cmd in gcloud gsutil; do

View File

@ -408,30 +408,11 @@ func (s *APIServer) Run(_ []string) error {
glog.Fatalf("Failure to start kubelet client: %v", err)
}
// "api/all=false" allows users to selectively enable specific api versions.
disableAllAPIs := false
allAPIFlagValue, ok := s.RuntimeConfig["api/all"]
if ok && allAPIFlagValue == "false" {
disableAllAPIs = true
apiGroupVersionOverrides, err := s.parseRuntimeConfig()
if err != nil {
glog.Fatalf("error in parsing runtime-config: %s", err)
}
// "api/legacy=false" allows users to disable legacy api versions.
disableLegacyAPIs := false
legacyAPIFlagValue, ok := s.RuntimeConfig["api/legacy"]
if ok && legacyAPIFlagValue == "false" {
disableLegacyAPIs = true
}
_ = disableLegacyAPIs // hush the compiler while we don't have legacy APIs to disable.
// "api/v1={true|false} allows users to enable/disable v1 API.
// This takes preference over api/all and api/legacy, if specified.
disableV1 := disableAllAPIs
disableV1 = !s.getRuntimeConfigValue("api/v1", !disableV1)
// "extensions/v1beta1={true|false} allows users to enable/disable the experimental API.
// This takes preference over api/all, if specified.
enableExp := s.getRuntimeConfigValue("extensions/v1beta1", false)
clientConfig := &client.Config{
Host: net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)),
Version: s.DeprecatedStorageVersion,
@ -458,17 +439,17 @@ func (s *APIServer) Run(_ []string) error {
}
storageDestinations.AddAPIGroup("", etcdStorage)
if enableExp {
if !apiGroupVersionOverrides["extensions/v1beta1"].Disable {
expGroup, err := latest.Group("extensions")
if err != nil {
glog.Fatalf("Experimental API is enabled in runtime config, but not enabled in the environment variable KUBE_API_VERSIONS. Error: %v", err)
glog.Fatalf("Extensions API is enabled in runtime config, but not enabled in the environment variable KUBE_API_VERSIONS. Error: %v", err)
}
if _, found := storageVersions[expGroup.Group]; !found {
glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", expGroup.Group, storageVersions)
}
expEtcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, expGroup.InterfacesFor, storageVersions[expGroup.Group], s.EtcdPathPrefix)
if err != nil {
glog.Fatalf("Invalid experimental storage version or misconfigured etcd: %v", err)
glog.Fatalf("Invalid extensions storage version or misconfigured etcd: %v", err)
}
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
}
@ -558,8 +539,7 @@ func (s *APIServer) Run(_ []string) error {
SupportsBasicAuth: len(s.BasicAuthFile) > 0,
Authorizer: authorizer,
AdmissionControl: admissionController,
DisableV1: disableV1,
EnableExp: enableExp,
APIGroupVersionOverrides: apiGroupVersionOverrides,
MasterServiceNamespace: s.MasterServiceNamespace,
ClusterName: s.ClusterName,
ExternalHost: s.ExternalHost,
@ -680,3 +660,61 @@ func (s *APIServer) getRuntimeConfigValue(apiKey string, defaultValue bool) bool
}
return defaultValue
}
// Parses the given runtime-config and formats it into map[string]ApiGroupVersionOverride
func (s *APIServer) parseRuntimeConfig() (map[string]master.APIGroupVersionOverride, error) {
// "api/all=false" allows users to selectively enable specific api versions.
disableAllAPIs := false
allAPIFlagValue, ok := s.RuntimeConfig["api/all"]
if ok && allAPIFlagValue == "false" {
disableAllAPIs = true
}
// "api/legacy=false" allows users to disable legacy api versions.
disableLegacyAPIs := false
legacyAPIFlagValue, ok := s.RuntimeConfig["api/legacy"]
if ok && legacyAPIFlagValue == "false" {
disableLegacyAPIs = true
}
_ = disableLegacyAPIs // hush the compiler while we don't have legacy APIs to disable.
// "api/v1={true|false} allows users to enable/disable v1 API.
// This takes preference over api/all and api/legacy, if specified.
disableV1 := disableAllAPIs
v1GroupVersion := "api/v1"
disableV1 = !s.getRuntimeConfigValue(v1GroupVersion, !disableV1)
apiGroupVersionOverrides := map[string]master.APIGroupVersionOverride{}
if disableV1 {
apiGroupVersionOverrides[v1GroupVersion] = master.APIGroupVersionOverride{
Disable: true,
}
}
// "extensions/v1beta1={true|false} allows users to enable/disable the extensions API.
// This takes preference over api/all, if specified.
disableExtensions := disableAllAPIs
extensionsGroupVersion := "extensions/v1beta1"
// TODO: Make this a loop over all group/versions when there are more of them.
disableExtensions = !s.getRuntimeConfigValue(extensionsGroupVersion, !disableExtensions)
if disableExtensions {
apiGroupVersionOverrides[extensionsGroupVersion] = master.APIGroupVersionOverride{
Disable: true,
}
}
for key := range s.RuntimeConfig {
if strings.HasPrefix(key, v1GroupVersion+"/") {
return nil, fmt.Errorf("api/v1 resources cannot be enabled/disabled individually")
} else if strings.HasPrefix(key, extensionsGroupVersion+"/") {
resource := strings.TrimPrefix(key, extensionsGroupVersion+"/")
apiGroupVersionOverride := apiGroupVersionOverrides[extensionsGroupVersion]
if apiGroupVersionOverride.ResourceOverrides == nil {
apiGroupVersionOverride.ResourceOverrides = map[string]bool{}
}
apiGroupVersionOverride.ResourceOverrides[resource] = s.getRuntimeConfigValue(key, false)
apiGroupVersionOverrides[extensionsGroupVersion] = apiGroupVersionOverride
}
}
return apiGroupVersionOverrides, nil
}

View File

@ -154,3 +154,96 @@ func TestUpdateEtcdOverrides(t *testing.T) {
}
}
}
func TestParseRuntimeConfig(t *testing.T) {
testCases := []struct {
runtimeConfig map[string]string
apiGroupVersionOverrides map[string]master.APIGroupVersionOverride
err bool
}{
{
runtimeConfig: map[string]string{},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{},
err: false,
},
{
// Cannot override v1 resources.
runtimeConfig: map[string]string{
"api/v1/pods": "false",
},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{},
err: true,
},
{
// Disable v1.
runtimeConfig: map[string]string{
"api/v1": "false",
},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{
"api/v1": {
Disable: true,
},
},
err: false,
},
{
// Disable extensions.
runtimeConfig: map[string]string{
"extensions/v1beta1": "false",
},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{
"extensions/v1beta1": {
Disable: true,
},
},
err: false,
},
{
// Disable deployments.
runtimeConfig: map[string]string{
"extensions/v1beta1/deployments": "false",
},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{
"extensions/v1beta1": {
ResourceOverrides: map[string]bool{
"deployments": false,
},
},
},
err: false,
},
{
// Enable deployments and disable jobs.
runtimeConfig: map[string]string{
"extensions/v1beta1/deployments": "true",
"extensions/v1beta1/jobs": "false",
},
apiGroupVersionOverrides: map[string]master.APIGroupVersionOverride{
"extensions/v1beta1": {
ResourceOverrides: map[string]bool{
"deployments": true,
"jobs": false,
},
},
},
err: false,
},
}
for _, test := range testCases {
s := &APIServer{
RuntimeConfig: test.runtimeConfig,
}
apiGroupVersionOverrides, err := s.parseRuntimeConfig()
if err == nil && test.err {
t.Fatalf("expected error for test: %q", test)
} else if err != nil && !test.err {
t.Fatalf("unexpected error: %s, for test: %q", err, test)
}
if err == nil && !reflect.DeepEqual(apiGroupVersionOverrides, test.apiGroupVersionOverrides) {
t.Fatalf("unexpected apiGroupVersionOverrides. Actual: %q, expected: %q", apiGroupVersionOverrides, test.apiGroupVersionOverrides)
}
}
}

View File

@ -58,7 +58,6 @@ KUBE_API_VERSIONS="v1,extensions/v1beta1" "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver
--public-address-override="127.0.0.1" \
--advertise-address="10.10.10.10" \
--kubelet-port=${KUBELET_PORT} \
--runtime-config=api/v1 \
--service-cluster-ip-range="10.0.0.0/24" >/dev/null 2>&1 &
APISERVER_PID=$!
@ -70,6 +69,7 @@ curl -fs ${SWAGGER_API_PATH} > ${SWAGGER_ROOT_DIR}/resourceListing.json
curl -fs ${SWAGGER_API_PATH}version > ${SWAGGER_ROOT_DIR}/version.json
curl -fs ${SWAGGER_API_PATH}api > ${SWAGGER_ROOT_DIR}/api.json
curl -fs ${SWAGGER_API_PATH}api/v1 > ${SWAGGER_ROOT_DIR}/v1.json
curl -fs ${SWAGGER_API_PATH}apis/extensions/v1beta1 > ${SWAGGER_ROOT_DIR}/v1beta1.json
kube::log::status "SUCCESS"

View File

@ -80,6 +80,7 @@ import (
"k8s.io/kubernetes/pkg/ui"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/sets"
utilSets "k8s.io/kubernetes/pkg/util/sets"
daemonetcd "k8s.io/kubernetes/pkg/registry/daemonset/etcd"
horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd"
@ -166,6 +167,15 @@ func (s *StorageDestinations) backends() []string {
return backends.List()
}
// Specifies the overrides for various API group versions.
// This can be used to enable/disable entire group versions or specific resources.
type APIGroupVersionOverride struct {
// Whether to enable or disable this group version.
Disable bool
// List of overrides for individual resources in this group version.
ResourceOverrides map[string]bool
}
// Config is a structure used to configure a Master.
type Config struct {
StorageDestinations StorageDestinations
@ -180,9 +190,8 @@ type Config struct {
EnableUISupport bool
// allow downstream consumers to disable swagger
EnableSwaggerSupport bool
// allow api versions to be conditionally disabled
DisableV1 bool
EnableExp bool
// Allows api group versions or specific resources to be conditionally enabled/disabled.
APIGroupVersionOverrides map[string]APIGroupVersionOverride
// allow downstream consumers to disable the index route
EnableIndex bool
EnableProfiling bool
@ -271,26 +280,25 @@ type Master struct {
cacheTimeout time.Duration
minRequestTimeout time.Duration
mux apiserver.Mux
muxHelper *apiserver.MuxHelper
handlerContainer *restful.Container
rootWebService *restful.WebService
enableCoreControllers bool
enableLogsSupport bool
enableUISupport bool
enableSwaggerSupport bool
enableProfiling bool
enableWatchCache bool
apiPrefix string
apiGroupPrefix string
corsAllowedOriginList []string
authenticator authenticator.Request
authorizer authorizer.Authorizer
admissionControl admission.Interface
masterCount int
v1 bool
exp bool
requestContextMapper api.RequestContextMapper
mux apiserver.Mux
muxHelper *apiserver.MuxHelper
handlerContainer *restful.Container
rootWebService *restful.WebService
enableCoreControllers bool
enableLogsSupport bool
enableUISupport bool
enableSwaggerSupport bool
enableProfiling bool
enableWatchCache bool
apiPrefix string
apiGroupPrefix string
corsAllowedOriginList []string
authenticator authenticator.Request
authorizer authorizer.Authorizer
admissionControl admission.Interface
masterCount int
apiGroupVersionOverrides map[string]APIGroupVersionOverride
requestContextMapper api.RequestContextMapper
// External host is the name that should be used in external (public internet) URLs for this master
externalHost string
@ -435,24 +443,23 @@ func New(c *Config) *Master {
}
m := &Master{
serviceClusterIPRange: c.ServiceClusterIPRange,
serviceNodePortRange: c.ServiceNodePortRange,
rootWebService: new(restful.WebService),
enableCoreControllers: c.EnableCoreControllers,
enableLogsSupport: c.EnableLogsSupport,
enableUISupport: c.EnableUISupport,
enableSwaggerSupport: c.EnableSwaggerSupport,
enableProfiling: c.EnableProfiling,
enableWatchCache: c.EnableWatchCache,
apiPrefix: c.APIPrefix,
apiGroupPrefix: c.APIGroupPrefix,
corsAllowedOriginList: c.CorsAllowedOriginList,
authenticator: c.Authenticator,
authorizer: c.Authorizer,
admissionControl: c.AdmissionControl,
v1: !c.DisableV1,
exp: c.EnableExp,
requestContextMapper: c.RequestContextMapper,
serviceClusterIPRange: c.ServiceClusterIPRange,
serviceNodePortRange: c.ServiceNodePortRange,
rootWebService: new(restful.WebService),
enableCoreControllers: c.EnableCoreControllers,
enableLogsSupport: c.EnableLogsSupport,
enableUISupport: c.EnableUISupport,
enableSwaggerSupport: c.EnableSwaggerSupport,
enableProfiling: c.EnableProfiling,
enableWatchCache: c.EnableWatchCache,
apiPrefix: c.APIPrefix,
apiGroupPrefix: c.APIGroupPrefix,
corsAllowedOriginList: c.CorsAllowedOriginList,
authenticator: c.Authenticator,
authorizer: c.Authorizer,
admissionControl: c.AdmissionControl,
apiGroupVersionOverrides: c.APIGroupVersionOverrides,
requestContextMapper: c.RequestContextMapper,
cacheTimeout: c.CacheTimeout,
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
@ -624,7 +631,8 @@ func (m *Master) init(c *Config) {
}
apiVersions := []string{}
if m.v1 {
// Install v1 unless disabled.
if !m.apiGroupVersionOverrides["api/v1"].Disable {
if err := m.api_v1().InstallREST(m.handlerContainer); err != nil {
glog.Fatalf("Unable to setup API v1: %v", err)
}
@ -637,7 +645,8 @@ func (m *Master) init(c *Config) {
// allGroups records all supported groups at /apis
allGroups := []unversioned.APIGroup{}
if m.exp {
// Install extensions unless disabled.
if !m.apiGroupVersionOverrides["extensions/v1beta1"].Disable {
m.thirdPartyStorage = c.StorageDestinations.APIGroups["extensions"].Default
m.thirdPartyResources = map[string]*thirdpartyresourcedataetcd.REST{}
@ -1023,45 +1032,71 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV
// experimental returns the resources and codec for the experimental api
func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
controllerStorage := expcontrolleretcd.NewStorage(c.StorageDestinations.get("", "replicationControllers"))
// All resources except these are disabled by default.
enabledResources := utilSets.NewString("jobs", "horizontalpodautoscalers", "ingress")
resourceOverrides := m.apiGroupVersionOverrides["extensions/v1beta1"].ResourceOverrides
isEnabled := func(resource string) bool {
// Check if the resource has been overriden.
enabled, ok := resourceOverrides[resource]
if !ok {
return enabledResources.Has(resource)
}
return enabled
}
dbClient := func(resource string) storage.Interface {
return c.StorageDestinations.get("extensions", resource)
}
autoscalerStorage, autoscalerStatusStorage := horizontalpodautoscaleretcd.NewREST(dbClient("horizonalpodautoscalers"))
thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(dbClient("thirdpartyresources"))
daemonSetStorage, daemonSetStatusStorage := daemonetcd.NewREST(dbClient("daemonsets"))
deploymentStorage := deploymentetcd.NewStorage(dbClient("deployments"))
jobStorage, jobStatusStorage := jobetcd.NewREST(dbClient("jobs"))
ingressStorage, ingressStatusStorage := ingressetcd.NewREST(dbClient("ingress"))
thirdPartyControl := ThirdPartyController{
master: m,
thirdPartyResourceRegistry: thirdPartyResourceStorage,
storage := map[string]rest.Storage{}
if isEnabled("replicationcontrollers") {
controllerStorage := expcontrolleretcd.NewStorage(c.StorageDestinations.get("", "replicationControllers"))
storage["replicationcontrollers"] = controllerStorage.ReplicationController
storage["replicationcontrollers/scale"] = controllerStorage.Scale
}
go func() {
util.Forever(func() {
if err := thirdPartyControl.SyncResources(); err != nil {
glog.Warningf("third party resource sync failed: %v", err)
}
}, 10*time.Second)
}()
storage := map[string]rest.Storage{
strings.ToLower("replicationControllers"): controllerStorage.ReplicationController,
strings.ToLower("replicationControllers/scale"): controllerStorage.Scale,
strings.ToLower("horizontalpodautoscalers"): autoscalerStorage,
strings.ToLower("horizontalpodautoscalers/status"): autoscalerStatusStorage,
strings.ToLower("thirdpartyresources"): thirdPartyResourceStorage,
strings.ToLower("daemonsets"): daemonSetStorage,
strings.ToLower("daemonsets/status"): daemonSetStatusStorage,
strings.ToLower("deployments"): deploymentStorage.Deployment,
strings.ToLower("deployments/scale"): deploymentStorage.Scale,
strings.ToLower("jobs"): jobStorage,
strings.ToLower("jobs/status"): jobStatusStorage,
strings.ToLower("ingress"): ingressStorage,
strings.ToLower("ingress/status"): ingressStatusStorage,
if isEnabled("horizontalpodautoscalers") {
autoscalerStorage, autoscalerStatusStorage := horizontalpodautoscaleretcd.NewREST(dbClient("horizonalpodautoscalers"))
storage["horizontalpodautoscalers"] = autoscalerStorage
storage["horizontalpodautoscalers/status"] = autoscalerStatusStorage
}
if isEnabled("thirdpartyresources") {
thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(dbClient("thirdpartyresources"))
thirdPartyControl := ThirdPartyController{
master: m,
thirdPartyResourceRegistry: thirdPartyResourceStorage,
}
go func() {
util.Forever(func() {
if err := thirdPartyControl.SyncResources(); err != nil {
glog.Warningf("third party resource sync failed: %v", err)
}
}, 10*time.Second)
}()
storage["thirdpartyresources"] = thirdPartyResourceStorage
}
expMeta := latest.GroupOrDie("extensions")
if isEnabled("daemonsets") {
daemonSetStorage, daemonSetStatusStorage := daemonetcd.NewREST(dbClient("daemonsets"))
storage["daemonsets"] = daemonSetStorage
storage["daemonsets/status"] = daemonSetStatusStorage
}
if isEnabled("deployments") {
deploymentStorage := deploymentetcd.NewStorage(dbClient("deployments"))
storage["deployments"] = deploymentStorage.Deployment
storage["deployments/scale"] = deploymentStorage.Scale
}
if isEnabled("jobs") {
jobStorage, jobStatusStorage := jobetcd.NewREST(dbClient("jobs"))
storage["jobs"] = jobStorage
storage["jobs/status"] = jobStatusStorage
}
if isEnabled("ingress") {
ingressStorage, ingressStatusStorage := ingressetcd.NewREST(dbClient("ingress"))
storage["ingress"] = ingressStorage
storage["ingress/status"] = ingressStatusStorage
}
extensionsGroup := latest.GroupOrDie("extensions")
return &apiserver.APIGroupVersion{
Root: m.apiGroupPrefix,
@ -1071,11 +1106,11 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
Convertor: api.Scheme,
Typer: api.Scheme,
Mapper: expMeta.RESTMapper,
Codec: expMeta.Codec,
Linker: expMeta.SelfLinker,
Mapper: extensionsGroup.RESTMapper,
Codec: extensionsGroup.Codec,
Linker: extensionsGroup.SelfLinker,
Storage: storage,
Version: expMeta.GroupVersion,
Version: extensionsGroup.GroupVersion,
ServerVersion: latest.GroupOrDie("").GroupVersion,
Admit: m.admissionControl,

View File

@ -100,8 +100,7 @@ func TestNew(t *testing.T) {
assert.Equal(master.authenticator, config.Authenticator)
assert.Equal(master.authorizer, config.Authorizer)
assert.Equal(master.admissionControl, config.AdmissionControl)
assert.Equal(master.v1, !config.DisableV1)
assert.Equal(master.exp, config.EnableExp)
assert.Equal(master.apiGroupVersionOverrides, config.APIGroupVersionOverrides)
assert.Equal(master.requestContextMapper, config.RequestContextMapper)
assert.Equal(master.cacheTimeout, config.CacheTimeout)
assert.Equal(master.masterCount, config.MasterCount)
@ -366,7 +365,6 @@ func TestGetNodeAddresses(t *testing.T) {
func TestDiscoveryAtAPIS(t *testing.T) {
master, config, assert := setUp(t)
master.exp = true
// ================= preparation for master.init() ======================
portRange := util.PortRange{Base: 10, Size: 10}
master.serviceNodePortRange = portRange

View File

@ -390,8 +390,19 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
@ -408,7 +419,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport
@ -508,8 +519,18 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@ -527,7 +548,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysDenyAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport
@ -578,8 +599,18 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@ -598,7 +629,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{},
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
previousResourceVersion := make(map[string]float64)
@ -668,8 +699,18 @@ func TestBobIsForbidden(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@ -688,7 +729,7 @@ func TestBobIsForbidden(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{},
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport
@ -732,8 +773,18 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@ -752,7 +803,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{},
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport
@ -819,8 +870,18 @@ func TestAuthorizationAttributeDetermination(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
trackingAuthorizer := &trackingAuthorizer{}
@ -841,7 +902,7 @@ func TestAuthorizationAttributeDetermination(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: trackingAuthorizer,
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport
@ -902,8 +963,18 @@ func TestNamespaceAuthorization(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
a := newAuthorizerWithContents(t, `{"namespace": "foo"}
`)
@ -925,7 +996,7 @@ func TestNamespaceAuthorization(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: a,
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
previousResourceVersion := make(map[string]float64)
@ -1020,8 +1091,18 @@ func TestKindAuthorization(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
a := newAuthorizerWithContents(t, `{"resource": "services"}
`)
@ -1043,7 +1124,7 @@ func TestKindAuthorization(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: a,
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
previousResourceVersion := make(map[string]float64)
@ -1126,8 +1207,18 @@ func TestReadOnlyAuthorization(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
a := newAuthorizerWithContents(t, `{"readonly": true}`)
@ -1148,7 +1239,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
Authenticator: getTestTokenAuth(),
Authorizer: a,
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
transport := http.DefaultTransport

View File

@ -44,6 +44,13 @@ func NewEtcdStorage() (storage.Interface, error) {
return master.NewEtcdStorage(NewEtcdClient(), latest.GroupOrDie("").InterfacesFor, testapi.Default.Version(), etcdtest.PathPrefix())
}
func NewExtensionsEtcdStorage(client *etcd.Client) (storage.Interface, error) {
if client == nil {
client = NewEtcdClient()
}
return master.NewEtcdStorage(client, latest.GroupOrDie("extensions").InterfacesFor, testapi.Extensions.GroupAndVersion(), etcdtest.PathPrefix())
}
func RequireEtcd() {
if _, err := NewEtcdClient().Get("/", false, false); err != nil {
glog.Fatalf("unable to connect to etcd for testing: %v", err)

View File

@ -131,8 +131,8 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
if err != nil {
glog.Fatalf("Failed to create etcd storage for master %v", err)
}
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, latest.GroupOrDie("extensions").InterfacesFor, latest.GroupOrDie("extensions").GroupVersion, etcdtest.PathPrefix())
storageVersions["extensions"] = latest.GroupOrDie("extensions").GroupVersion
expEtcdStorage, err := NewExtensionsEtcdStorage(etcdClient)
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
if err != nil {
glog.Fatalf("Failed to create etcd storage for master %v", err)
}
@ -144,7 +144,6 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
StorageDestinations: storageDestinations,
StorageVersions: storageVersions,
KubeletClient: client.FakeKubeletClient{},
EnableExp: true,
EnableLogsSupport: false,
EnableProfiling: true,
EnableSwaggerSupport: true,
@ -275,7 +274,7 @@ func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, latest.GroupOrDie("extensions").InterfacesFor, testapi.Extensions.GroupAndVersion(), etcdtest.PathPrefix())
expEtcdStorage, err := NewExtensionsEtcdStorage(etcdClient)
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -292,7 +291,6 @@ func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
EnableUISupport: false,
APIPrefix: "/api",
APIGroupPrefix: "/apis",
EnableExp: true,
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: storageVersions,

View File

@ -38,7 +38,7 @@ func TestKubectlValidation(t *testing.T) {
// The following test the experimental api.
// TOOD: Replace with something more robust. These may move.
{`{"apiVersion": "extensions/v1beta1", "kind": "DaemonSet"}`, false},
{`{"apiVersion": "extensions/v1beta1", "kind": "Ingress"}`, false},
{`{"apiVersion": "extensions/v1beta1", "kind": "Job"}`, false},
{`{"apiVersion": "vNotAVersion", "kind": "Job"}`, true},
}

View File

@ -59,8 +59,19 @@ func TestUnschedulableNodes(t *testing.T) {
if err != nil {
t.Fatalf("Couldn't create etcd storage: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
framework.DeleteAllEtcdKeys()
var m *master.Master
@ -79,7 +90,7 @@ func TestUnschedulableNodes(t *testing.T) {
APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
restClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
@ -298,8 +309,19 @@ func BenchmarkScheduling(b *testing.B) {
if err != nil {
b.Fatalf("Couldn't create etcd storage: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
framework.DeleteAllEtcdKeys()
var m *master.Master
@ -318,7 +340,7 @@ func BenchmarkScheduling(b *testing.B) {
APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
c := client.NewOrDie(&client.Config{

View File

@ -51,8 +51,18 @@ func TestSecrets(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@ -70,7 +80,7 @@ func TestSecrets(t *testing.T) {
APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admit.NewAlwaysAdmit(),
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
framework.DeleteAllEtcdKeys()

View File

@ -33,7 +33,6 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
@ -44,11 +43,11 @@ import (
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/tools/etcdtest"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait"
serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
"k8s.io/kubernetes/test/integration/framework"
)
const (
@ -341,12 +340,23 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
deleteAllEtcdKeys()
// Etcd
etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), latest.GroupOrDie("").InterfacesFor, testapi.Default.Version(), etcdtest.PathPrefix())
etcdStorage, err := framework.NewEtcdStorage()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storageDestinations := master.NewStorageDestinations()
storageDestinations.AddAPIGroup("", etcdStorage)
storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
storageVersions := make(map[string]string)
storageVersions[""] = testapi.Default.Version()
storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
// Listener
var m *master.Master
@ -422,7 +432,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
Authenticator: authenticator,
Authorizer: authorizer,
AdmissionControl: serviceAccountAdmission,
StorageVersions: map[string]string{"": testapi.Default.Version()},
StorageVersions: storageVersions,
})
// Start the service account and service account token controllers