Merge pull request #20818 from deads2k/remove-mixed-case

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-02-09 05:06:45 -08:00
commit b98d9a21a1
10 changed files with 63 additions and 93 deletions

View File

@ -53,7 +53,7 @@ func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, inter
if rootScoped.Has(kind) { if rootScoped.Has(kind) {
scope = meta.RESTScopeRoot scope = meta.RESTScopeRoot
} }
mapper.Add(gvk, scope, false) mapper.Add(gvk, scope)
} }
} }
return mapper return mapper

View File

@ -117,57 +117,50 @@ func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f Ver
} }
} }
func (m *DefaultRESTMapper) Add(kind unversioned.GroupVersionKind, scope RESTScope, mixedCase bool) { func (m *DefaultRESTMapper) Add(kind unversioned.GroupVersionKind, scope RESTScope) {
plural, singular := KindToResource(kind, mixedCase) plural, singular := KindToResource(kind)
lowerPlural := plural.GroupVersion().WithResource(strings.ToLower(plural.Resource))
lowerSingular := singular.GroupVersion().WithResource(strings.ToLower(singular.Resource))
m.singularToPlural[singular] = plural m.singularToPlural[singular] = plural
m.pluralToSingular[plural] = singular m.pluralToSingular[plural] = singular
m.singularToPlural[lowerSingular] = lowerPlural
m.pluralToSingular[lowerPlural] = lowerSingular
if _, mixedCaseExists := m.resourceToKind[plural]; !mixedCaseExists { m.resourceToKind[singular] = kind
m.resourceToKind[plural] = kind m.resourceToKind[plural] = kind
m.resourceToKind[singular] = kind
}
if _, lowerCaseExists := m.resourceToKind[lowerPlural]; !lowerCaseExists && (lowerPlural != plural) {
m.resourceToKind[lowerPlural] = kind
m.resourceToKind[lowerSingular] = kind
}
m.kindToPluralResource[kind] = plural m.kindToPluralResource[kind] = plural
m.kindToScope[kind] = scope m.kindToScope[kind] = scope
} }
// unpluralizedSuffixes is a list of resource suffixes that are the same plural and singular
// This is only is only necessary because some bits of code are lazy and don't actually use the RESTMapper like they should.
// TODO eliminate this so that different callers can correctly map to resources. This probably means updating all
// callers to use the RESTMapper they mean.
var unpluralizedSuffixes = []string{
"endpoints",
}
// KindToResource converts Kind to a resource name. // KindToResource converts Kind to a resource name.
func KindToResource(kind unversioned.GroupVersionKind, mixedCase bool) (plural, singular unversioned.GroupVersionResource) { func KindToResource(kind unversioned.GroupVersionKind) ( /*plural*/ unversioned.GroupVersionResource /*singular*/, unversioned.GroupVersionResource) {
kindName := kind.Kind kindName := kind.Kind
if len(kindName) == 0 { if len(kindName) == 0 {
return return unversioned.GroupVersionResource{}, unversioned.GroupVersionResource{}
}
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 := strings.ToLower(kindName)
singular := kind.GroupVersion().WithResource(singularName)
singularName := singular.Resource for _, skip := range unpluralizedSuffixes {
if strings.HasSuffix(singularName, "endpoints") { if strings.HasSuffix(singularName, skip) {
plural = singular return singular, 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
switch string(singularName[len(singularName)-1]) {
case "s":
return kind.GroupVersion().WithResource(singularName + "es"), singular
case "y":
return kind.GroupVersion().WithResource(strings.TrimSuffix(singularName, "y") + "ies"), singular
}
return kind.GroupVersion().WithResource(singularName + "s"), singular
} }
// ResourceSingularizer implements RESTMapper // ResourceSingularizer implements RESTMapper

View File

@ -62,7 +62,6 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
Resource unversioned.GroupVersionResource Resource unversioned.GroupVersionResource
GroupVersionToRegister unversioned.GroupVersion GroupVersionToRegister unversioned.GroupVersion
ExpectedGVK unversioned.GroupVersionKind ExpectedGVK unversioned.GroupVersionKind
MixedCase bool
Err bool Err bool
}{ }{
{Resource: unversioned.GroupVersionResource{Resource: "internalobjec"}, Err: true}, {Resource: unversioned.GroupVersionResource{Resource: "internalobjec"}, Err: true},
@ -70,17 +69,11 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
{Resource: unversioned.GroupVersionResource{Resource: "internalobject"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")}, {Resource: unversioned.GroupVersionResource{Resource: "internalobject"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
{Resource: unversioned.GroupVersionResource{Resource: "internalobjects"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")}, {Resource: unversioned.GroupVersionResource{Resource: "internalobjects"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
{Resource: unversioned.GroupVersionResource{Resource: "internalobject"}, MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
{Resource: unversioned.GroupVersionResource{Resource: "internalobjects"}, MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
{Resource: unversioned.GroupVersionResource{Resource: "internalObject"}, MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
{Resource: unversioned.GroupVersionResource{Resource: "internalObjects"}, MixedCase: true, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
} }
for i, testCase := range testCases { for i, testCase := range testCases {
mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion}, fakeInterfaces) mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion}, fakeInterfaces)
if len(testCase.ExpectedGVK.Kind) != 0 { if len(testCase.ExpectedGVK.Kind) != 0 {
mapper.Add(testCase.ExpectedGVK, RESTScopeNamespace, testCase.MixedCase) mapper.Add(testCase.ExpectedGVK, RESTScopeNamespace)
} }
actualGVK, err := mapper.KindFor(testCase.Resource) actualGVK, err := mapper.KindFor(testCase.Resource)
@ -112,7 +105,7 @@ func TestRESTMapperGroupForResource(t *testing.T) {
} }
for i, testCase := range testCases { for i, testCase := range testCases {
mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testCase.GroupVersionKind.GroupVersion()}, fakeInterfaces) mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testCase.GroupVersionKind.GroupVersion()}, fakeInterfaces)
mapper.Add(testCase.GroupVersionKind, RESTScopeNamespace, false) mapper.Add(testCase.GroupVersionKind, RESTScopeNamespace)
actualGVK, err := mapper.KindFor(testCase.Resource) actualGVK, err := mapper.KindFor(testCase.Resource)
if testCase.Err { if testCase.Err {
@ -202,7 +195,7 @@ func TestRESTMapperKindsFor(t *testing.T) {
tcName := testCase.Name tcName := testCase.Name
mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces) mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces)
for _, kind := range testCase.KindsToRegister { for _, kind := range testCase.KindsToRegister {
mapper.Add(kind, RESTScopeNamespace, false) mapper.Add(kind, RESTScopeNamespace)
} }
actualKinds, err := mapper.KindsFor(testCase.PartialResourceToRequest) actualKinds, err := mapper.KindsFor(testCase.PartialResourceToRequest)
@ -314,7 +307,7 @@ func TestRESTMapperResourcesFor(t *testing.T) {
tcName := testCase.Name tcName := testCase.Name
mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces) mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces)
for _, kind := range testCase.KindsToRegister { for _, kind := range testCase.KindsToRegister {
mapper.Add(kind, RESTScopeNamespace, false) mapper.Add(kind, RESTScopeNamespace)
} }
actualResources, err := mapper.ResourcesFor(testCase.PartialResourceToRequest) actualResources, err := mapper.ResourcesFor(testCase.PartialResourceToRequest)
@ -354,28 +347,23 @@ func TestRESTMapperResourcesFor(t *testing.T) {
func TestKindToResource(t *testing.T) { func TestKindToResource(t *testing.T) {
testCases := []struct { testCases := []struct {
Kind string Kind string
MixedCase bool
Plural, Singular string Plural, Singular string
}{ }{
{Kind: "Pod", MixedCase: true, Plural: "pods", Singular: "pod"}, {Kind: "Pod", Plural: "pods", Singular: "pod"},
{Kind: "Pod", MixedCase: true, Plural: "pods", Singular: "pod"},
{Kind: "Pod", MixedCase: false, Plural: "pods", Singular: "pod"},
{Kind: "ReplicationController", MixedCase: true, Plural: "replicationControllers", Singular: "replicationController"}, {Kind: "ReplicationController", Plural: "replicationcontrollers", Singular: "replicationcontroller"},
{Kind: "ReplicationController", MixedCase: true, Plural: "replicationControllers", Singular: "replicationController"},
{Kind: "ReplicationController", MixedCase: false, Plural: "replicationcontrollers", Singular: "replicationcontroller"},
// Add "ies" when ending with "y" // Add "ies" when ending with "y"
{Kind: "ImageRepository", MixedCase: true, Plural: "imageRepositories", Singular: "imageRepository"}, {Kind: "ImageRepository", Plural: "imagerepositories", Singular: "imagerepository"},
// Add "es" when ending with "s" // Add "es" when ending with "s"
{Kind: "miss", MixedCase: false, Plural: "misses", Singular: "miss"}, {Kind: "miss", Plural: "misses", Singular: "miss"},
// Add "s" otherwise // Add "s" otherwise
{Kind: "lowercase", MixedCase: false, Plural: "lowercases", Singular: "lowercase"}, {Kind: "lowercase", Plural: "lowercases", Singular: "lowercase"},
} }
for i, testCase := range testCases { for i, testCase := range testCases {
version := unversioned.GroupVersion{} version := unversioned.GroupVersion{}
plural, singular := KindToResource(version.WithKind(testCase.Kind), testCase.MixedCase) plural, singular := KindToResource(version.WithKind(testCase.Kind))
if singular != version.WithResource(testCase.Singular) || plural != version.WithResource(testCase.Plural) { if singular != version.WithResource(testCase.Singular) || plural != version.WithResource(testCase.Plural) {
t.Errorf("%d: unexpected plural and singular: %v %v", i, plural, singular) t.Errorf("%d: unexpected plural and singular: %v %v", i, plural, singular)
} }
@ -386,32 +374,24 @@ func TestRESTMapperResourceSingularizer(t *testing.T) {
testGroupVersion := unversioned.GroupVersion{Group: "tgroup", Version: "test"} testGroupVersion := unversioned.GroupVersion{Group: "tgroup", Version: "test"}
testCases := []struct { testCases := []struct {
Kind string Kind string
MixedCase bool Plural string
Plural string Singular string
Singular string
}{ }{
{Kind: "Pod", MixedCase: true, Plural: "pods", Singular: "pod"}, {Kind: "Pod", Plural: "pods", Singular: "pod"},
{Kind: "Pod", MixedCase: false, Plural: "pods", Singular: "pod"}, {Kind: "ReplicationController", Plural: "replicationcontrollers", Singular: "replicationcontroller"},
{Kind: "ImageRepository", Plural: "imagerepositories", Singular: "imagerepository"},
{Kind: "Status", Plural: "statuses", Singular: "status"},
{Kind: "ReplicationController", MixedCase: true, Plural: "replicationControllers", Singular: "replicationController"}, {Kind: "lowercase", Plural: "lowercases", Singular: "lowercase"},
{Kind: "ReplicationController", MixedCase: false, Plural: "replicationcontrollers", Singular: "replicationcontroller"},
{Kind: "ImageRepository", MixedCase: true, Plural: "imageRepositories", Singular: "imageRepository"},
{Kind: "ImageRepository", MixedCase: false, Plural: "imagerepositories", Singular: "imagerepository"},
{Kind: "Status", MixedCase: true, Plural: "statuses", Singular: "status"},
{Kind: "Status", MixedCase: false, Plural: "statuses", Singular: "status"},
{Kind: "lowercase", MixedCase: false, Plural: "lowercases", Singular: "lowercase"},
// TODO this test is broken. This updates to reflect actual behavior. Kinds are expected to be singular // TODO this test is broken. This updates to reflect actual behavior. Kinds are expected to be singular
// old (incorrect), coment: Don't add extra s if the original object is already plural // old (incorrect), coment: Don't add extra s if the original object is already plural
{Kind: "lowercases", MixedCase: false, Plural: "lowercaseses", Singular: "lowercases"}, {Kind: "lowercases", Plural: "lowercaseses", Singular: "lowercases"},
} }
for i, testCase := range testCases { for i, testCase := range testCases {
mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion}, fakeInterfaces) mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion}, fakeInterfaces)
// create singular/plural mapping // create singular/plural mapping
mapper.Add(testGroupVersion.WithKind(testCase.Kind), RESTScopeNamespace, testCase.MixedCase) mapper.Add(testGroupVersion.WithKind(testCase.Kind), RESTScopeNamespace)
singular, err := mapper.ResourceSingularizer(testCase.Plural) singular, err := mapper.ResourceSingularizer(testCase.Plural)
if err != nil { if err != nil {
@ -431,7 +411,6 @@ func TestRESTMapperRESTMapping(t *testing.T) {
testCases := []struct { testCases := []struct {
Kind string Kind string
APIGroupVersions []unversioned.GroupVersion APIGroupVersions []unversioned.GroupVersion
MixedCase bool
DefaultVersions []unversioned.GroupVersion DefaultVersions []unversioned.GroupVersion
Resource string Resource string
@ -451,13 +430,12 @@ func TestRESTMapperRESTMapping(t *testing.T) {
{DefaultVersions: []unversioned.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []unversioned.GroupVersion{}, Resource: "internalobjects", ExpectedGroupVersion: &unversioned.GroupVersion{Group: testGroup, Version: "test"}}, {DefaultVersions: []unversioned.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []unversioned.GroupVersion{}, Resource: "internalobjects", ExpectedGroupVersion: &unversioned.GroupVersion{Group: testGroup, Version: "test"}},
{DefaultVersions: []unversioned.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []unversioned.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"}, {DefaultVersions: []unversioned.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []unversioned.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"},
{DefaultVersions: []unversioned.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []unversioned.GroupVersion{{Group: testGroup, Version: "test"}}, MixedCase: true, Resource: "internalObjects"},
// TODO: add test for a resource that exists in one version but not another // TODO: add test for a resource that exists in one version but not another
} }
for i, testCase := range testCases { for i, testCase := range testCases {
mapper := NewDefaultRESTMapper(testCase.DefaultVersions, fakeInterfaces) mapper := NewDefaultRESTMapper(testCase.DefaultVersions, fakeInterfaces)
mapper.Add(internalGroupVersion.WithKind("InternalObject"), RESTScopeNamespace, testCase.MixedCase) mapper.Add(internalGroupVersion.WithKind("InternalObject"), RESTScopeNamespace)
preferredVersions := []string{} preferredVersions := []string{}
for _, gv := range testCase.APIGroupVersions { for _, gv := range testCase.APIGroupVersions {
@ -500,8 +478,8 @@ func TestRESTMapperRESTMappingSelectsVersion(t *testing.T) {
otherObjectGK := unversioned.GroupKind{Group: "tgroup", Kind: "OtherObject"} otherObjectGK := unversioned.GroupKind{Group: "tgroup", Kind: "OtherObject"}
mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, fakeInterfaces) mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, fakeInterfaces)
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace, false) mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
mapper.Add(expectedGroupVersion2.WithKind("OtherObject"), RESTScopeNamespace, false) mapper.Add(expectedGroupVersion2.WithKind("OtherObject"), RESTScopeNamespace)
// pick default matching object kind based on search order // pick default matching object kind based on search order
mapping, err := mapper.RESTMapping(otherObjectGK) mapping, err := mapper.RESTMapping(otherObjectGK)
@ -557,7 +535,7 @@ func TestRESTMapperReportsErrorOnBadVersion(t *testing.T) {
internalObjectGK := unversioned.GroupKind{Group: "tgroup", Kind: "InternalObject"} internalObjectGK := unversioned.GroupKind{Group: "tgroup", Kind: "InternalObject"}
mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, unmatchedVersionInterfaces) mapper := NewDefaultRESTMapper([]unversioned.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, unmatchedVersionInterfaces)
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace, false) mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
_, err := mapper.RESTMapping(internalObjectGK, expectedGroupVersion1.Version) _, err := mapper.RESTMapping(internalObjectGK, expectedGroupVersion1.Version)
if err == nil { if err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")

View File

@ -179,9 +179,9 @@ func init() {
gvk := gv.WithKind(kind) gvk := gv.WithKind(kind)
root := bool(kind == "SimpleRoot") root := bool(kind == "SimpleRoot")
if root { if root {
nsMapper.Add(gvk, meta.RESTScopeRoot, false) nsMapper.Add(gvk, meta.RESTScopeRoot)
} else { } else {
nsMapper.Add(gvk, meta.RESTScopeNamespace, false) nsMapper.Add(gvk, meta.RESTScopeNamespace)
} }
} }
} }

View File

@ -34,7 +34,7 @@ func (c *scales) Get(kind string, name string) (result *extensions.Scale, err er
// TODO this method needs to take a proper unambiguous kind // TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind} fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind}
resource, _ := meta.KindToResource(fullyQualifiedKind, false) resource, _ := meta.KindToResource(fullyQualifiedKind)
err = c.client.Get(). err = c.client.Get().
Namespace(c.ns). Namespace(c.ns).
@ -51,7 +51,7 @@ func (c *scales) Update(kind string, scale *extensions.Scale) (result *extension
// TODO this method needs to take a proper unambiguous kind // TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind} fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind}
resource, _ := meta.KindToResource(fullyQualifiedKind, false) resource, _ := meta.KindToResource(fullyQualifiedKind)
err = c.client.Put(). err = c.client.Put().
Namespace(scale.Namespace). Namespace(scale.Namespace).

View File

@ -52,7 +52,7 @@ func (c *scales) Get(kind string, name string) (result *extensions.Scale, err er
// TODO this method needs to take a proper unambiguous kind // TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind} fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind}
resource, _ := meta.KindToResource(fullyQualifiedKind, false) resource, _ := meta.KindToResource(fullyQualifiedKind)
err = c.client.Get().Namespace(c.ns).Resource(resource.Resource).Name(name).SubResource("scale").Do().Into(result) err = c.client.Get().Namespace(c.ns).Resource(resource.Resource).Name(name).SubResource("scale").Do().Into(result)
return return
@ -63,7 +63,7 @@ func (c *scales) Update(kind string, scale *extensions.Scale) (result *extension
// TODO this method needs to take a proper unambiguous kind // TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind} fullyQualifiedKind := unversioned.GroupVersionKind{Kind: kind}
resource, _ := meta.KindToResource(fullyQualifiedKind, false) resource, _ := meta.KindToResource(fullyQualifiedKind)
err = c.client.Put(). err = c.client.Put().
Namespace(scale.Namespace). Namespace(scale.Namespace).

View File

@ -124,9 +124,8 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
for kind := range scheme.KnownTypes(gv) { for kind := range scheme.KnownTypes(gv) {
gvk := gv.WithKind(kind) gvk := gv.WithKind(kind)
mixedCase := false
scope := meta.RESTScopeNamespace scope := meta.RESTScopeNamespace
mapper.Add(gvk, scope, mixedCase) mapper.Add(gvk, scope)
} }
} }

View File

@ -365,7 +365,7 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
if err != nil { if err != nil {
return err return err
} }
_, res := meta.KindToResource(kind, false) _, res := meta.KindToResource(kind)
cmdutil.PrintSuccess(mapper, false, out, res.Resource, oldName, message) cmdutil.PrintSuccess(mapper, false, out, res.Resource, oldName, message)
return nil return nil
} }

View File

@ -234,7 +234,7 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
if gvk != nil { if gvk != nil {
// TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper // TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper
_, resource := meta.KindToResource(*gvk, false) _, resource := meta.KindToResource(*gvk)
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name) fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
} else { } else {

View File

@ -42,7 +42,7 @@ type thirdPartyResourceDataMapper struct {
var _ meta.RESTMapper = &thirdPartyResourceDataMapper{} var _ meta.RESTMapper = &thirdPartyResourceDataMapper{}
func (t *thirdPartyResourceDataMapper) getResource() unversioned.GroupVersionResource { func (t *thirdPartyResourceDataMapper) getResource() unversioned.GroupVersionResource {
plural, _ := meta.KindToResource(t.getKind(), false) plural, _ := meta.KindToResource(t.getKind())
return plural return plural
} }