// KindToResource converts Kind to a resource name. func KindToResource(kind unversioned.GroupVersionKind, mixedCase bool) (plural, singular unversioned.GroupVersionResource) { kindName := kind.Kind if len(kindName) == 0 { return } if mixedCase { // Legacy support for mixed case names singular = kind.GroupVersion().WithResource(strings.ToLower(kindName[:1]) + kindName[1:]) } else { singular = kind.GroupVersion().WithResource(strings.ToLower(kindName)) } singularName := singular.Resource if strings.HasSuffix(singularName, "endpoints") { plural = singular } else { switch string(singularName[len(singularName)-1]) { case "s": plural = kind.GroupVersion().WithResource(singularName + "es") case "y": plural = kind.GroupVersion().WithResource(strings.TrimSuffix(singularName, "y") + "ies") default: plural = kind.GroupVersion().WithResource(singularName + "s") } } return }
// Recognizes returns true for any version or kind that is specified (internal // versions are specifically excluded). func (unstructuredJSONScheme) Recognizes(gvk unversioned.GroupVersionKind) bool { return !gvk.GroupVersion().IsEmpty() && len(gvk.Kind) > 0 }
// RESTMapping returns a struct representing the resource path and conversion interfaces a // RESTClient should use to operate on the provided group/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 // version should be used to access the named group/kind. func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) { // Pick an appropriate version var gvk *unversioned.GroupVersionKind hadVersion := false for _, version := range versions { if len(version) == 0 { continue } currGVK := gk.WithVersion(version) hadVersion = true if _, ok := m.kindToPluralResource[currGVK]; ok { gvk = &currGVK break } } // Use the default preferred versions if !hadVersion && (gvk == nil) { for _, gv := range m.defaultGroupVersions { if gv.Group != gk.Group { continue } currGVK := gk.WithVersion(gv.Version) if _, ok := m.kindToPluralResource[currGVK]; ok { gvk = &currGVK break } } } if gvk == nil { return nil, fmt.Errorf("no kind named %q is registered in versions %q", gk, versions) } // Ensure we have a REST mapping resource, ok := m.kindToPluralResource[*gvk] if !ok { found := []unversioned.GroupVersion{} for _, gv := range m.defaultGroupVersions { if _, ok := m.kindToPluralResource[*gvk]; ok { found = append(found, gv) } } if len(found) > 0 { return nil, fmt.Errorf("object with kind %q exists in versions %v, not %v", gvk.Kind, found, gvk.GroupVersion().String()) } return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported object", gvk.GroupVersion().String(), gvk.Kind) } // Ensure we have a REST scope scope, ok := m.kindToScope[*gvk] 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()) if err != nil { return nil, fmt.Errorf("the provided version %q has no relevant versions", gvk.GroupVersion().String()) } retVal := &RESTMapping{ Resource: resource.Resource, GroupVersionKind: *gvk, Scope: scope, Codec: interfaces.Codec, ObjectConvertor: interfaces.ObjectConvertor, MetadataAccessor: interfaces.MetadataAccessor, } return retVal, nil }