func TestGroupVersions(t *testing.T) {
	// legacyUnsuffixedGroups contains the groups released prior to deciding that kubernetes API groups should be dns-suffixed
	// new groups should be suffixed with ".k8s.io" (https://github.com/kubernetes/kubernetes/pull/31887#issuecomment-244462396)
	legacyUnsuffixedGroups := sets.NewString(
		"",
		"apps",
		"autoscaling",
		"batch",
		"componentconfig",
		"extensions",
		"federation",
		"policy",
	)

	// No new groups should be added to the legacyUnsuffixedGroups exclusion list
	if len(legacyUnsuffixedGroups) != 8 {
		t.Errorf("No additional unnamespaced groups should be created")
	}

	for _, gv := range registered.RegisteredGroupVersions() {
		if !strings.HasSuffix(gv.Group, ".k8s.io") && !legacyUnsuffixedGroups.Has(gv.Group) {
			t.Errorf("Group %s does not have the standard kubernetes API group suffix of .k8s.io", gv.Group)
		}
	}
}
Beispiel #2
0
func TestDescriptions(t *testing.T) {
	for _, version := range registered.RegisteredGroupVersions() {
		seen := map[reflect.Type]bool{}

		for _, apiType := range kapi.Scheme.KnownTypes(version) {
			checkDescriptions(apiType, &seen, t)
		}
	}
}
Beispiel #3
0
func TestExternalJsonTags(t *testing.T) {
	seen := map[reflect.Type]bool{}

	for _, version := range registered.RegisteredGroupVersions() {
		for _, apiType := range kapi.Scheme.KnownTypes(version) {
			checkExternalJsonTags(apiType, &seen, t)
		}
	}

	for _, apiType := range configapi.Scheme.KnownTypes(configapiv1.SchemeGroupVersion) {
		checkExternalJsonTags(apiType, &seen, t)
	}

}
Beispiel #4
0
func TestInternalJsonTags(t *testing.T) {
	seen := map[reflect.Type]bool{}
	seenGroups := sets.String{}

	for _, version := range registered.RegisteredGroupVersions() {
		if seenGroups.Has(version.Group) {
			continue
		}
		seenGroups.Insert(version.Group)

		internalVersion := unversioned.GroupVersion{Group: version.Group, Version: runtime.APIVersionInternal}
		for _, apiType := range kapi.Scheme.KnownTypes(internalVersion) {
			checkInternalJsonTags(apiType, &seen, t)
		}
	}

	for _, apiType := range configapi.Scheme.KnownTypes(configapi.SchemeGroupVersion) {
		checkInternalJsonTags(apiType, &seen, t)
	}
}
func TestParseRuntimeConfig(t *testing.T) {
	extensionsGroupVersion := extensionsapiv1beta1.SchemeGroupVersion
	apiv1GroupVersion := apiv1.SchemeGroupVersion
	testCases := []struct {
		runtimeConfig         map[string]string
		defaultResourceConfig func() *ResourceConfig
		expectedAPIConfig     func() *ResourceConfig
		err                   bool
	}{
		{
			// everything default value.
			runtimeConfig: map[string]string{},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			err: false,
		},
		{
			// no runtimeConfig override.
			runtimeConfig: map[string]string{},
			defaultResourceConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
				return config
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
				return config
			},
			err: false,
		},
		{
			// version enabled by runtimeConfig override.
			runtimeConfig: map[string]string{
				"extensions/v1beta1": "",
			},
			defaultResourceConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
				return config
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(extensionsapiv1beta1.SchemeGroupVersion)
				return config
			},
			err: false,
		},
		{
			// disable resource
			runtimeConfig: map[string]string{
				"api/v1/pods": "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(apiv1GroupVersion)
				return config
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(apiv1GroupVersion)
				config.DisableResources(apiv1GroupVersion.WithResource("pods"))
				return config
			},
			err: false,
		},
		{
			// Disable v1.
			runtimeConfig: map[string]string{
				"api/v1": "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableVersions(apiv1GroupVersion)
				return config
			},
			err: false,
		},
		{
			// Enable deployments and disable jobs.
			runtimeConfig: map[string]string{
				"extensions/v1beta1/anything": "true",
				"extensions/v1beta1/jobs":     "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(extensionsGroupVersion)
				return config
			},

			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(extensionsGroupVersion)
				config.DisableResources(extensionsGroupVersion.WithResource("jobs"))
				config.EnableResources(extensionsGroupVersion.WithResource("anything"))
				return config
			},
			err: false,
		},
		{
			// invalid runtime config
			runtimeConfig: map[string]string{
				"invalidgroup/version": "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			err: true,
		},
		{
			// cannot disable individual resource when version is not enabled.
			runtimeConfig: map[string]string{
				"api/v1/pods": "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableResources(schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"})
				return config
			},
			err: true,
		},
		{
			// enable all
			runtimeConfig: map[string]string{
				"api/all": "true",
			},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.EnableVersions(registered.RegisteredGroupVersions()...)
				return config
			},
			err: false,
		},
		{
			// disable all
			runtimeConfig: map[string]string{
				"api/all": "false",
			},
			defaultResourceConfig: func() *ResourceConfig {
				return NewResourceConfig()
			},
			expectedAPIConfig: func() *ResourceConfig {
				config := NewResourceConfig()
				config.DisableVersions(registered.RegisteredGroupVersions()...)
				return config
			},
			err: false,
		},
	}
	for _, test := range testCases {
		actualDisablers, err := mergeAPIResourceConfigs(test.defaultResourceConfig(), test.runtimeConfig)
		if err == nil && test.err {
			t.Fatalf("expected error for test: %v", test)
		} else if err != nil && !test.err {
			t.Fatalf("unexpected error: %s, for test: %v", err, test)
		}

		expectedConfig := test.expectedAPIConfig()
		if err == nil && !reflect.DeepEqual(actualDisablers, expectedConfig) {
			t.Fatalf("%v: unexpected apiResourceDisablers. Actual: %v\n expected: %v", test.runtimeConfig, actualDisablers, expectedConfig)
		}
	}
}
// Merges the given defaultAPIResourceConfig with the given resourceConfigOverrides.
func mergeAPIResourceConfigs(defaultAPIResourceConfig *ResourceConfig, resourceConfigOverrides config.ConfigurationMap) (*ResourceConfig, error) {
	resourceConfig := defaultAPIResourceConfig
	overrides := resourceConfigOverrides

	// "api/all=false" allows users to selectively enable specific api versions.
	allAPIFlagValue, ok := overrides["api/all"]
	if ok && allAPIFlagValue == "false" {
		// Disable all group versions.
		for _, groupVersion := range registered.RegisteredGroupVersions() {
			if resourceConfig.AnyResourcesForVersionEnabled(groupVersion) {
				resourceConfig.DisableVersions(groupVersion)
			}
		}
	}

	// "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 := unversioned.ParseGroupVersion(groupVersionString)
		if err != nil {
			return nil, fmt.Errorf("invalid key %s", key)
		}
		// Verify that the groupVersion is registered.
		if !registered.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 := unversioned.ParseGroupVersion(groupVersionString)
		if err != nil {
			return nil, fmt.Errorf("invalid key %s", key)
		}
		resource := tokens[2]
		// Verify that the groupVersion is registered.
		if !registered.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
}