func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) { scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(InternalGV.WithKind("Type"), &InternalType{}) scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("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(ValidVersionGV.WithKind("Type"), &ExternalType2{}) codecs := serializer.NewCodecFactory(scheme) codec := codecs.LegacyCodec(UnlikelyGV) mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{UnlikelyGV, ValidVersionGV}, func(version schema.GroupVersion) (*meta.VersionInterfaces, error) { return &meta.VersionInterfaces{ ObjectConvertor: scheme, MetadataAccessor: meta.NewAccessor(), }, versionErrIfFalse(version == ValidVersionGV || version == UnlikelyGV) }) for _, gv := range []schema.GroupVersion{UnlikelyGV, ValidVersionGV} { for kind := range scheme.KnownTypes(gv) { gvk := gv.WithKind(kind) scope := meta.RESTScopeNamespace mapper.Add(gvk, scope) } } return scheme, mapper, codec }
// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information. func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) { rm := meta.NewDefaultRESTMapper(nil, versionFunc) for _, resourceList := range resources { gv, err := schema.ParseGroupVersion(resourceList.GroupVersion) if err != nil { return nil, err } for _, resource := range resourceList.APIResources { gvk := gv.WithKind(resource.Kind) scope := meta.RESTScopeRoot if resource.Namespaced { scope = meta.RESTScopeNamespace } rm.Add(gvk, scope) } } return rm, nil }
// Instantiates a DefaultRESTMapper based on types registered in the given scheme. func NewDefaultRESTMapperFromScheme(defaultGroupVersions []schema.GroupVersion, interfacesFunc meta.VersionInterfacesFunc, importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *meta.DefaultRESTMapper { mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc) // enumerate all supported versions, get the kinds, and register with the mapper how to address // our resources. for _, gv := range defaultGroupVersions { for kind, oType := range scheme.KnownTypes(gv) { gvk := gv.WithKind(kind) // TODO: Remove import path check. // We check the import path because we currently stuff both "api" and "extensions" objects // into the same group within Scheme since Scheme has no notion of groups yet. if !strings.Contains(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) { continue } scope := meta.RESTScopeNamespace if rootScoped.Has(kind) { scope = meta.RESTScopeRoot } mapper.Add(gvk, scope) } } return mapper }
// NewRESTMapper returns a PriorityRESTMapper based on the discovered // groups and resources passed in. func NewRESTMapper(groupResources []*APIGroupResources, versionInterfaces meta.VersionInterfacesFunc) meta.RESTMapper { unionMapper := meta.MultiRESTMapper{} var groupPriority []string var resourcePriority []schema.GroupVersionResource var kindPriority []schema.GroupVersionKind for _, group := range groupResources { groupPriority = append(groupPriority, group.Group.Name) if len(group.Group.PreferredVersion.Version) != 0 { preferred := group.Group.PreferredVersion.Version if _, ok := group.VersionedResources[preferred]; ok { resourcePriority = append(resourcePriority, schema.GroupVersionResource{ Group: group.Group.Name, Version: group.Group.PreferredVersion.Version, Resource: meta.AnyResource, }) kindPriority = append(kindPriority, schema.GroupVersionKind{ Group: group.Group.Name, Version: group.Group.PreferredVersion.Version, Kind: meta.AnyKind, }) } } for _, discoveryVersion := range group.Group.Versions { resources, ok := group.VersionedResources[discoveryVersion.Version] if !ok { continue } gv := schema.GroupVersion{Group: group.Group.Name, Version: discoveryVersion.Version} versionMapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{gv}, versionInterfaces) for _, resource := range resources { scope := meta.RESTScopeNamespace if !resource.Namespaced { scope = meta.RESTScopeRoot } versionMapper.Add(gv.WithKind(resource.Kind), scope) // TODO only do this if it supports listing versionMapper.Add(gv.WithKind(resource.Kind+"List"), scope) } // TODO why is this type not in discovery (at least for "v1") versionMapper.Add(gv.WithKind("List"), meta.RESTScopeRoot) unionMapper = append(unionMapper, versionMapper) } } for _, group := range groupPriority { resourcePriority = append(resourcePriority, schema.GroupVersionResource{ Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource, }) kindPriority = append(kindPriority, schema.GroupVersionKind{ Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind, }) } return meta.PriorityRESTMapper{ Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority, } }