Merge pull request #15516 from nikhiljindal/runtimeConfig
Enable extensions/v1beta1 by default and allow runtimeConfig to support enabling/disabling specific resources
This commit is contained in:
		@@ -9,6 +9,14 @@
 | 
				
			|||||||
    "path": "/api",
 | 
					    "path": "/api",
 | 
				
			||||||
    "description": "get available API versions"
 | 
					    "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",
 | 
					    "path": "/apis",
 | 
				
			||||||
    "description": "get available API versions"
 | 
					    "description": "get available API versions"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3748
									
								
								api/swagger-spec/v1beta1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3748
									
								
								api/swagger-spec/v1beta1.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -59,6 +59,14 @@ function verify-prereqs {
 | 
				
			|||||||
      fi
 | 
					      fi
 | 
				
			||||||
    fi
 | 
					    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
 | 
					  local cmd
 | 
				
			||||||
  for cmd in gcloud gsutil; do
 | 
					  for cmd in gcloud gsutil; do
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -408,30 +408,11 @@ func (s *APIServer) Run(_ []string) error {
 | 
				
			|||||||
		glog.Fatalf("Failure to start kubelet client: %v", err)
 | 
							glog.Fatalf("Failure to start kubelet client: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// "api/all=false" allows users to selectively enable specific api versions.
 | 
						apiGroupVersionOverrides, err := s.parseRuntimeConfig()
 | 
				
			||||||
	disableAllAPIs := false
 | 
						if err != nil {
 | 
				
			||||||
	allAPIFlagValue, ok := s.RuntimeConfig["api/all"]
 | 
							glog.Fatalf("error in parsing runtime-config: %s", err)
 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
	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{
 | 
						clientConfig := &client.Config{
 | 
				
			||||||
		Host:    net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)),
 | 
							Host:    net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)),
 | 
				
			||||||
		Version: s.DeprecatedStorageVersion,
 | 
							Version: s.DeprecatedStorageVersion,
 | 
				
			||||||
@@ -458,17 +439,17 @@ func (s *APIServer) Run(_ []string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						storageDestinations.AddAPIGroup("", etcdStorage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if enableExp {
 | 
						if !apiGroupVersionOverrides["extensions/v1beta1"].Disable {
 | 
				
			||||||
		expGroup, err := latest.Group("extensions")
 | 
							expGroup, err := latest.Group("extensions")
 | 
				
			||||||
		if err != nil {
 | 
							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 {
 | 
							if _, found := storageVersions[expGroup.Group]; !found {
 | 
				
			||||||
			glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", expGroup.Group, storageVersions)
 | 
								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)
 | 
							expEtcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, expGroup.InterfacesFor, storageVersions[expGroup.Group], s.EtcdPathPrefix)
 | 
				
			||||||
		if err != nil {
 | 
							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)
 | 
							storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -558,8 +539,7 @@ func (s *APIServer) Run(_ []string) error {
 | 
				
			|||||||
		SupportsBasicAuth:         len(s.BasicAuthFile) > 0,
 | 
							SupportsBasicAuth:         len(s.BasicAuthFile) > 0,
 | 
				
			||||||
		Authorizer:                authorizer,
 | 
							Authorizer:                authorizer,
 | 
				
			||||||
		AdmissionControl:          admissionController,
 | 
							AdmissionControl:          admissionController,
 | 
				
			||||||
		DisableV1:                 disableV1,
 | 
							APIGroupVersionOverrides:  apiGroupVersionOverrides,
 | 
				
			||||||
		EnableExp:                 enableExp,
 | 
					 | 
				
			||||||
		MasterServiceNamespace:    s.MasterServiceNamespace,
 | 
							MasterServiceNamespace:    s.MasterServiceNamespace,
 | 
				
			||||||
		ClusterName:               s.ClusterName,
 | 
							ClusterName:               s.ClusterName,
 | 
				
			||||||
		ExternalHost:              s.ExternalHost,
 | 
							ExternalHost:              s.ExternalHost,
 | 
				
			||||||
@@ -680,3 +660,61 @@ func (s *APIServer) getRuntimeConfigValue(apiKey string, defaultValue bool) bool
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return defaultValue
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,6 @@ KUBE_API_VERSIONS="v1,extensions/v1beta1" "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver
 | 
				
			|||||||
  --public-address-override="127.0.0.1" \
 | 
					  --public-address-override="127.0.0.1" \
 | 
				
			||||||
  --advertise-address="10.10.10.10" \
 | 
					  --advertise-address="10.10.10.10" \
 | 
				
			||||||
  --kubelet-port=${KUBELET_PORT} \
 | 
					  --kubelet-port=${KUBELET_PORT} \
 | 
				
			||||||
  --runtime-config=api/v1 \
 | 
					 | 
				
			||||||
  --service-cluster-ip-range="10.0.0.0/24" >/dev/null 2>&1 &
 | 
					  --service-cluster-ip-range="10.0.0.0/24" >/dev/null 2>&1 &
 | 
				
			||||||
APISERVER_PID=$!
 | 
					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}version > ${SWAGGER_ROOT_DIR}/version.json
 | 
				
			||||||
curl -fs ${SWAGGER_API_PATH}api > ${SWAGGER_ROOT_DIR}/api.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}api/v1 > ${SWAGGER_ROOT_DIR}/v1.json
 | 
				
			||||||
 | 
					curl -fs ${SWAGGER_API_PATH}apis/extensions/v1beta1 > ${SWAGGER_ROOT_DIR}/v1beta1.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
kube::log::status "SUCCESS"
 | 
					kube::log::status "SUCCESS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,7 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/ui"
 | 
						"k8s.io/kubernetes/pkg/ui"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util"
 | 
						"k8s.io/kubernetes/pkg/util"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
						"k8s.io/kubernetes/pkg/util/sets"
 | 
				
			||||||
 | 
						utilSets "k8s.io/kubernetes/pkg/util/sets"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	daemonetcd "k8s.io/kubernetes/pkg/registry/daemonset/etcd"
 | 
						daemonetcd "k8s.io/kubernetes/pkg/registry/daemonset/etcd"
 | 
				
			||||||
	horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd"
 | 
						horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd"
 | 
				
			||||||
@@ -166,6 +167,15 @@ func (s *StorageDestinations) backends() []string {
 | 
				
			|||||||
	return backends.List()
 | 
						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.
 | 
					// Config is a structure used to configure a Master.
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	StorageDestinations StorageDestinations
 | 
						StorageDestinations StorageDestinations
 | 
				
			||||||
@@ -180,9 +190,8 @@ type Config struct {
 | 
				
			|||||||
	EnableUISupport       bool
 | 
						EnableUISupport       bool
 | 
				
			||||||
	// allow downstream consumers to disable swagger
 | 
						// allow downstream consumers to disable swagger
 | 
				
			||||||
	EnableSwaggerSupport bool
 | 
						EnableSwaggerSupport bool
 | 
				
			||||||
	// allow api versions to be conditionally disabled
 | 
						// Allows api group versions or specific resources to be conditionally enabled/disabled.
 | 
				
			||||||
	DisableV1 bool
 | 
						APIGroupVersionOverrides map[string]APIGroupVersionOverride
 | 
				
			||||||
	EnableExp bool
 | 
					 | 
				
			||||||
	// allow downstream consumers to disable the index route
 | 
						// allow downstream consumers to disable the index route
 | 
				
			||||||
	EnableIndex           bool
 | 
						EnableIndex           bool
 | 
				
			||||||
	EnableProfiling       bool
 | 
						EnableProfiling       bool
 | 
				
			||||||
@@ -271,26 +280,25 @@ type Master struct {
 | 
				
			|||||||
	cacheTimeout          time.Duration
 | 
						cacheTimeout          time.Duration
 | 
				
			||||||
	minRequestTimeout     time.Duration
 | 
						minRequestTimeout     time.Duration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mux                   apiserver.Mux
 | 
						mux                      apiserver.Mux
 | 
				
			||||||
	muxHelper             *apiserver.MuxHelper
 | 
						muxHelper                *apiserver.MuxHelper
 | 
				
			||||||
	handlerContainer      *restful.Container
 | 
						handlerContainer         *restful.Container
 | 
				
			||||||
	rootWebService        *restful.WebService
 | 
						rootWebService           *restful.WebService
 | 
				
			||||||
	enableCoreControllers bool
 | 
						enableCoreControllers    bool
 | 
				
			||||||
	enableLogsSupport     bool
 | 
						enableLogsSupport        bool
 | 
				
			||||||
	enableUISupport       bool
 | 
						enableUISupport          bool
 | 
				
			||||||
	enableSwaggerSupport  bool
 | 
						enableSwaggerSupport     bool
 | 
				
			||||||
	enableProfiling       bool
 | 
						enableProfiling          bool
 | 
				
			||||||
	enableWatchCache      bool
 | 
						enableWatchCache         bool
 | 
				
			||||||
	apiPrefix             string
 | 
						apiPrefix                string
 | 
				
			||||||
	apiGroupPrefix        string
 | 
						apiGroupPrefix           string
 | 
				
			||||||
	corsAllowedOriginList []string
 | 
						corsAllowedOriginList    []string
 | 
				
			||||||
	authenticator         authenticator.Request
 | 
						authenticator            authenticator.Request
 | 
				
			||||||
	authorizer            authorizer.Authorizer
 | 
						authorizer               authorizer.Authorizer
 | 
				
			||||||
	admissionControl      admission.Interface
 | 
						admissionControl         admission.Interface
 | 
				
			||||||
	masterCount           int
 | 
						masterCount              int
 | 
				
			||||||
	v1                    bool
 | 
						apiGroupVersionOverrides map[string]APIGroupVersionOverride
 | 
				
			||||||
	exp                   bool
 | 
						requestContextMapper     api.RequestContextMapper
 | 
				
			||||||
	requestContextMapper  api.RequestContextMapper
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// External host is the name that should be used in external (public internet) URLs for this master
 | 
						// External host is the name that should be used in external (public internet) URLs for this master
 | 
				
			||||||
	externalHost string
 | 
						externalHost string
 | 
				
			||||||
@@ -435,24 +443,23 @@ func New(c *Config) *Master {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m := &Master{
 | 
						m := &Master{
 | 
				
			||||||
		serviceClusterIPRange: c.ServiceClusterIPRange,
 | 
							serviceClusterIPRange:    c.ServiceClusterIPRange,
 | 
				
			||||||
		serviceNodePortRange:  c.ServiceNodePortRange,
 | 
							serviceNodePortRange:     c.ServiceNodePortRange,
 | 
				
			||||||
		rootWebService:        new(restful.WebService),
 | 
							rootWebService:           new(restful.WebService),
 | 
				
			||||||
		enableCoreControllers: c.EnableCoreControllers,
 | 
							enableCoreControllers:    c.EnableCoreControllers,
 | 
				
			||||||
		enableLogsSupport:     c.EnableLogsSupport,
 | 
							enableLogsSupport:        c.EnableLogsSupport,
 | 
				
			||||||
		enableUISupport:       c.EnableUISupport,
 | 
							enableUISupport:          c.EnableUISupport,
 | 
				
			||||||
		enableSwaggerSupport:  c.EnableSwaggerSupport,
 | 
							enableSwaggerSupport:     c.EnableSwaggerSupport,
 | 
				
			||||||
		enableProfiling:       c.EnableProfiling,
 | 
							enableProfiling:          c.EnableProfiling,
 | 
				
			||||||
		enableWatchCache:      c.EnableWatchCache,
 | 
							enableWatchCache:         c.EnableWatchCache,
 | 
				
			||||||
		apiPrefix:             c.APIPrefix,
 | 
							apiPrefix:                c.APIPrefix,
 | 
				
			||||||
		apiGroupPrefix:        c.APIGroupPrefix,
 | 
							apiGroupPrefix:           c.APIGroupPrefix,
 | 
				
			||||||
		corsAllowedOriginList: c.CorsAllowedOriginList,
 | 
							corsAllowedOriginList:    c.CorsAllowedOriginList,
 | 
				
			||||||
		authenticator:         c.Authenticator,
 | 
							authenticator:            c.Authenticator,
 | 
				
			||||||
		authorizer:            c.Authorizer,
 | 
							authorizer:               c.Authorizer,
 | 
				
			||||||
		admissionControl:      c.AdmissionControl,
 | 
							admissionControl:         c.AdmissionControl,
 | 
				
			||||||
		v1:                    !c.DisableV1,
 | 
							apiGroupVersionOverrides: c.APIGroupVersionOverrides,
 | 
				
			||||||
		exp:                   c.EnableExp,
 | 
							requestContextMapper:     c.RequestContextMapper,
 | 
				
			||||||
		requestContextMapper:  c.RequestContextMapper,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cacheTimeout:      c.CacheTimeout,
 | 
							cacheTimeout:      c.CacheTimeout,
 | 
				
			||||||
		minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
 | 
							minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
 | 
				
			||||||
@@ -624,7 +631,8 @@ func (m *Master) init(c *Config) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	apiVersions := []string{}
 | 
						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 {
 | 
							if err := m.api_v1().InstallREST(m.handlerContainer); err != nil {
 | 
				
			||||||
			glog.Fatalf("Unable to setup API v1: %v", err)
 | 
								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 records all supported groups at /apis
 | 
				
			||||||
	allGroups := []unversioned.APIGroup{}
 | 
						allGroups := []unversioned.APIGroup{}
 | 
				
			||||||
	if m.exp {
 | 
						// Install extensions unless disabled.
 | 
				
			||||||
 | 
						if !m.apiGroupVersionOverrides["extensions/v1beta1"].Disable {
 | 
				
			||||||
		m.thirdPartyStorage = c.StorageDestinations.APIGroups["extensions"].Default
 | 
							m.thirdPartyStorage = c.StorageDestinations.APIGroups["extensions"].Default
 | 
				
			||||||
		m.thirdPartyResources = map[string]*thirdpartyresourcedataetcd.REST{}
 | 
							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
 | 
					// experimental returns the resources and codec for the experimental api
 | 
				
			||||||
func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
 | 
					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 {
 | 
						dbClient := func(resource string) storage.Interface {
 | 
				
			||||||
		return c.StorageDestinations.get("extensions", resource)
 | 
							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{
 | 
						storage := map[string]rest.Storage{}
 | 
				
			||||||
		master: m,
 | 
						if isEnabled("replicationcontrollers") {
 | 
				
			||||||
		thirdPartyResourceRegistry: thirdPartyResourceStorage,
 | 
							controllerStorage := expcontrolleretcd.NewStorage(c.StorageDestinations.get("", "replicationControllers"))
 | 
				
			||||||
 | 
							storage["replicationcontrollers"] = controllerStorage.ReplicationController
 | 
				
			||||||
 | 
							storage["replicationcontrollers/scale"] = controllerStorage.Scale
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	go func() {
 | 
						if isEnabled("horizontalpodautoscalers") {
 | 
				
			||||||
		util.Forever(func() {
 | 
							autoscalerStorage, autoscalerStatusStorage := horizontalpodautoscaleretcd.NewREST(dbClient("horizonalpodautoscalers"))
 | 
				
			||||||
			if err := thirdPartyControl.SyncResources(); err != nil {
 | 
							storage["horizontalpodautoscalers"] = autoscalerStorage
 | 
				
			||||||
				glog.Warningf("third party resource sync failed: %v", err)
 | 
							storage["horizontalpodautoscalers/status"] = autoscalerStatusStorage
 | 
				
			||||||
			}
 | 
						}
 | 
				
			||||||
		}, 10*time.Second)
 | 
						if isEnabled("thirdpartyresources") {
 | 
				
			||||||
	}()
 | 
							thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(dbClient("thirdpartyresources"))
 | 
				
			||||||
	storage := map[string]rest.Storage{
 | 
							thirdPartyControl := ThirdPartyController{
 | 
				
			||||||
		strings.ToLower("replicationControllers"):          controllerStorage.ReplicationController,
 | 
								master: m,
 | 
				
			||||||
		strings.ToLower("replicationControllers/scale"):    controllerStorage.Scale,
 | 
								thirdPartyResourceRegistry: thirdPartyResourceStorage,
 | 
				
			||||||
		strings.ToLower("horizontalpodautoscalers"):        autoscalerStorage,
 | 
							}
 | 
				
			||||||
		strings.ToLower("horizontalpodautoscalers/status"): autoscalerStatusStorage,
 | 
							go func() {
 | 
				
			||||||
		strings.ToLower("thirdpartyresources"):             thirdPartyResourceStorage,
 | 
								util.Forever(func() {
 | 
				
			||||||
		strings.ToLower("daemonsets"):                      daemonSetStorage,
 | 
									if err := thirdPartyControl.SyncResources(); err != nil {
 | 
				
			||||||
		strings.ToLower("daemonsets/status"):               daemonSetStatusStorage,
 | 
										glog.Warningf("third party resource sync failed: %v", err)
 | 
				
			||||||
		strings.ToLower("deployments"):                     deploymentStorage.Deployment,
 | 
									}
 | 
				
			||||||
		strings.ToLower("deployments/scale"):               deploymentStorage.Scale,
 | 
								}, 10*time.Second)
 | 
				
			||||||
		strings.ToLower("jobs"):                            jobStorage,
 | 
							}()
 | 
				
			||||||
		strings.ToLower("jobs/status"):                     jobStatusStorage,
 | 
					
 | 
				
			||||||
		strings.ToLower("ingress"):                         ingressStorage,
 | 
							storage["thirdpartyresources"] = thirdPartyResourceStorage
 | 
				
			||||||
		strings.ToLower("ingress/status"):                  ingressStatusStorage,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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{
 | 
						return &apiserver.APIGroupVersion{
 | 
				
			||||||
		Root: m.apiGroupPrefix,
 | 
							Root: m.apiGroupPrefix,
 | 
				
			||||||
@@ -1071,11 +1106,11 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
 | 
				
			|||||||
		Convertor: api.Scheme,
 | 
							Convertor: api.Scheme,
 | 
				
			||||||
		Typer:     api.Scheme,
 | 
							Typer:     api.Scheme,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Mapper:        expMeta.RESTMapper,
 | 
							Mapper:        extensionsGroup.RESTMapper,
 | 
				
			||||||
		Codec:         expMeta.Codec,
 | 
							Codec:         extensionsGroup.Codec,
 | 
				
			||||||
		Linker:        expMeta.SelfLinker,
 | 
							Linker:        extensionsGroup.SelfLinker,
 | 
				
			||||||
		Storage:       storage,
 | 
							Storage:       storage,
 | 
				
			||||||
		Version:       expMeta.GroupVersion,
 | 
							Version:       extensionsGroup.GroupVersion,
 | 
				
			||||||
		ServerVersion: latest.GroupOrDie("").GroupVersion,
 | 
							ServerVersion: latest.GroupOrDie("").GroupVersion,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Admit:   m.admissionControl,
 | 
							Admit:   m.admissionControl,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,8 +100,7 @@ func TestNew(t *testing.T) {
 | 
				
			|||||||
	assert.Equal(master.authenticator, config.Authenticator)
 | 
						assert.Equal(master.authenticator, config.Authenticator)
 | 
				
			||||||
	assert.Equal(master.authorizer, config.Authorizer)
 | 
						assert.Equal(master.authorizer, config.Authorizer)
 | 
				
			||||||
	assert.Equal(master.admissionControl, config.AdmissionControl)
 | 
						assert.Equal(master.admissionControl, config.AdmissionControl)
 | 
				
			||||||
	assert.Equal(master.v1, !config.DisableV1)
 | 
						assert.Equal(master.apiGroupVersionOverrides, config.APIGroupVersionOverrides)
 | 
				
			||||||
	assert.Equal(master.exp, config.EnableExp)
 | 
					 | 
				
			||||||
	assert.Equal(master.requestContextMapper, config.RequestContextMapper)
 | 
						assert.Equal(master.requestContextMapper, config.RequestContextMapper)
 | 
				
			||||||
	assert.Equal(master.cacheTimeout, config.CacheTimeout)
 | 
						assert.Equal(master.cacheTimeout, config.CacheTimeout)
 | 
				
			||||||
	assert.Equal(master.masterCount, config.MasterCount)
 | 
						assert.Equal(master.masterCount, config.MasterCount)
 | 
				
			||||||
@@ -366,7 +365,6 @@ func TestGetNodeAddresses(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDiscoveryAtAPIS(t *testing.T) {
 | 
					func TestDiscoveryAtAPIS(t *testing.T) {
 | 
				
			||||||
	master, config, assert := setUp(t)
 | 
						master, config, assert := setUp(t)
 | 
				
			||||||
	master.exp = true
 | 
					 | 
				
			||||||
	// ================= preparation for master.init() ======================
 | 
						// ================= preparation for master.init() ======================
 | 
				
			||||||
	portRange := util.PortRange{Base: 10, Size: 10}
 | 
						portRange := util.PortRange{Base: 10, Size: 10}
 | 
				
			||||||
	master.serviceNodePortRange = portRange
 | 
						master.serviceNodePortRange = portRange
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -390,8 +390,19 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
		m.Handler.ServeHTTP(w, req)
 | 
							m.Handler.ServeHTTP(w, req)
 | 
				
			||||||
@@ -408,7 +419,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
 | 
				
			|||||||
		APIPrefix:             "/api",
 | 
							APIPrefix:             "/api",
 | 
				
			||||||
		Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
							Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
@@ -508,8 +519,18 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
@@ -527,7 +548,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
 | 
				
			|||||||
		APIPrefix:             "/api",
 | 
							APIPrefix:             "/api",
 | 
				
			||||||
		Authorizer:            apiserver.NewAlwaysDenyAuthorizer(),
 | 
							Authorizer:            apiserver.NewAlwaysDenyAuthorizer(),
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
@@ -578,8 +599,18 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
@@ -598,7 +629,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            allowAliceAuthorizer{},
 | 
							Authorizer:            allowAliceAuthorizer{},
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	previousResourceVersion := make(map[string]float64)
 | 
						previousResourceVersion := make(map[string]float64)
 | 
				
			||||||
@@ -668,8 +699,18 @@ func TestBobIsForbidden(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
@@ -688,7 +729,7 @@ func TestBobIsForbidden(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            allowAliceAuthorizer{},
 | 
							Authorizer:            allowAliceAuthorizer{},
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
@@ -732,8 +773,18 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
@@ -752,7 +803,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            allowAliceAuthorizer{},
 | 
							Authorizer:            allowAliceAuthorizer{},
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
@@ -819,8 +870,18 @@ func TestAuthorizationAttributeDetermination(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						storageDestinations.AddAPIGroup("", etcdStorage)
 | 
				
			||||||
 | 
						storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						storageVersions := make(map[string]string)
 | 
				
			||||||
 | 
						storageVersions[""] = testapi.Default.Version()
 | 
				
			||||||
 | 
						storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	trackingAuthorizer := &trackingAuthorizer{}
 | 
						trackingAuthorizer := &trackingAuthorizer{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -841,7 +902,7 @@ func TestAuthorizationAttributeDetermination(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            trackingAuthorizer,
 | 
							Authorizer:            trackingAuthorizer,
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
@@ -902,8 +963,18 @@ func TestNamespaceAuthorization(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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"}
 | 
						a := newAuthorizerWithContents(t, `{"namespace": "foo"}
 | 
				
			||||||
`)
 | 
					`)
 | 
				
			||||||
@@ -925,7 +996,7 @@ func TestNamespaceAuthorization(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            a,
 | 
							Authorizer:            a,
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	previousResourceVersion := make(map[string]float64)
 | 
						previousResourceVersion := make(map[string]float64)
 | 
				
			||||||
@@ -1020,8 +1091,18 @@ func TestKindAuthorization(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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"}
 | 
						a := newAuthorizerWithContents(t, `{"resource": "services"}
 | 
				
			||||||
`)
 | 
					`)
 | 
				
			||||||
@@ -1043,7 +1124,7 @@ func TestKindAuthorization(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            a,
 | 
							Authorizer:            a,
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	previousResourceVersion := make(map[string]float64)
 | 
						previousResourceVersion := make(map[string]float64)
 | 
				
			||||||
@@ -1126,8 +1207,18 @@ func TestReadOnlyAuthorization(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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}`)
 | 
						a := newAuthorizerWithContents(t, `{"readonly": true}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1148,7 +1239,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
 | 
				
			|||||||
		Authenticator:         getTestTokenAuth(),
 | 
							Authenticator:         getTestTokenAuth(),
 | 
				
			||||||
		Authorizer:            a,
 | 
							Authorizer:            a,
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transport := http.DefaultTransport
 | 
						transport := http.DefaultTransport
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,13 @@ func NewEtcdStorage() (storage.Interface, error) {
 | 
				
			|||||||
	return master.NewEtcdStorage(NewEtcdClient(), latest.GroupOrDie("").InterfacesFor, testapi.Default.Version(), etcdtest.PathPrefix())
 | 
						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() {
 | 
					func RequireEtcd() {
 | 
				
			||||||
	if _, err := NewEtcdClient().Get("/", false, false); err != nil {
 | 
						if _, err := NewEtcdClient().Get("/", false, false); err != nil {
 | 
				
			||||||
		glog.Fatalf("unable to connect to etcd for testing: %v", err)
 | 
							glog.Fatalf("unable to connect to etcd for testing: %v", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,8 +131,8 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			glog.Fatalf("Failed to create etcd storage for master %v", err)
 | 
								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())
 | 
							expEtcdStorage, err := NewExtensionsEtcdStorage(etcdClient)
 | 
				
			||||||
		storageVersions["extensions"] = latest.GroupOrDie("extensions").GroupVersion
 | 
							storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			glog.Fatalf("Failed to create etcd storage for master %v", err)
 | 
								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,
 | 
								StorageDestinations:  storageDestinations,
 | 
				
			||||||
			StorageVersions:      storageVersions,
 | 
								StorageVersions:      storageVersions,
 | 
				
			||||||
			KubeletClient:        client.FakeKubeletClient{},
 | 
								KubeletClient:        client.FakeKubeletClient{},
 | 
				
			||||||
			EnableExp:            true,
 | 
					 | 
				
			||||||
			EnableLogsSupport:    false,
 | 
								EnableLogsSupport:    false,
 | 
				
			||||||
			EnableProfiling:      true,
 | 
								EnableProfiling:      true,
 | 
				
			||||||
			EnableSwaggerSupport: true,
 | 
								EnableSwaggerSupport: true,
 | 
				
			||||||
@@ -275,7 +274,7 @@ func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							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()
 | 
						storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
@@ -292,7 +291,6 @@ func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
 | 
				
			|||||||
		EnableUISupport:     false,
 | 
							EnableUISupport:     false,
 | 
				
			||||||
		APIPrefix:           "/api",
 | 
							APIPrefix:           "/api",
 | 
				
			||||||
		APIGroupPrefix:      "/apis",
 | 
							APIGroupPrefix:      "/apis",
 | 
				
			||||||
		EnableExp:           true,
 | 
					 | 
				
			||||||
		Authorizer:          apiserver.NewAlwaysAllowAuthorizer(),
 | 
							Authorizer:          apiserver.NewAlwaysAllowAuthorizer(),
 | 
				
			||||||
		AdmissionControl:    admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:    admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:     storageVersions,
 | 
							StorageVersions:     storageVersions,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@ func TestKubectlValidation(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// The following test the experimental api.
 | 
							// The following test the experimental api.
 | 
				
			||||||
		// TOOD: Replace with something more robust. These may move.
 | 
							// 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": "extensions/v1beta1", "kind": "Job"}`, false},
 | 
				
			||||||
		{`{"apiVersion": "vNotAVersion", "kind": "Job"}`, true},
 | 
							{`{"apiVersion": "vNotAVersion", "kind": "Job"}`, true},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,8 +59,19 @@ func TestUnschedulableNodes(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Couldn't create etcd storage: %v", err)
 | 
							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 := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						storageDestinations.AddAPIGroup("", etcdStorage)
 | 
				
			||||||
 | 
						storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						storageVersions := make(map[string]string)
 | 
				
			||||||
 | 
						storageVersions[""] = testapi.Default.Version()
 | 
				
			||||||
 | 
						storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	framework.DeleteAllEtcdKeys()
 | 
						framework.DeleteAllEtcdKeys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var m *master.Master
 | 
						var m *master.Master
 | 
				
			||||||
@@ -79,7 +90,7 @@ func TestUnschedulableNodes(t *testing.T) {
 | 
				
			|||||||
		APIPrefix:             "/api",
 | 
							APIPrefix:             "/api",
 | 
				
			||||||
		Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
							Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	restClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
 | 
						restClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
 | 
				
			||||||
@@ -298,8 +309,19 @@ func BenchmarkScheduling(b *testing.B) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		b.Fatalf("Couldn't create etcd storage: %v", err)
 | 
							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 := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						storageDestinations.AddAPIGroup("", etcdStorage)
 | 
				
			||||||
 | 
						storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						storageVersions := make(map[string]string)
 | 
				
			||||||
 | 
						storageVersions[""] = testapi.Default.Version()
 | 
				
			||||||
 | 
						storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	framework.DeleteAllEtcdKeys()
 | 
						framework.DeleteAllEtcdKeys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var m *master.Master
 | 
						var m *master.Master
 | 
				
			||||||
@@ -318,7 +340,7 @@ func BenchmarkScheduling(b *testing.B) {
 | 
				
			|||||||
		APIPrefix:             "/api",
 | 
							APIPrefix:             "/api",
 | 
				
			||||||
		Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
							Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c := client.NewOrDie(&client.Config{
 | 
						c := client.NewOrDie(&client.Config{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,8 +51,18 @@ func TestSecrets(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						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
 | 
						var m *master.Master
 | 
				
			||||||
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
@@ -70,7 +80,7 @@ func TestSecrets(t *testing.T) {
 | 
				
			|||||||
		APIPrefix:             "/api",
 | 
							APIPrefix:             "/api",
 | 
				
			||||||
		Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
							Authorizer:            apiserver.NewAlwaysAllowAuthorizer(),
 | 
				
			||||||
		AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
							AdmissionControl:      admit.NewAlwaysAdmit(),
 | 
				
			||||||
		StorageVersions:       map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:       storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	framework.DeleteAllEtcdKeys()
 | 
						framework.DeleteAllEtcdKeys()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/errors"
 | 
						"k8s.io/kubernetes/pkg/api/errors"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/latest"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/testapi"
 | 
						"k8s.io/kubernetes/pkg/api/testapi"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/auth/authenticator"
 | 
						"k8s.io/kubernetes/pkg/auth/authenticator"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
 | 
						"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
 | 
				
			||||||
@@ -44,11 +43,11 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/fields"
 | 
						"k8s.io/kubernetes/pkg/fields"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/labels"
 | 
						"k8s.io/kubernetes/pkg/labels"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/master"
 | 
						"k8s.io/kubernetes/pkg/master"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/tools/etcdtest"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
						"k8s.io/kubernetes/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/wait"
 | 
						"k8s.io/kubernetes/pkg/util/wait"
 | 
				
			||||||
	serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
 | 
						serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
 | 
				
			||||||
	"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
 | 
						"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/test/integration/framework"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -341,12 +340,23 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
 | 
				
			|||||||
	deleteAllEtcdKeys()
 | 
						deleteAllEtcdKeys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Etcd
 | 
						// Etcd
 | 
				
			||||||
	etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), latest.GroupOrDie("").InterfacesFor, testapi.Default.Version(), etcdtest.PathPrefix())
 | 
						etcdStorage, err := framework.NewEtcdStorage()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error: %v", err)
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expEtcdStorage, err := framework.NewExtensionsEtcdStorage(nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storageDestinations := master.NewStorageDestinations()
 | 
						storageDestinations := master.NewStorageDestinations()
 | 
				
			||||||
	storageDestinations.AddAPIGroup("", etcdStorage)
 | 
						storageDestinations.AddAPIGroup("", etcdStorage)
 | 
				
			||||||
 | 
						storageDestinations.AddAPIGroup("extensions", expEtcdStorage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						storageVersions := make(map[string]string)
 | 
				
			||||||
 | 
						storageVersions[""] = testapi.Default.Version()
 | 
				
			||||||
 | 
						storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Listener
 | 
						// Listener
 | 
				
			||||||
	var m *master.Master
 | 
						var m *master.Master
 | 
				
			||||||
@@ -422,7 +432,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
 | 
				
			|||||||
		Authenticator:       authenticator,
 | 
							Authenticator:       authenticator,
 | 
				
			||||||
		Authorizer:          authorizer,
 | 
							Authorizer:          authorizer,
 | 
				
			||||||
		AdmissionControl:    serviceAccountAdmission,
 | 
							AdmissionControl:    serviceAccountAdmission,
 | 
				
			||||||
		StorageVersions:     map[string]string{"": testapi.Default.Version()},
 | 
							StorageVersions:     storageVersions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start the service account and service account token controllers
 | 
						// Start the service account and service account token controllers
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user