Merge pull request #1008 from Liujingfang1/resid

add ItemId type
This commit is contained in:
Kubernetes Prow Robot
2019-04-23 17:30:00 -07:00
committed by GitHub
5 changed files with 391 additions and 168 deletions

View File

@@ -35,6 +35,29 @@ func FromKind(k string) Gvk {
} }
} }
// FromString makes a Gvk with a string,
// which is constructed by String() function
func FromString(s string) Gvk {
values := strings.Split(s, separator)
g := values[0]
if g == noGroup {
g = ""
}
v := values[1]
if v == noVersion {
v = ""
}
k := values[2]
if k == noKind {
k = ""
}
return Gvk{
Group: g,
Version: v,
Kind: k,
}
}
// Values that are brief but meaningful in logs. // Values that are brief but meaningful in logs.
const ( const (
noGroup = "~G" noGroup = "~G"

81
pkg/resid/itemid.go Normal file
View File

@@ -0,0 +1,81 @@
/*
Copyright 2019 The Kubernetes Authors.
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 resid
import (
"strings"
"sigs.k8s.io/kustomize/pkg/gvk"
)
// ItemId contains the group, version, kind, namespace
// and name of a resource
type ItemId struct {
// Gvk of the resource.
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
// Name of the resource before transformation.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Namespace the resource belongs to.
// An untransformed resource has no namespace.
// A fully transformed resource has the namespace
// from the top most overlay.
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
}
// String of ItemId based on GVK, name and namespace
func (i ItemId) String() string {
ns := i.Namespace
if ns == "" {
ns = noNamespace
}
nm := i.Name
if nm == "" {
nm = noName
}
return strings.Join(
[]string{i.Gvk.String(), ns, nm}, separator)
}
func New(g gvk.Gvk, ns, nm string) ItemId {
return ItemId{
Gvk: g,
Namespace: ns,
Name: nm,
}
}
func FromString(s string) ItemId {
values := strings.Split(s, separator)
g := gvk.FromString(values[0])
ns := values[1]
if ns == noNamespace {
ns = ""
}
nm := values[2]
if nm == noName {
nm = ""
}
return ItemId{
Gvk: g,
Namespace: ns,
Name: nm,
}
}

66
pkg/resid/itemid_test.go Normal file
View File

@@ -0,0 +1,66 @@
/*
Copyright 2019 The Kubernetes Authors.
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 resid
import (
"testing"
"sigs.k8s.io/kustomize/pkg/gvk"
)
var itemIds = []ItemId{
{
Namespace: "ns",
Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
Name: "nm",
},
{
Namespace: "ns",
Gvk: gvk.Gvk{Version: "v", Kind: "k"},
Name: "nm",
},
{
Namespace: "ns",
Gvk: gvk.Gvk{Kind: "k"},
Name: "nm",
},
{
Namespace: "ns",
Gvk: gvk.Gvk{},
Name: "nm",
},
{
Gvk: gvk.Gvk{},
Name: "nm",
},
{
Gvk: gvk.Gvk{},
Name: "nm",
},
{
Gvk: gvk.Gvk{},
},
}
func TestItemIds(t *testing.T) {
for _, item := range itemIds {
newItem := FromString(item.String())
if newItem != item {
t.Fatalf("Actual: %v, Expected: '%s'", newItem, item)
}
}
}

View File

@@ -24,12 +24,7 @@ import (
// ResId is an immutable identifier of a k8s resource object. // ResId is an immutable identifier of a k8s resource object.
type ResId struct { type ResId struct {
// Gvk of the resource. ItemId
gvKind gvk.Gvk
// name of the resource before transformation.
name string
// namePrefix of the resource. // namePrefix of the resource.
// An untransformed resource has no prefix. // An untransformed resource has no prefix.
// A fully transformed resource has an arbitrary // A fully transformed resource has an arbitrary
@@ -41,42 +36,36 @@ type ResId struct {
// A fully transformed resource has an arbitrary // A fully transformed resource has an arbitrary
// number of suffixes concatenated together. // number of suffixes concatenated together.
suffix string suffix string
// Namespace the resource belongs to.
// An untransformed resource has no namespace.
// A fully transformed resource has the namespace
// from the top most overlay.
namespace string
} }
// NewResIdWithPrefixSuffixNamespace creates new resource identifier with a prefix, suffix and a namespace // NewResIdWithPrefixSuffixNamespace creates new resource identifier with a prefix, suffix and a namespace
func NewResIdWithPrefixSuffixNamespace(k gvk.Gvk, n, p, s, ns string) ResId { func NewResIdWithPrefixSuffixNamespace(k gvk.Gvk, n, p, s, ns string) ResId {
return ResId{gvKind: k, name: n, prefix: p, suffix: s, namespace: ns} return ResId{ItemId: ItemId{Gvk: k, Name: n, Namespace: ns}, prefix: p, suffix: s}
} }
// NewResIdWithPrefixNamespace creates new resource identifier with a prefix and a namespace // NewResIdWithPrefixNamespace creates new resource identifier with a prefix and a namespace
func NewResIdWithPrefixNamespace(k gvk.Gvk, n, p, ns string) ResId { func NewResIdWithPrefixNamespace(k gvk.Gvk, n, p, ns string) ResId {
return ResId{gvKind: k, name: n, prefix: p, namespace: ns} return ResId{ItemId: ItemId{Gvk: k, Name: n, Namespace: ns}, prefix: p}
} }
// NewResIdWithSuffixNamespace creates new resource identifier with a suffix and a namespace // NewResIdWithSuffixNamespace creates new resource identifier with a suffix and a namespace
func NewResIdWithSuffixNamespace(k gvk.Gvk, n, s, ns string) ResId { func NewResIdWithSuffixNamespace(k gvk.Gvk, n, s, ns string) ResId {
return ResId{gvKind: k, name: n, suffix: s, namespace: ns} return ResId{ItemId: ItemId{Gvk: k, Name: n, Namespace: ns}, suffix: s}
} }
// NewResIdWithPrefixSuffix creates new resource identifier with a prefix and suffix // NewResIdWithPrefixSuffix creates new resource identifier with a prefix and suffix
func NewResIdWithPrefixSuffix(k gvk.Gvk, n, p, s string) ResId { func NewResIdWithPrefixSuffix(k gvk.Gvk, n, p, s string) ResId {
return ResId{gvKind: k, name: n, prefix: p, suffix: s} return ResId{ItemId: ItemId{Gvk: k, Name: n}, prefix: p, suffix: s}
} }
// NewResId creates new resource identifier // NewResId creates new resource identifier
func NewResId(k gvk.Gvk, n string) ResId { func NewResId(k gvk.Gvk, n string) ResId {
return ResId{gvKind: k, name: n} return ResId{ItemId: ItemId{Gvk: k, Name: n}}
} }
// NewResIdKindOnly creates new resource identifier // NewResIdKindOnly creates new resource identifier
func NewResIdKindOnly(k string, n string) ResId { func NewResIdKindOnly(k string, n string) ResId {
return ResId{gvKind: gvk.FromKind(k), name: n} return ResId{ItemId: ItemId{Gvk: gvk.FromKind(k), Name: n}}
} }
const ( const (
@@ -89,7 +78,7 @@ const (
// String of ResId based on GVK, name and prefix // String of ResId based on GVK, name and prefix
func (n ResId) String() string { func (n ResId) String() string {
ns := n.namespace ns := n.ItemId.Namespace
if ns == "" { if ns == "" {
ns = noNamespace ns = noNamespace
} }
@@ -97,7 +86,7 @@ func (n ResId) String() string {
if p == "" { if p == "" {
p = noPrefix p = noPrefix
} }
nm := n.name nm := n.ItemId.Name
if nm == "" { if nm == "" {
nm = noName nm = noName
} }
@@ -107,39 +96,39 @@ func (n ResId) String() string {
} }
return strings.Join( return strings.Join(
[]string{n.gvKind.String(), ns, p, nm, s}, separator) []string{n.ItemId.Gvk.String(), ns, p, nm, s}, separator)
} }
// GvknString of ResId based on GVK and name // GvknString of ResId based on GVK and name
func (n ResId) GvknString() string { func (n ResId) GvknString() string {
return n.gvKind.String() + separator + n.name return n.ItemId.Gvk.String() + separator + n.ItemId.Name
} }
// GvknEquals returns true if the other id matches // GvknEquals returns true if the other id matches
// Group/Version/Kind/name. // Group/Version/Kind/name.
func (n ResId) GvknEquals(id ResId) bool { func (n ResId) GvknEquals(id ResId) bool {
return n.name == id.name && n.gvKind.Equals(id.gvKind) return n.ItemId.Name == id.ItemId.Name && n.ItemId.Gvk.Equals(id.ItemId.Gvk)
} }
// NsGvknEquals returns true if the other id matches // NsGvknEquals returns true if the other id matches
// namespace/Group/Version/Kind/name. // namespace/Group/Version/Kind/name.
func (n ResId) NsGvknEquals(id ResId) bool { func (n ResId) NsGvknEquals(id ResId) bool {
return n.namespace == id.namespace && n.GvknEquals(id) return n.ItemId.Namespace == id.ItemId.Namespace && n.GvknEquals(id)
} }
// Gvk returns Group/Version/Kind of the resource. // Gvk returns Group/Version/Kind of the resource.
func (n ResId) Gvk() gvk.Gvk { func (n ResId) Gvk() gvk.Gvk {
return n.gvKind return n.ItemId.Gvk
} }
// Name returns resource name. // Name returns resource name.
func (n ResId) Name() string { func (n ResId) Name() string {
return n.name return n.ItemId.Name
} }
// Namespace returns resource namespace. // Namespace returns resource namespace.
func (n ResId) Namespace() string { func (n ResId) Namespace() string {
return n.namespace return n.ItemId.Namespace
} }
// CopyWithNewPrefixSuffix make a new copy from current ResId // CopyWithNewPrefixSuffix make a new copy from current ResId
@@ -158,7 +147,7 @@ func (n ResId) CopyWithNewPrefixSuffix(p, s string) ResId {
// CopyWithNewNamespace make a new copy from current ResId and set a new namespace // CopyWithNewNamespace make a new copy from current ResId and set a new namespace
func (n ResId) CopyWithNewNamespace(ns string) ResId { func (n ResId) CopyWithNewNamespace(ns string) ResId {
result := n result := n
result.namespace = ns result.ItemId.Namespace = ns
return result return result
} }

View File

@@ -12,48 +12,58 @@ var stringTests = []struct {
}{ }{
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"g_v_k|ns|p|nm|s", "g_v_k|ns|p|nm|s",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Version: "v", Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Version: "v", Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"~G_v_k|ns|p|nm|s", "~G_v_k|ns|p|nm|s",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"~G_~V_k|ns|p|nm|s", "~G_~V_k|ns|p|nm|s",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"~G_~V_~K|ns|p|nm|s", "~G_~V_~K|ns|p|nm|s",
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
name: "nm", Gvk: gvk.Gvk{},
Name: "nm",
},
prefix: "p", prefix: "p",
suffix: "s", suffix: "s",
}, },
@@ -61,22 +71,28 @@ var stringTests = []struct {
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
name: "nm", Gvk: gvk.Gvk{},
Name: "nm",
},
suffix: "s", suffix: "s",
}, },
"~G_~V_~K|~X|~P|nm|s", "~G_~V_~K|~X|~P|nm|s",
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
Gvk: gvk.Gvk{},
},
suffix: "s", suffix: "s",
}, },
"~G_~V_~K|~X|~P|~N|s", "~G_~V_~K|~X|~P|~N|s",
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
Gvk: gvk.Gvk{},
},
}, },
"~G_~V_~K|~X|~P|~N|~S", "~G_~V_~K|~X|~P|~N|~S",
}, },
@@ -100,48 +116,47 @@ var gvknStringTests = []struct {
}{ }{
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"g_v_k|nm", "g_v_k|nm",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Version: "v", Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Version: "v", Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"~G_v_k|nm", "~G_v_k|nm",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{Kind: "k"}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{Kind: "k"},
prefix: "p", Name: "nm",
suffix: "s", },
prefix: "p",
suffix: "s",
}, },
"~G_~V_k|nm", "~G_~V_k|nm",
}, },
{ {
ResId{ ResId{
namespace: "ns", ItemId: ItemId{
gvKind: gvk.Gvk{}, Namespace: "ns",
name: "nm", Gvk: gvk.Gvk{},
prefix: "p", Name: "nm",
suffix: "s", },
},
"~G_~V_~K|nm",
},
{
ResId{
gvKind: gvk.Gvk{},
name: "nm",
prefix: "p", prefix: "p",
suffix: "s", suffix: "s",
}, },
@@ -149,22 +164,39 @@ var gvknStringTests = []struct {
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
name: "nm", Gvk: gvk.Gvk{},
Name: "nm",
},
prefix: "p",
suffix: "s", suffix: "s",
}, },
"~G_~V_~K|nm", "~G_~V_~K|nm",
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
Gvk: gvk.Gvk{},
Name: "nm",
},
suffix: "s",
},
"~G_~V_~K|nm",
},
{
ResId{
ItemId: ItemId{
Gvk: gvk.Gvk{},
},
suffix: "s", suffix: "s",
}, },
"~G_~V_~K|", "~G_~V_~K|",
}, },
{ {
ResId{ ResId{
gvKind: gvk.Gvk{}, ItemId: ItemId{
Gvk: gvk.Gvk{},
},
}, },
"~G_~V_~K|", "~G_~V_~K|",
}, },
@@ -190,51 +222,42 @@ var GvknEqualsTest = []struct {
}{ }{
{ {
id1: ResId{ id1: ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "AA", Name: "nm",
suffix: "aa", },
prefix: "AA",
suffix: "aa",
}, },
id2: ResId{ id2: ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "BB", Name: "nm",
suffix: "bb", },
prefix: "BB",
suffix: "bb",
}, },
gVknResult: true, gVknResult: true,
nSgVknResult: true, nSgVknResult: true,
}, },
{ {
id1: ResId{ id1: ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "AA", Name: "nm",
suffix: "aa", },
prefix: "AA",
suffix: "aa",
}, },
id2: ResId{ id2: ResId{
namespace: "Z", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "Z",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "BB", Name: "nm",
suffix: "bb", },
},
gVknResult: true,
nSgVknResult: false,
},
{
id1: ResId{
namespace: "X",
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
name: "nm",
prefix: "AA",
suffix: "aa",
},
id2: ResId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
name: "nm",
prefix: "BB", prefix: "BB",
suffix: "bb", suffix: "bb",
}, },
@@ -243,52 +266,85 @@ var GvknEqualsTest = []struct {
}, },
{ {
id1: ResId{ id1: ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "AA", Name: "nm",
suffix: "aa", },
prefix: "AA",
suffix: "aa",
}, },
id2: ResId{ id2: ResId{
namespace: "Z", ItemId: ItemId{
gvKind: gvk.Gvk{Version: "v", Kind: "k"}, Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
name: "nm", Name: "nm",
prefix: "BB", },
suffix: "bb", prefix: "BB",
suffix: "bb",
}, },
gVknResult: true, gVknResult: true,
nSgVknResult: false, nSgVknResult: false,
}, },
{ {
id1: ResId{ id1: ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Version: "v", Kind: "k"},
prefix: "AA", Name: "nm",
suffix: "aa", },
prefix: "AA",
suffix: "aa",
}, },
id2: ResId{ id2: ResId{
namespace: "Z", ItemId: ItemId{
gvKind: gvk.Gvk{Kind: "k"}, Namespace: "Z",
name: "nm", Gvk: gvk.Gvk{Version: "v", Kind: "k"},
prefix: "BB", Name: "nm",
suffix: "bb", },
prefix: "BB",
suffix: "bb",
}, },
gVknResult: true, gVknResult: true,
nSgVknResult: false, nSgVknResult: false,
}, },
{ {
id1: ResId{ id1: ResId{
namespace: "X", ItemId: ItemId{
name: "nm", Namespace: "X",
prefix: "AA", Gvk: gvk.Gvk{Kind: "k"},
suffix: "aa", Name: "nm",
},
prefix: "AA",
suffix: "aa",
}, },
id2: ResId{ id2: ResId{
namespace: "Z", ItemId: ItemId{
name: "nm", Namespace: "Z",
prefix: "BB", Gvk: gvk.Gvk{Kind: "k"},
suffix: "bb", Name: "nm",
},
prefix: "BB",
suffix: "bb",
},
gVknResult: true,
nSgVknResult: false,
},
{
id1: ResId{
ItemId: ItemId{
Namespace: "X",
Name: "nm",
},
prefix: "AA",
suffix: "aa",
},
id2: ResId{
ItemId: ItemId{
Namespace: "Z",
Name: "nm",
},
prefix: "BB",
suffix: "bb",
}, },
gVknResult: true, gVknResult: true,
nSgVknResult: false, nSgVknResult: false,
@@ -310,19 +366,23 @@ func TestEquals(t *testing.T) {
func TestCopyWithNewPrefixSuffix(t *testing.T) { func TestCopyWithNewPrefixSuffix(t *testing.T) {
r1 := ResId{ r1 := ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "a", Name: "nm",
suffix: "b", },
prefix: "a",
suffix: "b",
} }
r2 := r1.CopyWithNewPrefixSuffix("p-", "-s") r2 := r1.CopyWithNewPrefixSuffix("p-", "-s")
expected := ResId{ expected := ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "p-a", Name: "nm",
suffix: "b-s", },
prefix: "p-a",
suffix: "b-s",
} }
if !r2.GvknEquals(expected) { if !r2.GvknEquals(expected) {
t.Fatalf("%v should equal %v", r2, expected) t.Fatalf("%v should equal %v", r2, expected)
@@ -331,19 +391,23 @@ func TestCopyWithNewPrefixSuffix(t *testing.T) {
func TestCopyWithNewNamespace(t *testing.T) { func TestCopyWithNewNamespace(t *testing.T) {
r1 := ResId{ r1 := ResId{
namespace: "X", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "X",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "a", Name: "nm",
suffix: "b", },
prefix: "a",
suffix: "b",
} }
r2 := r1.CopyWithNewNamespace("zzz") r2 := r1.CopyWithNewNamespace("zzz")
expected := ResId{ expected := ResId{
namespace: "zzz", ItemId: ItemId{
gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, Namespace: "zzz",
name: "nm", Gvk: gvk.Gvk{Group: "g", Version: "v", Kind: "k"},
prefix: "a", Name: "nm",
suffix: "b", },
prefix: "a",
suffix: "b",
} }
if !r2.GvknEquals(expected) { if !r2.GvknEquals(expected) {
t.Fatalf("%v should equal %v", r2, expected) t.Fatalf("%v should equal %v", r2, expected)