fix: handle empty namespace as default

Update the namespace handling in the edit add configmap and secret commands to
handle the empty namespace and the default namespace in the same way. Before
this change, if a configmap/secret was created using kustomize edit add where
one command was issued with default as the namespace and the other without a
namespace specified it would create two separate configmap generators, and then
kustomize build would fail if merge was not the strategy for either.
This commit is contained in:
Mauren Berti
2023-11-04 17:33:34 -04:00
parent e219b8864e
commit 7226ba5086
9 changed files with 413 additions and 15 deletions

View File

@@ -118,6 +118,7 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs=
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
@@ -201,6 +202,7 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
@@ -208,21 +210,56 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
k8s.io/apiserver v0.17.0 h1:XhUix+FKFDcBygWkQNp7wKKvZL030QUlH1o8vFeSgZA=
k8s.io/code-generator v0.17.0 h1:y+KWtDWNqlJzJu/kUy8goJZO0X71PGIpAHLX8a0JYk0=
k8s.io/component-base v0.17.0 h1:BnDFcmBDq+RPpxXjmuYnZXb59XNN9CaFrX8ba9+3xrA=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ=
modernc.org/golex v1.0.0 h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=
modernc.org/mathutil v1.0.0 h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=
modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=
modernc.org/xc v1.0.0 h1:7ccXrupWZIS3twbUGrtKmHS2DXY6xegFua+6O3xgAFU=
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=

View File

@@ -148,7 +148,7 @@ func addConfigMap(
func findOrMakeConfigMapArgs(m *types.Kustomization, name, namespace string) *types.ConfigMapArgs {
for i, v := range m.ConfigMapGenerator {
if name == v.Name && namespace == v.Namespace {
if name == v.Name && util.NamespaceEqual(v.Namespace, namespace) {
return &m.ConfigMapGenerator[i]
}
}

View File

@@ -26,7 +26,7 @@ const (
func TestNewAddConfigMapIsNotNil(t *testing.T) {
fSys := filesys.MakeFsInMemory()
assert.NotNil(t, newCmdAddConfigMap(
require.NotNil(t, newCmdAddConfigMap(
fSys,
kv.NewLoader(
loader.NewFileLoaderAtCwd(fSys),
@@ -41,15 +41,14 @@ func TestMakeConfigMapArgs(t *testing.T) {
NamePrefix: "test-name-prefix",
}
if len(kustomization.ConfigMapGenerator) != 0 {
t.Fatal("Initial kustomization should not have any configmaps")
}
require.Len(t, kustomization.ConfigMapGenerator, 0, "Initial kustomization should not have any configmaps")
args := findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace)
assert.NotNil(t, args)
assert.Equal(t, 1, len(kustomization.ConfigMapGenerator))
assert.Equal(t, &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1], args)
assert.Equal(t, args, findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace))
assert.Equal(t, 1, len(kustomization.ConfigMapGenerator))
require.NotNil(t, args)
require.Equal(t, 1, len(kustomization.ConfigMapGenerator))
require.Equal(t, &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1], args)
require.Equal(t, args, findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace))
require.Equal(t, 1, len(kustomization.ConfigMapGenerator))
}
func TestMergeFlagsIntoConfigMapArgs_LiteralSources(t *testing.T) {
@@ -352,3 +351,143 @@ func TestEditAddConfigMapWithFileSource(t *testing.T) {
})
}
}
// TestEditAddConfigMapNamespaced tests situations regarding namespacing. For example, it
// verifies that the empty namespace and the default namespace are treated the
// same when adding a configmap to a kustomization file.
func TestEditAddConfigMapNamespaced(t *testing.T) {
testCases := []struct {
name string
configMapName string
configMapNamespace string
literalSources []string
initialArgs string
expectedResult []types.ConfigMapArgs
expectedSliceLength int
}{
{
name: "adds new key to configmap when default namespace matches empty",
configMapName: "test-cm",
configMapNamespace: "default",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- literals:
- key=value
name: test-cm
`,
expectedResult: []types.ConfigMapArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "",
Name: "test-cm",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value", "key1=value1"},
},
},
},
},
expectedSliceLength: 1,
},
{
name: "adds new key to configmap when empty namespace matches default",
configMapName: "test-cm",
configMapNamespace: "",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- literals:
- key=value
name: test-cm
namespace: default
`,
expectedResult: []types.ConfigMapArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "default",
Name: "test-cm",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value", "key1=value1"},
},
},
},
},
expectedSliceLength: 1,
},
{
name: "creates a new generator when namespaces don't match",
configMapName: "test-cm",
configMapNamespace: "",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- literals:
- key=value
name: test-cm
namespace: ns1
`,
expectedResult: []types.ConfigMapArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "ns1",
Name: "test-cm",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value"},
},
},
},
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "",
Name: "test-cm",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key1=value1"},
},
},
},
},
expectedSliceLength: 2,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fSys := filesys.MakeEmptyDirInMemory()
testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.initialArgs))
pvd := provider.NewDefaultDepProvider()
ldr := kv.NewLoader(loader.NewFileLoaderAtCwd(fSys), pvd.GetFieldValidator())
args := []string{
tc.configMapName,
fmt.Sprintf(util.FlagFormat, util.NamespaceFlag, tc.configMapNamespace),
}
for _, source := range tc.literalSources {
args = append(args, fmt.Sprintf(util.FlagFormat, util.FromLiteralFlag, source))
}
cmd := newCmdAddConfigMap(fSys, ldr, pvd.GetResourceFactory())
cmd.SetArgs(args)
require.NoError(t, cmd.Execute())
_, err := testutils_test.ReadTestKustomization(fSys)
require.NoError(t, err)
mf, err := kustfile.NewKustomizationFile(fSys)
require.NoError(t, err)
kustomization, err := mf.Read()
require.NoError(t, err)
require.Len(t, kustomization.ConfigMapGenerator, tc.expectedSliceLength)
require.ElementsMatch(t, tc.expectedResult, kustomization.ConfigMapGenerator)
})
}
}

View File

@@ -140,7 +140,7 @@ func addSecret(
func findOrMakeSecretArgs(m *types.Kustomization, name, namespace, secretType string) *types.SecretArgs {
for i, v := range m.SecretGenerator {
if name == v.Name && namespace == v.Namespace {
if name == v.Name && util.NamespaceEqual(v.Namespace, namespace) {
return &m.SecretGenerator[i]
}
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/pkg/loader"
"sigs.k8s.io/kustomize/api/provider"
@@ -237,3 +238,150 @@ func TestEditAddSecretWithFileSource(t *testing.T) {
require.Equal(t, secretName, newSecretGenerator.Name)
require.Contains(t, newSecretGenerator.FileSources, fileSource)
}
// TestEditAddSecretNamespaced tests situations regarding namespacing. For example, it
// verifies that the empty namespace and the default namespace are treated the
// same when adding a configmap to a kustomization file.
func TestEditAddSecretNamespaced(t *testing.T) {
testCases := []struct {
name string
secretName string
secretNamespace string
literalSources []string
initialArgs string
expectedResult []types.SecretArgs
expectedSliceLength int
}{
{
name: "adds new key to secret when default namespace matches empty",
secretName: "test-secret",
secretNamespace: "default",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- literals:
- key=value
name: test-secret
type: Opaque
`,
expectedResult: []types.SecretArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "",
Name: "test-secret",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value", "key1=value1"},
},
},
Type: ifc.SecretTypeOpaque,
},
},
expectedSliceLength: 1,
},
{
name: "adds new key to secret when empty namespace matches default",
secretName: "test-secret",
secretNamespace: "",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- literals:
- key=value
name: test-secret
namespace: default
type: Opaque
`,
expectedResult: []types.SecretArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "default",
Name: "test-secret",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value", "key1=value1"},
},
},
Type: ifc.SecretTypeOpaque,
},
},
expectedSliceLength: 1,
},
{
name: "creates a new generator when namespaces don't match",
secretName: "test-secret",
secretNamespace: "",
literalSources: []string{"key1=value1"},
initialArgs: `---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- literals:
- key=value
name: test-secret
namespace: ns1
type: Opaque
`,
expectedResult: []types.SecretArgs{
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "ns1",
Name: "test-secret",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key=value"},
},
},
Type: ifc.SecretTypeOpaque,
},
{
GeneratorArgs: types.GeneratorArgs{
Namespace: "",
Name: "test-secret",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"key1=value1"},
},
},
Type: ifc.SecretTypeOpaque,
},
},
expectedSliceLength: 2,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fSys := filesys.MakeEmptyDirInMemory()
testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.initialArgs))
pvd := provider.NewDefaultDepProvider()
ldr := kv.NewLoader(loader.NewFileLoaderAtCwd(fSys), pvd.GetFieldValidator())
args := []string{
tc.secretName,
fmt.Sprintf(util.FlagFormat, util.NamespaceFlag, tc.secretNamespace),
}
for _, source := range tc.literalSources {
args = append(args, fmt.Sprintf(util.FlagFormat, util.FromLiteralFlag, source))
}
cmd := newCmdAddSecret(fSys, ldr, pvd.GetResourceFactory())
cmd.SetArgs(args)
require.NoError(t, cmd.Execute())
_, err := testutils_test.ReadTestKustomization(fSys)
require.NoError(t, err)
mf, err := kustfile.NewKustomizationFile(fSys)
require.NoError(t, err)
kustomization, err := mf.Read()
require.NoError(t, err)
require.Len(t, kustomization.SecretGenerator, tc.expectedSliceLength)
require.ElementsMatch(t, tc.expectedResult, kustomization.SecretGenerator)
})
}
}

View File

@@ -12,6 +12,9 @@ import (
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// DefaultNamespace is the default namespace name in Kubernetes.
const DefaultNamespace = "default"
// GlobPatterns accepts a slice of glob strings and returns the set of
// matching file paths.
func GlobPatterns(fSys filesys.FileSystem, patterns []string) ([]string, error) {
@@ -30,7 +33,7 @@ func GlobPatterns(fSys filesys.FileSystem, patterns []string) ([]string, error)
return result, nil
}
// GlobPatterns accepts a slice of glob strings and returns the set of matching file paths.
// GlobPatternsWithLoader accepts a slice of glob strings and returns the set of matching file paths.
// If validation is skipped, then it will return the patterns as provided.
// Otherwise, It will try to load the files from the filesystem.
// If files are not found in the filesystem, it will try to load from remote.
@@ -109,3 +112,18 @@ func trimQuotes(s string) string {
}
return s
}
// NamespaceEqual checks if two namespaces are the same. It considers the empty namespace and the default namespace to
// be the same. As such, when one namespace is the empty string ('""') and the other namespace is "default", this function
// will return true.
func NamespaceEqual(namespace string, otherNamespace string) bool {
if "" == namespace {
namespace = DefaultNamespace
}
if "" == otherNamespace {
otherNamespace = DefaultNamespace
}
return namespace == otherNamespace
}

View File

@@ -1,7 +1,7 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package util
package util_test
import (
"fmt"
@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
. "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/util"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
@@ -86,6 +87,58 @@ func TestGlobPatternsWithLoaderRemoteFile(t *testing.T) {
require.Equal(t, invalidURL, resources[0], "incorrect resources")
}
func TestNamespaceEqual(t *testing.T) {
testCases := []struct {
name string
namespace1 string
namespace2 string
want func(require.TestingT, bool, ...interface{})
}{
{
name: "succeeds when namespaces are the same",
namespace1: "ns1",
namespace2: "ns1",
want: require.True,
},
{
name: "succeeds when namespaces are default and empty string",
namespace1: "",
namespace2: DefaultNamespace,
want: require.True,
},
{
name: "succeeds when namespaces are empty string and default",
namespace1: DefaultNamespace,
namespace2: "",
want: require.True,
},
{
name: "fails when namespaces are not the same",
namespace1: "ns1",
namespace2: "ns2",
want: require.False,
},
{
name: "fails when one is empty and other is different from default",
namespace1: "",
namespace2: "ns1",
want: require.False,
},
{
name: "fails when one is different from default and other is empty",
namespace1: "ns1",
namespace2: "",
want: require.False,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.want(t, NamespaceEqual(tc.namespace1, tc.namespace2))
})
}
}
type fakeLoader struct {
path string
}

View File

@@ -33,6 +33,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/sys v0.13.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect

View File

@@ -66,6 +66,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=