Compare commits

...

238 Commits

Author SHA1 Message Date
Kubernetes Prow Robot
3c321ef79c Merge pull request #4138 from KnVerey/pinToCmdConfig
Pin to cmd/config v0.10.0
2021-08-24 11:38:58 -07:00
Katrina Verey
7938fdb596 Pin to cmd/config v0.10.0 2021-08-24 11:27:56 -07:00
Kubernetes Prow Robot
a2111869e6 Merge pull request #4137 from KnVerey/pinToKyaml
Pin to kyaml v0.11.1
2021-08-24 11:10:59 -07:00
Katrina Verey
f8288e2f02 Pin to kyaml v0.11.1 2021-08-24 10:59:16 -07:00
Jeff Regan
f2f90d1185 Merge pull request #4114 from monopole/anchorsAweigh
Add YAML anchor/alias expansion.
2021-08-24 09:51:49 -07:00
Kubernetes Prow Robot
459e800ecf Merge pull request #4134 from phanimarupaka/FieldOrderingForNullFields
Preserve field order: Add test for null value
2021-08-23 16:44:14 -07:00
Phani Teja Marupaka
8f00d3fd53 Add test for null value 2021-08-21 15:58:49 -07:00
Kubernetes Prow Robot
cd94cb13c6 Merge pull request #4132 from natasha41575/moveWorkDirCheck
move check for working dir for exec functions
2021-08-20 11:11:31 -07:00
Natasha Sarkar
e100be620e move check for working dir for exec functions 2021-08-20 10:59:29 -07:00
Natasha Sarkar
1e1b9b484a exec function working dir is the kustomization that referenced it (#4125)
* exec function working dir is the kustomization that referenced it

* suggested changes

* more code review

* use a field instead of an annotation

* more code review
2021-08-19 20:15:24 -07:00
monopole
360585dfaf Add YAML anchor/alias expansion. 2021-08-19 11:55:09 -07:00
Kubernetes Prow Robot
f604619dd5 Merge pull request #4086 from campoy/pkgio-writer-filesys
Add FileSystem interface to LocalPackageWriter
2021-08-19 11:51:25 -07:00
Francesc Campoy
0fa056327a Skip in-memory tests for Windows and generate temporary directories correctly for Windows tests. 2021-08-19 10:27:39 -07:00
Francesc Campoy
6db2bf69f3 Add FileSystem interface to LocalPackageReadWriter and hook to LocalPackageWriter 2021-08-19 10:27:38 -07:00
Francesc Campoy
20fb9578c0 Adapt tests to new FileSystem field 2021-08-19 10:27:38 -07:00
Francesc Campoy
4eb8232495 Added FileSystem field to kio.LocalPackageWriter 2021-08-19 10:27:38 -07:00
Jeff Regan
6c4e8019f8 Merge pull request #4094 from brianpursley/merge3-test
Add unit tests to cover existing behavior of three way merge and strategic merge patch
2021-08-19 07:41:18 -07:00
Jeff Regan
28707bf5df Merge pull request #4065 from natasha41575/originDataAsAnnotation
option for origin data as annotation
2021-08-18 19:08:54 -07:00
Mike Borozdin
023a580f00 support for darwin and linux (#4122)
* support for darwin and linux

* updated to use go for env variables
2021-08-17 15:58:08 -07:00
Kubernetes Prow Robot
a2eaae5555 Merge pull request #4113 from KnVerey/kyaml_container_patch_kinds
Enable fn framework container patches to work with more kinds
2021-08-17 11:31:13 -07:00
Katrina Verey
75df1a5422 kyaml presubmit formatting 2021-08-17 11:13:54 -07:00
Katrina Verey
f0b4cc4581 ContainerPatch supports all common workload paths 2021-08-17 11:13:52 -07:00
Katrina Verey
7a41e479c9 Filter helper for fallback field lookup 2021-08-17 11:13:10 -07:00
Natasha Sarkar
3350c7213c option for origin data as annotation 2021-08-12 20:09:41 -07:00
Adrian Berger
7b5e43d343 Feature: Add edit set annotation (#4073)
* Add edit set annotation feature

* Apply suggested code improvements

* Apply suggested changes

* Fix regex, add more tests

* Add constant for common error message

* Fix too many characters per line error

* Use string concatenation instead, add FailNow call
2021-08-10 16:00:40 -07:00
Kubernetes Prow Robot
06661ea310 Merge pull request #4112 from natasha41575/updateOpenAPI
update openapi to v1.21.2
2021-08-10 10:44:40 -07:00
Natasha Sarkar
38b2b33503 update openapi to v1.21.2 2021-08-10 10:30:12 -07:00
Natasha Sarkar
f735d6fb3a Merge pull request #4110 from KnVerey/update-openapi-scripts
Update openapi updater scripts
2021-08-10 09:38:11 -07:00
Katrina Verey
5cb5e07ac0 Update openapi updater scripts 2021-08-09 11:44:27 -07:00
Kubernetes Prow Robot
54778504ed Merge pull request #4087 from campoy/fsnode-alias-fix
Avoid aliasing in fsnode by forcing copies for file contents
2021-08-04 20:32:56 -07:00
Kubernetes Prow Robot
1bfe0d08dc Merge pull request #4102 from monopole/anchorsNotHonored
Kyaml anchor failure test.
2021-08-04 19:40:55 -07:00
monopole
56da9a58fc Kyaml anchor failure test. 2021-08-04 17:10:04 -07:00
Kubernetes Prow Robot
54383bca25 Merge pull request #4085 from campoy/pkgio-reader-filesys
Add a filesys.FileSystem interface to kio.LocalPackageReader
2021-08-03 15:33:04 -07:00
Kubernetes Prow Robot
88461b4fed Merge pull request #4088 from natasha41575/noMoreGenArgs
replace genargs with two separate annotations
2021-08-03 14:07:03 -07:00
brianpursley
aabbea3e78 Add unit tests for current behavior of strategic merge patch 2021-08-02 20:36:55 -04:00
brianpursley
adedca09f2 Add unit tests for current behavior of three way merge 2021-08-02 20:36:28 -04:00
Natasha Sarkar
9a27a9f19f replace genargs with two separate annotations 2021-07-29 15:46:09 -07:00
Kubernetes Prow Robot
3ebdb3fcef Merge pull request #4091 from natasha41575/RemovePathAnno
remove annotations added by the kyaml reader
2021-07-28 11:28:48 -07:00
Natasha Sarkar
97e7cb1512 remove annotations added by the kyaml reader 2021-07-27 17:56:58 -07:00
Francesc Campoy
262a2d9288 Avoid testing in memory for Windows tests 2021-07-26 16:14:46 -07:00
Kubernetes Prow Robot
91b862b556 Merge pull request #4084 from kubernetes-sigs/kustomize-in-kubectl-1.22
Update kustomize-in-kubectl chart for 1.22
2021-07-26 13:42:34 -07:00
Katrina Verey
b8ffc725c7 Update kustomize-in-kubectl chart for 1.22 2021-07-26 13:23:45 -07:00
Jeff Regan
76f1411922 Merge pull request #4082 from monopole/autoChanges
Automated go.sum and fmt changes under go 1.16.6
2021-07-24 09:42:29 -07:00
monopole
d1003d6f8f Automated changes under go 1.16.6 2021-07-24 09:18:58 -07:00
Natasha Sarkar
91f74e8d16 replace Resource.options with annotations (#4061) 2021-07-23 18:19:05 -07:00
Kubernetes Prow Robot
94c5096a95 Merge pull request #4048 from natasha41575/DeprecateCfgCmds
Deprecate some cfg commands
2021-07-21 18:15:51 -07:00
Kubernetes Prow Robot
f35aeb6a8e Merge pull request #4077 from abutcher/cdpath
Unset CDPATH in hack/install_kustomize.sh
2021-07-21 10:14:07 -07:00
Kubernetes Prow Robot
d6ce846047 Merge pull request #4076 from KnVerey/kyaml_fixture_fix
Make UpdateExpectedFromActual work with hierarchical testdata directories
2021-07-21 08:52:08 -07:00
Andrew Butcher
ec069e4f19 Unset CDPATH to restore default cd behavior. 2021-07-21 11:38:44 -04:00
Katrina Verey
c5adafd9ce Make UpdateExpectedFromActual work with hierarchical testdata directories 2021-07-20 18:13:04 -07:00
Natasha Sarkar
16dcc98cff deprecate some cfg commands 2021-07-19 14:31:20 -07:00
Kubernetes Prow Robot
59c410a70a Merge pull request #4063 from dosmanak/mdrip_MYGOBIN
fix: Allow custom MYGOBIN in mdrip invocations
2021-07-19 10:30:52 -07:00
Francesc Campoy
9b586162d0 Add FileSystem interface to LocalPackageReadWriter and hook to LocalPackageReader 2021-07-16 14:48:22 -07:00
Francesc Campoy
803885049b Avoid aliasing in fsnode by forcing copies for file contents and add a test 2021-07-16 13:56:08 -07:00
Francesc Campoy
be4fe7540e Simplified tests with helper func 2021-07-16 11:06:32 -07:00
Francesc Campoy
927568eea2 Replace os.Stat call with FileSystem.Exists 2021-07-16 09:27:20 -07:00
Francesc Campoy
436d5e717c All LocalPackageReader tests adapted, one fails 2021-07-16 09:12:42 -07:00
Francesc Campoy
d37fa66ebc Adapt more LocalPackageReader tests 2021-07-15 18:21:42 -07:00
Francesc Campoy
e8a4bf6edc Add FileSystem field to LocalPackageReader and one of its tests 2021-07-15 18:06:30 -07:00
Kubernetes Prow Robot
35d1c3f9b4 Merge pull request #4072 from natasha41575/Revert
revert 'fix kyaml issue with multiline scalars'
2021-07-15 14:37:02 -07:00
Natasha Sarkar
e17785af21 revert 'fix kyaml issue with multiline scalars' 2021-07-15 14:24:39 -07:00
Natasha Sarkar
0537b59f27 support yaml formatted openapi schema (#4017)
* support yaml formatted openapi schema

* suggested changes
2021-07-15 14:11:02 -07:00
Kubernetes Prow Robot
339e33d2f3 Merge pull request #4071 from KnVerey/update-yaml-script
Update fork updater script
2021-07-15 10:06:45 -07:00
Natasha Sarkar
f082ac02cf fix multiline scalar value issue 2021-07-15 08:41:03 -07:00
Katrina Verey
9538ae1258 Update fork updater script 2021-07-15 08:31:32 -07:00
Kubernetes Prow Robot
34981b664f Merge pull request #4069 from natasha41575/LineBreakIssue
fix kyaml issue with multiline scalars
2021-07-14 16:20:47 -07:00
Natasha Sarkar
477d8930e0 fix kyaml issue with multiline scalars 2021-07-14 15:19:21 -07:00
Kubernetes Prow Robot
b5091a566a Merge pull request #4067 from natasha41575/demonstrateLineBreakIssue
demonstrate line break preservation issue in kyaml
2021-07-14 11:52:18 -07:00
Natasha Sarkar
9981c45554 demonstrate line break preservation issue in kyaml 2021-07-14 11:39:14 -07:00
phani
0f736ec7fd Handle comments for seq indent derivation (#4064)
* Handle comments for seq indent derivation

* Suggested changes
2021-07-13 17:46:26 -07:00
Kubernetes Prow Robot
7826ad1e06 Merge pull request #4031 from rjferguson21/prefix-overlay-fail
Add failing test for replacements when using an overlay with a namePrefix
2021-07-13 14:42:01 -07:00
Frank Farzan
f4e6816338 Expand documentation of annotations used in manifests and KRM functions API (#3995)
* Expand documentation of annotations used in manifests and KRM function wire format.

- Reserve `internal.config.kubernetes.io` for control annotations
- Document `local-config` annotation in a seperate document (It's
  orthogonal to KRM functions).
- There is a internal annotation that uses `config.k8s.io` instead of
  `config.kubernetes.io` used by other annotations. See [1] and [2]. We
  should avoid using two seperate annotation prefixes and audit the
  codebase for any other annotation. Given the `id` control annotation is used
  for comment preservation (no existing function should be modifying
  it), I suggest moving this over to use
  `fn-ctrl.config.kubernets.io/id`.

[1]: 7e8ba62e9f/kyaml/fn/runtime/runtimeutil/runtimeutil.go (L195)
[2]: https://github.com/kubernetes-sigs/kustomize/pull/2465

* Move path/index annotation to use internal prefix

* Clarify MUST NOT vs SHOULD NOT for internal annotations

* Update cmd/config/docs/api-conventions/functions-spec.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update cmd/config/docs/api-conventions/functions-spec.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update cmd/config/docs/api-conventions/manifest-annotations.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Remove kusotmization as example

Co-authored-by: Katrina Verey <kn.verey@gmail.com>
2021-07-13 11:58:00 -07:00
Kubernetes Prow Robot
4a13725678 Merge pull request #4043 from phanimarupaka/PreserveIndentation
Make seq indent configurable and add retain seq indent functionality
2021-07-13 10:24:30 -07:00
Petr Studeny
ab9b010856 fix: Allow custom MYGOBIN in mdrip invokations 2021-07-13 14:34:50 +02:00
Phani Teja Marupaka
29be7fabe4 Suggested changes 2021-07-12 23:34:03 -07:00
Phani Teja Marupaka
74e867833a First sequence indent wins 2021-07-09 14:10:30 -07:00
Rob Ferguson
91dc6d2a0f add additional replacement transformer test with todos for failures 2021-07-09 12:45:47 -05:00
Rob Ferguson
3c1fd0e9cf add replacement test failures 2021-07-09 10:39:38 -05:00
Rob Ferguson
4deeb7d59b make replacement transformer test pass and add todo 2021-07-09 09:49:08 -05:00
Phani Teja Marupaka
89b12cfc62 Change annotation name, error if conflicting options 2021-07-09 01:32:48 -07:00
Phani Teja Marupaka
c07ffa5c1e Update comments, tests, not expose indent option 2021-07-09 00:17:09 -07:00
Kubernetes Prow Robot
259fcfcef8 Merge pull request #4002 from natasha41575/resref
replace Resource.refBy with annotations
2021-07-08 17:26:54 -07:00
Phani Teja Marupaka
f81201b74d Add options, keep seqindent annotation equivalent to index annotation 2021-07-08 14:54:23 -07:00
Phani Teja Marupaka
6dbc74b32e Suggested changes 2021-07-07 23:22:15 -07:00
Phani Teja Marupaka
ed38b5fe2b Make seq indent configurable and add retain seq indent functionality 2021-07-07 16:53:40 -07:00
Natasha Sarkar
a84badb834 replace Resource.refBy with annotations 2021-07-07 15:22:36 -07:00
phani
e1804cbc76 Retain field order after running any arbitrary functions on resources (#4021)
* Reorder resource fields

* Fix comment conflict

* Update e2e test ordering

* Suggested changes
2021-07-07 10:12:44 -07:00
Kubernetes Prow Robot
d13eef7951 Merge pull request #4040 from zhouhaibing089/fix-iampolicy-mod
iampolicygenerator: update module name
2021-07-07 09:46:44 -07:00
Kubernetes Prow Robot
0b4c6baf44 Merge pull request #4039 from zhouhaibing089/handle-dot-git-suffix
api/internal/git: handle .git suffix in repospec
2021-07-07 09:24:43 -07:00
Haibing Zhou
b3af54340c iampolicygenerator: update module name
The previous module name is incorrect and seems to be copied from
another builtin plugin. This change fixes the name.
2021-07-05 14:11:32 -07:00
Haibing Zhou
8c14b9d1af api/internal/git: handle .git suffix in repospec
This change adds a new test case for parsing url with `.git` suffix. In
that case, we should have the full url as clone spec with an empty
abspath.
2021-07-05 13:10:35 -07:00
Natasha Sarkar
d818ccae92 Merge pull request #4037 from natasha41575/pin
Unpin modules
2021-07-02 14:25:03 -07:00
Natasha Sarkar
4cea8b9785 Unpin modules 2021-07-02 14:10:05 -07:00
Kubernetes Prow Robot
84a36801e0 Merge pull request #4036 from joebowbeer/patch-1
Fix broken KEP link in README
2021-07-02 13:58:10 -07:00
Joe Bowbeer
6eb7b3508d Fix broken KEP link in README 2021-07-02 13:12:22 -07:00
Rob Ferguson
2a5f4ac7d7 add failing test for replacements 2021-07-02 08:54:52 -05:00
Kubernetes Prow Robot
518a16d3ac Merge pull request #4014 from brianpursley/doc-separator
Updated ByteReader to allow white space and comments content after --- when splitting YAML documents
2021-07-01 14:25:51 -07:00
Jeff Regan
d53a2ad45d Merge pull request #4027 from monopole/deleteWindowsBuild
Temporarily remove windows build.
2021-06-30 15:37:56 -07:00
monopole
bb02a7645b Temporarily remove windows build. 2021-06-30 15:36:57 -07:00
Jeff Regan
5a9d90c872 Merge pull request #4026 from monopole/upgradeGoReleaser
release process: upgrade to goreleaser v0.172.1 calling go1.16.5
2021-06-30 14:04:18 -07:00
monopole
4fd7269643 release process: upgrade to goreleaser v0.172.1 calling go go1.16.5 2021-06-30 14:02:55 -07:00
Kubernetes Prow Robot
1eb3c1a075 Merge pull request #4025 from KnVerey/pinToApi
Pin to api v0.8.11
2021-06-30 12:53:03 -07:00
Katrina Verey
a1746f2f8c Pin to api v0.8.11 2021-06-30 12:42:04 -07:00
Kubernetes Prow Robot
b727febd08 Merge pull request #4023 from mengqiy/jsontag
add missing json tags
2021-06-30 12:37:03 -07:00
Natasha Sarkar
c819d69ae4 Merge pull request #4022 from KnVerey/pinToCmdConfig
Pin to cmd/config v0.9.13
2021-06-30 12:26:40 -07:00
Katrina Verey
bb6f83fb96 Pin to cmd/config v0.9.13 2021-06-30 12:16:04 -07:00
Mengqi Yu
02d14d724a add missing json tags 2021-06-30 12:15:50 -07:00
Katrina Verey
aa92d83d8c Pin to kyaml (#4020)
* Pin to kyaml

* Pin prefixsuffixtransformer to kyaml 0.11.0

* Pin replicacounttransformer to kyaml 0.11.0
2021-06-30 11:59:03 -07:00
Natasha Sarkar
5427ab7cc3 Merge pull request #4013 from KnVerey/go-yaml-fork
Internal go-yaml/yaml fork
2021-06-30 10:41:27 -07:00
Katrina Verey
e583f199b8 Comment out part of script that is likely only needed on first run 2021-06-30 10:18:11 -07:00
Katrina Verey
b465c20f65 Remove pinning to external fork 2021-06-30 10:15:02 -07:00
Natasha Sarkar
5c2c617ff0 fix affected cmd/config tests 2021-06-30 10:14:45 -07:00
Natasha Sarkar
3ab0665c19 fix affected kyaml tests 2021-06-30 10:14:45 -07:00
Natasha Sarkar
4b66043735 compact sequence indent 2021-06-30 10:14:45 -07:00
Natasha Sarkar
979f03e76c remove serialization hack after bump 2021-06-30 10:14:44 -07:00
Natasha Sarkar
c8b049f57f point to natasha's fork 2021-06-30 10:14:33 -07:00
Katrina Verey
f3d8883046 Internalize forked code 2021-06-30 10:13:33 -07:00
Natasha Sarkar
e308f321d3 fix leading newline issue 2021-06-30 10:13:33 -07:00
Natasha Sarkar
beea785ead tests for compactSeqIndent 2021-06-30 10:13:33 -07:00
Natasha Sarkar
95c5b686be add defaultSeqIndent method 2021-06-30 10:13:32 -07:00
Natasha Sarkar
0ddf68cc8a compact sequence indentation option 2021-06-30 10:13:32 -07:00
Katrina Verey
4cadad5cfe Internal copy of go-yaml at 496545a6307b2a7d7a710fd516e5e16e8ab62dbc 2021-06-30 10:13:30 -07:00
Katrina Verey
9e4a6397d6 Instructions and script for go-yaml fork 2021-06-28 17:04:04 -07:00
Katrina Verey
2e8a3b7c45 Use the forked go-yaml module 2021-06-28 15:29:32 -07:00
Kubernetes Prow Robot
276d0430bf Merge pull request #4018 from phanimarupaka/DontAddFormatTags
Handle null values while formatting
2021-06-27 17:05:24 -07:00
Phani Teja Marupaka
1aa7a1e709 Handle null values while formatting 2021-06-27 16:55:16 -07:00
brianpursley
78737f5a38 Updated ByteReader to allow white space and comments on the same line after --- and throw an error if anything else is detected 2021-06-24 21:32:39 -04:00
Kubernetes Prow Robot
dac84d867e Merge pull request #4010 from natasha41575/openapicommanddocs
fix openapi command help page
2021-06-23 08:54:10 -07:00
Natasha Sarkar
217e5c7268 fix openapi command help page 2021-06-22 18:46:34 -07:00
Jeff Regan
936ac37a2e Update repospec_test.go 2021-06-21 14:30:11 -07:00
Kubernetes Prow Robot
cb4f5c3983 Merge pull request #4006 from runewake2/validate-data-map
Introduce Validate Data Map Function
2021-06-18 12:34:06 -07:00
Sam Wronski
1801d33287 Add error when datamap is nil 2021-06-18 10:14:17 -07:00
Sam Wronski
b01da61d83 Update argument name 2021-06-17 16:12:09 -07:00
Natasha Sarkar
23e28bb18a change marshal indent to 2 (#4005) 2021-06-17 13:34:04 -07:00
Sam Wronski
a1f1c2d32f Add documentation 2021-06-17 11:47:56 -07:00
Sam Wronski
10331d9560 Add GetValidatedDataMap to rnode 2021-06-17 01:46:35 -07:00
Francesc Campoy
60038d44f9 Add filesys.FileSystem to ignoreFileMatcher (#3994) 2021-06-16 17:16:20 -07:00
Kubernetes Prow Robot
24d06f83ca Merge pull request #3998 from yhrn/star-fix
Remove debug fmt.Println breaking kpt Starlark output
2021-06-16 15:53:59 -07:00
Kubernetes Prow Robot
e76638f98d Merge pull request #4000 from KnVerey/readme_update
Update kubectl kustomize section of readme
2021-06-16 14:47:59 -07:00
Kubernetes Prow Robot
ef1b9d4854 Merge pull request #3999 from campoy/patch-1
Test api in workflows
2021-06-16 14:29:59 -07:00
Katrina Verey
3c0f805674 Update kubectl kustomize section of readme 2021-06-16 14:26:40 -07:00
Francesc Campoy
324581594c Test api for all platforms and skip those breaking on Windows 2021-06-16 14:18:48 -07:00
Francesc Campoy
7fae7d1bd6 Move api/filesys to kyaml/filesys (#3997)
* Move api/filesys to kyaml/filesys

* Add deprecated version of api/filesys with aliases to new code

* Use new kyaml/filesys package and update dependencies

* Migrate to kyaml/filesys and update dependencies

* Skip tests that break on Windows
2021-06-16 11:42:00 -07:00
Mattias Öhrn
0af3a75708 Remove debug fmt.Println breaking kpt Starlark output 2021-06-16 12:27:17 +02:00
Kubernetes Prow Robot
d39d7db9ed Merge pull request #3966 from pacoxu/json-patch-v4.11.0
json-patch upgrade to v4.11.0
2021-06-15 15:25:43 -07:00
Kubernetes Prow Robot
a04a6de0ef Merge pull request #3991 from natasha41575/convertvarstoreplacements
convert vars to replacements: mapping value with dot
2021-06-15 15:07:43 -07:00
Kubernetes Prow Robot
69a6708f9b Merge pull request #3996 from khrisrichardson/kustomize-build-as-current-user
expose --as-current-user flag to kustomize build command
2021-06-15 12:53:43 -07:00
Khris Richardson
c19a972739 expose --as-current-user via AddFunctionBasicsFlags 2021-06-15 12:30:37 -07:00
Khris Richardson
2e674337b3 expose --as-current-user via GetRunFnRunner 2021-06-15 12:30:17 -07:00
Khris Richardson
727e24f365 append AsCurrentUser to FnPluginLoadingOptions 2021-06-15 12:29:59 -07:00
Natasha Sarkar
7e8ba62e9f Merge pull request #3986 from campoy/filesys-default
Filesys default
2021-06-14 12:55:35 -07:00
Kubernetes Prow Robot
fe60d0c403 Merge pull request #3992 from mortent/AllowErrorForResourceHandler
Allow the Handle function of the ResourceHandler interface to return an error
2021-06-14 09:55:04 -07:00
Morten Torkildsen
2e0556b544 Allow the Handle function of the ResourceHandler interface to return an error 2021-06-13 15:06:08 -07:00
Kubernetes Prow Robot
479acac581 Merge pull request #3987 from mortent/AddResourceHandlerForMerge3
Allow users to customize handling of deleted resources for merge3
2021-06-11 18:19:00 -07:00
Natasha Sarkar
3b37fed24b convert vars to replacements: mapping value with dot 2021-06-11 13:45:04 -07:00
Kubernetes Prow Robot
8fdb3f1703 Merge pull request #3926 from natasha41575/ConvertVarsToReplacements
convert vars to replacements
2021-06-11 13:01:00 -07:00
Morten Torkildsen
95e242353b Allow users to customize handling of deleted resources for merge3 2021-06-11 11:37:24 -07:00
Francesc Campoy
199802a176 Ensure 'not exist' errors wrap os.ErrNotExist (#3982)
* Ensure 'not exist' errors wrap os.ErrNotExist

* Update go.sum

* Use an error type to avoid changing the error's string
2021-06-11 09:44:59 -07:00
Kubernetes Prow Robot
065432e074 Merge pull request #3984 from natasha41575/replacementWithDot
Replacement with dot
2021-06-10 18:12:13 -07:00
Francesc Campoy
62fd36facb Updating go.sum 2021-06-10 16:56:50 -07:00
Natasha Sarkar
f121e74744 convert vars to replacements 2021-06-10 15:29:28 -07:00
Jeff Regan
5aa2f534be Merge pull request #3985 from monopole/stringslice
Gather some string slice utils.
2021-06-10 14:30:15 -07:00
monopole
86dd74fd62 Gather some string slice utils. 2021-06-10 13:34:20 -07:00
Natasha Sarkar
218da9858f support mapping values with '.' in replacements fieldpaths 2021-06-10 11:33:05 -07:00
Natasha Sarkar
cebda58437 test for '.' in replacement mapping value 2021-06-10 11:15:05 -07:00
Francesc Campoy
6a82437bc9 Renaming to better name 2021-06-10 09:53:49 -07:00
Francesc Campoy
6b9e8eb891 Add a new type that defaults to FsOnDisk for convenience 2021-06-09 18:00:30 -07:00
Jeff Regan
615984bf2d Merge pull request #3977 from KnVerey/roadmap
Commit roadmap presented to SIG-CLI
2021-06-09 14:43:01 -07:00
Katrina Verey
bc6ac8a68a Commit roadmap presented to SIG-CLI 2021-06-09 14:37:54 -07:00
Kubernetes Prow Robot
39f24ef8d2 Merge pull request #3956 from natasha41575/ReplacementPreviousIds
replacements should be able to use previous IDs
2021-06-09 10:45:26 -07:00
pacoxu
24294d3bd0 upgrade json-patch 4.11.0
Signed-off-by: pacoxu <paco.xu@daocloud.io>
2021-06-09 12:34:19 +08:00
Jeff Regan
234fcbfc02 Update OWNERS_ALIASES 2021-06-08 16:59:45 -07:00
Jeff Regan
b54093ebca Merge pull request #3972 from KnVerey/contributor_ladder
Document contributor roles
2021-06-08 16:43:18 -07:00
Katrina Verey
db307a7084 Document contributor roles 2021-06-08 16:39:37 -07:00
Jeff Regan
a0c7997b66 Merge pull request #3963 from natasha41575/KustomizeEditFix
small `api` changes for kustomize fix
2021-06-08 13:52:06 -07:00
Natasha Sarkar
7458a53a73 copy method for selector 2021-06-08 11:18:38 -07:00
Natasha Sarkar
cf6e6ca4db omitempty for replacement type 2021-06-08 11:18:27 -07:00
Natasha Sarkar
e847ec7474 ReadDir method for filesys 2021-06-08 11:18:11 -07:00
Jeff Regan
440026b9b3 Merge pull request #3965 from mengqiy/listcomments
handle comments in list correctly
2021-06-07 17:32:53 -07:00
Kubernetes Prow Robot
64331ad845 Merge pull request #3964 from ash2k/ash2k/handle-errors2
Handle errors
2021-06-07 16:26:03 -07:00
Mengqi Yu
294070b3ab address comments 2021-06-07 15:06:57 -07:00
Mengqi Yu
cabbea0d97 handle comments in list correctly 2021-06-07 14:57:49 -07:00
Jeff Regan
732a8522df Merge pull request #3968 from monopole/fixFailingHelmTest
Don't run helm inflator test against released version.
2021-06-07 13:19:02 -07:00
monopole
8f82c4c748 Don't run helm inflator test against released version. 2021-06-07 12:26:12 -07:00
Jeff Regan
d0bc25f339 Update byteio_writer.go 2021-06-07 12:25:04 -07:00
Jeff Regan
ed3200e4f5 Remove bad TODO 2021-06-04 17:56:42 -07:00
Mikhail Mazurskiy
a3ed120efb Handle errors 2021-06-05 09:43:13 +10:00
Jeff Regan
f1b191c02f Update README.md 2021-06-04 16:22:59 -07:00
Jeff Regan
1493b24b46 Update README.md 2021-06-04 16:21:25 -07:00
Kubernetes Prow Robot
5993eae1aa Merge pull request #3934 from yhrn/fix-json-sink
Sink: Force JSON encoding for .json files
2021-06-04 11:38:38 -07:00
Mattias Öhrn
3e506eae02 PR feedback - more tests and some cleanup 2021-06-04 11:06:22 +02:00
Kubernetes Prow Robot
0305860078 Merge pull request #3962 from natasha41575/resourceRef
remove metadata field from resourceRef schema
2021-06-03 15:57:02 -07:00
Natasha Sarkar
0205090e0d remove metadata field from resourceRef schema 2021-06-03 12:46:51 -07:00
Natasha Sarkar
6adefe4562 replacements should be able to use previous IDs 2021-06-03 12:14:27 -07:00
Jeff Regan
da1bd901b4 Merge pull request #3939 from KnVerey/framework_test_helpers
[kyaml] Improvements to frameworktestutil
2021-06-03 11:14:54 -07:00
Jeff Regan
636b9c7aeb Merge pull request #3931 from natasha41575/ReplacementOverwritesSource
Fix issues with replacements
2021-06-03 10:57:01 -07:00
Mattias Öhrn
942f112ef5 Fix kyaml tests 2021-06-03 08:31:03 +02:00
Mattias Öhrn
03bbb076bf plugin/builtin/iampolicygenerator/go.sum tidy 2021-06-03 08:30:38 +02:00
Mattias Öhrn
e468d6b4d2 Fixing cmd/config/internal/commands/e2e/e2e_test.go 2021-06-03 08:29:53 +02:00
Kubernetes Prow Robot
57206a628d Merge pull request #3955 from mengqiy/betterresults
Check for empty GKNN when formatting results
2021-06-02 18:05:38 -07:00
Mengqi Yu
f061bb887b Check for empty GKNN when formatting results 2021-06-02 16:32:18 -07:00
Kubernetes Prow Robot
75fd9a43a3 Merge pull request #3925 from frankfarzan/krm-functions-spec
Fully specify KRM Functions Spec and graduate it to v1.
2021-06-02 12:10:42 -07:00
Frank Farzan
58165dfc89 comments 2021-06-02 10:53:49 -07:00
Frank Farzan
0e8257c387 comments 2021-06-02 10:50:39 -07:00
Kubernetes Prow Robot
62e78f8349 Merge pull request #3940 from Shell32-Natsu/resource-factory
add an option to include local configs
2021-06-01 17:20:12 -07:00
Natasha Sarkar
84724a3ebf smarter path splitter for replacements 2021-06-01 17:15:54 -07:00
Donny Xia
23544e0431 code review 2021-06-01 16:25:41 -07:00
Donny Xia
b1fda3d62e add an option to include local configs 2021-06-01 13:38:36 -07:00
Natasha Sarkar
b8ae69b748 copy target rnode in replacements 2021-06-01 13:24:51 -07:00
Natasha Sarkar
4014440d06 test to demonstrate '.' in list element path issue 2021-06-01 13:24:51 -07:00
Natasha Sarkar
74b0b3adc6 test to demonstrate multiple fieldpaths issue in replacements 2021-06-01 13:24:51 -07:00
Katrina Verey
382f09a126 Make frameworktestutil assertions configurable
Also refactor to share common code between results checkers
2021-06-01 12:20:23 -07:00
Katrina Verey
f9afdc5c95 Improve frameworktestutil usability with complex error messages 2021-06-01 12:20:17 -07:00
Mattias Öhrn
5e4fb4796e Only encoding non-wrapped single .json items as JSON 2021-06-01 20:44:21 +02:00
Katrina Verey
76f8988865 Mark updated tests as skipped instead of passed 2021-05-31 10:56:32 -07:00
Mattias Öhrn
fa3e829eb6 Sink: Force JSON encoding for .json files 2021-05-31 08:00:54 +02:00
Jeff Regan
d9435bd1b1 Merge pull request #3898 from dmizelle/add-helm-include-crds
Add includeCRDs Field to HelmChart
2021-05-27 16:04:07 -07:00
Kubernetes Prow Robot
af96bb4bda Merge pull request #3914 from natasha41575/GkeServiceAccountGenerator
Gke service account generator
2021-05-27 15:36:23 -07:00
Kubernetes Prow Robot
8607e0adec Merge pull request #3930 from monopole/demo3929
Demonstrate issue 3929
2021-05-26 17:04:06 -07:00
Natasha Sarkar
5a2a7709a4 add IAMPolicyGenerator 2021-05-26 16:54:38 -07:00
monopole
437e8f90f6 Demonstrate issue 3929 2021-05-26 16:29:55 -07:00
Jeff Regan
06ac670951 Merge pull request #3911 from ash2k/ash2k/handle-errors
Handle errors
2021-05-25 21:05:26 -07:00
Frank Farzan
3ee1579688 Fully specify KRM Functions Spec and graduate it to v1.
- Define the OpenAPI schema for ResourceList
- Graduate `ResourceList` to apiVersion `v1`. Many functions have been implemented
  and we are effectively treating the spec as backwards compatible.
- Add `results` field to the spec. This has been implemented in the
  orchestrator and couple of functions libraries for a while, but hasn't been
  yet standardized leading to minor discrepencies. Concurrent to this PR,
  we need to udpate the fn framework (kyaml) to be compatible with
  the standard and update the orchestrator to be backwards compatible.
- Include per-resource annotations (previously a seperate doc)
- Remove support for non-ResourceList wire formats. In practice, this is
  not widely used and complicates the standard. The orchestrators can
  easily covert a List to a ResourceList.
2021-05-25 16:09:32 -07:00
Jeff Regan
5954314b98 Merge pull request #3917 from zhouhao3/clean-tempfile
Cleanup tempfiles
2021-05-24 20:01:33 -07:00
Jeff Regan
c0324456a7 Merge pull request #3921 from monopole/deleteScriptsDir
Consolidate scripts into k8s-traditional hack dir.
2021-05-24 17:25:01 -07:00
monopole
172adc404f Consolidate scripts into k8s-traditional hack dir. 2021-05-24 17:09:11 -07:00
Jeff Regan
501748192b Merge pull request #3920 from monopole/unpinEverything
Back to development mode; unpin the modules
2021-05-24 09:42:57 -07:00
monopole
f6e6ac0320 Back to development mode; unpin the modules 2021-05-24 09:30:04 -07:00
Zhou Hao
a10ce1d787 cleanup tempfiles for runfn_test
Signed-off-by: Zhou Hao <zhouhao@fujitsu.com>
2021-05-24 17:01:44 +08:00
Zhou Hao
839cc2467c cleanup tempfiles for fmtr_test
Signed-off-by: Zhou Hao <zhouhao@fujitsu.com>
2021-05-24 15:52:28 +08:00
Mikhail Mazurskiy
dbc11ed29f Handle errors 2021-05-21 16:53:14 +10:00
Jeff Regan
0f614e92f7 Merge pull request #3909 from monopole/pinToApi
Pin to api v0.8.10
2021-05-20 13:44:39 -07:00
monopole
afaf7c62bc Pin to api v0.8.10 2021-05-20 13:34:27 -07:00
Jeff Regan
78d22069d7 Merge pull request #3910 from monopole/noMorePluginPin
No more plugin pinning.
2021-05-20 13:32:25 -07:00
monopole
22720a8b7a No more plugin pinning. 2021-05-20 13:31:50 -07:00
Jeff Regan
38c66d213a Update README.md 2021-05-20 13:14:28 -07:00
Devon Mizelle
73da51d0ac Apply suggestions from code review
Co-authored-by: Steven E. Harris <seh@panix.com>
2021-05-17 12:18:33 -04:00
Devon Mizelle
df10d5a17d Add includeCRDs Field to HelmChart
This commit adds functionality for a user to specify that `helm` should
include CRDs when inflating a Helm Chart.

As of Helm v3, the `install-crd` hook is no more, with
`CustomResourceDefinitions` existing in the root of the chart, under the
`crds` directory.

When calling `helm template`, `helm` does not output these CRDs unless
the user passes the `--include-crds` flag to the command.

With this commit, users can set `includeCRDs: true` as part of their helm
chart definition in `kustomize.yaml` to have these included as part of
the output.

Signed-off-by: Devon Mizelle <devon.mizelle@onepeloton.com>
2021-05-14 16:46:30 -04:00
384 changed files with 34245 additions and 3604 deletions

View File

@@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v2
- name: Lint
run: ./scripts/kyaml-pre-commit.sh
run: ./hack/kyaml-pre-commit.sh
env:
KUSTOMIZE_DOCKER_E2E: false # don't need to do e2e tests for linting
@@ -45,6 +45,10 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
- name: Test api
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
@@ -69,6 +73,10 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
- name: Test api
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
@@ -93,6 +101,11 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
# TODO: uncomment once Windows tests are passing.
# - name: Test api
# run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
# working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config

View File

@@ -20,6 +20,20 @@ We have full documentation on how to get started contributing here:
- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
## Contributor Ladder
Kustomize generally follows the [Kubernetes Community Membership](https://github.com/kubernetes/community/blob/master/community-membership.md) contributor ladder. Roles are as follows:
1. Contributor: Anyone who actively contributes code, issues or reviews to the project. There are no Kustomize-specific requirements for this status. All contributors must [sign the CLA](https://github.com/kubernetes/community/tree/master/contributors/guide#prerequisites).
1. Member/Reviewer: All Kubernetes-SIGs org members have LGTM rights on the Kustomize repo. There are no Kustomize-specific requirements. Kustomize does not currently have any formal reviewers, but the role will be created if there is interest.
1. Maintainer/Approver: Highly experienced active reviewer and contributor to Kustomize. Has both LTGM and approval rights on the Kustomize repo, as well as [Github "maintain" rights](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
1. Admin/Owner: Maintainer who sets technical direction and makes or approves design decisions for the project. Has LGTM and approval rights on the Kustomize repo as well as [Github "admin" rights](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
Administrative notes:
- Maintainers and admins must be added to the appropriate list both [in the Kustomize repo](https://github.com/kubernetes-sigs/kustomize/blob/8049f7b1af52e8a7ec26faf6cf714f560d0043c5/OWNERS_ALIASES) and [in the community repo](https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml). If this isn't done, the individual in question will lack either PR approval rights (Kustomize list) or the appropriate Github repository permissions (community list).
- The spec for the OWNERS file is [in the community repo](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md).
## Contact Information
- [Slack channel](https://kubernetes.slack.com/messages/sig-cli)

View File

@@ -4,6 +4,8 @@
# Makefile for kustomize CLI and API.
SHELL := /usr/bin/env bash
GOOS = $(shell go env GOOS)
GOARCH = $(shell go env GOARCH)
MYGOBIN = $(shell go env GOBIN)
ifeq ($(MYGOBIN),)
MYGOBIN = $(shell go env GOPATH)/bin
@@ -131,6 +133,7 @@ pSrc=plugin/builtin
_builtinplugins = \
AnnotationsTransformer.go \
ConfigMapGenerator.go \
IAMPolicyGenerator.go \
HashTransformer.go \
ImageTagTransformer.go \
LabelTransformer.go \
@@ -158,6 +161,7 @@ builtinplugins = $(patsubst %,$(pGen)/%,$(_builtinplugins))
# that file, will be recreated.
$(pGen)/AnnotationsTransformer.go: $(pSrc)/annotationstransformer/AnnotationsTransformer.go
$(pGen)/ConfigMapGenerator.go: $(pSrc)/configmapgenerator/ConfigMapGenerator.go
$(pGen)/GkeSaGenerator.go: $(pSrc)/gkesagenerator/GkeSaGenerator.go
$(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go
$(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go
$(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go
@@ -241,10 +245,10 @@ test-unit-kustomize-all: \
test-unit-kustomize-plugins
test-unit-cmd-all:
./scripts/kyaml-pre-commit.sh
./hack/kyaml-pre-commit.sh
test-go-mod:
./scripts/check-go-mod.sh
./hack/check-go-mod.sh
# Environment variables are defined at
# https://github.com/kubernetes/test-infra/blob/master/prow/jobs.md#job-environment-variables
@@ -256,7 +260,7 @@ test-multi-module: $(MYGOBIN)/prchecker
export REPO_NAME=$(REPO_NAME); \
export PULL_NUMBER=$(PULL_NUMBER); \
export MODULES=$(MODULES); \
./scripts/check-multi-module.sh; \
./hack/check-multi-module.sh; \
)
.PHONY:
@@ -287,8 +291,8 @@ $(MYGOBIN)/kubeval:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz; \
tar xf kubeval-linux-amd64.tar.gz; \
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-$(GOOS)-$(GOARCH).tar.gz; \
tar xf kubeval-$(GOOS)-$(GOARCH).tar.gz; \
mv kubeval $(MYGOBIN); \
rm -rf $$d; \
)
@@ -302,10 +306,10 @@ $(MYGOBIN)/helmV2:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v2.13.1-linux-amd64.tar.gz; \
tgzFile=helm-v2.13.1-$(GOOS)-$(GOARCH).tar.gz; \
wget https://storage.googleapis.com/kubernetes-helm/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv linux-amd64/helm $(MYGOBIN)/helmV2; \
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV2; \
rm -rf $$d \
)
@@ -315,10 +319,10 @@ $(MYGOBIN)/helmV3:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v3.5.3-linux-amd64.tar.gz; \
tgzFile=helm-v3.5.3-$(GOOS)-$(GOARCH).tar.gz; \
wget https://get.helm.sh/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv linux-amd64/helm $(MYGOBIN)/helmV3; \
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV3; \
rm -rf $$d \
)
@@ -326,7 +330,7 @@ $(MYGOBIN)/kind:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(shell uname)-amd64; \
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(GOOS)-$(GOARCH); \
chmod +x ./kind; \
mv ./kind $(MYGOBIN); \
rm -rf $$d; \
@@ -337,10 +341,10 @@ $(MYGOBIN)/gh:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=gh_1.0.0_linux_amd64.tar.gz; \
tgzFile=gh_1.0.0_$(GOOS)_$(GOARCH).tar.gz; \
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv gh_1.0.0_linux_amd64/bin/gh $(MYGOBIN)/gh; \
mv gh_1.0.0_$(GOOS)_$(GOARCH)/bin/gh $(MYGOBIN)/gh; \
rm -rf $$d \
)

View File

@@ -1,17 +1,16 @@
# Keep *-admins and *-maintainers list in sync with corresponding lists in
# https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml
aliases:
kustomize-admins:
- knverey
- monopole
- pwittrock
kustomize-maintainers:
- droot
- justinsb
- knverey
- monopole
- mortent
- natasha41575
- phanimarupaka
- pwittrock
- Shell32-Natsu
# emeritus
# - liujingfang1
# - mengqiy
emeritus-maintainers:
- liujingfang1
- mengqiy

View File

@@ -22,15 +22,22 @@ This tool is sponsored by [sig-cli] ([KEP]).
The kustomize build flow at [v2.0.3] was added
to [kubectl v1.14][kubectl announcement]. The kustomize
flow in kubectl has remained frozen at v2.0.3 while work
to extract kubectl from the k/k repo, and work to remove
kustomize's dependence on core k/k code ([#2506]) has proceeded.
The reintegration effort is tracked in [#1500] (and its blocking
issues).
flow in kubectl remained frozen at v2.0.3 until kubectl v1.21,
which [updated it to v4.0.5][kust-in-kubectl update]. It will
be updated on a regular basis going forward, and such updates
will be reflected in the Kubernetes release notes.
| Kubectl version | Kustomize version |
| --- | --- |
| < v1.14 | n/a |
| v1.14-v1.20 | v2.0.3 |
| v1.21 | v4.0.5 |
| v1.22 | v4.2.0 |
[v2.0.3]: /../../tree/v2.0.3
[#2506]: https://github.com/kubernetes-sigs/kustomize/issues/2506
[#1500]: https://github.com/kubernetes-sigs/kustomize/issues/1500
[kust-in-kubectl update]: https://github.com/kubernetes/kubernetes/blob/4d75a6238a6e330337526e0513e67d02b1940b63/CHANGELOG/CHANGELOG-1.21.md#kustomize-updates-in-kubectl
For examples and guides for using the kubectl integration please
see the [kubectl book] or the [kubernetes documentation].
@@ -145,7 +152,7 @@ is governed by the [Kubernetes Code of Conduct].
[`make`]: https://www.gnu.org/software/make
[`sed`]: https://www.gnu.org/software/sed
[DAM]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/2377-Kustomize/README.md
[Kubernetes Code of Conduct]: code-of-conduct.md
[applied]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#apply
[base]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#base

View File

@@ -280,6 +280,9 @@ func (p *HelmChartInflationGeneratorPlugin) templateCommand() []string {
// I've tried placing the flag before and after the name argument.
args = append(args, "--generate-name")
}
if p.IncludeCRDs {
args = append(args, "--include-crds")
}
return args
}

View File

@@ -0,0 +1,33 @@
// Code generated by pluginator on IAMPolicyGenerator; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
package builtins
import (
"sigs.k8s.io/kustomize/api/filters/iampolicygenerator"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
type IAMPolicyGeneratorPlugin struct {
types.IAMPolicyGeneratorArgs
}
func (p *IAMPolicyGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) (err error) {
p.IAMPolicyGeneratorArgs = types.IAMPolicyGeneratorArgs{}
err = yaml.Unmarshal(config, p)
return
}
func (p *IAMPolicyGeneratorPlugin) Generate() (resmap.ResMap, error) {
r := resmap.New()
err := r.ApplyFilter(iampolicygenerator.Filter{
IAMPolicyGenerator: p.IAMPolicyGeneratorArgs,
})
return r, err
}
func NewIAMPolicyGeneratorPlugin() resmap.GeneratorPlugin {
return &IAMPolicyGeneratorPlugin{}
}

61
api/filesys/filesys.go Normal file
View File

@@ -0,0 +1,61 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package filesys provides a file system abstraction,
// a subset of that provided by golang.org/pkg/os,
// with an on-disk and in-memory representation.
//
// Deprecated: use sigs.k8s.io/kustomize/kyaml/filesys instead.
package filesys
import "sigs.k8s.io/kustomize/kyaml/filesys"
const (
// Separator is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.Separator.
Separator = filesys.Separator
// SelfDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.SelfDir.
SelfDir = filesys.SelfDir
// ParentDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.ParentDir.
ParentDir = filesys.ParentDir
)
type (
// FileSystem is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.FileSystem.
FileSystem = filesys.FileSystem
// FileSystemOrOnDisk is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.FileSystemOrOnDisk.
FileSystemOrOnDisk = filesys.FileSystemOrOnDisk
// ConfirmedDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.ConfirmedDir.
ConfirmedDir = filesys.ConfirmedDir
)
// MakeEmptyDirInMemory is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeEmptyDirInMemory.
func MakeEmptyDirInMemory() FileSystem { return filesys.MakeEmptyDirInMemory() }
// MakeFsInMemory is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeFsInMemory.
func MakeFsInMemory() FileSystem { return filesys.MakeFsInMemory() }
// MakeFsOnDisk is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeFsOnDisk.
func MakeFsOnDisk() FileSystem { return filesys.MakeFsOnDisk() }
// NewTmpConfirmedDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.NewTmpConfirmedDir.
func NewTmpConfirmedDir() (filesys.ConfirmedDir, error) { return filesys.NewTmpConfirmedDir() }
// RootedPath is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.RootedPath.
func RootedPath(elem ...string) string { return filesys.RootedPath(elem...) }
// StripTrailingSeps is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.StripTrailingSeps.
func StripTrailingSeps(s string) string { return filesys.StripTrailingSeps(s) }
// StripLeadingSeps is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.StripLeadingSeps.
func StripLeadingSeps(s string) string { return filesys.StripLeadingSeps(s) }
// PathSplit is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.PathSplit.
func PathSplit(incoming string) []string { return filesys.PathSplit(incoming) }
// PathJoin is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.PathJoin.
func PathJoin(incoming []string) string { return filesys.PathJoin(incoming) }
// InsertPathPart is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.InsertPathPart.
func InsertPathPart(path string, pos int, part string) string {
return filesys.InsertPathPart(path, pos, part)
}

View File

@@ -1,50 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package filesys provides a file system abstraction layer.
package filesys
import (
"path/filepath"
)
const (
Separator = string(filepath.Separator)
SelfDir = "."
ParentDir = ".."
)
// FileSystem groups basic os filesystem methods.
// It's supposed be functional subset of https://golang.org/pkg/os
type FileSystem interface {
// Create a file.
Create(path string) (File, error)
// MkDir makes a directory.
Mkdir(path string) error
// MkDirAll makes a directory path, creating intervening directories.
MkdirAll(path string) error
// RemoveAll removes path and any children it contains.
RemoveAll(path string) error
// Open opens the named file for reading.
Open(path string) (File, error)
// IsDir returns true if the path is a directory.
IsDir(path string) bool
// CleanedAbs converts the given path into a
// directory and a file name, where the directory
// is represented as a ConfirmedDir and all that implies.
// If the entire path is a directory, the file component
// is an empty string.
CleanedAbs(path string) (ConfirmedDir, string, error)
// Exists is true if the path exists in the file system.
Exists(path string) bool
// Glob returns the list of matching files,
// emulating https://golang.org/pkg/path/filepath/#Glob
Glob(pattern string) ([]string, error)
// ReadFile returns the contents of the file at the given path.
ReadFile(path string) ([]byte, error)
// WriteFile writes the data to a file at the given path,
// overwriting anything that's already there.
WriteFile(path string, data []byte) error
// Walk walks the file system with the given WalkFunc.
Walk(path string, walkFn filepath.WalkFunc) error
}

5
api/filters/doc.go Normal file
View File

@@ -0,0 +1,5 @@
package filters
// Package filters collects various implementations
// sigs.k8s.io/kustomize/kyaml/kio.Filter used by kustomize
// transformers to modify kubernetes objects.

View File

@@ -49,7 +49,7 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
if match := isMatchGVK(fltr.FieldSpec, obj); !match {
return obj, nil
}
fltr.path = utils.PathSplitter(fltr.FieldSpec.Path)
fltr.path = utils.PathSplitter(fltr.FieldSpec.Path, "/")
if err := fltr.filter(obj); err != nil {
s, _ := obj.String()
return nil, errors.WrapPrefixf(err,

View File

@@ -0,0 +1,3 @@
// Package gkesagenerator contains a kio.Filter that that generates a
// iampolicy-related resources for a given cloud provider
package iampolicygenerator

View File

@@ -0,0 +1,46 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package iampolicygenerator
import (
"log"
"os"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func ExampleFilter() {
f := Filter{}
var err = yaml.Unmarshal([]byte(`
cloud: gke
kubernetesService:
namespace: k8s-namespace
name: k8s-sa-name
serviceAccount:
name: gsa-name
projectId: project-id
`), &f)
if err != nil {
log.Fatal(err)
}
err = kio.Pipeline{
Inputs: []kio.Reader{},
Filters: []kio.Filter{f},
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
}.Execute()
if err != nil {
log.Fatal(err)
}
// Output:
// apiVersion: v1
// kind: ServiceAccount
// metadata:
// annotations:
// iam.gke.io/gcp-service-account: gsa-name@project-id.iam.gserviceaccount.com
// name: k8s-sa-name
// namespace: k8s-namespace
}

View File

@@ -0,0 +1,55 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package iampolicygenerator
import (
"fmt"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type Filter struct {
IAMPolicyGenerator types.IAMPolicyGeneratorArgs `json:",inline,omitempty" yaml:",inline,omitempty"`
}
// Filter adds a GKE service account object to nodes
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
switch f.IAMPolicyGenerator.Cloud {
case types.GKE:
IAMPolicyResources, err := f.generateGkeIAMPolicyResources()
if err != nil {
return nil, err
}
nodes = append(nodes, IAMPolicyResources...)
default:
return nil, fmt.Errorf("cloud provider %s not supported yet", f.IAMPolicyGenerator.Cloud)
}
return nodes, nil
}
func (f Filter) generateGkeIAMPolicyResources() ([]*yaml.RNode, error) {
var result []*yaml.RNode
input := fmt.Sprintf(`
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: %s@%s.iam.gserviceaccount.com
name: %s
`, f.IAMPolicyGenerator.ServiceAccount.Name,
f.IAMPolicyGenerator.ProjectId,
f.IAMPolicyGenerator.KubernetesService.Name)
if f.IAMPolicyGenerator.Namespace != "" {
input = input + fmt.Sprintf("\n namespace: %s", f.IAMPolicyGenerator.Namespace)
}
sa, err := yaml.Parse(input)
if err != nil {
return nil, err
}
return append(result, sa), nil
}

View File

@@ -0,0 +1,75 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package iampolicygenerator
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
filtertest "sigs.k8s.io/kustomize/api/testutils/filtertest"
"sigs.k8s.io/kustomize/api/types"
)
func TestFilter(t *testing.T) {
testCases := map[string]struct {
args types.IAMPolicyGeneratorArgs
expected string
}{
"with namespace": {
args: types.IAMPolicyGeneratorArgs{
Cloud: types.GKE,
KubernetesService: types.KubernetesService{
Namespace: "k8s-namespace",
Name: "k8s-sa-name",
},
ServiceAccount: types.ServiceAccount{
Name: "gsa-name",
ProjectId: "project-id",
},
},
expected: `
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name@project-id.iam.gserviceaccount.com
name: k8s-sa-name
namespace: k8s-namespace
`,
},
"without namespace": {
args: types.IAMPolicyGeneratorArgs{
Cloud: types.GKE,
KubernetesService: types.KubernetesService{
Name: "k8s-sa-name",
},
ServiceAccount: types.ServiceAccount{
Name: "gsa-name",
ProjectId: "project-id",
},
},
expected: `
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name@project-id.iam.gserviceaccount.com
name: k8s-sa-name
`,
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
f := Filter{
IAMPolicyGenerator: tc.args,
}
actual := filtertest.RunFilter(t, "", f)
if !assert.Equal(t, strings.TrimSpace(tc.expected), strings.TrimSpace(actual)) {
t.FailNow()
}
})
}
}

View File

@@ -4,6 +4,7 @@
package imagetag
import (
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -74,7 +75,7 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error {
return err
}
key := n.Key.YNode().Value
if contains(f.fields, key) {
if utils.StringSliceContains(f.fields, key) {
return f.fieldCallback(n.Value)
}
return nil
@@ -87,15 +88,6 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error {
return nil
}
func contains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
func checkImageTagsFn(imageTag types.Image) fieldCallback {
return func(node *yaml.RNode) error {
if node.YNode().Kind != yaml.SequenceNode {

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -43,11 +44,17 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
t.FieldPaths = []string{types.DefaultReplacementFieldPath}
}
for _, n := range nodes {
id := makeResId(n)
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, id) {
err := applyToNode(n, value, t)
if err != nil {
return nil, err
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, err
}
for _, id := range ids {
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
err := applyToNode(n, value, t)
if err != nil {
return nil, err
}
break
}
}
}
@@ -66,7 +73,7 @@ func rejectId(rejects []*types.Selector, id *resid.ResId) bool {
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
for _, fp := range target.FieldPaths {
fieldPath := strings.Split(fp, ".")
fieldPath := utils.SmarterPathSplitter(fp, ".")
var t *yaml.RNode
var err error
if target.Options != nil && target.Options.Create {
@@ -87,12 +94,11 @@ func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelect
}
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
value = value.Copy()
if options != nil && options.Delimiter != "" {
if t.YNode().Kind != yaml.ScalarNode {
return fmt.Errorf("delimiter option can only be used with scalar nodes")
}
tv := strings.Split(t.YNode().Value, options.Delimiter)
v := yaml.GetValue(value)
// TODO: Add a way to remove an element
@@ -119,7 +125,7 @@ func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, err
if r.Source.FieldPath == "" {
r.Source.FieldPath = types.DefaultReplacementFieldPath
}
fieldPath := strings.Split(r.Source.FieldPath, ".")
fieldPath := utils.SmarterPathSplitter(r.Source.FieldPath, ".")
rn, err := source.Pipe(yaml.Lookup(fieldPath...))
if err != nil {
@@ -152,12 +158,19 @@ func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode,
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
var matches []*yaml.RNode
for _, n := range nodes {
if makeResId(n).IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, err
}
for _, id := range ids {
if id.IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
}
matches = append(matches, n)
break
}
matches = append(matches, n)
}
}
if len(matches) == 0 {
@@ -165,17 +178,3 @@ func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yam
}
return matches[0], nil
}
// makeResId makes a ResId from an RNode.
func makeResId(n *yaml.RNode) *resid.ResId {
apiVersion := n.Field(yaml.APIVersionField)
var group, version string
if apiVersion != nil {
group, version = resid.ParseGroupVersion(yaml.GetValue(apiVersion.Value))
}
return &resid.ResId{
Gvk: resid.Gvk{Group: group, Version: version, Kind: n.GetKind()},
Name: n.GetName(),
Namespace: n.GetNamespace(),
}
}

View File

@@ -1338,6 +1338,224 @@ spec:
`,
expectedErr: "delimiter option can only be used with scalar nodes",
},
"mapping value contains '.' character": {
input: `apiVersion: v1
kind: Custom
metadata:
name: custom
annotations:
a.b.c/d-e: source
f.g.h/i-j: target
`,
replacements: `replacements:
- source:
name: custom
fieldPath: metadata.annotations.[a.b.c/d-e]
targets:
- select:
name: custom
fieldPaths:
- metadata.annotations.[f.g.h/i-j]
`,
expected: `apiVersion: v1
kind: Custom
metadata:
name: custom
annotations:
a.b.c/d-e: source
f.g.h/i-j: source
`,
},
"list index contains '.' character": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-replaceme
name: .first
version: latest
property: first
- key: some-prefix-replaceme
name: second
version: latest
property: second
`,
replacements: `replacements:
- source:
kind: ConfigMap
version: v1
name: source
fieldPath: data.value
targets:
- select:
group: kubernetes-client.io
version: v1
kind: ExternalSecret
name: some-secret
fieldPaths:
- spec.data.[name=.first].key
- spec.data.[name=second].key
options:
delimiter: "-"
index: 2
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-example
name: .first
version: latest
property: first
- key: some-prefix-example
name: second
version: latest
property: second`,
},
"multiple field paths in target": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-replaceme
name: first
version: latest
property: first
- key: some-prefix-replaceme
name: second
version: latest
property: second
- key: some-prefix-replaceme
name: third
version: latest
property: third
`,
replacements: `replacements:
- source:
kind: ConfigMap
version: v1
name: source
fieldPath: data.value
targets:
- select:
group: kubernetes-client.io
version: v1
kind: ExternalSecret
name: some-secret
fieldPaths:
- spec.data.0.key
- spec.data.1.key
- spec.data.2.key
options:
delimiter: "-"
index: 2
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-example
name: first
version: latest
property: first
- key: some-prefix-example
name: second
version: latest
property: second
- key: some-prefix-example
name: third
version: latest
property: third
`,
},
"using a previous ID": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: pre-deploy
annotations:
internal.config.kubernetes.io/previousNames: deploy,deploy
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
internal.config.kubernetes.io/previousNamespaces: default,default
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: CronJob
name: deploy
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: Deployment
name: deploy
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: pre-deploy
annotations:
internal.config.kubernetes.io/previousNames: deploy,deploy
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
internal.config.kubernetes.io/previousNamespaces: default,default
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
`,
},
}
for tn, tc := range testCases {
@@ -1353,7 +1571,7 @@ spec:
t.Errorf("unexpected error: %s\n", err.Error())
t.FailNow()
}
if !assert.Equal(t, tc.expectedErr, err.Error()) {
if !assert.Contains(t, err.Error(), tc.expectedErr) {
t.FailNow()
}
}

View File

@@ -6,7 +6,7 @@ package valueadd
import (
"strings"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

View File

@@ -3,7 +3,7 @@ module sigs.k8s.io/kustomize/api
go 1.16
require (
github.com/evanphx/json-patch v4.5.0+incompatible
github.com/evanphx/json-patch v4.11.0+incompatible
github.com/go-errors/errors v1.0.1
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/imdario/mergo v0.3.5
@@ -11,8 +11,6 @@ require (
github.com/stretchr/testify v1.5.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e
sigs.k8s.io/kustomize/kyaml v0.10.20
sigs.k8s.io/kustomize/kyaml v0.11.1
sigs.k8s.io/yaml v1.2.0
)
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c

View File

@@ -30,8 +30,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
@@ -217,15 +217,14 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
sigs.k8s.io/kustomize/kyaml v0.10.20 h1:L9JNKvJfCBpmYFr4tP0igpfj/pXP7nW2aXOWNtF5k1g=
sigs.k8s.io/kustomize/kyaml v0.10.20/go.mod h1:TYWhGwW9vjoRh3rWqBwB/ZOXyEGRVWe7Ggc3+KZIO+c=
sigs.k8s.io/kustomize/kyaml v0.11.1 h1:MWihd9syKG7VQnAzr/OpKb94FvH+cw96nEV1u3it7pI=
sigs.k8s.io/kustomize/kyaml v0.11.1/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -9,10 +9,10 @@ import (
"github.com/pkg/errors"
"k8s.io/kube-openapi/pkg/validation/spec"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/yaml"
)
@@ -178,9 +178,12 @@ func loadCrdIntoConfig(
}
}
if property.Ref.GetURL() != nil {
loadCrdIntoConfig(
err = loadCrdIntoConfig(
theConfig, theGvk, theMap,
property.Ref.String(), append(path, propName))
if err != nil {
return
}
}
}
return nil

View File

@@ -7,11 +7,12 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/stretchr/testify/require"
. "sigs.k8s.io/kustomize/api/internal/accumulator"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)
@@ -162,16 +163,13 @@ func TestLoadCRDs(t *testing.T) {
}
fSys := filesys.MakeFsInMemory()
fSys.WriteFile("/testpath/crd.json", []byte(crdContent))
err := fSys.WriteFile("/testpath/crd.json", []byte(crdContent))
require.NoError(t, err)
ldr, err := loader.NewLoader(loader.RestrictionRootOnly, "/testpath", fSys)
if err != nil {
t.Fatalf("unexpected error:%v", err)
}
require.NoError(t, err)
actualTc, err := LoadConfigFromCRDs(ldr, []string{"crd.json"})
if err != nil {
t.Fatalf("unexpected error:%v", err)
}
require.NoError(t, err)
if !reflect.DeepEqual(actualTc, expectedTc) {
t.Fatalf("expected\n %v\n but got\n %v\n", expectedTc, actualTc)
}

View File

@@ -897,7 +897,9 @@ func TestNameReferenceClusterWide(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
expected.RemoveBuildAnnotations()
m.RemoveBuildAnnotations()
if err = expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf(notEqualErrFmt, err)
}

View File

@@ -10,6 +10,7 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
. "sigs.k8s.io/kustomize/api/internal/accumulator"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/provider"
@@ -224,20 +225,26 @@ func TestResolveVarConflicts(t *testing.T) {
// create accumulators holding apparently conflicting vars that are not
// actually in conflict because they point to the same concrete value.
rm0 := resmap.New()
rm0.Append(rf.FromMap(fooAws))
err := rm0.Append(rf.FromMap(fooAws))
require.NoError(t, err)
ac0 := MakeEmptyAccumulator()
ac0.AppendAll(rm0)
ac0.MergeVars([]types.Var{varFoo})
err = ac0.AppendAll(rm0)
require.NoError(t, err)
err = ac0.MergeVars([]types.Var{varFoo})
require.NoError(t, err)
rm1 := resmap.New()
rm1.Append(rf.FromMap(barAws))
err = rm1.Append(rf.FromMap(barAws))
require.NoError(t, err)
ac1 := MakeEmptyAccumulator()
ac1.AppendAll(rm1)
ac1.MergeVars([]types.Var{varBar})
err = ac1.AppendAll(rm1)
require.NoError(t, err)
err = ac1.MergeVars([]types.Var{varBar})
require.NoError(t, err)
// validate that two vars of the same name which reference the same concrete
// value do not produce a conflict.
err := ac0.MergeAccumulator(ac1)
err = ac0.MergeAccumulator(ac1)
if err == nil {
t.Fatalf("see bug gh-1600")
}
@@ -246,10 +253,13 @@ func TestResolveVarConflicts(t *testing.T) {
// two above (because it contains a variable whose name is used in the other
// accumulators AND whose concrete values are different).
rm2 := resmap.New()
rm2.Append(rf.FromMap(barGcp))
err = rm2.Append(rf.FromMap(barGcp))
require.NoError(t, err)
ac2 := MakeEmptyAccumulator()
ac2.AppendAll(rm2)
ac2.MergeVars([]types.Var{varBar})
err = ac2.AppendAll(rm2)
require.NoError(t, err)
err = ac2.MergeVars([]types.Var{varBar})
require.NoError(t, err)
err = ac1.MergeAccumulator(ac2)
if err == nil {
t.Fatalf("dupe vars w/ different concrete values should conflict")
@@ -352,10 +362,10 @@ func TestResolveVarsWithNoambiguation(t *testing.T) {
"metadata": map[string]interface{}{
"name": "sub-backendOne",
"annotations": map[string]interface{}{
"config.kubernetes.io/previousKinds": "Service",
"config.kubernetes.io/previousNames": "backendOne",
"config.kubernetes.io/previousNamespaces": "default",
"config.kubernetes.io/prefixes": "sub-",
"internal.config.kubernetes.io/previousKinds": "Service",
"internal.config.kubernetes.io/previousNames": "backendOne",
"internal.config.kubernetes.io/previousNamespaces": "default",
"internal.config.kubernetes.io/prefixes": "sub-",
},
}}).ResMap()

View File

@@ -40,7 +40,13 @@ func MakeConfigMap(
if err = rn.LoadMapIntoConfigMapData(m); err != nil {
return nil, err
}
copyLabelsAndAnnotations(rn, args.Options)
setImmutable(rn, args.Options)
err = copyLabelsAndAnnotations(rn, args.Options)
if err != nil {
return nil, err
}
err = setImmutable(rn, args.Options)
if err != nil {
return nil, err
}
return rn, nil
}

View File

@@ -8,12 +8,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/generators"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
var binaryHello = []byte{

View File

@@ -8,12 +8,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/generators"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestMakeSecret(t *testing.T) {

View File

@@ -4,7 +4,7 @@
package git
import (
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Cloner is a function that can clone a git repo.

View File

@@ -8,8 +8,8 @@ import (
"time"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// gitRunner runs the external git binary.

View File

@@ -11,7 +11,7 @@ import (
"strings"
"time"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Used as a temporary non-empty occupant of the cloneDir
@@ -125,7 +125,7 @@ func parseGitUrl(n string) (
index := strings.Index(n, gitSuffix)
orgRepo = n[0:index]
n = n[index+len(gitSuffix):]
if n[0] == '/' {
if len(n) > 0 && n[0] == '/' {
n = n[1:]
}
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n)

View File

@@ -35,7 +35,6 @@ var hostNamesRawAndNormalized = [][]string{
{"git::https://git.example.com/", "https://git.example.com/"},
{"git@github.com:", "git@github.com:"},
{"git@github.com/", "git@github.com:"},
{"git@gitlab2.sqtools.ru:10022/", "git@gitlab2.sqtools.ru:10022/"},
}
func makeUrl(hostFmt, orgRepo, path, href string) string {
@@ -183,6 +182,12 @@ func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) {
absPath: notCloned.String(),
ref: "",
},
"t12": {
input: "https://bitbucket.example.com/scm/project/repository.git",
cloneSpec: "https://bitbucket.example.com/scm/project/repository.git",
absPath: notCloned.String(),
ref: "",
},
}
for tn, tc := range testcases {
t.Run(tn, func(t *testing.T) {

View File

@@ -7,9 +7,9 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)

View File

@@ -11,25 +11,26 @@ func _() {
_ = x[Unknown-0]
_ = x[AnnotationsTransformer-1]
_ = x[ConfigMapGenerator-2]
_ = x[HashTransformer-3]
_ = x[ImageTagTransformer-4]
_ = x[LabelTransformer-5]
_ = x[LegacyOrderTransformer-6]
_ = x[NamespaceTransformer-7]
_ = x[PatchJson6902Transformer-8]
_ = x[PatchStrategicMergeTransformer-9]
_ = x[PatchTransformer-10]
_ = x[PrefixSuffixTransformer-11]
_ = x[ReplicaCountTransformer-12]
_ = x[SecretGenerator-13]
_ = x[ValueAddTransformer-14]
_ = x[HelmChartInflationGenerator-15]
_ = x[ReplacementTransformer-16]
_ = x[IAMPolicyGenerator-3]
_ = x[HashTransformer-4]
_ = x[ImageTagTransformer-5]
_ = x[LabelTransformer-6]
_ = x[LegacyOrderTransformer-7]
_ = x[NamespaceTransformer-8]
_ = x[PatchJson6902Transformer-9]
_ = x[PatchStrategicMergeTransformer-10]
_ = x[PatchTransformer-11]
_ = x[PrefixSuffixTransformer-12]
_ = x[ReplicaCountTransformer-13]
_ = x[SecretGenerator-14]
_ = x[ValueAddTransformer-15]
_ = x[HelmChartInflationGenerator-16]
_ = x[ReplacementTransformer-17]
}
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer"
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorIAMPolicyGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer"
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289, 316, 338}
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 65, 80, 99, 115, 137, 157, 181, 211, 227, 250, 273, 288, 307, 334, 356}
func (i BuiltinPluginType) String() string {
if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) {

View File

@@ -15,6 +15,7 @@ const (
Unknown BuiltinPluginType = iota
AnnotationsTransformer
ConfigMapGenerator
IAMPolicyGenerator
HashTransformer
ImageTagTransformer
LabelTransformer
@@ -58,6 +59,7 @@ func GetBuiltinPluginType(n string) BuiltinPluginType {
var GeneratorFactories = map[BuiltinPluginType]func() resmap.GeneratorPlugin{
ConfigMapGenerator: builtins.NewConfigMapGeneratorPlugin,
IAMPolicyGenerator: builtins.NewIAMPolicyGeneratorPlugin,
SecretGenerator: builtins.NewSecretGeneratorPlugin,
HelmChartInflationGenerator: builtins.NewHelmChartInflationGeneratorPlugin,
}

View File

@@ -7,9 +7,9 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/compiler"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Regression coverage over compiler behavior.

View File

@@ -94,9 +94,6 @@ TO GENERATE CODE
cd $repo/plugin/builtin
go generate ./...
See scripts/kyaml-pre-commit.sh for canonical way
to execute the above.
This creates
$repo/api/plugins/builtins/SecretGenerator.go

View File

@@ -89,7 +89,10 @@ type argsConfig struct {
func (p *ExecPlugin) processOptionalArgsFields() error {
var c argsConfig
yaml.Unmarshal(p.cfg, &c)
err := yaml.Unmarshal(p.cfg, &c)
if err != nil {
return err
}
if c.ArgsOneLiner != "" {
p.args, _ = shlex.Split(c.ArgsOneLiner)
}

View File

@@ -9,7 +9,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/stretchr/testify/require"
. "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
@@ -17,15 +17,17 @@ import (
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestExecPluginConfig(t *testing.T) {
fSys := filesys.MakeFsInMemory()
fSys.WriteFile("sed-input.txt", []byte(`
err := fSys.WriteFile("sed-input.txt", []byte(`
s/$FOO/foo/g
s/$BAR/bar baz/g
\ \ \
`))
require.NoError(t, err)
ldr, err := fLdr.NewLoader(
fLdr.RestrictionRootOnly, filesys.Separator, fSys)
if err != nil {
@@ -62,9 +64,10 @@ s/$BAR/bar baz/g
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
p.Config(
err = p.Config(
resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf, pc),
yaml)
require.NoError(t, err)
expected := "someteam.example.com/v1/sedtransformer/SedTransformer"
if !strings.HasSuffix(p.Path(), expected) {

View File

@@ -78,6 +78,8 @@ func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts),
Env: o.Env,
AsCurrentUser: o.AsCurrentUser,
WorkingDir: o.WorkingDir,
},
}
}

View File

@@ -13,7 +13,6 @@ 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"
@@ -23,6 +22,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)
@@ -47,6 +47,11 @@ func (l *Loader) Config() *types.PluginConfig {
return l.pc
}
// SetWorkDir sets the working directory for this loader's plugins
func (l *Loader) SetWorkDir(wd string) {
l.pc.FnpLoadingOptions.WorkingDir = wd
}
func (l *Loader) LoadGenerators(
ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]resmap.Generator, error) {
var result []resmap.Generator

View File

@@ -6,7 +6,6 @@ package loader_test
import (
"testing"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
@@ -14,6 +13,7 @@ import (
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (

View File

@@ -12,11 +12,11 @@ import (
"strconv"
"time"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/yaml"
)
@@ -192,7 +192,9 @@ func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byt
for _, id := range rm.AllIds() {
newIdx, _ := newMap.GetIndexOfCurrentId(id)
if newIdx == -1 {
rm.Remove(id)
if err = rm.Remove(id); err != nil {
return err
}
}
}
@@ -229,10 +231,10 @@ func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
if err := r.SetAnnotations(annotations); err != nil {
return nil, err
}
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
if needsHash {
r.EnableHashSuffix()
}
r.SetBehavior(types.NewGenerationBehavior(behavior))
}
return rm, nil
}

View File

@@ -10,12 +10,13 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestDeterminePluginSrcRoot(t *testing.T) {
@@ -86,8 +87,10 @@ func TestUpdateResourceOptions(t *testing.T) {
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
err := in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
require.NoError(t, err)
err = expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
require.NoError(t, err)
}
actual, err := UpdateResourceOptions(in)
assert.NoError(t, err)
@@ -105,10 +108,9 @@ func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in := resmap.New()
in.Append(makeConfigMap(rf, name, "", &c))
_, err := UpdateResourceOptions(in)
if err == nil {
t.Errorf("expected error from value %q", c)
}
err := in.Append(makeConfigMap(rf, name, "", &c))
require.NoError(t, err)
_, err = UpdateResourceOptions(in)
require.Error(t, err)
}
}

View File

@@ -16,8 +16,10 @@ import (
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/yaml"
@@ -38,11 +40,13 @@ func NewKustTarget(
validator ifc.Validator,
rFactory *resmap.Factory,
pLdr *loader.Loader) *KustTarget {
pLdrCopy := *pLdr
pLdrCopy.SetWorkDir(ldr.Root())
return &KustTarget{
ldr: ldr,
validator: validator,
rFactory: rFactory,
pLdr: pLdr,
pLdr: &pLdrCopy,
}
}
@@ -108,7 +112,7 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
}
func (kt *KustTarget) makeCustomizedResMap() (resmap.ResMap, error) {
ra, err := kt.AccumulateTarget()
ra, err := kt.AccumulateTarget(&resource.Origin{})
if err != nil {
return nil, err
}
@@ -151,20 +155,29 @@ func (kt *KustTarget) addHashesToNames(
// holding customized resources and the data/rules used
// to do so. The name back references and vars are
// not yet fixed.
func (kt *KustTarget) AccumulateTarget() (
// The origin parameter is used through the recursive calls
// to annotate each resource with information about where
// the resource came from, e.g. the file and/or the repository
// it originated from.
// As an entrypoint, one can pass an empty resource.Origin object to
// AccumulateTarget. As AccumulateTarget moves recursively
// through kustomization directories, it updates `origin.path`
// accordingly. When a remote base is found, it updates `origin.repo`
// and `origin.ref` accordingly.
func (kt *KustTarget) AccumulateTarget(origin *resource.Origin) (
ra *accumulator.ResAccumulator, err error) {
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator())
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator(), origin)
}
// ra should be empty when this KustTarget is a Kustomization, or the ra of the parent if this KustTarget is a Component
// (or empty if the Component does not have a parent).
func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator, origin *resource.Origin) (
resRa *accumulator.ResAccumulator, err error) {
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources)
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources, origin)
if err != nil {
return nil, errors.Wrap(err, "accumulating resources")
}
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components, origin)
if err != nil {
return nil, errors.Wrap(err, "accumulating components")
}
@@ -247,7 +260,7 @@ func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error)
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, generatorPaths)
ra, err := kt.accumulateResources(ra, generatorPaths, &resource.Origin{})
if err != nil {
return nil, err
}
@@ -283,8 +296,7 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]re
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, transformerPaths)
ra, err := kt.accumulateResources(ra, transformerPaths, &resource.Origin{})
if err != nil {
return nil, err
}
@@ -332,16 +344,16 @@ func (kt *KustTarget) removeValidatedByLabel(rm resmap.ResMap) error {
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateResources(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, paths []string, origin *resource.Origin) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// try loading resource as file then as base (directory or git repository)
if errF := kt.accumulateFile(ra, path); errF != nil {
if errF := kt.accumulateFile(ra, path, origin); errF != nil {
ldr, err := kt.ldr.New(path)
if err != nil {
return nil, errors.Wrapf(
err, "accumulation err='%s'", errF.Error())
}
ra, err = kt.accumulateDirectory(ra, ldr, false)
ra, err = kt.accumulateDirectory(ra, ldr, origin.Append(path), false)
if err != nil {
return nil, errors.Wrapf(
err, "accumulation err='%s'", errF.Error())
@@ -354,7 +366,7 @@ func (kt *KustTarget) accumulateResources(
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateComponents(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, paths []string, origin *resource.Origin) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// Components always refer to directories
ldr, errL := kt.ldr.New(path)
@@ -362,7 +374,8 @@ func (kt *KustTarget) accumulateComponents(
return nil, fmt.Errorf("loader.New %q", errL)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, true)
origin.Path = filepath.Join(origin.Path, path)
ra, errD = kt.accumulateDirectory(ra, ldr, origin, true)
if errD != nil {
return nil, fmt.Errorf("accumulateDirectory: %q", errD)
}
@@ -371,7 +384,7 @@ func (kt *KustTarget) accumulateComponents(
}
func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, ldr ifc.Loader, origin *resource.Origin, isComponent bool) (*accumulator.ResAccumulator, error) {
defer ldr.Cleanup()
subKt := NewKustTarget(ldr, kt.validator, kt.rFactory, kt.pLdr)
err := subKt.Load()
@@ -379,6 +392,7 @@ func (kt *KustTarget) accumulateDirectory(
return nil, errors.Wrapf(
err, "couldn't make target for path '%s'", ldr.Root())
}
subKt.kustomization.BuildMetadata = kt.kustomization.BuildMetadata
var bytes []byte
path := ldr.Root()
if openApiPath, exists := subKt.Kustomization().OpenAPI["path"]; exists {
@@ -402,12 +416,12 @@ func (kt *KustTarget) accumulateDirectory(
var subRa *accumulator.ResAccumulator
if isComponent {
// Components don't create a new accumulator: the kustomization directives are added to the current accumulator
subRa, err = subKt.accumulateTarget(ra)
subRa, err = subKt.accumulateTarget(ra, origin)
ra = accumulator.MakeEmptyAccumulator()
} else {
// Child Kustomizations create a new accumulator which resolves their kustomization directives, which will later
// be merged into the current accumulator.
subRa, err = subKt.AccumulateTarget()
subRa, err = subKt.AccumulateTarget(origin)
}
if err != nil {
return nil, errors.Wrapf(
@@ -422,11 +436,18 @@ func (kt *KustTarget) accumulateDirectory(
}
func (kt *KustTarget) accumulateFile(
ra *accumulator.ResAccumulator, path string) error {
ra *accumulator.ResAccumulator, path string, origin *resource.Origin) error {
resources, err := kt.rFactory.FromFile(kt.ldr, path)
if err != nil {
return errors.Wrapf(err, "accumulating resources from '%s'", path)
}
if utils.StringSliceContains(kt.kustomization.BuildMetadata, "originAnnotations") {
origin = origin.Append(path)
err = resources.AnnotateAll(utils.OriginAnnotation, origin.String())
if err != nil {
return errors.Wrapf(err, "cannot add path annotation for '%s'", path)
}
}
err = ra.AppendAll(resources)
if err != nil {
return errors.Wrapf(err, "merging resources from '%s'", path)

View File

@@ -255,5 +255,5 @@ metadata:
actual.RemoveBuildAnnotations()
actYaml, err := actual.AsYaml()
assert.NoError(t, err)
assert.Equal(t, expYaml, actYaml)
assert.Equal(t, string(expYaml), string(actYaml))
}

View File

@@ -6,7 +6,6 @@ package target_test
import (
"testing"
"sigs.k8s.io/kustomize/api/filesys"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
fLdr "sigs.k8s.io/kustomize/api/loader"
@@ -14,6 +13,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func makeAndLoadKustTarget(

View File

@@ -8,6 +8,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/resid"
@@ -65,7 +66,7 @@ vars:
apiVersion: v300
`)
ra, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app").AccumulateTarget()
t, th.GetFSys(), "/app").AccumulateTarget(&resource.Origin{})
if err != nil {
t.Fatalf("Err: %v", err)
}
@@ -120,7 +121,7 @@ resources:
`)
ra, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget(&resource.Origin{})
if err != nil {
t.Fatalf("Err: %v", err)
}
@@ -177,7 +178,7 @@ resources:
- ../o1
`)
_, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget(&resource.Origin{})
if err == nil {
t.Fatalf("expected var collision")
}

View File

@@ -0,0 +1,23 @@
package utils
import "sigs.k8s.io/kustomize/api/konfig"
const (
BuildAnnotationPreviousKinds = konfig.ConfigAnnoDomain + "/previousKinds"
BuildAnnotationPreviousNames = konfig.ConfigAnnoDomain + "/previousNames"
BuildAnnotationPrefixes = konfig.ConfigAnnoDomain + "/prefixes"
BuildAnnotationSuffixes = konfig.ConfigAnnoDomain + "/suffixes"
BuildAnnotationPreviousNamespaces = konfig.ConfigAnnoDomain + "/previousNamespaces"
BuildAnnotationsRefBy = konfig.ConfigAnnoDomain + "/refBy"
BuildAnnotationsGenBehavior = konfig.ConfigAnnoDomain + "/generatorBehavior"
BuildAnnotationsGenAddHashSuffix = konfig.ConfigAnnoDomain + "/needsHashSuffix"
// 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"
OriginAnnotation = "config.kubernetes.io/origin"
Enabled = "enabled"
)

View File

@@ -0,0 +1,64 @@
package utils
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// MakeResIds returns all of an RNode's current and previous Ids
func MakeResIds(n *yaml.RNode) ([]resid.ResId, error) {
var result []resid.ResId
apiVersion := n.Field(yaml.APIVersionField)
var group, version string
if apiVersion != nil {
group, version = resid.ParseGroupVersion(yaml.GetValue(apiVersion.Value))
}
result = append(result, resid.NewResIdWithNamespace(
resid.Gvk{Group: group, Version: version, Kind: n.GetKind()}, n.GetName(), n.GetNamespace()),
)
prevIds, err := PrevIds(n)
if err != nil {
return nil, err
}
result = append(result, prevIds...)
return result, nil
}
// PrevIds returns all of an RNode's previous Ids
func PrevIds(n *yaml.RNode) ([]resid.ResId, error) {
var ids []resid.ResId
// TODO: merge previous names and namespaces into one list of
// pairs on one annotation so there is no chance of error
annotations := n.GetAnnotations()
if _, ok := annotations[BuildAnnotationPreviousNames]; !ok {
return nil, nil
}
names := strings.Split(annotations[BuildAnnotationPreviousNames], ",")
ns := strings.Split(annotations[BuildAnnotationPreviousNamespaces], ",")
kinds := strings.Split(annotations[BuildAnnotationPreviousKinds], ",")
// This should never happen
if len(names) != len(ns) || len(names) != len(kinds) {
return nil, fmt.Errorf(
"number of previous names, " +
"number of previous namespaces, " +
"number of previous kinds not equal")
}
for i := range names {
meta, err := n.GetMeta()
if err != nil {
return nil, err
}
group, version := resid.ParseGroupVersion(meta.APIVersion)
gvk := resid.Gvk{
Group: group,
Version: version,
Kind: kinds[i],
}
ids = append(ids, resid.NewResIdWithNamespace(
gvk, names[i], ns[i]))
}
return ids, nil
}

View File

@@ -5,18 +5,60 @@ package utils
import "strings"
// PathSplitter splits a slash delimited string, permitting escaped slashes.
func PathSplitter(path string) []string {
ps := strings.Split(path, "/")
// TODO: Move these to kyaml
// PathSplitter splits a delimited string, permitting escaped delimiters.
func PathSplitter(path string, delimiter string) []string {
ps := strings.Split(path, delimiter)
var res []string
res = append(res, ps[0])
for i := 1; i < len(ps); i++ {
last := len(res) - 1
if strings.HasSuffix(res[last], `\`) {
res[last] = strings.TrimSuffix(res[last], `\`) + "/" + ps[i]
res[last] = strings.TrimSuffix(res[last], `\`) + delimiter + ps[i]
} else {
res = append(res, ps[i])
}
}
return res
}
// SmarterPathSplitter splits a path, retaining bracketed elements.
// If the element is a list entry identifier (defined by the '='),
// it will retain the brackets.
// E.g. "[name=com.foo.someapp]" survives as one thing after splitting
// "spec.template.spec.containers.[name=com.foo.someapp].image"
// See kyaml/yaml/match.go for use of list entry identifiers.
// If the element is a mapping entry identifier, it will remove the
// brackets.
// E.g. "a.b.c" survives as one thing after splitting
// "metadata.annotations.[a.b.c]
// This function uses `PathSplitter`, so it also respects escaped delimiters.
func SmarterPathSplitter(path string, delimiter string) []string {
var result []string
split := PathSplitter(path, delimiter)
for i := 0; i < len(split); i++ {
elem := split[i]
if strings.HasPrefix(elem, "[") && !strings.HasSuffix(elem, "]") {
// continue until we find the matching "]"
bracketed := []string{elem}
for i < len(split)-1 {
i++
bracketed = append(bracketed, split[i])
if strings.HasSuffix(split[i], "]") {
break
}
}
bracketedStr := strings.Join(bracketed, delimiter)
if strings.Contains(bracketedStr, "=") {
result = append(result, bracketedStr)
} else {
result = append(result, strings.Trim(bracketedStr, "[]"))
}
} else {
result = append(result, elem)
}
}
return result
}

View File

@@ -44,6 +44,51 @@ func TestPathSplitter(t *testing.T) {
"nginx.ingress.kubernetes.io/auth-secret"},
},
} {
assert.Equal(t, tc.exp, PathSplitter(tc.path))
assert.Equal(t, tc.exp, PathSplitter(tc.path, "/"))
}
}
func TestSmarterPathSplitter(t *testing.T) {
testCases := map[string]struct {
input string
expected []string
}{
"simple": {
input: "spec.replicas",
expected: []string{"spec", "replicas"},
},
"sequence": {
input: "spec.data.[name=first].key",
expected: []string{"spec", "data", "[name=first]", "key"},
},
"key, value with . prefix": {
input: "spec.data.[.name=.first].key",
expected: []string{"spec", "data", "[.name=.first]", "key"},
},
"key, value with . suffix": {
input: "spec.data.[name.=first.].key",
expected: []string{"spec", "data", "[name.=first.]", "key"},
},
"multiple '.' in value": {
input: "spec.data.[name=f.i.r.s.t.].key",
expected: []string{"spec", "data", "[name=f.i.r.s.t.]", "key"},
},
"with escaped delimiter": {
input: `spec\.replicas`,
expected: []string{`spec.replicas`},
},
"unmatched bracket": {
input: "spec.data.[name=f.i.[r.s.t..key",
expected: []string{"spec", "data", "[name=f.i.[r.s.t..key"},
},
"mapping value with .": {
input: "metadata.annotations.[a.b.c/d.e.f-g.]",
expected: []string{"metadata", "annotations", "a.b.c/d.e.f-g."},
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
assert.Equal(t, tc.expected, SmarterPathSplitter(tc.input, "."))
})
}
}

View File

@@ -0,0 +1,44 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils
// StringSliceIndex returns the index of the str, else -1.
func StringSliceIndex(slice []string, str string) int {
for i := range slice {
if slice[i] == str {
return i
}
}
return -1
}
// StringSliceContains returns true if the slice has the string.
func StringSliceContains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
// SameEndingSubSlice returns true if the slices end the same way, e.g.
// {"a", "b", "c"}, {"b", "c"} => true
// {"a", "b", "c"}, {"a", "b"} => false
// If one slice is empty and the other is not, return false.
func SameEndingSubSlice(shortest, longest []string) bool {
if len(shortest) > len(longest) {
longest, shortest = shortest, longest
}
diff := len(longest) - len(shortest)
if len(shortest) == 0 {
return diff == 0
}
for i := len(shortest) - 1; i >= 0; i-- {
if longest[i+diff] != shortest[i] {
return false
}
}
return true
}

View File

@@ -0,0 +1,37 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils_test
import (
"testing"
"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/api/internal/utils"
)
func TestStringSliceIndex(t *testing.T) {
assert.Equal(t, 0, StringSliceIndex([]string{"a", "b"}, "a"))
assert.Equal(t, 1, StringSliceIndex([]string{"a", "b"}, "b"))
assert.Equal(t, -1, StringSliceIndex([]string{"a", "b"}, "c"))
assert.Equal(t, -1, StringSliceIndex([]string{}, "c"))
}
func TestStringSliceContains(t *testing.T) {
assert.True(t, StringSliceContains([]string{"a", "b"}, "a"))
assert.True(t, StringSliceContains([]string{"a", "b"}, "b"))
assert.False(t, StringSliceContains([]string{"a", "b"}, "c"))
assert.False(t, StringSliceContains([]string{}, "c"))
}
func TestSameEndingSubarray(t *testing.T) {
assert.True(t, SameEndingSubSlice([]string{"", "a", "b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{"a", "b", ""}, []string{"b", ""}))
assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b"}))
assert.True(t, SameEndingSubSlice([]string{"b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{}, []string{}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b", "a"}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{""}))
}

View File

@@ -3,9 +3,6 @@
package builtinpluginconsts
// TODO: rename 'fieldSpecs' to 'referrers' for clarity.
// This will, however, break anyone using a custom config.
const (
nameReferenceFieldSpecs = `
nameReference:

View File

@@ -2,5 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
// Package konfig provides configuration methods and constants
// for the kustomize API.
// for the kustomize API, e.g. the set of file names to look for
// to identify a kustomization root.
package konfig

View File

@@ -31,11 +31,12 @@ const (
// A program name, for use in help, finding the XDG_CONFIG_DIR, etc.
ProgramName = "kustomize"
// ConfigAnnoDomain is configuration-related annotation namespace.
ConfigAnnoDomain = "config.kubernetes.io"
// ConfigAnnoDomain is internal configuration-related annotation namespace.
// See https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md.
ConfigAnnoDomain = "internal.config.kubernetes.io"
// If a resource has this annotation, kustomize will drop it.
IgnoredByKustomizeAnnotation = ConfigAnnoDomain + "/local-config"
IgnoredByKustomizeAnnotation = "config.kubernetes.io/local-config"
// Label key that indicates the resources are built from Kustomize
ManagedbyLabelKey = "app.kubernetes.io/managed-by"

View File

@@ -8,8 +8,8 @@ import (
"path/filepath"
"runtime"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (

View File

@@ -9,20 +9,20 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestDefaultAbsPluginHome_NoKustomizePluginHomeEnv(t *testing.T) {
fSys := filesys.MakeFsInMemory()
keep, isSet := os.LookupEnv(KustomizePluginHomeEnv)
if isSet {
_ = os.Unsetenv(KustomizePluginHomeEnv)
unsetenv(t, KustomizePluginHomeEnv)
}
_, err := DefaultAbsPluginHome(fSys)
if isSet {
os.Setenv(KustomizePluginHomeEnv, keep)
setenv(t, KustomizePluginHomeEnv, keep)
}
if err == nil {
t.Fatalf("expected err")
@@ -43,13 +43,13 @@ func TestDefaultAbsPluginHome_NoKustomizePluginHomeEnv(t *testing.T) {
func TestDefaultAbsPluginHome_EmptyKustomizePluginHomeEnv(t *testing.T) {
keep, isSet := os.LookupEnv(KustomizePluginHomeEnv)
os.Setenv(KustomizePluginHomeEnv, "")
setenv(t, KustomizePluginHomeEnv, "")
_, err := DefaultAbsPluginHome(filesys.MakeFsInMemory())
if !isSet {
_ = os.Unsetenv(KustomizePluginHomeEnv)
unsetenv(t, KustomizePluginHomeEnv)
} else {
_ = os.Setenv(KustomizePluginHomeEnv, keep)
setenv(t, KustomizePluginHomeEnv, keep)
}
if err == nil {
t.Fatalf("expected err")
@@ -65,16 +65,15 @@ func TestDefaultAbsPluginHome_WithKustomizePluginHomeEnv(t *testing.T) {
keep, isSet := os.LookupEnv(KustomizePluginHomeEnv)
if !isSet {
keep = "whatever"
os.Setenv(KustomizePluginHomeEnv, keep)
setenv(t, KustomizePluginHomeEnv, keep)
}
fSys.Mkdir(keep)
err := fSys.Mkdir(keep)
require.NoError(t, err)
h, err := DefaultAbsPluginHome(fSys)
if !isSet {
_ = os.Unsetenv(KustomizePluginHomeEnv)
}
if err != nil {
t.Fatalf("unexpected err: %v", err)
unsetenv(t, KustomizePluginHomeEnv)
}
require.NoError(t, err)
if h != keep {
t.Fatalf("unexpected config dir: %s", h)
}
@@ -85,13 +84,14 @@ func TestDefaultAbsPluginHomeWithXdg(t *testing.T) {
keep, isSet := os.LookupEnv(XdgConfigHomeEnv)
if !isSet {
keep = "whatever"
os.Setenv(XdgConfigHomeEnv, keep)
setenv(t, XdgConfigHomeEnv, keep)
}
configDir := filepath.Join(keep, ProgramName, RelPluginHome)
fSys.Mkdir(configDir)
err := fSys.Mkdir(configDir)
require.NoError(t, err)
h, err := DefaultAbsPluginHome(fSys)
if !isSet {
_ = os.Unsetenv(XdgConfigHomeEnv)
unsetenv(t, XdgConfigHomeEnv)
}
if err != nil {
t.Fatalf("unexpected err: %v", err)
@@ -105,11 +105,11 @@ func TestDefaultAbsPluginHomeNoConfig(t *testing.T) {
fSys := filesys.MakeFsInMemory()
keep, isSet := os.LookupEnv(XdgConfigHomeEnv)
if isSet {
_ = os.Unsetenv(XdgConfigHomeEnv)
unsetenv(t, XdgConfigHomeEnv)
}
_, err := DefaultAbsPluginHome(fSys)
if isSet {
os.Setenv(XdgConfigHomeEnv, keep)
setenv(t, XdgConfigHomeEnv, keep)
}
if err == nil {
t.Fatalf("expected err")
@@ -121,13 +121,13 @@ func TestDefaultAbsPluginHomeNoConfig(t *testing.T) {
func TestDefaultAbsPluginHomeEmptyXdgConfig(t *testing.T) {
keep, isSet := os.LookupEnv(XdgConfigHomeEnv)
os.Setenv(XdgConfigHomeEnv, "")
setenv(t, XdgConfigHomeEnv, "")
if isSet {
_ = os.Unsetenv(XdgConfigHomeEnv)
unsetenv(t, XdgConfigHomeEnv)
}
_, err := DefaultAbsPluginHome(filesys.MakeFsInMemory())
if isSet {
os.Setenv(XdgConfigHomeEnv, keep)
setenv(t, XdgConfigHomeEnv, keep)
}
if err == nil {
t.Fatalf("expected err")
@@ -142,14 +142,16 @@ func TestDefaultAbsPluginHomeNoXdgWithDotConfig(t *testing.T) {
fSys := filesys.MakeFsInMemory()
configDir := filepath.Join(
HomeDir(), XdgConfigHomeEnvDefault, ProgramName, RelPluginHome)
fSys.Mkdir(configDir)
err := fSys.Mkdir(configDir)
require.NoError(t, err)
keep, isSet := os.LookupEnv(XdgConfigHomeEnv)
if isSet {
_ = os.Unsetenv(XdgConfigHomeEnv)
unsetenv(t, XdgConfigHomeEnv)
}
s, _ := DefaultAbsPluginHome(fSys)
s, err := DefaultAbsPluginHome(fSys)
require.NoError(t, err)
if isSet {
os.Setenv(XdgConfigHomeEnv, keep)
setenv(t, XdgConfigHomeEnv, keep)
}
if s != configDir {
t.Fatalf("unexpected config dir: %s", s)
@@ -160,16 +162,26 @@ func TestDefaultAbsPluginHomeNoXdgJustHomeDir(t *testing.T) {
fSys := filesys.MakeFsInMemory()
configDir := filepath.Join(
HomeDir(), ProgramName, RelPluginHome)
fSys.Mkdir(configDir)
err := fSys.Mkdir(configDir)
require.NoError(t, err)
keep, isSet := os.LookupEnv(XdgConfigHomeEnv)
if isSet {
_ = os.Unsetenv(XdgConfigHomeEnv)
unsetenv(t, XdgConfigHomeEnv)
}
s, _ := DefaultAbsPluginHome(fSys)
s, err := DefaultAbsPluginHome(fSys)
require.NoError(t, err)
if isSet {
os.Setenv(XdgConfigHomeEnv, keep)
setenv(t, XdgConfigHomeEnv, keep)
}
if s != configDir {
t.Fatalf("unexpected config dir: %s", s)
}
}
func setenv(t *testing.T, key, value string) {
require.NoError(t, os.Setenv(key, value))
}
func unsetenv(t *testing.T, key string) {
require.NoError(t, os.Unsetenv(key))
}

View File

@@ -0,0 +1,265 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
_ "sigs.k8s.io/kustomize/api/krusty"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestAnnoOriginLocalFiles(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
ports:
- port: 7002
`)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service.yaml
buildMetadata: [originAnnotations]
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: service.yaml
name: myService
spec:
ports:
- port: 7002
`)
}
func TestAnnoOriginLocalFilesWithOverlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: b-
resources:
- namespace.yaml
- role.yaml
- service.yaml
- deployment.yaml
`)
th.WriteF("base/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
`)
th.WriteF("base/namespace.yaml", `
apiVersion: v1
kind: Namespace
metadata:
name: myNs
`)
th.WriteF("base/role.yaml", `
apiVersion: v1
kind: Role
metadata:
name: myRole
`)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: myDep
`)
th.WriteK("prod", `
namePrefix: p-
resources:
- ../base
- service.yaml
- namespace.yaml
buildMetadata: [originAnnotations]
`)
th.WriteF("prod/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService2
`)
th.WriteF("prod/namespace.yaml", `
apiVersion: v1
kind: Namespace
metadata:
name: myNs2
`)
m := th.Run("prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/namespace.yaml
name: myNs
---
apiVersion: v1
kind: Role
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/role.yaml
name: p-b-myRole
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/service.yaml
name: p-b-myService
---
apiVersion: v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/deployment.yaml
name: p-b-myDep
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: service.yaml
name: p-myService2
---
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/origin: |
path: namespace.yaml
name: myNs2
`)
}
// This is a copy of TestGeneratorBasics in configmaps_test.go,
// except that we've enabled the addAnnoOrigin option
// (which doesn't do anything yet).
// TODO: Generated resources should receive the annotation
// config.kubernetes.io/origin: |
// generated-by: path/to/kustomization.yaml
func TestGeneratorWithAnnoOrigin(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
namePrefix: blah-
configMapGenerator:
- name: bob
literals:
- fruit=apple
- vegetable=broccoli
envs:
- foo.env
env: bar.env
files:
- passphrase=phrase.dat
- forces.txt
- name: json
literals:
- 'v2=[{"path": "var/druid/segment-cache"}]'
- >-
druid_segmentCache_locations=[{"path":
"var/druid/segment-cache",
"maxSize": 32000000000,
"freeSpacePercent": 1.0}]
secretGenerator:
- name: bob
literals:
- fruit=apple
- vegetable=broccoli
envs:
- foo.env
files:
- passphrase=phrase.dat
- forces.txt
env: bar.env
`)
th.WriteF("foo.env", `
MOUNTAIN=everest
OCEAN=pacific
`)
th.WriteF("bar.env", `
BIRD=falcon
`)
th.WriteF("phrase.dat", `
Life is short.
But the years are long.
Not while the evil days come not.
`)
th.WriteF("forces.txt", `
gravitational
electromagnetic
strong nuclear
weak nuclear
`)
opts := th.MakeDefaultOptions()
m := th.Run(".", opts)
th.AssertActualEqualsExpected(
m, `
apiVersion: v1
data:
BIRD: falcon
MOUNTAIN: everest
OCEAN: pacific
forces.txt: |2
gravitational
electromagnetic
strong nuclear
weak nuclear
fruit: apple
passphrase: |2
Life is short.
But the years are long.
Not while the evil days come not.
vegetable: broccoli
kind: ConfigMap
metadata:
name: blah-bob-g9df72cd5b
---
apiVersion: v1
data:
druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize":
32000000000, "freeSpacePercent": 1.0}]'
v2: '[{"path": "var/druid/segment-cache"}]'
kind: ConfigMap
metadata:
name: blah-json-5298bc8g99
---
apiVersion: v1
data:
BIRD: ZmFsY29u
MOUNTAIN: ZXZlcmVzdA==
OCEAN: cGFjaWZpYw==
forces.txt: |
CmdyYXZpdGF0aW9uYWwKZWxlY3Ryb21hZ25ldGljCnN0cm9uZyBudWNsZWFyCndlYWsgbn
VjbGVhcgo=
fruit: YXBwbGU=
passphrase: |
CkxpZmUgaXMgc2hvcnQuCkJ1dCB0aGUgeWVhcnMgYXJlIGxvbmcuCk5vdCB3aGlsZSB0aG
UgZXZpbCBkYXlzIGNvbWUgbm90Lgo=
vegetable: YnJvY2NvbGk=
kind: Secret
metadata:
name: blah-bob-58g62h555c
type: Opaque
`)
}

View File

@@ -1,17 +1,52 @@
package krusty_test
import (
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestFnExecGenerator(t *testing.T) {
// Function plugins should not need the env setup done by MakeEnhancedHarness
th := kusttest_test.MakeHarness(t)
const generateDeploymentDotSh = `#!/bin/sh
th.WriteK(".", `
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
`
func TestFnExecGenerator(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
th.WriteK(tmpDir.String(), `
resources:
- short_secret.yaml
generators:
@@ -19,7 +54,8 @@ generators:
`)
// Create some additional resource just to make sure everything is added
th.WriteF("short_secret.yaml", `
th.WriteF(filepath.Join(tmpDir.String(), "short_secret.yaml"),
`
apiVersion: v1
kind: Secret
metadata:
@@ -32,22 +68,25 @@ stringData:
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(tmpDir.String(), "generateDeployment.sh"), generateDeploymentDotSh)
th.WriteF("gener.yaml", `
assert.NoError(t, os.Chmod(filepath.Join(tmpDir.String(), "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(tmpDir.String(), "gener.yaml"), `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./fnplugin_test/fnexectest.sh
path: ./generateDeployment.sh
spec:
`)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
m := th.Run(".", o)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
m := th.Run(tmpDir.String(), o)
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Secret
metadata:
labels:
@@ -63,7 +102,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
@@ -80,7 +118,99 @@ spec:
containers:
- image: nginx
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestFnExecGeneratorWithOverlay(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
base := filepath.Join(tmpDir.String(), "base")
prod := filepath.Join(tmpDir.String(), "prod")
assert.NoError(t, fSys.Mkdir(base))
assert.NoError(t, fSys.Mkdir(prod))
th.WriteK(base, `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
th.WriteK(prod, `
resources:
- ../base
`)
th.WriteF(filepath.Join(base, "short_secret.yaml"),
`
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(base, "generateDeployment.sh"), generateDeploymentDotSh)
assert.NoError(t, os.Chmod(filepath.Join(base, "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(base, "gener.yaml"), `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./generateDeployment.sh
spec:
`)
m := th.Run(prod, o)
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func skipIfNoDocker(t *testing.T) {
@@ -146,8 +276,6 @@ type: Opaque
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
annotations:
config.kubernetes.io/path: config/demo-budget_poddisruptionbudget.yaml
labels:
app: cockroachdb
name: demo
@@ -162,8 +290,6 @@ spec:
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo-public_service.yaml
labels:
app: cockroachdb
name: demo
@@ -184,7 +310,6 @@ apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo_service.yaml
prometheus.io/path: _status/vars
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
@@ -209,8 +334,6 @@ spec:
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
config.kubernetes.io/path: config/demo_statefulset.yaml
labels:
app: cockroachdb
name: demo
@@ -383,7 +506,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
@@ -450,8 +572,6 @@ data:
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_my-namespace.yaml
labels:
my-ns-name: function-test
name: my-namespace
@@ -459,8 +579,6 @@ metadata:
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_another-namespace.yaml
labels:
my-ns-name: function-test
name: another-namespace
@@ -508,8 +626,6 @@ data:
value: value
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/path: configmap_env.yaml
name: env
`)
}

View File

@@ -1,24 +0,0 @@
#!/bin/sh
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF

View File

@@ -0,0 +1,124 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestGkeGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK(".", `
generators:
- |-
apiVersion: builtin
kind: IAMPolicyGenerator
metadata:
name: my-gke-generator
cloud: gke
kubernetesService:
name: k8s-sa-name
serviceAccount:
name: gsa-name
projectId: project-id
`)
expected := `
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name@project-id.iam.gserviceaccount.com
name: k8s-sa-name
`
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}
func TestGkeGeneratorWithNamespace(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK(".", `
generators:
- |-
apiVersion: builtin
kind: IAMPolicyGenerator
metadata:
name: my-gke-generator
cloud: gke
kubernetesService:
namespace: k8s-namespace
name: k8s-sa-name
serviceAccount:
name: gsa-name
projectId: project-id
`)
expected := `
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name@project-id.iam.gserviceaccount.com
name: k8s-sa-name
namespace: k8s-namespace
`
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}
func TestGkeGeneratorWithTwo(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK(".", `
generators:
- gkegenerator1.yaml
- gkegenerator2.yaml
`)
th.WriteF("gkegenerator1.yaml", `
apiVersion: builtin
kind: IAMPolicyGenerator
metadata:
name: my-gke-generator1
cloud: gke
kubernetesService:
namespace: k8s-namespace-1
name: k8s-sa-name-1
serviceAccount:
name: gsa-name-1
projectId: project-id-1
`)
th.WriteF("gkegenerator2.yaml", `
apiVersion: builtin
kind: IAMPolicyGenerator
metadata:
name: my-gke-generator2
cloud: gke
kubernetesService:
name: k8s-sa-name-2
serviceAccount:
name: gsa-name-2
projectId: project-id-2
`)
expected := `
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name-1@project-id-1.iam.gserviceaccount.com
name: k8s-sa-name-1
namespace: k8s-namespace-1
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: gsa-name-2@project-id-2.iam.gserviceaccount.com
name: k8s-sa-name-2
`
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}

View File

@@ -230,3 +230,92 @@ spec:
name: configmap-in-base
`)
}
func TestPathWithCronJobV1(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- resources.yaml
patches:
- patch: |
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
jobTemplate:
spec:
template:
spec:
containers:
- name: test
env:
- name: ENV_NEW
value: val_new
target:
kind: CronJob
name: test
`)
th.WriteF("resources.yaml", `
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
schedule: "5 10 * * 1"
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 3
template:
spec:
restartPolicy: Never
containers:
- name: test
image: bash
command:
- /bin/sh
- -c
- echo "test"
env:
- name: ENV1
value: val1
- name: ENV2
value: val2
- name: ENV3
value: val3`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 3
template:
spec:
containers:
- command:
- /bin/sh
- -c
- echo "test"
env:
- name: ENV_NEW
value: val_new
- name: ENV1
value: val1
- name: ENV2
value: val2
- name: ENV3
value: val3
image: bash
name: test
restartPolicy: Never
schedule: 5 10 * * 1
`)
}

View File

@@ -8,7 +8,6 @@ import (
"path/filepath"
"sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/filesys"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/konfig"
@@ -17,6 +16,7 @@ import (
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/openapi"
)
@@ -90,19 +90,25 @@ func (b *Kustomizer) Run(
return nil, err
}
if b.options.DoLegacyResourceSort {
builtins.NewLegacyOrderTransformerPlugin().Transform(m)
err = builtins.NewLegacyOrderTransformerPlugin().Transform(m)
if err != nil {
return nil, err
}
}
if b.options.AddManagedbyLabel {
t := builtins.LabelTransformerPlugin{
Labels: map[string]string{
konfig.ManagedbyLabelKey: fmt.Sprintf(
"kustomize-%s", provenance.GetProvenance().Semver())},
konfig.ManagedbyLabelKey: fmt.Sprintf("kustomize-%s", provenance.GetProvenance().Semver()),
},
FieldSpecs: []types.FieldSpec{{
Path: "metadata/labels",
CreateIfNotPresent: true,
}},
}
t.Transform(m)
err = t.Transform(m)
if err != nil {
return nil, err
}
}
m.RemoveBuildAnnotations()
return m, nil

View File

@@ -7,8 +7,8 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// A simple usage example to shows what happens when

View File

@@ -6,9 +6,319 @@ package krusty_test
import (
"testing"
"github.com/stretchr/testify/assert"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestPatchesInOneFile(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- namespace.yaml
- deployment-controller-manager.yaml
- deployment-audit-manager.yaml
`)
th.WriteF("base/namespace.yaml", `
apiVersion: v1
kind: Namespace
metadata:
labels:
control-plane: controller-manager
admission.gatekeeper.sh/ignore: no-self-managing
name: system
`)
th.WriteF("base/deployment-controller-manager.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
labels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
spec:
selector:
matchLabels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
replicas: 3
template:
metadata:
annotations:
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
labels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
spec:
containers:
- command:
- /manager
args:
- "--port=8443"
- "--logtostderr"
- "--exempt-namespace=gatekeeper-system"
- "--operation=webhook"
image: openpolicyagent/gatekeeper:v3.4.0
imagePullPolicy: Always
name: manager
terminationGracePeriodSeconds: 60
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
`)
th.WriteF("base/deployment-audit-manager.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: audit
namespace: system
labels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
spec:
selector:
matchLabels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
replicas: 1
template:
metadata:
labels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
annotations:
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
spec:
automountServiceAccountToken: true
containers:
- args:
- --operation=audit
- --operation=status
- --logtostderr
command:
- /manager
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
image: openpolicyagent/gatekeeper:v3.4.0
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 9090
name: manager
serviceAccountName: gatekeeper-admin
terminationGracePeriodSeconds: 60
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
`)
const imagePatchAuditManager = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: audit
namespace: system
spec:
template:
spec:
containers:
- image: AUDIT_IMAGE
name: manager
args:
- --port=8443
- --logtostderr
- --emit-admission-events
- --exempt-namespace=gatekeeper-system
- --operation=webhook
- --disable-opa-builtin=http.send
`
const imagePatchControllerManager = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- image: CONTROLLER_IMAGE
name: manager
args:
- --emit-audit-events
- --operation=audit
- --operation=status
- --logtostderr
`
th.WriteF(
"overlay/image_patch_audit_manager.yaml",
imagePatchAuditManager)
th.WriteF(
"overlay/image_patch_controller_manager.yaml",
imagePatchControllerManager)
const expected = `
apiVersion: v1
kind: Namespace
metadata:
labels:
admission.gatekeeper.sh/ignore: no-self-managing
control-plane: controller-manager
name: system
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
name: controller-manager
namespace: system
spec:
replicas: 3
selector:
matchLabels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
template:
metadata:
annotations:
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
labels:
control-plane: controller-manager
gatekeeper.sh/operation: webhook
spec:
containers:
- args:
- --emit-audit-events
- --operation=audit
- --operation=status
- --logtostderr
command:
- /manager
image: CONTROLLER_IMAGE
imagePullPolicy: Always
name: manager
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
terminationGracePeriodSeconds: 60
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
name: audit
namespace: system
spec:
replicas: 1
selector:
matchLabels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
template:
metadata:
annotations:
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
labels:
control-plane: audit-controller
gatekeeper.sh/operation: audit
spec:
automountServiceAccountToken: true
containers:
- args:
- --port=8443
- --logtostderr
- --emit-admission-events
- --exempt-namespace=gatekeeper-system
- --operation=webhook
- --disable-opa-builtin=http.send
command:
- /manager
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
image: AUDIT_IMAGE
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 9090
name: manager
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: gatekeeper-admin
terminationGracePeriodSeconds: 60
`
// Technique 1: "patchesStrategicMerge:" field, two patch files.
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- image_patch_controller_manager.yaml
- image_patch_audit_manager.yaml
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
// Technique 2: "patches:" field, two patch files.
th.WriteK("overlay", `
resources:
- ../base
patches:
- path: image_patch_controller_manager.yaml
- path: image_patch_audit_manager.yaml
`)
m = th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
// Technique 3: "patchesStrategicMerge:" field, one patch file.
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- twoPatchesInOneFile.yaml
`)
th.WriteF(
"overlay/twoPatchesInOneFile.yaml",
imagePatchAuditManager+"\n---\n"+imagePatchControllerManager)
m = th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
// Technique 4: "patches:" field, one patch file. Fails.
th.WriteK("overlay", `
resources:
- ../base
patches:
- path: twoPatchesInOneFile.yaml
`)
err := th.RunWithErr("overlay", th.MakeDefaultOptions())
assert.Error(t, err)
// This should fail, because the semantics of the `patches` field.
// That field allows specific patch targeting to a list of targets,
// while the `patchesStrategicMerge` field accepts patches that
// implicitly identify their targets via GVKN.
assert.Contains(t, err.Error(), "unable to parse SM or JSON patch from ")
}
func TestRemoveEmptyDirWithNullFieldInSmp(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `

View File

@@ -17,6 +17,11 @@ func writeTestSchema(th kusttest_test.Harness, filepath string) {
th.WriteF(filepath+"mycrd_schema.json", string(bytes))
}
func writeTestSchemaYaml(th kusttest_test.Harness, filepath string) {
bytes, _ := ioutil.ReadFile("testdata/customschema.yaml")
th.WriteF(filepath+"mycrd_schema.yaml", string(bytes))
}
func writeCustomResource(th kusttest_test.Harness, filepath string) {
th.WriteF(filepath, `
apiVersion: example.com/v1alpha1
@@ -103,6 +108,21 @@ openapi:
th.AssertActualEqualsExpected(m, patchedCustomResource)
}
func TestCustomOpenApiFieldYaml(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
resources:
- mycrd.yaml
openapi:
path: mycrd_schema.yaml
`+customSchemaPatch)
writeCustomResource(th, "mycrd.yaml")
writeTestSchemaYaml(th, "./")
openapi.ResetOpenAPI()
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, patchedCustomResource)
}
// Error if user tries to specify both builtin version
// and custom schema
func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
@@ -111,7 +131,7 @@ func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
resources:
- mycrd.yaml
openapi:
version: v1.20.4
version: v1.21.2
path: mycrd_schema.json
`+customSchemaPatch)
writeCustomResource(th, "mycrd.yaml")
@@ -197,7 +217,7 @@ openapi:
resources:
- ../base
openapi:
version: v1.20.4
version: v1.21.2
`+customSchemaPatch)
writeCustomResource(th, "base/mycrd.yaml")
writeTestSchema(th, "base/")
@@ -215,7 +235,7 @@ spec:
- image: nginx
name: server
`)
assert.Equal(t, "v1204", openapi.GetSchemaVersion())
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
}
func TestCustomOpenAPIFieldFromComponent(t *testing.T) {

View File

@@ -16,7 +16,7 @@ func TestOpenApiFieldBasicUsage(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
openapi:
version: v1.20.4
version: v1.21.2
resources:
- deployment.yaml
`)
@@ -44,7 +44,8 @@ spec:
containers:
- image: whatever
`)
assert.Equal(t, "v1204", openapi.GetSchemaVersion())
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
openapi.ResetOpenAPI()
}
func TestOpenApiFieldNotBuiltin(t *testing.T) {
@@ -71,6 +72,7 @@ spec:
if err == nil {
t.Fatalf("expected an error")
}
openapi.ResetOpenAPI()
}
func TestOpenApiFieldDefaultVersion(t *testing.T) {
@@ -104,4 +106,5 @@ spec:
- image: whatever
`)
assert.Equal(t, kubernetesapi.DefaultOpenAPI, openapi.GetSchemaVersion())
openapi.ResetOpenAPI()
}

View File

@@ -9,9 +9,9 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// The PrintPluginEnv plugin is a toy plugin that emits

View File

@@ -4,12 +4,13 @@
package krusty_test
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestRemoteLoad(t *testing.T) {
@@ -39,3 +40,124 @@ spec:
name: nginx
`, string(yml))
}
func TestRemoteResource(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
`)))
m, err := b.Run(
fSys,
tmpDir.String())
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
labels:
app: myapp
name: dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestRemoteResourceAnnoOrigin(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
buildMetadata: [originAnnotations]
`)))
m, err := b.Run(
fSys,
tmpDir.String())
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
annotations:
config.kubernetes.io/origin: |
path: examples/multibases/base/pod.yaml
repo: https://github.com/kubernetes-sigs/kustomize
ref: v1.0.6
labels:
app: myapp
name: dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestRemoteResourceAsBaseWithAnnoOrigin(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
base := filepath.Join(tmpDir.String(), "base")
prod := filepath.Join(tmpDir.String(), "prod")
assert.NoError(t, fSys.Mkdir(base))
assert.NoError(t, fSys.Mkdir(prod))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
`)))
assert.NoError(t, fSys.WriteFile(filepath.Join(prod, "kustomization.yaml"), []byte(`
resources:
- ../base
namePrefix: prefix-
buildMetadata: [originAnnotations]
`)))
m, err := b.Run(
fSys,
prod)
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
annotations:
config.kubernetes.io/origin: |
path: examples/multibases/base/pod.yaml
repo: https://github.com/kubernetes-sigs/kustomize
ref: v1.0.6
labels:
app: myapp
name: prefix-dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}

View File

@@ -261,3 +261,224 @@ spec:
name: nginx
`)
}
func TestReplacementTransformerWithOriginalName(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteF("base/deployments.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: target
spec:
template:
spec:
containers:
- image: nginx:oldtag
name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: source
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
`)
th.WriteK("base", `
resources:
- deployments.yaml
`)
th.WriteK("overlay", `
namePrefix: prefix1-
resources:
- ../base
`)
th.WriteK(".", `
namePrefix: prefix2-
resources:
- overlay
replacements:
- path: replacement.yaml
`)
th.WriteF("replacement.yaml", `
source:
name: source
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
name: prefix1-target
fieldPaths:
- spec.template.spec.containers.[name=nginx].image
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: prefix2-prefix1-target
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prefix2-prefix1-source
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
`)
}
// TODO: Address namePrefix in overlay not applying to replacement targets
// The property `data.blue-name` should end up being `overlay-blue` instead of `blue`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithNamePrefixOverlay(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("base", `
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.name
targets:
- select:
name: red
fieldPaths:
- data.blue-name
options:
create: true
`)
th.WriteK(".", `
namePrefix: overlay-
resources:
- base
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: overlay-blue
---
apiVersion: v1
data:
blue-name: blue
kind: ConfigMap
metadata:
name: overlay-red
`)
}
// TODO: Address namespace in overlay not applying to replacement targets
// The property `data.blue-namespace` should end up being `overlay-namespace` instead of `base-namespace`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithNamespaceOverlay(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("base", `
namespace: base-namespace
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.namespace
targets:
- select:
name: red
fieldPaths:
- data.blue-namespace
options:
create: true
`)
th.WriteK(".", `
namespace: overlay-namespace
resources:
- base
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: blue
namespace: overlay-namespace
---
apiVersion: v1
data:
blue-namespace: base-namespace
kind: ConfigMap
metadata:
name: red
namespace: overlay-namespace
`)
}
// TODO: Address configMapGenerator suffix not applying to replacement targets
// The property `data.blue-name` should end up being `blue-6ct58987ht` instead of `blue`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithConfigMapGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK(".", `
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.name
targets:
- select:
name: red
fieldPaths:
- data.blue-name
options:
create: true
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: blue-6ct58987ht
---
apiVersion: v1
data:
blue-name: blue
kind: ConfigMap
metadata:
name: red-dc6gc5btkc
`)
}

75
api/krusty/testdata/customschema.yaml vendored Normal file
View File

@@ -0,0 +1,75 @@
definitions:
v1alpha1.MyCRD:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
properties:
template:
"$ref": "#/definitions/io.k8s.api.core.v1.PodTemplateSpec"
type: object
status:
properties:
success:
type: boolean
type: object
type: object
x-kubernetes-group-version-kind:
- group: example.com
kind: MyCRD
version: v1alpha1
io.k8s.api.core.v1.PodTemplateSpec:
properties:
metadata:
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
spec:
"$ref": "#/definitions/io.k8s.api.core.v1.PodSpec"
type: object
io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta:
properties:
name:
type: string
type: object
io.k8s.api.core.v1.PodSpec:
properties:
containers:
items:
"$ref": "#/definitions/io.k8s.api.core.v1.Container"
type: array
x-kubernetes-patch-merge-key: name
x-kubernetes-patch-strategy: merge
type: object
io.k8s.api.core.v1.Container:
properties:
command:
items:
type: string
type: array
image:
type: string
name:
type: string
ports:
items:
"$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort"
type: array
x-kubernetes-list-map-keys:
- containerPort
- protocol
x-kubernetes-list-type: map
x-kubernetes-patch-merge-key: containerPort
x-kubernetes-patch-strategy: merge
type: object
io.k8s.api.core.v1.ContainerPort:
properties:
containerPort:
type: integer
name:
type: string
protocol:
type: string
type: object

View File

@@ -7,10 +7,11 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/stretchr/testify/require"
ldr "sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func makeKvLoader(fSys filesys.FileSystem) *loader {
@@ -83,7 +84,8 @@ func TestKeyValuesFromFileSources(t *testing.T) {
}
fSys := filesys.MakeFsInMemory()
fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar"))
err := fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar"))
require.NoError(t, err)
kvl := makeKvLoader(fSys)
for _, tc := range tests {
kvs, err := kvl.keyValuesFromFileSources(tc.sources)

View File

@@ -12,9 +12,9 @@ import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// fileLoader is a kustomization's interface to files.

View File

@@ -14,10 +14,10 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
type testData struct {

View File

@@ -5,9 +5,9 @@
package loader
import (
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// NewLoader returns a Loader pointed at the given target.

View File

@@ -6,7 +6,7 @@ package loader
import (
"fmt"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
type LoadRestrictorFunc func(

View File

@@ -8,7 +8,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestRestrictionNone(t *testing.T) {

View File

@@ -8,7 +8,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
@@ -16,6 +15,7 @@ import (
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -219,8 +219,10 @@ BAR=baz
}
r, err := rmF.NewResMapFromConfigMapArgs(kvLdr, tc.input)
assert.NoError(t, err, tc.description)
r.RemoveBuildAnnotations()
rYaml, err := r.AsYaml()
assert.NoError(t, err, tc.description)
tc.expected.RemoveBuildAnnotations()
expYaml, err := tc.expected.AsYaml()
assert.NoError(t, err, tc.description)
assert.Equal(t, expYaml, rYaml)
@@ -252,6 +254,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual.RemoveBuildAnnotations()
actYaml, err := actual.AsYaml()
assert.NoError(t, err)

View File

@@ -136,6 +136,10 @@ type ResMap interface {
// self, then its behavior _cannot_ be merge or replace.
AbsorbAll(ResMap) error
// AnnotateAll annotates all resources in the ResMap with
// the provided key value pair.
AnnotateAll(key string, value string) error
// AsYaml returns the yaml form of resources.
AsYaml() ([]byte, error)
@@ -210,6 +214,35 @@ type ResMap interface {
// namespaces. Cluster wide objects are never excluded.
SubsetThatCouldBeReferencedByResource(*resource.Resource) ResMap
// DeAnchor replaces YAML aliases with structured data copied from anchors.
// This cannot be undone; if desired, call DeepCopy first.
// Subsequent marshalling to YAML will no longer have anchor
// definitions ('&') or aliases ('*').
//
// Anchors are not expected to work across YAML 'documents'.
// If three resources are loaded from one file containing three YAML docs:
//
// {resourceA}
// ---
// {resourceB}
// ---
// {resourceC}
//
// then anchors defined in A cannot be seen from B and C and vice versa.
// OTOH, cross-resource links (a field in B referencing fields in A) will
// work if the resources are gathered in a ResourceList:
//
// apiVersion: config.kubernetes.io/v1
// kind: ResourceList
// metadata:
// name: someList
// items:
// - {resourceA}
// - {resourceB}
// - {resourceC}
//
DeAnchor() error
// DeepCopy copies the ResMap and underlying resources.
DeepCopy() ResMap

View File

@@ -9,6 +9,7 @@ import (
"reflect"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/annotations"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -531,6 +532,19 @@ func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error {
}
}
// AnnotateAll implements ResMap
func (m *resWrangler) AnnotateAll(key string, value string) error {
return m.ApplyFilter(annotations.Filter{
Annotations: map[string]string{
key: value,
},
FsSlice: []types.FieldSpec{{
Path: "metadata/annotations",
CreateIfNotPresent: true,
}},
})
}
// Select returns a list of resources that
// are selected by a Selector
func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
@@ -593,6 +607,16 @@ func (m *resWrangler) ToRNodeSlice() []*kyaml.RNode {
return result
}
// DeAnchor implements ResMap.
func (m *resWrangler) DeAnchor() (err error) {
for i := range m.rList {
if err = m.rList[i].DeAnchor(); err != nil {
return err
}
}
return nil
}
// ApplySmPatch applies the patch, and errors on Id collisions.
func (m *resWrangler) ApplySmPatch(
selectedSet *resource.IdSet, patch *resource.Resource) error {

View File

@@ -343,9 +343,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"metadata": map[string]interface{}{
"name": "new-alice",
"annotations": map[string]interface{}{
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "alice",
"config.kubernetes.io/previousNamespaces": "default",
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "alice",
"internal.config.kubernetes.io/previousNamespaces": "default",
},
},
})
@@ -356,9 +356,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"metadata": map[string]interface{}{
"name": "new-bob",
"annotations": map[string]interface{}{
"config.kubernetes.io/previousKinds": "ConfigMap,ConfigMap",
"config.kubernetes.io/previousNames": "bob,bob2",
"config.kubernetes.io/previousNamespaces": "default,default",
"internal.config.kubernetes.io/previousKinds": "ConfigMap,ConfigMap",
"internal.config.kubernetes.io/previousNames": "bob,bob2",
"internal.config.kubernetes.io/previousNamespaces": "default,default",
},
},
})
@@ -370,9 +370,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"name": "new-bob",
"namespace": "new-happy",
"annotations": map[string]interface{}{
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "bob",
"config.kubernetes.io/previousNamespaces": "happy",
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "bob",
"internal.config.kubernetes.io/previousNamespaces": "happy",
},
},
})
@@ -384,9 +384,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"name": "charlie",
"namespace": "happy",
"annotations": map[string]interface{}{
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "charlie",
"config.kubernetes.io/previousNamespaces": "default",
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "charlie",
"internal.config.kubernetes.io/previousNamespaces": "default",
},
},
})
@@ -845,6 +845,8 @@ func TestAbsorbAll(t *testing.T) {
}))
w := makeMap1()
assert.NoError(t, w.AbsorbAll(makeMap2(types.BehaviorMerge)))
expected.RemoveBuildAnnotations()
w.RemoveBuildAnnotations()
assert.NoError(t, expected.ErrorIfNotEqualLists(w))
w = makeMap1()
assert.NoError(t, w.AbsorbAll(nil))
@@ -853,6 +855,7 @@ func TestAbsorbAll(t *testing.T) {
w = makeMap1()
w2 := makeMap2(types.BehaviorReplace)
assert.NoError(t, w.AbsorbAll(w2))
w2.RemoveBuildAnnotations()
assert.NoError(t, w2.ErrorIfNotEqualLists(w))
w = makeMap1()
w2 = makeMap2(types.BehaviorUnspecified)
@@ -899,6 +902,100 @@ rules:
}
}
func TestDeAnchorSingleDoc(t *testing.T) {
input := `apiVersion: v1
kind: ConfigMap
metadata:
name: wildcard
data:
color: &color-used blue
feeling: *color-used
`
rm, err := rmF.NewResMapFromBytes([]byte(input))
assert.NoError(t, err)
assert.NoError(t, rm.DeAnchor())
yaml, err := rm.AsYaml()
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(`
apiVersion: v1
data:
color: blue
feeling: blue
kind: ConfigMap
metadata:
name: wildcard
`), strings.TrimSpace(string(yaml)))
}
// Anchor references don't cross YAML document boundaries.
func TestDeAnchorMultiDoc(t *testing.T) {
input := `apiVersion: v1
kind: ConfigMap
metadata:
name: betty
data:
color: &color-used blue
feeling: *color-used
---
apiVersion: v1
kind: ConfigMap
metadata:
name: bob
data:
color: red
feeling: *color-used
`
_, err := rmF.NewResMapFromBytes([]byte(input))
assert.Error(t, err)
assert.Contains(t, err.Error(), "unknown anchor 'color-used' referenced")
}
// Anchor references cross list elements in a ResourceList.
func TestDeAnchorResourceList(t *testing.T) {
input := `apiVersion: config.kubernetes.io/v1
kind: ResourceList
metadata:
name: aShortList
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: betty
data:
color: &color-used blue
feeling: *color-used
- apiVersion: v1
kind: ConfigMap
metadata:
name: bob
data:
color: red
feeling: *color-used
`
rm, err := rmF.NewResMapFromBytes([]byte(input))
assert.NoError(t, err)
assert.NoError(t, rm.DeAnchor())
yaml, err := rm.AsYaml()
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(`
apiVersion: v1
data:
color: blue
feeling: blue
kind: ConfigMap
metadata:
name: betty
---
apiVersion: v1
data:
color: red
feeling: blue
kind: ConfigMap
metadata:
name: bob
`), strings.TrimSpace(string(yaml)))
}
func TestApplySmPatch_General(t *testing.T) {
const (
myDeployment = "Deployment"

View File

@@ -22,6 +22,12 @@ import (
// Factory makes instances of Resource.
type Factory struct {
hasher ifc.KustHasher
// When set to true, IncludeLocalConfigs indicates
// that Factory should include resources with the
// annotation 'config.kubernetes.io/local-config'.
// By default these resources are ignored.
IncludeLocalConfigs bool
}
// NewFactory makes an instance of Factory.
@@ -58,18 +64,23 @@ func (rf *Factory) FromMapAndOption(
// TODO: return err instead of log.
log.Fatal(err)
}
return rf.makeOne(n, types.NewGenArgs(args))
return rf.makeOne(n, args)
}
// makeOne returns a new instance of Resource.
func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GenArgs) *Resource {
func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GeneratorArgs) *Resource {
if rn == nil {
log.Fatal("RNode must not be null")
}
if o == nil {
o = types.NewGenArgs(nil)
resource := &Resource{RNode: *rn}
if o != nil {
if o.Options == nil || !o.Options.DisableNameSuffixHash {
resource.EnableHashSuffix()
}
resource.SetBehavior(types.NewGenerationBehavior(o.Behavior))
}
return &Resource{RNode: *rn, options: o}
return resource
}
// SliceFromPatches returns a slice of resources given a patch path
@@ -221,13 +232,15 @@ 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 !rf.IncludeLocalConfigs {
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)
@@ -257,7 +270,7 @@ func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs)
if err != nil {
return nil, err
}
return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil
return rf.makeOne(rn, &args.GeneratorArgs), nil
}
// MakeSecret makes an instance of Resource for Secret
@@ -266,5 +279,5 @@ func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Reso
if err != nil {
return nil, err
}
return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil
return rf.makeOne(rn, &args.GeneratorArgs), nil
}

View File

@@ -9,10 +9,10 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/loader"
. "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestSliceFromBytes(t *testing.T) {

60
api/resource/origin.go Normal file
View File

@@ -0,0 +1,60 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource
import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/internal/git"
)
// Origin retains information about where resources in the output
// of `kustomize build` originated from
type Origin struct {
// Path is the path to the resource, rooted from the directory upon
// which `kustomize build` was invoked
Path string
// Repo is the remote repository that the resource originated from if it is
// not from a local file
Repo string
// Ref is the ref of the remote repository that the resource originated from
// if it is not from a local file
Ref string
}
// Copy returns a copy of origin
func (origin *Origin) Copy() Origin {
return *origin
}
// Append returns a copy of origin with a path appended to it
func (origin *Origin) Append(path string) *Origin {
originCopy := origin.Copy()
repoSpec, err := git.NewRepoSpecFromUrl(path)
if err == nil {
originCopy.Repo = repoSpec.Host + repoSpec.OrgRepo
absPath := repoSpec.AbsPath()
path = absPath[strings.Index(absPath[1:], "/")+1:][1:]
originCopy.Path = ""
originCopy.Ref = repoSpec.Ref
}
originCopy.Path = filepath.Join(originCopy.Path, path)
return &originCopy
}
// String returns a string version of origin
func (origin *Origin) String() string {
var anno string
anno = anno + "path: " + origin.Path + "\n"
if origin.Repo != "" {
anno = anno + "repo: " + origin.Repo + "\n"
}
if origin.Ref != "" {
anno = anno + "ref: " + origin.Ref + "\n"
}
return anno
}

View File

@@ -0,0 +1,83 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource_test
import (
"testing"
. "sigs.k8s.io/kustomize/api/resource"
)
func TestOriginAppend(t *testing.T) {
tests := []struct {
in *Origin
path string
expected string
}{
{
in: &Origin{
Path: "prod",
},
path: "service.yaml",
expected: `path: prod/service.yaml
`,
},
{
in: &Origin{
Path: "overlay/prod",
},
path: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
expected: `path: examples/multibases/dev
repo: https://github.com/kubernetes-sigs/kustomize
`,
},
}
for _, test := range tests {
actual := test.in.Append(test.path).String()
if actual != test.expected {
t.Fatalf("Expected %v, but got %v\n", test.expected, actual)
}
}
}
func TestOriginString(t *testing.T) {
tests := []struct {
in *Origin
expected string
}{
{
in: &Origin{
Path: "prod/service.yaml",
Repo: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
Ref: "v1.0.6",
},
expected: `path: prod/service.yaml
repo: github.com/kubernetes-sigs/kustomize/examples/multibases/dev/
ref: v1.0.6
`,
},
{
in: &Origin{
Path: "prod/service.yaml",
Repo: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
},
expected: `path: prod/service.yaml
repo: github.com/kubernetes-sigs/kustomize/examples/multibases/dev/
`,
},
{
in: &Origin{
Path: "prod/service.yaml",
},
expected: `path: prod/service.yaml
`,
},
}
for _, test := range tests {
if test.in.String() != test.expected {
t.Fatalf("Expected %v, but got %v\n", test.expected, test.in.String())
}
}
}

View File

@@ -4,16 +4,16 @@
package resource
import (
"errors"
"fmt"
"log"
"strings"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/resid"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/yaml"
@@ -23,33 +23,24 @@ import (
// paired with metadata used by kustomize.
type Resource struct {
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"
var BuildAnnotations = []string{
utils.BuildAnnotationPreviousKinds,
utils.BuildAnnotationPreviousNames,
utils.BuildAnnotationPrefixes,
utils.BuildAnnotationSuffixes,
utils.BuildAnnotationPreviousNamespaces,
utils.BuildAnnotationAllowNameChange,
utils.BuildAnnotationAllowKindChange,
utils.BuildAnnotationsRefBy,
utils.BuildAnnotationsGenBehavior,
utils.BuildAnnotationsGenAddHashSuffix,
// 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"
allowed = "allowed"
)
var buildAnnotations = []string{
buildAnnotationPreviousKinds,
buildAnnotationPreviousNames,
buildAnnotationPrefixes,
buildAnnotationSuffixes,
buildAnnotationPreviousNamespaces,
buildAnnotationAllowNameChange,
buildAnnotationAllowKindChange,
kioutil.PathAnnotation,
kioutil.IndexAnnotation,
kioutil.SeqIndentAnnotation,
}
func (r *Resource) ResetRNode(incoming *Resource) {
@@ -95,6 +86,8 @@ func (r *Resource) DeepCopy() *Resource {
// CopyMergeMetaDataFieldsFrom copies everything but the non-metadata in
// the resource.
// TODO: move to RNode, use GetMeta to improve performance.
// TODO: make a version of mergeStringMaps that is build-annotation aware
// to avoid repeatedly setting refby and genargs annotations
// Must remove the kustomize bit at the end.
func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
if err := r.SetLabels(
@@ -102,7 +95,7 @@ func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
return fmt.Errorf("copyMerge cannot set labels - %w", err)
}
if err := r.SetAnnotations(
mergeStringMaps(other.GetAnnotations(), r.GetAnnotations())); err != nil {
mergeStringMapsWithBuildAnnotations(other.GetAnnotations(), r.GetAnnotations())); err != nil {
return fmt.Errorf("copyMerge cannot set annotations - %w", err)
}
if err := r.SetName(other.GetName()); err != nil {
@@ -116,8 +109,6 @@ func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
}
func (r *Resource) copyKustomizeSpecificFields(other *Resource) {
r.options = other.options
r.refBy = other.copyRefBy()
r.refVarNames = copyStringSlice(other.refVarNames)
}
@@ -159,10 +150,10 @@ func (r *Resource) ErrIfNotEquals(o *Resource) error {
func (r *Resource) ReferencesEqual(other *Resource) bool {
setSelf := make(map[resid.ResId]bool)
setOther := make(map[resid.ResId]bool)
for _, ref := range other.refBy {
for _, ref := range other.GetRefBy() {
setOther[ref] = true
}
for _, ref := range r.refBy {
for _, ref := range r.GetRefBy() {
if _, ok := setOther[ref]; !ok {
return false
}
@@ -171,15 +162,6 @@ func (r *Resource) ReferencesEqual(other *Resource) bool {
return len(setSelf) == len(setOther)
}
func (r *Resource) copyRefBy() []resid.ResId {
if r.refBy == nil {
return nil
}
s := make([]resid.ResId, len(r.refBy))
copy(s, r.refBy)
return s
}
func copyStringSlice(s []string) []string {
if s == nil {
return nil
@@ -191,12 +173,12 @@ func copyStringSlice(s []string) []string {
// Implements ResCtx AddNamePrefix
func (r *Resource) AddNamePrefix(p string) {
r.appendCsvAnnotation(buildAnnotationPrefixes, p)
r.appendCsvAnnotation(utils.BuildAnnotationPrefixes, p)
}
// Implements ResCtx AddNameSuffix
func (r *Resource) AddNameSuffix(s string) {
r.appendCsvAnnotation(buildAnnotationSuffixes, s)
r.appendCsvAnnotation(utils.BuildAnnotationSuffixes, s)
}
func (r *Resource) appendCsvAnnotation(name, value string) {
@@ -214,30 +196,14 @@ func (r *Resource) appendCsvAnnotation(name, value string) {
}
}
func SameEndingSubarray(shortest, longest []string) bool {
if len(shortest) > len(longest) {
longest, shortest = shortest, longest
}
diff := len(longest) - len(shortest)
if len(shortest) == 0 {
return diff == 0
}
for i := len(shortest) - 1; i >= 0; i-- {
if longest[i+diff] != shortest[i] {
return false
}
}
return true
}
// Implements ResCtx GetNamePrefixes
func (r *Resource) GetNamePrefixes() []string {
return r.getCsvAnnotation(buildAnnotationPrefixes)
return r.getCsvAnnotation(utils.BuildAnnotationPrefixes)
}
// Implements ResCtx GetNameSuffixes
func (r *Resource) GetNameSuffixes() []string {
return r.getCsvAnnotation(buildAnnotationSuffixes)
return r.getCsvAnnotation(utils.BuildAnnotationSuffixes)
}
func (r *Resource) getCsvAnnotation(name string) []string {
@@ -252,7 +218,8 @@ func (r *Resource) getCsvAnnotation(name string) []string {
// as OutermostPrefixSuffix but performs a deeper comparison
// of the suffix and prefix slices.
func (r *Resource) PrefixesSuffixesEquals(o ResCtx) bool {
return SameEndingSubarray(r.GetNamePrefixes(), o.GetNamePrefixes()) && SameEndingSubarray(r.GetNameSuffixes(), o.GetNameSuffixes())
return utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes()) &&
utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes())
}
// RemoveBuildAnnotations removes annotations created by the build process.
@@ -263,7 +230,7 @@ func (r *Resource) RemoveBuildAnnotations() {
if len(annotations) == 0 {
return
}
for _, a := range buildAnnotations {
for _, a := range BuildAnnotations {
delete(annotations, a)
}
if err := r.SetAnnotations(annotations); err != nil {
@@ -272,49 +239,53 @@ func (r *Resource) RemoveBuildAnnotations() {
}
func (r *Resource) setPreviousId(ns string, n string, k string) *Resource {
r.appendCsvAnnotation(buildAnnotationPreviousNames, n)
r.appendCsvAnnotation(buildAnnotationPreviousNamespaces, ns)
r.appendCsvAnnotation(buildAnnotationPreviousKinds, k)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNames, n)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNamespaces, ns)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousKinds, k)
return r
}
// AllowNameChange allows name changes to the resource.
func (r *Resource) AllowNameChange() {
annotations := r.GetAnnotations()
annotations[buildAnnotationAllowNameChange] = allowed
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
r.enable(utils.BuildAnnotationAllowNameChange)
}
// NameChangeAllowed checks if a patch resource is allowed to change another resource's name.
func (r *Resource) NameChangeAllowed() bool {
annotations := r.GetAnnotations()
v, ok := annotations[buildAnnotationAllowNameChange]
return ok && v == allowed
return r.isEnabled(utils.BuildAnnotationAllowNameChange)
}
// AllowKindChange allows kind changes to the resource.
func (r *Resource) AllowKindChange() {
r.enable(utils.BuildAnnotationAllowKindChange)
}
// KindChangeAllowed checks if a patch resource is allowed to change another resource's kind.
func (r *Resource) KindChangeAllowed() bool {
return r.isEnabled(utils.BuildAnnotationAllowKindChange)
}
func (r *Resource) isEnabled(annoKey string) bool {
annotations := r.GetAnnotations()
annotations[buildAnnotationAllowKindChange] = allowed
v, ok := annotations[annoKey]
return ok && v == utils.Enabled
}
func (r *Resource) enable(annoKey string) {
annotations := r.GetAnnotations()
annotations[annoKey] = utils.Enabled
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
}
func (r *Resource) KindChangeAllowed() bool {
annotations := r.GetAnnotations()
v, ok := annotations[buildAnnotationAllowKindChange]
return ok && v == allowed
}
// String returns resource as JSON.
func (r *Resource) String() string {
bs, err := r.MarshalJSON()
if err != nil {
return "<" + err.Error() + ">"
}
return strings.TrimSpace(string(bs)) + r.options.String()
return strings.TrimSpace(string(bs))
}
// AsYAML returns the resource in Yaml form.
@@ -336,20 +307,34 @@ func (r *Resource) MustYaml() string {
return string(yml)
}
// SetOptions updates the generator options for the resource.
func (r *Resource) SetOptions(o *types.GenArgs) {
r.options = o
}
// Behavior returns the behavior for the resource.
func (r *Resource) Behavior() types.GenerationBehavior {
return r.options.Behavior()
annotations := r.GetAnnotations()
if v, ok := annotations[utils.BuildAnnotationsGenBehavior]; ok {
return types.NewGenerationBehavior(v)
}
return types.NewGenerationBehavior("")
}
// SetBehavior sets the behavior for the resource.
func (r *Resource) SetBehavior(behavior types.GenerationBehavior) {
annotations := r.GetAnnotations()
annotations[utils.BuildAnnotationsGenBehavior] = behavior.String()
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
}
// NeedHashSuffix returns true if a resource content
// hash should be appended to the name of the resource.
func (r *Resource) NeedHashSuffix() bool {
return r.options != nil && r.options.ShouldAddHashSuffixToName()
return r.isEnabled(utils.BuildAnnotationsGenAddHashSuffix)
}
// EnableHashSuffix marks the resource as needing a content
// hash to be appended to the name of the resource.
func (r *Resource) EnableHashSuffix() {
r.enable(utils.BuildAnnotationsGenAddHashSuffix)
}
// OrgId returns the original, immutable ResId for the resource.
@@ -369,26 +354,12 @@ func (r *Resource) OrgId() resid.ResId {
// The returned array does not include the resource's current
// ID. If there are no previous IDs, this will return nil.
func (r *Resource) PrevIds() []resid.ResId {
var ids []resid.ResId
// TODO: merge previous names and namespaces into one list of
// pairs on one annotation so there is no chance of error
names := r.getCsvAnnotation(buildAnnotationPreviousNames)
ns := r.getCsvAnnotation(buildAnnotationPreviousNamespaces)
kinds := r.getCsvAnnotation(buildAnnotationPreviousKinds)
if len(names) != len(ns) || len(names) != len(kinds) {
panic(errors.New(
"number of previous names, " +
"number of previous namespaces, " +
"number of previous kinds not equal"))
prevIds, err := utils.PrevIds(&r.RNode)
if err != nil {
// this should never happen
panic(err)
}
for i := range names {
k := kinds[i]
gvk := r.GetGvk()
gvk.Kind = k
ids = append(ids, resid.NewResIdWithNamespace(
gvk, names[i], ns[i]))
}
return ids
return prevIds
}
// StorePreviousId stores the resource's current ID via build annotations.
@@ -407,12 +378,18 @@ func (r *Resource) CurId() resid.ResId {
// GetRefBy returns the ResIds that referred to current resource
func (r *Resource) GetRefBy() []resid.ResId {
return r.refBy
var resIds []resid.ResId
asStrings := r.getCsvAnnotation(utils.BuildAnnotationsRefBy)
for _, s := range asStrings {
resIds = append(resIds, resid.FromString(s))
}
return resIds
}
// AppendRefBy appends a ResId into the refBy list
func (r *Resource) AppendRefBy(id resid.ResId) {
r.refBy = append(r.refBy, id)
// Using any type except fmt.Stringer here results in a compilation error
func (r *Resource) AppendRefBy(id fmt.Stringer) {
r.appendCsvAnnotation(utils.BuildAnnotationsRefBy, id.String())
}
// GetRefVarNames returns vars that refer to current resource
@@ -468,3 +445,17 @@ func mergeStringMaps(maps ...map[string]string) map[string]string {
}
return result
}
func mergeStringMapsWithBuildAnnotations(maps ...map[string]string) map[string]string {
result := mergeStringMaps(maps...)
for i := range BuildAnnotations {
if len(maps) > 0 {
if v, ok := maps[0][BuildAnnotations[i]]; ok {
result[BuildAnnotations[i]] = v
continue
}
}
delete(result, BuildAnnotations[i])
}
return result
}

View File

@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/provider"
. "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
@@ -27,8 +28,6 @@ var testConfigMap = factory.FromMap(
},
})
const genArgOptions = "{nsfx:false,beh:unspecified}"
//nolint:gosec
const configMapAsString = `{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}`
@@ -65,17 +64,15 @@ func TestResourceString(t *testing.T) {
}{
{
in: testConfigMap,
s: configMapAsString + genArgOptions,
s: configMapAsString,
},
{
in: testDeployment,
s: deploymentAsString + genArgOptions,
s: deploymentAsString,
},
}
for _, test := range tests {
if test.in.String() != test.s {
t.Fatalf("Expected %s == %s", test.in.String(), test.s)
}
assert.Equal(t, test.in.String(), test.s)
}
}
@@ -283,6 +280,266 @@ spec:
`, string(bytes))
}
func TestApplySmPatchShouldOutputListItemsInCorrectOrder(t *testing.T) {
cases := []struct {
name string
skip bool
patch string
expectedOutput string
}{
{
name: "Order should not change when patch has foo only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
},
{
name: "Order changes when patch has bar only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
`,
// This test records current behavior, but this behavior might be undesirable.
// If so, feel free to change the test to pass with some improved algorithm.
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
},
{
name: "Order should not change and should include a new item at the beginning when patch has a new list item",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: baz
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: baz
- name: foo
- name: bar
`,
},
{
name: "Order should not change when patch has foo and bar in same order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
},
{
name: "Order should change when patch has foo and bar in different order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
resource, err := factory.FromBytes([]byte(`
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`))
assert.NoError(t, err)
patch, err := factory.FromBytes([]byte(tc.patch))
assert.NoError(t, err)
assert.NoError(t, resource.ApplySmPatch(patch))
bytes, err := resource.AsYAML()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, string(bytes))
})
}
}
func TestApplySmPatchShouldOutputPrimitiveListItemsInCorrectOrder(t *testing.T) {
cases := []struct {
name string
skip bool
patch string
expectedOutput string
}{
{
name: "Order should not change when patch has foo only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["foo"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should not change when patch has bar only",
skip: true, // TODO: This test should pass but fails currently. Fix the problem and unskip this test
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["bar"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should not change and should include a new item at the beginning when patch has a new list item",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["baz"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- baz
- foo
- bar
name: test
`,
},
{
name: "Order should not change when patch has foo and bar in same order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["foo", "bar"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should change when patch has foo and bar in different order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["bar", "foo"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- bar
- foo
name: test
`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
resource, err := factory.FromBytes([]byte(`
kind: Pod
metadata:
name: test
finalizers: ["foo", "bar"]
`))
assert.NoError(t, err)
patch, err := factory.FromBytes([]byte(tc.patch))
assert.NoError(t, err)
assert.NoError(t, resource.ApplySmPatch(patch))
bytes, err := resource.AsYAML()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, string(bytes))
})
}
}
func TestMergeDataMapFrom(t *testing.T) {
resource, err := factory.FromBytes([]byte(`
apiVersion: v1
@@ -716,9 +973,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
name: newName
`,
},
@@ -728,9 +985,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
name: oldName2
`,
newName: "newName",
@@ -739,9 +996,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,default
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,default
name: newName
`,
},
@@ -751,9 +1008,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
name: oldName2
namespace: oldNamespace
`,
@@ -763,9 +1020,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,oldNamespace
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,oldNamespace
name: newName
namespace: newNamespace
`,
@@ -813,9 +1070,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
name: newName
`,
expected: []resid.ResId{
@@ -832,9 +1089,9 @@ metadata:
kind: Secret
metadata:
annotations:
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,oldNamespace
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,oldNamespace
name: newName
namespace: newNamespace
`,
@@ -1077,7 +1334,7 @@ func TestSameEndingSubarray(t *testing.T) {
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
assert.Equal(t, tc.expected, SameEndingSubarray(tc.a, tc.b))
assert.Equal(t, tc.expected, utils.SameEndingSubSlice(tc.a, tc.b))
})
}
}
@@ -1132,3 +1389,41 @@ spec:
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestRefBy(t *testing.T) {
r, err := factory.FromBytes([]byte(`
apiVersion: v1
kind: Deployment
metadata:
name: clown
spec:
numReplicas: 1
`))
assert.NoError(t, err)
r.AppendRefBy(resid.FromString("gr1_ver1_knd1|ns1|name1"))
assert.Equal(t, r.RNode.MustString(), `apiVersion: v1
kind: Deployment
metadata:
name: clown
annotations:
internal.config.kubernetes.io/refBy: gr1_ver1_knd1|ns1|name1
spec:
numReplicas: 1
`)
assert.Equal(t, r.GetRefBy(), []resid.ResId{resid.FromString("gr1_ver1_knd1|ns1|name1")})
r.AppendRefBy(resid.FromString("gr2_ver2_knd2|ns2|name2"))
assert.Equal(t, r.RNode.MustString(), `apiVersion: v1
kind: Deployment
metadata:
name: clown
annotations:
internal.config.kubernetes.io/refBy: gr1_ver1_knd1|ns1|name1,gr2_ver2_knd2|ns2|name2
spec:
numReplicas: 1
`)
assert.Equal(t, r.GetRefBy(), []resid.ResId{
resid.FromString("gr1_ver1_knd1|ns1|name1"),
resid.FromString("gr2_ver2_knd2|ns2|name2"),
})
}

View File

@@ -7,12 +7,12 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Harness manages a test environment.

View File

@@ -11,7 +11,6 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/konfig"
@@ -20,6 +19,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// HarnessEnhanced manages a full plugin environment for tests.
@@ -148,6 +148,13 @@ func (th *HarnessEnhanced) ResetLoaderRoot(root string) {
}
func (th *HarnessEnhanced) LoadAndRunGenerator(
config string) resmap.ResMap {
rm := th.LoadAndRunGeneratorWithBuildAnnotations(config)
rm.RemoveBuildAnnotations()
return rm
}
func (th *HarnessEnhanced) LoadAndRunGeneratorWithBuildAnnotations(
config string) resmap.ResMap {
res, err := th.rf.RF().FromBytes([]byte(config))
if err != nil {
@@ -162,7 +169,6 @@ func (th *HarnessEnhanced) LoadAndRunGenerator(
if err != nil {
th.t.Fatalf("generate err: %v", err)
}
rm.RemoveBuildAnnotations()
return rm
}

View File

@@ -7,10 +7,10 @@ import (
"os"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/plugins/compiler"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// pluginTestEnv manages compiling plugins for tests.

View File

@@ -1,46 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
import (
"strconv"
"strings"
)
// GenArgs is a facade over GeneratorArgs, exposing a few readonly properties.
type GenArgs struct {
args *GeneratorArgs
}
// NewGenArgs returns a new instance of GenArgs.
func NewGenArgs(args *GeneratorArgs) *GenArgs {
return &GenArgs{args: args}
}
func (g *GenArgs) String() string {
if g == nil {
return "{nilGenArgs}"
}
return "{" +
strings.Join([]string{
"nsfx:" + strconv.FormatBool(g.ShouldAddHashSuffixToName()),
"beh:" + g.Behavior().String()},
",") +
"}"
}
// ShouldAddHashSuffixToName returns true if a resource
// content hash should be appended to the name of the resource.
func (g *GenArgs) ShouldAddHashSuffixToName() bool {
return g.args != nil &&
(g.args.Options == nil || !g.args.Options.DisableNameSuffixHash)
}
// Behavior returns Behavior field of GeneratorArgs
func (g *GenArgs) Behavior() GenerationBehavior {
if g.args == nil {
return BehaviorUnspecified
}
return NewGenerationBehavior(g.args.Behavior)
}

View File

@@ -1,39 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types_test
import (
"testing"
. "sigs.k8s.io/kustomize/api/types"
)
func TestGenArgs_String(t *testing.T) {
tests := []struct {
ga *GenArgs
expected string
}{
{
ga: nil,
expected: "{nilGenArgs}",
},
{
ga: &GenArgs{},
expected: "{nsfx:false,beh:unspecified}",
},
{
ga: NewGenArgs(
&GeneratorArgs{
Behavior: "merge",
Options: &GeneratorOptions{DisableNameSuffixHash: false},
}),
expected: "{nsfx:true,beh:merge}",
},
}
for _, test := range tests {
if test.ga.String() != test.expected {
t.Fatalf("Expected '%s', got '%s'", test.expected, test.ga.String())
}
}
}

View File

@@ -68,6 +68,10 @@ type HelmChart struct {
// Legal values: 'merge', 'override', 'replace'.
// Defaults to 'override'.
ValuesMerge string `json:"valuesMerge,omitempty" yaml:"valuesMerge,omitempty"`
// IncludeCRDs specifies if Helm should also generate CustomResourceDefinitions.
// Defaults to 'false'.
IncludeCRDs bool `json:"includeCRDs,omitempty" yaml:"includeCRDs,omitempty"`
}
// HelmChartArgs contains arguments to helm.

View File

@@ -0,0 +1,36 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
type Cloud string
const GKE Cloud = "gke"
// IAMPolicyGeneratorArgs contains arguments to generate a GKE service account resource.
type IAMPolicyGeneratorArgs struct {
// which cloud provider to generate for (e.g. "gke")
Cloud `json:"cloud" yaml:"cloud"`
// information about the kubernetes cluster for this object
KubernetesService `json:"kubernetesService" yaml:"kubernetesService"`
// information about the service account and project
ServiceAccount `json:"serviceAccount" yaml:"serviceAccount"`
}
type KubernetesService struct {
// the name used for the Kubernetes service account
Name string `json:"name" yaml:"name"`
// the name of the Kubernetes namespace for this object
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
}
type ServiceAccount struct {
// the name of the new cloud provider service account
Name string `json:"name" yaml:"name"`
// The ID of the project
ProjectId string `json:"projectId" yaml:"projectId"`
}

View File

@@ -161,6 +161,9 @@ type Kustomization struct {
// Inventory appends an object that contains the record
// of all other objects, which can be used in apply, prune and delete
Inventory *Inventory `json:"inventory,omitempty" yaml:"inventory,omitempty"`
// BuildMetadata is a list of strings used to toggle different build options
BuildMetadata []string `json:"buildMetadata,omitempty" yaml:"buildMetadata,omitempty"`
}
// FixKustomizationPostUnmarshalling fixes things

View File

@@ -42,7 +42,7 @@ const (
BploLoadFromFileSys
)
// FnPluginLoadingOptions set way functions-based pluing are restricted
// FnPluginLoadingOptions set way functions-based plugins are restricted
type FnPluginLoadingOptions struct {
// Allow to run executables
EnableExec bool
@@ -55,4 +55,8 @@ type FnPluginLoadingOptions struct {
Mounts []string
// list of env variables to pass to fn
Env []string
// Run as uid and gid of the command executor
AsCurrentUser bool
// Run in this working directory
WorkingDir string
}

View File

@@ -28,10 +28,10 @@ type SourceSelector struct {
resid.ResId `json:",inline,omitempty" yaml:",inline,omitempty"`
// Structured field path expected in the allowed object.
FieldPath string `json:"fieldPath" yaml:"fieldPath"`
FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"`
// Used to refine the interpretation of the field.
Options *FieldOptions `json:"options" yaml:"options"`
Options *FieldOptions `json:"options,omitempty" yaml:"options,omitempty"`
}
func (s *SourceSelector) String() string {
@@ -54,34 +54,34 @@ type TargetSelector struct {
Select *Selector `json:"select" yaml:"select"`
// From the allowed set, remove objects that match this.
Reject []*Selector `json:"reject" yaml:"reject"`
Reject []*Selector `json:"reject,omitempty" yaml:"reject,omitempty"`
// Structured field paths expected in each allowed object.
FieldPaths []string `json:"fieldPaths" yaml:"fieldPaths"`
FieldPaths []string `json:"fieldPaths,omitempty" yaml:"fieldPaths,omitempty"`
// Used to refine the interpretation of the field.
Options *FieldOptions `json:"options" yaml:"options"`
Options *FieldOptions `json:"options,omitempty" yaml:"options,omitempty"`
}
// FieldOptions refine the interpretation of FieldPaths.
type FieldOptions struct {
// Used to split/join the field.
Delimiter string `json:"delimiter" yaml:"delimiter"`
Delimiter string `json:"delimiter,omitempty" yaml:"delimiter,omitempty"`
// Which position in the split to consider.
Index int `json:"index" yaml:"index"`
Index int `json:"index,omitempty" yaml:"index,omitempty"`
// TODO (#3492): Implement use of this option
// None, Base64, URL, Hex, etc
Encoding string `json:"encoding" yaml:"encoding"`
Encoding string `json:"encoding,omitempty" yaml:"encoding,omitempty"`
// If field missing, add it.
Create bool `json:"create" yaml:"create"`
Create bool `json:"create,omitempty" yaml:"create,omitempty"`
}
func (fo *FieldOptions) String() string {
if fo == nil || fo.Delimiter == "" {
if fo == nil || (fo.Delimiter == "" && !fo.Create) {
return ""
}
return fmt.Sprintf("%s(%d)", fo.Delimiter, fo.Index)
return fmt.Sprintf("%s(%d), create=%t", fo.Delimiter, fo.Index, fo.Create)
}

View File

@@ -28,6 +28,10 @@ type Selector struct {
LabelSelector string `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"`
}
func (s *Selector) Copy() Selector {
return *s
}
func (s *Selector) String() string {
return fmt.Sprintf(
"%s:a=%s:l=%s", s.ResId, s.AnnotationSelector, s.LabelSelector)

Some files were not shown because too many files have changed in this diff Show More