Beispiel #1
0
func TestRESTMapperVersionAndKindForResource(t *testing.T) {
	testGroup := "test.group"
	testVersion := "test"
	testGroupVersion := unversioned.GroupVersion{Group: testGroup, Version: testVersion}

	testCases := []struct {
		Resource               string
		GroupVersionToRegister unversioned.GroupVersion
		ExpectedGVK            unversioned.GroupVersionKind
		MixedCase              bool
		Err                    bool
	}{
		{Resource: "internalobjec", Err: true},
		{Resource: "internalObjec", Err: true},

		{Resource: "internalobject", ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
		{Resource: "internalobjects", ExpectedGVK: testGroupVersion.WithKind("InternalObject")},

		{Resource: "internalobject", MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
		{Resource: "internalobjects", MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},

		{Resource: "internalObject", MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
		{Resource: "internalObjects", MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
	}
	for i, testCase := range testCases {
		mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion}, fakeInterfaces)
		if len(testCase.ExpectedGVK.Kind) != 0 {
			mapper.Add(testCase.ExpectedGVK, RESTScopeNamespace, testCase.MixedCase)
		}
		v, k, err := mapper.VersionAndKindForResource(testCase.Resource)

		hasErr := err != nil
		if hasErr != testCase.Err {
			t.Errorf("%d: unexpected error behavior %t: %v", i, testCase.Err, err)
			continue
		}
		if err != nil {
			continue
		}

		actualGV, err := unversioned.ParseGroupVersion(v)
		if err != nil {
			t.Errorf("%d: unexpected error: %v", i, err)
			continue
		}
		actualGVK := unversioned.NewGroupVersionKind(actualGV, k)

		if actualGVK != testCase.ExpectedGVK {
			t.Errorf("%d: unexpected version and kind: e=%s a=%s", i, testCase.ExpectedGVK, actualGVK)
		}
	}
}
// RESTMapping returns a struct representing the resource path and conversion interfaces a
// RESTClient should use to operate on the provided kind in order of versions. If a version search
// order is not provided, the search order provided to DefaultRESTMapper will be used to resolve which
// APIVersion should be used to access the named kind.
// TODO version here in this RESTMapper means just APIVersion, but the RESTMapper API is intended to handle multiple groups
// So this API is broken.  The RESTMapper test made it clear that versions here were API versions, but the code tries to use
// them with group/version tuples.
// TODO this should probably become RESTMapping(GroupKind, versions ...string)
func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTMapping, error) {
	// Pick an appropriate version
	var groupVersion *unversioned.GroupVersion
	hadVersion := false
	for _, v := range versions {
		if len(v) == 0 {
			continue
		}
		currGroupVersion, err := unversioned.ParseGroupVersion(v)
		if err != nil {
			return nil, err
		}

		hadVersion = true
		if _, ok := m.reverse[typeMeta{APIVersion: currGroupVersion.String(), Kind: kind}]; ok {
			groupVersion = &currGroupVersion
			break
		}
	}
	// Use the default preferred versions
	if !hadVersion && (groupVersion == nil) {
		for _, currGroupVersion := range m.groupVersions {
			if _, ok := m.reverse[typeMeta{APIVersion: currGroupVersion.String(), Kind: kind}]; ok {
				groupVersion = &currGroupVersion
				break
			}
		}
	}
	if groupVersion == nil {
		return nil, fmt.Errorf("no kind named %q is registered in versions %q", kind, versions)
	}

	gvk := unversioned.NewGroupVersionKind(*groupVersion, kind)

	// Ensure we have a REST mapping
	resource, ok := m.reverse[typeMeta{APIVersion: gvk.GroupVersion().String(), Kind: gvk.Kind}]
	if !ok {
		found := []unversioned.GroupVersion{}
		for _, gv := range m.groupVersions {
			if _, ok := m.reverse[typeMeta{APIVersion: gv.String(), Kind: kind}]; ok {
				found = append(found, gv)
			}
		}
		if len(found) > 0 {
			return nil, fmt.Errorf("object with kind %q exists in versions %v, not %v", kind, found, *groupVersion)
		}
		return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported object", groupVersion, kind)
	}

	// Ensure we have a REST scope
	scope, ok := m.scopes[typeMeta{APIVersion: gvk.GroupVersion().String(), Kind: gvk.Kind}]
	if !ok {
		return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion().String(), gvk.Kind)
	}

	interfaces, err := m.interfacesFunc(gvk.GroupVersion().String())
	if err != nil {
		return nil, fmt.Errorf("the provided version %q has no relevant versions", gvk.GroupVersion().String())
	}

	retVal := &RESTMapping{
		Resource:         resource,
		GroupVersionKind: gvk,
		Scope:            scope,

		Codec:            interfaces.Codec,
		ObjectConvertor:  interfaces.ObjectConvertor,
		MetadataAccessor: interfaces.MetadataAccessor,
	}

	return retVal, nil
}