Example #1
0
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
	scheme := runtime.NewScheme()
	scheme.AddKnownTypeWithName("", "Type", &internalType{})
	scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})
	//This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
	scheme.AddKnownTypeWithName(testapi.Version(), "Type", &ExternalType2{})

	codec := runtime.CodecFor(scheme, "unlikelyversion")
	validVersion := testapi.Version()
	mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion", validVersion}, func(version string) (*meta.VersionInterfaces, bool) {
		return &meta.VersionInterfaces{
			Codec:            runtime.CodecFor(scheme, version),
			ObjectConvertor:  scheme,
			MetadataAccessor: meta.NewAccessor(),
		}, (version == validVersion || version == "unlikelyversion")
	})
	for _, version := range []string{"unlikelyversion", validVersion} {
		for kind := range scheme.KnownTypes(version) {
			mixedCase := false
			scope := meta.RESTScopeNamespace
			mapper.Add(scope, kind, version, mixedCase)
		}
	}

	return scheme, mapper, codec
}
Example #2
0
func Merge(dst runtime.Object, fragment, kind string) error {
	// Ok, this is a little hairy, we'd rather not force the user to specify a kind for their JSON
	// So we pull it into a map, add the Kind field, and then reserialize.
	// We also pull the apiVersion for proper parsing
	var intermediate interface{}
	if err := json.Unmarshal([]byte(fragment), &intermediate); err != nil {
		return err
	}
	dataMap, ok := intermediate.(map[string]interface{})
	if !ok {
		return fmt.Errorf("Expected a map, found something else: %s", fragment)
	}
	version, found := dataMap["apiVersion"]
	if !found {
		return fmt.Errorf("Inline JSON requires an apiVersion field")
	}
	versionString, ok := version.(string)
	if !ok {
		return fmt.Errorf("apiVersion must be a string")
	}
	codec := runtime.CodecFor(api.Scheme, versionString)

	dataMap["kind"] = kind
	data, err := json.Marshal(intermediate)
	if err != nil {
		return err
	}
	src, err := codec.Decode(data)
	if err != nil {
		return err
	}
	return mergo.Merge(dst, src)
}
Example #3
0
func init() {
	// Use the first API version in the list of registered versions as the latest.
	Version = registered.RegisteredVersions[0]
	OldestVersion = registered.RegisteredVersions[len(registered.RegisteredVersions)-1]
	Codec = runtime.CodecFor(api.Scheme, Version)
	// Put the registered versions in Versions in reverse order.
	versions := registered.RegisteredVersions
	Versions = []string{}
	for i := len(versions) - 1; i >= 0; i-- {
		Versions = append(Versions, versions[i])
	}

	mapper := meta.NewDefaultRESTMapper(
		versions,
		func(version string) (*meta.VersionInterfaces, bool) {
			interfaces, err := InterfacesFor(version)
			if err != nil {
				return nil, false
			}
			return interfaces, true
		},
	)

	// the list of kinds that are scoped at the root of the api hierarchy
	// if a kind is not enumerated here, it is assumed to have a namespace scope
	kindToRootScope := map[string]bool{
		"Node":                       true,
		"Minion":                     true,
		"Namespace":                  true,
		"PersistentVolume":           true,
		"SecurityContextConstraints": true,
	}

	// setup aliases for groups of resources
	mapper.AddResourceAlias("all", userResources...)

	// these kinds should be excluded from the list of resources
	ignoredKinds := util.NewStringSet(
		"ListOptions",
		"DeleteOptions",
		"Status",
		"PodLogOptions",
		"PodExecOptions",
		"PodProxyOptions")

	// enumerate all supported versions, get the kinds, and register with the mapper how to address our resources.
	for _, version := range versions {
		for kind := range api.Scheme.KnownTypes(version) {
			if ignoredKinds.Has(kind) {
				continue
			}
			scope := meta.RESTScopeNamespace
			if kindToRootScope[kind] {
				scope = meta.RESTScopeRoot
			}
			mapper.Add(scope, kind, version, false)
		}
	}
	RESTMapper = mapper
}
Example #4
0
func init() {
	scheme = runtime.NewScheme()
	scheme.AddKnownTypes("", &TestResource{})
	scheme.AddKnownTypes(testapi.Version(), &TestResource{})
	codec = runtime.CodecFor(scheme, testapi.Version())
	scheme.AddConversionFuncs(
		func(in *TestResource, out *TestResource, s conversion.Scope) error {
			*out = *in
			return nil
		},
	)
}
Example #5
0
func serviceErrorHandler(requestResolver *APIRequestInfoResolver, apiVersions []string, serviceErr restful.ServiceError, request *restful.Request, response *restful.Response) {
	requestInfo, err := requestResolver.GetAPIRequestInfo(request.Request)
	codec := latest.Codec
	if err == nil && requestInfo.APIVersion != "" {
		// check if the api version is valid.
		for _, version := range apiVersions {
			if requestInfo.APIVersion == version {
				// valid api version.
				codec = runtime.CodecFor(api.Scheme, requestInfo.APIVersion)
				break
			}
		}
	}

	errorJSON(apierrors.NewGenericServerResponse(serviceErr.Code, "", "", "", "", 0, false), codec, response.ResponseWriter)
}
Example #6
0
func getFakeClient(t *testing.T, validURLs []string) (ClientFunc, *httptest.Server) {
	handlerFunc := func(w http.ResponseWriter, r *http.Request) {
		for _, u := range validURLs {
			if u == r.RequestURI {
				return
			}
		}
		t.Errorf("Unexpected HTTP request: %s, expected %v", r.RequestURI, validURLs)
	}
	server := httptest.NewServer(http.HandlerFunc(handlerFunc))
	return func(mapping *meta.RESTMapping) (*client.RESTClient, error) {
		fakeCodec := runtime.CodecFor(api.Scheme, "v1beta1")
		fakeUri, _ := url.Parse(server.URL + "/api/v1beta1")
		return client.NewRESTClient(fakeUri, fakeCodec), nil
	}, server
}
Example #7
0
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
	scheme := runtime.NewScheme()
	scheme.AddKnownTypeWithName("", "Type", &internalType{})
	scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})

	codec := runtime.CodecFor(scheme, "unlikelyversion")
	mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion"}, func(version string) (*meta.VersionInterfaces, bool) {
		return &meta.VersionInterfaces{
			Codec:            codec,
			ObjectConvertor:  scheme,
			MetadataAccessor: meta.NewAccessor(),
		}, (version == "unlikelyversion")
	})
	mapper.Add(scheme, false, "unlikelyversion")

	return scheme, mapper, codec
}
Example #8
0
func init() {
	Version = registered.RegisteredVersions[0]
	Codec = runtime.CodecFor(api.Scheme, Version)
	// Put the registered versions in Versions in reverse order.
	for i := len(registered.RegisteredVersions) - 1; i >= 0; i-- {
		Versions = append(Versions, registered.RegisteredVersions[i])
	}

	// the list of kinds that are scoped at the root of the api hierarchy
	// if a kind is not enumerated here, it is assumed to have a namespace scope
	rootScoped := util.NewStringSet()

	ignoredKinds := util.NewStringSet()

	RESTMapper = api.NewDefaultRESTMapper(Versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped)
	api.RegisterRESTMapper(RESTMapper)
}
func testCompatibility(
	t *testing.T,
	version string,
	input []byte,
	validator func(obj runtime.Object) fielderrors.ValidationErrorList,
	serialized map[string]string,
) {

	// Decode
	codec := runtime.CodecFor(api.Scheme, version)
	obj, err := codec.Decode(input)
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	// Validate
	errs := validator(obj)
	if len(errs) != 0 {
		t.Fatalf("Unexpected errors: %v", errs)
	}

	// Encode
	output, err := codec.Encode(obj)
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	// Validate old and new fields are encoded
	generic := map[string]interface{}{}
	if err := json.Unmarshal(output, &generic); err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	for k, expectedValue := range serialized {
		keys := strings.Split(k, ".")
		if actualValue, ok, err := getJSONValue(generic, keys...); err != nil || !ok {
			t.Errorf("Unexpected error for %s: %v", k, err)
		} else if !reflect.DeepEqual(expectedValue, actualValue) {
			t.Errorf("Expected %v, got %v", expectedValue, actualValue)
		}
	}
}
func TestEncode(t *testing.T) {
	scheme := runtime.NewScheme()
	scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
	scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
	codec := runtime.CodecFor(scheme, "externalVersion")
	test := &InternalSimple{
		TestString: "I'm the same",
	}
	obj := runtime.Object(test)
	data, err := codec.Encode(obj)
	obj2, err2 := codec.Decode(data)
	if err != nil || err2 != nil {
		t.Fatalf("Failure: '%v' '%v'", err, err2)
	}
	if _, ok := obj2.(*InternalSimple); !ok {
		t.Fatalf("Got wrong type")
	}
	if !reflect.DeepEqual(obj2, test) {
		t.Errorf("Expected:\n %#v,\n Got:\n %#v", &test, obj2)
	}
}
Example #11
0
func TestTypes(t *testing.T) {
	for kind, reflectType := range api.Scheme.KnownTypes("") {
		if !strings.Contains(reflectType.PkgPath(), "/origin/") {
			continue
		}
		t.Logf("About to test %v", reflectType)
		// Try a few times, since runTest uses random values.
		for i := 0; i < fuzzIters; i++ {
			item, err := api.Scheme.New("", kind)
			if err != nil {
				t.Errorf("Couldn't make a %v? %v", kind, err)
				continue
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			seed := rand.Int63()

			if versions, ok := skipStandardVersions[kind]; ok {
				for _, v := range versions {
					fuzzInternalObject(t, "", item, seed)
					roundTrip(t, runtime.CodecFor(api.Scheme, v), item)
				}
				continue
			}
			fuzzInternalObject(t, "", item, seed)
			roundTrip(t, osapi.Codec, item)
			if _, ok := skipV1beta3[kind]; !ok {
				fuzzInternalObject(t, "v1beta3", item, seed)
				roundTrip(t, v1beta3.Codec, item)
			}
			if _, ok := skipV1[kind]; !ok {
				fuzzInternalObject(t, "v1", item, seed)
				roundTrip(t, v1.Codec, item)
			}
		}
	}
}
Example #12
0
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
	scheme := runtime.NewScheme()
	scheme.AddKnownTypeWithName("", "Type", &internalType{})
	scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})

	codec := runtime.CodecFor(scheme, "unlikelyversion")
	mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion"}, func(version string) (*meta.VersionInterfaces, bool) {
		return &meta.VersionInterfaces{
			Codec:            codec,
			ObjectConvertor:  scheme,
			MetadataAccessor: meta.NewAccessor(),
		}, (version == "unlikelyversion")
	})
	for _, version := range []string{"unlikelyversion"} {
		for kind := range scheme.KnownTypes(version) {
			mixedCase := false
			scope := meta.RESTScopeNamespace
			mapper.Add(scope, kind, version, mixedCase)
		}
	}

	return scheme, mapper, codec
}
Example #13
0
func init() {
	// Use the first API version in the list of registered versions as the latest.
	Version = registered.RegisteredVersions[0]
	OldestVersion = registered.RegisteredVersions[len(registered.RegisteredVersions)-1]
	Codec = runtime.CodecFor(api.Scheme, Version)
	// Put the registered versions in Versions in reverse order.
	versions := registered.RegisteredVersions
	Versions = []string{}
	for i := len(versions) - 1; i >= 0; i-- {
		Versions = append(Versions, versions[i])
	}

	// the list of kinds that are scoped at the root of the api hierarchy
	// if a kind is not enumerated here, it is assumed to have a namespace scope
	rootScoped := util.NewStringSet(
		"Node",
		"Minion",
		"Namespace",
		"PersistentVolume",
	)

	// these kinds should be excluded from the list of resources
	ignoredKinds := util.NewStringSet(
		"ListOptions",
		"DeleteOptions",
		"Status",
		"PodLogOptions",
		"PodExecOptions",
		"PodAttachOptions",
		"PodProxyOptions")

	mapper := api.NewDefaultRESTMapper(versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped)
	// setup aliases for groups of resources
	mapper.AddResourceAlias("all", userResources...)
	RESTMapper = mapper
	api.RegisterRESTMapper(RESTMapper)
}
Example #14
0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
)

// Codec encodes internal objects to the v1 scheme
var Codec = runtime.CodecFor(api.Scheme, "v1")

func init() {
	api.Scheme.AddKnownTypes("v1",
		&Policy{},
	)
}

func (*Policy) IsAnAPIObject() {}
Example #15
0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

import (
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

// Codec is the identity codec for this package - it can only convert itself
// to itself.
var Codec = runtime.CodecFor(Scheme, "")

// EmbeddedObject implements a Codec specific version of an
// embedded object.
type EmbeddedObject struct {
	runtime.Object
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
	obj, err := runtime.CodecUnmarshalJSON(Codec, b)
	a.Object = obj
	return err
}

// MarshalJSON implements the json.Marshaler interface.
func init() {
	scheme = runtime.NewScheme()
	scheme.AddKnownTypes("", &TestResource{})
	scheme.AddKnownTypes("v1beta1", &TestResource{})
	codec = runtime.CodecFor(scheme, "v1beta1")
}
Example #17
0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta3

import (
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

// Codec encodes internal objects to the v1beta3 scheme
var Codec = runtime.CodecFor(api.Scheme, "v1beta3")

func init() {
	api.Scheme.AddKnownTypes("v1beta3",
		&Pod{},
		&PodList{},
		&PodStatusResult{},
		&PodTemplate{},
		&PodTemplateList{},
		&ReplicationController{},
		&ReplicationControllerList{},
		&Service{},
		&ServiceList{},
		&Endpoints{},
		&EndpointsList{},
		&Node{},
Example #18
0
	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/deny"

	"github.com/emicklei/go-restful"
)

func convert(obj runtime.Object) (runtime.Object, error) {
	return obj, nil
}

// This creates a fake API version, similar to api/latest.go
const testVersion = "version"

var versions = []string{testVersion}
var codec = runtime.CodecFor(api.Scheme, testVersion)
var accessor = meta.NewAccessor()
var versioner runtime.ResourceVersioner = accessor
var selfLinker runtime.SelfLinker = accessor
var mapper, namespaceMapper, legacyNamespaceMapper meta.RESTMapper // The mappers with namespace and with legacy namespace scopes.
var admissionControl admission.Interface
var requestContextMapper api.RequestContextMapper

func interfacesFor(version string) (*meta.VersionInterfaces, error) {
	switch version {
	case testVersion:
		return &meta.VersionInterfaces{
			Codec:            codec,
			ObjectConvertor:  api.Scheme,
			MetadataAccessor: accessor,
		}, nil
Example #19
0
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
// Because api.List is part of the Kube API, resource.Builder has to perform a conversion on
// api.Scheme, which may not have access to all objects, and not all objects are at the same
// internal versioning scheme. This test verifies that two isolated schemes (Test, and api.Scheme)
// can be conjoined into a single output object.
//
// The expected behavior of the `kubectl get` command is:
// 1. objects using unrecognized schemes will always be returned using that scheme/version, "unlikelyversion" in this test;
// 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, latest.Version in this test;
// 3a. if the specified output-version is a recognized, valid Scheme, in which the requested object (replicationcontroller) can be represented, then the object should be returned using that version;
// 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, latest.Version in this test.
func TestGetUnknownSchemaObjectListGeneric(t *testing.T) {
	testCases := map[string]struct {
		outputVersion   string
		listVersion     string
		testtypeVersion string
		rcVersion       string
	}{
		"handles specific version": {
			outputVersion:   latest.Version,
			listVersion:     latest.Version,
			testtypeVersion: "unlikelyversion",
			rcVersion:       latest.Version,
		},
		"handles second specific version": {
			outputVersion:   "unlikelyversion",
			listVersion:     latest.Version,
			testtypeVersion: "unlikelyversion",
			rcVersion:       latest.Version, // see expected behavior 3b
		},
		"handles common version": {
			outputVersion:   testapi.Version(),
			listVersion:     testapi.Version(),
			testtypeVersion: "unlikelyversion",
			rcVersion:       testapi.Version(),
		},
	}
	for k, test := range testCases {
		apiCodec := runtime.CodecFor(api.Scheme, testapi.Version())
		regularClient := &client.FakeRESTClient{
			Codec: apiCodec,
			Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
				return &http.Response{StatusCode: 200, Body: objBody(apiCodec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})}, nil
			}),
		}

		f, tf, codec := NewMixedFactory(regularClient)
		tf.Printer = &testPrinter{}
		tf.Client = &client.FakeRESTClient{
			Codec: codec,
			Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
				return &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})}, nil
			}),
		}
		tf.Namespace = "test"
		tf.ClientConfig = &client.Config{Version: latest.Version}
		buf := bytes.NewBuffer([]byte{})
		cmd := NewCmdGet(f, buf)
		cmd.SetOutput(buf)
		cmd.Flags().Set("output", "json")
		cmd.Flags().Set("output-version", test.outputVersion)
		err := RunGet(f, buf, cmd, []string{"type/foo", "replicationcontrollers/foo"})
		if err != nil {
			t.Errorf("%s: unexpected error: %v", k, err)
			continue
		}
		out := make(map[string]interface{})
		if err := encjson.Unmarshal(buf.Bytes(), &out); err != nil {
			t.Errorf("%s: unexpected error: %v\n%s", k, err, buf.String())
			continue
		}
		if out["apiVersion"] != test.listVersion {
			t.Errorf("%s: unexpected list: %#v", k, out)
		}
		arr := out["items"].([]interface{})
		if arr[0].(map[string]interface{})["apiVersion"] != test.testtypeVersion {
			t.Errorf("%s: unexpected list: %#v", k, out)
		}
		if arr[1].(map[string]interface{})["apiVersion"] != test.rcVersion {
			t.Errorf("%s: unexpected list: %#v", k, out)
		}
	}
}
Example #20
0
See the License for the specific language governing permissions and
limitations under the License.
*/

package runtime_test

import (
	"encoding/json"
	"reflect"
	"testing"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

var scheme = runtime.NewScheme()
var Codec = runtime.CodecFor(scheme, "v1test")

type EmbeddedTest struct {
	runtime.TypeMeta `yaml:",inline" json:",inline"`
	ID               string                 `yaml:"id,omitempty" json:"id,omitempty"`
	Object           runtime.EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"`
	EmptyObject      runtime.EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
}

type EmbeddedTestExternal struct {
	runtime.TypeMeta `yaml:",inline" json:",inline"`
	ID               string               `yaml:"id,omitempty" json:"id,omitempty"`
	Object           runtime.RawExtension `yaml:"object,omitempty" json:"object,omitempty"`
	EmptyObject      runtime.RawExtension `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
}
Example #21
0
func init() {
	// Use the first API version in the list of registered versions as the latest.
	Version = registered.RegisteredVersions[0]
	Codec = runtime.CodecFor(api.Scheme, Version)
	// Put the registered versions in Versions in reverse order.
	versions := registered.RegisteredVersions
	Versions = []string{}
	for i := len(versions) - 1; i >= 0; i-- {
		Versions = append(Versions, versions[i])
	}

	mapper := meta.NewDefaultRESTMapper(
		versions,
		func(version string) (*meta.VersionInterfaces, bool) {
			interfaces, err := InterfacesFor(version)
			if err != nil {
				return nil, false
			}
			return interfaces, true
		},
	)

	// versions that used mixed case URL formats
	versionMixedCase := map[string]bool{
		"v1beta1": true,
		"v1beta2": true,
	}

	// backwards compatibility, prior to v1beta3, we identified the namespace as a query parameter
	versionToNamespaceScope := map[string]meta.RESTScope{
		"v1beta1": meta.RESTScopeNamespaceLegacy,
		"v1beta2": meta.RESTScopeNamespaceLegacy,
		"v1beta3": meta.RESTScopeNamespace,
		"v1":      meta.RESTScopeNamespace,
	}

	// the list of kinds that are scoped at the root of the api hierarchy
	// if a kind is not enumerated here, it is assumed to have a namespace scope
	kindToRootScope := map[string]bool{
		"Node":             true,
		"Minion":           true,
		"Namespace":        true,
		"PersistentVolume": true,
	}

	// setup aliases for groups of resources
	mapper.AddResourceAlias("all", userResources...)

	// these kinds should be excluded from the list of resources
	ignoredKinds := util.NewStringSet(
		"ListOptions",
		"DeleteOptions",
		"Status",
		"ContainerManifest",
		"PodLogOptions",
		"PodExecOptions",
		"PodProxyOptions")

	// enumerate all supported versions, get the kinds, and register with the mapper how to address our resources.
	for _, version := range versions {
		for kind := range api.Scheme.KnownTypes(version) {
			if ignoredKinds.Has(kind) {
				continue
			}
			mixedCase, found := versionMixedCase[version]
			if !found {
				mixedCase = false
			}
			scope := versionToNamespaceScope[version]
			_, found = kindToRootScope[kind]
			if found {
				scope = meta.RESTScopeRoot
			}
			mapper.Add(scope, kind, version, mixedCase)
		}
	}
	RESTMapper = mapper
}