Compare commits

...

334 Commits

Author SHA1 Message Date
Kubernetes Prow Robot
5279ad904b Merge pull request #3282 from pwittrock/main
Fn framework utilities for parsing templates from directories
2020-11-30 08:42:50 -08:00
Phillip Wittrock
736f110f04 Fn framework template and process options
- Refactor framework code to be simpler
- Add TemplatesFn feature
- Add PreProcessFilters feature
- Add PostProcessFilters features
- Add TemplatesFromDir
- Add PatchTemplatesFromDir
- Add PatchContainerTemplatesFromDir
2020-11-30 08:23:34 -08:00
Jeff Regan
c9ab1270fa Merge pull request #3290 from monopole/idSet
Add resource id set.
2020-11-30 05:42:26 -08:00
jregan
bb5fc9086b Add resource id set. 2020-11-30 05:37:53 -08:00
Kubernetes Prow Robot
e8c85456cc Merge pull request #3279 from monopole/addGeneratedCode
Add label and annotation selector code.
2020-11-28 22:36:48 -08:00
jregan
aa9a397808 Kyaml: disable generation on each build. 2020-11-28 05:55:16 -08:00
jregan
60ea8de5f1 Complete WNode implementation. 2020-11-26 14:48:00 -08:00
jregan
56c8df7b85 Add RNode implementation of label and annotation selectors. 2020-11-26 14:47:23 -08:00
Jeff Regan
a51e4234c4 Merge pull request #3283 from Shell32-Natsu/docker
Add git and openssh in docker image
2020-11-26 08:18:44 -08:00
Jeff Regan
50cd01e5f7 Update Makefile 2020-11-26 07:00:13 -08:00
Jeff Regan
42b082a6b1 Merge pull request #3285 from monopole/improveSelectTest
Add labels to selector test.
2020-11-26 06:57:14 -08:00
jregan
c3cdd15769 Clean up selector test. 2020-11-26 06:36:24 -08:00
Donny Xia
c3a8b6f359 Add git and openssh in docker image 2020-11-25 15:02:47 -08:00
Jeff Regan
4af4483e12 Merge pull request #3281 from Shell32-Natsu/update-go-version
update Go version to 1.15
2020-11-25 14:05:24 -08:00
Donny Xia
8f7bcb9b16 update Go version to 1.15 2020-11-25 12:41:20 -08:00
Jeff Regan
f54d904766 Merge pull request #3277 from monopole/moreRNodeSetters
More RNode setters and WNode delegation
2020-11-25 10:20:06 -08:00
Jeff Regan
ba91b6f79f Merge pull request #3278 from SyamSundarKirubakaran/doc-site-changes
Remove `zh` site contents and redirect to new site
2020-11-25 09:09:07 -08:00
Syam Sundar K
851acafe32 generate site 2020-11-25 21:42:09 +05:30
Syam Sundar K
14eac6020f remove duplicate contents and redirect 2020-11-25 21:41:27 +05:30
Jeff Regan
e45d667b4d Delete .gitattributes
Didn't work as desired.
2020-11-25 07:59:58 -08:00
Jeff Regan
cbdf4a0e43 Update .gitattributes 2020-11-25 07:53:35 -08:00
jregan
aed7e5aaf9 Delegate more from WNode to RNode.
The implementations in WNode are supposed to be thin,
as it will be removed once #2506 closes.

The change also makes some addjustments for the
upcoming flip of the enable_kyaml flag, pointing to
issue #3271.
2020-11-25 07:11:06 -08:00
jregan
ec64ef705b Add metadata getters and setters to RNode.
These setters completely remove the field if the argument
is empty, rather than setting the field to an empty value,
mimicing apimachinery behavior.
2020-11-25 07:03:12 -08:00
Jeff Regan
1e0eb58bc9 Merge pull request #3273 from Shell32-Natsu/reenable-multi-module-check
Re-enable multi-module check
2020-11-24 19:18:16 -08:00
Jeff Regan
fd2fe35863 Merge pull request #3275 from monopole/tryGitAttributes
Start a gitattributes file.
2020-11-24 19:12:23 -08:00
jregan
ebdbd81ed8 Start a gitattributes file. 2020-11-24 18:50:46 -08:00
Donny Xia
c9d2ae6b49 Re-enable multi-module check 2020-11-24 16:29:01 -08:00
Kubernetes Prow Robot
e8c212a10f Merge pull request #3272 from monopole/moreTests
Add more tests around yaml parsing.
2020-11-24 14:34:39 -08:00
jregan
1eb378254a Add more tests around yaml parsing. 2020-11-24 14:15:45 -08:00
Kubernetes Prow Robot
0d030e3095 Merge pull request #3270 from pwittrock/main
Improved fn framework support for patching
2020-11-24 12:22:39 -08:00
Phillip Wittrock
f2706dce68 Improved fn framework support for patching
- Generate patches with a func
- Generate patches for containers
2020-11-24 12:02:55 -08:00
Jeff Regan
f8194bd3c2 Merge pull request #3267 from monopole/generatedCode
Add generated code.
2020-11-23 16:51:41 -08:00
jregan
eb5227680e Add generated code. 2020-11-23 16:47:00 -08:00
Jeff Regan
27e89f271f Merge pull request #3266 from monopole/modsToMakefile
Consistently prefix make targets with clean, generate, build.
2020-11-23 16:37:34 -08:00
jregan
626f2f9d1d Another cleaning target in Makefile. 2020-11-23 16:14:47 -08:00
Jeff Regan
ffda124ca5 Update Makefile 2020-11-23 06:48:53 -08:00
Jeff Regan
fd677f635e Update README.md 2020-11-22 21:01:28 -08:00
Jeff Regan
14b1388c6a Merge pull request #3263 from monopole/useLessReflectionInTests
In some tests, replace reflection with yaml compare.
2020-11-22 20:34:38 -08:00
jregan
5248fd0cd9 In some tests, replace reflection with yaml compare. 2020-11-22 18:48:32 -08:00
Jeff Regan
b6ae9f80d3 Merge pull request #3257 from monopole/binaryData
Secrets and ConfigMaps with binary data in kyaml
2020-11-21 15:11:29 -08:00
Jeff Regan
2ad502d5a8 Merge pull request #3261 from monopole/depProviderInjection
Use DepProvider in tests to access kyaml impls.
2020-11-21 15:07:45 -08:00
jregan
a5f3d5c823 Use DepProvider in tests to access kyaml impls. 2020-11-21 14:49:44 -08:00
Jeff Regan
c65875cacc Merge pull request #3259 from pwittrock/main
fn/framework support for reading from stdin in standalone
2020-11-21 14:44:54 -08:00
Phillip Wittrock
82b2d83ede fn/framework support for reading from stdin in standalone
- speficy '-' to read from stdin when running standalone
2020-11-21 09:17:26 -08:00
Jeff Regan
7e01aec5a4 Update Makefile 2020-11-21 07:14:04 -08:00
Jeff Regan
9e8a84c5ff Merge pull request #3251 from Shell32-Natsu/krm-function-converter
[KRM function converter] Get plugin config from data field
2020-11-21 06:25:42 -08:00
Jeff Regan
849d5c4a8d Merge branch 'master' into krm-function-converter 2020-11-21 06:10:25 -08:00
Jeff Regan
00352cbc58 Merge pull request #3256 from Shell32-Natsu/pluginator-api-version
update module api version in wrapper
2020-11-21 06:09:04 -08:00
jregan
b88e770b1d binary data nope 2020-11-20 17:55:20 -08:00
Jeff Regan
eda7a9f8d6 Merge pull request #3258 from monopole/goSumAutomated
Automated go.sum change.
2020-11-20 17:55:01 -08:00
jregan
114b3f4b00 Automated go.sum change. 2020-11-20 17:18:14 -08:00
Donny Xia
6cb339142d update module api version in wrapper 2020-11-20 16:28:38 -08:00
Kubernetes Prow Robot
052a6b4e96 Merge pull request #3255 from Shell32-Natsu/rnode-format
fix rnode string format converted from resmap
2020-11-20 15:07:33 -08:00
Donny Xia
4add7eccd0 fix rnode string format converted from resmap 2020-11-20 14:34:11 -08:00
Kubernetes Prow Robot
a0a89e1adc Merge pull request #3250 from pwittrock/main
Function framework support for patching containers
2020-11-20 12:42:51 -08:00
Donny Xia
10fd4b4bbe Merge pull request #3252 from runewake2/notes
Update release notes generation
2020-11-20 10:24:03 -08:00
Donny Xia
e15ede037d Merge pull request #3253 from yujunz/remote-build
Fix test against examples
2020-11-20 09:47:47 -08:00
Yujun Zhang
32a2f5ffa9 Fix test against examples
Tests in examples.remoteBuild.md were skipped unexpectedly
2020-11-20 20:10:07 +08:00
Sam Wronski
4f74203f6c Fix variable name: "currentTag" -> "fullTag" 2020-11-19 15:37:39 -08:00
Sam Wronski
5b0cbcb5fb Update release notes generation
- Notes use tags instead commit sha
2020-11-19 14:28:05 -08:00
Donny Xia
2f4c35347e Get plugin config from data field 2020-11-19 13:11:47 -08:00
Phillip Wittrock
be5db09db1 Function framework support for patching containers 2020-11-19 10:01:12 -08:00
Jeff Regan
a6833bc4c0 Merge pull request #3211 from Shell32-Natsu/krm-plugin-tool
modify pluginator to support convert builtin plugin to krm function
2020-11-18 15:59:29 -08:00
Donny Xia
2ae323bb26 move files into internal 2020-11-18 12:21:59 -08:00
Donny Xia
7e74271071 fix script name 2020-11-18 12:21:59 -08:00
Donny Xia
260e093547 modify pluginator to add support for krm function 2020-11-18 12:21:59 -08:00
Jeff Regan
47b12fa3dc Merge pull request #3240 from Shell32-Natsu/list-builtin
Add command to list builtin plugins
2020-11-18 11:13:39 -08:00
Jeff Regan
38801cd966 Merge pull request #3238 from Shell32-Natsu/managed-by-label
fix invalid managed-by label value
2020-11-18 11:09:28 -08:00
Jeff Regan
c49e177b9c Merge pull request #3247 from monopole/secretsAndMaps
Secrets and ConfigMaps with string data in kyaml
2020-11-18 10:00:38 -08:00
jregan
486be07e22 Add WNodeFactory.MakeConfigMap,MakeSecret 2020-11-18 09:45:43 -08:00
Donny Xia
a12db91a10 mark the list-builtin command alpha 2020-11-18 09:38:03 -08:00
jregan
f7613631d1 Add some kyaml filters for k8s metadata. 2020-11-18 08:57:13 -08:00
Kubernetes Prow Robot
8a77494c7d Merge pull request #3239 from pwittrock/framework
Function framework features
2020-11-17 17:58:04 -08:00
Kubernetes Prow Robot
af25469c8b Merge pull request #3219 from phanimarupaka/RefactorOpenAPI
Refactor open api
2020-11-17 11:26:04 -08:00
Phillip Wittrock
8c4841c28f Support for framework.Selector substitutions 2020-11-17 08:52:34 -08:00
Phani Teja Marupaka
b6a4dd446a Refactor openAPI
Refactor global openapi
2020-11-16 23:03:56 -08:00
Jeff Regan
606654756d Update kfns.go 2020-11-16 21:38:25 -08:00
Jeff Regan
97c18518ea Update rnode.go 2020-11-16 21:37:28 -08:00
Jeff Regan
2dca4ab987 Merge pull request #3242 from monopole/useConst
Gather and use some of the kyaml constants.
2020-11-16 21:31:13 -08:00
jregan
712276176c Gather and use some of the kyaml constants. 2020-11-16 21:26:18 -08:00
Donny Xia
c610e3a364 Add command to list builtin plugins 2020-11-16 17:18:56 -08:00
Phillip Wittrock
02e7589323 Function framework testutil support for functions which refer to local files
Some functions may read local files using relative paths.  Update the test
framework to `cd` into the directory containing the config.yaml before
running the function.
2020-11-16 16:35:07 -08:00
Kubernetes Prow Robot
2ae180ca23 Merge pull request #3235 from pwittrock/framework
fn framework TemplatePatch support
2020-11-16 14:14:05 -08:00
Donny Xia
98900c43f7 fix invalid managed-by label value 2020-11-16 14:05:21 -08:00
Phillip Wittrock
02b14d919b fn framework -- add support for patch templates 2020-11-16 14:01:08 -08:00
Phillip Wittrock
bd0a699ff6 Refactor fn/framework tests to use a common library. 2020-11-16 14:00:55 -08:00
Jeff Regan
02b4b56c60 Merge pull request #3233 from monopole/sliceFromBytes
Implement WNodeFactory.SliceFromBytes
2020-11-16 11:57:09 -08:00
jregan
0cac05448b Implement WNodeFactory.SliceFromBytes and FromMap 2020-11-16 11:33:04 -08:00
jregan
e1c3caeba6 Introduce some RNode validation methods. 2020-11-16 11:32:23 -08:00
Jeff Regan
a25429ae3b Merge pull request #3236 from runewake2/mergeless-releases
Remove merge commits from release notes
2020-11-16 11:22:01 -08:00
Kubernetes Prow Robot
e557677fed Merge pull request #3229 from Shell32-Natsu/krm-plugin-tool-helpers
Add methods to convert ResMap to and from RNodes
2020-11-16 11:12:06 -08:00
Donny Xia
59e0b593cf Merge pull request #3232 from justinsb/hint_about_bytereader
Expand rnode function comments to point to multi-object options.
2020-11-16 10:12:54 -08:00
Sam Wronski
3fa906505c Remove merge commits from release notes 2020-11-16 09:47:57 -08:00
Justin SB
a823f3043f Expand rnode function comments to point to multi-object options.
The rnode Parse and ReadFile functions only return a single object;
suggest kio.ByteReader for the case of parsing multiple objects.
2020-11-15 13:07:28 -05:00
Jeff Regan
b2ba82a0bd Merge pull request #3231 from monopole/fromMap
Add RNode FromMap factory method.
2020-11-14 13:33:12 -08:00
jregan
a4f22cb84f Add RNode fromMap method. 2020-11-14 13:10:53 -08:00
Jeff Regan
22f41c789a Merge pull request #3230 from monopole/fmtFix
Fix go fmt.
2020-11-14 11:03:59 -08:00
jregan
966d0a054c Fix go fmt. 2020-11-14 11:02:44 -08:00
Kubernetes Prow Robot
97f3ac2da1 Merge pull request #3185 from aodinokov/streamline-fn-plugin-kyaml-part
Allowing RunFns not to stop on empty result
2020-11-13 13:47:04 -08:00
Donny Xia
536b69e5dc add methods to convert resmap to&from rnodes 2020-11-13 13:41:34 -08:00
Kubernetes Prow Robot
c7aaa18d0c Merge pull request #3227 from radTuti/master
update kustomize download script
2020-11-13 11:39:05 -08:00
tuti
a45523bb95 dry release_url 2020-11-13 11:25:35 -08:00
Kubernetes Prow Robot
376f59f0f6 Merge pull request #3222 from natasha41575/EditSetLabel
added kustomize edit set label
2020-11-13 11:15:04 -08:00
tuti
34863346b0 include arch type in grep string 2020-11-13 11:09:56 -08:00
Kubernetes Prow Robot
9569ca93d9 Merge pull request #3220 from natasha41575/OpenApiVersionField
Add multiple versions of OpenAPI schema to kyaml
2020-11-13 10:39:05 -08:00
Kubernetes Prow Robot
09377ac19c Merge pull request #3223 from sylr/azure-file
Add namereference for PersistentVolume
2020-11-13 10:25:04 -08:00
Jeff Regan
a25300dfd6 Merge pull request #3225 from Shell32-Natsu/inline-transformer
support inline transformer and generator
2020-11-13 10:05:43 -08:00
Kubernetes Prow Robot
50e9e90b17 Merge pull request #3226 from phanimarupaka/DeprecateV1Setters
Delete v1 setters code
2020-11-13 09:21:06 -08:00
tuti
e3ad472933 allow downloading older releases 2020-11-12 18:19:02 -08:00
tuti
154f894774 fix latest release download failure 2020-11-12 18:17:47 -08:00
Natasha Sarkar
4d7600d4ef updated comments and readme 2020-11-12 18:02:11 -08:00
tuti
0a0a0ccddc Merge branch 'master' from kubernetes-sigs/kustomize 2020-11-12 17:59:53 -08:00
Phani Teja Marupaka
2278e01b7f Delete v1 setters code 2020-11-12 15:29:07 -08:00
Donny Xia
abc88c56c4 support inline transformer and generator 2020-11-12 15:19:14 -08:00
Kubernetes Prow Robot
eddd872eca Merge pull request #3221 from pwittrock/framework
Function framework standalone feature
2020-11-12 13:52:25 -08:00
Sylvain Rabot
febede115e Add namereference for PersistentVolume
Signed-off-by: Sylvain Rabot <sylvain@abstraction.fr>
2020-11-12 22:47:33 +01:00
Natasha Sarkar
a2087f07d4 added kustomize edit set label 2020-11-12 13:26:52 -08:00
Phillip Wittrock
8b9d8a266d Support standalone mode for framework functions 2020-11-12 11:54:58 -08:00
Phillip Wittrock
5557e1ff3c Retain element ordering when merge resources 2020-11-12 08:54:16 -08:00
Phillip Wittrock
1c009ca217 More control over bytereadwriter options
- Override wrapping
- Override function config
2020-11-12 08:54:16 -08:00
Natasha Sarkar
bdb59d2cd2 updated releasing readme 2020-11-11 18:09:41 -08:00
Natasha Sarkar
b61a115e76 added support for multiple kubernetes openapi schemas 2020-11-11 18:09:41 -08:00
Jeff Regan
66221d17d4 Merge pull request #3217 from Shell32-Natsu/image
remove a tag from image
2020-11-11 16:22:51 -08:00
Kubernetes Prow Robot
c83f256dbe Merge pull request #3218 from monopole/unpinEverything
Unpin everything post v3.8.7 release
2020-11-11 15:58:52 -08:00
jregan
fa3caaacee Unpin everything post v3.8.7 release 2020-11-11 15:45:09 -08:00
Kubernetes Prow Robot
0a0a2ed586 Merge pull request #3209 from pwittrock/main
Remove duplicate docs content
2020-11-11 15:44:52 -08:00
Donny Xia
aff1db13e0 remove a tag from image 2020-11-11 15:41:32 -08:00
Kubernetes Prow Robot
ad092cc7a9 Merge pull request #3216 from monopole/pin_api_v0.6.5
Pin to api_v0.6.5
2020-11-11 15:08:50 -08:00
jregan
0a9fc6c8cb Pin to api_v0.6.5 2020-11-11 14:56:25 -08:00
Kubernetes Prow Robot
881d33ac5c Merge pull request #3214 from monopole/pin_cmd_config_v0.8.5
Pin to cmd/config/v0.8.5
2020-11-11 14:48:50 -08:00
jregan
842e4f5dc5 Pin to cmd/config/v0.8.5 2020-11-11 14:34:30 -08:00
Kubernetes Prow Robot
ef612286e4 Merge pull request #3213 from monopole/pinToCli-utils_v0.21.1
Pin to cli-utils_v0.21.1 kyaml_v0.9.4
2020-11-11 13:40:50 -08:00
jregan
636c9fcddf Pin to cli-utils_v0.21.1 kyaml_v0.9.4 2020-11-11 13:26:05 -08:00
Kubernetes Prow Robot
333945d361 Merge pull request #3207 from runewake2/local-presubmit
Skip multi-mod check if PULL_NUMBER unset
2020-11-11 08:34:29 -08:00
Phillip Wittrock
afff3ce5ab update docs site 2020-11-11 08:30:00 -08:00
Phillip Wittrock
71b763888c Remove duplicate kustomize docs content 2020-11-11 08:29:43 -08:00
Jeff Regan
c5cd539b01 Merge pull request #3118 from brianpursley/kustomize-2893
Implement WNode methods
2020-11-11 08:15:29 -08:00
Sam Wronski
4b89c2afa2 Skip multi-mod check if PULL_NUMBER unset 2020-11-10 16:22:48 -08:00
Kubernetes Prow Robot
630fc9b973 Merge pull request #3206 from monopole/disableHelmTests
Disable helm inflator tests.
2020-11-10 16:12:42 -08:00
jregan
a468743b81 Disable helm inflator tests. 2020-11-10 15:22:25 -08:00
Kubernetes Prow Robot
e9a74b87e3 Merge pull request #3203 from Shell32-Natsu/fix-helm
fix helm chart inflation generator
2020-11-10 10:36:41 -08:00
Donny Xia
64f8d2ae38 add one more test 2020-11-10 10:25:05 -08:00
Donny Xia
5ab320c216 fix helm chart inflation generator 2020-11-10 10:03:26 -08:00
Kubernetes Prow Robot
6131f86d23 Merge pull request #3197 from Shell32-Natsu/doc
add link for component reference
2020-11-10 09:14:40 -08:00
Jeff Regan
e7609559ce Merge pull request #3201 from monopole/tmpRemoveCheck
Temporarily remove cross-module PR check.
2020-11-10 08:23:12 -08:00
Donny Xia
c2bdac7a6b Merge pull request #3200 from natasha41575/CleanTestComments
cleaned comments
2020-11-09 21:30:35 -08:00
Jeffrey Regan
4cc2c4f623 Temporarily remove cross-module PR check. 2020-11-09 20:47:06 -08:00
Natasha Sarkar
155c42679c cleaned comments 2020-11-09 20:17:51 -08:00
Donny Xia
88239445ce add link for component reference 2020-11-09 12:05:06 -08:00
Kubernetes Prow Robot
d66fc462ec Merge pull request #3159 from natasha41575/MergeKeyList
use merge key list instead of a single merge key
2020-11-09 11:51:58 -08:00
Natasha Sarkar
6788af083b updated tests for multiple merge keys 2020-11-09 11:35:37 -08:00
Natasha Sarkar
df0576a270 use merge key tuple instead of single merge key 2020-11-09 11:34:31 -08:00
Jeff Regan
f4d8ebb1da Merge pull request #3182 from pwittrock/master
Redirect kustomize site to the unified site
2020-11-07 08:59:07 -08:00
Kubernetes Prow Robot
0acac39640 Merge pull request #3192 from Shell32-Natsu/multierror
Improve the readability for multiple errors in kusttarget
2020-11-06 17:21:38 -08:00
Donny Xia
65db82df0c Merge pull request #3177 from Shell32-Natsu/json-patch
Improve json patch plugin
2020-11-06 16:17:24 -08:00
Donny Xia
68951bb37e format 2020-11-06 15:38:33 -08:00
Donny Xia
b18910aa6d format 2020-11-06 15:38:18 -08:00
Donny Xia
f780f7a3c2 update go.sum 2020-11-06 15:18:41 -08:00
Donny Xia
7966386615 improve format 2020-11-06 15:17:56 -08:00
Donny Xia
2130ba72cc improve format 2020-11-06 15:17:43 -08:00
Donny Xia
94d26ba53a improve the readability for multiple errors 2020-11-06 15:16:48 -08:00
Jeff Regan
c53f31ca4f Merge pull request #3169 from Shell32-Natsu/patch-target
support regex in GVK selection
2020-11-06 15:15:40 -08:00
Jeff Regan
b58075cbc3 Merge pull request #3176 from natasha41575/ElementSetterList
add ElementSetterList and ElementMatcherList to fns.go
2020-11-06 13:40:48 -08:00
Jeff Regan
b3e82a2fe7 Merge pull request #3187 from runewake2/multi-module-golang
Run multi-module check during presubmit
2020-11-06 13:33:29 -08:00
Donny Xia
78c26f55b5 support regex in GVK selection 2020-11-06 13:23:55 -08:00
Jeff Regan
ec2a6e4e4b Update Makefile 2020-11-06 13:15:43 -08:00
Natasha Sarkar
886f73aa0f added test case for no values 2020-11-06 13:14:25 -08:00
Natasha Sarkar
73d91dda6e changed handling of empty values 2020-11-06 11:42:17 -08:00
Natasha Sarkar
9f06376ab2 updated associative sequence 2020-11-05 17:22:54 -08:00
Natasha Sarkar
e785bab474 updated matchelementlist 2020-11-05 17:03:52 -08:00
Natasha Sarkar
8f80a898b6 removed elementsetterlist and updated elementsetter 2020-11-05 16:50:18 -08:00
Sam Wronski
fe84d119d6 Use gomodule when running prchecker 2020-11-05 16:03:36 -08:00
Sam Wronski
03b847a749 Use PULL_NUMBER env from prow 2020-11-05 15:44:40 -08:00
Sam Wronski
9d2f257acf Install dependencies from go module 2020-11-05 15:28:37 -08:00
Jeff Regan
129b25ceff Merge pull request #3167 from Shell32-Natsu/patch-test
re-enable test for edit patch add
2020-11-05 15:07:14 -08:00
Jeff Regan
57f4ea5354 Merge pull request #3166 from phanimarupaka/DeferOpenAPICleanup
Defer openAPI cleanup
2020-11-05 14:48:00 -08:00
Phani Teja Marupaka
ec2cc2d421 Defer openAPI cleanup 2020-11-05 13:49:43 -08:00
Sam Wronski
712eb6d276 Refactor changeset spanning function naming 2020-11-05 12:23:45 -08:00
Natasha Sarkar
a04e3a575c added test case for different length keys/values 2020-11-05 12:19:54 -08:00
Natasha Sarkar
03e2fed925 checked array length 2020-11-05 12:16:17 -08:00
Jeff Regan
c37b3b2525 Merge pull request #3170 from natasha41575/MultipleMergeKeyTests
added tests for merge key tuple behavior
2020-11-05 12:12:59 -08:00
Donny Xia
ceeba8764f update Makefile 2020-11-05 12:06:06 -08:00
Donny Xia
04d133a66f re-enable test for edit patch add 2020-11-05 12:06:06 -08:00
Natasha Sarkar
99aaa80e1d updated stale comments 2020-11-05 11:40:36 -08:00
Natasha Sarkar
1f806b0aa2 add elementsetterlist and elementmatcherlist to fns.go 2020-11-05 11:37:45 -08:00
Sam Wronski
1f697e3792 Run multi-module check during presubmit 2020-11-05 11:21:15 -08:00
Alexey Odinokov
28cdcc2e46 Allowing RunFns not to stop on empty result
Introducing the additional flag
ContinueOnEmptyResult that is false by default
to keep compatibility with the previous behavior.
Based on [1]

[1]
https://github.com/kubernetes-sigs/kustomize/pull/3112
2020-11-05 07:19:20 +00:00
Natasha Sarkar
c0ecd1d1ad added more tests 2020-11-04 19:07:58 -08:00
Natasha Sarkar
3923c63182 added some tests to merge3/element_test.go 2020-11-04 19:07:58 -08:00
Natasha Sarkar
9943e74187 updated comments 2020-11-04 19:07:58 -08:00
Natasha Sarkar
3b504fa3e5 added StringList set 2020-11-04 19:07:58 -08:00
Kubernetes Prow Robot
9fb25fc5a7 Merge pull request #3139 from runewake2/multi-module-golang
Update Multi Module Check to Scan Commits
2020-11-04 12:14:52 -08:00
Phillip Wittrock
4d99217a7c Build kustomize docs site with redirects to new unified at cli-experimental 2020-11-04 11:18:56 -08:00
Phillip Wittrock
0834e152b2 Redirect kustomize docs to the new unified site. 2020-11-04 11:15:40 -08:00
Donny Xia
ff276af317 use same logic with path transformer 2020-11-03 17:14:08 -08:00
Donny Xia
3b79944190 improve target in JSON6902 transformer 2020-11-03 17:13:43 -08:00
Kubernetes Prow Robot
d8d57eae29 Merge pull request #3174 from Shell32-Natsu/elementsetter-test
add tests for ElementSetter
2020-11-03 15:42:04 -08:00
Donny Xia
c803ca83a4 fix linter error 2020-11-03 15:29:01 -08:00
Donny Xia
6bed275234 add more tests for ElementSetter 2020-11-03 15:23:34 -08:00
Jeff Regan
8e5df26e4c Merge pull request #3173 from natasha41575/StringListSet
added StringList set
2020-11-03 13:34:56 -08:00
Donny Xia
3fed68b694 clarify the comments 2020-11-03 13:09:12 -08:00
Natasha Sarkar
0e59c36d03 added StringList set 2020-11-03 12:42:37 -08:00
Jeff Regan
00fdf71dc3 Merge pull request #2951 from dearchap/cm_merge
Add ability to specify behavior adding configmap
2020-11-03 12:02:45 -08:00
Donny Xia
be327e7443 add tests for ElementSetter 2020-11-03 11:54:44 -08:00
Donny Xia
be8d2fe016 Merge pull request #3161 from mikebz/mb_remove_travis
removing travis references
2020-11-03 11:15:58 -08:00
Mike Borozdin
072ae36fe6 removing travis references 2020-11-03 10:04:42 -08:00
Naveen Gogineni
b5d8b8d258 Add ability to specify behavior when running "kustomize edit add configmap" command 2020-11-02 16:09:51 -05:00
Jeff Regan
e6b21174f1 Merge pull request #3143 from Shell32-Natsu/helm-inflator-builtin
Convert helminflator to builtin plugin HelmChartGenerator
2020-11-02 12:30:02 -08:00
Donny Xia
49094cf999 Merge pull request #3164 from Shell32-Natsu/cloudbuild
fix version in releasing/cloudbuild_kustomize_image.yaml
2020-11-02 11:12:11 -08:00
Donny Xia
d2c7db6ca0 update chart examples 2020-11-02 11:03:31 -08:00
Donny Xia
d141f9b973 fix version 2020-11-02 10:52:04 -08:00
Sam Wronski
877da8da6d Update module span to check commits
- Use regex to detect if check should run
- Update scan to be per-commit
2020-11-02 10:29:40 -08:00
Kubernetes Prow Robot
8596e63203 Merge pull request #3163 from Shell32-Natsu/cloudbuild
update version in image creation
2020-11-02 10:16:15 -08:00
Donny Xia
b2df55e9d7 update version in image creation 2020-11-02 09:55:06 -08:00
Donny Xia
6daf8f8820 Merge pull request #3160 from Shell32-Natsu/cloudbuild
update cloudbuild for image pushing job
2020-11-02 09:39:48 -08:00
Donny Xia
e75d4fc87d convert helm inflator to builtin plugin 2020-10-30 23:18:54 -07:00
Donny Xia
9ae07634f2 update cloudbuild for image pushing job 2020-10-30 12:19:17 -07:00
Donny Xia
981959ffcf Merge pull request #3155 from radTuti/master
fix binary install script
2020-10-29 22:01:18 -07:00
tuti
dc31321b05 fix binary install script 2020-10-29 17:51:54 -07:00
Kubernetes Prow Robot
64dc3e14ff Merge pull request #3153 from Shell32-Natsu/master
unpin modules
2020-10-29 16:32:05 -07:00
Donny Xia
da0893bac0 unpin modules 2020-10-29 16:17:45 -07:00
Kubernetes Prow Robot
c1747439cd Merge pull request #3152 from Shell32-Natsu/master
Pin to api 0.6.4
2020-10-29 16:06:05 -07:00
Donny Xia
f68986827b Pin to api 0.6.4 2020-10-29 15:53:34 -07:00
Kubernetes Prow Robot
b736b81167 Merge pull request #3151 from Shell32-Natsu/master
Pin to cmd/config 0.8.4
2020-10-29 15:24:06 -07:00
Donny Xia
0a04b1bb78 Pin to cmd/config 0.8.4 2020-10-29 15:11:09 -07:00
Kubernetes Prow Robot
f7ebaae39e Merge pull request #3150 from Shell32-Natsu/master
Pin to kyaml v0.9.3
2020-10-29 15:04:06 -07:00
Donny Xia
08099f0cea Pin to kyaml v0.9.3 2020-10-29 14:47:52 -07:00
Kubernetes Prow Robot
6fd04dd253 Merge pull request #3146 from ilyakaznacheev/fix-configmap-doc
Add better configMap cleanup description.
2020-10-28 17:38:59 -07:00
Ilya Kaznacheev
9ac97ef91f Add better configMap cleanup descripion 2020-10-29 01:50:45 +03:00
Jeff Regan
cfbf426174 Merge pull request #3129 from Shell32-Natsu/patches-command
Update edit patch command
2020-10-28 12:47:13 -07:00
Donny Xia
9aafc61c5b disable edit add patch command tests temporarily 2020-10-28 12:24:51 -07:00
Donny Xia
cd2ebd3046 code review 2020-10-27 15:10:29 -07:00
Jeff Regan
b20e5d7f84 Merge pull request #3135 from Shell32-Natsu/cleanup-namespace-transformer
cleanup namespace transformer
2020-10-27 09:54:28 -07:00
Jeff Regan
13c9a2873e Update comments in multi-transformer 2020-10-27 07:17:14 -07:00
Kubernetes Prow Robot
fc06283905 Merge pull request #3140 from teruyam/patch-1
Fix broken link to release page
2020-10-26 12:37:02 -07:00
Jeff Regan
119d7cadf5 Merge pull request #3136 from natasha41575/NamespaceabilityFromOpenAPI
removed hardcoded list of namespaceable resources
2020-10-26 12:22:36 -07:00
Masashi Teruya
cdc6d1fc28 Fix broken link to release page 2020-10-24 11:18:33 +09:00
Natasha Sarkar
49dced2e01 removed hardcoded list of namespaceable resources 2020-10-23 11:47:29 -07:00
Donny Xia
76a8f034cb Merge pull request #3133 from robinbraemer/patch-2
Add Ingress tls secretName to Secret builtin nameref
2020-10-23 11:20:11 -07:00
Donny Xia
52060ac480 Merge pull request #3132 from robinbraemer/patch-1
Add Ingress v1 support to builtin name references
2020-10-23 11:19:51 -07:00
Donny Xia
719532e4df Merge pull request #3123 from AlphaWong/patch-1
doc: add varReference example
2020-10-22 14:42:05 -07:00
Donny Xia
70dcc79bf4 cleanup namespace transformer 2020-10-22 13:18:20 -07:00
Kubernetes Prow Robot
55b4448862 Merge pull request #3134 from phanimarupaka/OptionallySuppressIsSet
Make isSet a parameter
2020-10-22 11:43:37 -07:00
Phani Teja Marupaka
bcaac6f8c1 Make isSet a parameter 2020-10-22 11:31:30 -07:00
Jeff Regan
ba4b44db6b Merge pull request #3126 from monopole/mechanical
Generated go.sum/mod and docs.go changes.
2020-10-22 10:30:52 -07:00
Robin Brämer
fd280d0c0b Add Ingress tls secretName to Secret builtin nameref 2020-10-22 17:00:10 +02:00
Robin Brämer
1dbf490146 Add IngressClass kind
Adds IngressClass kind and Ingress fieldSpecs path spec/ingressClassName
2020-10-22 16:11:44 +02:00
Robin Brämer
62e4df72d3 Add Service name references for Ingress v1
Since Kubernetes v1.19, Ingress networking.k8s.io/v1 has two more Server name references.
- https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource
- https://kubernetes.io/docs/setup/release/notes/
2020-10-22 15:59:22 +02:00
Donny Xia
bb77a7c86d refactor edit remove patch 2020-10-21 18:48:53 -07:00
Donny Xia
41abeb85be refactor edit add patch command 2020-10-21 14:56:20 -07:00
Jeff Regan
3c86d37148 Merge pull request #3122 from Shell32-Natsu/ref-target
check Gvk in roleRef when update name reference
2020-10-21 11:19:20 -07:00
Kubernetes Prow Robot
287b38cc87 Merge pull request #3106 from Shell32-Natsu/array-index
support array index in PathGetter
2020-10-21 11:16:20 -07:00
jregan
d8d727b1ca Generated go.sum/mod and docs.go changes. 2020-10-20 17:22:48 -07:00
Jeff Regan
a81a3d40ce Merge pull request #3087 from etefera/add-isSet-to-list-setters
Add isSet to ListSetters cmd.
2020-10-20 16:52:13 -07:00
Eyob Tefera
52e682489c Merge branch 'add-isSet-to-list-setters' of https://github.com/etefera/kustomize into add-isSet-to-list-setters 2020-10-20 23:24:11 +00:00
Eyob Tefera
8714ca5a58 Move "Is Set" column to after "Required" 2020-10-20 23:17:54 +00:00
Eyob Tefera
0490ca163f Fix list_setters test. 2020-10-20 23:17:54 +00:00
Eyob Tefera
b4947fe8a0 Add isSet to ListSetters cmd. 2020-10-20 23:17:54 +00:00
Donny Xia
9c7b4fddf9 code review 2020-10-20 12:39:50 -07:00
Alpha
5d5b1c2c38 doc: simplify the language for understanding 2020-10-20 13:13:13 +08:00
Alpha
cf1aafb121 doc: add description for new user about vars 2020-10-20 13:06:31 +08:00
Alpha
2d4e406a86 doc: add varReference example 2020-10-20 12:56:43 +08:00
Jeff Regan
2a8edd2859 Merge pull request #3110 from aude/completion
Use Cobra for shell completion
2020-10-19 18:03:06 -07:00
Kubernetes Prow Robot
a3bc13847c Merge pull request #3119 from phanimarupaka/MakeRecurseLogicPublic
Make recurse logic public
2020-10-19 17:28:07 -07:00
Kubernetes Prow Robot
944b19ff7c Merge pull request #3114 from monopole/hideOpenapi
Hide openapi top-level command
2020-10-19 17:14:07 -07:00
Jeff Regan
f75274bae7 Merge pull request #3085 from mikeyrcamp/feat/add-edit-transformer
Add kustomize edit add/remove transformer command #3053
2020-10-19 15:04:12 -07:00
Donny Xia
62a8a8c57d check Gvk in roleRef when update name reference 2020-10-19 14:01:13 -07:00
Kubernetes Prow Robot
9514f9cd3a Merge pull request #3121 from natasha41575/regenerateSwagger
regenerated swagger.go files and updated asset name
2020-10-19 13:39:18 -07:00
Natasha Sarkar
c1c2725360 regenerated swagger.go files and updated asset name 2020-10-19 13:04:56 -07:00
Phani Teja Marupaka
e9ff26bb1b Make recurse logic public 2020-10-19 12:26:15 -07:00
Kubernetes Prow Robot
14dc3dfb81 Merge pull request #3112 from KnVerey/pipeline_continue
[kyaml] Option to continue pipeline processing when filter returns empty result
2020-10-19 10:46:14 -07:00
Katrina Verey
44619d5ca2 Option to continue pipeline processing when filter returns empty result 2020-10-19 10:34:28 -07:00
brianpursley
027b7d61ea Implemented the following WNode methods:
* GetFieldValue
* GetSlice
* GetString
* Map
* SetAnnotations
* SetGvk
* SetLabels
* SetName
* SetNamespace
2020-10-18 20:09:42 -04:00
Kubernetes Prow Robot
a458ed84f9 Merge pull request #3113 from etefera/add-isSet-to-setter-struct
Add IsSet to SetterDefinition for kyaml release.
2020-10-18 11:26:13 -07:00
Kubernetes Prow Robot
108f44377d Merge pull request #3115 from monopole/refactorOpenapiMakefile
Refactor making of openapi generated files.
2020-10-16 19:24:12 -07:00
jregan
dc8439fbfa Refactor making of openapi generated files. 2020-10-16 19:03:33 -07:00
Jeff Regan
f5353fafa1 Update info.go 2020-10-16 18:00:18 -07:00
jregan
3d1376bbbc oopsHideProperCommand 2020-10-16 17:57:25 -07:00
Eyob Tefera
b1ea25e86a Add IsSet to SetterDefinition for kyaml release. 2020-10-17 00:46:30 +00:00
Jeff Regan
495f6df973 Merge pull request #3107 from natasha41575/reportOpenAPIinfo
Created a "kustomize openapi info" command
2020-10-16 14:33:21 -07:00
Natasha Sarkar
a4f1f0841e added a hidden openapi info command 2020-10-16 13:55:37 -07:00
Asbjørn Apeland
9d0fba81f0 Use Cobra for shell completion 2020-10-16 18:55:54 +02:00
Donny Xia
92826c6a1e support array index in PathGetter 2020-10-15 16:28:09 -07:00
Kubernetes Prow Robot
7e04be9ec6 Merge pull request #3105 from Shell32-Natsu/unpinKyaml
Unpin kyaml
2020-10-15 14:23:25 -07:00
Donny Xia
d954c39ef7 Unpin kyaml 2020-10-15 14:05:31 -07:00
Jeff Regan
176ac5b4fa Merge pull request #3104 from Shell32-Natsu/pinToKyaml0.9.2
Pin to kyaml v0.9.2
2020-10-15 14:02:47 -07:00
Donny Xia
dd696b5cb4 Pin to kyaml v0.9.2 2020-10-15 13:55:30 -07:00
Jeff Regan
501404e403 Merge pull request #3103 from monopole/prchecker
Move multi-module-span.go to cmd/prchecker
2020-10-15 13:39:48 -07:00
Jeff Regan
ddf94175ee Merge pull request #3102 from natasha41575/rollbackPortMergeKey
changed port merge key back to containerPort
2020-10-15 12:06:51 -07:00
Jeff Regan
232da9e12b Update Makefile 2020-10-15 11:58:50 -07:00
jregan
8b9ce8eacb Move multi-module-span.go to cmd/prchecker 2020-10-15 11:46:27 -07:00
Natasha Sarkar
ee9a4f2526 changed port merge key back to containerport 2020-10-15 11:43:14 -07:00
Kubernetes Prow Robot
006ce72b2d Merge pull request #3099 from umangachapagain/patch-1
Updated description for commonannotations
2020-10-15 11:35:25 -07:00
Jeff Regan
a80bd15bda Merge pull request #3096 from runewake2/multi-module-golang
Add Support for Paginated Pull Request Responses to Multi-Module Check
2020-10-15 11:23:30 -07:00
Sam Wronski
6c63bb2727 Revert Makefile changes 2020-10-15 10:29:38 -07:00
Jeff Regan
a7ba93b1d8 Merge pull request #3101 from monopole/cleanUpMakeTargets
Cleanup Makefile.
2020-10-15 10:03:37 -07:00
jregan
4a78cd6579 Cleanup Makefile. 2020-10-15 10:02:15 -07:00
Jeff Regan
b2b8c12203 Update README.md 2020-10-15 09:46:35 -07:00
Jeff Regan
8cc281fad6 Merge pull request #3100 from monopole/movePluginatorToCmd
Move pluginator to cmd dir.
2020-10-15 09:43:46 -07:00
jregan
7346813b8d Move pluginator to cmd dir. 2020-10-15 09:22:29 -07:00
Umanga Chapagain
52f3aca22d Updated description for commonannotations 2020-10-15 09:13:39 +05:30
Mike Camp
a6a061215f Add kustomize edit add/remove transformer command #3053
Similar to edit add/remove patch these commands
add the ability to add or remove a transformer file path
from the kustomization.yaml.

Refactored the "remove resource" and new "remove transformer"
tests into a common testRemoveCommand function to prevent
code duplication.
2020-10-14 22:24:08 -04:00
Kubernetes Prow Robot
7464d8ac8f Merge pull request #3097 from Shell32-Natsu/as-current-user
add --as-current-user flag to fn run
2020-10-14 18:09:51 -07:00
Donny Xia
64fda38e2d add --as-current-user flag to fn run 2020-10-14 17:07:03 -07:00
Sam Wronski
4cefb62d41 Add multi-module check to prow-presubmit-check 2020-10-14 15:34:52 -07:00
Eyob Tefera
ccca424234 Move "Is Set" column to after "Required" 2020-10-14 19:38:47 +00:00
Jeff Regan
ca45907af0 Merge pull request #3083 from stuartpb/patch-1
Group regex within anchoring
2020-10-14 08:34:28 -07:00
Jeff Regan
dcf43c7f2b Merge pull request #3076 from natasha41575/fetchOpenAPIdata
Fetch openAPI data
2020-10-14 08:20:27 -07:00
Natasha Sarkar
1386ec3850 edited kpt target 2020-10-13 17:19:03 -07:00
Natasha Sarkar
de8e16df15 added script for installing kpt 2020-10-13 17:11:00 -07:00
Natasha Sarkar
222b2d4485 added MYGOBIN variable for kind 2020-10-13 16:25:29 -07:00
Natasha Sarkar
e107020bd2 edited make schema for kyaml 2020-10-13 13:53:25 -07:00
Natasha Sarkar
430665e984 version -> api_version 2020-10-13 13:21:19 -07:00
Kubernetes Prow Robot
017d5673ba Merge pull request #3088 from Shell32-Natsu/arm-build
add arm build
2020-10-12 15:33:22 -07:00
Donny Xia
f346b9803e add arm build 2020-10-12 13:41:24 -07:00
Eyob Tefera
58092bf66d Fix list_setters test. 2020-10-12 20:23:53 +00:00
Eyob Tefera
747323efce Add isSet to ListSetters cmd. 2020-10-12 20:14:25 +00:00
Jeff Regan
7428e08f93 Merge pull request #3081 from Shell32-Natsu/release-container
files for building image when release kustomize
2020-10-12 11:18:09 -07:00
Stuart P. Bentley
3c8e6d7151 Group regex within anchoring
This ensures that anchoring will apply to the entire anchored expression, eg. a pattern like `foo|bar` will only match the strings "foo" and "bar" (`^(?:foo|bar)$`), instead of matching any string that begins with "foo" or ends with "bar" (`^foo|bar$`).
2020-10-10 15:47:38 -07:00
Donny Xia
43bd2f4cdb files for building image when release kustomize 2020-10-09 14:35:17 -07:00
Natasha Sarkar
1dfc9a88a8 moved openapi instructions to top of readme 2020-10-09 12:31:14 -07:00
Natasha Sarkar
01beba8697 formatting documentation: 2020-10-09 12:29:06 -07:00
Natasha Sarkar
b1e01b238b updated documentation 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1f595da9ad updated way to fetch go-bindata 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1cf876927d minor makefile fix 2020-10-09 12:29:06 -07:00
Natasha Sarkar
a422c935d8 added make target to fetch new openapi schema 2020-10-09 12:29:06 -07:00
Jeff Regan
1971816663 Update README.md 2020-10-09 09:45:19 -07:00
Kubernetes Prow Robot
3d1eab872b Merge pull request #3071 from monopole/unpinAll
Unpin api,cmd/config,kyaml
2020-10-08 13:03:06 -07:00
Jeff Regan
10c1b0c5fa Update README.md 2020-10-08 11:34:07 -07:00
Jeff Regan
4d95cd3630 Merge pull request #3072 from monopole/gorepomod
Replace bash release helper scripts with Go progam
2020-10-08 11:10:57 -07:00
jregan
0c169e96e5 Replace bash release helper scripts with Go progam 2020-10-08 10:54:14 -07:00
jregan
5baea8400f Unpin api,cmd/config,kyaml 2020-10-08 09:39:49 -07:00
Jeff Regan
4052cd4fd8 Merge pull request #3069 from monopole/pinToCmdConfigV0.8.2
Pin to cmd/config/v0.8.2,  api/v0.6.3
2020-10-07 19:40:12 -07:00
jregan
21ac400d49 Pin to cmd/config/v0.8.2 2020-10-07 19:21:23 -07:00
686 changed files with 388984 additions and 25143 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
.github
docs
examples
functions
hack
site
travis
*.md

View File

@@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v2
- name: Lint
run: ./travis/kyaml-pre-commit.sh
run: ./scripts/kyaml-pre-commit.sh
env:
KUSTOMIZE_DOCKER_E2E: false # don't need to do e2e tests for linting

127
Makefile
View File

@@ -6,6 +6,17 @@
MYGOBIN := $(shell go env GOPATH)/bin
SHELL := /bin/bash
export PATH := $(MYGOBIN):$(PATH)
MODULES := '"cmd/config" "api/" "kustomize/" "kyaml/"'
# Provide defaults for REPO_OWNER and REPO_NAME if not present.
# Typically these values would be provided by Prow.
ifndef REPO_OWNER
REPO_OWNER := "kubernetes-sigs"
endif
ifndef REPO_NAME
REPO_NAME := "kustomize"
endif
.PHONY: all
all: verify-kustomize
@@ -15,20 +26,19 @@ verify-kustomize: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0 \
test-examples-kustomize-against-3.8.2
test-examples-kustomize-against-3.8.6
# The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
.PHONY: prow-presubmit-check
prow-presubmit-check: \
lint-kustomize \
test-multi-module \
test-unit-kustomize-all \
test-unit-cmd-all \
test-go-mod \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0 \
test-examples-kustomize-against-3.8.2
test-examples-kustomize-against-3.8.6
.PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -47,35 +57,37 @@ $(MYGOBIN)/golangci-lint-kustomize:
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
)
$(MYGOBIN)/gorepomod:
cd api; \
go install github.com/monopole/gorepomod
# Install from version specified in api/go.mod.
$(MYGOBIN)/mdrip:
cd api; \
go install github.com/monopole/mdrip
# Install from version specified in api/go.mod.
$(MYGOBIN)/stringer:
cd api; \
go install golang.org/x/tools/cmd/stringer
# Install from version specified in api/go.mod.
$(MYGOBIN)/goimports:
cd api; \
go install golang.org/x/tools/cmd/goimports
# Install resource from whatever is checked out.
$(MYGOBIN)/resource:
cd cmd/resource; \
# Build from local source.
$(MYGOBIN)/gorepomod:
cd cmd/gorepomod; \
go install .
# To pin pluginator, use this recipe instead:
# cd api;
# go install sigs.k8s.io/kustomize/pluginator/v2
# Build from local source.
$(MYGOBIN)/pluginator:
cd pluginator; \
cd cmd/pluginator; \
go install .
# Install kustomize from whatever is checked out.
# Build from local source.
$(MYGOBIN)/prchecker:
cd cmd/prchecker; \
go install .
# Build from local source.
$(MYGOBIN)/kustomize:
cd kustomize; \
go install .
@@ -88,7 +100,9 @@ install-tools: \
$(MYGOBIN)/gorepomod \
$(MYGOBIN)/mdrip \
$(MYGOBIN)/pluginator \
$(MYGOBIN)/stringer
$(MYGOBIN)/prchecker \
$(MYGOBIN)/stringer \
$(MYGOBIN)/helm
### Begin kustomize plugin rules.
#
@@ -130,7 +144,8 @@ _builtinplugins = \
PrefixSuffixTransformer.go \
ReplicaCountTransformer.go \
SecretGenerator.go \
ValueAddTransformer.go
ValueAddTransformer.go \
HelmChartInflationGenerator.go
# Maintaining this explicit list of generated files, and
# adding it as a dependency to a few targets, to assure
@@ -156,6 +171,7 @@ $(pGen)/PrefixSuffixTransformer.go: $(pSrc)/prefixsuffixtransformer/PrefixSuffix
$(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go
$(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go
$(pGen)/ValueAddTransformer.go: $(pSrc)/valueaddtransformer/ValueAddTransformer.go
$(pGen)/HelmChartInflationGenerator.go: $(pSrc)/helmchartinflationgenerator/HelmChartInflationGenerator.go
# The (verbose but portable) Makefile way to convert to lowercase.
toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
@@ -174,24 +190,27 @@ $(pGen)/%.go: $(MYGOBIN)/pluginator
.PHONY: generate-kustomize-builtin-plugins
generate-kustomize-builtin-plugins: $(builtinplugins)
.PHONY: kustomize-external-go-plugin-build
kustomize-external-go-plugin-build:
.PHONY: build-kustomize-external-go-plugin
build-kustomize-external-go-plugin:
./hack/buildExternalGoPlugins.sh ./plugin
.PHONY: kustomize-external-go-plugin-clean
kustomize-external-go-plugin-clean:
.PHONY: clean-kustomize-external-go-plugin
clean-kustomize-external-go-plugin:
./hack/buildExternalGoPlugins.sh ./plugin clean
### End kustomize plugin rules.
.PHONY: lint-kustomize
lint-kustomize: install-tools $(builtinplugins)
cd api; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd kustomize; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd api; $(MYGOBIN)/golangci-lint-kustomize \
-c ../.golangci-kustomize.yml \
run ./...
cd kustomize; $(MYGOBIN)/golangci-lint-kustomize \
-c ../.golangci-kustomize.yml \
run ./...
cd cmd/pluginator; $(MYGOBIN)/golangci-lint-kustomize \
-c ../../.golangci-kustomize.yml \
run ./...
# Used to add non-default compilation flags when experimenting with
# plugin-to-api compatibility checks.
@@ -199,6 +218,10 @@ lint-kustomize: install-tools $(builtinplugins)
build-kustomize-api: $(builtinplugins)
cd api; go build ./...
.PHONY: generate-kustomize-api
generate-kustomize-api:
cd api; go generate ./...
.PHONY: test-unit-kustomize-api
test-unit-kustomize-api: build-kustomize-api
cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
@@ -218,10 +241,23 @@ test-unit-kustomize-all: \
test-unit-kustomize-plugins
test-unit-cmd-all:
./travis/kyaml-pre-commit.sh
./scripts/kyaml-pre-commit.sh
test-go-mod:
./travis/check-go-mod.sh
./scripts/check-go-mod.sh
# Environment variables are defined at
# https://github.com/kubernetes/test-infra/blob/master/prow/jobs.md#job-environment-variables
.PHONY: test-multi-module
test-multi-module: $(MYGOBIN)/prchecker
( \
export MYGOBIN=$(MYGOBIN); \
export REPO_OWNER=$(REPO_OWNER); \
export REPO_NAME=$(REPO_NAME); \
export PULL_NUMBER=$(PULL_NUMBER); \
export MODULES=$(MODULES); \
./scripts/check-multi-module.sh; \
)
.PHONY:
test-examples-e2e-kustomize: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
@@ -238,23 +274,10 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY:
test-examples-kustomize-against-3.8.0: $(MYGOBIN)/mdrip
test-examples-kustomize-against-3.8.6: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.8.0; \
/bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \
./hack/testExamplesAgainstKustomize.sh $$tag; \
echo "Reinstalling kustomize from HEAD."; \
cd kustomize; go install .; \
)
.PHONY:
test-examples-kustomize-against-3.8.2: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.8.2; \
tag=v3.8.6; \
/bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \
@@ -301,16 +324,16 @@ $(MYGOBIN)/helmV3:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v3.2.0-rc.1-linux-amd64.tar.gz; \
tgzFile=helm-v3.4.0-linux-amd64.tar.gz; \
wget https://get.helm.sh/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv linux-amd64/helm $(MYGOBIN)/helmV3; \
rm -rf $$d \
)
# Default version of helm is v2 for the time being.
$(MYGOBIN)/helm: $(MYGOBIN)/helmV2
ln -s $(MYGOBIN)/helmV2 $(MYGOBIN)/helm
# Default version of helm is v3.
$(MYGOBIN)/helm: $(MYGOBIN)/helmV3
ln -s $(MYGOBIN)/helmV3 $(MYGOBIN)/helm
$(MYGOBIN)/kind:
( \
@@ -335,13 +358,15 @@ $(MYGOBIN)/gh:
)
.PHONY: clean
clean: kustomize-external-go-plugin-clean
clean: clean-kustomize-external-go-plugin
go clean --cache
rm -f $(builtinplugins)
rm -f $(MYGOBIN)/pluginator
rm -f $(MYGOBIN)/kustomize
rm -f $(MYGOBIN)/golangci-lint-kustomize
# Handle pluginator manually.
# rm -f $(MYGOBIN)/pluginator
# Nuke the site from orbit. It's the only way to be sure.
.PHONY: nuke
nuke: clean

View File

@@ -20,15 +20,20 @@ This tool is sponsored by [sig-cli] ([KEP]).
## kubectl integration
Since [v1.14][kubectl announcement] the kustomize build system has been included in kubectl.
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).
| kubectl version | kustomize version |
|---------|--------|
| v1.16.0 | [v2.0.3](/../../tree/v2.0.3) |
| v1.15.x | [v2.0.3](/../../tree/v2.0.3) |
| v1.14.x | [v2.0.3](/../../tree/v2.0.3) |
[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
For examples and guides for using the kubectl integration please see the [kubectl book] or the [kubernetes documentation].
For examples and guides for using the kubectl integration please
see the [kubectl book] or the [kubernetes documentation].
## Usage

View File

@@ -0,0 +1,178 @@
// Code generated by pluginator on HelmChartInflationGenerator; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
package builtins
import (
"bytes"
"fmt"
"os"
"os/exec"
"path"
"regexp"
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
// HelmChartInflationGeneratorPlugin is a plugin to generate resources
// from a remote or local helm chart.
type HelmChartInflationGeneratorPlugin struct {
h *resmap.PluginHelpers
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
runHelmCommand func([]string) ([]byte, error)
types.HelmChartArgs
tmpDir string
}
var KustomizePlugin HelmChartInflationGeneratorPlugin
// Config uses the input plugin configurations `config` to setup the generator
// options
func (p *HelmChartInflationGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) error {
p.h = h
err := yaml.Unmarshal(config, p)
if err != nil {
return err
}
tmpDir, err := filesys.NewTmpConfirmedDir()
if err != nil {
return err
}
p.tmpDir = string(tmpDir)
if p.ChartName == "" {
return fmt.Errorf("chartName cannot be empty")
}
if p.ChartHome == "" {
p.ChartHome = path.Join(p.tmpDir, "chart")
}
if p.ChartRepoName == "" {
p.ChartRepoName = "stable"
}
if p.HelmBin == "" {
p.HelmBin = "helm"
}
if p.HelmHome == "" {
p.HelmHome = path.Join(p.tmpDir, ".helm")
}
if p.Values == "" {
p.Values = path.Join(p.ChartHome, p.ChartName, "values.yaml")
}
// runHelmCommand will run `helm` command with args provided. Return stdout
// and error if there is any.
p.runHelmCommand = func(args []string) ([]byte, error) {
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
cmd := exec.Command(p.HelmBin, args...)
cmd.Stdout = stdout
cmd.Stderr = stderr
cmd.Env = append(cmd.Env,
fmt.Sprintf("HELM_CONFIG_HOME=%s", p.HelmHome),
fmt.Sprintf("HELM_CACHE_HOME=%s/.cache", p.HelmHome),
fmt.Sprintf("HELM_DATA_HOME=%s/.data", p.HelmHome),
)
err := cmd.Run()
if err != nil {
return stdout.Bytes(),
errors.Wrap(
fmt.Errorf("failed to run command %s %s", p.HelmBin, strings.Join(args, " ")),
stderr.String(),
)
}
return stdout.Bytes(), nil
}
return nil
}
// Generate implements generator
func (p *HelmChartInflationGeneratorPlugin) Generate() (resmap.ResMap, error) {
// cleanup
defer os.RemoveAll(p.tmpDir)
// check helm version. we only support V3
err := p.checkHelmVersion()
if err != nil {
return nil, err
}
// pull the chart
if !p.checkLocalChart() {
_, err := p.runHelmCommand(p.getPullCommandArgs())
if err != nil {
return nil, err
}
}
// render the charts
stdout, err := p.runHelmCommand(p.getTemplateCommandArgs())
if err != nil {
return nil, err
}
return p.h.ResmapFactory().NewResMapFromBytes(stdout)
}
func (p *HelmChartInflationGeneratorPlugin) getTemplateCommandArgs() []string {
args := []string{"template"}
if p.ReleaseName != "" {
args = append(args, p.ReleaseName)
}
args = append(args, path.Join(p.ChartHome, p.ChartName))
if p.ReleaseNamespace != "" {
args = append(args, "--namespace", p.ReleaseNamespace)
}
if p.Values != "" {
args = append(args, "--values", p.Values)
}
return args
}
func (p *HelmChartInflationGeneratorPlugin) getPullCommandArgs() []string {
args := []string{"pull", "--untar", "--untardir", p.ChartHome}
chartName := fmt.Sprintf("%s/%s", p.ChartRepoName, p.ChartName)
if p.ChartVersion != "" {
args = append(args, "--version", p.ChartVersion)
}
if p.ChartRepoURL != "" {
args = append(args, "--repo", p.ChartRepoURL)
chartName = p.ChartName
}
args = append(args, chartName)
return args
}
// checkLocalChart will return true if the chart does exist in
// local chart home.
func (p *HelmChartInflationGeneratorPlugin) checkLocalChart() bool {
path := path.Join(p.ChartHome, p.ChartName)
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}
// checkHelmVersion will return an error if the helm version is not V3
func (p *HelmChartInflationGeneratorPlugin) checkHelmVersion() error {
stdout, err := p.runHelmCommand([]string{"version", "-c", "--short"})
if err != nil {
return err
}
r, err := regexp.Compile(`v\d+(\.\d+)+`)
if err != nil {
return err
}
v := string(r.Find(stdout))[1:]
majorVersion := strings.Split(v, ".")[0]
if majorVersion != "3" {
return fmt.Errorf("this plugin requires helm V3 but got v%s", v)
}
return nil
}
func NewHelmChartInflationGeneratorPlugin() resmap.GeneratorPlugin {
return &HelmChartInflationGeneratorPlugin{}
}

View File

@@ -7,9 +7,7 @@ import (
"fmt"
"sigs.k8s.io/kustomize/api/filters/namespace"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
@@ -53,74 +51,6 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
return nil
}
// Special casing metadata.namespace since
// all objects have it, even "ClusterKind" objects
// that don't exist in a namespace (the Namespace
// object itself doesn't live in a namespace).
func (p *NamespaceTransformerPlugin) applicableFieldSpecs(id resid.ResId) []types.FieldSpec {
var res []types.FieldSpec
for _, fs := range p.FieldSpecs {
if id.IsSelected(&fs.Gvk) &&
(fs.Path != types.MetadataNamespacePath ||
(fs.Path == types.MetadataNamespacePath && id.IsNamespaceableKind())) {
res = append(res, fs)
}
}
return res
}
func (p *NamespaceTransformerPlugin) changeNamespace(
_ *resource.Resource) func(in interface{}) (interface{}, error) {
return func(in interface{}) (interface{}, error) {
switch in.(type) {
case string:
// will happen when the metadata/namespace
// value is replaced
return p.Namespace, nil
case []interface{}:
l, _ := in.([]interface{})
for idx, item := range l {
switch item.(type) {
case map[string]interface{}:
// Will happen when mutating the subjects
// field of ClusterRoleBinding and RoleBinding
inMap, _ := item.(map[string]interface{})
if _, ok := inMap["name"]; !ok {
continue
}
name, ok := inMap["name"].(string)
if !ok {
continue
}
// The only case we need to force the namespace
// if for the "service account". "default" is
// kind of hardcoded here for right now.
if name != "default" {
continue
}
inMap["namespace"] = p.Namespace
l[idx] = inMap
default:
// nothing to do for right now
}
}
return in, nil
case map[string]interface{}:
// Will happen if the createField=true
// when the namespace is added to the
// object
inMap := in.(map[string]interface{})
if len(inMap) == 0 {
return p.Namespace, nil
} else {
return in, nil
}
default:
return in, nil
}
}
}
func NewNamespaceTransformerPlugin() resmap.TransformerPlugin {
return &NamespaceTransformerPlugin{}
}

View File

@@ -10,7 +10,6 @@ import (
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/patchjson6902"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
@@ -20,9 +19,9 @@ import (
type PatchJson6902TransformerPlugin struct {
ldr ifc.Loader
decodedPatch jsonpatch.Patch
Target types.PatchTarget `json:"target,omitempty" yaml:"target,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
JsonOp string `json:"jsonOp,omitempty" yaml:"jsonOp,omitempty"`
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
JsonOp string `json:"jsonOp,omitempty" yaml:"jsonOp,omitempty"`
}
func (p *PatchJson6902TransformerPlugin) Config(
@@ -72,22 +71,22 @@ func (p *PatchJson6902TransformerPlugin) Config(
}
func (p *PatchJson6902TransformerPlugin) Transform(m resmap.ResMap) error {
id := resid.NewResIdWithNamespace(
resid.Gvk{
Group: p.Target.Group,
Version: p.Target.Version,
Kind: p.Target.Kind,
},
p.Target.Name,
p.Target.Namespace,
)
obj, err := m.GetById(id)
if p.Target == nil {
return fmt.Errorf("must specify a target for patch %s", p.JsonOp)
}
resources, err := m.Select(*p.Target)
if err != nil {
return err
}
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.JsonOp,
}, obj)
for _, res := range resources {
err = filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.JsonOp,
}, res)
if err != nil {
return err
}
}
return nil
}
func NewPatchJson6902TransformerPlugin() resmap.TransformerPlugin {

View File

@@ -1,7 +1,9 @@
package nameref
import (
"encoding/json"
"fmt"
"strings"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
@@ -9,6 +11,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
kyaml_filtersutil "sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -19,6 +22,7 @@ type Filter struct {
Referrer *resource.Resource
Target resid.Gvk
ReferralCandidates resmap.ResMap
isRoleRef bool
}
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
@@ -37,6 +41,9 @@ func (f Filter) set(node *yaml.RNode) error {
if yaml.IsMissingOrNull(node) {
return nil
}
if strings.HasSuffix(f.FieldSpec.Path, "roleRef/name") {
f.isRoleRef = true
}
switch node.YNode().Kind {
case yaml.ScalarNode:
return f.setScalar(node)
@@ -65,6 +72,7 @@ func (f Filter) setMapping(node *yaml.RNode) error {
f.Referrer,
f.Target,
f.ReferralCandidates,
f.isRoleRef,
)
}
@@ -75,6 +83,7 @@ func (f Filter) setScalar(node *yaml.RNode) error {
f.Target,
f.ReferralCandidates,
f.ReferralCandidates.Resources(),
f.isRoleRef,
)
if err != nil {
return err
@@ -86,6 +95,40 @@ func (f Filter) setScalar(node *yaml.RNode) error {
return nil
}
// getRoleRefGvk returns a Gvk in the roleRef field. Return error
// if the roleRef, roleRef/apiGroup or roleRef/kind is missing.
func getRoleRefGvk(res json.Marshaler) (*resid.Gvk, error) {
n, err := kyaml_filtersutil.GetRNode(res)
if err != nil {
return nil, err
}
roleRef, err := n.Pipe(yaml.Lookup("roleRef"))
if err != nil {
return nil, err
}
if roleRef.IsNil() {
return nil, fmt.Errorf("roleRef cannot be found in %s", n.MustString())
}
apiGroup, err := roleRef.Pipe(yaml.Lookup("apiGroup"))
if err != nil {
return nil, err
}
if apiGroup.IsNil() {
return nil, fmt.Errorf("apiGroup cannot be found in roleRef %s", roleRef.MustString())
}
kind, err := roleRef.Pipe(yaml.Lookup("kind"))
if err != nil {
return nil, err
}
if kind.IsNil() {
return nil, fmt.Errorf("kind cannot be found in roleRef %s", roleRef.MustString())
}
return &resid.Gvk{
Group: apiGroup.YNode().Value,
Kind: kind.YNode().Value,
}, nil
}
func filterReferralCandidates(
referrer *resource.Resource,
matches []*resource.Resource,
@@ -117,11 +160,22 @@ func selectReferral(
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap,
referralCandidateSubset []*resource.Resource) (string, string, error) {
referralCandidateSubset []*resource.Resource,
isRoleRef bool) (string, string, error) {
var roleRefGvk *resid.Gvk
if isRoleRef {
var err error
roleRefGvk, err = getRoleRefGvk(referrer)
if err != nil {
return "", "", err
}
}
for _, res := range referralCandidateSubset {
id := res.OrgId()
if id.IsSelected(&target) && res.GetOriginalName() == oldName {
// If the we are processing a roleRef, the apiGroup and Kind in the
// roleRef are needed to be considered.
if (!isRoleRef || id.IsSelected(roleRefGvk)) &&
id.IsSelected(&target) && res.GetOriginalName() == oldName {
matches := referralCandidates.GetMatchingResourcesByOriginalId(id.Equals)
// If there's more than one match,
// filter the matches by prefix and suffix
@@ -155,10 +209,11 @@ func getSimpleNameField(
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap,
referralCandidateSubset []*resource.Resource) (string, error) {
referralCandidateSubset []*resource.Resource,
isRoleRef bool) (string, error) {
newName, _, err := selectReferral(oldName, referrer, target,
referralCandidates, referralCandidateSubset)
referralCandidates, referralCandidateSubset, isRoleRef)
return newName, err
}
@@ -177,7 +232,8 @@ func setNameAndNs(
in *yaml.RNode,
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap) error {
referralCandidates resmap.ResMap,
isRoleRef bool) error {
if in.YNode().Kind != yaml.MappingNode {
return fmt.Errorf("expect a mapping node")
@@ -213,7 +269,7 @@ func setNameAndNs(
oldName := nameNode.YNode().Value
newname, newnamespace, err := selectReferral(oldName, referrer, target,
referralCandidates, subset)
referralCandidates, subset, isRoleRef)
if err != nil {
return err
}

View File

@@ -5,10 +5,9 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
"sigs.k8s.io/kustomize/api/types"
)
@@ -220,7 +219,7 @@ map:
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
factory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
factory := provider.NewDefaultDepProvider().GetResourceFactory()
referrer, err := factory.FromBytes([]byte(tc.input))
if err != nil {
t.Fatal(err)
@@ -321,7 +320,7 @@ metadata:
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
factory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
factory := provider.NewDefaultDepProvider().GetResourceFactory()
referrer, err := factory.FromBytes([]byte(tc.input))
if err != nil {
t.Fatal(err)
@@ -732,7 +731,7 @@ ref:
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
factory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
factory := provider.NewDefaultDepProvider().GetResourceFactory()
referrer, err := factory.FromBytes([]byte(tc.input))
if err != nil {
t.Fatal(err)

View File

@@ -194,47 +194,47 @@ metadata:
{
name: "update-clusterrolebinding",
input: `
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: foo
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
namespace: foo
`,
expected: `
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: bar
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: bar
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something

View File

@@ -370,6 +370,213 @@ spec:
image: test2
- name: test
image: test
`,
},
"list map keys - add a port, no names": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: TCP
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
- containerPort: 80
protocol: UDP
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
- containerPort: 80
protocol: UDP
- containerPort: 8080
protocol: TCP
`,
},
"list map keys - add name to port": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
- containerPort: 8080
protocol: TCP
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
name: UDP-name-patch
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
name: UDP-name-patch
- containerPort: 8080
protocol: TCP
`,
},
"list map keys - replace port name": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
name: UDP-name-original
- containerPort: 8080
protocol: TCP
name: TCP-name-original
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
name: UDP-name-patch
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
protocol: UDP
name: UDP-name-patch
- containerPort: 8080
protocol: TCP
name: TCP-name-original
`,
},
"list map keys - add a port, no protocol": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 8080
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 80
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
template:
spec:
containers:
- image: test-image
name: test-deployment
ports:
- containerPort: 80
- containerPort: 8080
`,
},
}

View File

@@ -1,12 +1,15 @@
module sigs.k8s.io/kustomize/api
go 1.14
go 1.15
require (
github.com/evanphx/json-patch v4.5.0+incompatible
github.com/go-errors/errors v1.0.1
github.com/go-openapi/spec v0.19.5
github.com/golangci/golangci-lint v1.21.0
github.com/google/go-cmp v0.3.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/hashicorp/go-multierror v1.1.0
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.4.0
github.com/yujunz/go-getter v1.4.1-lite
@@ -17,6 +20,8 @@ require (
k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.9.1
sigs.k8s.io/kustomize/kyaml v0.9.4
sigs.k8s.io/yaml v1.2.0
)
replace sigs.k8s.io/kustomize/kyaml v0.9.4 => ../kyaml

View File

@@ -232,8 +232,12 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
@@ -588,8 +592,6 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -8,17 +8,14 @@ import (
"testing"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
)
func TestNameReferenceHappyRun(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmaptest_test.NewRmBuilder(t, rf).AddWithName(
m := resmaptest_test.NewRmBuilderDefault(t).AddWithName(
"cm1",
map[string]interface{}{
"apiVersion": "v1",
@@ -261,7 +258,8 @@ func TestNameReferenceHappyRun(t *testing.T) {
},
}).ResMap()
expected := resmaptest_test.NewSeededRmBuilder(t, rf, m.ShallowCopy()).ReplaceResource(
expected := resmaptest_test.NewSeededRmBuilderDefault(
t, m.ShallowCopy()).ReplaceResource(
map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -475,14 +473,12 @@ func TestNameReferenceHappyRun(t *testing.T) {
}
func TestNameReferenceUnhappyRun(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
tests := []struct {
resMap resmap.ResMap
expectedErr string
}{
{
resMap: resmaptest_test.NewRmBuilder(t, rf).Add(
resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
@@ -502,7 +498,7 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
}).ResMap(),
expectedErr: "is expected to be"},
{
resMap: resmaptest_test.NewRmBuilder(t, rf).Add(
resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
@@ -538,8 +534,7 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
}
func TestNameReferencePersistentVolumeHappyRun(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
rf := provider.NewDefaultDepProvider().GetResourceFactory()
v1 := rf.FromMapWithName(
"volume1",
@@ -664,9 +659,7 @@ const (
// object with the same original names (uniquename) in different namespaces
// and with different current Id.
func TestNameReferenceNamespace(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmaptest_test.NewRmBuilder(t, rf).
m := resmaptest_test.NewRmBuilderDefault(t).
// Add ConfigMap with the same org name in noNs, "ns1" and "ns2" namespaces
AddWithName(orgname, map[string]interface{}{
"apiVersion": "v1",
@@ -715,7 +708,7 @@ func TestNameReferenceNamespace(t *testing.T) {
AddWithNsAndName(ns1, orgname, deploymentMap(ns1, prefixedname, orgname, orgname)).
AddWithNsAndName(ns2, orgname, deploymentMap(ns2, suffixedname, orgname, orgname)).ResMap()
expected := resmaptest_test.NewSeededRmBuilder(t, rf, m.ShallowCopy()).
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
ReplaceResource(deploymentMap(defaultNs, modifiedname, modifiedname, modifiedname)).
ReplaceResource(deploymentMap(ns1, prefixedname, prefixedname, prefixedname)).
ReplaceResource(deploymentMap(ns2, suffixedname, suffixedname, suffixedname)).ResMap()
@@ -735,9 +728,7 @@ func TestNameReferenceNamespace(t *testing.T) {
// object with the same original names (uniquename) in different namespaces
// and with different current Id.
func TestNameReferenceClusterWide(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmaptest_test.NewRmBuilder(t, rf).
m := resmaptest_test.NewRmBuilderDefault(t).
// Add ServiceAccount with the same org name in noNs, "ns1" and "ns2" namespaces
AddWithName(orgname, map[string]interface{}{
"apiVersion": "v1",
@@ -789,9 +780,9 @@ func TestNameReferenceClusterWide(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": orgname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": orgname,
},
"subjects": []interface{}{
map[string]interface{}{
@@ -816,7 +807,7 @@ func TestNameReferenceClusterWide(t *testing.T) {
},
}}).ResMap()
expected := resmaptest_test.NewSeededRmBuilder(t, rf, m.ShallowCopy()).
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
ReplaceResource(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
@@ -845,9 +836,9 @@ func TestNameReferenceClusterWide(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": modifiedname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": modifiedname,
},
// The following tests required a change in
// getNameFunc implementation in order to leverage
@@ -898,9 +889,7 @@ func TestNameReferenceClusterWide(t *testing.T) {
// object with the same original names (uniquename) in different namespaces
// and with different current Id.
func TestNameReferenceNamespaceTransformation(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmaptest_test.NewRmBuilder(t, rf).
m := resmaptest_test.NewRmBuilderDefault(t).
AddWithNsAndName(ns4, orgname, map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -937,9 +926,9 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": orgname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": orgname,
},
"subjects": []interface{}{
map[string]interface{}{
@@ -964,7 +953,7 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
},
}}).ResMap()
expected := resmaptest_test.NewSeededRmBuilder(t, rf, m.ShallowCopy()).
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
ReplaceResource(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
@@ -973,9 +962,9 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": modifiedname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": modifiedname,
},
// The following tests required a change in
// getNameFunc implementation in order to leverage
@@ -1026,9 +1015,7 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
// It validates the change done is IsSameFuzzyNamespace which
// uses the IsNsEquals method instead of the simple == operator.
func TestNameReferenceCandidateSelection(t *testing.T) {
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmaptest_test.NewRmBuilder(t, rf).
m := resmaptest_test.NewRmBuilderDefault(t).
AddWithName("cm1", map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -1045,7 +1032,7 @@ func TestNameReferenceCandidateSelection(t *testing.T) {
AddWithName("deploy1", deploymentMap("", "p1-deploy1", "cm1", "secret1")).
ResMap()
expected := resmaptest_test.NewSeededRmBuilder(t, rf, m.ShallowCopy()).
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
ReplaceResource(deploymentMap("", "p1-deploy1", "p1-cm1-hash", "p1-secret1-hash")).
ResMap()

View File

@@ -7,10 +7,8 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
"sigs.k8s.io/kustomize/api/types"
)
@@ -46,8 +44,7 @@ func TestRefVarTransformer(t *testing.T) {
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/interface"},
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/num"},
},
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
res: resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -77,8 +74,7 @@ func TestRefVarTransformer(t *testing.T) {
}}).ResMap(),
},
expected: expected{
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
res: resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -116,8 +112,7 @@ func TestRefVarTransformer(t *testing.T) {
fs: []types.FieldSpec{
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/slice"},
},
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
res: resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -138,8 +133,7 @@ func TestRefVarTransformer(t *testing.T) {
fs: []types.FieldSpec{
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/nil"},
},
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
res: resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -151,8 +145,7 @@ func TestRefVarTransformer(t *testing.T) {
}}).ResMap(),
},
expected: expected{
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
res: resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",

View File

@@ -12,7 +12,7 @@ import (
. "sigs.k8s.io/kustomize/api/internal/accumulator"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
@@ -20,16 +20,14 @@ import (
"sigs.k8s.io/kustomize/api/types"
)
func makeResAccumulator(t *testing.T) (*ResAccumulator, *resource.Factory) {
func makeResAccumulator(t *testing.T) *ResAccumulator {
ra := MakeEmptyAccumulator()
err := ra.MergeConfig(builtinconfig.MakeDefaultConfig())
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
err = ra.AppendAll(
resmaptest_test.NewRmBuilder(t, rf).
resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -66,11 +64,11 @@ func makeResAccumulator(t *testing.T) (*ResAccumulator, *resource.Factory) {
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
return ra, rf
return ra
}
func TestResolveVarsHappy(t *testing.T) {
ra, _ := makeResAccumulator(t)
ra := makeResAccumulator(t)
err := ra.MergeVars([]types.Var{
{
Name: "SERVICE_ONE",
@@ -99,7 +97,7 @@ func TestResolveVarsHappy(t *testing.T) {
}
func TestResolveVarsOneUnused(t *testing.T) {
ra, _ := makeResAccumulator(t)
ra := makeResAccumulator(t)
err := ra.MergeVars([]types.Var{
{
Name: "SERVICE_ONE",
@@ -140,11 +138,10 @@ func expectLog(t *testing.T, log bytes.Buffer, expect string) {
}
func TestResolveVarsVarNeedsDisambiguation(t *testing.T) {
ra, rf := makeResAccumulator(t)
ra := makeResAccumulator(t)
rm0 := resmap.New()
err := rm0.Append(
rf.FromMap(
provider.NewDefaultDepProvider().GetResourceFactory().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -213,8 +210,7 @@ func makeVarToNamepaceAndPath(
}
func TestResolveVarConflicts(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
rf := provider.NewDefaultDepProvider().GetResourceFactory()
// create configmaps in foo and bar namespaces with `data.provider` values.
fooAws := makeNamespacedConfigMapWithDataProviderValue("foo", "aws")
barAws := makeNamespacedConfigMapWithDataProviderValue("bar", "aws")
@@ -261,7 +257,7 @@ func TestResolveVarConflicts(t *testing.T) {
}
func TestResolveVarsGoodResIdBadField(t *testing.T) {
ra, _ := makeResAccumulator(t)
ra := makeResAccumulator(t)
err := ra.MergeVars([]types.Var{
{
Name: "SERVICE_ONE",
@@ -286,7 +282,7 @@ func TestResolveVarsGoodResIdBadField(t *testing.T) {
}
func TestResolveVarsUnmappableVar(t *testing.T) {
ra, _ := makeResAccumulator(t)
ra := makeResAccumulator(t)
err := ra.MergeVars([]types.Var{
{
Name: "SERVICE_THREE",
@@ -310,7 +306,7 @@ func TestResolveVarsUnmappableVar(t *testing.T) {
}
func TestResolveVarsWithNoambiguation(t *testing.T) {
ra1, rf := makeResAccumulator(t)
ra1 := makeResAccumulator(t)
err := ra1.MergeVars([]types.Var{
{
Name: "SERVICE_ONE",
@@ -327,7 +323,7 @@ func TestResolveVarsWithNoambiguation(t *testing.T) {
// Create another accumulator having a resource with different prefix
ra2 := MakeEmptyAccumulator()
m := resmaptest_test.NewRmBuilder(t, rf).
m := resmaptest_test.NewRmBuilderDefault(t).
Add(map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",

View File

@@ -7,14 +7,13 @@ import (
"sort"
"strings"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
var fileReader = kunstruct.NewKunstructuredFactoryImpl()
// This document is meant to be used at the elasticsearch document type.
// Fields are serialized as-is to elasticsearch, where indices are built
// to facilitate text search queries. Identifiers, Values, FilePath,
@@ -42,6 +41,7 @@ type KustomizationDocument struct {
Kinds []string `json:"kinds,omitempty"`
Identifiers []string `json:"identifiers,omitempty"`
Values []string `json:"values,omitempty"`
resFactory *resource.Factory
}
type set map[string]struct{}
@@ -52,6 +52,7 @@ func (doc *KustomizationDocument) Copy() *KustomizationDocument {
Kinds: doc.Kinds,
Identifiers: doc.Identifiers,
Values: doc.Values,
resFactory: provider.NewDefaultDepProvider().GetResourceFactory(),
}
}
@@ -150,7 +151,7 @@ func (doc *KustomizationDocument) readBytes() ([]map[string]interface{}, error)
}
configs := make([]map[string]interface{}, 0)
ks, err := fileReader.SliceFromBytes(data)
ks, err := doc.resFactory.SliceFromBytes(data)
if err != nil {
return nil, fmt.Errorf("unable to parse resource: %v", err)
}

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/api/internal/crawl
go 1.14
go 1.15
require (
github.com/elastic/go-elasticsearch/v6 v6.8.5

View File

@@ -206,8 +206,10 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:Fecb
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
@@ -315,6 +317,7 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
@@ -527,8 +530,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.4 h1:DDuzZtjIzFqp2IPy4DTyCI69Cl3bDgcJODjI6sjF9NY=
sigs.k8s.io/kustomize/kyaml v0.9.4/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -0,0 +1,51 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators
import (
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// MakeConfigMap makes a configmap.
//
// ConfigMap: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#configmap-v1-core
//
// ConfigMaps and Secrets are similar.
//
// Both objects have a `data` field, which contains a map from keys to
// values that must be UTF-8 valid strings. Such data might be simple text,
// or whoever made the data may have done so by performing a base64 encoding
// on binary data. Regardless, k8s has no means to know this, so it treats
// the data field as a string.
//
// The ConfigMap has an additional field `binaryData`, also a map, but its
// values are _intended_ to be interpreted as a base64 encoding of []byte,
// by whatever makes use of the ConfigMap.
//
// In a ConfigMap, any key used in `data` cannot also be used in `binaryData`
// and vice-versa. A key must be unique across both maps.
func MakeConfigMap(
ldr ifc.KvLoader, args *types.ConfigMapArgs) (rn *yaml.RNode, err error) {
rn, err = makeBaseNode("ConfigMap", args.Name, args.Namespace)
if err != nil {
return nil, err
}
m, err := makeValidatedDataMap(ldr, args.Name, args.KvPairSources)
if err != nil {
return nil, err
}
for _, k := range filtersutil.SortedMapKeys(m) {
fldName, vrN := makeConfigMapValueRNode(m[k])
if _, err = rn.Pipe(
yaml.LookupCreate(yaml.MappingNode, fldName),
yaml.SetField(k, vrN)); err != nil {
return nil, err
}
}
copyLabelsAndAnnotations(rn, args.Options)
return rn, err
}

View File

@@ -0,0 +1,223 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators_test
import (
"path/filepath"
"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"
)
var binaryHello = []byte{
0xff, // non-utf8
0x68, // h
0x65, // e
0x6c, // l
0x6c, // l
0x6f, // o
}
func manyHellos(count int) (result []byte) {
for i := 0; i < count; i++ {
result = append(result, binaryHello...)
}
return
}
func TestMakeConfigMap(t *testing.T) {
type expected struct {
out string
errMsg string
}
testCases := map[string]struct {
args types.ConfigMapArgs
exp expected
}{
"construct config map from env": {
args: types.ConfigMapArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "envConfigMap",
KvPairSources: types.KvPairSources{
EnvSources: []string{
filepath.Join("configmap", "app.env"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: ConfigMap
metadata:
name: envConfigMap
data:
DB_PASSWORD: qwerty
DB_USERNAME: admin
`,
},
},
"construct config map from text file": {
args: types.ConfigMapArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "fileConfigMap1",
KvPairSources: types.KvPairSources{
FileSources: []string{
filepath.Join("configmap", "app-init.ini"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: ConfigMap
metadata:
name: fileConfigMap1
data:
app-init.ini: |
FOO=bar
BAR=baz
`,
},
},
"construct config map from text and binary file": {
args: types.ConfigMapArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "fileConfigMap2",
KvPairSources: types.KvPairSources{
FileSources: []string{
filepath.Join("configmap", "app-init.ini"),
filepath.Join("configmap", "app.bin"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: ConfigMap
metadata:
name: fileConfigMap2
data:
app-init.ini: |
FOO=bar
BAR=baz
binaryData:
app.bin: |
/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbG
xv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hl
bGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv/2
hlbGxv/2hlbGxv/2hlbGxv/2hlbGxv
`,
},
},
"construct config map from literal": {
args: types.ConfigMapArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "literalConfigMap1",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"},
},
Options: &types.GeneratorOptions{
Labels: map[string]string{
"foo": "bar",
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: ConfigMap
metadata:
name: literalConfigMap1
labels:
foo: 'bar'
data:
a: x
b: y
c: Hello World
d: "true"
`,
},
},
"construct config map from literal with GeneratorOptions in ConfigMapArgs": {
args: types.ConfigMapArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "literalConfigMap2",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"},
},
Options: &types.GeneratorOptions{
Labels: map[string]string{
"veggie": "celery",
"dog": "beagle",
"cat": "annoying",
},
Annotations: map[string]string{
"river": "Missouri",
"city": "Iowa City",
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: ConfigMap
metadata:
name: literalConfigMap2
labels:
cat: 'annoying'
dog: 'beagle'
veggie: 'celery'
annotations:
city: 'Iowa City'
river: 'Missouri'
data:
a: x
b: y
c: Hello World
d: "true"
`,
},
},
}
fSys := filesys.MakeFsInMemory()
fSys.WriteFile(
filesys.RootedPath("configmap", "app.env"),
[]byte("DB_USERNAME=admin\nDB_PASSWORD=qwerty\n"))
fSys.WriteFile(
filesys.RootedPath("configmap", "app-init.ini"),
[]byte("FOO=bar\nBAR=baz\n"))
fSys.WriteFile(
filesys.RootedPath("configmap", "app.bin"),
manyHellos(30))
kvLdr := kv.NewLoader(
loader.NewFileLoaderAtRoot(fSys),
valtest_test.MakeFakeValidator())
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
rn, err := MakeConfigMap(kvLdr, &tc.args)
if err != nil {
if !assert.EqualError(t, err, tc.exp.errMsg) {
t.FailNow()
}
return
}
if tc.exp.errMsg != "" {
t.Fatalf("%s: should return error '%s'", n, tc.exp.errMsg)
}
output := rn.MustString()
if !assert.Equal(t, tc.exp.out, output) {
t.FailNow()
}
})
}
}

View File

@@ -0,0 +1,60 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators
import (
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// MakeSecret makes a kubernetes Secret.
//
// Secret: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#secret-v1-core
//
// ConfigMaps and Secrets are similar.
//
// Like a ConfigMap, a Secret has a `data` field, but unlike a ConfigMap it has
// no `binaryData` field.
//
// All of a Secret's data is assumed to be opaque in nature, and assumed to be
// base64 encoded from its original representation, regardless of whether the
// original data was UTF-8 text or binary.
//
// This encoding provides no secrecy. It's just a neutral, common means to
// represent opaque text and binary data. Beneath the base64 encoding
// is presumably further encoding under control of the Secret's consumer.
//
// A Secret has string field `type` which holds an identifier, used by the
// client, to choose the algorithm to interpret the `data` field. Kubernetes
// cannot make use of this data; it's up to a controller or some pod's service
// to interpret the value, using `type` as a clue as to how to do this.
func MakeSecret(
ldr ifc.KvLoader, args *types.SecretArgs) (rn *yaml.RNode, err error) {
rn, err = makeBaseNode("Secret", args.Name, args.Namespace)
if err != nil {
return nil, err
}
if _, err := rn.Pipe(
yaml.FieldSetter{
Name: "type",
Value: yaml.NewStringRNode("Opaque")}); err != nil {
return nil, err
}
m, err := makeValidatedDataMap(ldr, args.Name, args.KvPairSources)
if err != nil {
return nil, err
}
for _, k := range filtersutil.SortedMapKeys(m) {
vrN := makeSecretValueRNode(m[k])
if _, err = rn.Pipe(
yaml.LookupCreate(yaml.MappingNode, yaml.DataField),
yaml.SetField(k, vrN)); err != nil {
return nil, err
}
}
copyLabelsAndAnnotations(rn, args.Options)
return rn, err
}

View File

@@ -0,0 +1,203 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators_test
import (
"path/filepath"
"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"
)
func TestMakeSecret(t *testing.T) {
type expected struct {
out string
errMsg string
}
testCases := map[string]struct {
args types.SecretArgs
exp expected
}{
"construct secret from env": {
args: types.SecretArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "envSecret",
KvPairSources: types.KvPairSources{
EnvSources: []string{
filepath.Join("secret", "app.env"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: Secret
metadata:
name: envSecret
type: Opaque
data:
DB_PASSWORD: cXdlcnR5
DB_USERNAME: YWRtaW4=
`,
},
},
"construct secret from text file": {
args: types.SecretArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "fileSecret1",
KvPairSources: types.KvPairSources{
FileSources: []string{
filepath.Join("secret", "app-init.ini"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: Secret
metadata:
name: fileSecret1
type: Opaque
data:
app-init.ini: Rk9PPWJhcgpCQVI9YmF6Cg==
`,
},
},
"construct secret from text and binary file": {
args: types.SecretArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "fileSecret2",
KvPairSources: types.KvPairSources{
FileSources: []string{
filepath.Join("secret", "app-init.ini"),
filepath.Join("secret", "app.bin"),
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: Secret
metadata:
name: fileSecret2
type: Opaque
data:
app-init.ini: Rk9PPWJhcgpCQVI9YmF6Cg==
app.bin: //0=
`,
},
},
"construct secret from literal": {
args: types.SecretArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "literalSecret1",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"},
},
Options: &types.GeneratorOptions{
Labels: map[string]string{
"foo": "bar",
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: Secret
metadata:
name: literalSecret1
labels:
foo: 'bar'
type: Opaque
data:
a: eA==
b: eQ==
c: SGVsbG8gV29ybGQ=
d: dHJ1ZQ==
`,
},
},
"construct secret from literal with GeneratorOptions in SecretArgs": {
args: types.SecretArgs{
GeneratorArgs: types.GeneratorArgs{
Name: "literalSecret2",
KvPairSources: types.KvPairSources{
LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"},
},
Options: &types.GeneratorOptions{
Labels: map[string]string{
"veggie": "celery",
"dog": "beagle",
"cat": "annoying",
},
Annotations: map[string]string{
"river": "Missouri",
"city": "Iowa City",
},
},
},
},
exp: expected{
out: `apiVersion: v1
kind: Secret
metadata:
name: literalSecret2
labels:
cat: 'annoying'
dog: 'beagle'
veggie: 'celery'
annotations:
city: 'Iowa City'
river: 'Missouri'
type: Opaque
data:
a: eA==
b: eQ==
c: SGVsbG8gV29ybGQ=
d: dHJ1ZQ==
`,
},
},
}
fSys := filesys.MakeFsInMemory()
fSys.WriteFile(
filesys.RootedPath("secret", "app.env"),
[]byte("DB_USERNAME=admin\nDB_PASSWORD=qwerty\n"))
fSys.WriteFile(
filesys.RootedPath("secret", "app-init.ini"),
[]byte("FOO=bar\nBAR=baz\n"))
fSys.WriteFile(
filesys.RootedPath("secret", "app.bin"),
[]byte{0xff, 0xfd})
kvLdr := kv.NewLoader(
loader.NewFileLoaderAtRoot(fSys),
valtest_test.MakeFakeValidator())
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
rn, err := MakeSecret(kvLdr, &tc.args)
if err != nil {
if !assert.EqualError(t, err, tc.exp.errMsg) {
t.FailNow()
}
return
}
if tc.exp.errMsg != "" {
t.Fatalf("%s: should return error '%s'", n, tc.exp.errMsg)
}
output := rn.MustString()
if !assert.Equal(t, tc.exp.out, output) {
t.FailNow()
}
})
}
}

View File

@@ -0,0 +1,139 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators
import (
"encoding/base64"
"fmt"
"strings"
"unicode/utf8"
"github.com/go-errors/errors"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func makeBaseNode(kind, name, namespace string) (*yaml.RNode, error) {
rn, err := yaml.Parse(fmt.Sprintf(`
apiVersion: v1
kind: %s
`, kind))
if err != nil {
return nil, err
}
if name == "" {
return nil, errors.Errorf("a configmap must have a name")
}
if _, err := rn.Pipe(yaml.SetK8sName(name)); err != nil {
return nil, err
}
if namespace != "" {
if _, err := rn.Pipe(yaml.SetK8sNamespace(namespace)); err != nil {
return nil, err
}
}
return rn, nil
}
func makeValidatedDataMap(
ldr ifc.KvLoader, name string, sources types.KvPairSources) (map[string]string, error) {
pairs, err := ldr.Load(sources)
if err != nil {
return nil, errors.WrapPrefix(err, "loading KV pairs", 0)
}
knownKeys := make(map[string]string)
for _, p := range pairs {
// legal key: alphanumeric characters, '-', '_' or '.'
if err := ldr.Validator().ErrIfInvalidKey(p.Key); err != nil {
return nil, err
}
if _, ok := knownKeys[p.Key]; ok {
return nil, errors.Errorf(
"configmap %s illegally repeats the key `%s`", name, p.Key)
}
knownKeys[p.Key] = p.Value
}
return knownKeys, nil
}
// copyLabelsAndAnnotations copies labels and annotations from
// GeneratorOptions into the given object.
func copyLabelsAndAnnotations(
rn *yaml.RNode, opts *types.GeneratorOptions) error {
if opts == nil {
return nil
}
for _, k := range filtersutil.SortedMapKeys(opts.Labels) {
v := opts.Labels[k]
if _, err := rn.Pipe(yaml.SetLabel(k, v)); err != nil {
return err
}
}
for _, k := range filtersutil.SortedMapKeys(opts.Annotations) {
v := opts.Annotations[k]
if _, err := rn.Pipe(yaml.SetAnnotation(k, v)); err != nil {
return err
}
}
return nil
}
// In a secret, all data is base64 encoded, regardless of its conformance
// or lack thereof to UTF-8.
func makeSecretValueRNode(s string) *yaml.RNode {
yN := &yaml.Node{Kind: yaml.ScalarNode}
// Purposely don't use YAML tags to identify the data as being plain text or
// binary. It kubernetes Secrets the values in the `data` map are expected
// to be base64 encoded, and in ConfigMaps that same can be said for the
// values in the `binaryData` field.
yN.Tag = yaml.NodeTagString
yN.Value = encodeBase64(s)
if strings.Contains(yN.Value, "\n") {
yN.Style = yaml.LiteralStyle
}
return yaml.NewRNode(yN)
}
func makeConfigMapValueRNode(s string) (field string, rN *yaml.RNode) {
yN := &yaml.Node{Kind: yaml.ScalarNode}
yN.Tag = yaml.NodeTagString
if utf8.ValidString(s) {
field = yaml.DataField
yN.Value = s
} else {
field = yaml.BinaryDataField
yN.Value = encodeBase64(s)
}
if strings.Contains(yN.Value, "\n") {
yN.Style = yaml.LiteralStyle
}
return field, yaml.NewRNode(yN)
}
// encodeBase64 encodes s as base64 that is broken up into multiple lines
// as appropriate for the resulting length.
func encodeBase64(s string) string {
const lineLen = 70
encLen := base64.StdEncoding.EncodedLen(len(s))
lines := encLen/lineLen + 1
buf := make([]byte, encLen*2+lines)
in := buf[0:encLen]
out := buf[encLen:]
base64.StdEncoding.Encode(in, []byte(s))
k := 0
for i := 0; i < len(in); i += lineLen {
j := i + lineLen
if j > len(in) {
j = len(in)
}
k += copy(out[k:], in[i:j])
if lines > 1 {
out[k] = '\n'
k++
}
}
return string(out[:k])
}

View File

@@ -23,11 +23,12 @@ func _() {
_ = x[ReplicaCountTransformer-12]
_ = x[SecretGenerator-13]
_ = x[ValueAddTransformer-14]
_ = x[HelmChartInflationGenerator-15]
}
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformer"
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGenerator"
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289}
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289, 316}
func (i BuiltinPluginType) String() string {
if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) {

View File

@@ -27,6 +27,7 @@ const (
ReplicaCountTransformer
SecretGenerator
ValueAddTransformer
HelmChartInflationGenerator
)
var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType
@@ -55,8 +56,9 @@ func GetBuiltinPluginType(n string) BuiltinPluginType {
}
var GeneratorFactories = map[BuiltinPluginType]func() resmap.GeneratorPlugin{
ConfigMapGenerator: builtins.NewConfigMapGeneratorPlugin,
SecretGenerator: builtins.NewSecretGeneratorPlugin,
ConfigMapGenerator: builtins.NewConfigMapGeneratorPlugin,
SecretGenerator: builtins.NewSecretGeneratorPlugin,
HelmChartInflationGenerator: builtins.NewHelmChartInflationGeneratorPlugin,
}
var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin{

View File

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

View File

@@ -13,12 +13,10 @@ import (
. "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"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
)
func TestExecPluginConfig(t *testing.T) {
@@ -33,10 +31,8 @@ s/$BAR/bar baz/g
if err != nil {
t.Fatal(err)
}
rf := resmap.NewFactory(
resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl()), nil)
v := valtest_test.MakeFakeValidator()
pvd := provider.NewDefaultDepProvider()
rf := resmap.NewFactory(pvd.GetResourceFactory(), pvd.GetMerginator())
pluginConfig := rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "someteam.example.com/v1",
@@ -62,7 +58,7 @@ s/$BAR/bar baz/g
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
p.Config(resmap.NewPluginHelpers(ldr, v, rf), yaml)
p.Config(resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf), yaml)
expected := "someteam.example.com/v1/sedtransformer/SedTransformer"
if !strings.HasSuffix(p.Path(), expected) {

View File

@@ -8,11 +8,10 @@ import (
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
@@ -51,8 +50,8 @@ func TestLoader(t *testing.T) {
BuildGoPlugin("builtin", "", "SecretGenerator").
BuildGoPlugin("someteam.example.com", "v1", "SomeServiceGenerator")
defer th.Reset()
rmF := resmap.NewFactory(resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl()), nil)
p := provider.NewDefaultDepProvider()
rmF := resmap.NewFactory(p.GetResourceFactory(), p.GetMerginator())
fLdr, err := loader.NewLoader(
loader.RestrictionRootOnly,
filesys.Separator, filesys.MakeFsInMemory())

View File

@@ -9,9 +9,10 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"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"
@@ -64,7 +65,7 @@ func strptr(s string) *string {
}
func TestUpdateResourceOptions(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
rf := provider.NewDefaultDepProvider().GetResourceFactory()
in := resmap.New()
expected := resmap.New()
cases := []struct {
@@ -87,28 +88,12 @@ func TestUpdateResourceOptions(t *testing.T) {
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
}
actual, err := UpdateResourceOptions(in)
if err != nil {
t.Fatalf("unexpected error: %v", err.Error())
}
for i, a := range expected.Resources() {
b := actual.GetByIndex(i)
if b == nil {
t.Fatalf("resource %d missing from processed map", i)
}
if !a.Equals(b) {
t.Errorf("expected %v got %v", a, b)
}
if a.NeedHashSuffix() != b.NeedHashSuffix() {
t.Errorf("")
}
if a.Behavior() != b.Behavior() {
t.Errorf("expected %v got %v", a.Behavior(), b.Behavior())
}
}
assert.NoError(t, err)
assert.NoError(t, expected.ErrorIfNotEqualLists(actual))
}
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
rf := provider.NewDefaultDepProvider().GetResourceFactory()
cases := []string{
"",
"FaLsE",

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"strings"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/ifc"
@@ -234,7 +235,18 @@ func (kt *KustTarget) runGenerators(
func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error) {
ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, kt.kustomization.Generators)
var generatorPaths []string
for _, p := range kt.kustomization.Generators {
// handle inline generators
rm, err := kt.rFactory.NewResMapFromBytes([]byte(p))
if err != nil {
// not an inline config
generatorPaths = append(generatorPaths, p)
continue
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, generatorPaths)
if err != nil {
return nil, err
}
@@ -259,7 +271,18 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]resmap.Transformer, error) {
ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, transformers)
var transformerPaths []string
for _, p := range transformers {
// handle inline transformers
rm, err := kt.rFactory.NewResMapFromBytes([]byte(p))
if err != nil {
// not an inline config
transformerPaths = append(transformerPaths, p)
continue
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, transformerPaths)
if err != nil {
return nil, err
@@ -313,12 +336,18 @@ func (kt *KustTarget) accumulateResources(
if errF := kt.accumulateFile(ra, path); errF != nil {
ldr, errL := kt.ldr.New(path)
if errL != nil {
return nil, fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL)
return nil, multierror.Append(
fmt.Errorf("accumulateFile error: %q", errF),
fmt.Errorf("loader.New error: %q", errL),
)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, false)
if errD != nil {
return nil, fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD)
return nil, multierror.Append(
fmt.Errorf("accumulateFile error: %q", errF),
fmt.Errorf("accumulateDirector error: %q", errD),
)
}
}
}

View File

@@ -32,6 +32,7 @@ func (kt *KustTarget) configureBuiltinGenerators() (
for _, bpt := range []builtinhelpers.BuiltinPluginType{
builtinhelpers.ConfigMapGenerator,
builtinhelpers.SecretGenerator,
builtinhelpers.HelmChartInflationGenerator,
} {
r, err := generatorConfigurators[bpt](
kt, bpt, builtinhelpers.GeneratorFactories[bpt])
@@ -110,6 +111,23 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func(
}
return
},
builtinhelpers.HelmChartInflationGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) (
result []resmap.Generator, err error) {
var c struct {
types.HelmChartArgs
}
for _, args := range kt.kustomization.HelmChartInflationGenerator {
c.HelmChartArgs = args
p := f()
err := kt.configureBuiltinPlugin(p, c, bpt)
if err != nil {
return nil, err
}
result = append(result, p)
}
return
},
}
type tFactory func() resmap.TransformerPlugin
@@ -141,12 +159,12 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Target types.PatchTarget `json:"target,omitempty" yaml:"target,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
JsonOp string `json:"jsonOp,omitempty" yaml:"jsonOp,omitempty"`
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
JsonOp string `json:"jsonOp,omitempty" yaml:"jsonOp,omitempty"`
}
for _, args := range kt.kustomization.PatchesJson6902 {
c.Target = *args.Target
c.Target = args.Target
c.Path = args.Path
c.JsonOp = args.Patch
p := f()

View File

@@ -8,9 +8,10 @@ import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
@@ -76,8 +77,7 @@ commonLabels:
}
kt := makeKustTargetWithRf(
t, th.GetFSys(), "/",
resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()))
t, th.GetFSys(), "/", provider.NewDefaultDepProvider())
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th.WriteK("/", tc.content)
@@ -148,7 +148,8 @@ metadata:
{"op": "add", "path": "/spec/replica", "value": "3"}
]`)
resFactory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
pvd := provider.NewDefaultDepProvider()
resFactory := pvd.GetResourceFactory()
resources := []*resource.Resource{
resFactory.FromMapWithName("dply1", map[string]interface{}{
@@ -243,19 +244,14 @@ metadata:
t.Fatalf("unexpected error %v", err)
}
}
expYaml, err := expected.AsYaml()
assert.NoError(t, err)
kt := makeKustTargetWithRf(
t, th.GetFSys(), "/whatever", resFactory)
err := kt.Load()
if err != nil {
t.Fatalf("unexpected Resources error %v", err)
}
kt := makeKustTargetWithRf(t, th.GetFSys(), "/whatever", pvd)
assert.NoError(t, kt.Load())
actual, err := kt.MakeCustomizedResMap()
if err != nil {
t.Fatalf("unexpected Resources error %v", err)
}
if err = expected.ErrorIfNotEqualLists(actual); err != nil {
t.Fatalf("unexpected inequality: %v", err)
}
assert.NoError(t, err)
actYaml, err := actual.AsYaml()
assert.NoError(t, err)
assert.Equal(t, expYaml, actYaml)
}

View File

@@ -7,14 +7,12 @@ import (
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/k8sdeps/merge"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
)
@@ -22,9 +20,7 @@ func makeAndLoadKustTarget(
t *testing.T,
fSys filesys.FileSystem,
root string) *target.KustTarget {
kt := makeKustTargetWithRf(
t, fSys, root,
resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()))
kt := makeKustTargetWithRf(t, fSys, root, provider.NewDefaultDepProvider())
if err := kt.Load(); err != nil {
t.Fatalf("Unexpected load error %v", err)
}
@@ -35,13 +31,12 @@ func makeKustTargetWithRf(
t *testing.T,
fSys filesys.FileSystem,
root string,
resourceFactory *resource.Factory) *target.KustTarget {
pvd *provider.DepProvider) *target.KustTarget {
ldr, err := fLdr.NewLoader(fLdr.RestrictionRootOnly, root, fSys)
if err != nil {
t.Fatal(err)
}
rf := resmap.NewFactory(
resourceFactory, merge.NewMerginator(resourceFactory))
rf := resmap.NewFactory(pvd.GetResourceFactory(), pvd.GetMerginator())
pc := konfig.DisabledPluginConfig()
return target.NewKustTarget(
ldr,

View File

@@ -26,13 +26,15 @@ func newMultiTransformer(t []resmap.Transformer) resmap.Transformer {
return r
}
// Transform prepends the name prefix.
// Transform applies the member transformers in order to the resources,
// optionally detecting and erroring on commutation conflict.
func (o *multiTransformer) Transform(m resmap.ResMap) error {
if o.checkConflictEnabled {
return o.transformWithCheckConflict(m)
}
return o.transform(m)
}
func (o *multiTransformer) transform(m resmap.ResMap) error {
for _, t := range o.transformers {
err := t.Transform(m)

View File

@@ -21,5 +21,5 @@ import (
// major version increments in pluginator with each
// api release to allow this trick to work and not
// introduce cycles.
// _ "sigs.k8s.io/kustomize/pluginator/v2"
// _ "sigs.k8s.io/kustomize/cmd/pluginator/v2"
)

View File

@@ -4,38 +4,105 @@
package wrappy
import (
"fmt"
"sigs.k8s.io/kustomize/api/hasher"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/generators"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// WNodeFactory makes instances of WNode.
//
// These instances in turn adapt
// sigs.k8s.io/kustomize/kyaml/yaml.RNode
// to implement ifc.Unstructured.
// This factory is meant to implement ifc.KunstructuredFactory.
//
// This implementation should be thin, as both WNode and WNodeFactory must be
// factored away (deleted) along with ifc.Kunstructured in favor of direct use
// of RNode methods upon completion of
// https://github.com/kubernetes-sigs/kustomize/issues/2506.
//
// See also api/krusty/internal/provider/depprovider.go
type WNodeFactory struct {
}
var _ ifc.KunstructuredFactory = (*WNodeFactory)(nil)
func (k *WNodeFactory) SliceFromBytes(bs []byte) ([]ifc.Kunstructured, error) {
panic("TODO(#WNodeFactory): implement SliceFromBytes")
yamlRNodes, err := kio.FromBytes(bs)
if err != nil {
return nil, err
}
var result []ifc.Kunstructured
for i := range yamlRNodes {
rn := yamlRNodes[i]
meta, err := rn.GetValidatedMetadata()
if err != nil {
return nil, err
}
if !shouldDropObject(meta) {
if foundNil, path := rn.HasNilEntryInList(); foundNil {
return nil, fmt.Errorf("empty item at %v in object %v", path, rn)
}
result = append(result, FromRNode(rn))
}
}
return result, nil
}
// shouldDropObject returns true if the resource should not be accumulated.
func shouldDropObject(m yaml.ResourceMeta) bool {
_, y := m.ObjectMeta.Annotations[konfig.IgnoredByKustomizeResourceAnnotation]
return y
}
func (k *WNodeFactory) FromMap(m map[string]interface{}) ifc.Kunstructured {
panic("TODO(#WNodeFactory): implement FromMap")
rn, err := FromMap(m)
if err != nil {
// TODO(#WNodeFactory): handle or bubble error"
panic(err)
}
return rn
}
// kustHash computes a hash of an unstructured object.
type kustHash struct{}
// Hash returns a hash of the given object
func (h *kustHash) Hash(m ifc.Kunstructured) (string, error) {
node, err := filtersutil.GetRNode(m)
if err != nil {
return "", err
}
return hasher.HashRNode(node)
}
func (k *WNodeFactory) Hasher() ifc.KunstructuredHasher {
panic("TODO(#WNodeFactory): implement Hasher")
return &kustHash{}
}
// MakeConfigMap makes a wrapped configmap.
func (k *WNodeFactory) MakeConfigMap(
kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (ifc.Kunstructured, error) {
panic("TODO(#WNodeFactory): implement MakeConfigMap")
ldr ifc.KvLoader, args *types.ConfigMapArgs) (ifc.Kunstructured, error) {
rn, err := generators.MakeConfigMap(ldr, args)
if err != nil {
return nil, err
}
return FromRNode(rn), nil
}
// MakeSecret makes a wrapped secret.
func (k *WNodeFactory) MakeSecret(
kvLdr ifc.KvLoader, args *types.SecretArgs) (ifc.Kunstructured, error) {
panic("TODO(#WNodeFactory): implement MakeSecret")
ldr ifc.KvLoader, args *types.SecretArgs) (ifc.Kunstructured, error) {
rn, err := generators.MakeSecret(ldr, args)
if err != nil {
return nil, err
}
return FromRNode(rn), nil
}

View File

@@ -2,3 +2,320 @@
// SPDX-License-Identifier: Apache-2.0
package wrappy_test
import (
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/api/internal/wrappy"
)
func TestHasher(t *testing.T) {
input := `
apiVersion: v1
kind: ConfigMap
metadata:
name: foo
data:
one: ""
binaryData:
two: ""
`
expect := "698h7c7t9m"
factory := &WNodeFactory{}
k, err := factory.SliceFromBytes([]byte(input))
if err != nil {
t.Fatal(err)
}
hasher := factory.Hasher()
result, err := hasher.Hash(k[0])
if err != nil {
t.Fatal(err)
}
if result != expect {
t.Fatalf("expect %s but got %s", expect, result)
}
}
func TestSliceFromBytes(t *testing.T) {
factory := &WNodeFactory{}
testConfigMap :=
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "winnie",
},
}
testConfigMapList :=
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMapList",
"items": []interface{}{
testConfigMap,
testConfigMap,
},
}
testDeploymentSpec := map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"hostAliases": []interface{}{
map[string]interface{}{
"hostnames": []interface{}{
"a.example.com",
},
"ip": "8.8.8.8",
},
},
},
},
}
testDeploymentA := map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deployment-a",
},
"spec": testDeploymentSpec,
}
testDeploymentB := map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deployment-b",
},
"spec": testDeploymentSpec,
}
testDeploymentList :=
map[string]interface{}{
"apiVersion": "v1",
"kind": "DeploymentList",
"items": []interface{}{
testDeploymentA,
testDeploymentB,
},
}
type expected struct {
out []map[string]interface{}
isErr bool
}
testCases := map[string]struct {
input []byte
exp expected
}{
"garbage": {
input: []byte("garbageIn: garbageOut"),
exp: expected{
isErr: true,
},
},
"noBytes": {
input: []byte{},
exp: expected{
out: []map[string]interface{}{},
},
},
"goodJson": {
input: []byte(`
{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie"}}
`),
exp: expected{
out: []map[string]interface{}{testConfigMap},
},
},
"goodYaml1": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
exp: expected{
out: []map[string]interface{}{testConfigMap},
},
},
"goodYaml2": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
---
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
exp: expected{
out: []map[string]interface{}{testConfigMap, testConfigMap},
},
},
"localConfigYaml": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie-skip
annotations:
# this annotation causes the Resource to be ignored by kustomize
config.kubernetes.io/local-config: ""
---
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
exp: expected{
out: []map[string]interface{}{testConfigMap},
},
},
"garbageInOneOfTwoObjects": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
---
WOOOOOOOOOOOOOOOOOOOOOOOOT: woot
`),
exp: expected{
isErr: true,
},
},
"emptyObjects": {
input: []byte(`
---
#a comment
---
`),
exp: expected{
out: []map[string]interface{}{},
},
},
"Missing .metadata.name in object": {
input: []byte(`
apiVersion: v1
kind: Namespace
metadata:
annotations:
foo: bar
`),
exp: expected{
isErr: true,
},
},
"nil value in list": {
input: []byte(`
apiVersion: builtin
kind: ConfigMapGenerator
metadata:
name: kube100-site
labels:
app: web
testList:
- testA
-
`),
exp: expected{
isErr: true,
},
},
"List": {
input: []byte(`
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
- apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
exp: expected{
out: []map[string]interface{}{
testConfigMap,
testConfigMap},
},
},
"ConfigMapList": {
input: []byte(`
apiVersion: v1
kind: ConfigMapList
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
- apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
exp: expected{
out: []map[string]interface{}{testConfigMapList},
},
},
"listWithAnchors": {
input: []byte(`
apiVersion: v1
kind: DeploymentList
items:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-a
spec: &hostAliases
template:
spec:
hostAliases:
- hostnames:
- a.example.com
ip: 8.8.8.8
- apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-b
spec:
<<: *hostAliases
`),
exp: expected{
out: []map[string]interface{}{testDeploymentList},
},
},
}
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
rs, err := factory.SliceFromBytes(tc.input)
if err != nil {
assert.True(t, tc.exp.isErr)
return
}
assert.False(t, tc.exp.isErr)
assert.Equal(t, len(tc.exp.out), len(rs))
for i := range rs {
assert.Equal(
t, fmt.Sprintf("%v", tc.exp.out[i]), fmt.Sprintf("%v", rs[i].Map()))
if n != "listWithAnchors" {
// https://github.com/kubernetes-sigs/kustomize/issues/3271
if !reflect.DeepEqual(tc.exp.out[i], rs[i].Map()) {
t.Fatalf("%s:\nexpected: %v\n actual: %v",
n, tc.exp.out[i], rs[i].Map())
}
}
}
})
}
}

View File

@@ -4,7 +4,9 @@
package wrappy
import (
"fmt"
"log"
"strings"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/resid"
@@ -29,6 +31,14 @@ func NewWNode() *WNode {
return FromRNode(yaml.NewRNode(nil))
}
func FromMap(m map[string]interface{}) (*WNode, error) {
n, err := yaml.FromMap(m)
if err != nil {
return nil, err
}
return FromRNode(n), nil
}
func FromRNode(node *yaml.RNode) *WNode {
return &WNode{node: node}
}
@@ -54,10 +64,41 @@ func (wn *WNode) GetAnnotations() map[string]string {
// GetFieldValue implements ifc.Kunstructured.
func (wn *WNode) GetFieldValue(path string) (interface{}, error) {
// The argument is a json path, e.g. "metadata.name"
// fields := strings.Split(path, ".")
// return wn.node.Pipe(yaml.Lookup(fields...))
panic("TODO(#WNode): GetFieldValue; implement or drop from API")
fields := strings.Split(path, ".")
rn, err := wn.node.Pipe(yaml.Lookup(fields...))
if err != nil {
return nil, err
}
if rn == nil {
return nil, NoFieldError{path}
}
yn := rn.YNode()
// If this is an alias node, resolve it
if yn.Kind == yaml.AliasNode {
yn = yn.Alias
}
// Return value as map for DocumentNode and MappingNode kinds
if yn.Kind == yaml.DocumentNode || yn.Kind == yaml.MappingNode {
var result map[string]interface{}
if err := yn.Decode(&result); err != nil {
return nil, err
}
return result, err
}
// Return value as slice for SequenceNode kind
if yn.Kind == yaml.SequenceNode {
var result []interface{}
for _, node := range yn.Content {
result = append(result, node.Value)
}
return result, nil
}
// Return value value directly for all other (ScalarNode) kinds
return yn.Value, nil
}
// GetGvk implements ifc.Kunstructured.
@@ -83,18 +124,37 @@ func (wn *WNode) GetName() string {
}
// GetSlice implements ifc.Kunstructured.
func (wn *WNode) GetSlice(string) ([]interface{}, error) {
panic("TODO(#WNode) GetSlice; implement or drop from API")
func (wn *WNode) GetSlice(path string) ([]interface{}, error) {
value, err := wn.GetFieldValue(path)
if err != nil {
return nil, err
}
if sliceValue, ok := value.([]interface{}); ok {
return sliceValue, nil
}
return nil, fmt.Errorf("node %s is not a slice", path)
}
// GetSlice implements ifc.Kunstructured.
func (wn *WNode) GetString(string) (string, error) {
panic("TODO(#WNode) GetString; implement or drop from API")
func (wn *WNode) GetString(path string) (string, error) {
value, err := wn.GetFieldValue(path)
if err != nil {
return "", err
}
if v, ok := value.(string); ok {
return v, nil
}
return "", fmt.Errorf("node %s is not a string: %v", path, value)
}
// Map implements ifc.Kunstructured.
func (wn *WNode) Map() map[string]interface{} {
panic("TODO(#WNode) Map; implement or drop from API")
var result map[string]interface{}
if err := wn.node.YNode().Decode(&result); err != nil {
// Log and die since interface doesn't allow error.
log.Fatalf("failed to decode ynode: %v", err)
}
return result
}
// MarshalJSON implements ifc.Kunstructured.
@@ -103,41 +163,65 @@ func (wn *WNode) MarshalJSON() ([]byte, error) {
}
// MatchesAnnotationSelector implements ifc.Kunstructured.
func (wn *WNode) MatchesAnnotationSelector(string) (bool, error) {
panic("TODO(#WNode) MatchesAnnotationSelector; implement or drop from API")
func (wn *WNode) MatchesAnnotationSelector(selector string) (bool, error) {
return wn.node.MatchesAnnotationSelector(selector)
}
// MatchesLabelSelector implements ifc.Kunstructured.
func (wn *WNode) MatchesLabelSelector(string) (bool, error) {
panic("TODO(#WNode) MatchesLabelSelector; implement or drop from API")
func (wn *WNode) MatchesLabelSelector(selector string) (bool, error) {
return wn.node.MatchesLabelSelector(selector)
}
// SetAnnotations implements ifc.Kunstructured.
func (wn *WNode) SetAnnotations(map[string]string) {
panic("TODO(#WNode) SetAnnotations; implement or drop from API")
func (wn *WNode) SetAnnotations(annotations map[string]string) {
if err := wn.node.SetAnnotations(annotations); err != nil {
log.Fatal(err) // interface doesn't allow error.
}
}
// SetGvk implements ifc.Kunstructured.
func (wn *WNode) SetGvk(resid.Gvk) {
panic("TODO(#WNode) SetGvk; implement or drop from API")
func (wn *WNode) SetGvk(gvk resid.Gvk) {
wn.setMapField(yaml.NewScalarRNode(gvk.Kind), yaml.KindField)
wn.setMapField(
yaml.NewScalarRNode(
fmt.Sprintf("%s/%s", gvk.Group, gvk.Version)), yaml.APIVersionField)
}
// SetLabels implements ifc.Kunstructured.
func (wn *WNode) SetLabels(map[string]string) {
panic("TODO(#WNode) SetLabels; implement or drop from API")
func (wn *WNode) SetLabels(labels map[string]string) {
if err := wn.node.SetLabels(labels); err != nil {
log.Fatal(err) // interface doesn't allow error.
}
}
// SetName implements ifc.Kunstructured.
func (wn *WNode) SetName(string) {
panic("TODO(#WNode) SetName; implement or drop from API")
func (wn *WNode) SetName(name string) {
wn.setMapField(yaml.NewScalarRNode(name), yaml.MetadataField, yaml.NameField)
}
// SetNamespace implements ifc.Kunstructured.
func (wn *WNode) SetNamespace(string) {
panic("TODO(#WNode) SetNamespace; implement or drop from API")
func (wn *WNode) SetNamespace(ns string) {
if err := wn.node.SetNamespace(ns); err != nil {
log.Fatal(err) // interface doesn't allow error.
}
}
func (wn *WNode) setMapField(value *yaml.RNode, path ...string) {
if err := wn.node.SetMapField(value, path...); err != nil {
// Log and die since interface doesn't allow error.
log.Fatalf("failed to set field %v: %v", path, err)
}
}
// UnmarshalJSON implements ifc.Kunstructured.
func (wn *WNode) UnmarshalJSON(data []byte) error {
return wn.node.UnmarshalJSON(data)
}
type NoFieldError struct {
Field string
}
func (e NoFieldError) Error() string {
return fmt.Sprintf("no field named '%s'", e.Field)
}

View File

@@ -1,14 +1,15 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package wrappy_test
package wrappy
import (
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"gopkg.in/yaml.v3"
. "sigs.k8s.io/kustomize/api/internal/wrappy"
"sigs.k8s.io/kustomize/api/resid"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -337,3 +338,215 @@ func TestGettingFields(t *testing.T) {
t.Fatalf("unexpected annotations '%v'", actualMap)
}
}
func TestGetFieldValueReturnsMap(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
expected := map[string]interface{}{
"fruit": "apple",
"veggie": "carrot",
}
actual, err := wn.GetFieldValue("metadata.labels")
if err != nil {
t.Fatalf("error getting field value: %v", err)
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Fatalf("actual map does not deep equal expected map:\n%v", diff)
}
}
func TestGetFieldValueReturnsSlice(t *testing.T) {
bytes, err := yaml.Marshal(makeBigMap())
if err != nil {
t.Fatalf("unexpected yaml.Marshal err: %v", err)
}
rNode, err := kyaml.Parse(string(bytes))
if err != nil {
t.Fatalf("unexpected yaml.Marshal err: %v", err)
}
wn := FromRNode(rNode)
expected := []interface{}{"idx0", "idx1", "idx2", "idx3"}
actual, err := wn.GetFieldValue("that")
if err != nil {
t.Fatalf("error getting slice: %v", err)
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Fatalf("actual slice does not deep equal expected slice:\n%v", diff)
}
}
func TestGetFieldValueReturnsString(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
actual, err := wn.GetFieldValue("metadata.labels.fruit")
if err != nil {
t.Fatalf("error getting field value: %v", err)
}
v, ok := actual.(string)
if !ok || v != "apple" {
t.Fatalf("unexpected value '%v'", actual)
}
}
func TestGetFieldValueResolvesAlias(t *testing.T) {
yamlWithAlias := `
foo: &a theValue
bar: *a
`
rNode, err := kyaml.Parse(yamlWithAlias)
if err != nil {
t.Fatalf("unexpected yaml parse error: %v", err)
}
wn := FromRNode(rNode)
actual, err := wn.GetFieldValue("bar")
if err != nil {
t.Fatalf("error getting field value: %v", err)
}
v, ok := actual.(string)
if !ok || v != "theValue" {
t.Fatalf("unexpected value '%v'", actual)
}
}
func TestGetString(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
expected := "carrot"
actual, err := wn.GetString("metadata.labels.veggie")
if err != nil {
t.Fatalf("error getting string: %v", err)
}
if expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestGetSlice(t *testing.T) {
bytes, err := yaml.Marshal(makeBigMap())
if err != nil {
t.Fatalf("unexpected yaml.Marshal err: %v", err)
}
rNode, err := kyaml.Parse(string(bytes))
if err != nil {
t.Fatalf("unexpected yaml.Marshal err: %v", err)
}
wn := FromRNode(rNode)
expected := []interface{}{"idx0", "idx1", "idx2", "idx3"}
actual, err := wn.GetSlice("that")
if err != nil {
t.Fatalf("error getting slice: %v", err)
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Fatalf("actual slice does not deep equal expected slice:\n%v", diff)
}
}
func TestMap(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentLittleJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
expected := map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "homer",
"namespace": "simpsons",
},
}
actual := wn.Map()
if diff := cmp.Diff(expected, actual); diff != "" {
t.Fatalf("actual map does not deep equal expected map:\n%v", diff)
}
}
func TestSetName(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
wn.SetName("marge")
if expected, actual := "marge", wn.GetName(); expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestSetNamespace(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
wn.SetNamespace("flanders")
meta, _ := wn.node.GetMeta()
if expected, actual := "flanders", meta.Namespace; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestSetLabels(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
wn.SetLabels(map[string]string{
"label1": "foo",
"label2": "bar",
})
labels := wn.GetLabels()
if expected, actual := 2, len(labels); expected != actual {
t.Fatalf("expected '%d', got '%d'", expected, actual)
}
if expected, actual := "foo", labels["label1"]; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
if expected, actual := "bar", labels["label2"]; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestGetAnnotations(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
wn.SetAnnotations(map[string]string{
"annotation1": "foo",
"annotation2": "bar",
})
annotations := wn.GetAnnotations()
if expected, actual := 2, len(annotations); expected != actual {
t.Fatalf("expected '%d', got '%d'", expected, actual)
}
if expected, actual := "foo", annotations["annotation1"]; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
if expected, actual := "bar", annotations["annotation2"]; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestSetGvk(t *testing.T) {
wn := NewWNode()
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
t.Fatalf("unexpected unmarshaljson err: %v", err)
}
wn.SetGvk(resid.GvkFromString("grp_ver_knd"))
gvk := wn.GetGvk()
if expected, actual := "grp", gvk.Group; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
if expected, actual := "ver", gvk.Version; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
if expected, actual := "knd", gvk.Kind; expected != actual {
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}

View File

@@ -14,6 +14,7 @@ import (
"k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/k8sdeps/configmapandsecret"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
)
@@ -116,10 +117,6 @@ func (kf *KunstructuredFactoryImpl) validate(u unstructured.Unstructured) error
return nil
}
// nonKustomizableResourceAnnotation if set on a Resource will cause Kustomize to
// ignore the Resource rather than Kustomize it.
const ignoredByKustomizeResourceAnnotation = "config.kubernetes.io/local-config"
// skipResource returns true if the Resource should not be accumulated
func (kf *KunstructuredFactoryImpl) skipResource(u unstructured.Unstructured) bool {
an := u.GetAnnotations()
@@ -128,7 +125,7 @@ func (kf *KunstructuredFactoryImpl) skipResource(u unstructured.Unstructured) bo
return false
}
// check if the Resource has opt-ed out of kustomize
_, found := an[ignoredByKustomizeResourceAnnotation]
_, found := an[konfig.IgnoredByKustomizeResourceAnnotation]
return found
}

View File

@@ -238,6 +238,8 @@ nameReference:
kind: Ingress
- path: metadata/annotations/nginx.ingress.kubernetes.io\/auth-tls-secret
kind: Ingress
- path: spec/tls/secretName
kind: Ingress
- path: imagePullSecrets/name
kind: ServiceAccount
- path: parameters/secretName
@@ -256,6 +258,8 @@ nameReference:
kind: Service
group: serving.knative.dev
version: v1
- path: spec/azureFile/secretName
kind: PersistentVolume
- kind: Service
version: v1
@@ -267,6 +271,10 @@ nameReference:
kind: Ingress
- path: spec/backend/serviceName
kind: Ingress
- path: spec/rules/http/paths/backend/service/name
kind: Ingress
- path: spec/defaultBackend/service/name
kind: Ingress
- path: spec/service/name
kind: APIService
group: apiregistration.k8s.io
@@ -373,5 +381,12 @@ nameReference:
kind: Job
- path: spec/template/spec/priorityClassName
kind: DaemonSet
- kind: IngressClass
version: v1
group: networking.k8s.io/v1
fieldSpecs:
- path: spec/ingressClassName
kind: Ingress
`
)

View File

@@ -20,6 +20,10 @@ func DefaultKustomizationFileName() string {
}
const (
// FlagEnableKyamlDefaultValue is the default value for the --enable_kyaml
// flag. This value is also used in unit tests. See provider.DepProvider.
FlagEnableKyamlDefaultValue = false
// An environment variable to consult for kustomization
// configuration data. See:
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
@@ -31,6 +35,9 @@ const (
// A program name, for use in help, finding the XDG_CONFIG_DIR, etc.
ProgramName = "kustomize"
// If a resource has this annotation, kustomize will drop it.
IgnoredByKustomizeResourceAnnotation = "config.kubernetes.io/local-config"
// Label key that indicates the resources are built from Kustomize
ManagedbyLabelKey = "app.kubernetes.io/managed-by"

View File

@@ -9,6 +9,7 @@ import (
"runtime"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/types"
)
@@ -157,3 +158,15 @@ func pwdEnv() string {
}
return "PWD"
}
// GetBuiltinPluginNames returns a list of builtin plugin names
func GetBuiltinPluginNames() []string {
var ret []string
for k := range builtinhelpers.GeneratorFactories {
ret = append(ret, k.String())
}
for k := range builtinhelpers.TransformerFactories {
ret = append(ret, k.String())
}
return ret
}

View File

@@ -0,0 +1,103 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
/*
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
var expected string = `
apiVersion: v1
data:
rcon-password: Q0hBTkdFTUUh
kind: Secret
metadata:
labels:
app: test-minecraft
chart: minecraft-1.2.0
heritage: Helm
release: test
name: test-minecraft
type: Opaque
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
volume.alpha.kubernetes.io/storage-class: default
labels:
app: test-minecraft
chart: minecraft-1.2.0
heritage: Helm
release: test
name: test-minecraft-datadir
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
labels:
app: test-minecraft
chart: minecraft-1.2.0
heritage: Helm
release: test
name: test-minecraft
spec:
ports:
- name: minecraft
port: 25565
protocol: TCP
targetPort: minecraft
selector:
app: test-minecraft
type: LoadBalancer
`
func TestHelmChartInflationGenerator(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("/app", `
helmChartInflationGenerator:
- chartName: minecraft
chartRepoUrl: https://kubernetes-charts.storage.googleapis.com
chartVersion: v1.2.0
releaseName: test
releaseNamespace: testNamespace
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}
func TestHelmChartInflationGeneratorAsPlugin(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("/app", `
generators:
- helm.yaml
`)
th.WriteF("/app/helm.yaml", `
apiVersion: builtin
kind: HelmChartInflationGenerator
metadata:
name: myMap
chartName: minecraft
chartRepoUrl: https://kubernetes-charts.storage.googleapis.com
chartVersion: v1.2.0
releaseName: test
releaseNamespace: testNamespace
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}
*/

View File

@@ -0,0 +1,79 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestInlineTransformer(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteF("/app/resource.yaml", `
apiVersion: apps/v1
kind: ConfigMap
metadata:
name: whatever
data: {}
`)
th.WriteK("/app", `
resources:
- resource.yaml
transformers:
- |-
apiVersion: builtin
kind: NamespaceTransformer
metadata:
name: not-important-to-example
namespace: test
fieldSpecs:
- path: metadata/namespace
create: true
`)
expected := `
apiVersion: apps/v1
data: {}
kind: ConfigMap
metadata:
name: whatever
namespace: test
`
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}
func TestInlineGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
generators:
- |-
apiVersion: builtin
kind: ConfigMapGenerator
metadata:
name: mymap
literals:
- FRUIT=apple
- VEGETABLE=carrot
`)
expected := `
apiVersion: v1
data:
FRUIT: apple
VEGETABLE: carrot
kind: ConfigMap
metadata:
name: mymap-kfd8tf729k
`
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, expected)
}

View File

@@ -11,9 +11,9 @@ import (
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/krusty/internal/provider"
fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provenance"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
)
@@ -85,7 +85,7 @@ func (b *Kustomizer) Run(path string) (resmap.ResMap, error) {
t := builtins.LabelTransformerPlugin{
Labels: map[string]string{
konfig.ManagedbyLabelKey: fmt.Sprintf(
"kustomize-%s", provenance.GetProvenance().Version)},
"kustomize-%s", provenance.GetProvenance().Semver())},
FieldSpecs: []types.FieldSpec{{
Path: "metadata/labels",
CreateIfNotPresent: true,

View File

@@ -159,7 +159,7 @@ subjects:
name: default
namespace: irrelevant
---
apiVersion: admissionregistration.k8s.io/v1beta1
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: example
@@ -180,15 +180,17 @@ webhooks:
name: svc3
namespace: random
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crds.my.org
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb1
@@ -197,6 +199,7 @@ subjects:
name: default
namespace: irrelevant
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
@@ -257,7 +260,7 @@ subjects:
name: default
namespace: newnamespace
---
apiVersion: admissionregistration.k8s.io/v1beta1
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: p1-example-s1
@@ -278,15 +281,17 @@ webhooks:
namespace: random
name: example3
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crds.my.org
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: p1-cr1-s1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: p1-crb1-s1
@@ -295,6 +300,7 @@ subjects:
name: default
namespace: newnamespace
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: p1-pv1-s1

View File

@@ -0,0 +1,287 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
// https://github.com/kubernetes-sigs/kustomize/issues/2640
func TestNameUpdateInRoleRef(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/rbac.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: my-role
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: my-role
subjects:
- kind: ServiceAccount
name: default
namespace: foo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
version: v1
kind: Role
name: my-role
subjects:
- kind: ServiceAccount
name: default
`)
th.WriteK("/app", `
namespace: foo
resources:
- rbac.yaml
patches:
- patch: |-
- op: add
path: /metadata/name
value: prefix_my-role
target:
group: rbac.authorization.k8s.io
version: v1
kind: ClusterRole
name: my-role
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prefix_my-role
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prefix_my-role
subjects:
- kind: ServiceAccount
name: default
namespace: foo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
namespace: foo
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role
namespace: foo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-role
version: v1
subjects:
- kind: ServiceAccount
name: default
namespace: foo
`)
}
// https://github.com/kubernetes-sigs/kustomize/issues/3073
func TestNameUpdateInRoleRef2(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/workloads.yaml", `
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myapp
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: myapp
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
`)
th.WriteF("/app/suffixTransformer.yaml", `
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: notImportantHere
suffix: -suffix
fieldSpecs:
- path: metadata/name
kind: ClusterRole
name: myapp
- path: metadata/name
kind: ClusterRoleBinding
name: myapp
`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- workloads.yaml
transformers:
- suffixTransformer.yaml
namespace: test
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myapp-suffix
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: myapp-suffix
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myapp-suffix
subjects:
- kind: ServiceAccount
name: myapp
namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp
namespace: test
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
namespace: test
`)
}

View File

@@ -6,6 +6,7 @@ package provenance
import (
"fmt"
"runtime"
"strings"
)
var (
@@ -57,3 +58,11 @@ func (v Provenance) Short() string {
BuildDate: v.BuildDate,
})
}
// Semver returns the semantic version of kustomize.
// kustomize version is set in format "kustomize/vX.X.X" in every release.
// X.X.X is a semver. If the version string is not in this format,
// return the original version string
func (v Provenance) Semver() string {
return strings.TrimPrefix(v.Version, "kustomize/")
}

View File

@@ -11,6 +11,7 @@ import (
"sigs.k8s.io/kustomize/api/internal/wrappy"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/k8sdeps/validator"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
)
@@ -138,6 +139,7 @@ import (
// If you're reading this, plan not done.
//
type DepProvider struct {
kFactory ifc.KunstructuredFactory
resourceFactory *resource.Factory
merginator resmap.Merginator
fieldValidator ifc.Validator
@@ -147,6 +149,7 @@ func makeK8sdepBasedInstances() *DepProvider {
kf := kunstruct.NewKunstructuredFactoryImpl()
rf := resource.NewFactory(kf)
return &DepProvider{
kFactory: kf,
resourceFactory: rf,
merginator: merge.NewMerginator(rf),
fieldValidator: validator.NewKustValidator(),
@@ -157,6 +160,7 @@ func makeKyamlBasedInstances() *DepProvider {
kf := &wrappy.WNodeFactory{}
rf := resource.NewFactory(kf)
return &DepProvider{
kFactory: kf,
resourceFactory: rf,
merginator: kmerge.NewMerginator(rf),
fieldValidator: validate.NewFieldValidator(),
@@ -170,6 +174,14 @@ func NewDepProvider(useKyaml bool) *DepProvider {
return makeK8sdepBasedInstances()
}
func NewDefaultDepProvider() *DepProvider {
return NewDepProvider(konfig.FlagEnableKyamlDefaultValue)
}
func (dp *DepProvider) GetKunstructuredFactory() ifc.KunstructuredFactory {
return dp.kFactory
}
func (dp *DepProvider) GetResourceFactory() *resource.Factory {
return dp.resourceFactory
}

View File

@@ -6,6 +6,7 @@ package resid
import (
"strings"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -207,5 +208,6 @@ func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta {
// IsNamespaceableKind returns true if x is a namespaceable Gvk
// Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace
func (x Gvk) IsNamespaceableKind() bool {
return x.toKyamlTypeMeta().IsNamespaceable()
isNamespaceScoped, found := openapi.IsNamespaceScoped(x.toKyamlTypeMeta())
return !found || isNamespaceScoped
}

View File

@@ -18,6 +18,8 @@ package resid
import (
"testing"
"github.com/stretchr/testify/assert"
)
var equalsTests = []struct {
@@ -255,3 +257,40 @@ func TestSelectByGVK(t *testing.T) {
}
}
}
func TestIsNamespaceableKind(t *testing.T) {
testCases := []struct {
name string
gvk Gvk
expected bool
}{
{
"namespaceable resource",
Gvk{Group: "apps", Version: "v1", Kind: "Deployment"},
true,
},
{
"clusterscoped resource",
Gvk{Group: "", Version: "v1", Kind: "Namespace"},
false,
},
{
"unknown resource (should default to namespaceable)",
Gvk{Group: "example1.com", Version: "v1", Kind: "Bar"},
true,
},
{
"unknown resource (should default to namespaceable)",
Gvk{Group: "apps", Version: "v1", Kind: "ClusterRoleBinding"},
true,
},
}
for i := range testCases {
test := testCases[i]
t.Run(test.name, func(t *testing.T) {
isNamespaceable := test.gvk.IsNamespaceableKind()
assert.Equal(t, test.expected, isNamespaceable)
})
}
}

View File

@@ -265,7 +265,7 @@ func TestResIdEquals(t *testing.T) {
Name: "nm",
},
gVknResult: false,
nsEquals: false,
nsEquals: true,
equals: false,
},
{
@@ -376,7 +376,7 @@ func TestEffectiveNamespace(t *testing.T) {
}{
{
id: ResId{
Gvk: Gvk{Group: "g", Version: "v", Kind: "Node"},
Gvk: Gvk{Group: "", Version: "v1", Kind: "Node"},
Name: "nm",
},
expected: TotallyNotANamespace,
@@ -384,7 +384,7 @@ func TestEffectiveNamespace(t *testing.T) {
{
id: ResId{
Namespace: "foo",
Gvk: Gvk{Group: "g", Version: "v", Kind: "Node"},
Gvk: Gvk{Group: "", Version: "v1", Kind: "Node"},
Name: "nm",
},
expected: TotallyNotANamespace,

View File

@@ -9,6 +9,7 @@ import (
"sigs.k8s.io/kustomize/api/internal/kusterr"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// Merginator merges resources.
@@ -148,3 +149,20 @@ func newResMapFromResourceSlice(
}
return result, nil
}
// NewResMapFromRNodeSlice returns a ResMap from a slice of RNodes
func (rmF *Factory) NewResMapFromRNodeSlice(rnodes []*yaml.RNode) (ResMap, error) {
var resources []*resource.Resource
for _, rnode := range rnodes {
s, err := rnode.String()
if err != nil {
return nil, err
}
r, err := rmF.resF.FromBytes([]byte(s))
if err != nil {
return nil, err
}
resources = append(resources, r)
}
return newResMapFromResourceSlice(resources)
}

View File

@@ -5,9 +5,9 @@ package resmap_test
import (
"encoding/base64"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/kv"
@@ -17,6 +17,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/yaml"
)
func TestFromFile(t *testing.T) {
@@ -59,29 +60,21 @@ metadata:
"name": "dply2",
"namespace": "test",
}}).ResMap()
expYaml, err := expected.AsYaml()
assert.NoError(t, err)
fSys := filesys.MakeFsInMemory()
err := fSys.WriteFile("deployment.yaml", []byte(resourceStr))
if err != nil {
t.Fatal(err)
}
assert.NoError(t, fSys.WriteFile("deployment.yaml", []byte(resourceStr)))
ldr, err := loader.NewLoader(
loader.RestrictionRootOnly, filesys.Separator, fSys)
if err != nil {
t.Fatal(err)
}
assert.NoError(t, err)
m, err := rmF.FromFile(ldr, "deployment.yaml")
if err != nil {
t.Fatal(err)
}
if m.Size() != 3 {
t.Fatalf("result should contain 3, but got %d", m.Size())
}
if err := expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
assert.NoError(t, err)
mYaml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, expYaml, mYaml)
}
func TestFromBytes(t *testing.T) {
@@ -108,13 +101,13 @@ metadata:
"metadata": map[string]interface{}{
"name": "cm2",
}}).ResMap()
expYaml, err := expected.AsYaml()
assert.NoError(t, err)
m, err := rmF.NewResMapFromBytes(encoded)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
t.Fatalf("%#v doesn't match expected %#v", m, expected)
}
assert.NoError(t, err)
mYaml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, expYaml, mYaml)
}
var cmap = resid.Gvk{Version: "v1", Kind: "ConfigMap"}
@@ -228,12 +221,12 @@ BAR=baz
}
}
r, err := rmF.NewResMapFromConfigMapArgs(kvLdr, tc.input)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = tc.expected.ErrorIfNotEqualLists(r); err != nil {
t.Fatalf("testcase: %q, err: %v", tc.description, err)
}
assert.NoError(t, err, tc.description)
rYaml, err := r.AsYaml()
assert.NoError(t, err, tc.description)
expYaml, err := tc.expected.AsYaml()
assert.NoError(t, err, tc.description)
assert.Equal(t, expYaml, rYaml)
}
}
@@ -262,6 +255,8 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actYaml, err := actual.AsYaml()
assert.NoError(t, err)
expected := resmaptest_test.NewRmBuilder(t, rf).Add(
map[string]interface{}{
@@ -276,7 +271,61 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
},
}).ResMap()
if err = expected.ErrorIfNotEqualLists(actual); err != nil {
expYaml, err := expected.AsYaml()
assert.NoError(t, err)
assert.Equal(t, string(expYaml), string(actYaml))
}
func TestFromRNodeSlice(t *testing.T) {
input := `apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- watch
- list
`
rnodes := []*yaml.RNode{
yaml.MustParse(input),
}
rm, err := rmF.NewResMapFromRNodeSlice(rnodes)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expected := resmaptest_test.NewRmBuilder(t, rf).Add(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": map[string]interface{}{
"name": "namespace-reader",
},
"rules": []interface{}{
map[string]interface{}{
"apiGroups": []interface{}{
"",
},
"resources": []interface{}{
"namespaces",
},
"verbs": []interface{}{
"get",
"watch",
"list",
},
},
},
}).ResMap()
if err = expected.ErrorIfNotEqualLists(rm); err != nil {
t.Fatalf("error: %s", err)
}
}

View File

@@ -10,6 +10,7 @@ import (
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// A Transformer modifies an instance of ResMap.
@@ -235,4 +236,8 @@ type ResMap interface {
// Select returns a list of resources that
// are selected by a Selector
Select(types.Selector) ([]*resource.Resource, error)
// ToRNodeSlice converts the resources in the resmp
// to a list of RNodes
ToRNodeSlice() ([]*yaml.RNode, error)
}

View File

@@ -6,12 +6,12 @@ package resmap
import (
"bytes"
"fmt"
"regexp"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
kyaml_yaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/yaml"
)
@@ -339,10 +339,8 @@ func (m *resWrangler) ErrorIfNotEqualLists(other ResMap) error {
}
for i, r1 := range m.rList {
r2 := m2.rList[i]
if !r1.Equals(r2) {
return fmt.Errorf(
"Item i=%d differs:\n n1 = %s\n n2 = %s\n o1 = %s\n o2 = %s\n",
i, r1.OrgId(), r2.OrgId(), r1, r2)
if err := r1.ErrIfNotEquals(r2); err != nil {
return err
}
}
return nil
@@ -510,51 +508,34 @@ func (m *resWrangler) appendReplaceOrMerge(
return nil
}
func anchorRegex(pattern string) string {
if pattern == "" {
return pattern
}
return "^" + pattern + "$"
}
// Select returns a list of resources that
// are selected by a Selector
func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
ns := regexp.MustCompile(anchorRegex(s.Namespace))
nm := regexp.MustCompile(anchorRegex(s.Name))
var result []*resource.Resource
sr, err := types.NewSelectorRegex(&s)
if err != nil {
return nil, err
}
for _, r := range m.Resources() {
curId := r.CurId()
orgId := r.OrgId()
// matches the namespace when namespace is not empty in the selector
// It first tries to match with the original namespace
// then matches with the current namespace
if s.Namespace != "" {
matched := ns.MatchString(orgId.EffectiveNamespace())
if !matched {
matched = ns.MatchString(curId.EffectiveNamespace())
if !matched {
continue
}
}
if !sr.MatchNamespace(orgId.EffectiveNamespace()) &&
!sr.MatchNamespace(curId.EffectiveNamespace()) {
continue
}
// matches the name when name is not empty in the selector
// It first tries to match with the original name
// then matches with the current name
if s.Name != "" {
matched := nm.MatchString(orgId.Name)
if !matched {
matched = nm.MatchString(curId.Name)
if !matched {
continue
}
}
if !sr.MatchName(orgId.Name) &&
!sr.MatchName(curId.Name) {
continue
}
// matches the GVK
if !r.GetGvk().IsSelected(&s.Gvk) {
if !sr.MatchGvk(r.GetGvk()) {
continue
}
@@ -579,3 +560,21 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
}
return result, nil
}
// ToRNodeSlice converts the resources in the resmp
// to a list of RNodes
func (m *resWrangler) ToRNodeSlice() ([]*kyaml_yaml.RNode, error) {
var rnodes []*kyaml_yaml.RNode
for _, r := range m.Resources() {
s, err := r.AsYAML()
if err != nil {
return nil, err
}
rnode, err := kyaml_yaml.Parse(string(s))
if err != nil {
return nil, err
}
rnodes = append(rnodes, rnode)
}
return rnodes, nil
}

View File

@@ -4,12 +4,15 @@
package resmap_test
import (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
@@ -17,8 +20,7 @@ import (
"sigs.k8s.io/kustomize/api/types"
)
var rf = resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
var rf = provider.NewDefaultDepProvider().GetResourceFactory()
var rmF = NewFactory(rf, nil)
func doAppend(t *testing.T, w ResMap, r *resource.Resource) {
@@ -355,7 +357,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
})
r4 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "charlie",
@@ -374,7 +376,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
r5.AddNamePrefix("little-")
r6 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "domino",
@@ -384,7 +386,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
r6.AddNamePrefix("little-")
r7 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRoleBinding",
"metadata": map[string]interface{}{
"name": "meh",
@@ -686,49 +688,85 @@ func makeMap2(b types.GenerationBehavior) ResMap {
}
func TestAbsorbAll(t *testing.T) {
metadata := map[string]interface{}{
"name": "cmap",
}
if !konfig.FlagEnableKyamlDefaultValue {
metadata["annotations"] = map[string]interface{}{}
metadata["labels"] = map[string]interface{}{}
}
expected := rmF.FromResource(rf.FromMapAndOption(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{},
"labels": map[string]interface{}{},
"name": "cmap",
},
"metadata": metadata,
"data": map[string]interface{}{
"a": "u",
"b": "v",
"c": "w",
},
}, &types.GeneratorArgs{
},
&types.GeneratorArgs{
Behavior: "create",
}))
w := makeMap1()
if err := w.AbsorbAll(makeMap2(types.BehaviorMerge)); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := expected.ErrorIfNotEqualLists(w); err != nil {
t.Fatal(err)
}
assert.NoError(t, w.AbsorbAll(makeMap2(types.BehaviorMerge)))
assert.NoError(t, expected.ErrorIfNotEqualLists(w))
w = makeMap1()
if err := w.AbsorbAll(nil); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := w.ErrorIfNotEqualLists(makeMap1()); err != nil {
t.Fatal(err)
}
assert.NoError(t, w.AbsorbAll(nil))
assert.NoError(t, w.ErrorIfNotEqualLists(makeMap1()))
w = makeMap1()
w2 := makeMap2(types.BehaviorReplace)
if err := w.AbsorbAll(w2); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := w2.ErrorIfNotEqualLists(w); err != nil {
t.Fatal(err)
}
assert.NoError(t, w.AbsorbAll(w2))
assert.NoError(t, w2.ErrorIfNotEqualLists(w))
w = makeMap1()
w2 = makeMap2(types.BehaviorUnspecified)
err := w.AbsorbAll(w2)
if err == nil {
t.Fatalf("expected error with unspecified behavior")
assert.Error(t, err)
assert.True(
t, strings.Contains(err.Error(), "behavior must be merge or replace"))
}
func TestToRNodeSlice(t *testing.T) {
input := `apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- watch
- list
`
rm, err := rmF.NewResMapFromBytes([]byte(input))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
rnodes, err := rm.ToRNodeSlice()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
b := bytes.NewBufferString("")
for i, n := range rnodes {
if i != 0 {
b.WriteString("---\n")
}
s, err := n.String()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
b.WriteString(s)
}
if !reflect.DeepEqual(input, b.String()) {
t.Fatalf("actual doesn't match expected.\nActual:\n%s\n===\nExpected:\n%s\n",
b.String(), input)
}
}

View File

@@ -6,6 +6,7 @@ package resmap_test
import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
@@ -48,38 +49,36 @@ metadata:
name: x-name1
namespace: x-default
`))
if err != nil {
t.Fatalf("unexpected error %v", err)
}
assert.NoError(t, err)
return result
}
func TestFindPatchTargets(t *testing.T) {
rm := setupRMForPatchTargets(t)
testcases := []struct {
testcases := map[string]struct {
target types.Selector
count int
}{
{
"select_01": {
target: types.Selector{
Name: "name.*",
},
count: 3,
},
{
"select_02": {
target: types.Selector{
Name: "name.*",
AnnotationSelector: "foo=bar",
},
count: 2,
},
{
"select_03": {
target: types.Selector{
LabelSelector: "app=name1",
},
count: 1,
},
{
"select_04": {
target: types.Selector{
Gvk: resid.Gvk{
Kind: "Kind1",
@@ -88,31 +87,31 @@ func TestFindPatchTargets(t *testing.T) {
},
count: 2,
},
{
"select_05": {
target: types.Selector{
Name: "NotMatched",
},
count: 0,
},
{
"select_06": {
target: types.Selector{
Name: "",
},
count: 4,
},
{
"select_07": {
target: types.Selector{
Namespace: "default",
},
count: 2,
},
{
"select_08": {
target: types.Selector{
Namespace: "",
},
count: 4,
},
{
"select_09": {
target: types.Selector{
Namespace: "default",
Name: "name.*",
@@ -122,69 +121,65 @@ func TestFindPatchTargets(t *testing.T) {
},
count: 1,
},
{
"select_10": {
target: types.Selector{
Name: "^name.*",
},
count: 3,
},
{
"select_11": {
target: types.Selector{
Name: "name.*$",
},
count: 3,
},
{
"select_12": {
target: types.Selector{
Name: "^name.*$",
},
count: 3,
},
{
"select_13": {
target: types.Selector{
Namespace: "^def.*",
},
count: 2,
},
{
"select_14": {
target: types.Selector{
Namespace: "def.*$",
},
count: 2,
},
{
"select_15": {
target: types.Selector{
Namespace: "^def.*$",
},
count: 2,
},
{
"select_16": {
target: types.Selector{
Namespace: "default",
},
count: 2,
},
{
"select_17": {
target: types.Selector{
Namespace: "NotMatched",
},
count: 0,
},
{
"select_18": {
target: types.Selector{
Namespace: "ns1",
},
count: 1,
},
}
for _, testcase := range testcases {
for n, testcase := range testcases {
actual, err := rm.Select(testcase.target)
if err != nil {
t.Errorf("unexpected error %v", err)
}
if len(actual) != testcase.count {
t.Errorf("expected %d objects, but got %d:\n%v", testcase.count, len(actual), actual)
}
assert.NoError(t, err)
assert.Equalf(
t, testcase.count, len(actual), "test=%s target=%v", n, testcase.target)
}
}

View File

@@ -94,7 +94,7 @@ func (rf *Factory) SliceFromPatches(
return result, nil
}
// FromBytes unmarshals bytes into one Resource.
// FromBytes unmarshalls bytes into one Resource.
func (rf *Factory) FromBytes(in []byte) (*Resource, error) {
result, err := rf.SliceFromBytes(in)
if err != nil {

View File

@@ -4,9 +4,12 @@
package resource_test
import (
"reflect"
"fmt"
"testing"
"sigs.k8s.io/kustomize/api/konfig"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/loader"
. "sigs.k8s.io/kustomize/api/resource"
@@ -340,7 +343,15 @@ kind: List
name: "listWithAnchorReference",
input: []types.PatchStrategicMerge{patchList2},
expectedOut: []*Resource{testDeploymentA, testDeploymentB},
expectedErr: false,
// See https://github.com/kubernetes-sigs/kustomize/issues/3271
// This test should not have an error, but does when kyaml is used.
// The error using kyaml is:
// json: unsupported type: map[interface {}]interface {}
// probably arising from too many conversions between
// yaml, json, Resource, RNode, Unstructured etc.
// These conversions can be removed after closing
// https://github.com/kubernetes-sigs/kustomize/issues/2506
expectedErr: konfig.FlagEnableKyamlDefaultValue,
},
{
name: "listWithNoEntries",
@@ -349,7 +360,7 @@ kind: List
expectedErr: false,
},
{
name: "listWithNo'items:'",
name: "listWithNoItems",
input: []types.PatchStrategicMerge{patchList4},
expectedOut: []*Resource{},
expectedErr: false,
@@ -357,21 +368,19 @@ kind: List
}
for _, test := range tests {
rs, err := factory.SliceFromPatches(ldr, test.input)
if test.expectedErr && err == nil {
t.Fatalf("%v: should return error", test.name)
}
if !test.expectedErr && err != nil {
t.Fatalf("%v: unexpected error: %s", test.name, err)
}
if len(rs) != len(test.expectedOut) {
t.Fatalf("%s: length mismatch %d != %d",
test.name, len(rs), len(test.expectedOut))
if err != nil {
assert.True(t, test.expectedErr,
fmt.Sprintf("in test %s, got unexpected error: %v", test.name, err))
continue
}
assert.False(t, test.expectedErr, "expected no error in "+test.name)
assert.Equal(t, len(test.expectedOut), len(rs))
for i := range rs {
if !reflect.DeepEqual(test.expectedOut[i], rs[i]) {
t.Fatalf("%s: Got: %v\nexpected:%v",
test.name, test.expectedOut[i], rs[i])
}
expYaml, err := test.expectedOut[i].AsYAML()
assert.NoError(t, err)
actYaml, err := rs[i].AsYAML()
assert.NoError(t, err)
assert.Equal(t, expYaml, actYaml)
}
}
}

30
api/resource/idset.go Normal file
View File

@@ -0,0 +1,30 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource
import "sigs.k8s.io/kustomize/api/resid"
type IdSet struct {
ids map[resid.ResId]bool
}
func MakeIdSet(slice []*Resource) *IdSet {
set := make(map[resid.ResId]bool)
for _, r := range slice {
id := r.CurId()
if _, ok := set[id]; !ok {
set[id] = true
}
}
return &IdSet{ids: set}
}
func (s IdSet) Contains(id resid.ResId) bool {
_, ok := s.ids[id]
return ok
}
func (s IdSet) Size() int {
return len(s.ids)
}

View File

@@ -0,0 +1,32 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource_test
import (
"testing"
"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/api/resource"
)
func TestIdSet_Empty(t *testing.T) {
s := MakeIdSet([]*Resource{})
assert.Equal(t, 0, s.Size())
assert.False(t, s.Contains(testDeployment.CurId()))
assert.False(t, s.Contains(testConfigMap.CurId()))
}
func TestIdSet_One(t *testing.T) {
s := MakeIdSet([]*Resource{testDeployment})
assert.Equal(t, 1, s.Size())
assert.True(t, s.Contains(testDeployment.CurId()))
assert.False(t, s.Contains(testConfigMap.CurId()))
}
func TestIdSet_Two(t *testing.T) {
s := MakeIdSet([]*Resource{testDeployment, testConfigMap})
assert.Equal(t, 2, s.Size())
assert.True(t, s.Contains(testDeployment.CurId()))
assert.True(t, s.Contains(testConfigMap.CurId()))
}

View File

@@ -5,6 +5,7 @@
package resource
import (
"fmt"
"reflect"
"strings"
@@ -156,9 +157,25 @@ func (r *Resource) copyOtherFields(other *Resource) {
r.nameSuffixes = copyStringSlice(other.nameSuffixes)
}
func (r *Resource) Equals(o *Resource) bool {
return r.ReferencesEqual(o) &&
reflect.DeepEqual(r.kunStr, o.kunStr)
func (r *Resource) ErrIfNotEquals(o *Resource) error {
meYaml, err := r.AsYAML()
if err != nil {
return err
}
otherYaml, err := o.AsYAML()
if err != nil {
return err
}
if !r.ReferencesEqual(o) {
return fmt.Errorf("references unequal")
}
if string(meYaml) != string(otherYaml) {
return fmt.Errorf("--- self:\n"+
"%s\n"+
"--- other:\n"+
"%s\n", meYaml, otherYaml)
}
return nil
}
func (r *Resource) ReferencesEqual(o *Resource) bool {

View File

@@ -1,18 +1,5 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource_test
@@ -20,14 +7,13 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
)
var factory = NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
var factory = provider.NewDefaultDepProvider().GetResourceFactory()
var testConfigMap = factory.FromMap(
map[string]interface{}{

View File

@@ -8,13 +8,11 @@ import (
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/k8sdeps/merge"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
)
@@ -46,11 +44,9 @@ func MakeEnhancedHarness(t *testing.T) *HarnessEnhanced {
if err != nil {
t.Fatal(err)
}
resourceFactory := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
resmapFactory := resmap.NewFactory(
resourceFactory,
merge.NewMerginator(resourceFactory))
p := provider.NewDefaultDepProvider()
resourceFactory := p.GetResourceFactory()
resmapFactory := resmap.NewFactory(resourceFactory, p.GetMerginator())
result := &HarnessEnhanced{
Harness: MakeHarness(t),

View File

@@ -6,6 +6,7 @@ package resmaptest_test
import (
"testing"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
)
@@ -25,6 +26,15 @@ func NewRmBuilder(t *testing.T, rf *resource.Factory) *rmBuilder {
return NewSeededRmBuilder(t, rf, resmap.New())
}
func NewRmBuilderDefault(t *testing.T) *rmBuilder {
return NewSeededRmBuilderDefault(t, resmap.New())
}
func NewSeededRmBuilderDefault(t *testing.T, m resmap.ResMap) *rmBuilder {
return NewSeededRmBuilder(
t, provider.NewDefaultDepProvider().GetResourceFactory(), m)
}
func (rm *rmBuilder) Add(m map[string]interface{}) *rmBuilder {
return rm.AddR(rm.rf.FromMap(m))
}

View File

@@ -0,0 +1,25 @@
// Code generated by "stringer -type=BuiltinPluginLoadingOptions"; DO NOT EDIT.
package types
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[BploUndefined-0]
_ = x[BploUseStaticallyLinked-1]
_ = x[BploLoadFromFileSys-2]
}
const _BuiltinPluginLoadingOptions_name = "BploUndefinedBploUseStaticallyLinkedBploLoadFromFileSys"
var _BuiltinPluginLoadingOptions_index = [...]uint8{0, 13, 36, 55}
func (i BuiltinPluginLoadingOptions) String() string {
if i < 0 || i >= BuiltinPluginLoadingOptions(len(_BuiltinPluginLoadingOptions_index)-1) {
return "BuiltinPluginLoadingOptions(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _BuiltinPluginLoadingOptions_name[_BuiltinPluginLoadingOptions_index[i]:_BuiltinPluginLoadingOptions_index[i+1]]
}

View File

@@ -0,0 +1,19 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
// HelmChartArgs contains the metadata of how to generate a secret.
type HelmChartArgs struct {
ChartName string `json:"chartName,omitempty" yaml:"chartName,omitempty"`
ChartVersion string `json:"chartVersion,omitempty" yaml:"chartVersion,omitempty"`
ChartRepoURL string `json:"chartRepoUrl,omitempty" yaml:"chartRepoUrl,omitempty"`
ChartHome string `json:"chartHome,omitempty" yaml:"chartHome,omitempty"`
// Use chartRelease to keep compatible with old exec plugin
ChartRepoName string `json:"chartRelease,omitempty" yaml:"chartRelease,omitempty"`
HelmBin string `json:"helmBin,omitempty" yaml:"helmBin,omitempty"`
HelmHome string `json:"helmHome,omitempty" yaml:"helmHome,omitempty"`
Values string `json:"values,omitempty" yaml:"values,omitempty"`
ReleaseName string `json:"releaseName,omitempty" yaml:"releaseName,omitempty"`
ReleaseNamespace string `json:"releaseNamespace,omitempty" yaml:"releaseNamespace,omitempty"`
}

View File

@@ -55,7 +55,7 @@ type Kustomization struct {
// JSONPatches is a list of JSONPatch for applying JSON patch.
// Format documented at https://tools.ietf.org/html/rfc6902
// and http://jsonpatch.com
PatchesJson6902 []PatchJson6902 `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
PatchesJson6902 []Patch `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
// Patches is a list of patches, where each one can be either a
// Strategic Merge Patch or a JSON patch.
@@ -122,6 +122,11 @@ type Kustomization struct {
// the map will have a suffix hash generated from its contents.
SecretGenerator []SecretArgs `json:"secretGenerator,omitempty" yaml:"secretGenerator,omitempty"`
// HelmChartInflationGenerator is a list of helm chart configurations.
// The resulting resource is a normal operand rendered from
// a remote chart by `helm template`
HelmChartInflationGenerator []HelmChartArgs `json:"helmChartInflationGenerator,omitempty" yaml:"helmChartInflationGenerator,omitempty"`
// GeneratorOptions modify behavior of all ConfigMap and Secret generators.
GeneratorOptions *GeneratorOptions `json:"generatorOptions,omitempty" yaml:"generatorOptions,omitempty"`
@@ -167,9 +172,7 @@ func (k *Kustomization) FixKustomizationPostUnmarshalling() {
// has been processed.
func (k *Kustomization) FixKustomizationPreMarshalling() {
// PatchesJson6902 should be under the Patches field.
for _, patch := range k.PatchesJson6902 {
k.Patches = append(k.Patches, patch.ToPatch())
}
k.Patches = append(k.Patches, k.PatchesJson6902...)
k.PatchesJson6902 = nil
}

View File

@@ -17,3 +17,12 @@ type Patch struct {
// Target points to the resources that the patch is applied to
Target *Selector `json:"target,omitempty" yaml:"target,omitempty"`
}
// Equals return true if p equals o.
func (p *Patch) Equals(o Patch) bool {
targetEqual := (p.Target == o.Target) ||
(p.Target != nil && o.Target != nil && *p.Target == *o.Target)
return p.Path == o.Path &&
p.Patch == o.Patch &&
targetEqual
}

125
api/types/patch_test.go Normal file
View File

@@ -0,0 +1,125 @@
package types_test
import (
"testing"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/types"
)
func TestPatchEquals(t *testing.T) {
selector := Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
}
type testcase struct {
patch1 Patch
patch2 Patch
expect bool
name string
}
testcases := []testcase{
{
name: "empty patches",
patch1: Patch{},
patch2: Patch{},
expect: true,
},
{
name: "full patches",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
},
},
patch2: Patch{
Path: "foo",
Patch: "bar",
Target: &Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
},
},
expect: true,
},
{
name: "same target",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
patch2: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
expect: true,
},
{
name: "omit target",
patch1: Patch{
Path: "foo",
Patch: "bar",
},
patch2: Patch{
Path: "foo",
Patch: "bar",
},
expect: true,
},
{
name: "one nil target",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
patch2: Patch{
Path: "foo",
Patch: "bar",
},
expect: false,
},
{
name: "different path",
patch1: Patch{
Path: "foo",
},
patch2: Patch{
Path: "bar",
},
expect: false,
},
}
for _, tc := range testcases {
if tc.expect != tc.patch1.Equals(tc.patch2) {
t.Fatalf("%s: unexpected result %v", tc.name, !tc.expect)
}
}
}

View File

@@ -1,27 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
// PatchJson6902 represents a json patch for an object
// with format documented https://tools.ietf.org/html/rfc6902.
type PatchJson6902 struct {
// PatchTarget refers to a Kubernetes object that the json patch will be
// applied to. It must refer to a Kubernetes resource under the
// purview of this kustomization. PatchTarget should use the
// raw name of the object (the name specified in its YAML,
// before addition of a namePrefix and a nameSuffix).
Target *PatchTarget `json:"target" yaml:"target"`
// relative file path for a json patch file inside a kustomization
Path string `json:"path,omitempty" yaml:"path,omitempty"`
// inline patch string
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
}
// ToPatch converts a PatchJson6902 to its superset Patch.
func (patch *PatchJson6902) ToPatch() Patch {
selector := patch.Target.ToSelector()
return Patch{Path: patch.Path, Patch: patch.Patch, Target: &selector}
}

View File

@@ -1,20 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
import (
"sigs.k8s.io/kustomize/api/resid"
)
// PatchTarget represents the kubernetes object that the patch is applied to
type PatchTarget struct {
resid.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Name string `json:"name" yaml:"name"`
}
// ToSelector converts a PatchTarget to a Selector.
func (target *PatchTarget) ToSelector() Selector {
return Selector{Name: target.Name, Namespace: target.Namespace, Gvk: target.Gvk}
}

View File

@@ -4,6 +4,8 @@
package types
import (
"regexp"
"sigs.k8s.io/kustomize/api/resid"
)
@@ -25,3 +27,89 @@ type Selector struct {
// It matches with the resource labels.
LabelSelector string `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"`
}
// SelectorRegex is a Selector with regex in GVK
// Any resource that matches intersection of all conditions
// is included in this set.
type SelectorRegex struct {
selector *Selector
groupRegex *regexp.Regexp
versionRegex *regexp.Regexp
kindRegex *regexp.Regexp
nameRegex *regexp.Regexp
namespaceRegex *regexp.Regexp
}
// NewSelectorRegex returns a pointer to a new SelectorRegex
// which uses the same condition as s.
func NewSelectorRegex(s *Selector) (*SelectorRegex, error) {
sr := new(SelectorRegex)
var err error
sr.selector = s
sr.groupRegex, err = regexp.Compile(anchorRegex(s.Gvk.Group))
if err != nil {
return nil, err
}
sr.versionRegex, err = regexp.Compile(anchorRegex(s.Gvk.Version))
if err != nil {
return nil, err
}
sr.kindRegex, err = regexp.Compile(anchorRegex(s.Gvk.Kind))
if err != nil {
return nil, err
}
sr.nameRegex, err = regexp.Compile(anchorRegex(s.Name))
if err != nil {
return nil, err
}
sr.namespaceRegex, err = regexp.Compile(anchorRegex(s.Namespace))
if err != nil {
return nil, err
}
return sr, nil
}
func anchorRegex(pattern string) string {
if pattern == "" {
return pattern
}
return "^(?:" + pattern + ")$"
}
// MatchGvk return true if gvk can be matched by s.
func (s *SelectorRegex) MatchGvk(gvk resid.Gvk) bool {
if len(s.selector.Gvk.Group) > 0 {
if !s.groupRegex.MatchString(gvk.Group) {
return false
}
}
if len(s.selector.Gvk.Version) > 0 {
if !s.versionRegex.MatchString(gvk.Version) {
return false
}
}
if len(s.selector.Gvk.Kind) > 0 {
if !s.kindRegex.MatchString(gvk.Kind) {
return false
}
}
return true
}
// MatchName returns true if the name in selector is
// empty or the n can be matches by the name in selector
func (s *SelectorRegex) MatchName(n string) bool {
if s.selector.Name == "" {
return true
}
return s.nameRegex.MatchString(n)
}
// MatchNamespace returns true if the namespace in selector is
// empty or the ns can be matches by the namespace in selector
func (s *SelectorRegex) MatchNamespace(ns string) bool {
if s.selector.Namespace == "" {
return true
}
return s.namespaceRegex.MatchString(ns)
}

216
api/types/selector_test.go Normal file
View File

@@ -0,0 +1,216 @@
package types_test
import (
"testing"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/types"
)
func TestSelectorRegexMatchGvk(t *testing.T) {
testcases := []struct {
S Selector
G resid.Gvk
Expected bool
}{
{
S: Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
},
G: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Expected: true,
},
{
S: Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "",
Kind: "",
},
},
G: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Expected: true,
},
{
S: Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
},
G: resid.Gvk{
Group: "group",
Version: "version",
Kind: "",
},
Expected: false,
},
{
S: Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
},
G: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind2",
},
Expected: false,
},
{
S: Selector{
Gvk: resid.Gvk{
Group: "g.*",
Version: "\\d+",
Kind: ".{4}",
},
},
G: resid.Gvk{
Group: "group",
Version: "123",
Kind: "abcd",
},
Expected: true,
},
{
S: Selector{
Gvk: resid.Gvk{
Group: "g.*",
Version: "\\d+",
Kind: ".{4}",
},
},
G: resid.Gvk{
Group: "group",
Version: "123",
Kind: "abc",
},
Expected: false,
},
}
for _, tc := range testcases {
sr, err := NewSelectorRegex(&tc.S)
if err != nil {
t.Fatal(err)
}
if sr.MatchGvk(tc.G) != tc.Expected {
t.Fatalf("unexpected result for selector gvk %s and gvk %s",
tc.S.Gvk.String(), tc.G.String())
}
}
}
func TestSelectorRegexMatchName(t *testing.T) {
testcases := []struct {
S Selector
Name string
Expected bool
}{
{
S: Selector{
Name: "foo",
Namespace: "bar",
},
Name: "foo",
Expected: true,
},
{
S: Selector{
Name: "foo",
Namespace: "bar",
},
Name: "bar",
Expected: false,
},
{
S: Selector{
Name: "f.*",
},
Name: "foo",
Expected: true,
},
{
S: Selector{
Name: "b.*",
},
Name: "foo",
Expected: false,
},
}
for _, tc := range testcases {
sr, err := NewSelectorRegex(&tc.S)
if err != nil {
t.Fatal(err)
}
if sr.MatchName(tc.Name) != tc.Expected {
t.Fatalf("unexpected result for selector name %s and name %s",
tc.S.Name, tc.Name)
}
}
}
func TestSelectorRegexMatchNamespace(t *testing.T) {
testcases := []struct {
S Selector
Namespace string
Expected bool
}{
{
S: Selector{
Name: "bar",
Namespace: "foo",
},
Namespace: "foo",
Expected: true,
},
{
S: Selector{
Name: "foo",
Namespace: "bar",
},
Namespace: "foo",
Expected: false,
},
{
S: Selector{
Namespace: "f.*",
},
Namespace: "foo",
Expected: true,
},
{
S: Selector{
Namespace: "b.*",
},
Namespace: "foo",
Expected: false,
},
}
for _, tc := range testcases {
sr, err := NewSelectorRegex(&tc.S)
if err != nil {
t.Fatal(err)
}
if sr.MatchNamespace(tc.Namespace) != tc.Expected {
t.Fatalf("unexpected result for selector namespace %s and namespace %s",
tc.S.Namespace, tc.Namespace)
}
}
}

View File

@@ -1,72 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package complete
import (
"os"
"strings"
"github.com/posener/complete/v2"
"github.com/posener/complete/v2/predict"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors"
)
// NewCommand returns a new install-completion command
func NewCommand() *cobra.Command {
return &cobra.Command{
Use: "install-completion",
Short: commands.CompletionShort,
Long: commands.CompletionLong,
PreRunE: preRunE,
Run: run,
}
}
func preRunE(cmd *cobra.Command, args []string) error {
// install by default
if os.Getenv("COMP_INSTALL") == "" {
if err := errors.Wrap(os.Setenv("COMP_INSTALL", "1")); err != nil {
return err
}
}
return nil
}
func run(cmd *cobra.Command, args []string) {
// find the root command
for cmd.Parent() != nil {
cmd = cmd.Parent()
}
// do completion
Complete(cmd).Complete("kustomize")
}
// Complete returns a completion command for a cobra command
func Complete(cmd *cobra.Command) *complete.Command {
cc := &complete.Command{
Flags: map[string]complete.Predictor{},
Sub: map[string]*complete.Command{},
}
if strings.Contains(cmd.Use, "DIR") {
// if usage contains directory, then use a file predictor
cc.Args = predict.Dirs("*")
}
// add completion for each subcommand
for i := range cmd.Commands() {
c := cmd.Commands()[i]
name := strings.Split(c.Use, " ")[0]
cc.Sub[name] = Complete(c)
}
// add completion for each flag
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
cc.Flags[flag.Name] = predict.Nothing
})
return cc
}

View File

@@ -0,0 +1,33 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package completion
import (
"os"
"github.com/spf13/cobra"
)
func NewCommand() *cobra.Command {
return &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate shell completion script",
Long: "Generate shell completion.",
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
cmd.Root().GenPowerShellCompletion(os.Stdout)
}
},
}
}

View File

@@ -10,6 +10,7 @@ import (
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/api"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/tutorials"
"sigs.k8s.io/kustomize/cmd/config/runner"
)
// Export commands publicly for composition
@@ -35,13 +36,13 @@ var (
Wrap = commands.WrapCommand
XArgs = commands.XArgsCommand
StackOnError = &commands.StackOnError
ExitOnError = &commands.ExitOnError
StackOnError = &runner.StackOnError
ExitOnError = &runner.ExitOnError
)
// AddCommands adds the cfg and fn commands to kustomize.
func AddCommands(root *cobra.Command, name string) *cobra.Command {
commands.ExitOnError = true
runner.ExitOnError = true
root.PersistentFlags().BoolVar(StackOnError, "stack-trace", false,
"print a stack-trace on error")

View File

@@ -1,20 +1,25 @@
## install-completion
## completion
Install shell completion.
Generate shell completion.
### Synopsis
Install shell completion for kustomize commands and flags -- supports bash, fish and zsh.
Generate shell completion for `kustomize` -- supports bash, zsh, fish and powershell.
kustomize install-completion
### Examples
Registers the completion command with known shells (e.g. .bashrc, .bash_profile, etc):
# load completion for Bash
source <(kustomize completion bash)
complete -C /Users/USER/go/bin/kustomize kustomize
# install for Bash in Linux
kustomize completion bash > /etc/bash_completion.d/kustomize
Because the completion command is embedded in kustomize directly, there is no need to update
it separately from the kustomize binary.
# install for Bash in MacOS
kustomize completion bash > /usr/local/etc/bash_completion.d/kustomize
To uninstall shell completion run:
# package for Bash
kustomize completion bash > /usr/share/bash-completion/completions/kustomize
# package for zsh
kustomize completion zsh > /usr/share/zsh/site-functions/_kustomize
COMP_UNINSTALL=1 kustomize install-completion

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/cmd/config
go 1.14
go 1.15
require (
github.com/go-errors/errors v1.0.1
@@ -9,13 +9,13 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/posener/complete/v2 v2.0.1-alpha.12
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
k8s.io/apimachinery v0.17.3
sigs.k8s.io/kustomize/kyaml v0.9.1
k8s.io/apimachinery v0.18.10
sigs.k8s.io/kustomize/kyaml v0.9.4
)
replace sigs.k8s.io/kustomize/kyaml v0.9.4 => ../../kyaml

View File

@@ -34,7 +34,6 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -45,10 +44,9 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -122,8 +120,8 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
@@ -141,21 +139,19 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@@ -165,7 +161,7 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -200,7 +196,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -217,8 +212,7 @@ github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -227,13 +221,8 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete/v2 v2.0.1-alpha.12 h1:0wvkuDfHb5vSZlNBYgpEH4XQHpF46MjLPHav8XC77Nc=
github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ=
github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -268,7 +257,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -339,9 +327,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -392,16 +380,15 @@ gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C
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=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/apimachinery v0.17.3 h1:f+uZV6rm4/tHE7xXgLyToprg6xWairaClGVkm2t8omg=
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apimachinery v0.18.10 h1:Zupk3lPrUfhCF9puTpA8EvEfPsrhNZtrpOqdp66mKVs=
k8s.io/apimachinery v0.18.10/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -27,7 +28,7 @@ func NewAnnotateRunner(parent string) *AnnotateRunner {
Example: commands.AnnotateExamples,
RunE: r.runE,
}
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
c.Flags().StringVar(&r.Kind, "kind", "", "Resource kind to annotate")
c.Flags().StringVar(&r.ApiVersion, "apiVersion", "", "Resource apiVersion to annotate")
@@ -62,29 +63,29 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
input = []kio.Reader{rw}
output = []kio.Writer{rw}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: input,
Filters: []kio.Filter{r},
Outputs: output,
}.Execute())
}
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
e := runner.ExecuteCmdOnPkgs{
Writer: c.OutOrStdout(),
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
return nil
}
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *AnnotateRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
rw := &kio.LocalPackageReadWriter{
PackagePath: pkgPath,
NoDeleteFiles: true,

View File

@@ -13,6 +13,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -30,7 +31,7 @@ func GetCatRunner(name string) *CatRunner {
RunE: r.runE,
Args: cobra.MaximumNArgs(1),
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.Format, "format", true,
"format resource config yaml before printing.")
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false,
@@ -95,21 +96,21 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
if err != nil {
return err
}
return handleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
return runner.HandleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
}
out := &bytes.Buffer{}
e := executeCmdOnPkgs{
writer: out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
skipPkgPathPrint: true,
e := runner.ExecuteCmdOnPkgs{
Writer: out,
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
SkipPkgPathPrint: true,
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
@@ -120,7 +121,7 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
return nil
}
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CatRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
outputs, err := r.out(out)

View File

@@ -15,9 +15,9 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -33,37 +33,26 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
PreRunE: r.preRunE,
RunE: r.runE,
}
set.Flags().StringVar(&r.Set.SetPartialField.Setter.Value, "value", "",
set.Flags().StringVar(&r.FieldValue, "value", "",
"optional flag, alternative to specifying the value as an argument. e.g. used to specify values that start with '-'")
set.Flags().StringVar(&r.Set.SetPartialField.SetBy, "set-by", "",
set.Flags().StringVar(&r.SetBy, "set-by", "",
"record who the field was default by.")
set.Flags().StringVar(&r.Set.SetPartialField.Description, "description", "",
set.Flags().StringVar(&r.Description, "description", "",
"record a description for the current setter value.")
set.Flags().StringVar(&r.Set.SetPartialField.Field, "field", "",
set.Flags().StringVar(&r.FieldName, "field", "",
"name of the field to set, a suffix of the path to the field, or the full"+
" path to the field. Default is to match all fields.")
set.Flags().StringVar(&r.Set.ResourceMeta.Name, "name", "",
"name of the Resource on which to create the setter.")
set.Flags().MarkHidden("name")
set.Flags().StringVar(&r.Set.ResourceMeta.Kind, "kind", "",
"kind of the Resource on which to create the setter.")
set.Flags().MarkHidden("kind")
set.Flags().StringVar(&r.Set.SetPartialField.Type, "type", "",
set.Flags().StringVar(&r.Type, "type", "",
"OpenAPI field type for the setter -- e.g. integer,boolean,string.")
set.Flags().BoolVar(&r.Set.SetPartialField.Partial, "partial", false,
"create a partial setter for only part of the field value.")
set.Flags().MarkHidden("partial")
set.Flags().StringVar(&setterVersion, "version", "",
"use this version of the setter format")
set.Flags().BoolVar(&r.CreateSetter.Required, "required", false,
set.Flags().BoolVar(&r.Required, "required", false,
"indicates that this setter must be set by package consumer before live apply/preview")
set.Flags().StringVar(&r.SchemaPath, "schema-path", "",
`openAPI schema file path for setter constraints -- file content `+
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
set.Flags().BoolVarP(&r.CreateSetter.RecurseSubPackages, "recurse-subpackages", "R", false,
set.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"creates setter recursively in all the nested subpackages")
set.Flags().MarkHidden("version")
fixDocs(parent, set)
runner.FixDocs(parent, set)
r.Command = set
return r
}
@@ -73,60 +62,49 @@ func CreateSetterCommand(parent string) *cobra.Command {
}
type CreateSetterRunner struct {
Command *cobra.Command
Set setters.CreateSetter
CreateSetter settersutil.SetterCreator
OpenAPIFile string
SchemaPath string
Command *cobra.Command
CreateSetter settersutil.SetterCreator
OpenAPIFile string
SchemaPath string
FieldValue string
SetBy string
Description string
SetterName string
Type string
FieldName string
Schema string
Required bool
RecurseSubPackages bool
}
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.createSetter(c, args))
return runner.HandleError(c, r.createSetter(c, args))
}
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
valueSetFromFlag := c.Flag("value").Changed
var err error
r.Set.SetPartialField.Setter.Name = args[1]
r.CreateSetter.Name = args[1]
if valueSetFromFlag {
r.CreateSetter.FieldValue = r.Set.SetPartialField.Setter.Value
} else if len(args) > 2 {
r.Set.SetPartialField.Setter.Value = args[2]
r.CreateSetter.FieldValue = args[2]
r.SetterName = args[1]
if len(args) > 2 {
r.FieldValue = args[2]
}
r.CreateSetter.FieldName, err = c.Flags().GetString("field")
r.FieldName, err = c.Flags().GetString("field")
if err != nil {
return err
}
if setterVersion == "" {
if len(args) == 2 && r.Set.SetPartialField.Type == "array" && c.Flag("field").Changed {
setterVersion = "v2"
} else if err := initSetterVersion(c, args); err != nil {
return err
}
}
if r.Set.SetPartialField.Type != "array" && !c.Flag("value").Changed && len(args) < 3 {
if r.Type != "array" && !c.Flag("value").Changed && len(args) < 3 {
return errors.Errorf("setter name and value must be provided, " +
"value can either be an argument or can be passed as a flag --value")
}
if setterVersion == "v2" {
r.CreateSetter.Description = r.Set.SetPartialField.Description
r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy
r.CreateSetter.Type = r.Set.SetPartialField.Type
err = r.processSchema()
if err != nil {
return err
}
err = r.processSchema()
if err != nil {
return err
}
if r.CreateSetter.Type == "array" {
if !c.Flag("field").Changed {
return errors.Errorf("field flag must be set for array type setters")
}
if r.Type == "array" {
if !c.Flag("field").Changed {
return errors.Errorf("field flag must be set for array type setters")
}
}
return nil
@@ -138,7 +116,7 @@ func (r *CreateSetterRunner) processSchema() error {
return err
}
flagType := r.CreateSetter.Type
flagType := r.Type
var schemaType string
switch {
// json schema allows more than one type to be specified, but openapi
@@ -155,13 +133,13 @@ func (r *CreateSetterRunner) processSchema() error {
// are both set with different values, we return an error.
switch {
case flagType == "" && schemaType != "":
r.CreateSetter.Type = schemaType
r.Type = schemaType
case flagType != "" && schemaType == "":
sc.Type = []string{flagType}
case flagType != "" && schemaType != "":
if flagType != schemaType {
return errors.Errorf("type provided in type flag (%s) and in schema (%s) doesn't match",
r.CreateSetter.Type, sc.Type[0])
r.Type, sc.Type[0])
}
}
@@ -173,54 +151,47 @@ func (r *CreateSetterRunner) processSchema() error {
if err != nil {
return errors.Errorf("error marshalling schema: %v", err)
}
r.CreateSetter.Schema = string(b)
r.Schema = string(b)
return nil
}
func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSetter.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
rw := &kio.LocalPackageReadWriter{PackagePath: args[0]}
err := kio.Pipeline{
Inputs: []kio.Reader{rw},
Filters: []kio.Filter{&r.Set},
Outputs: []kio.Writer{rw}}.Execute()
err := e.Execute()
if err != nil {
return err
return runner.HandleError(c, err)
}
return nil
}
func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CreateSetterRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
sc, err := openapi.SchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
r.CreateSetter = settersutil.SetterCreator{
Name: r.CreateSetter.Name,
SetBy: r.CreateSetter.SetBy,
Description: r.CreateSetter.Description,
Type: r.CreateSetter.Type,
Schema: r.CreateSetter.Schema,
FieldName: r.CreateSetter.FieldName,
FieldValue: r.CreateSetter.FieldValue,
Required: r.CreateSetter.Required,
RecurseSubPackages: r.CreateSetter.RecurseSubPackages,
Name: r.SetterName,
SetBy: r.SetBy,
Description: r.Description,
Type: r.Type,
Schema: r.Schema,
FieldName: r.FieldName,
FieldValue: r.FieldValue,
Required: r.Required,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
SettersSchema: sc,
}
err := r.CreateSetter.Create()
err = r.CreateSetter.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSetter.RecurseSubPackages {

View File

@@ -466,60 +466,6 @@ spec:
replicas: 3 # {"$openapi":"foo.bar"}
`,
},
{
name: "create setter v1",
args: []string{"hubsetter", "my-hub"},
inputOpenAPI: `
`,
input: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name"
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub: my-hub
`,
expectedOpenAPI: `
`,
expectedResources: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name"
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub: my-hub # {"type":"","x-kustomize":{"setter":{"name":"hubsetter","value":"my-hub"}}}
`,
},
{
name: "create partial setter v1",
args: []string{"regionsetter", "us-east1-d", "--partial"},
inputOpenAPI: `
`,
input: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name" # {"type":"","x-kustomize":{"partialSetters":[{"name":"projectsetter","value":"project-id"}]}}
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub: my-hub # {"type":"","x-kustomize":{"setter":{"name":"hubsetter","value":"my-hub"}}}
`,
expectedOpenAPI: `
`,
expectedResources: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name" # {"type":"","x-kustomize":{"partialSetters":[{"name":"projectsetter","value":"project-id"},{"name":"regionsetter","value":"us-east1-d"}]}}
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub: my-hub # {"type":"","x-kustomize":{"setter":{"name":"hubsetter","value":"my-hub"}}}
`,
},
{
name: "provide different type values in schema and with flag",
args: []string{"replicas", "3", "--description", "hello world", "--type", "string"},

View File

@@ -10,6 +10,8 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -32,7 +34,7 @@ func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
"creates substitution recursively in all the nested subpackages")
_ = cs.MarkFlagRequired("pattern")
_ = cs.MarkFlagRequired("field-value")
fixDocs(parent, cs)
runner.FixDocs(parent, cs)
r.Command = cs
return r
}
@@ -49,22 +51,26 @@ type CreateSubstitutionRunner struct {
}
func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CreateSubstitutionRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
sc, err := openapi.SchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
r.CreateSubstitution = settersutil.SubstitutionCreator{
Name: r.CreateSubstitution.Name,
FieldName: r.CreateSubstitution.FieldName,
@@ -74,9 +80,10 @@ func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
SettersSchema: sc,
}
err := r.CreateSubstitution.Create()
err = r.CreateSubstitution.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSubstitution.RecurseSubPackages {

View File

@@ -11,7 +11,9 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -29,7 +31,7 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
}
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes setter recursively in all the nested subpackages")
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
return r
@@ -56,22 +58,25 @@ func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
}
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *DeleteSetterRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
sc, err := openapi.SchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
r.DeleteSetter = settersutil.DeleterCreator{
Name: r.DeleteSetter.Name,
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
@@ -79,9 +84,10 @@ func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
SettersSchema: sc,
}
err := r.DeleteSetter.Delete()
err = r.DeleteSetter.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSetter.RecurseSubPackages {

View File

@@ -10,7 +10,9 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -25,7 +27,7 @@ func NewDeleteSubstitutionRunner(parent string) *DeleteSubstitutionRunner {
}
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes substitution recursively in all the nested subpackages")
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
return r
@@ -52,21 +54,25 @@ func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
}
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *DeleteSubstitutionRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
sc, err := openapi.SchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
r.DeleteSubstitution = settersutil.DeleterCreator{
Name: r.DeleteSubstitution.Name,
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,
@@ -74,9 +80,10 @@ func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
SettersSchema: sc,
}
err := r.DeleteSubstitution.Delete()
err = r.DeleteSubstitution.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSubstitution.RecurseSubPackages {

View File

@@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/krmfile"
)
@@ -26,7 +27,7 @@ func GetInitRunner(name string) *InitRunner {
Example: commands.InitExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
r.Command = c
return r
}

View File

@@ -14,8 +14,9 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2"
)
@@ -37,7 +38,7 @@ func NewListSettersRunner(parent string) *ListSettersRunner {
"include substitutions in the output")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"list setters recursively in all the nested subpackages")
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
return r
}
@@ -48,46 +49,46 @@ func ListSettersCommand(parent string) *cobra.Command {
type ListSettersRunner struct {
Command *cobra.Command
Lookup setters.LookupSetters
List setters2.List
Markdown bool
IncludeSubst bool
RecurseSubPackages bool
Name string
}
func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
if len(args) > 1 {
r.Lookup.Name = args[1]
r.List.Name = args[1]
r.Name = args[1]
}
initSetterVersion(c, args)
return nil
}
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
return handleError(c, lookup(r.Lookup, c, args))
err := e.Execute()
if err != nil {
return runner.HandleError(c, err)
}
return nil
}
func (r *ListSettersRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *ListSettersRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
sc, err := openapi.SchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
r.List = setters2.List{
Name: r.List.Name,
Name: r.Name,
OpenAPIFileName: ext.KRMFileName(),
SettersSchema: sc,
}
openAPIPath := filepath.Join(pkgPath, ext.KRMFileName())
if err := r.ListSetters(w, openAPIPath, pkgPath); err != nil {
@@ -107,7 +108,7 @@ func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath s
return err
}
table := newTable(w, r.Markdown)
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED"})
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED", "IS SET"})
for i := range r.List.Setters {
s := r.List.Setters[i]
v := s.Value
@@ -117,20 +118,23 @@ func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath s
v = strings.Join(s.ListValues, ",")
v = fmt.Sprintf("[%s]", v)
}
var required string
required := "No"
if s.Required {
required = "Yes"
} else {
required = "No"
}
isSet := "No"
if s.IsSet {
isSet = "Yes"
}
table.Append([]string{
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count), required})
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count), required, isSet})
}
table.Render()
if len(r.List.Setters) == 0 {
// exit non-0 if no matching setters are found
if ExitOnError {
if runner.ExitOnError {
os.Exit(1)
}
}

View File

@@ -46,8 +46,8 @@ metadata:
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 me hello world 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 3 me hello world 1 Yes No
`,
},
@@ -72,8 +72,8 @@ metadata:
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 4 me hello world 1 No
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 4 me hello world 1 No No
`,
},
{
@@ -131,10 +131,10 @@ spec:
- name: nginx2
image: nginx # {"$ref": "#/definitions/io.k8s.cli.setters.image"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 2 No
replicas 3 me1 hello world 1 1 No
tag 1.7.9 me3 hello world 3 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 2 No No
replicas 3 me1 hello world 1 1 No No
tag 1.7.9 me3 hello world 3 1 Yes No
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
image IMAGE:TAG [image,tag]
@@ -207,10 +207,10 @@ spec:
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 No
replicas 3 me1 hello world 1 2 No
tag 1.7.9 me3 hello world 3 2 No
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 3 No No
replicas 3 me1 hello world 1 2 No No
tag 1.7.9 me3 hello world 3 2 No No
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
image IMAGE:TAG [image,tag]
@@ -284,8 +284,8 @@ spec:
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 3 Yes No
`,
},
@@ -324,8 +324,8 @@ spec:
- "b"
- "c"
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
list [a,b,c] me hello world 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
list [a,b,c] me hello world 1 Yes No
`,
},
@@ -390,10 +390,10 @@ openAPI:
name: my-other-setter
value: nginxotherthing
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
my-image-setter nginx 2 No
my-other-setter nginxotherthing 1 No
my-tag-setter 1.7.9 2 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
my-image-setter nginx 2 No No
my-other-setter nginxotherthing 1 No No
my-tag-setter 1.7.9 2 Yes Yes
------------------ ------------------------------------------------ -----------------------------------
SUBSTITUTION PATTERN REFERENCES
my-image-subst ${my-image-setter}::${my-tag-setter} [my-image-setter,my-tag-setter]
@@ -476,20 +476,20 @@ func TestListSettersSubPackages(t *testing.T) {
expected: `
test/testdata/dataset-with-setters/mysql/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image mysql 1 No
namespace myspace 1 No
tag 1.7.9 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image mysql 1 No No
namespace myspace 1 No No
tag 1.7.9 1 No No
--------------- ----------------- --------------
SUBSTITUTION PATTERN REFERENCES
image-tag ${image}:${tag} [image,tag]
test/testdata/dataset-with-setters/mysql/nosetters/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
test/testdata/dataset-with-setters/mysql/storage/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
namespace myspace 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
namespace myspace 1 No No
`,
},
{
@@ -499,10 +499,10 @@ test/testdata/dataset-with-setters/mysql/storage/
expected: `
test/testdata/dataset-with-setters/mysql/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image mysql 1 No
namespace myspace 1 No
tag 1.7.9 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image mysql 1 No No
namespace myspace 1 No No
tag 1.7.9 1 No No
`,
},
}

View File

@@ -6,16 +6,13 @@ package commands
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -31,17 +28,17 @@ func NewSetRunner(parent string) *SetRunner {
PreRunE: r.preRunE,
RunE: r.runE,
}
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
c.Flags().StringArrayVar(&r.Values, "values", []string{},
"optional flag, the values of the setter to be set to")
c.Flags().StringVar(&r.Perform.SetBy, "set-by", "",
c.Flags().StringVar(&r.SetBy, "set-by", "",
"annotate the field with who set it")
c.Flags().StringVar(&r.Perform.Description, "description", "",
c.Flags().StringVar(&r.Description, "description", "",
"annotate the field with a description of its value")
c.Flags().StringVar(&setterVersion, "version", "",
"use this version of the setter format")
c.Flags().BoolVarP(&r.Set.RecurseSubPackages, "recurse-subpackages", "R", false,
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"sets recursively in all the nested subpackages")
c.Flags().MarkHidden("version")
@@ -55,31 +52,16 @@ func SetCommand(parent string) *cobra.Command {
}
type SetRunner struct {
Command *cobra.Command
Lookup setters.LookupSetters
Perform setters.PerformSetters
Set settersutil.FieldSetter
OpenAPIFile string
Values []string
}
func initSetterVersion(c *cobra.Command, args []string) error {
setterVersion = "v2"
l := setters.LookupSetters{}
// backwards compatibility for resources with setter v1
err := kio.Pipeline{
Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: args[0]}},
Filters: []kio.Filter{&l},
}.Execute()
if err != nil {
return err
}
if len(l.SetterCounts) > 0 {
setterVersion = "v1"
}
return nil
Command *cobra.Command
Set settersutil.FieldSetter
OpenAPIFile string
Values []string
SetBy string
Description string
Name string
Value string
ListValues []string
RecurseSubPackages bool
}
func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
@@ -89,79 +71,52 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
return errors.Errorf("value should set either from flag or arg")
}
if len(args) > 1 {
r.Perform.Name = args[1]
r.Lookup.Name = args[1]
}
r.Name = args[1]
if valueFlagSet {
r.Perform.Value = r.Values[0]
} else if len(args) > 2 {
r.Perform.Value = args[2]
r.Value = r.Values[0]
} else {
r.Value = args[2]
}
if setterVersion == "" {
if len(args) < 2 || len(args) < 3 && !valueFlagSet {
setterVersion = "v1"
} else if err := initSetterVersion(c, args); err != nil {
return err
}
// set remaining values as list values
if valueFlagSet && len(r.Values) > 1 {
r.ListValues = r.Values[1:]
} else if !valueFlagSet && len(args) > 3 {
r.ListValues = args[3:]
}
if setterVersion == "v2" {
r.Set.Name = args[1]
if valueFlagSet {
r.Set.Value = r.Values[0]
} else {
r.Set.Value = args[2]
}
// set remaining values as list values
if valueFlagSet && len(r.Values) > 1 {
r.Set.ListValues = r.Values[1:]
} else if !valueFlagSet && len(args) > 3 {
r.Set.ListValues = args[3:]
}
r.Set.Description = r.Perform.Description
r.Set.SetBy = r.Perform.SetBy
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName())
}
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName())
return nil
}
func (r *SetRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.Set.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
if len(args) > 2 || c.Flag("values").Changed {
return handleError(c, r.perform(c, args))
err := e.Execute()
if err != nil {
return runner.HandleError(c, err)
}
return handleError(c, lookup(r.Lookup, c, args))
return nil
}
func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *SetRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.Set = settersutil.FieldSetter{
Name: r.Set.Name,
Value: r.Set.Value,
ListValues: r.Set.ListValues,
Description: r.Set.Description,
SetBy: r.Set.SetBy,
Name: r.Name,
Value: r.Value,
ListValues: r.ListValues,
Description: r.Description,
SetBy: r.SetBy,
Count: 0,
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
OpenAPIFileName: ext.KRMFileName(),
ResourcesPath: pkgPath,
RecurseSubPackages: r.Set.RecurseSubPackages,
RecurseSubPackages: r.RecurseSubPackages,
IsSet: true,
}
count, err := r.Set.Set()
if err != nil {
@@ -177,65 +132,3 @@ func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
}
return nil
}
func lookup(l setters.LookupSetters, c *cobra.Command, args []string) error {
// lookup the setters
err := kio.Pipeline{
Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: args[0]}},
Filters: []kio.Filter{&l},
}.Execute()
if err != nil {
return err
}
table := tablewriter.NewWriter(c.OutOrStdout())
table.SetRowLine(false)
table.SetBorder(false)
table.SetHeaderLine(false)
table.SetColumnSeparator(" ")
table.SetCenterSeparator(" ")
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetHeader([]string{
"NAME", "DESCRIPTION", "VALUE", "TYPE", "COUNT", "SETBY",
})
for i := range l.SetterCounts {
s := l.SetterCounts[i]
v := s.Value
if s.Value == "" {
v = s.Value
}
table.Append([]string{
s.Name,
"'" + s.Description + "'",
v,
fmt.Sprintf("%v", s.Type),
fmt.Sprintf("%d", s.Count),
s.SetBy,
})
}
table.Render()
if len(l.SetterCounts) == 0 {
// exit non-0 if no matching setters are found
os.Exit(1)
}
return nil
}
// perform the setters
func (r *SetRunner) perform(c *cobra.Command, args []string) error {
rw := &kio.LocalPackageReadWriter{
PackagePath: args[0],
}
// perform the setters in the package
err := kio.Pipeline{
Inputs: []kio.Reader{rw},
Filters: []kio.Filter{&r.Perform},
Outputs: []kio.Writer{rw},
}.Execute()
if err != nil {
return err
}
fmt.Fprintf(c.OutOrStdout(), "set %d fields\n", r.Perform.Count)
return nil
}

View File

@@ -942,70 +942,6 @@ spec:
`,
errMsg: "cyclic substitution detected with name my-nested-subst",
},
{
name: "set v1 setter asm",
args: []string{"profilesetter", "my-asm"},
out: "set 1 fields\n",
inputOpenAPI: `
`,
input: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name"
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub:
- --gcr.io/asm-testing
- --gcr.io/asm-testing2
`,
expectedOpenAPI: `
`,
expectedResources: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name"
spec:
profile: my-asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"my-asm"}}}
hub:
- --gcr.io/asm-testing
- --gcr.io/asm-testing2
`,
},
{
name: "set v1 partial setter",
args: []string{"gcloud.core.project", "my-project"},
out: "set 1 fields\n",
inputOpenAPI: `
`,
input: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "project-id/us-east1-d/cluster-name" # {"type":"string","x-kustomize":{"partialSetters":[{"name":"gcloud.core.project","value":"project-id"},{"name":"cluster-name","value":"cluster-name"},{"name":"gcloud.compute.zone","value":"us-east1-d"}]}}
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub:
- --gcr.io/asm-testing
- --gcr.io/asm-testing2
`,
expectedOpenAPI: `
`,
expectedResources: `
apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
clusterName: "my-project/us-east1-d/cluster-name" # {"type":"string","x-kustomize":{"partialSetters":[{"name":"gcloud.core.project","value":"my-project"},{"name":"cluster-name","value":"cluster-name"},{"name":"gcloud.compute.zone","value":"us-east1-d"}]}}
spec:
profile: asm # {"type":"string","x-kustomize":{"setter":{"name":"profilesetter","value":"asm"}}}
hub:
- --gcr.io/asm-testing
- --gcr.io/asm-testing2
`,
},
}
for i := range tests {
test := tests[i]

View File

@@ -10,6 +10,7 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -135,5 +136,5 @@ func (r *WrapRunner) runE(c *cobra.Command, args []string) error {
Writer: c.OutOrStdout(),
WrappingKind: kio.ResourceListKind,
WrappingAPIVersion: kio.ResourceListAPIVersion}}}.Execute()
return handleError(c, err)
return runner.HandleError(c, err)
}

View File

@@ -11,6 +11,7 @@ import (
"unicode"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -211,7 +212,7 @@ func (r *XArgsRunner) runE(c *cobra.Command, _ []string) error {
return err
}
return handleError(c, run.Run())
return runner.HandleError(c, run.Run())
}
func parseYNode(node *yaml.Node) string {

View File

@@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/sets"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -26,7 +27,7 @@ func GetCountRunner(name string) *CountRunner {
Example: commands.CountExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.Kind, "kind", true,
"count resources by kind.")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
@@ -51,24 +52,24 @@ func (r *CountRunner) runE(c *cobra.Command, args []string) error {
if len(args) == 0 {
input := &kio.ByteReader{Reader: c.InOrStdin()}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: []kio.Reader{input},
Outputs: r.out(c.OutOrStdout()),
}.Execute())
}
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
e := runner.ExecuteCmdOnPkgs{
Writer: c.OutOrStdout(),
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
}
return e.execute()
return e.Execute()
}
func (r *CountRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CountRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
err := kio.Pipeline{

View File

@@ -1,5 +1,5 @@
module sigs.k8s.io/kustomize/cmd/config/internal/commands/e2e/e2econtainerconfig
go 1.14
go 1.15
require sigs.k8s.io/kustomize/kyaml v0.1.10

View File

@@ -35,8 +35,8 @@ openAPI:
},
expectedStdOut: `
./
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 3 1 No No
`,
},
}

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