add ItemId type

This commit is contained in:
Jingfang Liu
2019-04-23 16:31:48 -07:00
parent 256ffdb932
commit 5b18c4de0c
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.
const (
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.
type ResId struct {
// Gvk of the resource.
gvKind gvk.Gvk
// name of the resource before transformation.
name string
ItemId
// namePrefix of the resource.
// An untransformed resource has no prefix.
// A fully transformed resource has an arbitrary
@@ -41,42 +36,36 @@ type ResId struct {
// A fully transformed resource has an arbitrary
// number of suffixes concatenated together.
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
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
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
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
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
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
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 (
@@ -89,7 +78,7 @@ const (
// String of ResId based on GVK, name and prefix
func (n ResId) String() string {
ns := n.namespace
ns := n.ItemId.Namespace
if ns == "" {
ns = noNamespace
}
@@ -97,7 +86,7 @@ func (n ResId) String() string {
if p == "" {
p = noPrefix
}
nm := n.name
nm := n.ItemId.Name
if nm == "" {
nm = noName
}
@@ -107,39 +96,39 @@ func (n ResId) String() string {
}
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
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
// Group/Version/Kind/name.
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
// namespace/Group/Version/Kind/name.
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.
func (n ResId) Gvk() gvk.Gvk {
return n.gvKind
return n.ItemId.Gvk
}
// Name returns resource name.
func (n ResId) Name() string {
return n.name
return n.ItemId.Name
}
// Namespace returns resource namespace.
func (n ResId) Namespace() string {
return n.namespace
return n.ItemId.Namespace
}
// 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
func (n ResId) CopyWithNewNamespace(ns string) ResId {
result := n
result.namespace = ns
result.ItemId.Namespace = ns
return result
}

View File

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