diff --git a/api/krusty/no_list_items_test.go b/api/krusty/no_list_items_test.go new file mode 100644 index 0000000000..befe621ea9 --- /dev/null +++ b/api/krusty/no_list_items_test.go @@ -0,0 +1,228 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package krusty_test + +import ( + "testing" + + kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" +) + +// test for https://github.com/kubernetes-sigs/kustomize/issues/4240 +func TestSuffix5042(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- resource.yaml +`) + + th.WriteF("resource.yaml", ` +apiVersion: example.com/v1alpha1 +kind: MyResource +metadata: + name: service +--- +apiVersion: example.com/v1alpha1 +kind: MyResourceTwo +metadata: + name: test +rules: [] +`) + m := th.Run(".", th.MakeDefaultOptions()) + + th.AssertActualEqualsExpected(m, ` +apiVersion: example.com/v1alpha1 +kind: MyResource +metadata: + name: service +--- +apiVersion: example.com/v1alpha1 +kind: MyResourceTwo +metadata: + name: test +rules: [] +`) +} + +func TestListSuffix5042(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- resource.yaml +`) + + th.WriteF("resource.yaml", ` +apiVersion: example.com/v1alpha1 +kind: MyResource +metadata: + name: service +--- +apiVersion: example.com/v1alpha1 +kind: MyResourceList +metadata: + name: test +rules: [] +`) + m := th.Run(".", th.MakeDefaultOptions()) + + th.AssertActualEqualsExpected(m, ` +apiVersion: example.com/v1alpha1 +kind: MyResource +metadata: + name: service +--- +apiVersion: example.com/v1alpha1 +kind: MyResourceList +metadata: + name: test +rules: [] +`) +} + +func TestListSuffix5485(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- resource.yaml + `) + + th.WriteF("resource.yaml", ` +apiVersion: infra.protonbase.io/v1alpha1 +kind: AccessWhiteList +metadata: + name: wlmls5769f + namespace: dc7i4hyxzw +spec: + rules: + - sourceIps: 0.0.0.0/16 +`) + + m := th.Run(".", th.MakeDefaultOptions()) + + th.AssertActualEqualsExpected(m, ` +apiVersion: infra.protonbase.io/v1alpha1 +kind: AccessWhiteList +metadata: + name: wlmls5769f + namespace: dc7i4hyxzw +spec: + rules: + - sourceIps: 0.0.0.0/16 +`) +} + +func TestListToIndividualResources(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- list.yaml +`) + + th.WriteF("list.yaml", ` +apiVersion: v1 +kind: PodList +items: + - apiVersion: v1 + kind: Pod + metadata: + name: my-pod-1 + namespace: default + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:1.19.10 + ports: + - containerPort: 80 + - apiVersion: v1 + kind: Pod + metadata: + name: my-pod-2 + namespace: default + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:1.19.10 + ports: + - containerPort: 80 + - apiVersion: v1 + kind: Pod + metadata: + name: my-pod-3 + namespace: default + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:1.19.10 + ports: + - containerPort: 80 +`) + + m := th.Run(".", th.MakeDefaultOptions()) + + th.AssertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Pod +metadata: + labels: + app: my-app + name: my-pod-1 + namespace: default +spec: + containers: + - image: nginx:1.19.10 + name: my-container + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: my-app + name: my-pod-2 + namespace: default +spec: + containers: + - image: nginx:1.19.10 + name: my-container + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: my-app + name: my-pod-3 + namespace: default +spec: + containers: + - image: nginx:1.19.10 + name: my-container + ports: + - containerPort: 80 +`) +} + +// Empty list should result in no resources +func TestEmptyList(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- emptyList.yaml +`) + th.WriteF("emptyList.yaml", ` +apiVersion: v1 +kind: PodList +items: [] +`) + m := th.Run(".", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, "") +} diff --git a/api/resource/factory.go b/api/resource/factory.go index fef2f6e499..a42f93bb8e 100644 --- a/api/resource/factory.go +++ b/api/resource/factory.go @@ -202,7 +202,10 @@ func (rf *Factory) inlineAnyEmbeddedLists( } items, ok := m["items"] if !ok { - // treat as an empty list + // Items field is not present. + // This is not a collections resource. + // read more https://kubernetes.io/docs/reference/using-api/api-concepts/#collections + result = append(result, n0) continue } slice, ok := items.([]interface{}) diff --git a/api/resource/factory_test.go b/api/resource/factory_test.go index 8695ab0364..953caa7ddb 100644 --- a/api/resource/factory_test.go +++ b/api/resource/factory_test.go @@ -301,6 +301,17 @@ kind: List t.Fatalf("failed to create new instance with %v: %v", deploymentB, errB) } + deploymentNoItems := "deployment-no-items" + testDeploymentNoItems, errNoItems := factory.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "List", + }, + ) + if errNoItems != nil { + t.Fatalf("failed to create new instance with %v: %v", deploymentNoItems, testDeploymentNoItems) + } + fSys := filesys.MakeFsInMemory() fSys.WriteFile(string(patchGood1), []byte(patch1)) fSys.WriteFile(string(patchGood2), []byte(patch2)) @@ -363,7 +374,7 @@ kind: List }, "listWithNoItems": { input: []types.PatchStrategicMerge{patchList4}, - expectedOut: []*Resource{}, + expectedOut: []*Resource{testDeploymentNoItems}, expectedErr: false, }, } diff --git a/go.work.sum b/go.work.sum index b858ddeb8b..03812685dd 100644 --- a/go.work.sum +++ b/go.work.sum @@ -232,6 +232,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= @@ -275,6 +276,7 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= @@ -528,6 +530,7 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= 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/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= @@ -548,7 +551,9 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=