pass APIEnablement through apiserver chain

This commit is contained in:
hzxuzhonghu
2017-12-21 11:27:20 +08:00
parent b7b5bbb20f
commit 2f403b7ad1
20 changed files with 618 additions and 436 deletions

View File

@@ -17,16 +17,11 @@ limitations under the License.
package kubeapiserver
import (
"fmt"
"strconv"
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/server/resourceconfig"
serverstorage "k8s.io/apiserver/pkg/server/storage"
"k8s.io/apiserver/pkg/storage/storagebackend"
utilflag "k8s.io/apiserver/pkg/util/flag"
"k8s.io/kubernetes/pkg/api/legacyscheme"
)
// SpecialDefaultResourcePrefixes are prefixes compiled into Kubernetes.
@@ -41,151 +36,17 @@ var SpecialDefaultResourcePrefixes = map[schema.GroupResource]string{
}
// NewStorageFactory builds the DefaultStorageFactory.
// Merges defaultResourceConfig with the user specified overrides and merges
// defaultAPIResourceConfig with the corresponding user specified overrides as well.
func NewStorageFactory(storageConfig storagebackend.Config, defaultMediaType string, serializer runtime.StorageSerializer,
defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, storageEncodingOverrides map[string]schema.GroupVersion, resourceEncodingOverrides []schema.GroupVersionResource,
defaultAPIResourceConfig *serverstorage.ResourceConfig, resourceConfigOverrides utilflag.ConfigurationMap) (*serverstorage.DefaultStorageFactory, error) {
resourceEncodingConfig := mergeGroupEncodingConfigs(defaultResourceEncoding, storageEncodingOverrides)
resourceEncodingConfig = mergeResourceEncodingConfigs(resourceEncodingConfig, resourceEncodingOverrides)
apiResourceConfig, err := mergeAPIResourceConfigs(defaultAPIResourceConfig, resourceConfigOverrides)
if err != nil {
return nil, err
}
// Merges defaultResourceEncoding with the user specified overrides.
func NewStorageFactory(
storageConfig storagebackend.Config,
defaultMediaType string,
serializer runtime.StorageSerializer,
defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig,
storageEncodingOverrides map[string]schema.GroupVersion,
resourceEncodingOverrides []schema.GroupVersionResource,
apiResourceConfig *serverstorage.ResourceConfig,
) (*serverstorage.DefaultStorageFactory, error) {
resourceEncodingConfig := resourceconfig.MergeGroupEncodingConfigs(defaultResourceEncoding, storageEncodingOverrides)
resourceEncodingConfig = resourceconfig.MergeResourceEncodingConfigs(resourceEncodingConfig, resourceEncodingOverrides)
return serverstorage.NewDefaultStorageFactory(storageConfig, defaultMediaType, serializer, resourceEncodingConfig, apiResourceConfig, SpecialDefaultResourcePrefixes), nil
}
// Merges the given defaultResourceConfig with specific GroupVersionResource overrides.
func mergeResourceEncodingConfigs(defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, resourceEncodingOverrides []schema.GroupVersionResource) *serverstorage.DefaultResourceEncodingConfig {
resourceEncodingConfig := defaultResourceEncoding
for _, gvr := range resourceEncodingOverrides {
resourceEncodingConfig.SetResourceEncoding(gvr.GroupResource(), gvr.GroupVersion(),
schema.GroupVersion{Group: gvr.Group, Version: runtime.APIVersionInternal})
}
return resourceEncodingConfig
}
// Merges the given defaultResourceConfig with specific GroupVersion overrides.
func mergeGroupEncodingConfigs(defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, storageEncodingOverrides map[string]schema.GroupVersion) *serverstorage.DefaultResourceEncodingConfig {
resourceEncodingConfig := defaultResourceEncoding
for group, storageEncodingVersion := range storageEncodingOverrides {
resourceEncodingConfig.SetVersionEncoding(group, storageEncodingVersion, schema.GroupVersion{Group: group, Version: runtime.APIVersionInternal})
}
return resourceEncodingConfig
}
// Merges the given defaultAPIResourceConfig with the given resourceConfigOverrides.
func mergeAPIResourceConfigs(defaultAPIResourceConfig *serverstorage.ResourceConfig, resourceConfigOverrides utilflag.ConfigurationMap) (*serverstorage.ResourceConfig, error) {
resourceConfig := defaultAPIResourceConfig
overrides := resourceConfigOverrides
// "api/all=false" allows users to selectively enable specific api versions.
allAPIFlagValue, ok := overrides["api/all"]
if ok {
if allAPIFlagValue == "false" {
// Disable all group versions.
resourceConfig.DisableVersions(legacyscheme.Registry.RegisteredGroupVersions()...)
} else if allAPIFlagValue == "true" {
resourceConfig.EnableVersions(legacyscheme.Registry.RegisteredGroupVersions()...)
}
}
// "api/legacy=false" allows users to disable legacy api versions.
disableLegacyAPIs := false
legacyAPIFlagValue, ok := overrides["api/legacy"]
if ok && legacyAPIFlagValue == "false" {
disableLegacyAPIs = true
}
_ = disableLegacyAPIs // hush the compiler while we don't have legacy APIs to disable.
// "<resourceSpecifier>={true|false} allows users to enable/disable API.
// This takes preference over api/all and api/legacy, if specified.
// Iterate through all group/version overrides specified in runtimeConfig.
for key := range overrides {
if key == "api/all" || key == "api/legacy" {
// Have already handled them above. Can skip them here.
continue
}
tokens := strings.Split(key, "/")
if len(tokens) != 2 {
continue
}
groupVersionString := tokens[0] + "/" + tokens[1]
// HACK: Hack for "v1" legacy group version.
// Remove when we stop supporting the legacy group version.
if groupVersionString == "api/v1" {
groupVersionString = "v1"
}
groupVersion, err := schema.ParseGroupVersion(groupVersionString)
if err != nil {
return nil, fmt.Errorf("invalid key %s", key)
}
// Verify that the groupVersion is legacyscheme.Registry.
if !legacyscheme.Registry.IsRegisteredVersion(groupVersion) {
return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
}
enabled, err := getRuntimeConfigValue(overrides, key, false)
if err != nil {
return nil, err
}
if enabled {
resourceConfig.EnableVersions(groupVersion)
} else {
resourceConfig.DisableVersions(groupVersion)
}
}
// Iterate through all group/version/resource overrides specified in runtimeConfig.
for key := range overrides {
tokens := strings.Split(key, "/")
if len(tokens) != 3 {
continue
}
groupVersionString := tokens[0] + "/" + tokens[1]
// HACK: Hack for "v1" legacy group version.
// Remove when we stop supporting the legacy group version.
if groupVersionString == "api/v1" {
groupVersionString = "v1"
}
groupVersion, err := schema.ParseGroupVersion(groupVersionString)
if err != nil {
return nil, fmt.Errorf("invalid key %s", key)
}
resource := tokens[2]
// Verify that the groupVersion is legacyscheme.Registry.
if !legacyscheme.Registry.IsRegisteredVersion(groupVersion) {
return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
}
if !resourceConfig.AnyResourcesForVersionEnabled(groupVersion) {
return nil, fmt.Errorf("%v is disabled, you cannot configure its resources individually", groupVersion)
}
enabled, err := getRuntimeConfigValue(overrides, key, false)
if err != nil {
return nil, err
}
if enabled {
resourceConfig.EnableResources(groupVersion.WithResource(resource))
} else {
resourceConfig.DisableResources(groupVersion.WithResource(resource))
}
}
return resourceConfig, nil
}
func getRuntimeConfigValue(overrides utilflag.ConfigurationMap, apiKey string, defaultValue bool) (bool, error) {
flagValue, ok := overrides[apiKey]
if ok {
if flagValue == "" {
return true, nil
}
boolValue, err := strconv.ParseBool(flagValue)
if err != nil {
return false, fmt.Errorf("invalid value of %s: %s, err: %v", apiKey, flagValue, err)
}
return boolValue, nil
}
return defaultValue, nil
}