From 6ab3cced0ca15f5412074bca8654faf493c712ea Mon Sep 17 00:00:00 2001 From: monopole Date: Thu, 15 Apr 2021 14:19:03 -0700 Subject: [PATCH] Upgrade kustomize-in-kubectl to v4.1.2 --- go.mod | 8 +- go.sum | 14 +- staging/src/k8s.io/cli-runtime/go.mod | 2 +- staging/src/k8s.io/cli-runtime/go.sum | 8 +- staging/src/k8s.io/kubectl/go.mod | 4 +- staging/src/k8s.io/kubectl/go.sum | 14 +- staging/src/k8s.io/sample-cli-plugin/go.sum | 8 +- vendor/modules.txt | 17 +- .../kustomize/api/builtins/HashTransformer.go | 4 +- .../builtins/HelmChartInflationGenerator.go | 418 ++++++++++-------- .../api/builtins/NamespaceTransformer.go | 11 +- .../PatchStrategicMergeTransformer.go | 59 +-- .../api/builtins/PatchTransformer.go | 7 + .../kustomize/api/filters/nameref/nameref.go | 10 +- .../api/filters/namespace/namespace.go | 1 - .../patchstrategicmerge.go | 3 +- .../kustomize/api/hasher/hasher.go | 37 +- vendor/sigs.k8s.io/kustomize/api/ifc/ifc.go | 90 +--- .../accumulator/loadconfigfromcrds.go | 2 +- .../api/internal/conflict/factory.go | 23 - .../conflict/smpatchmergeonlydetector.go | 33 -- .../api/internal/plugins/loader/loader.go | 75 +++- .../api/internal/plugins/utils/utils.go | 2 +- .../api/internal/target/kusttarget.go | 5 +- .../target/kusttarget_configplugin.go | 51 ++- .../api/internal/target/multitransformer.go | 59 +-- .../kustomize/api/internal/wrappy/factory.go | 108 ----- .../kustomize/api/internal/wrappy/wnode.go | 292 ------------ .../konfig/builtinpluginconsts/namespace.go | 3 + .../kustomize/api/konfig/general.go | 24 - .../kustomize/api/konfig/plugins.go | 47 +- .../kustomize/api/krusty/kustomizer.go | 9 +- .../kustomize/api/krusty/options.go | 29 +- .../kustomize/api/loader/fileloader.go | 1 - .../kustomize/api/provider/depprovider.go | 187 +------- vendor/sigs.k8s.io/kustomize/api/resid/gvk.go | 13 +- .../kustomize/api/resmap/factory.go | 32 +- .../kustomize/api/resmap/merginator.go | 123 ------ .../kustomize/api/resmap/resmap.go | 22 +- .../kustomize/api/resmap/reswrangler.go | 153 +++---- .../api/resource/conflictdetector.go | 20 - .../kustomize/api/resource/factory.go | 207 ++++++--- .../kustomize/api/resource/resource.go | 204 ++++++--- .../kustomize/api/types/errunabletofind.go | 2 +- .../kustomize/api/types/fieldspec.go | 3 +- .../kustomize/api/types/helmchartargs.go | 106 ++++- .../kustomize/api/types/kustomization.go | 42 +- .../sigs.k8s.io/kustomize/api/types/labels.go | 25 ++ .../sigs.k8s.io/kustomize/api/types/patch.go | 8 +- .../kustomize/api/types/pluginconfig.go | 50 ++- .../kustomize/api/types/replacement.go | 62 ++- .../kustomize/api/types/selector.go | 22 +- vendor/sigs.k8s.io/kustomize/api/types/var.go | 4 +- .../kustomize/v4/commands/build/build.go | 19 +- .../build/flagallowresourceidchanges.go | 16 - .../v4/commands/build/flagenablehelm.go | 24 + .../kustomize/kyaml/filtersutil/doc.go | 6 - .../kyaml/filtersutil/filtersutil.go | 83 ---- .../kustomize/kyaml/kio/pkgio_reader.go | 52 ++- .../kustomize/kyaml/openapi/Makefile | 5 +- .../kustomize/kyaml/openapi/openapi.go | 26 +- .../sigs.k8s.io/kustomize/kyaml/yaml/rnode.go | 157 ++++++- .../kyaml/yaml/walk/associative_sequence.go | 69 ++- 63 files changed, 1443 insertions(+), 1777 deletions(-) delete mode 100644 vendor/sigs.k8s.io/kustomize/api/internal/conflict/factory.go delete mode 100644 vendor/sigs.k8s.io/kustomize/api/internal/conflict/smpatchmergeonlydetector.go delete mode 100644 vendor/sigs.k8s.io/kustomize/api/internal/wrappy/factory.go delete mode 100644 vendor/sigs.k8s.io/kustomize/api/internal/wrappy/wnode.go delete mode 100644 vendor/sigs.k8s.io/kustomize/api/resmap/merginator.go delete mode 100644 vendor/sigs.k8s.io/kustomize/api/resource/conflictdetector.go create mode 100644 vendor/sigs.k8s.io/kustomize/api/types/labels.go delete mode 100644 vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagallowresourceidchanges.go create mode 100644 vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagenablehelm.go delete mode 100644 vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/doc.go delete mode 100644 vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/filtersutil.go diff --git a/go.mod b/go.mod index 026a226d734..1abbdff2c98 100644 --- a/go.mod +++ b/go.mod @@ -532,10 +532,10 @@ replace ( modernc.org/xc => modernc.org/xc v1.0.0 rsc.io/pdf => rsc.io/pdf v0.1.1 sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15 - sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.8.5 - sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.9.7 - sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 - sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.10.15 + sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.8.8 + sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.9.10 + sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 + sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.10.17 sigs.k8s.io/structured-merge-diff/v4 => sigs.k8s.io/structured-merge-diff/v4 v4.1.1 sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 687033a3e45..8e68ee549a7 100644 --- a/go.sum +++ b/go.sum @@ -602,13 +602,13 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15 h1:4uqm9Mv+w2MmBYD+F4qf/v6tDFUdPOk29C095RbU5mY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ= -sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY= -sigs.k8s.io/kustomize/cmd/config v0.9.7/go.mod h1:MvXCpHs77cfyxRmCNUQjIqCmZyYsbn5PyQpWiq44nW0= -sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 h1:0xQWp03aKWilF6UJrupcA2rCoCn3jejkJ+m/CCI/Fis= -sigs.k8s.io/kustomize/kustomize/v4 v4.0.5/go.mod h1:C7rYla7sI8EnxHE/xEhRBSHMNfcL91fx0uKmUlUhrBk= -sigs.k8s.io/kustomize/kyaml v0.10.15 h1:dSLgG78KyaxN4HylPXdK+7zB3k7sW6q3IcCmcfKA+aI= -sigs.k8s.io/kustomize/kyaml v0.10.15/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= +sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= +sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0= +sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 h1:iP3ckqMIftwsIKnMqtztReSkkPJvhqNc5QiOpMoFpbY= +sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo= +sigs.k8s.io/kustomize/kyaml v0.10.17 h1:4zrV0ym5AYa0e512q7K3Wp1u7mzoWW0xR3UHJcGWGIg= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU= sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= diff --git a/staging/src/k8s.io/cli-runtime/go.mod b/staging/src/k8s.io/cli-runtime/go.mod index 59bfb79e306..225c391d7aa 100644 --- a/staging/src/k8s.io/cli-runtime/go.mod +++ b/staging/src/k8s.io/cli-runtime/go.mod @@ -19,7 +19,7 @@ require ( k8s.io/apimachinery v0.0.0 k8s.io/client-go v0.0.0 k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 - sigs.k8s.io/kustomize/api v0.8.5 + sigs.k8s.io/kustomize/api v0.8.8 sigs.k8s.io/yaml v1.2.0 ) diff --git a/staging/src/k8s.io/cli-runtime/go.sum b/staging/src/k8s.io/cli-runtime/go.sum index 2059d3d92b7..7b16f8fb0c9 100644 --- a/staging/src/k8s.io/cli-runtime/go.sum +++ b/staging/src/k8s.io/cli-runtime/go.sum @@ -653,10 +653,10 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ= -sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY= -sigs.k8s.io/kustomize/kyaml v0.10.15 h1:dSLgG78KyaxN4HylPXdK+7zB3k7sW6q3IcCmcfKA+aI= -sigs.k8s.io/kustomize/kyaml v0.10.15/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= +sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= +sigs.k8s.io/kustomize/kyaml v0.10.17 h1:4zrV0ym5AYa0e512q7K3Wp1u7mzoWW0xR3UHJcGWGIg= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU= sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/staging/src/k8s.io/kubectl/go.mod b/staging/src/k8s.io/kubectl/go.mod index 47e84089411..41b21f76679 100644 --- a/staging/src/k8s.io/kubectl/go.mod +++ b/staging/src/k8s.io/kubectl/go.mod @@ -43,8 +43,8 @@ require ( k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 k8s.io/metrics v0.0.0 k8s.io/utils v0.0.0-20201110183641-67b214c5f920 - sigs.k8s.io/kustomize/api v0.8.5 - sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 + sigs.k8s.io/kustomize/api v0.8.8 + sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 sigs.k8s.io/yaml v1.2.0 ) diff --git a/staging/src/k8s.io/kubectl/go.sum b/staging/src/k8s.io/kubectl/go.sum index 62c0ef59dc2..a603f1bd668 100644 --- a/staging/src/k8s.io/kubectl/go.sum +++ b/staging/src/k8s.io/kubectl/go.sum @@ -740,13 +740,13 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ= -sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY= -sigs.k8s.io/kustomize/cmd/config v0.9.7/go.mod h1:MvXCpHs77cfyxRmCNUQjIqCmZyYsbn5PyQpWiq44nW0= -sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 h1:0xQWp03aKWilF6UJrupcA2rCoCn3jejkJ+m/CCI/Fis= -sigs.k8s.io/kustomize/kustomize/v4 v4.0.5/go.mod h1:C7rYla7sI8EnxHE/xEhRBSHMNfcL91fx0uKmUlUhrBk= -sigs.k8s.io/kustomize/kyaml v0.10.15 h1:dSLgG78KyaxN4HylPXdK+7zB3k7sW6q3IcCmcfKA+aI= -sigs.k8s.io/kustomize/kyaml v0.10.15/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= +sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= +sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0= +sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 h1:iP3ckqMIftwsIKnMqtztReSkkPJvhqNc5QiOpMoFpbY= +sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo= +sigs.k8s.io/kustomize/kyaml v0.10.17 h1:4zrV0ym5AYa0e512q7K3Wp1u7mzoWW0xR3UHJcGWGIg= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU= sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/staging/src/k8s.io/sample-cli-plugin/go.sum b/staging/src/k8s.io/sample-cli-plugin/go.sum index 2059d3d92b7..7b16f8fb0c9 100644 --- a/staging/src/k8s.io/sample-cli-plugin/go.sum +++ b/staging/src/k8s.io/sample-cli-plugin/go.sum @@ -653,10 +653,10 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ= -sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY= -sigs.k8s.io/kustomize/kyaml v0.10.15 h1:dSLgG78KyaxN4HylPXdK+7zB3k7sW6q3IcCmcfKA+aI= -sigs.k8s.io/kustomize/kyaml v0.10.15/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= +sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= +sigs.k8s.io/kustomize/kyaml v0.10.17 h1:4zrV0ym5AYa0e512q7K3Wp1u7mzoWW0xR3UHJcGWGIg= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU= sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/vendor/modules.txt b/vendor/modules.txt index b8df1e595d5..9057234223f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2630,8 +2630,8 @@ k8s.io/utils/trace # sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client -# sigs.k8s.io/kustomize/api v0.8.5 => sigs.k8s.io/kustomize/api v0.8.5 -# sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.8.5 +# sigs.k8s.io/kustomize/api v0.8.8 => sigs.k8s.io/kustomize/api v0.8.8 +# sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.8.8 sigs.k8s.io/kustomize/api/builtins sigs.k8s.io/kustomize/api/filesys sigs.k8s.io/kustomize/api/filters/annotations @@ -2652,7 +2652,6 @@ sigs.k8s.io/kustomize/api/hasher sigs.k8s.io/kustomize/api/ifc sigs.k8s.io/kustomize/api/image sigs.k8s.io/kustomize/api/internal/accumulator -sigs.k8s.io/kustomize/api/internal/conflict sigs.k8s.io/kustomize/api/internal/generators sigs.k8s.io/kustomize/api/internal/git sigs.k8s.io/kustomize/api/internal/kusterr @@ -2665,7 +2664,6 @@ sigs.k8s.io/kustomize/api/internal/plugins/utils sigs.k8s.io/kustomize/api/internal/target sigs.k8s.io/kustomize/api/internal/utils sigs.k8s.io/kustomize/api/internal/validate -sigs.k8s.io/kustomize/api/internal/wrappy sigs.k8s.io/kustomize/api/konfig sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts sigs.k8s.io/kustomize/api/krusty @@ -2677,17 +2675,16 @@ sigs.k8s.io/kustomize/api/resid sigs.k8s.io/kustomize/api/resmap sigs.k8s.io/kustomize/api/resource sigs.k8s.io/kustomize/api/types -# sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.9.7 -# sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 => sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 -# sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.0.5 +# sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.9.10 +# sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 => sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 +# sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.1.2 sigs.k8s.io/kustomize/kustomize/v4/commands/build -# sigs.k8s.io/kustomize/kyaml v0.10.15 => sigs.k8s.io/kustomize/kyaml v0.10.15 -# sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.10.15 +# sigs.k8s.io/kustomize/kyaml v0.10.17 => sigs.k8s.io/kustomize/kyaml v0.10.17 +# sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.10.17 sigs.k8s.io/kustomize/kyaml/comments sigs.k8s.io/kustomize/kyaml/errors sigs.k8s.io/kustomize/kyaml/ext sigs.k8s.io/kustomize/kyaml/fieldmeta -sigs.k8s.io/kustomize/kyaml/filtersutil sigs.k8s.io/kustomize/kyaml/fn/runtime/container sigs.k8s.io/kustomize/kyaml/fn/runtime/exec sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil diff --git a/vendor/sigs.k8s.io/kustomize/api/builtins/HashTransformer.go b/vendor/sigs.k8s.io/kustomize/api/builtins/HashTransformer.go index c7ce6f7e86b..54586beeb3c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/builtins/HashTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/builtins/HashTransformer.go @@ -11,7 +11,7 @@ import ( ) type HashTransformerPlugin struct { - hasher ifc.KunstructuredHasher + hasher ifc.KustHasher } func (p *HashTransformerPlugin) Config( @@ -24,7 +24,7 @@ func (p *HashTransformerPlugin) Config( func (p *HashTransformerPlugin) Transform(m resmap.ResMap) error { for _, res := range m.Resources() { if res.NeedHashSuffix() { - h, err := p.hasher.Hash(res) + h, err := res.Hash(p.hasher) if err != nil { return err } diff --git a/vendor/sigs.k8s.io/kustomize/api/builtins/HelmChartInflationGenerator.go b/vendor/sigs.k8s.io/kustomize/api/builtins/HelmChartInflationGenerator.go index e03d5abadf5..7037a01b5f5 100644 --- a/vendor/sigs.k8s.io/kustomize/api/builtins/HelmChartInflationGenerator.go +++ b/vendor/sigs.k8s.io/kustomize/api/builtins/HelmChartInflationGenerator.go @@ -6,7 +6,6 @@ package builtins import ( "bytes" "fmt" - "io" "io/ioutil" "os" "os/exec" @@ -16,7 +15,6 @@ import ( "github.com/imdario/mergo" "github.com/pkg/errors" - "sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/yaml" @@ -25,243 +23,285 @@ import ( // HelmChartInflationGeneratorPlugin is a plugin to generate resources // from a remote or local helm chart. type HelmChartInflationGeneratorPlugin struct { - h *resmap.PluginHelpers - types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - runHelmCommand func([]string) ([]byte, error) - types.HelmChartArgs + h *resmap.PluginHelpers + types.HelmGlobals + types.HelmChart tmpDir string } var KustomizePlugin HelmChartInflationGeneratorPlugin +const ( + valuesMergeOptionMerge = "merge" + valuesMergeOptionOverride = "override" + valuesMergeOptionReplace = "replace" +) + +var legalMergeOptions = []string{ + valuesMergeOptionMerge, + valuesMergeOptionOverride, + valuesMergeOptionReplace, +} + // Config uses the input plugin configurations `config` to setup the generator // options -func (p *HelmChartInflationGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) error { +func (p *HelmChartInflationGeneratorPlugin) Config( + h *resmap.PluginHelpers, config []byte) (err error) { + if h.GeneralConfig() == nil { + return fmt.Errorf("unable to access general config") + } + if !h.GeneralConfig().HelmConfig.Enabled { + return fmt.Errorf("must specify --enable-helm") + } + if h.GeneralConfig().HelmConfig.Command == "" { + return fmt.Errorf("must specify --helm-command") + } p.h = h - err := yaml.Unmarshal(config, p) - if err != nil { - return err + if err = yaml.Unmarshal(config, p); err != nil { + return } - tmpDir, err := filesys.NewTmpConfirmedDir() - if err != nil { - return err - } - p.tmpDir = string(tmpDir) - if p.ChartName == "" { - return fmt.Errorf("chartName cannot be empty") - } - if p.ChartHome == "" { - p.ChartHome = filepath.Join(p.tmpDir, "chart") - } - if p.ChartRepoName == "" { - p.ChartRepoName = "stable" - } - if p.HelmBin == "" { - p.HelmBin = "helm" - } - if p.HelmHome == "" { - p.HelmHome = filepath.Join(p.tmpDir, ".helm") - } - if p.Values == "" { - p.Values = filepath.Join(p.ChartHome, p.ChartName, "values.yaml") - } - if p.ValuesMerge == "" { - p.ValuesMerge = "override" - } - // runHelmCommand will run `helm` command with args provided. Return stdout - // and error if there is any. - p.runHelmCommand = func(args []string) ([]byte, error) { - stdout := new(bytes.Buffer) - stderr := new(bytes.Buffer) - cmd := exec.Command(p.HelmBin, args...) - cmd.Stdout = stdout - cmd.Stderr = stderr - cmd.Env = append(cmd.Env, - fmt.Sprintf("HELM_CONFIG_HOME=%s", p.HelmHome), - fmt.Sprintf("HELM_CACHE_HOME=%s/.cache", p.HelmHome), - fmt.Sprintf("HELM_DATA_HOME=%s/.data", p.HelmHome), - ) - err := cmd.Run() - if err != nil { - return stdout.Bytes(), - errors.Wrap( - fmt.Errorf("failed to run command %s %s", p.HelmBin, strings.Join(args, " ")), - stderr.String(), - ) - } - return stdout.Bytes(), nil - } - return nil + return p.validateArgs() } -// EncodeValues for writing -func (p *HelmChartInflationGeneratorPlugin) EncodeValues(w io.Writer) error { - d, err := yaml.Marshal(p.ValuesLocal) - if err != nil { - return err - } - _, err = w.Write(d) - if err != nil { - return err - } - return nil -} - -// useValuesLocal process (merge) inflator config provided values with chart default values.yaml -func (p *HelmChartInflationGeneratorPlugin) useValuesLocal() error { - // not override, merge, none - if !(p.ValuesMerge == "none" || p.ValuesMerge == "no" || p.ValuesMerge == "false") { - var pValues []byte - var err error - - if filepath.IsAbs(p.Values) { - pValues, err = ioutil.ReadFile(p.Values) - } else { - pValues, err = p.h.Loader().Load(p.Values) - } - if err != nil { - return err - } - chValues := make(map[string]interface{}) - err = yaml.Unmarshal(pValues, &chValues) - if err != nil { - return err - } - if p.ValuesMerge == "override" { - err = mergo.Merge(&chValues, p.ValuesLocal, mergo.WithOverride) - if err != nil { - return err - } - } - if p.ValuesMerge == "merge" { - err = mergo.Merge(&chValues, p.ValuesLocal) - if err != nil { - return err - } - } - p.ValuesLocal = chValues - } - b, err := yaml.Marshal(p.ValuesLocal) - if err != nil { - return err - } - path, err := p.writeValuesBytes(b) - if err != nil { - return err - } - p.Values = path - return nil -} - -// copyValues will copy the relative values file into the temp directory -// to avoid messing up with CWD. -func (p *HelmChartInflationGeneratorPlugin) copyValues() error { - // only copy when the values path is not absolute - if filepath.IsAbs(p.Values) { +// This uses the real file system since tmpDir may be used +// by the helm subprocess. Cannot use a chroot jail or fake +// filesystem since we allow the user to use previously +// downloaded charts. This is safe since this plugin is +// owned by kustomize. +func (p *HelmChartInflationGeneratorPlugin) establishTmpDir() (err error) { + if p.tmpDir != "" { + // already done. return nil } - // we must use use loader to read values file - b, err := p.h.Loader().Load(p.Values) - if err != nil { + p.tmpDir, err = ioutil.TempDir("", "kustomize-helm-") + return err +} + +func (p *HelmChartInflationGeneratorPlugin) validateArgs() (err error) { + if p.Name == "" { + return fmt.Errorf("chart name cannot be empty") + } + + // ChartHome might be consulted by the plugin (to read + // values files below it), so it must be located under + // the loader root (unless root restrictions are + // disabled, in which case this can be an absolute path). + if p.ChartHome == "" { + p.ChartHome = "charts" + } + + // The ValuesFile may be consulted by the plugin, so it must + // be under the loader root (unless root restrictions are + // disabled). + if p.ValuesFile == "" { + p.ValuesFile = filepath.Join(p.ChartHome, p.Name, "values.yaml") + } + + if err = p.errIfIllegalValuesMerge(); err != nil { return err } - path, err := p.writeValuesBytes(b) - if err != nil { - return err + + // ConfigHome is not loaded by the plugin, and can be located anywhere. + if p.ConfigHome == "" { + if err = p.establishTmpDir(); err != nil { + return errors.Wrap( + err, "unable to create tmp dir for HELM_CONFIG_HOME") + } + p.ConfigHome = filepath.Join(p.tmpDir, "helm") } - p.Values = path return nil } -func (p *HelmChartInflationGeneratorPlugin) writeValuesBytes(b []byte) (string, error) { - path := filepath.Join(p.ChartHome, p.ChartName, "kustomize-values.yaml") - err := ioutil.WriteFile(path, b, 0644) +func (p *HelmChartInflationGeneratorPlugin) errIfIllegalValuesMerge() error { + if p.ValuesMerge == "" { + // Use the default. + p.ValuesMerge = valuesMergeOptionOverride + return nil + } + for _, opt := range legalMergeOptions { + if p.ValuesMerge == opt { + return nil + } + } + return fmt.Errorf("valuesMerge must be one of %v", legalMergeOptions) +} + +func (p *HelmChartInflationGeneratorPlugin) absChartHome() string { + if filepath.IsAbs(p.ChartHome) { + return p.ChartHome + } + return filepath.Join(p.h.Loader().Root(), p.ChartHome) +} + +func (p *HelmChartInflationGeneratorPlugin) runHelmCommand( + args []string) ([]byte, error) { + stdout := new(bytes.Buffer) + stderr := new(bytes.Buffer) + cmd := exec.Command(p.h.GeneralConfig().HelmConfig.Command, args...) + cmd.Stdout = stdout + cmd.Stderr = stderr + env := []string{ + fmt.Sprintf("HELM_CONFIG_HOME=%s", p.ConfigHome), + fmt.Sprintf("HELM_CACHE_HOME=%s/.cache", p.ConfigHome), + fmt.Sprintf("HELM_DATA_HOME=%s/.data", p.ConfigHome)} + cmd.Env = append(os.Environ(), env...) + err := cmd.Run() + if err != nil { + helm := p.h.GeneralConfig().HelmConfig.Command + err = errors.Wrap( + fmt.Errorf( + "unable to run: '%s %s' with env=%s (is '%s' installed?)", + helm, strings.Join(args, " "), env, helm), + stderr.String(), + ) + } + return stdout.Bytes(), err +} + +// createNewMergedValuesFile replaces/merges original values file with ValuesInline. +func (p *HelmChartInflationGeneratorPlugin) createNewMergedValuesFile() ( + path string, err error) { + if p.ValuesMerge == valuesMergeOptionMerge || + p.ValuesMerge == valuesMergeOptionOverride { + if err = p.replaceValuesInline(); err != nil { + return "", err + } + } + var b []byte + b, err = yaml.Marshal(p.ValuesInline) if err != nil { return "", err } - return path, nil + return p.writeValuesBytes(b) +} + +func (p *HelmChartInflationGeneratorPlugin) replaceValuesInline() error { + pValues, err := p.h.Loader().Load(p.ValuesFile) + if err != nil { + return err + } + chValues := make(map[string]interface{}) + if err = yaml.Unmarshal(pValues, &chValues); err != nil { + return err + } + switch p.ValuesMerge { + case valuesMergeOptionOverride: + err = mergo.Merge( + &chValues, p.ValuesInline, mergo.WithOverride) + case valuesMergeOptionMerge: + err = mergo.Merge(&chValues, p.ValuesInline) + } + p.ValuesInline = chValues + return err +} + +// copyValuesFile to avoid branching. TODO: get rid of this. +func (p *HelmChartInflationGeneratorPlugin) copyValuesFile() (string, error) { + b, err := p.h.Loader().Load(p.ValuesFile) + if err != nil { + return "", err + } + return p.writeValuesBytes(b) +} + +// Write a absolute path file in the tmp file system. +func (p *HelmChartInflationGeneratorPlugin) writeValuesBytes( + b []byte) (string, error) { + if err := p.establishTmpDir(); err != nil { + return "", fmt.Errorf("cannot create tmp dir to write helm values") + } + path := filepath.Join(p.tmpDir, p.Name+"-kustomize-values.yaml") + return path, ioutil.WriteFile(path, b, 0644) +} + +func (p *HelmChartInflationGeneratorPlugin) cleanup() { + if p.tmpDir != "" { + os.RemoveAll(p.tmpDir) + } } // Generate implements generator -func (p *HelmChartInflationGeneratorPlugin) Generate() (resmap.ResMap, error) { - // cleanup - defer os.RemoveAll(p.tmpDir) - // check helm version. we only support V3 - err := p.checkHelmVersion() - if err != nil { +func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err error) { + defer p.cleanup() + if err = p.checkHelmVersion(); err != nil { return nil, err } - // pull the chart - if !p.checkLocalChart() { - _, err := p.runHelmCommand(p.getPullCommandArgs()) - if err != nil { + if path, exists := p.chartExistsLocally(); !exists { + if p.Repo == "" { + return nil, fmt.Errorf( + "no repo specified for pull, no chart found at '%s'", path) + } + if _, err := p.runHelmCommand(p.pullCommand()); err != nil { return nil, err } } - - // inflator config valuesLocal - if len(p.ValuesLocal) > 0 { - err := p.useValuesLocal() - if err != nil { - return nil, err - } + if len(p.ValuesInline) > 0 { + p.ValuesFile, err = p.createNewMergedValuesFile() } else { - err := p.copyValues() - if err != nil { - return nil, err - } + p.ValuesFile, err = p.copyValuesFile() } - - // render the charts - stdout, err := p.runHelmCommand(p.getTemplateCommandArgs()) + if err != nil { + return nil, err + } + var stdout []byte + stdout, err = p.runHelmCommand(p.templateCommand()) if err != nil { return nil, err } - return p.h.ResmapFactory().NewResMapFromBytes(stdout) + rm, err = p.h.ResmapFactory().NewResMapFromBytes(stdout) + if err == nil { + return rm, nil + } + // try to remove the contents before first "---" because + // helm may produce messages to stdout before it + stdoutStr := string(stdout) + if idx := strings.Index(stdoutStr, "---"); idx != -1 { + return p.h.ResmapFactory().NewResMapFromBytes([]byte(stdoutStr[idx:])) + } + return nil, err } -func (p *HelmChartInflationGeneratorPlugin) getTemplateCommandArgs() []string { +func (p *HelmChartInflationGeneratorPlugin) templateCommand() []string { args := []string{"template"} if p.ReleaseName != "" { args = append(args, p.ReleaseName) } - args = append(args, filepath.Join(p.ChartHome, p.ChartName)) - if p.ReleaseNamespace != "" { - args = append(args, "--namespace", p.ReleaseNamespace) + args = append(args, filepath.Join(p.absChartHome(), p.Name)) + if p.ValuesFile != "" { + args = append(args, "--values", p.ValuesFile) } - if p.Values != "" { - args = append(args, "--values", p.Values) + if p.ReleaseName == "" { + // AFAICT, this doesn't work as intended due to a bug in helm. + // See https://github.com/helm/helm/issues/6019 + // I've tried placing the flag before and after the name argument. + args = append(args, "--generate-name") } - args = append(args, p.ExtraArgs...) return args } -func (p *HelmChartInflationGeneratorPlugin) getPullCommandArgs() []string { - args := []string{"pull", "--untar", "--untardir", p.ChartHome} - chartName := fmt.Sprintf("%s/%s", p.ChartRepoName, p.ChartName) - if p.ChartVersion != "" { - args = append(args, "--version", p.ChartVersion) +func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string { + args := []string{ + "pull", + "--untar", + "--untardir", p.absChartHome(), + "--repo", p.Repo, + p.Name} + if p.Version != "" { + args = append(args, "--version", p.Version) } - if p.ChartRepoURL != "" { - args = append(args, "--repo", p.ChartRepoURL) - chartName = p.ChartName - } - - args = append(args, chartName) - return args } -// checkLocalChart will return true if the chart does exist in +// chartExistsLocally will return true if the chart does exist in // local chart home. -func (p *HelmChartInflationGeneratorPlugin) checkLocalChart() bool { - path := filepath.Join(p.ChartHome, p.ChartName) +func (p *HelmChartInflationGeneratorPlugin) chartExistsLocally() (string, bool) { + path := filepath.Join(p.absChartHome(), p.Name) s, err := os.Stat(path) if err != nil { - return false + return "", false } - return s.IsDir() + return path, s.IsDir() } // checkHelmVersion will return an error if the helm version is not V3 @@ -270,11 +310,17 @@ func (p *HelmChartInflationGeneratorPlugin) checkHelmVersion() error { if err != nil { return err } - r, err := regexp.Compile(`v\d+(\.\d+)+`) + r, err := regexp.Compile(`v?\d+(\.\d+)+`) if err != nil { return err } - v := string(r.Find(stdout))[1:] + v := r.FindString(string(stdout)) + if v == "" { + return fmt.Errorf("cannot find version string in %s", string(stdout)) + } + if v[0] == 'v' { + v = v[1:] + } majorVersion := strings.Split(v, ".")[0] if majorVersion != "3" { return fmt.Errorf("this plugin requires helm V3 but got v%s", v) diff --git a/vendor/sigs.k8s.io/kustomize/api/builtins/NamespaceTransformer.go b/vendor/sigs.k8s.io/kustomize/api/builtins/NamespaceTransformer.go index 0ed2796a4e0..6794f26e81c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/builtins/NamespaceTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/builtins/NamespaceTransformer.go @@ -30,20 +30,15 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error { return nil } for _, r := range m.Resources() { - empty, err := r.IsEmpty() - if err != nil { - return err - } - if empty { + if r.IsEmpty() { // Don't mutate empty objects? continue } r.StorePreviousId() - err = r.ApplyFilter(namespace.Filter{ + if err := r.ApplyFilter(namespace.Filter{ Namespace: p.Namespace, FsSlice: p.FieldSpecs, - }) - if err != nil { + }); err != nil { return err } matches := m.GetMatchingResourcesByCurrentId(r.CurId().Equals) diff --git a/vendor/sigs.k8s.io/kustomize/api/builtins/PatchStrategicMergeTransformer.go b/vendor/sigs.k8s.io/kustomize/api/builtins/PatchStrategicMergeTransformer.go index 77ebbc8aeba..f93d1266d71 100644 --- a/vendor/sigs.k8s.io/kustomize/api/builtins/PatchStrategicMergeTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/builtins/PatchStrategicMergeTransformer.go @@ -28,45 +28,48 @@ func (p *PatchStrategicMergeTransformerPlugin) Config( return fmt.Errorf("empty file path and empty patch content") } if len(p.Paths) != 0 { - for _, onePath := range p.Paths { - // The following oddly attempts to interpret a path string as an - // actual patch (instead of as a path to a file containing a patch). - // All tests pass if this code is commented out. This code should - // be deleted; the user should use the Patches field which - // exists for this purpose (inline patch declaration). - res, err := h.ResmapFactory().RF().SliceFromBytes([]byte(onePath)) - if err == nil { - p.loadedPatches = append(p.loadedPatches, res...) - continue - } - res, err = h.ResmapFactory().RF().SliceFromPatches( - h.Loader(), []types.PatchStrategicMerge{onePath}) - if err != nil { - return err - } - p.loadedPatches = append(p.loadedPatches, res...) - } - } - if p.Patches != "" { - res, err := h.ResmapFactory().RF().SliceFromBytes([]byte(p.Patches)) + patches, err := loadFromPaths(h, p.Paths) if err != nil { return err } - p.loadedPatches = append(p.loadedPatches, res...) + p.loadedPatches = append(p.loadedPatches, patches...) + } + if p.Patches != "" { + patches, err := h.ResmapFactory().RF().SliceFromBytes([]byte(p.Patches)) + if err != nil { + return err + } + p.loadedPatches = append(p.loadedPatches, patches...) } - if len(p.loadedPatches) == 0 { return fmt.Errorf( "patch appears to be empty; files=%v, Patch=%s", p.Paths, p.Patches) } - // Merge the patches, looking for conflicts. - _, err = h.ResmapFactory().ConflatePatches(p.loadedPatches) - if err != nil { - return err - } return nil } +func loadFromPaths( + h *resmap.PluginHelpers, + paths []types.PatchStrategicMerge) ( + result []*resource.Resource, err error) { + var patches []*resource.Resource + for _, path := range paths { + // For legacy reasons, attempt to treat the path string as + // actual patch content. + patches, err = h.ResmapFactory().RF().SliceFromBytes([]byte(path)) + if err != nil { + // Failing that, treat it as a file path. + patches, err = h.ResmapFactory().RF().SliceFromPatches( + h.Loader(), []types.PatchStrategicMerge{path}) + if err != nil { + return + } + } + result = append(result, patches...) + } + return +} + func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error { for _, patch := range p.loadedPatches { target, err := m.GetById(patch.OrgId()) diff --git a/vendor/sigs.k8s.io/kustomize/api/builtins/PatchTransformer.go b/vendor/sigs.k8s.io/kustomize/api/builtins/PatchTransformer.go index 0696f3e1a69..99f48e74895 100644 --- a/vendor/sigs.k8s.io/kustomize/api/builtins/PatchTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/builtins/PatchTransformer.go @@ -21,6 +21,7 @@ type PatchTransformerPlugin struct { Path string `json:"path,omitempty" yaml:"path,omitempty"` Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` + Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` } func (p *PatchTransformerPlugin) Config( @@ -60,6 +61,12 @@ func (p *PatchTransformerPlugin) Config( } if errSM == nil { p.loadedPatch = patchSM + if p.Options["allowNameChange"] { + p.loadedPatch.SetAllowNameChange("true") + } + if p.Options["allowKindChange"] { + p.loadedPatch.SetAllowKindChange("true") + } } else { p.decodedPatch = patchJson } diff --git a/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go b/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go index e5a3d2635a0..a048d97f120 100644 --- a/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go +++ b/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go @@ -1,7 +1,6 @@ package nameref import ( - "encoding/json" "fmt" "strings" @@ -11,7 +10,6 @@ import ( "sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/types" - "sigs.k8s.io/kustomize/kyaml/filtersutil" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -186,11 +184,7 @@ func (f Filter) recordTheReferral(referral *resource.Resource) { // getRoleRefGvk returns a Gvk in the roleRef field. Return error // if the roleRef, roleRef/apiGroup or roleRef/kind is missing. -func getRoleRefGvk(res json.Marshaler) (*resid.Gvk, error) { - n, err := filtersutil.GetRNode(res) - if err != nil { - return nil, err - } +func getRoleRefGvk(n *yaml.RNode) (*resid.Gvk, error) { roleRef, err := n.Pipe(yaml.Lookup("roleRef")) if err != nil { return nil, err @@ -276,7 +270,7 @@ func (f Filter) roleRefFilter() sieveFunc { if !strings.HasSuffix(f.NameFieldToUpdate.Path, "roleRef/name") { return acceptAll } - roleRefGvk, err := getRoleRefGvk(f.Referrer) + roleRefGvk, err := getRoleRefGvk(f.Referrer.AsRNode()) if err != nil { return acceptAll } diff --git a/vendor/sigs.k8s.io/kustomize/api/filters/namespace/namespace.go b/vendor/sigs.k8s.io/kustomize/api/filters/namespace/namespace.go index 85e56c57243..69458e198b0 100644 --- a/vendor/sigs.k8s.io/kustomize/api/filters/namespace/namespace.go +++ b/vendor/sigs.k8s.io/kustomize/api/filters/namespace/namespace.go @@ -118,7 +118,6 @@ func (ns Filter) roleBindingHack(obj *yaml.RNode, meta yaml.ResourceMeta) error // add the namespace to each "subject" with name: default err = obj.VisitElements(func(o *yaml.RNode) error { - // copied from kunstruct based kustomize NamespaceTransformer plugin // The only case we need to force the namespace // if for the "service account". "default" is // kind of hardcoded here for right now. diff --git a/vendor/sigs.k8s.io/kustomize/api/filters/patchstrategicmerge/patchstrategicmerge.go b/vendor/sigs.k8s.io/kustomize/api/filters/patchstrategicmerge/patchstrategicmerge.go index 3fa532df053..1a70d19aace 100644 --- a/vendor/sigs.k8s.io/kustomize/api/filters/patchstrategicmerge/patchstrategicmerge.go +++ b/vendor/sigs.k8s.io/kustomize/api/filters/patchstrategicmerge/patchstrategicmerge.go @@ -4,7 +4,6 @@ package patchstrategicmerge import ( - "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml/merge2" @@ -29,7 +28,7 @@ func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { if err != nil { return nil, err } - if !konfig.FlagEnableKyamlDefaultValue || r != nil { + if r != nil { result = append(result, r) } } diff --git a/vendor/sigs.k8s.io/kustomize/api/hasher/hasher.go b/vendor/sigs.k8s.io/kustomize/api/hasher/hasher.go index 36d930af69d..aef436d9192 100644 --- a/vendor/sigs.k8s.io/kustomize/api/hasher/hasher.go +++ b/vendor/sigs.k8s.io/kustomize/api/hasher/hasher.go @@ -20,12 +20,12 @@ func SortArrayAndComputeHash(s []string) (string, error) { if err != nil { return "", err } - return Encode(Hash(string(data))) + return encode(hex256(string(data))) } // Copied from https://github.com/kubernetes/kubernetes // /blob/master/pkg/kubectl/util/hash/hash.go -func Encode(hex string) (string, error) { +func encode(hex string) (string, error) { if len(hex) < 10 { return "", fmt.Errorf( "input length must be at least 10") @@ -48,23 +48,18 @@ func Encode(hex string) (string, error) { return string(enc), nil } -// Hash returns the hex form of the sha256 of the argument. -func Hash(data string) string { +// hex256 returns the hex form of the sha256 of the argument. +func hex256(data string) string { return fmt.Sprintf("%x", sha256.Sum256([]byte(data))) } -// HashRNode returns the hash value of input RNode -func HashRNode(node *yaml.RNode) (string, error) { - // get node kind - kindNode, err := node.Pipe(yaml.FieldMatcher{Name: "kind"}) - if err != nil { - return "", err - } - kind := kindNode.YNode().Value +// Hasher computes the hash of an RNode. +type Hasher struct{} - // calculate hash for different kinds - encoded := "" - switch kind { +// Hash returns a hash of the argument. +func (h *Hasher) Hash(node *yaml.RNode) (r string, err error) { + var encoded string + switch node.GetKind() { case "ConfigMap": encoded, err = encodeConfigMap(node) case "Secret": @@ -77,10 +72,11 @@ func HashRNode(node *yaml.RNode) (string, error) { if err != nil { return "", err } - return Encode(Hash(encoded)) + return encode(hex256(encoded)) } -func getNodeValues(node *yaml.RNode, paths []string) (map[string]interface{}, error) { +func getNodeValues( + node *yaml.RNode, paths []string) (map[string]interface{}, error) { values := make(map[string]interface{}) for _, p := range paths { vn, err := node.Pipe(yaml.Lookup(p)) @@ -117,8 +113,11 @@ func encodeConfigMap(node *yaml.RNode) (string, error) { if err != nil { return "", err } - m := map[string]interface{}{"kind": "ConfigMap", "name": values["metadata/name"], - "data": values["data"]} + m := map[string]interface{}{ + "kind": "ConfigMap", + "name": values["metadata/name"], + "data": values["data"], + } if _, ok := values["binaryData"].(map[string]interface{}); ok { m["binaryData"] = values["binaryData"] } diff --git a/vendor/sigs.k8s.io/kustomize/api/ifc/ifc.go b/vendor/sigs.k8s.io/kustomize/api/ifc/ifc.go index ee1ce0338be..9fd297478ad 100644 --- a/vendor/sigs.k8s.io/kustomize/api/ifc/ifc.go +++ b/vendor/sigs.k8s.io/kustomize/api/ifc/ifc.go @@ -5,8 +5,8 @@ package ifc import ( - "sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/yaml" ) // Validator provides functions to validate annotations and labels @@ -38,92 +38,10 @@ type Loader interface { Cleanup() error } -// Kunstructured represents a Kubernetes Resource Model object. -type Kunstructured interface { - // Several uses. - Copy() Kunstructured - - // GetAnnotations returns the k8s annotations. - GetAnnotations() map[string]string - - // GetData returns a top-level "data" field, as in a ConfigMap. - GetDataMap() map[string]string - - // GetData returns a top-level "binaryData" field, as in a ConfigMap. - GetBinaryDataMap() map[string]string - - // Used by ResAccumulator and ReplacementTransformer. - GetFieldValue(string) (interface{}, error) - - // Used by Resource.OrgId - GetGvk() resid.Gvk - - // Used by resource.Factory.SliceFromBytes - GetKind() string - - // GetLabels returns the k8s labels. - GetLabels() map[string]string - - // Used by Resource.CurId and resource factory. - GetName() string - - // Used by special case code in - // ResMap.SubsetThatCouldBeReferencedByResource - GetSlice(path string) ([]interface{}, error) - - // GetString returns the value of a string field. - // Used by Resource.GetNamespace - GetString(string) (string, error) - - // Several uses. - Map() (map[string]interface{}, error) - - // Used by Resource.AsYAML and Resource.String - MarshalJSON() ([]byte, error) - - // Used by resWrangler.Select - MatchesAnnotationSelector(selector string) (bool, error) - - // Used by resWrangler.Select - MatchesLabelSelector(selector string) (bool, error) - - // SetAnnotations replaces the k8s annotations. - SetAnnotations(map[string]string) - - // SetDataMap sets a top-level "data" field, as in a ConfigMap. - SetDataMap(map[string]string) - - // SetDataMap sets a top-level "binaryData" field, as in a ConfigMap. - SetBinaryDataMap(map[string]string) - // Used by PatchStrategicMergeTransformer. - SetGvk(resid.Gvk) - - // SetLabels replaces the k8s labels. - SetLabels(map[string]string) - - // SetName changes the name. - SetName(string) - - // SetNamespace changes the namespace. - SetNamespace(string) - - // Needed, for now, by kyaml/filtersutil.ApplyToJSON. - UnmarshalJSON([]byte) error -} - -// KunstructuredFactory makes instances of Kunstructured. -type KunstructuredFactory interface { - SliceFromBytes([]byte) ([]Kunstructured, error) - FromMap(m map[string]interface{}) Kunstructured - Hasher() KunstructuredHasher - MakeConfigMap(kvLdr KvLoader, args *types.ConfigMapArgs) (Kunstructured, error) - MakeSecret(kvLdr KvLoader, args *types.SecretArgs) (Kunstructured, error) -} - -// KunstructuredHasher returns a hash of the argument +// KustHasher returns a hash of the argument // or an error. -type KunstructuredHasher interface { - Hash(Kunstructured) (string, error) +type KustHasher interface { + Hash(*yaml.RNode) (string, error) } // See core.v1.SecretTypeOpaque diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/accumulator/loadconfigfromcrds.go b/vendor/sigs.k8s.io/kustomize/api/internal/accumulator/loadconfigfromcrds.go index a43f66d8fa7..d48c7a9dc0b 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/accumulator/loadconfigfromcrds.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/accumulator/loadconfigfromcrds.go @@ -25,7 +25,7 @@ type OpenAPIDefinition struct { Dependencies []string } -type myProperties map[string]spec.Schema +type myProperties = map[string]spec.Schema type nameToApiMap map[string]OpenAPIDefinition // LoadConfigFromCRDs parse CRD schemas from paths into a TransformerConfig diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/conflict/factory.go b/vendor/sigs.k8s.io/kustomize/api/internal/conflict/factory.go deleted file mode 100644 index 3cfed193a1b..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/internal/conflict/factory.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2020 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package conflict - -import ( - "sigs.k8s.io/kustomize/api/resid" - "sigs.k8s.io/kustomize/api/resource" -) - -type cdFactory struct{} - -var _ resource.ConflictDetectorFactory = &cdFactory{} - -// NewFactory returns a new conflict detector factory. -func NewFactory() resource.ConflictDetectorFactory { - return &cdFactory{} -} - -// New returns an instance of smPatchMergeOnlyDetector. -func (c cdFactory) New(_ resid.Gvk) (resource.ConflictDetector, error) { - return &smPatchMergeOnlyDetector{}, nil -} diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/conflict/smpatchmergeonlydetector.go b/vendor/sigs.k8s.io/kustomize/api/internal/conflict/smpatchmergeonlydetector.go deleted file mode 100644 index a33fdc3c38f..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/internal/conflict/smpatchmergeonlydetector.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2020 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package conflict - -import ( - "sigs.k8s.io/kustomize/api/resource" -) - -// smPatchMergeOnlyDetector ignores conflicts, -// but does real strategic merge patching. -// This is part of an effort to eliminate dependence on -// apimachinery package to allow kustomize integration -// into kubectl (#2506 and #1500) -type smPatchMergeOnlyDetector struct{} - -var _ resource.ConflictDetector = &smPatchMergeOnlyDetector{} - -func (c *smPatchMergeOnlyDetector) HasConflict( - _, _ *resource.Resource) (bool, error) { - return false, nil -} - -// There's at least one case that doesn't work. Suppose one has a -// Deployment with a volume with the bizarre "emptyDir: {}" entry. -// If you want to get rid of this entry via a patch containing -// the entry "emptyDir: null", then the following won't work, -// because null entries are eliminated. -func (c *smPatchMergeOnlyDetector) MergePatches( - r, patch *resource.Resource) (*resource.Resource, error) { - err := r.ApplySmPatch(patch) - return r, err -} diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go index aaa7c36004c..0cbdfbe2101 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/pkg/errors" + "sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers" "sigs.k8s.io/kustomize/api/internal/plugins/execplugin" @@ -29,11 +30,21 @@ import ( type Loader struct { pc *types.PluginConfig rf *resmap.Factory + fs filesys.FileSystem + + // absolutePluginHome caches the location of a valid plugin root directory. + // It should only be set once the directory's existence has been confirmed. + absolutePluginHome string } func NewLoader( - pc *types.PluginConfig, rf *resmap.Factory) *Loader { - return &Loader{pc: pc, rf: rf} + pc *types.PluginConfig, rf *resmap.Factory, fs filesys.FileSystem) *Loader { + return &Loader{pc: pc, rf: rf, fs: fs} +} + +// Config provides the global (not plugin specific) PluginConfig data. +func (l *Loader) Config() *types.PluginConfig { + return l.pc } func (l *Loader) LoadGenerators( @@ -95,13 +106,47 @@ func relativePluginPath(id resid.ResId) string { strings.ToLower(id.Kind)) } -func AbsolutePluginPath(pc *types.PluginConfig, id resid.ResId) string { - return filepath.Join( - pc.AbsPluginHome, relativePluginPath(id), id.Kind) +func (l *Loader) AbsolutePluginPath(id resid.ResId) (string, error) { + pluginHome, err := l.absPluginHome() + if err != nil { + return "", err + } + return filepath.Join(pluginHome, relativePluginPath(id), id.Kind), nil } -func (l *Loader) absolutePluginPath(id resid.ResId) string { - return AbsolutePluginPath(l.pc, id) +// absPluginHome is the home of kustomize Exec and Go plugins. +// Kustomize plugin configuration files are k8s-style objects +// containing the fields 'apiVersion' and 'kind', e.g. +// apiVersion: apps/v1 +// kind: Deployment +// kustomize reads plugin configuration data from a file path +// specified in the 'generators:' or 'transformers:' field of a +// kustomization file. For Exec and Go plugins, kustomize +// uses this data to both locate the plugin and configure it. +// Each Exec or Go plugin (its code, its tests, its supporting data +// files, etc.) must be housed in its own directory at +// ${absPluginHome}/${pluginApiVersion}/LOWERCASE(${pluginKind}) +// where +// - ${absPluginHome} is an absolute path, defined below. +// - ${pluginApiVersion} is taken from the plugin config file. +// - ${pluginKind} is taken from the plugin config file. +func (l *Loader) absPluginHome() (string, error) { + // External plugins are disabled--return the dummy plugin root. + if l.pc.PluginRestrictions != types.PluginRestrictionsNone { + return konfig.NoPluginHomeSentinal, nil + } + // We've already determined plugin home--use the cached value. + if l.absolutePluginHome != "" { + return l.absolutePluginHome, nil + } + + // Check default locations for a valid plugin root, and cache it if found. + dir, err := konfig.DefaultAbsPluginHome(l.fs) + if err != nil { + return "", err + } + l.absolutePluginHome = dir + return l.absolutePluginHome, nil } func isBuiltinPlugin(res *resource.Resource) bool { @@ -148,7 +193,7 @@ func (l *Loader) loadAndConfigurePlugin( if err != nil { return nil, errors.Wrapf(err, "marshalling yaml from res %s", res.OrgId()) } - err = c.Config(resmap.NewPluginHelpers(ldr, v, l.rf), yaml) + err = c.Config(resmap.NewPluginHelpers(ldr, v, l.rf, l.pc), yaml) if err != nil { return nil, errors.Wrapf( err, "plugin %s fails configuration", res.OrgId()) @@ -176,10 +221,13 @@ func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) } func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, error) { + absPluginPath, err := l.AbsolutePluginPath(resId) + if err != nil { + return nil, err + } // First try to load the plugin as an executable. - p := execplugin.NewExecPlugin(l.absolutePluginPath(resId)) - err := p.ErrIfNotExecutable() - if err == nil { + p := execplugin.NewExecPlugin(absPluginPath) + if err = p.ErrIfNotExecutable(); err == nil { return p, nil } if !os.IsNotExist(err) { @@ -193,7 +241,7 @@ func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, err return nil, err } // Failing the above, try loading it as a Go plugin. - c, err := l.loadGoPlugin(resId) + c, err := l.loadGoPlugin(resId, absPluginPath+".so") if err != nil { return nil, err } @@ -208,12 +256,11 @@ func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, err // as a Loader instance variable. So make it a package variable. var registry = make(map[string]resmap.Configurable) -func (l *Loader) loadGoPlugin(id resid.ResId) (resmap.Configurable, error) { +func (l *Loader) loadGoPlugin(id resid.ResId, absPath string) (resmap.Configurable, error) { regId := relativePluginPath(id) if c, ok := registry[regId]; ok { return copyPlugin(c), nil } - absPath := l.absolutePluginPath(id) + ".so" if !utils.FileExists(absPath) { return nil, fmt.Errorf( "expected file with Go object code at: %s", absPath) diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/utils/utils.go b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/utils/utils.go index 12dd6e89f05..7fa46119144 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/utils/utils.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/utils/utils.go @@ -34,7 +34,7 @@ func GoBin() string { // has her ${g}/${v}/$lower(${k})/${k}.go files. func DeterminePluginSrcRoot(fSys filesys.FileSystem) (string, error) { return konfig.FirstDirThatExistsElseError( - "source directory", fSys, []konfig.NotedFunc{ + "plugin src root", fSys, []konfig.NotedFunc{ { Note: "relative to unit test", F: func() string { diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go index acc3d131631..efbb71ea61e 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go @@ -443,7 +443,10 @@ func (kt *KustTarget) configureBuiltinPlugin( err, "builtin %s marshal", bpt) } } - err = p.Config(resmap.NewPluginHelpers(kt.ldr, kt.validator, kt.rFactory), y) + err = p.Config( + resmap.NewPluginHelpers( + kt.ldr, kt.validator, kt.rFactory, kt.pLdr.Config()), + y) if err != nil { return errors.Wrapf( err, "trouble configuring builtin %s with config: `\n%s`", bpt, string(y)) diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go index 640cc742add..2715af471f4 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go @@ -112,16 +112,22 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( return }, - builtinhelpers.HelmChartInflationGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( + builtinhelpers.HelmChartInflationGenerator: func( + kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( result []resmap.Generator, err error) { var c struct { - types.HelmChartArgs + types.HelmGlobals + types.HelmChart } - for _, args := range kt.kustomization.HelmChartInflationGenerator { - c.HelmChartArgs = args + var globals types.HelmGlobals + if kt.kustomization.HelmGlobals != nil { + globals = *kt.kustomization.HelmGlobals + } + for _, chart := range kt.kustomization.HelmCharts { + c.HelmGlobals = globals + c.HelmChart = chart p := f() - err := kt.configureBuiltinPlugin(p, c, bpt) - if err != nil { + if err = kt.configureBuiltinPlugin(p, c, bpt); err != nil { return nil, err } result = append(result, p) @@ -201,14 +207,16 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( return } var c struct { - Path string `json:"path,omitempty" yaml:"path,omitempty"` - Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` - Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` + Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` + Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` } for _, pc := range kt.kustomization.Patches { c.Target = pc.Target c.Patch = pc.Patch c.Path = pc.Path + c.Options = pc.Options p := f() err = kt.configureBuiltinPlugin(p, c, bpt) if err != nil { @@ -221,6 +229,31 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.LabelTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + for _, label := range kt.kustomization.Labels { + var c struct { + Labels map[string]string + FieldSpecs []types.FieldSpec + } + c.Labels = label.Pairs + fss := types.FsSlice(label.FieldSpecs) + // merge the custom fieldSpecs with the default + if label.IncludeSelectors { + fss, err = fss.MergeAll(tc.CommonLabels) + } else { + // only add to metadata by default + fss, err = fss.MergeOne(types.FieldSpec{Path: "metadata/labels", CreateIfNotPresent: true}) + } + if err != nil { + return nil, err + } + c.FieldSpecs = fss + p := f() + err = kt.configureBuiltinPlugin(p, c, bpt) + if err != nil { + return nil, err + } + result = append(result, p) + } var c struct { Labels map[string]string FieldSpecs []types.FieldSpec diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/target/multitransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/target/multitransformer.go index 1896bdf0474..caf1bd2de49 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/target/multitransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/target/multitransformer.go @@ -4,15 +4,12 @@ package target import ( - "fmt" - "sigs.k8s.io/kustomize/api/resmap" ) // multiTransformer contains a list of transformers. type multiTransformer struct { - transformers []resmap.Transformer - checkConflictEnabled bool + transformers []resmap.Transformer } var _ resmap.Transformer = &multiTransformer{} @@ -20,8 +17,8 @@ var _ resmap.Transformer = &multiTransformer{} // newMultiTransformer constructs a multiTransformer. func newMultiTransformer(t []resmap.Transformer) resmap.Transformer { r := &multiTransformer{ - transformers: make([]resmap.Transformer, len(t)), - checkConflictEnabled: false} + transformers: make([]resmap.Transformer, len(t)), + } copy(r.transformers, t) return r } @@ -29,57 +26,11 @@ func newMultiTransformer(t []resmap.Transformer) resmap.Transformer { // Transform applies the member transformers in order to the resources, // optionally detecting and erroring on commutation conflict. func (o *multiTransformer) Transform(m resmap.ResMap) error { - if o.checkConflictEnabled { - return o.transformWithCheckConflict(m) - } - return o.transform(m) -} - -func (o *multiTransformer) transform(m resmap.ResMap) error { for _, t := range o.transformers { - err := t.Transform(m) - if err != nil { + if err := t.Transform(m); err != nil { return err } - } - for _, r := range m.Resources() { - empty, err := r.IsEmpty() - if err != nil { - return err - } - if empty { - err := m.Remove(r.CurId()) - if err != nil { - return err - } - } + m.DropEmpties() } return nil } - -// Of the len(o.transformers)! possible transformer orderings, compare to a reversed order. -// A spot check to perform when the transformations are supposed to be commutative. -// Fail if there's a difference in the result. -func (o *multiTransformer) transformWithCheckConflict(m resmap.ResMap) error { - mcopy := m.DeepCopy() - err := o.transform(m) - if err != nil { - return err - } - o.reverseTransformers() - err = o.transform(mcopy) - if err != nil { - return err - } - err = m.ErrorIfNotEqualSets(mcopy) - if err != nil { - return fmt.Errorf("found conflict between different patches\n%v", err) - } - return nil -} - -func (o *multiTransformer) reverseTransformers() { - for i, j := 0, len(o.transformers)-1; i < j; i, j = i+1, j-1 { - o.transformers[i], o.transformers[j] = o.transformers[j], o.transformers[i] - } -} diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/factory.go b/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/factory.go deleted file mode 100644 index b155ed3c66f..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/factory.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2020 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package wrappy - -import ( - "fmt" - - "sigs.k8s.io/kustomize/api/hasher" - "sigs.k8s.io/kustomize/api/ifc" - "sigs.k8s.io/kustomize/api/internal/generators" - "sigs.k8s.io/kustomize/api/konfig" - "sigs.k8s.io/kustomize/api/types" - "sigs.k8s.io/kustomize/kyaml/filtersutil" - "sigs.k8s.io/kustomize/kyaml/kio" - "sigs.k8s.io/kustomize/kyaml/yaml" -) - -// WNodeFactory makes instances of WNode. -// -// These instances in turn adapt -// sigs.k8s.io/kustomize/kyaml/yaml.RNode -// to implement ifc.Unstructured. -// This factory is meant to implement ifc.KunstructuredFactory. -// -// This implementation should be thin, as both WNode and WNodeFactory must be -// factored away (deleted) along with ifc.Kunstructured in favor of direct use -// of RNode methods upon completion of -// https://github.com/kubernetes-sigs/kustomize/issues/2506. -// -// See also api/krusty/internal/provider/depprovider.go -type WNodeFactory struct { -} - -var _ ifc.KunstructuredFactory = (*WNodeFactory)(nil) - -func (k *WNodeFactory) SliceFromBytes(bs []byte) ([]ifc.Kunstructured, error) { - yamlRNodes, err := kio.FromBytes(bs) - if err != nil { - return nil, err - } - var result []ifc.Kunstructured - for i := range yamlRNodes { - rn := yamlRNodes[i] - meta, err := rn.GetValidatedMetadata() - if err != nil { - return nil, err - } - if !shouldDropObject(meta) { - if foundNil, path := rn.HasNilEntryInList(); foundNil { - return nil, fmt.Errorf("empty item at %v in object %v", path, rn) - } - result = append(result, FromRNode(rn)) - } - } - return result, nil -} - -// shouldDropObject returns true if the resource should not be accumulated. -func shouldDropObject(m yaml.ResourceMeta) bool { - _, y := m.ObjectMeta.Annotations[konfig.IgnoredByKustomizeAnnotation] - return y -} - -func (k *WNodeFactory) FromMap(m map[string]interface{}) ifc.Kunstructured { - rn, err := FromMap(m) - if err != nil { - // TODO(#WNodeFactory): handle or bubble error" - panic(err) - } - return rn -} - -// kustHash computes a hash of an unstructured object. -type kustHash struct{} - -// Hash returns a hash of the given object -func (h *kustHash) Hash(m ifc.Kunstructured) (string, error) { - node, err := filtersutil.GetRNode(m) - if err != nil { - return "", err - } - return hasher.HashRNode(node) -} - -func (k *WNodeFactory) Hasher() ifc.KunstructuredHasher { - return &kustHash{} -} - -// MakeConfigMap makes a wrapped configmap. -func (k *WNodeFactory) MakeConfigMap( - ldr ifc.KvLoader, args *types.ConfigMapArgs) (ifc.Kunstructured, error) { - rn, err := generators.MakeConfigMap(ldr, args) - if err != nil { - return nil, err - } - return FromRNode(rn), nil -} - -// MakeSecret makes a wrapped secret. -func (k *WNodeFactory) MakeSecret( - ldr ifc.KvLoader, args *types.SecretArgs) (ifc.Kunstructured, error) { - rn, err := generators.MakeSecret(ldr, args) - if err != nil { - return nil, err - } - return FromRNode(rn), nil -} diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/wnode.go b/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/wnode.go deleted file mode 100644 index 81a35d1745f..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/internal/wrappy/wnode.go +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2020 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package wrappy - -import ( - "fmt" - "log" - "regexp" - "strconv" - "strings" - - "sigs.k8s.io/kustomize/api/ifc" - "sigs.k8s.io/kustomize/api/resid" - "sigs.k8s.io/kustomize/kyaml/yaml" -) - -// WNode implements ifc.Kunstructured using yaml.RNode. -// -// It exists only to help manage a switch from -// kunstruct.UnstructAdapter to yaml.RNode as the core -// representation of KRM objects in kustomize. -// -// It's got a silly name because we don't want it around for long, -// and want its use to be obvious. -type WNode struct { - node *yaml.RNode -} - -var _ ifc.Kunstructured = (*WNode)(nil) - -func NewWNode() *WNode { - return FromRNode(yaml.NewRNode(nil)) -} - -func FromMap(m map[string]interface{}) (*WNode, error) { - n, err := yaml.FromMap(m) - if err != nil { - return nil, err - } - return FromRNode(n), nil -} - -func FromRNode(node *yaml.RNode) *WNode { - return &WNode{node: node} -} - -func (wn *WNode) AsRNode() *yaml.RNode { - return wn.node -} - -func (wn *WNode) demandMetaData(label string) yaml.ResourceMeta { - meta, err := wn.node.GetMeta() - if err != nil { - // Log and die since interface doesn't allow error. - log.Fatalf("for %s', expected valid resource: %v", label, err) - } - return meta -} - -// Copy implements ifc.Kunstructured. -func (wn *WNode) Copy() ifc.Kunstructured { - return &WNode{node: wn.node.Copy()} -} - -// GetAnnotations implements ifc.Kunstructured. -func (wn *WNode) GetAnnotations() map[string]string { - return wn.demandMetaData("GetAnnotations").Annotations -} - -// convertSliceIndex traverses the items in `fields` and find -// if there is a slice index in the item and change it to a -// valid Lookup field path. For example, 'ports[0]' will be -// converted to 'ports' and '0'. -func convertSliceIndex(fields []string) []string { - var res []string - for _, s := range fields { - if !strings.HasSuffix(s, "]") { - res = append(res, s) - continue - } - re := regexp.MustCompile(`^(.*)\[(\d+)\]$`) - groups := re.FindStringSubmatch(s) - if len(groups) == 0 { - // no match, add to result - res = append(res, s) - continue - } - if groups[1] != "" { - res = append(res, groups[1]) - } - res = append(res, groups[2]) - } - return res -} - -// GetFieldValue implements ifc.Kunstructured. -func (wn *WNode) GetFieldValue(path string) (interface{}, error) { - fields := convertSliceIndex(strings.Split(path, ".")) - rn, err := wn.node.Pipe(yaml.Lookup(fields...)) - if err != nil { - return nil, err - } - if rn == nil { - return nil, NoFieldError{path} - } - yn := rn.YNode() - - // If this is an alias node, resolve it - if yn.Kind == yaml.AliasNode { - yn = yn.Alias - } - - // Return value as map for DocumentNode and MappingNode kinds - if yn.Kind == yaml.DocumentNode || yn.Kind == yaml.MappingNode { - var result map[string]interface{} - if err := yn.Decode(&result); err != nil { - return nil, err - } - return result, err - } - - // Return value as slice for SequenceNode kind - if yn.Kind == yaml.SequenceNode { - var result []interface{} - if err := yn.Decode(&result); err != nil { - return nil, err - } - return result, nil - } - if yn.Kind != yaml.ScalarNode { - return nil, fmt.Errorf("expected ScalarNode, got Kind=%d", yn.Kind) - } - - // TODO: When doing kustomize var replacement, which is likely a - // a primary use of this function and the reason it returns interface{} - // rather than string, we do conversion from Nodes to Go types and back - // to nodes. We should figure out how to do replacement using raw nodes, - // assuming we keep the var feature in kustomize. - // The other end of this is: refvar.go:updateNodeValue. - switch yn.Tag { - case yaml.NodeTagString: - return yn.Value, nil - case yaml.NodeTagInt: - return strconv.Atoi(yn.Value) - case yaml.NodeTagFloat: - return strconv.ParseFloat(yn.Value, 64) - case yaml.NodeTagBool: - return strconv.ParseBool(yn.Value) - default: - // Possibly this should be an error or log. - return yn.Value, nil - } -} - -// GetGvk implements ifc.Kunstructured. -func (wn *WNode) GetGvk() resid.Gvk { - meta := wn.demandMetaData("GetGvk") - g, v := resid.ParseGroupVersion(meta.APIVersion) - return resid.Gvk{Group: g, Version: v, Kind: meta.Kind} -} - -// GetDataMap implements ifc.Kunstructured. -func (wn *WNode) GetDataMap() map[string]string { - return wn.node.GetDataMap() -} - -// SetDataMap implements ifc.Kunstructured. -func (wn *WNode) SetDataMap(m map[string]string) { - wn.node.SetDataMap(m) -} - -// GetBinaryDataMap implements ifc.Kunstructured. -func (wn *WNode) GetBinaryDataMap() map[string]string { - return wn.node.GetBinaryDataMap() -} - -// SetBinaryDataMap implements ifc.Kunstructured. -func (wn *WNode) SetBinaryDataMap(m map[string]string) { - wn.node.SetBinaryDataMap(m) -} - -// GetKind implements ifc.Kunstructured. -func (wn *WNode) GetKind() string { - return wn.demandMetaData("GetKind").Kind -} - -// GetLabels implements ifc.Kunstructured. -func (wn *WNode) GetLabels() map[string]string { - return wn.demandMetaData("GetLabels").Labels -} - -// GetName implements ifc.Kunstructured. -func (wn *WNode) GetName() string { - return wn.demandMetaData("GetName").Name -} - -// GetSlice implements ifc.Kunstructured. -func (wn *WNode) GetSlice(path string) ([]interface{}, error) { - value, err := wn.GetFieldValue(path) - if err != nil { - return nil, err - } - if sliceValue, ok := value.([]interface{}); ok { - return sliceValue, nil - } - return nil, fmt.Errorf("node %s is not a slice", path) -} - -// GetSlice implements ifc.Kunstructured. -func (wn *WNode) GetString(path string) (string, error) { - value, err := wn.GetFieldValue(path) - if err != nil { - return "", err - } - if v, ok := value.(string); ok { - return v, nil - } - return "", fmt.Errorf("node %s is not a string: %v", path, value) -} - -// Map implements ifc.Kunstructured. -func (wn *WNode) Map() (map[string]interface{}, error) { - return wn.node.Map() -} - -// MarshalJSON implements ifc.Kunstructured. -func (wn *WNode) MarshalJSON() ([]byte, error) { - return wn.node.MarshalJSON() -} - -// MatchesAnnotationSelector implements ifc.Kunstructured. -func (wn *WNode) MatchesAnnotationSelector(selector string) (bool, error) { - return wn.node.MatchesAnnotationSelector(selector) -} - -// MatchesLabelSelector implements ifc.Kunstructured. -func (wn *WNode) MatchesLabelSelector(selector string) (bool, error) { - return wn.node.MatchesLabelSelector(selector) -} - -// SetAnnotations implements ifc.Kunstructured. -func (wn *WNode) SetAnnotations(annotations map[string]string) { - if err := wn.node.SetAnnotations(annotations); err != nil { - log.Fatal(err) // interface doesn't allow error. - } -} - -// SetGvk implements ifc.Kunstructured. -func (wn *WNode) SetGvk(gvk resid.Gvk) { - wn.setMapField(yaml.NewScalarRNode(gvk.Kind), yaml.KindField) - wn.setMapField(yaml.NewScalarRNode(gvk.ApiVersion()), yaml.APIVersionField) -} - -// SetLabels implements ifc.Kunstructured. -func (wn *WNode) SetLabels(labels map[string]string) { - if err := wn.node.SetLabels(labels); err != nil { - log.Fatal(err) // interface doesn't allow error. - } -} - -// SetName implements ifc.Kunstructured. -func (wn *WNode) SetName(name string) { - wn.setMapField(yaml.NewScalarRNode(name), yaml.MetadataField, yaml.NameField) -} - -// SetNamespace implements ifc.Kunstructured. -func (wn *WNode) SetNamespace(ns string) { - if err := wn.node.SetNamespace(ns); err != nil { - log.Fatal(err) // interface doesn't allow error. - } -} - -func (wn *WNode) setMapField(value *yaml.RNode, path ...string) { - if err := wn.node.SetMapField(value, path...); err != nil { - // Log and die since interface doesn't allow error. - log.Fatalf("failed to set field %v: %v", path, err) - } -} - -// UnmarshalJSON implements ifc.Kunstructured. -func (wn *WNode) UnmarshalJSON(data []byte) error { - return wn.node.UnmarshalJSON(data) -} - -type NoFieldError struct { - Field string -} - -func (e NoFieldError) Error() string { - return fmt.Sprintf("no field named '%s'", e.Field) -} diff --git a/vendor/sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts/namespace.go b/vendor/sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts/namespace.go index 2a922b25a82..a35ef9c6f7d 100644 --- a/vendor/sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts/namespace.go +++ b/vendor/sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts/namespace.go @@ -19,5 +19,8 @@ namespace: group: apiregistration.k8s.io kind: APIService create: true +- path: spec/conversion/webhook/clientConfig/service/namespace + group: apiextensions.k8s.io + kind: CustomResourceDefinition ` ) diff --git a/vendor/sigs.k8s.io/kustomize/api/konfig/general.go b/vendor/sigs.k8s.io/kustomize/api/konfig/general.go index 40167bae09b..6c86391df97 100644 --- a/vendor/sigs.k8s.io/kustomize/api/konfig/general.go +++ b/vendor/sigs.k8s.io/kustomize/api/konfig/general.go @@ -19,31 +19,7 @@ func DefaultKustomizationFileName() string { return RecognizedKustomizationFileNames()[0] } -// IfApiMachineryElseKyaml returns true if executing the apimachinery code -// path, else we're executing the kyaml code paths. -func IfApiMachineryElseKyaml(s1, s2 string) string { - if !FlagEnableKyamlDefaultValue { - return s1 - } - return s2 -} - const ( - // FlagEnableKyamlDefaultValue is the default value for the --enable_kyaml - // flag. This value is also used in unit tests. See provider.DepProvider. - // - // TODO(#3588): Delete this constant. - // - // All tests should pass for either true or false values - // of this constant, without having to check its value. - // In the cases where there's a different outcome, either decide - // that the difference is acceptable, or make the difference go away. - // - // Historically, tests passed for enable_kyaml == false, i.e. using - // apimachinery libs. This doesn't mean the code was better, it just - // means regression tests preserved those outcomes. - FlagEnableKyamlDefaultValue = true - // An environment variable to consult for kustomization // configuration data. See: // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html diff --git a/vendor/sigs.k8s.io/kustomize/api/konfig/plugins.go b/vendor/sigs.k8s.io/kustomize/api/konfig/plugins.go index a42e5e296af..0615f1768fa 100644 --- a/vendor/sigs.k8s.io/kustomize/api/konfig/plugins.go +++ b/vendor/sigs.k8s.io/kustomize/api/konfig/plugins.go @@ -41,32 +41,6 @@ const ( NoPluginHomeSentinal = "/No/non-builtin/plugins!" ) -func EnabledPluginConfig(b types.BuiltinPluginLoadingOptions) (*types.PluginConfig, error) { - dir, err := DefaultAbsPluginHome(filesys.MakeFsOnDisk()) - if err != nil { - return nil, err - } - return MakePluginConfig(types.PluginRestrictionsNone, b, dir), nil -} - -func DisabledPluginConfig() *types.PluginConfig { - return MakePluginConfig( - types.PluginRestrictionsBuiltinsOnly, - types.BploUseStaticallyLinked, - NoPluginHomeSentinal) -} - -func MakePluginConfig( - pr types.PluginRestrictions, - b types.BuiltinPluginLoadingOptions, - home string) *types.PluginConfig { - return &types.PluginConfig{ - PluginRestrictions: pr, - AbsPluginHome: home, - BpLoadingOptions: b, - } -} - type NotedFunc struct { Note string F func() string @@ -77,7 +51,7 @@ type NotedFunc struct { // the home of kustomize plugins. func DefaultAbsPluginHome(fSys filesys.FileSystem) (string, error) { return FirstDirThatExistsElseError( - "plugin home directory", fSys, []NotedFunc{ + "plugin root", fSys, []NotedFunc{ { Note: "homed in $" + KustomizePluginHomeEnv, F: func() string { @@ -87,9 +61,11 @@ func DefaultAbsPluginHome(fSys filesys.FileSystem) (string, error) { { Note: "homed in $" + XdgConfigHomeEnv, F: func() string { - return filepath.Join( - os.Getenv(XdgConfigHomeEnv), - ProgramName, RelPluginHome) + if root := os.Getenv(XdgConfigHomeEnv); root != "" { + return filepath.Join(root, ProgramName, RelPluginHome) + } + // do not look in "kustomize/plugin" if XdgConfigHomeEnv is unset + return "" }, }, { @@ -118,11 +94,14 @@ func FirstDirThatExistsElseError( pathFuncs []NotedFunc) (string, error) { var nope []types.Pair for _, dt := range pathFuncs { - dir := dt.F() - if fSys.Exists(dir) { - return dir, nil + if dir := dt.F(); dir != "" { + if fSys.Exists(dir) { + return dir, nil + } + nope = append(nope, types.Pair{Key: dt.Note, Value: dir}) + } else { + nope = append(nope, types.Pair{Key: dt.Note, Value: ""}) } - nope = append(nope, types.Pair{Key: dt.Note, Value: dir}) } return "", types.NewErrUnableToFind(what, nope) } diff --git a/vendor/sigs.k8s.io/kustomize/api/krusty/kustomizer.go b/vendor/sigs.k8s.io/kustomize/api/krusty/kustomizer.go index 8120f9351f6..08af7ee7532 100644 --- a/vendor/sigs.k8s.io/kustomize/api/krusty/kustomizer.go +++ b/vendor/sigs.k8s.io/kustomize/api/krusty/kustomizer.go @@ -36,7 +36,7 @@ type Kustomizer struct { func MakeKustomizer(o *Options) *Kustomizer { return &Kustomizer{ options: o, - depProvider: provider.NewDepProvider(o.UseKyaml), + depProvider: provider.NewDepProvider(), } } @@ -52,9 +52,7 @@ func MakeKustomizer(o *Options) *Kustomizer { // and Run can be called on each of them). func (b *Kustomizer) Run( fSys filesys.FileSystem, path string) (resmap.ResMap, error) { - resmapFactory := resmap.NewFactory( - b.depProvider.GetResourceFactory(), - b.depProvider.GetConflictDetectorFactory()) + resmapFactory := resmap.NewFactory(b.depProvider.GetResourceFactory()) lr := fLdr.RestrictionNone if b.options.LoadRestrictions == types.LoadRestrictionsRootOnly { lr = fLdr.RestrictionRootOnly @@ -68,7 +66,8 @@ func (b *Kustomizer) Run( ldr, b.depProvider.GetFieldValidator(), resmapFactory, - pLdr.NewLoader(b.options.PluginConfig, resmapFactory), + // The plugin configs are always located on disk, regardless of the fSys passed in + pLdr.NewLoader(b.options.PluginConfig, resmapFactory, filesys.MakeFsOnDisk()), ) err = kt.Load() if err != nil { diff --git a/vendor/sigs.k8s.io/kustomize/api/krusty/options.go b/vendor/sigs.k8s.io/kustomize/api/krusty/options.go index 91d7fac053f..438f6c10290 100644 --- a/vendor/sigs.k8s.io/kustomize/api/krusty/options.go +++ b/vendor/sigs.k8s.io/kustomize/api/krusty/options.go @@ -5,7 +5,6 @@ package krusty import ( "sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers" - "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/types" ) @@ -33,37 +32,19 @@ type Options struct { // Options related to kustomize plugins. PluginConfig *types.PluginConfig - - // TODO(#3588): Delete this field (it's always true). - // When true, use kyaml/ packages to manipulate KRM yaml. - // When false, use k8sdeps/ instead (uses k8s.io/api* packages). - UseKyaml bool - - // When true, allow name and kind changing via a patch - // When false, patch name/kind don't overwrite target name/kind - AllowResourceIdChanges bool } // MakeDefaultOptions returns a default instance of Options. func MakeDefaultOptions() *Options { return &Options{ - DoLegacyResourceSort: false, - AddManagedbyLabel: false, - LoadRestrictions: types.LoadRestrictionsRootOnly, - DoPrune: false, - PluginConfig: konfig.DisabledPluginConfig(), - UseKyaml: konfig.FlagEnableKyamlDefaultValue, - AllowResourceIdChanges: false, + DoLegacyResourceSort: false, + AddManagedbyLabel: false, + LoadRestrictions: types.LoadRestrictionsRootOnly, + DoPrune: false, + PluginConfig: types.DisabledPluginConfig(), } } -func (o Options) IfApiMachineryElseKyaml(s1, s2 string) string { - if !o.UseKyaml { - return s1 - } - return s2 -} - // GetBuiltinPluginNames returns a list of builtin plugin names func GetBuiltinPluginNames() []string { var ret []string diff --git a/vendor/sigs.k8s.io/kustomize/api/loader/fileloader.go b/vendor/sigs.k8s.io/kustomize/api/loader/fileloader.go index 9e8412de4c7..e0fa2807f55 100644 --- a/vendor/sigs.k8s.io/kustomize/api/loader/fileloader.go +++ b/vendor/sigs.k8s.io/kustomize/api/loader/fileloader.go @@ -319,7 +319,6 @@ func (fl *fileLoader) Load(path string) ([]byte, error) { } return body, nil } - if !filepath.IsAbs(path) { path = fl.root.Join(path) } diff --git a/vendor/sigs.k8s.io/kustomize/api/provider/depprovider.go b/vendor/sigs.k8s.io/kustomize/api/provider/depprovider.go index 4bd567f3ee1..0102c89ce01 100644 --- a/vendor/sigs.k8s.io/kustomize/api/provider/depprovider.go +++ b/vendor/sigs.k8s.io/kustomize/api/provider/depprovider.go @@ -4,198 +4,39 @@ package provider import ( - "log" - + "sigs.k8s.io/kustomize/api/hasher" "sigs.k8s.io/kustomize/api/ifc" - "sigs.k8s.io/kustomize/api/internal/conflict" "sigs.k8s.io/kustomize/api/internal/validate" - "sigs.k8s.io/kustomize/api/internal/wrappy" - "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/resource" ) -// DepProvider is a dependency provider. -// -// The instances it returns are either -// - old implementations backed by k8sdeps code, -// - new implementations backed by kyaml code. -// -// History: -// -// kubectl depends on k8s.io code, and at the time of writing, so -// does kustomize. Code that imports k8s.io/api* cannot be imported -// back into k8s.io/*, yet kustomize appears inside k8s.io/kubectl. -// -// To allow kustomize to appear inside kubectl, yet still be developed -// outside kubectl, the kustomize code was divided into the following -// packages -// -// api/ -// k8sdeps/ (and internal/ks8deps/) -// ifc/ -// krusty/ -// everythingElse/ -// -// with the following rules: -// -// - Only k8sdeps/ may import k8s.io/api*. -// -// - Only krusty/ (and its internals) may import k8sdeps/. -// I.e., ifc/ and everythingElse/ must not -// import k8sdeps/ or k8s.io/api*. -// -// - Code in krusty/ may use code in k8sdeps/ to create -// objects then inject said objects into -// everythingElse/ behind dependency neutral interfaces. -// -// The idea was to periodically copy, not import, the large k8sdeps/ -// tree (plus a snippet from krusty/kustomizer.go) into the kubectl -// codebase via a large PR, and have kubectl depend on the rest via -// normal importing. -// -// Over 2019, however, kubectl underwent large changes including -// a switch to Go modules, and a concerted attempt to extract kubectl -// from the k8s repo. This made large kustomize integration PRs too -// intrusive to review. -// -// In 2020, kubectl is based on Go modules, and almost entirely -// extracted from the k8s.io repositories, and further the kyaml -// library has a appeared as a viable replacement to k8s.io/api* -// KRM manipulation code. -// -// The new plan is to eliminate k8sdeps/ entirely, along with its -// k8s.io/api* dependence, allowing kustomize code to be imported -// into kubectl via normal Go module imports. Then the kustomize API -// code can then move into the github.com/kubernetes-sigs/cli-utils -// repo. The kustomize CLI in github.com/kubernetes-sigs/kustomize -// and the kubectl CLI can then both depend on the kustomize API. -// -// So, all code that depends on k8sdeps must go behind interfaces, -// and kustomize must be factored to choose the implementation. -// -// That problem has been reduced to three interfaces, each having -// two implementations. (1) is k8sdeps-based, (2) is kyaml-based. -// -// - ifc.Kunstructured -// -// 1) api/k8sdeps/kunstruct.UnstructAdapter -// -// This adapts structs in -// k8s.io/apimachinery/pkg/apis/meta/v1/unstructured -// to ifc.Kunstructured. -// -// 2) api/wrappy.WNode -// -// This adapts sigs.k8s.io/kustomize/kyaml/yaml.RNode -// to ifc.Unstructured. -// -// At time of writing, implementation started. -// Further reducing the size of ifc.Kunstructed -// would really reduce the work -// (e.g. drop Vars, drop ReplacementTranformer). -// -// - resource.ConflictDetector -// -// 1) api/internal/k8sdeps/conflict.conflictDetectorJson -// api/internal/k8sdeps/conflict.conflictDetectorSm -// -// Uses k8s.io/apimachinery/pkg/util/strategicpatch, -// apimachinery/pkg/util/mergepatch, etc. to merge -// resource.Resource instances. -// -// 2) api/internal/conflict.smPatchMergeOnlyDetector -// -// At time of writing, this doesn't report conflicts, -// but it does know how to merge patches. Conflict -// reporting isn't vital to kustomize function. It's -// rare that a person would configure one transformer -// with many patches, much less so many that it became -// hard to spot conflicts. In the case of an undetected -// conflict, the last patch applied wins, likely what -// the user wants anyway. Regardless, the effect of this -// is plainly visible and usable in the output, even if -// a conflict happened but wasn't reported as an error. -// -// - ifc.Validator -// -// 1) api/k8sdeps/validator.KustValidator -// -// Uses k8s.io/apimachinery/pkg/api/validation and -// friends to validate strings. -// -// 2) api/internal/validate.FieldValidator -// -// See TODO inside the validator for status. -// At time of writing, this is a do-nothing -// validator as it's not critical to kustomize function. -// -// Proposed plan: -// [x] Ship kustomize with the ability to switch from 1 to 2 via -// an --enable_kyaml flag. -// [x] Make --enable_kyaml true by default. -// [x] When 2 is not noticeably more buggy than 1, delete 1. -// I.e. delete k8sdeps/, transitively deleting all k8s.io/api* deps. -// This DepProvider should be left in place to retain these -// comments, but it will have only one choice. -// [x] The way is now clear to reintegrate into kubectl. -// This should be done ASAP; the last step is cleanup. -// [ ] Cleanup. With only one impl of Kunstructure remaining, -// that interface and WNode can be deleted, along with this -// DepProvider. The other two interfaces could be dropped too. -// -// When the above is done, kustomize will use yaml.RNode and/or -// KRM Config Functions directly and exclusively. -// If you're reading this, plan not done. -// +// DepProvider is a dependency provider, injecting different +// implementations depending on the context. type DepProvider struct { - kFactory ifc.KunstructuredFactory - resourceFactory *resource.Factory - conflictDectectorFactory resource.ConflictDetectorFactory - fieldValidator ifc.Validator + resourceFactory *resource.Factory + // implemented by api/internal/validate.FieldValidator + // See TODO inside the validator for status. + // At time of writing, this is a do-nothing + // validator as it's not critical to kustomize function. + fieldValidator ifc.Validator } -// The dependencies this method needs have been deleted - -// see comments above. This method will be deleted -// along with DepProvider in the final step. -func makeK8sdepBasedInstances() *DepProvider { - log.Fatal("This binary cannot use k8s.io code; it must use kyaml.") - return nil -} - -func makeKyamlBasedInstances() *DepProvider { - kf := &wrappy.WNodeFactory{} - rf := resource.NewFactory(kf) +func NewDepProvider() *DepProvider { + rf := resource.NewFactory(&hasher.Hasher{}) return &DepProvider{ - kFactory: kf, - resourceFactory: rf, - conflictDectectorFactory: conflict.NewFactory(), - fieldValidator: validate.NewFieldValidator(), + resourceFactory: rf, + fieldValidator: validate.NewFieldValidator(), } } -func NewDepProvider(useKyaml bool) *DepProvider { - if useKyaml { - return makeKyamlBasedInstances() - } - return makeK8sdepBasedInstances() -} - func NewDefaultDepProvider() *DepProvider { - return NewDepProvider(konfig.FlagEnableKyamlDefaultValue) -} - -func (dp *DepProvider) GetKunstructuredFactory() ifc.KunstructuredFactory { - return dp.kFactory + return NewDepProvider() } func (dp *DepProvider) GetResourceFactory() *resource.Factory { return dp.resourceFactory } -func (dp *DepProvider) GetConflictDetectorFactory() resource.ConflictDetectorFactory { - return dp.conflictDectectorFactory -} - func (dp *DepProvider) GetFieldValidator() ifc.Validator { return dp.fieldValidator } diff --git a/vendor/sigs.k8s.io/kustomize/api/resid/gvk.go b/vendor/sigs.k8s.io/kustomize/api/resid/gvk.go index 70f7107386a..b112151d389 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resid/gvk.go +++ b/vendor/sigs.k8s.io/kustomize/api/resid/gvk.go @@ -36,6 +36,14 @@ func ParseGroupVersion(apiVersion string) (group, version string) { // GvkFromString makes a Gvk from the output of Gvk.String(). func GvkFromString(s string) Gvk { values := strings.Split(s, fieldSep) + if len(values) != 3 { + // ...then the string didn't come from Gvk.String(). + return Gvk{ + Group: noGroup, + Version: noVersion, + Kind: noKind, + } + } g := values[0] if g == noGroup { g = "" @@ -213,7 +221,10 @@ func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta { } } -// IsNamespaceableKind returns true if x is a namespaceable Gvk +// IsNamespaceableKind returns true if x is a namespaceable Gvk, +// e.g. instances of Pod and Deployment are namespaceable, +// but instances of Node and Namespace are not namespaceable. +// Alternative name for this method: IsNotClusterScoped. // Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace func (x Gvk) IsNamespaceableKind() bool { isNamespaceScoped, found := openapi.IsNamespaceScoped(x.toKyamlTypeMeta()) diff --git a/vendor/sigs.k8s.io/kustomize/api/resmap/factory.go b/vendor/sigs.k8s.io/kustomize/api/resmap/factory.go index a93b0ad6c62..9ec0fe39678 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resmap/factory.go +++ b/vendor/sigs.k8s.io/kustomize/api/resmap/factory.go @@ -16,14 +16,11 @@ import ( type Factory struct { // Makes resources. resF *resource.Factory - // Makes ConflictDetectors. - cdf resource.ConflictDetectorFactory } // NewFactory returns a new resmap.Factory. -func NewFactory( - rf *resource.Factory, cdf resource.ConflictDetectorFactory) *Factory { - return &Factory{resF: rf, cdf: cdf} +func NewFactory(rf *resource.Factory) *Factory { + return &Factory{resF: rf} } // RF returns a resource.Factory. @@ -126,13 +123,6 @@ func (rmF *Factory) FromSecretArgs( return rmF.FromResource(res), nil } -// ConflatePatches creates a new ResMap containing a merger of the -// incoming patches. -// Error if conflict found. -func (rmF *Factory) ConflatePatches(patches []*resource.Resource) (ResMap, error) { - return (&merginator{cdf: rmF.cdf}).ConflatePatches(patches) -} - func newResMapFromResourceSlice( resources []*resource.Resource) (ResMap, error) { result := New() @@ -146,18 +136,10 @@ func newResMapFromResourceSlice( } // NewResMapFromRNodeSlice returns a ResMap from a slice of RNodes -func (rmF *Factory) NewResMapFromRNodeSlice(rnodes []*yaml.RNode) (ResMap, error) { - var resources []*resource.Resource - for _, rnode := range rnodes { - s, err := rnode.String() - if err != nil { - return nil, err - } - r, err := rmF.resF.SliceFromBytes([]byte(s)) - if err != nil { - return nil, err - } - resources = append(resources, r...) +func (rmF *Factory) NewResMapFromRNodeSlice(s []*yaml.RNode) (ResMap, error) { + rs, err := rmF.resF.ResourcesFromRNodes(s) + if err != nil { + return nil, err } - return newResMapFromResourceSlice(resources) + return newResMapFromResourceSlice(rs) } diff --git a/vendor/sigs.k8s.io/kustomize/api/resmap/merginator.go b/vendor/sigs.k8s.io/kustomize/api/resmap/merginator.go deleted file mode 100644 index c09b5aacb2d..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/resmap/merginator.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2020 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package resmap - -import ( - "fmt" - - "sigs.k8s.io/kustomize/api/resource" -) - -// merginator coordinates merging the resources in incoming to the result. -type merginator struct { - incoming []*resource.Resource - cdf resource.ConflictDetectorFactory - result ResMap -} - -func (m *merginator) ConflatePatches(in []*resource.Resource) (ResMap, error) { - m.result = New() - m.incoming = in - for index := range m.incoming { - alreadyInResult, err := m.appendIfNoMatch(index) - if err != nil { - return nil, err - } - if alreadyInResult != nil { - // The resource at index has the same resId as a previously - // considered resource. - // - // If they conflict with each other (e.g. they both want to change - // the image name in a Deployment, but to different values), - // return an error. - // - // If they don't conflict, then merge them into a single resource, - // since they both target the same item, and we want cumulative - // behavior. E.g. say both patches modify a map. Without a merge, - // the last patch wins, replacing the entire map. - err = m.mergeWithExisting(index, alreadyInResult) - if err != nil { - return nil, err - } - } - } - return m.result, nil -} - -func (m *merginator) appendIfNoMatch(index int) (*resource.Resource, error) { - candidate := m.incoming[index] - matchedResources := m.result.GetMatchingResourcesByAnyId( - candidate.OrgId().Equals) - if len(matchedResources) == 0 { - m.result.Append(candidate) - return nil, nil - } - if len(matchedResources) > 1 { - return nil, fmt.Errorf("multiple resources targeted by patch") - } - return matchedResources[0], nil -} - -func (m *merginator) mergeWithExisting( - index int, alreadyInResult *resource.Resource) error { - candidate := m.incoming[index] - cd, err := m.cdf.New(candidate.OrgId().Gvk) - if err != nil { - return err - } - hasConflict, err := cd.HasConflict(candidate, alreadyInResult) - if err != nil { - return err - } - if hasConflict { - return m.makeError(cd, index) - } - merged, err := cd.MergePatches(alreadyInResult, candidate) - if err != nil { - return err - } - _, err = m.result.Replace(merged) - return err -} - -// Make an error message describing the conflict. -func (m *merginator) makeError(cd resource.ConflictDetector, index int) error { - conflict, err := m.findConflict(cd, index) - if err != nil { - return err - } - if conflict == nil { - return fmt.Errorf("expected conflict for %s", m.incoming[index].OrgId()) - } - conflictMap, _ := conflict.Map() - incomingIndexMap, _ := m.incoming[index].Map() - return fmt.Errorf( - "conflict between %#v at index %d and %#v", - incomingIndexMap, - index, - conflictMap, - ) -} - -// findConflict looks for a conflict in a resource slice. -// It returns the first conflict between the resource at index -// and some other resource. Two resources can only conflict if -// they have the same original ResId. -func (m *merginator) findConflict( - cd resource.ConflictDetector, index int) (*resource.Resource, error) { - targetId := m.incoming[index].OrgId() - for i, p := range m.incoming { - if i == index || !targetId.Equals(p.OrgId()) { - continue - } - conflict, err := cd.HasConflict(p, m.incoming[index]) - if err != nil { - return nil, err - } - if conflict { - return p, nil - } - } - return nil, nil -} diff --git a/vendor/sigs.k8s.io/kustomize/api/resmap/resmap.go b/vendor/sigs.k8s.io/kustomize/api/resmap/resmap.go index b803453e128..2b62482aa55 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resmap/resmap.go +++ b/vendor/sigs.k8s.io/kustomize/api/resmap/resmap.go @@ -33,8 +33,10 @@ type Configurable interface { } // NewPluginHelpers makes an instance of PluginHelpers. -func NewPluginHelpers(ldr ifc.Loader, v ifc.Validator, rf *Factory) *PluginHelpers { - return &PluginHelpers{ldr: ldr, v: v, rf: rf} +func NewPluginHelpers( + ldr ifc.Loader, v ifc.Validator, rf *Factory, + pc *types.PluginConfig) *PluginHelpers { + return &PluginHelpers{ldr: ldr, v: v, rf: rf, pc: pc} } // PluginHelpers holds things that any or all plugins might need. @@ -44,6 +46,11 @@ type PluginHelpers struct { ldr ifc.Loader v ifc.Validator rf *Factory + pc *types.PluginConfig +} + +func (c *PluginHelpers) GeneralConfig() *types.PluginConfig { + return c.pc } func (c *PluginHelpers) Loader() ifc.Loader { @@ -80,6 +87,9 @@ type TransformerPlugin interface { // resource to transform, try the OrgId first, and if this // fails or finds too many, it might make sense to then try // the CurrId. Depends on the situation. +// +// TODO: get rid of this interface (use bare resWrangler). +// There aren't multiple implementations any more. type ResMap interface { // Size reports the number of resources. Size() int @@ -189,6 +199,9 @@ type ResMap interface { // Clear removes all resources and Ids. Clear() + // DropEmpties drops empty resources from the ResMap. + DropEmpties() + // SubsetThatCouldBeReferencedByResource returns a ResMap subset // of self with resources that could be referenced by the // resource argument. @@ -231,9 +244,8 @@ type ResMap interface { // are selected by a Selector Select(types.Selector) ([]*resource.Resource, error) - // ToRNodeSlice converts the resources in the resmp - // to a list of RNodes - ToRNodeSlice() ([]*yaml.RNode, error) + // ToRNodeSlice returns a copy of the resources as RNodes. + ToRNodeSlice() []*yaml.RNode // ApplySmPatch applies a strategic-merge patch to the // selected set of resources. diff --git a/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go b/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go index f76276c481b..acdceed2316 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go +++ b/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go @@ -6,14 +6,12 @@ package resmap import ( "bytes" "fmt" - "strings" "github.com/pkg/errors" "sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/types" - kyaml_yaml "sigs.k8s.io/kustomize/kyaml/yaml" - "sigs.k8s.io/yaml" + kyaml "sigs.k8s.io/kustomize/kyaml/yaml" ) // resWrangler implements ResMap. @@ -38,6 +36,18 @@ func (m *resWrangler) Clear() { m.rList = nil } +// DropEmpties quickly drops empty resources. +// It doesn't use Append, which checks for Id collisions. +func (m *resWrangler) DropEmpties() { + var rList []*resource.Resource + for _, r := range m.rList { + if !r.IsEmpty() { + rList = append(rList, r) + } + } + m.rList = rList +} + // Size implements ResMap. func (m *resWrangler) Size() int { return len(m.rList) @@ -66,22 +76,27 @@ func (m *resWrangler) Append(res *resource.Resource) error { return fmt.Errorf( "may not add resource with an already registered id: %s", id) } - m.rList = append(m.rList, res) + m.append(res) return nil } +// append appends without performing an Id check +func (m *resWrangler) append(res *resource.Resource) { + m.rList = append(m.rList, res) +} + // Remove implements ResMap. func (m *resWrangler) Remove(adios resid.ResId) error { - tmp := newOne() + var rList []*resource.Resource for _, r := range m.rList { if r.CurId() != adios { - tmp.Append(r) + rList = append(rList, r) } } - if tmp.Size() != m.Size()-1 { + if len(rList) != m.Size()-1 { return fmt.Errorf("id %s not found in removal", adios) } - m.rList = tmp.rList + m.rList = rList return nil } @@ -118,16 +133,7 @@ func (m *resWrangler) Debug(title string) { } else { fmt.Println("---") } - fmt.Printf("# %d %s\n", i, r.OrgId()) - m, err := r.Map() - if err != nil { - panic(err) - } - blob, err := yaml.Marshal(m) - if err != nil { - panic(err) - } - fmt.Println(string(blob)) + fmt.Printf("# %d %s\n%s\n", i, r.OrgId(), r.String()) } } @@ -273,7 +279,7 @@ func (m *resWrangler) AsYaml() ([]byte, error) { firstObj := true var b []byte buf := bytes.NewBuffer(b) - for _, res := range m.Resources() { + for _, res := range m.rList { out, err := res.AsYAML() if err != nil { m, _ := res.Map() @@ -297,7 +303,7 @@ func (m *resWrangler) AsYaml() ([]byte, error) { func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error { m2, ok := other.(*resWrangler) if !ok { - panic("bad cast") + return fmt.Errorf("bad cast to resWrangler 1") } if m.Size() != m2.Size() { return fmt.Errorf( @@ -317,9 +323,9 @@ func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error { "id in self matches %d in other; id: %s", len(others), id) } r2 := others[0] - if !r1.KunstructEqual(r2) { + if !r1.NodeEqual(r2) { return fmt.Errorf( - "kunstruct not equal: \n -- %s,\n -- %s\n\n--\n%#v\n------\n%#v\n", + "nodes unequal: \n -- %s,\n -- %s\n\n--\n%#v\n------\n%#v\n", r1, r2, r1, r2) } seen[m2.indexOfResource(r2)] = true @@ -334,7 +340,7 @@ func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error { func (m *resWrangler) ErrorIfNotEqualLists(other ResMap) error { m2, ok := other.(*resWrangler) if !ok { - panic("bad cast") + return fmt.Errorf("bad cast to resWrangler 2") } if m.Size() != m2.Size() { return fmt.Errorf( @@ -388,7 +394,7 @@ func (m *resWrangler) SubsetThatCouldBeReferencedByResource( } result := newOne() roleBindingNamespaces := getNamespacesForRoleBinding(referrer) - for _, possibleTarget := range m.Resources() { + for _, possibleTarget := range m.rList { id := possibleTarget.CurId() if !id.IsNamespaceableKind() { // A cluster-scoped resource can be referred to by anything. @@ -435,16 +441,21 @@ func getNamespacesForRoleBinding(r *resource.Resource) map[string]bool { return result } -func (m *resWrangler) append(res *resource.Resource) { - m.rList = append(m.rList, res) -} - // AppendAll implements ResMap. func (m *resWrangler) AppendAll(other ResMap) error { if other == nil { return nil } - for _, res := range other.Resources() { + m2, ok := other.(*resWrangler) + if !ok { + return fmt.Errorf("bad cast to resWrangler 3") + } + return m.appendAll(m2.rList) +} + +// appendAll appends all the resources, error on Id collision. +func (m *resWrangler) appendAll(list []*resource.Resource) error { + for _, res := range list { if err := m.Append(res); err != nil { return err } @@ -457,7 +468,11 @@ func (m *resWrangler) AbsorbAll(other ResMap) error { if other == nil { return nil } - for _, r := range other.Resources() { + m2, ok := other.(*resWrangler) + if !ok { + return fmt.Errorf("bad cast to resWrangler 4") + } + for _, r := range m2.rList { err := m.appendReplaceOrMerge(r) if err != nil { return err @@ -522,7 +537,7 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) { if err != nil { return nil, err } - for _, r := range m.Resources() { + for _, r := range m.rList { curId := r.CurId() orgId := r.OrgId() @@ -567,77 +582,39 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) { return result, nil } -// ToRNodeSlice converts the resources in the resmp -// to a list of RNodes -func (m *resWrangler) ToRNodeSlice() ([]*kyaml_yaml.RNode, error) { - var rnodes []*kyaml_yaml.RNode - for _, r := range m.Resources() { - s, err := r.AsYAML() - if err != nil { - return nil, err - } - rnode, err := kyaml_yaml.Parse(string(s)) - if err != nil { - return nil, err - } - rnodes = append(rnodes, rnode) +// ToRNodeSlice returns a copy of the resources as RNodes. +func (m *resWrangler) ToRNodeSlice() []*kyaml.RNode { + result := make([]*kyaml.RNode, len(m.rList)) + for i := range m.rList { + result[i] = m.rList[i].AsRNode() } - return rnodes, nil + return result } +// ApplySmPatch applies the patch, and errors on Id collisions. func (m *resWrangler) ApplySmPatch( selectedSet *resource.IdSet, patch *resource.Resource) error { - newRm := New() - for _, res := range m.Resources() { - if !selectedSet.Contains(res.CurId()) { - newRm.Append(res) - continue - } - patchCopy := patch.DeepCopy() - patchCopy.CopyMergeMetaDataFieldsFrom(patch) - patchCopy.SetGvk(res.GetGvk()) - err := res.ApplySmPatch(patchCopy) - if err != nil { - // Check for an error string from UnmarshalJSON that's indicative - // of an object that's missing basic KRM fields, and thus may have been - // entirely deleted (an acceptable outcome). This error handling should - // be deleted along with use of ResMap and apimachinery functions like - // UnmarshalJSON. - if !strings.Contains(err.Error(), "Object 'Kind' is missing") { - // Some unknown error, let it through. + var list []*resource.Resource + for _, res := range m.rList { + if selectedSet.Contains(res.CurId()) { + patchCopy := patch.DeepCopy() + patchCopy.CopyMergeMetaDataFieldsFrom(patch) + patchCopy.SetGvk(res.GetGvk()) + patchCopy.SetKind(patch.GetKind()) + if err := res.ApplySmPatch(patchCopy); err != nil { return err } - empty, err := res.IsEmpty() - if err != nil { - return err - } - if !empty { - m, _ := res.Map() - return errors.Wrapf( - err, "with unexpectedly non-empty object map of size %d", - len(m)) - } - // Fall through to handle deleted object. } - empty, err := res.IsEmpty() - if err != nil { - return err - } - if !empty { - // IsEmpty means all fields have been removed from the object. - // This can happen if a patch required deletion of the - // entire resource (not just a part of it). This means - // the overall resmap must shrink by one. - newRm.Append(res) + if !res.IsEmpty() { + list = append(list, res) } } m.Clear() - m.AppendAll(newRm) - return nil + return m.appendAll(list) } func (m *resWrangler) RemoveBuildAnnotations() { - for _, r := range m.Resources() { + for _, r := range m.rList { r.RemoveBuildAnnotations() } } diff --git a/vendor/sigs.k8s.io/kustomize/api/resource/conflictdetector.go b/vendor/sigs.k8s.io/kustomize/api/resource/conflictdetector.go deleted file mode 100644 index f079cdd5abb..00000000000 --- a/vendor/sigs.k8s.io/kustomize/api/resource/conflictdetector.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package resource - -import "sigs.k8s.io/kustomize/api/resid" - -// ConflictDetector detects conflicts between resources. -type ConflictDetector interface { - // HasConflict returns true if the given resources have a conflict. - HasConflict(patch1, patch2 *Resource) (bool, error) - // Merge two resources into one. - MergePatches(patch1, patch2 *Resource) (*Resource, error) -} - -// ConflictDetectorFactory makes instances of ConflictDetector that know -// how to handle the given Group, Version, Kind tuple. -type ConflictDetectorFactory interface { - New(gvk resid.Gvk) (ConflictDetector, error) -} diff --git a/vendor/sigs.k8s.io/kustomize/api/resource/factory.go b/vendor/sigs.k8s.io/kustomize/api/resource/factory.go index df08c5dbf51..a9a1006bc06 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resource/factory.go +++ b/vendor/sigs.k8s.io/kustomize/api/resource/factory.go @@ -10,28 +10,33 @@ import ( "strings" "sigs.k8s.io/kustomize/api/ifc" + "sigs.k8s.io/kustomize/api/internal/generators" "sigs.k8s.io/kustomize/api/internal/kusterr" + "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/yaml" ) // Factory makes instances of Resource. type Factory struct { - kf ifc.KunstructuredFactory + hasher ifc.KustHasher } // NewFactory makes an instance of Factory. -func NewFactory(kf ifc.KunstructuredFactory) *Factory { - return &Factory{kf: kf} +func NewFactory(h ifc.KustHasher) *Factory { + return &Factory{hasher: h} } -func (rf *Factory) Hasher() ifc.KunstructuredHasher { - return rf.kf.Hasher() +// Hasher returns an ifc.KustHasher +func (rf *Factory) Hasher() ifc.KustHasher { + return rf.hasher } // FromMap returns a new instance of Resource. func (rf *Factory) FromMap(m map[string]interface{}) *Resource { - return rf.makeOne(rf.kf.FromMap(m), nil) + return rf.FromMapAndOption(m, nil) } // FromMapWithName returns a new instance with the given "original" name. @@ -41,34 +46,30 @@ func (rf *Factory) FromMapWithName(n string, m map[string]interface{}) *Resource // FromMapWithNamespaceAndName returns a new instance with the given "original" namespace. func (rf *Factory) FromMapWithNamespaceAndName(ns string, n string, m map[string]interface{}) *Resource { - return rf.makeOne(rf.kf.FromMap(m), nil).setPreviousNamespaceAndName(ns, n) + r := rf.FromMapAndOption(m, nil) + return r.setPreviousId(ns, n, r.GetKind()) } // FromMapAndOption returns a new instance of Resource with given options. func (rf *Factory) FromMapAndOption( m map[string]interface{}, args *types.GeneratorArgs) *Resource { - return rf.makeOne(rf.kf.FromMap(m), types.NewGenArgs(args)) -} - -// FromKunstructured returns a new instance of Resource. -func (rf *Factory) FromKunstructured(u ifc.Kunstructured) *Resource { - return rf.makeOne(u, nil) + n, err := yaml.FromMap(m) + if err != nil { + // TODO: return err instead of log. + log.Fatal(err) + } + return rf.makeOne(n, types.NewGenArgs(args)) } // makeOne returns a new instance of Resource. -func (rf *Factory) makeOne( - u ifc.Kunstructured, o *types.GenArgs) *Resource { - if u == nil { - log.Fatal("unstruct ifc must not be null") +func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GenArgs) *Resource { + if rn == nil { + log.Fatal("RNode must not be null") } if o == nil { o = types.NewGenArgs(nil) } - r := &Resource{ - kunStr: u, - options: o, - } - return r + return &Resource{node: rn, options: o} } // SliceFromPatches returns a slice of resources given a patch path @@ -105,47 +106,135 @@ func (rf *Factory) FromBytes(in []byte) (*Resource, error) { // SliceFromBytes unmarshals bytes into a Resource slice. func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { - kunStructs, err := rf.kf.SliceFromBytes(in) + nodes, err := rf.RNodesFromBytes(in) if err != nil { return nil, err } - var result []*Resource - for len(kunStructs) > 0 { - u := kunStructs[0] - kunStructs = kunStructs[1:] - if strings.HasSuffix(u.GetKind(), "List") { - m, err := u.Map() - if err != nil { - return nil, err + return rf.resourcesFromRNodes(nodes), nil +} + +// ResourcesFromRNodes converts RNodes to Resources. +func (rf *Factory) ResourcesFromRNodes( + nodes []*yaml.RNode) (result []*Resource, err error) { + nodes, err = rf.dropBadNodes(nodes) + if err != nil { + return nil, err + } + return rf.resourcesFromRNodes(nodes), nil +} + +// resourcesFromRNode assumes all nodes are good. +func (rf *Factory) resourcesFromRNodes( + nodes []*yaml.RNode) (result []*Resource) { + for _, n := range nodes { + result = append(result, rf.makeOne(n, nil)) + } + return +} + +func (rf *Factory) RNodesFromBytes(b []byte) (result []*yaml.RNode, err error) { + nodes, err := kio.FromBytes(b) + if err != nil { + return nil, err + } + nodes, err = rf.dropBadNodes(nodes) + if err != nil { + return nil, err + } + for len(nodes) > 0 { + n0 := nodes[0] + nodes = nodes[1:] + kind := n0.GetKind() + if !strings.HasSuffix(kind, "List") { + result = append(result, n0) + continue + } + // Convert a FooList into a slice of Foo. + var m map[string]interface{} + m, err = n0.Map() + if err != nil { + return nil, err + } + items, ok := m["items"] + if !ok { + // treat as an empty list + continue + } + slice, ok := items.([]interface{}) + if !ok { + if items == nil { + // an empty list + continue } - items := m["items"] - itemsSlice, ok := items.([]interface{}) - if !ok { - if items == nil { - // an empty list - continue - } - return nil, fmt.Errorf("items in List is type %T, expected array", items) - } - for _, item := range itemsSlice { - itemJSON, err := json.Marshal(item) - if err != nil { - return nil, err - } - innerU, err := rf.kf.SliceFromBytes(itemJSON) - if err != nil { - return nil, err - } - // append innerU to kunStructs so nested Lists can be handled - kunStructs = append(kunStructs, innerU...) - } - } else { - result = append(result, rf.FromKunstructured(u)) + return nil, fmt.Errorf( + "expected array in %s/items, but found %T", kind, items) + } + innerNodes, err := rf.convertObjectSliceToNodeSlice(slice) + if err != nil { + return nil, err + } + nodes = append(nodes, innerNodes...) + } + return result, nil +} + +// convertObjectSlice converts a list of objects to a list of RNode. +func (rf *Factory) convertObjectSliceToNodeSlice( + objects []interface{}) (result []*yaml.RNode, err error) { + var bytes []byte + var nodes []*yaml.RNode + for _, obj := range objects { + bytes, err = json.Marshal(obj) + if err != nil { + return + } + nodes, err = kio.FromBytes(bytes) + if err != nil { + return + } + nodes, err = rf.dropBadNodes(nodes) + if err != nil { + return + } + result = append(result, nodes...) + } + return +} + +// dropBadNodes may drop some nodes from its input argument. +func (rf *Factory) dropBadNodes(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + var result []*yaml.RNode + for _, n := range nodes { + ignore, err := rf.shouldIgnore(n) + if err != nil { + return nil, err + } + if !ignore { + result = append(result, n) } } return result, nil } +// shouldIgnore returns true if there's some reason to ignore the node. +func (rf *Factory) shouldIgnore(n *yaml.RNode) (bool, error) { + if n.IsNilOrEmpty() { + return true, nil + } + md, err := n.GetValidatedMetadata() + if err != nil { + return true, err + } + _, ignore := md.ObjectMeta.Annotations[konfig.IgnoredByKustomizeAnnotation] + if ignore { + return true, nil + } + if foundNil, path := n.HasNilEntryInList(); foundNil { + return true, fmt.Errorf("empty item at %v in object %v", path, n) + } + return false, nil +} + // SliceFromBytesWithNames unmarshals bytes into a Resource slice with specified original // name. func (rf *Factory) SliceFromBytesWithNames(names []string, in []byte) ([]*Resource, error) { @@ -157,25 +246,25 @@ func (rf *Factory) SliceFromBytesWithNames(names []string, in []byte) ([]*Resour return nil, fmt.Errorf("number of names doesn't match number of resources") } for i, res := range result { - res.setPreviousNamespaceAndName(resid.DefaultNamespace, names[i]) + res.setPreviousId(resid.DefaultNamespace, names[i], res.GetKind()) } return result, nil } // MakeConfigMap makes an instance of Resource for ConfigMap func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (*Resource, error) { - u, err := rf.kf.MakeConfigMap(kvLdr, args) + rn, err := generators.MakeConfigMap(kvLdr, args) if err != nil { return nil, err } - return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil + return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil } // MakeSecret makes an instance of Resource for Secret func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Resource, error) { - u, err := rf.kf.MakeSecret(kvLdr, args) + rn, err := generators.MakeSecret(kvLdr, args) if err != nil { return nil, err } - return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil + return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil } diff --git a/vendor/sigs.k8s.io/kustomize/api/resource/resource.go b/vendor/sigs.k8s.io/kustomize/api/resource/resource.go index d9f2b107b03..f0177989997 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resource/resource.go +++ b/vendor/sigs.k8s.io/kustomize/api/resource/resource.go @@ -12,153 +12,184 @@ import ( "sigs.k8s.io/kustomize/api/filters/patchstrategicmerge" "sigs.k8s.io/kustomize/api/ifc" - "sigs.k8s.io/kustomize/api/internal/wrappy" "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/types" - "sigs.k8s.io/kustomize/kyaml/filtersutil" "sigs.k8s.io/kustomize/kyaml/kio" kyaml "sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/yaml" ) -// Resource is a representation of a Kubernetes Resource Model (KRM) object +// Resource is an RNode, representing a Kubernetes Resource Model object, // paired with metadata used by kustomize. -// For more history, see sigs.k8s.io/kustomize/api/ifc.Unstructured type Resource struct { - kunStr ifc.Kunstructured + // TODO: Inline RNode, dropping complexity. Resource is just a decorator. + node *kyaml.RNode options *types.GenArgs refBy []resid.ResId refVarNames []string } const ( + buildAnnotationPreviousKinds = konfig.ConfigAnnoDomain + "/previousKinds" buildAnnotationPreviousNames = konfig.ConfigAnnoDomain + "/previousNames" buildAnnotationPrefixes = konfig.ConfigAnnoDomain + "/prefixes" buildAnnotationSuffixes = konfig.ConfigAnnoDomain + "/suffixes" buildAnnotationPreviousNamespaces = konfig.ConfigAnnoDomain + "/previousNamespaces" + + // the following are only for patches, to specify whether they can change names + // and kinds of their targets + buildAnnotationAllowNameChange = konfig.ConfigAnnoDomain + "/allowNameChange" + buildAnnotationAllowKindChange = konfig.ConfigAnnoDomain + "/allowKindChange" ) var buildAnnotations = []string{ + buildAnnotationPreviousKinds, buildAnnotationPreviousNames, buildAnnotationPrefixes, buildAnnotationSuffixes, buildAnnotationPreviousNamespaces, + buildAnnotationAllowNameChange, + buildAnnotationAllowKindChange, +} + +func (r *Resource) AsRNode() *kyaml.RNode { + return r.node.Copy() } func (r *Resource) ResetPrimaryData(incoming *Resource) { - r.kunStr = incoming.Copy() + r.node = incoming.node.Copy() } func (r *Resource) GetAnnotations() map[string]string { - annotations := r.kunStr.GetAnnotations() - if annotations == nil { + annotations, err := r.node.GetAnnotations() + if err != nil || annotations == nil { return make(map[string]string) } return annotations } -func (r *Resource) Copy() ifc.Kunstructured { - return r.kunStr.Copy() -} - func (r *Resource) GetFieldValue(f string) (interface{}, error) { - return r.kunStr.GetFieldValue(f) + //nolint:staticcheck + return r.node.GetFieldValue(f) } func (r *Resource) GetDataMap() map[string]string { - return r.kunStr.GetDataMap() + return r.node.GetDataMap() } func (r *Resource) GetBinaryDataMap() map[string]string { - return r.kunStr.GetBinaryDataMap() + return r.node.GetBinaryDataMap() } func (r *Resource) GetGvk() resid.Gvk { - return r.kunStr.GetGvk() + meta, err := r.node.GetMeta() + if err != nil { + return resid.GvkFromString("") + } + g, v := resid.ParseGroupVersion(meta.APIVersion) + return resid.Gvk{Group: g, Version: v, Kind: meta.Kind} +} + +func (r *Resource) Hash(h ifc.KustHasher) (string, error) { + return h.Hash(r.node) } func (r *Resource) GetKind() string { - return r.kunStr.GetKind() + return r.node.GetKind() } func (r *Resource) GetLabels() map[string]string { - return r.kunStr.GetLabels() + l, err := r.node.GetLabels() + if err != nil { + return map[string]string{} + } + return l } func (r *Resource) GetName() string { - return r.kunStr.GetName() + return r.node.GetName() } func (r *Resource) GetSlice(p string) ([]interface{}, error) { - return r.kunStr.GetSlice(p) + //nolint:staticcheck + return r.node.GetSlice(p) } func (r *Resource) GetString(p string) (string, error) { - return r.kunStr.GetString(p) + //nolint:staticcheck + return r.node.GetString(p) } -func (r *Resource) IsEmpty() (bool, error) { - m, err := r.kunStr.Map() - return len(m) == 0, err +func (r *Resource) IsEmpty() bool { + return r.node.IsNilOrEmpty() } func (r *Resource) Map() (map[string]interface{}, error) { - return r.kunStr.Map() + return r.node.Map() } func (r *Resource) MarshalJSON() ([]byte, error) { - return r.kunStr.MarshalJSON() + return r.node.MarshalJSON() } func (r *Resource) MatchesLabelSelector(selector string) (bool, error) { - return r.kunStr.MatchesLabelSelector(selector) + return r.node.MatchesLabelSelector(selector) } func (r *Resource) MatchesAnnotationSelector(selector string) (bool, error) { - return r.kunStr.MatchesAnnotationSelector(selector) + return r.node.MatchesAnnotationSelector(selector) } func (r *Resource) SetAnnotations(m map[string]string) { if len(m) == 0 { // Force field erasure. - r.kunStr.SetAnnotations(nil) + r.node.SetAnnotations(nil) return } - r.kunStr.SetAnnotations(m) + r.node.SetAnnotations(m) } func (r *Resource) SetDataMap(m map[string]string) { - r.kunStr.SetDataMap(m) + r.node.SetDataMap(m) } func (r *Resource) SetBinaryDataMap(m map[string]string) { - r.kunStr.SetBinaryDataMap(m) + r.node.SetBinaryDataMap(m) } func (r *Resource) SetGvk(gvk resid.Gvk) { - r.kunStr.SetGvk(gvk) + r.node.SetMapField( + kyaml.NewScalarRNode(gvk.Kind), kyaml.KindField) + r.node.SetMapField( + kyaml.NewScalarRNode(gvk.ApiVersion()), kyaml.APIVersionField) } func (r *Resource) SetLabels(m map[string]string) { if len(m) == 0 { // Force field erasure. - r.kunStr.SetLabels(nil) + r.node.SetLabels(nil) return } - r.kunStr.SetLabels(m) + r.node.SetLabels(m) } func (r *Resource) SetName(n string) { - r.kunStr.SetName(n) + r.node.SetName(n) } func (r *Resource) SetNamespace(n string) { - r.kunStr.SetNamespace(n) + r.node.SetNamespace(n) +} + +func (r *Resource) SetKind(k string) { + gvk := r.GetGvk() + gvk.Kind = k + r.SetGvk(gvk) } func (r *Resource) UnmarshalJSON(s []byte) error { - return r.kunStr.UnmarshalJSON(s) + return r.node.UnmarshalJSON(s) } // ResCtx is an interface describing the contextual added @@ -178,14 +209,14 @@ type ResCtxMatcher func(ResCtx) bool // DeepCopy returns a new copy of resource func (r *Resource) DeepCopy() *Resource { rc := &Resource{ - kunStr: r.Copy(), + node: r.node.Copy(), } rc.copyOtherFields(r) return rc } // CopyMergeMetaDataFields copies everything but the non-metadata in -// the ifc.Kunstructured map, merging labels and annotations. +// the resource. func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) { r.SetLabels(mergeStringMaps(other.GetLabels(), r.GetLabels())) r.SetAnnotations( @@ -251,8 +282,10 @@ func (r *Resource) ReferencesEqual(other *Resource) bool { return len(setSelf) == len(setOther) } -func (r *Resource) KunstructEqual(o *Resource) bool { - return reflect.DeepEqual(r.kunStr, o.kunStr) +// NodeEqual returns true if the resource's nodes are +// equal, ignoring ancillary information like genargs, refby, etc. +func (r *Resource) NodeEqual(o *Resource) bool { + return reflect.DeepEqual(r.node, o.node) } func (r *Resource) copyRefBy() []resid.ResId { @@ -351,12 +384,41 @@ func (r *Resource) RemoveBuildAnnotations() { r.SetAnnotations(annotations) } -func (r *Resource) setPreviousNamespaceAndName(ns string, n string) *Resource { +func (r *Resource) setPreviousId(ns string, n string, k string) *Resource { r.appendCsvAnnotation(buildAnnotationPreviousNames, n) r.appendCsvAnnotation(buildAnnotationPreviousNamespaces, ns) + r.appendCsvAnnotation(buildAnnotationPreviousKinds, k) return r } +func (r *Resource) SetAllowNameChange(value string) { + annotations := r.GetAnnotations() + annotations[buildAnnotationAllowNameChange] = value + r.SetAnnotations(annotations) +} + +func (r *Resource) NameChangeAllowed() bool { + annotations := r.GetAnnotations() + if allowed, set := annotations[buildAnnotationAllowNameChange]; set && allowed == "true" { + return true + } + return false +} + +func (r *Resource) SetAllowKindChange(value string) { + annotations := r.GetAnnotations() + annotations[buildAnnotationAllowKindChange] = value + r.SetAnnotations(annotations) +} + +func (r *Resource) KindChangeAllowed() bool { + annotations := r.GetAnnotations() + if allowed, set := annotations[buildAnnotationAllowKindChange]; set && allowed == "true" { + return true + } + return false +} + // String returns resource as JSON. func (r *Resource) String() string { bs, err := r.MarshalJSON() @@ -430,14 +492,19 @@ func (r *Resource) PrevIds() []resid.ResId { // pairs on one annotation so there is no chance of error names := r.getCsvAnnotation(buildAnnotationPreviousNames) ns := r.getCsvAnnotation(buildAnnotationPreviousNamespaces) - if len(names) != len(ns) { + kinds := r.getCsvAnnotation(buildAnnotationPreviousKinds) + if len(names) != len(ns) || len(names) != len(kinds) { panic(errors.New( - "number of previous names not equal to " + - "number of previous namespaces")) + "number of previous names, " + + "number of previous namespaces, " + + "number of previous kinds not equal")) } for i := range names { + k := kinds[i] + gvk := r.GetGvk() + gvk.Kind = k ids = append(ids, resid.NewResIdWithNamespace( - r.GetGvk(), names[i], ns[i])) + gvk, names[i], ns[i])) } return ids } @@ -445,7 +512,7 @@ func (r *Resource) PrevIds() []resid.ResId { // StorePreviousId stores the resource's current ID via build annotations. func (r *Resource) StorePreviousId() { id := r.CurId() - r.setPreviousNamespaceAndName(id.EffectiveNamespace(), id.Name) + r.setPreviousId(id.EffectiveNamespace(), id.Name, id.Kind) } // CurId returns a ResId for the resource using the @@ -478,38 +545,35 @@ func (r *Resource) AppendRefVarName(variable types.Var) { // ApplySmPatch applies the provided strategic merge patch. func (r *Resource) ApplySmPatch(patch *Resource) error { - node, err := filtersutil.GetRNode(patch) - if err != nil { + n, ns, k := r.GetName(), r.GetNamespace(), r.GetKind() + if patch.NameChangeAllowed() || patch.KindChangeAllowed() { + r.StorePreviousId() + } + if err := r.ApplyFilter(patchstrategicmerge.Filter{ + Patch: patch.node, + }); err != nil { return err } - n, ns := r.GetName(), r.GetNamespace() - err = r.ApplyFilter(patchstrategicmerge.Filter{ - Patch: node, - }) - if err != nil { - return err + if r.IsEmpty() { + return nil } - empty, err := r.IsEmpty() - if err != nil { - return err + if !patch.KindChangeAllowed() { + r.SetKind(k) } - if !empty { + if !patch.NameChangeAllowed() { r.SetName(n) - r.SetNamespace(ns) } - return err + r.SetNamespace(ns) + return nil } func (r *Resource) ApplyFilter(f kio.Filter) error { - if wn, ok := r.kunStr.(*wrappy.WNode); ok { - l, err := f.Filter([]*kyaml.RNode{wn.AsRNode()}) - if len(l) == 0 { - // Hack to deal with deletion. - r.kunStr = wrappy.NewWNode() - } - return err + l, err := f.Filter([]*kyaml.RNode{r.node}) + if len(l) == 0 { + // The node was deleted. The following makes r.IsEmpty() true. + r.node = nil } - return filtersutil.ApplyToJSON(f, r) + return err } func mergeStringMaps(maps ...map[string]string) map[string]string { diff --git a/vendor/sigs.k8s.io/kustomize/api/types/errunabletofind.go b/vendor/sigs.k8s.io/kustomize/api/types/errunabletofind.go index a39e9a38546..f95b8edd5a1 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/errunabletofind.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/errunabletofind.go @@ -23,7 +23,7 @@ func (e *errUnableToFind) Error() string { m = append(m, "('"+p.Value+"'; "+p.Key+")") } return fmt.Sprintf( - "unable to find plugin root - tried: %s", strings.Join(m, ", ")) + "unable to find %s - tried: %s", e.what, strings.Join(m, ", ")) } func NewErrUnableToFind(w string, a []Pair) *errUnableToFind { diff --git a/vendor/sigs.k8s.io/kustomize/api/types/fieldspec.go b/vendor/sigs.k8s.io/kustomize/api/types/fieldspec.go index f5b711ee576..0bee70256b2 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/fieldspec.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/fieldspec.go @@ -9,8 +9,7 @@ import ( "sigs.k8s.io/kustomize/api/resid" ) -// FieldSpec completely specifies a kustomizable field in -// an unstructured representation of a k8s API object. +// FieldSpec completely specifies a kustomizable field in a k8s API object. // It helps define the operands of transformations. // // For example, a directive to add a common label to objects diff --git a/vendor/sigs.k8s.io/kustomize/api/types/helmchartargs.go b/vendor/sigs.k8s.io/kustomize/api/types/helmchartargs.go index 57037208378..7bb22f2e41d 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/helmchartargs.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/helmchartargs.go @@ -3,14 +3,77 @@ package types -// HelmChartArgs contains the metadata of how to generate a secret. +type HelmGlobals struct { + // ChartHome is a file path, relative to the kustomization root, + // to a directory containing a subdirectory for each chart to be + // included in the kustomization. + // The default value of this field is "charts". + // So, for example, kustomize looks for the minecraft chart + // at {kustomizationRoot}/{ChartHome}/minecraft. + // If the chart is there at build time, kustomize will use it as found, + // and not check version numbers or dates. + // If the chart is not there, kustomize will attempt to pull it + // using the version number specified in the kustomization file, + // and put it there. To suppress the pull attempt, simply assure + // that the chart is already there. + ChartHome string `json:"chartHome,omitempty" yaml:"chartHome,omitempty"` + + // ConfigHome defines a value that kustomize should pass to helm via + // the HELM_CONFIG_HOME environment variable. kustomize doesn't attempt + // to read or write this directory. + // If omitted, {tmpDir}/helm is used, where {tmpDir} is some temporary + // directory created by kustomize for the benefit of helm. + // Likewise, kustomize sets + // HELM_CACHE_HOME={ConfigHome}/.cache + // HELM_DATA_HOME={ConfigHome}/.data + // for the helm subprocess. + ConfigHome string `json:"configHome,omitempty" yaml:"configHome,omitempty"` +} + +type HelmChart struct { + // Name is the name of the chart, e.g. 'minecraft'. + Name string `json:"name,omitempty" yaml:"name,omitempty"` + + // Version is the version of the chart, e.g. '3.1.3' + Version string `json:"version,omitempty" yaml:"version,omitempty"` + + // Repo is a URL locating the chart on the internet. + // This is the argument to helm's `--repo` flag, e.g. + // `https://itzg.github.io/minecraft-server-charts`. + Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` + + // ReleaseName replaces RELEASE-NAME in chart template output, + // making a particular inflation of a chart unique with respect to + // other inflations of the same chart in a cluster. It's the first + // argument to the helm `install` and `template` commands, i.e. + // helm install {RELEASE-NAME} {chartName} + // helm template {RELEASE-NAME} {chartName} + // If omitted, the flag --generate-name is passed to 'helm template'. + ReleaseName string `json:"releaseName,omitempty" yaml:"releaseName,omitempty"` + + // ValuesFile is local file path to a values file to use _instead of_ + // the default values that accompanied the chart. + // The default values are in '{ChartHome}/{Name}/values.yaml'. + ValuesFile string `json:"valuesFile,omitempty" yaml:"valuesFile,omitempty"` + + // ValuesInline holds value mappings specified directly, + // rather than in a separate file. + ValuesInline map[string]interface{} `json:"valuesInline,omitempty" yaml:"valuesInline,omitempty"` + + // ValuesMerge specifies how to treat ValuesInline with respect to Values. + // Legal values: 'merge', 'override', 'replace'. + // Defaults to 'override'. + ValuesMerge string `json:"valuesMerge,omitempty" yaml:"valuesMerge,omitempty"` +} + +// HelmChartArgs contains arguments to helm. +// Deprecated. Use HelmGlobals and HelmChart instead. type HelmChartArgs struct { - ChartName string `json:"chartName,omitempty" yaml:"chartName,omitempty"` - ChartVersion string `json:"chartVersion,omitempty" yaml:"chartVersion,omitempty"` - ChartRepoURL string `json:"chartRepoUrl,omitempty" yaml:"chartRepoUrl,omitempty"` - ChartHome string `json:"chartHome,omitempty" yaml:"chartHome,omitempty"` - // Use chartRelease to keep compatible with old exec plugin - ChartRepoName string `json:"chartRelease,omitempty" yaml:"chartRelease,omitempty"` + ChartName string `json:"chartName,omitempty" yaml:"chartName,omitempty"` + ChartVersion string `json:"chartVersion,omitempty" yaml:"chartVersion,omitempty"` + ChartRepoURL string `json:"chartRepoUrl,omitempty" yaml:"chartRepoUrl,omitempty"` + ChartHome string `json:"chartHome,omitempty" yaml:"chartHome,omitempty"` + ChartRepoName string `json:"chartRepoName,omitempty" yaml:"chartRepoName,omitempty"` HelmBin string `json:"helmBin,omitempty" yaml:"helmBin,omitempty"` HelmHome string `json:"helmHome,omitempty" yaml:"helmHome,omitempty"` Values string `json:"values,omitempty" yaml:"values,omitempty"` @@ -20,3 +83,32 @@ type HelmChartArgs struct { ReleaseNamespace string `json:"releaseNamespace,omitempty" yaml:"releaseNamespace,omitempty"` ExtraArgs []string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` } + +// SplitHelmParameters splits helm parameters into +// per-chart params and global chart-independent parameters. +func SplitHelmParameters( + oldArgs []HelmChartArgs) (charts []HelmChart, globals HelmGlobals) { + for _, old := range oldArgs { + charts = append(charts, makeHelmChartFromHca(&old)) + if old.HelmHome != "" { + // last non-empty wins + globals.ConfigHome = old.HelmHome + } + if old.ChartHome != "" { + // last non-empty wins + globals.ChartHome = old.ChartHome + } + } + return charts, globals +} + +func makeHelmChartFromHca(old *HelmChartArgs) (c HelmChart) { + c.Name = old.ChartName + c.Version = old.ChartVersion + c.Repo = old.ChartRepoURL + c.ValuesFile = old.Values + c.ValuesInline = old.ValuesLocal + c.ValuesMerge = old.ValuesMerge + c.ReleaseName = old.ReleaseName + return +} diff --git a/vendor/sigs.k8s.io/kustomize/api/types/kustomization.go b/vendor/sigs.k8s.io/kustomize/api/types/kustomization.go index 30f0e4b2e57..9c555a860eb 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/kustomization.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/kustomization.go @@ -6,6 +6,7 @@ package types import ( "bytes" "encoding/json" + "fmt" "sigs.k8s.io/yaml" ) @@ -46,6 +47,9 @@ type Kustomization struct { // CommonLabels to add to all objects and selectors. CommonLabels map[string]string `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"` + // Labels to add to all objects but not selectors. + Labels []Label `json:"labels,omitempty" yaml:"labels,omitempty"` + // CommonAnnotations to add to all objects. CommonAnnotations map[string]string `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"` @@ -125,9 +129,14 @@ type Kustomization struct { // the map will have a suffix hash generated from its contents. SecretGenerator []SecretArgs `json:"secretGenerator,omitempty" yaml:"secretGenerator,omitempty"` + // HelmGlobals contains helm configuration that isn't chart specific. + HelmGlobals *HelmGlobals `json:"helmGlobals,omitempty" yaml:"helmGlobals,omitempty"` + + // HelmCharts is a list of helm chart configuration instances. + HelmCharts []HelmChart `json:"helmCharts,omitempty" yaml:"helmCharts,omitempty"` + // HelmChartInflationGenerator is a list of helm chart configurations. - // The resulting resource is a normal operand rendered from - // a remote chart by `helm template` + // Deprecated. Auto-converted to HelmGlobals and HelmCharts. HelmChartInflationGenerator []HelmChartArgs `json:"helmChartInflationGenerator,omitempty" yaml:"helmChartInflationGenerator,omitempty"` // GeneratorOptions modify behavior of all ConfigMap and Secret generators. @@ -181,15 +190,42 @@ func (k *Kustomization) FixKustomizationPostUnmarshalling() { k.SecretGenerator[i].EnvSource = "" } } + charts, globals := SplitHelmParameters(k.HelmChartInflationGenerator) + if k.HelmGlobals == nil { + if globals.ChartHome != "" || globals.ConfigHome != "" { + k.HelmGlobals = &globals + } + } + k.HelmCharts = append(k.HelmCharts, charts...) + // Wipe it for the fix command. + k.HelmChartInflationGenerator = nil } // FixKustomizationPreMarshalling fixes things // that should occur after the kustomization file // has been processed. -func (k *Kustomization) FixKustomizationPreMarshalling() { +func (k *Kustomization) FixKustomizationPreMarshalling() error { // PatchesJson6902 should be under the Patches field. k.Patches = append(k.Patches, k.PatchesJson6902...) k.PatchesJson6902 = nil + + // this fix is not in FixKustomizationPostUnmarshalling because + // it will break some commands like `create` and `add`. those + // commands depend on 'commonLabels' field + if cl := labelFromCommonLabels(k.CommonLabels); cl != nil { + // check conflicts between commonLabels and labels + for _, l := range k.Labels { + for k := range l.Pairs { + if _, exist := cl.Pairs[k]; exist { + return fmt.Errorf("label name '%s' exists in both commonLabels and labels", k) + } + } + } + k.Labels = append(k.Labels, *cl) + k.CommonLabels = nil + } + + return nil } func (k *Kustomization) EnforceFields() []string { diff --git a/vendor/sigs.k8s.io/kustomize/api/types/labels.go b/vendor/sigs.k8s.io/kustomize/api/types/labels.go new file mode 100644 index 00000000000..e2a2aee7894 --- /dev/null +++ b/vendor/sigs.k8s.io/kustomize/api/types/labels.go @@ -0,0 +1,25 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package types + +type Label struct { + // Pairs contains the key-value pairs for labels to add + Pairs map[string]string `json:"pairs,omitempty" yaml:"pairs,omitempty"` + // IncludeSelectors inidicates should transformer include the + // fieldSpecs for selectors. Custom fieldSpecs specified by + // FieldSpecs will be merged with builtin fieldSpecs if this + // is true. + IncludeSelectors bool `json:"includeSelectors,omitempty" yaml:"includeSelectors,omitempty"` + FieldSpecs []FieldSpec `json:"fields,omitempty" yaml:"fields,omitempty"` +} + +func labelFromCommonLabels(commonLabels map[string]string) *Label { + if len(commonLabels) == 0 { + return nil + } + return &Label{ + Pairs: commonLabels, + IncludeSelectors: true, + } +} diff --git a/vendor/sigs.k8s.io/kustomize/api/types/patch.go b/vendor/sigs.k8s.io/kustomize/api/types/patch.go index 48b521d7e87..5310a6e66db 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/patch.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/patch.go @@ -3,6 +3,8 @@ package types +import "reflect" + // Patch represent either a Strategic Merge Patch or a JSON patch // and its targets. // The content of the patch can either be from a file @@ -16,6 +18,9 @@ type Patch struct { // Target points to the resources that the patch is applied to Target *Selector `json:"target,omitempty" yaml:"target,omitempty"` + + // Options is a list of options for the patch + Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` } // Equals return true if p equals o. @@ -24,5 +29,6 @@ func (p *Patch) Equals(o Patch) bool { (p.Target != nil && o.Target != nil && *p.Target == *o.Target) return p.Path == o.Path && p.Patch == o.Patch && - targetEqual + targetEqual && + reflect.DeepEqual(p.Options, o.Options) } diff --git a/vendor/sigs.k8s.io/kustomize/api/types/pluginconfig.go b/vendor/sigs.k8s.io/kustomize/api/types/pluginconfig.go index 2756f982681..741e5debc46 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/pluginconfig.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/pluginconfig.go @@ -3,27 +3,13 @@ package types +type HelmConfig struct { + Enabled bool + Command string +} + // PluginConfig holds plugin configuration. type PluginConfig struct { - // AbsPluginHome is the home of kustomize plugins. - // Kustomize plugin configuration files are k8s-style objects - // containing the fields 'apiVersion' and 'kind', e.g. - // apiVersion: apps/v1 - // kind: Deployment - // kustomize reads plugin configuration data from a file path - // specified in the 'generators:' or 'transformers:' field of a - // kustomization file. kustomize must then use this data to both - // locate the plugin and configure it. - // Every kustomize plugin (its code, its tests, its supporting data - // files, etc.) must be housed in its own directory at - // ${AbsPluginHome}/${pluginApiVersion}/LOWERCASE(${pluginKind}) - // where - // - ${AbsPluginHome} is an absolute path, defined below. - // - ${pluginApiVersion} is taken from the plugin config file. - // - ${pluginKind} is taken from the plugin config file. - // The value of AbsPluginHome can be any absolute path. - AbsPluginHome string - // PluginRestrictions distinguishes plugin restrictions. PluginRestrictions PluginRestrictions @@ -32,4 +18,30 @@ type PluginConfig struct { // FnpLoadingOptions sets the way function-based plugin behaviors. FnpLoadingOptions FnPluginLoadingOptions + + // HelmConfig contains metadata needed for allowing and running helm. + HelmConfig HelmConfig +} + +func EnabledPluginConfig(b BuiltinPluginLoadingOptions) (pc *PluginConfig) { + pc = MakePluginConfig(PluginRestrictionsNone, b) + pc.FnpLoadingOptions.EnableStar = true + pc.HelmConfig.Enabled = true + // If this command is not on PATH, tests needing it should skip. + pc.HelmConfig.Command = "helmV3" + return +} + +func DisabledPluginConfig() *PluginConfig { + return MakePluginConfig( + PluginRestrictionsBuiltinsOnly, + BploUseStaticallyLinked) +} + +func MakePluginConfig(pr PluginRestrictions, + b BuiltinPluginLoadingOptions) *PluginConfig { + return &PluginConfig{ + PluginRestrictions: pr, + BpLoadingOptions: b, + } } diff --git a/vendor/sigs.k8s.io/kustomize/api/types/replacement.go b/vendor/sigs.k8s.io/kustomize/api/types/replacement.go index 57c2507ada7..41bd848a34f 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/replacement.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/replacement.go @@ -1,27 +1,59 @@ -// Copyright 2019 The Kubernetes Authors. +// Copyright 2021 The Kubernetes Authors. // SPDX-License-Identifier: Apache-2.0 package types +const DefaultReplacementFieldPath = "metadata.name" + // Replacement defines how to perform a substitution // where it is from and where it is to. type Replacement struct { - Source *ReplSource `json:"source" yaml:"source"` - Target *ReplTarget `json:"target" yaml:"target"` + // The source of the value. + Source *SourceSelector `json:"source" yaml:"source"` + + // The N fields to write the value to. + Targets []*TargetSelector `json:"targets" yaml:"targets"` } -// ReplSource defines where a substitution is from -// It can from two different kinds of sources -// - from a field of one resource -// - from a string -type ReplSource struct { - ObjRef *Target `json:"objref,omitempty" yaml:"objref,omitempty"` - FieldRef string `json:"fieldref,omitempty" yaml:"fiedldref,omitempty"` - Value string `json:"value,omitempty" yaml:"value,omitempty"` +// SourceSelector is the source of the replacement transformer. +type SourceSelector struct { + // A specific object to read it from. + KrmId `json:",inline,omitempty" yaml:",inline,omitempty"` + + // Structured field path expected in the allowed object. + FieldPath string `json:"fieldPath" yaml:"fieldPath"` + + // Used to refine the interpretation of the field. + Options *FieldOptions `json:"options" yaml:"options"` } -// ReplTarget defines where a substitution is to. -type ReplTarget struct { - ObjRef *Selector `json:"objref,omitempty" yaml:"objref,omitempty"` - FieldRefs []string `json:"fieldrefs,omitempty" yaml:"fieldrefs,omitempty"` +// TargetSelector specifies fields in one or more objects. +type TargetSelector struct { + // Include objects that match this. + Select *Selector `json:"select" yaml:"select"` + + // From the allowed set, remove objects that match this. + Reject []*Selector `json:"reject" yaml:"reject"` + + // Structured field paths expected in each allowed object. + FieldPaths []string `json:"fieldPaths" yaml:"fieldPaths"` + + // Used to refine the interpretation of the field. + Options *FieldOptions `json:"options" yaml:"options"` +} + +// FieldOptions refine the interpretation of FieldPaths. +type FieldOptions struct { + // Used to split/join the field. + Delimiter string `json:"delimiter" yaml:"delimiter"` + + // Which position in the split to consider. + Index int `json:"index" yaml:"index"` + + // TODO (#3492): Implement use of this option + // None, Base64, URL, Hex, etc + Encoding string `json:"encoding" yaml:"encoding"` + + // If field missing, add it. + Create bool `json:"create" yaml:"create"` } diff --git a/vendor/sigs.k8s.io/kustomize/api/types/selector.go b/vendor/sigs.k8s.io/kustomize/api/types/selector.go index 007b508f131..4b7295c6a7f 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/selector.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/selector.go @@ -13,9 +13,8 @@ import ( // Any resource that matches intersection of all conditions // is included in this set. type Selector struct { - resid.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"` - Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty"` + // KrmId refers to a GVKN/Ns of a resource. + KrmId `json:",inline,omitempty" yaml:",inline,omitempty"` // AnnotationSelector is a string that follows the label selection expression // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api @@ -28,6 +27,23 @@ type Selector struct { LabelSelector string `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` } +// KrmId refers to a GVKN/Ns of a resource. +type KrmId struct { + resid.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} + +// Match returns true if id selects other, i.e. id's fields +// either match other's or are empty +func (id *KrmId) Match(other *KrmId) bool { + return (id.Group == "" || id.Group == other.Group) && + (id.Version == "" || id.Version == other.Version) && + (id.Kind == "" || id.Kind == other.Kind) && + (id.Name == "" || id.Name == other.Name) && + (id.Namespace == "" || id.Namespace == other.Namespace) +} + // SelectorRegex is a Selector with regex in GVK // Any resource that matches intersection of all conditions // is included in this set. diff --git a/vendor/sigs.k8s.io/kustomize/api/types/var.go b/vendor/sigs.k8s.io/kustomize/api/types/var.go index f636d0d35bb..a9531516671 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/var.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/var.go @@ -12,8 +12,6 @@ import ( "sigs.k8s.io/kustomize/api/resid" ) -const defaultFieldPath = "metadata.name" - // Var represents a variable whose value will be sourced // from a field in a Kubernetes object. type Var struct { @@ -71,7 +69,7 @@ type FieldSelector struct { // defaulting sets reference to field used by default. func (v *Var) Defaulting() { if v.FieldRef.FieldPath == "" { - v.FieldRef.FieldPath = defaultFieldPath + v.FieldRef.FieldPath = DefaultReplacementFieldPath } v.ObjRef.GVK() } diff --git a/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/build.go b/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/build.go index 0fa5177fd10..eea6401557e 100644 --- a/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/build.go +++ b/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/build.go @@ -6,7 +6,6 @@ package build import ( "fmt" "io" - "log" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/api/filesys" @@ -22,10 +21,11 @@ var theArgs struct { var theFlags struct { outputPath string enable struct { - resourceIdChanges bool - plugins bool - managedByLabel bool + plugins bool + managedByLabel bool + helm bool } + helmCommand string loadRestrictor string reorderOutput string fnOptions types.FnPluginLoadingOptions @@ -104,7 +104,7 @@ func NewCmdBuild( AddFlagEnablePlugins(cmd.Flags()) AddFlagReorderOutput(cmd.Flags()) AddFlagEnableManagedbyLabel(cmd.Flags()) - AddFlagAllowResourceIdChanges(cmd.Flags()) + AddFlagEnableHelm(cmd.Flags()) return cmd } @@ -132,14 +132,13 @@ func HonorKustomizeFlags(kOpts *krusty.Options) *krusty.Options { kOpts.DoLegacyResourceSort = getFlagReorderOutput() == legacy kOpts.LoadRestrictions = getFlagLoadRestrictorValue() if theFlags.enable.plugins { - c, err := konfig.EnabledPluginConfig(types.BploUseStaticallyLinked) - if err != nil { - log.Fatal(err) - } + c := types.EnabledPluginConfig(types.BploUseStaticallyLinked) c.FnpLoadingOptions = theFlags.fnOptions kOpts.PluginConfig = c + } else { + kOpts.PluginConfig.HelmConfig.Enabled = theFlags.enable.helm } + kOpts.PluginConfig.HelmConfig.Command = theFlags.helmCommand kOpts.AddManagedbyLabel = isManagedByLabelEnabled() - kOpts.AllowResourceIdChanges = theFlags.enable.resourceIdChanges return kOpts } diff --git a/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagallowresourceidchanges.go b/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagallowresourceidchanges.go deleted file mode 100644 index c05aa5b769b..00000000000 --- a/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagallowresourceidchanges.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2019 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package build - -import ( - "github.com/spf13/pflag" -) - -func AddFlagAllowResourceIdChanges(set *pflag.FlagSet) { - set.BoolVar( - &theFlags.enable.resourceIdChanges, - "allow-id-changes", - false, - `enable changes to a resourceId`) -} diff --git a/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagenablehelm.go b/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagenablehelm.go new file mode 100644 index 00000000000..1a328ce671f --- /dev/null +++ b/vendor/sigs.k8s.io/kustomize/kustomize/v4/commands/build/flagenablehelm.go @@ -0,0 +1,24 @@ +// Copyright 2021 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "github.com/spf13/pflag" +) + +// AddFlagEnableHelm adds the --enable-helm flag. +// The helm plugin is builtin, meaning it's +// enabled independently of --enable-alpha-plugins. +func AddFlagEnableHelm(set *pflag.FlagSet) { + set.BoolVar( + &theFlags.enable.helm, + "enable-helm", + false, + "Enable use of the Helm chart inflator generator.") + set.StringVar( + &theFlags.helmCommand, + "helm-command", + "helm", // default + "helm command (path to executable)") +} diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/doc.go b/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/doc.go deleted file mode 100644 index b5cb975fa29..00000000000 --- a/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2019 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -// Package filtersutil provides utilities for working with yaml.Filter and -// kio.Filter interfaces. -package filtersutil diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/filtersutil.go b/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/filtersutil.go deleted file mode 100644 index 80e4505ada5..00000000000 --- a/vendor/sigs.k8s.io/kustomize/kyaml/filtersutil/filtersutil.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2019 The Kubernetes Authors. -// SPDX-License-Identifier: Apache-2.0 - -package filtersutil - -import ( - "encoding/json" - - "sigs.k8s.io/kustomize/kyaml/errors" - "sigs.k8s.io/kustomize/kyaml/kio" - "sigs.k8s.io/kustomize/kyaml/yaml" -) - -// ApplyToJSON applies the filter to the json objects. -// -// ApplyToJSON marshals the objects into a slice of yaml.RNodes, runs -// the filter on the slice, and then unmarshals the values back. -// -// The filter must not create or delete objects because the objects -// are updated in place. -func ApplyToJSON(filter kio.Filter, objs ...marshalerUnmarshaler) error { - var nodes []*yaml.RNode - - // convert the json objects to rnodes - for i := range objs { - node, err := GetRNode(objs[i]) - if err != nil { - return err - } - nodes = append(nodes, node) - } - - // apply the filter - nodes, err := filter.Filter(nodes) - if err != nil { - return err - } - if len(nodes) != len(objs) { - return errors.Errorf("filter cannot create or delete objects") - } - - // convert the rnodes to json objects - for i := range nodes { - err = setRNode(objs[i], nodes[i]) - if err != nil { - return err - } - } - - return nil -} - -type marshalerUnmarshaler interface { - json.Unmarshaler - json.Marshaler -} - -// GetRNode converts k into an RNode -func GetRNode(k json.Marshaler) (*yaml.RNode, error) { - j, err := k.MarshalJSON() - if err != nil { - return nil, err - } - return yaml.Parse(string(j)) -} - -// setRNode marshals node into k -func setRNode(k json.Unmarshaler, node *yaml.RNode) error { - s, err := node.String() - if err != nil { - return err - } - m := map[string]interface{}{} - if err := yaml.Unmarshal([]byte(s), &m); err != nil { - return err - } - - b, err := json.Marshal(m) - if err != nil { - return err - } - return k.UnmarshalJSON(b) -} diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go b/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go index 2fb1758e2d4..1dfec3c7737 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go @@ -71,6 +71,10 @@ type LocalPackageReadWriter struct { NoDeleteFiles bool `yaml:"noDeleteFiles,omitempty"` files sets.String + + // FileSkipFunc is a function which returns true if reader should ignore + // the file + FileSkipFunc LocalPackageSkipFileFunc } func (r *LocalPackageReadWriter) Read() ([]*yaml.RNode, error) { @@ -81,6 +85,7 @@ func (r *LocalPackageReadWriter) Read() ([]*yaml.RNode, error) { ErrorIfNonResources: r.ErrorIfNonResources, SetAnnotations: r.SetAnnotations, PackageFileName: r.PackageFileName, + FileSkipFunc: r.FileSkipFunc, }.Read() if err != nil { return nil, errors.Wrap(err) @@ -133,6 +138,11 @@ func (r *LocalPackageReadWriter) getFiles(nodes []*yaml.RNode) (sets.String, err return val, nil } +// LocalPackageSkipFileFunc is a function which returns true if the file +// in the package should be ignored by reader. +// relPath is an OS specific relative path +type LocalPackageSkipFileFunc func(relPath string) bool + // LocalPackageReader reads ResourceNodes from a local package. type LocalPackageReader struct { Kind string `yaml:"kind,omitempty"` @@ -163,6 +173,10 @@ type LocalPackageReader struct { // SetAnnotations are annotations to set on the Resources as they are read. SetAnnotations map[string]string `yaml:"setAnnotations,omitempty"` + + // FileSkipFunc is a function which returns true if reader should ignore + // the file + FileSkipFunc LocalPackageSkipFileFunc } var _ Reader = LocalPackageReader{} @@ -215,24 +229,24 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) { if info.IsDir() { return r.shouldSkipDir(path, ignoreFilesMatcher) } - if match, err := r.shouldSkipFile(path, ignoreFilesMatcher); err != nil { + + // get the relative path to file within the package so we can write the files back out + // to another location. + relPath, err := filepath.Rel(pathRelativeTo, path) + if err != nil { + return errors.WrapPrefixf(err, pathRelativeTo) + } + if match, err := r.shouldSkipFile(path, relPath, ignoreFilesMatcher); err != nil { return err - } else if !match { + } else if match { // skip this file return nil } - // get the relative path to file within the package so we can write the files back out - // to another location. - path, err = filepath.Rel(pathRelativeTo, path) + r.initReaderAnnotations(relPath, info) + nodes, err := r.readFile(path, info) if err != nil { - return errors.WrapPrefixf(err, pathRelativeTo) - } - - r.initReaderAnnotations(path, info) - nodes, err := r.readFile(filepath.Join(pathRelativeTo, path), info) - if err != nil { - return errors.WrapPrefixf(err, filepath.Join(pathRelativeTo, path)) + return errors.WrapPrefixf(err, path) } operand = append(operand, nodes...) return nil @@ -258,21 +272,25 @@ func (r *LocalPackageReader) readFile(path string, _ os.FileInfo) ([]*yaml.RNode } // shouldSkipFile returns true if the file should be skipped -func (r *LocalPackageReader) shouldSkipFile(path string, matcher *ignoreFilesMatcher) (bool, error) { +func (r *LocalPackageReader) shouldSkipFile(path, relPath string, matcher *ignoreFilesMatcher) (bool, error) { // check if the file is covered by a .krmignore file. if matcher.matchFile(path) { - return false, nil + return true, nil + } + + if r.FileSkipFunc != nil && r.FileSkipFunc(relPath) { + return true, nil } // check if the files are in scope for _, g := range r.MatchFilesGlob { if match, err := filepath.Match(g, filepath.Base(path)); err != nil { - return false, errors.Wrap(err) + return true, errors.Wrap(err) } else if match { - return true, nil + return false, nil } } - return false, nil + return true, nil } // initReaderAnnotations adds the LocalPackageReader Annotations to r.SetAnnotations diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/openapi/Makefile b/vendor/sigs.k8s.io/kustomize/kyaml/openapi/Makefile index f5cd8dc6770..945f1aa5261 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/openapi/Makefile +++ b/vendor/sigs.k8s.io/kustomize/kyaml/openapi/Makefile @@ -1,7 +1,10 @@ # Copyright 2020 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 -MYGOBIN := $(shell go env GOPATH)/bin +MYGOBIN = $(shell go env GOBIN) +ifeq ($(MYGOBIN),) +MYGOBIN = $(shell go env GOPATH)/bin +endif API_VERSION := "v1.19.1" .PHONY: all diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/openapi/openapi.go b/vendor/sigs.k8s.io/kustomize/kyaml/openapi/openapi.go index cfe18e469cd..5b7857606ba 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/openapi/openapi.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/openapi/openapi.go @@ -44,10 +44,9 @@ type openapiData struct { // Kubernetes schema as part of the global schema noUseBuiltInSchema bool - // currentOpenAPIVersion stores the version if the kubernetes openapi data - // that is currently stored as the schema, so that we only reparse the - // schema when necessary (to speed up performance) - currentOpenAPIVersion string + // schemaInit stores whether or not we've parsed the schema already, + // so that we only reparse the when necessary (to speed up performance) + schemaInit bool } // ResourceSchema wraps the OpenAPI Schema. @@ -477,27 +476,28 @@ func GetSchemaVersion() string { // initSchema parses the json schema func initSchema() { + if globalSchema.schemaInit { + return + } + globalSchema.schemaInit = true + if customSchema != nil { - ResetOpenAPI() err := parse(customSchema) if err != nil { panic("invalid schema file") } - if err := parse(kustomizationapi.MustAsset(kustomizationAPIAssetName)); err != nil { + if err = parse(kustomizationapi.MustAsset(kustomizationAPIAssetName)); err != nil { // this should never happen panic(err) } return } - currentVersion := kubernetesOpenAPIVersion - if currentVersion == "" { - currentVersion = kubernetesOpenAPIDefaultVersion + if kubernetesOpenAPIVersion == "" { + parseBuiltinSchema(kubernetesOpenAPIDefaultVersion) + } else { + parseBuiltinSchema(kubernetesOpenAPIVersion) } - if globalSchema.currentOpenAPIVersion != currentVersion { - parseBuiltinSchema(currentVersion) - } - globalSchema.currentOpenAPIVersion = currentVersion } // parseBuiltinSchema calls parse to parse the json schemas diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go index 22e5d326efa..9b1b5ff1b1e 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "log" + "regexp" "strconv" "strings" @@ -336,6 +337,33 @@ func (rn *RNode) SetYNode(node *yaml.Node) { *rn.value = *node } +// GetKind returns the kind. +func (rn *RNode) GetKind() string { + node, err := rn.Pipe(FieldMatcher{Name: KindField}) + if err != nil { + return "" + } + return GetValue(node) +} + +// GetName returns the name. +func (rn *RNode) GetName() string { + f := rn.Field(MetadataField) + if f.IsNilOrEmpty() { + return "" + } + f = f.Value.Field(NameField) + if f.IsNilOrEmpty() { + return "" + } + return f.Value.YNode().Value +} + +// SetName sets the metadata name field. +func (rn *RNode) SetName(name string) error { + return rn.SetMapField(NewScalarRNode(name), MetadataField, NameField) +} + // GetNamespace gets the metadata namespace field. func (rn *RNode) GetNamespace() (string, error) { meta, err := rn.GetMeta() @@ -752,7 +780,7 @@ func (rn *RNode) GetValidatedMetadata() (ResourceMeta, error) { return m, nil } -// MatchesAnnotationSelector implements ifc.Kunstructured. +// MatchesAnnotationSelector returns true on a selector match to annotations. func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) { s, err := labels.Parse(selector) if err != nil { @@ -765,7 +793,7 @@ func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) { return s.Matches(labels.Set(slice)), nil } -// MatchesLabelSelector implements ifc.Kunstructured. +// MatchesLabelSelector returns true on a selector match to labels. func (rn *RNode) MatchesLabelSelector(selector string) (bool, error) { s, err := labels.Parse(selector) if err != nil { @@ -780,9 +808,8 @@ func (rn *RNode) MatchesLabelSelector(selector string) (bool, error) { // HasNilEntryInList returns true if the RNode contains a list which has // a nil item, along with the path to the missing item. -// TODO(broken): This was copied from -// api/k8sdeps/kunstruct/factory.go//checkListItemNil -// and doesn't do what it claims to do (see TODO in unit test and pr 1513). +// TODO(broken): This doesn't do what it claims to do. +// (see TODO in unit test and pr 1513). func (rn *RNode) HasNilEntryInList() (bool, string) { return hasNilEntryInList(rn.value) } @@ -859,3 +886,123 @@ func checkKey(key string, elems []*Node) bool { } return count == len(elems) } + +// Deprecated: use pipes instead. +// GetSlice returns the contents of the slice field at the given path. +func (rn *RNode) GetSlice(path string) ([]interface{}, error) { + value, err := rn.GetFieldValue(path) + if err != nil { + return nil, err + } + if sliceValue, ok := value.([]interface{}); ok { + return sliceValue, nil + } + return nil, fmt.Errorf("node %s is not a slice", path) +} + +// Deprecated: use pipes instead. +// GetString returns the contents of the string field at the given path. +func (rn *RNode) GetString(path string) (string, error) { + value, err := rn.GetFieldValue(path) + if err != nil { + return "", err + } + if v, ok := value.(string); ok { + return v, nil + } + return "", fmt.Errorf("node %s is not a string: %v", path, value) +} + +// Deprecated: use slash paths instead. +// GetFieldValue finds period delimited fields. +// TODO: When doing kustomize var replacement, which is likely a +// a primary use of this function and the reason it returns interface{} +// rather than string, we do conversion from Nodes to Go types and back +// to nodes. We should figure out how to do replacement using raw nodes, +// assuming we keep the var feature in kustomize. +// The other end of this is: refvar.go:updateNodeValue. +func (rn *RNode) GetFieldValue(path string) (interface{}, error) { + fields := convertSliceIndex(strings.Split(path, ".")) + rn, err := rn.Pipe(Lookup(fields...)) + if err != nil { + return nil, err + } + if rn == nil { + return nil, NoFieldError{path} + } + yn := rn.YNode() + + // If this is an alias node, resolve it + if yn.Kind == yaml.AliasNode { + yn = yn.Alias + } + + // Return value as map for DocumentNode and MappingNode kinds + if yn.Kind == yaml.DocumentNode || yn.Kind == yaml.MappingNode { + var result map[string]interface{} + if err := yn.Decode(&result); err != nil { + return nil, err + } + return result, err + } + + // Return value as slice for SequenceNode kind + if yn.Kind == yaml.SequenceNode { + var result []interface{} + if err := yn.Decode(&result); err != nil { + return nil, err + } + return result, nil + } + if yn.Kind != yaml.ScalarNode { + return nil, fmt.Errorf("expected ScalarNode, got Kind=%d", yn.Kind) + } + + switch yn.Tag { + case NodeTagString: + return yn.Value, nil + case NodeTagInt: + return strconv.Atoi(yn.Value) + case NodeTagFloat: + return strconv.ParseFloat(yn.Value, 64) + case NodeTagBool: + return strconv.ParseBool(yn.Value) + default: + // Possibly this should be an error or log. + return yn.Value, nil + } +} + +// convertSliceIndex traverses the items in `fields` and find +// if there is a slice index in the item and change it to a +// valid Lookup field path. For example, 'ports[0]' will be +// converted to 'ports' and '0'. +func convertSliceIndex(fields []string) []string { + var res []string + for _, s := range fields { + if !strings.HasSuffix(s, "]") { + res = append(res, s) + continue + } + re := regexp.MustCompile(`^(.*)\[(\d+)\]$`) + groups := re.FindStringSubmatch(s) + if len(groups) == 0 { + // no match, add to result + res = append(res, s) + continue + } + if groups[1] != "" { + res = append(res, groups[1]) + } + res = append(res, groups[2]) + } + return res +} + +type NoFieldError struct { + Field string +} + +func (e NoFieldError) Error() string { + return fmt.Sprintf("no field named '%s'", e.Field) +} diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/walk/associative_sequence.go b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/walk/associative_sequence.go index 3b6222a9a4b..7657ebc0fac 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/walk/associative_sequence.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/walk/associative_sequence.go @@ -53,14 +53,27 @@ func appendListNode(dst, src *yaml.RNode, keys []string) (*yaml.RNode, error) { v = append(v, valueNode.YNode().Value) } + // When there are multiple keys, ElementSetter appends the node to dst + // even if the output is already in dst. We remove the node from dst to + // prevent duplicates. + if len(keys) > 1 { + _, err = dst.Pipe(yaml.ElementSetter{ + Keys: keys, + Values: v, + }) + if err != nil { + return nil, err + } + } + // We use the key and value from elem to find the corresponding element in dst. // Then we will use ElementSetter to replace the element with elem. If we cannot + // find the item, the element will be appended. _, err = dst.Pipe(yaml.ElementSetter{ Element: elem, Keys: keys, Values: v, }) - if err != nil { return nil, err } @@ -97,6 +110,47 @@ func validateKeys(valuesList [][]string, values []string, keys []string) ([]stri return validKeys, validValues } +// mergeValues merges values together - e.g. if two containerPorts +// have the same port and targetPort but one has an empty protocol +// and the other doesn't, they are treated as the same containerPort +func mergeValues(valuesList [][]string) [][]string { + for i, values1 := range valuesList { + for j, values2 := range valuesList { + if matched, values := match(values1, values2); matched { + valuesList[i] = values + valuesList[j] = values + } + } + } + return valuesList +} + +// two values match if they have at least one common element and +// corresponding elements only differ if one is an empty string +func match(values1 []string, values2 []string) (bool, []string) { + if len(values1) != len(values2) { + return false, nil + } + var commonElement bool + var res []string + for i := range values1 { + if values1[i] == values2[i] { + commonElement = true + res = append(res, values1[i]) + continue + } + if values1[i] != "" && values2[i] != "" { + return false, nil + } + if values1[i] != "" { + res = append(res, values1[i]) + } else { + res = append(res, values2[i]) + } + } + return commonElement, res +} + // setAssociativeSequenceElements recursively set the elements in the list func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []string, dest *yaml.RNode) (*yaml.RNode, error) { // itemsToBeAdded contains the items that will be added to dest @@ -105,6 +159,9 @@ func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []st if l.Schema != nil { schema = l.Schema.Elements() } + if len(keys) > 1 { + valuesList = mergeValues(valuesList) + } // each element in valuesList is a list of values corresponding to the keys // for example, for the following yaml: @@ -114,12 +171,14 @@ func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []st // protocol: TCP // `keys` would be [containerPort, protocol] // and `valuesList` would be [ [8080, UDP], [8080, TCP] ] + var validKeys []string + var validValues []string for _, values := range valuesList { if len(values) == 0 { continue } - validKeys, validValues := validateKeys(valuesList, values, keys) + validKeys, validValues = validateKeys(valuesList, values, keys) val, err := Walker{ VisitKeysAsScalars: l.VisitKeysAsScalars, InferAssociativeLists: l.InferAssociativeLists, @@ -144,7 +203,7 @@ func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []st return nil, err } exit = true - } else if val.Field(key) == nil { + } else if val.Field(key) == nil && validValues[i] != "" { // make sure the key is set on the field _, err = val.Pipe(yaml.SetField(key, yaml.NewScalarRNode(validValues[i]))) if err != nil { @@ -162,7 +221,7 @@ func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []st _, err = itemsToBeAdded.Pipe(yaml.ElementSetter{ Element: val.YNode(), Keys: validKeys, - Values: values, + Values: validValues, }) if err != nil { return nil, err @@ -171,7 +230,6 @@ func (l *Walker) setAssociativeSequenceElements(valuesList [][]string, keys []st var err error if len(valuesList) > 0 { - validKeys, _ := validateKeys(valuesList, valuesList[0], keys) if l.MergeOptions.ListIncreaseDirection == yaml.MergeOptionsListPrepend { // items from patches are needed to be prepended. so we append the // dest to itemsToBeAdded @@ -314,6 +372,7 @@ func (l Walker) elementPrimitiveValues() [][]string { // fieldValue returns a slice containing each source's value for fieldName func (l Walker) elementValueList(keys []string, values []string) []*yaml.RNode { + keys, values = validateKeys([][]string{values}, values, keys) var fields []*yaml.RNode for i := range l.Sources { if l.Sources[i] == nil {