Compare commits

...

394 Commits

Author SHA1 Message Date
k8s-ci-robot
58492e2d83 Merge pull request #349 from Liujingfang1/master
fix the release and build files
2018-09-13 12:00:36 -07:00
Jingfang Liu
a9f44aa259 fix the release and build files 2018-09-13 11:51:47 -07:00
k8s-ci-robot
b17d7fbbfd Merge pull request #339 from lswith/master
treat sub paths correctly
2018-09-13 09:24:09 -07:00
Luke Swithenbank
d78e77fb92 fix remote build's for subdirectories 2018-09-13 09:56:04 +10:00
Jingfang Liu
64fdb8d760 change github.com/kubernetes-sigs to sigs.k8s.io (#343)
* change github.com/kubernetes-sigs to sigs.k8s.io

* change go_import_path in .travis.yml
2018-09-12 12:41:38 -07:00
Jeff Regan
a377ec1dde Merge pull request #342 from Liujingfang1/master
remove dependency on internal error
2018-09-12 11:08:52 -07:00
Jingfang Liu
87e9964091 Merge pull request #341 from ebriand/patch-1
Fix typo in multibases readme
2018-09-12 09:17:21 -07:00
Jingfang Liu
60d8334fed remove dependency on internal error 2018-09-11 15:23:30 -07:00
Eric Briand
71f5105a86 Fix typo on staging 2018-09-11 13:33:28 +02:00
Jeff Regan
09a62efe88 Merge pull request #331 from burdiyan/master
Implement support for digests in imageTags
2018-09-10 10:57:53 -07:00
Alexandr Burdiyan
6dbf4b5b60 Apply code review recommendations 2018-09-10 11:48:47 +02:00
Alexandr Burdiyan
5401bd367b Implement support for digests in imageTags
This commit adds a new field to imageTags transformer
so that digests can be used instead of image tags if needed.

Closes https://github.com/kubernetes-sigs/kustomize/issues/326
2018-09-10 11:21:53 +02:00
Jeff Regan
f7def79764 Merge pull request #333 from monopole/deleteCode
Remove duplicate code.
2018-09-09 13:51:54 -07:00
jregan
cda909a609 Remove duplicate code. 2018-09-09 12:33:23 -07:00
k8s-ci-robot
6f61cadf9f Merge pull request #325 from Liujingfang1/master
Add examples and docs for patchesJson6902
2018-09-07 13:14:34 -07:00
Jingfang Liu
1c616b1962 Add examples and docs for patchesJson6902 2018-09-07 11:55:12 -07:00
Jeff Regan
849343fb41 Merge pull request #324 from Liujingfang1/master
Enable jsonpath transformers in application
2018-09-06 14:18:47 -07:00
Jingfang Liu
8810027d89 Enable jsonpath transformers in application 2018-09-06 14:02:30 -07:00
k8s-ci-robot
548ea8a9fb Merge pull request #323 from Liujingfang1/master
remove inline json patch format
2018-09-06 13:36:19 -07:00
Jingfang Liu
81b5cf65d6 remove inline json patch format 2018-09-06 11:18:19 -07:00
Jeff Regan
dc9ae64646 Merge pull request #321 from Liujingfang1/multibases
filter by namespace, prefix and detect conflict when resolving name reference
2018-09-05 16:10:53 -07:00
Jingfang Liu
829cb2baa3 address comments 2018-09-05 16:08:24 -07:00
Jingfang Liu
7b301446fa filter by namespace and nameprefix in namereference transformer 2018-09-05 13:17:44 -07:00
Jingfang Liu
4a297fa138 improve idslice 2018-09-05 13:02:51 -07:00
Jingfang Liu
7811d9f2bc Add multibases test with namereference conflict 2018-09-05 13:01:56 -07:00
Jingfang Liu
21ff81b758 Add multibases test with namereference nonconflict 2018-09-05 13:01:15 -07:00
Jingfang Liu
485bbddd3e Merge pull request #320 from Liujingfang1/master
remove go get varcheck
2018-09-04 15:43:59 -07:00
Jingfang Liu
6dc80293a6 remove go get varcheck 2018-09-04 15:07:38 -07:00
Jeff Regan
b649ad5c69 Merge pull request #310 from Liujingfang1/patchtransformer
Update patch factory and add multi transformer with checking conflicts
2018-09-04 09:32:08 -07:00
Jingfang Liu
d782abb214 Update patch factory and add multi transformer with checking conflicts 2018-09-04 09:13:26 -07:00
k8s-ci-robot
95f5becee1 Merge pull request #312 from monopole/fixSomeImports
Remove some unnecessary import renames.
2018-09-04 08:31:31 -07:00
k8s-ci-robot
694d809f33 Merge pull request #313 from monopole/fixMarkdownLinks
Fix some busted documentation links.
2018-08-31 18:30:41 -07:00
k8s-ci-robot
df3c3c3357 Merge pull request #314 from monopole/noCleanup
Remove unread variable.
2018-08-31 18:29:25 -07:00
Jeffrey Regan
99e770b05a Remove unused variable. 2018-08-31 17:25:00 -07:00
Jeffrey Regan
340cb2b385 Remove unnecessary import aliases. 2018-08-31 17:20:03 -07:00
Jeffrey Regan
cdbd83a645 Fix some busted documentation links. 2018-08-31 17:05:32 -07:00
Jeff Regan
fab2a5a5d7 Merge pull request #311 from monopole/updateDeps
Add gopkg.in/yaml.v2 to Gopkg.lock
2018-08-31 16:24:16 -07:00
Jeffrey Regan
8da2f37181 Add gopkg.in/yaml.v2 to Gopkg.lock 2018-08-31 16:20:18 -07:00
k8s-ci-robot
c906a0c16e Merge pull request #309 from monopole/cleanupAddLabels
Simplify addmetadata.
2018-08-31 16:13:31 -07:00
Jeffrey Regan
93618166b6 Cleanup addmetadata. 2018-08-31 15:58:36 -07:00
k8s-ci-robot
babfb3faa9 Merge pull request #300 from Liujingfang1/patchtransformer
Add transformer to apply json patch6902
2018-08-31 12:07:17 -07:00
Jingfang Liu
cedf215445 add PatchJson6902Factory to make transformer 2018-08-31 10:21:58 -07:00
Jeff Regan
51a4907f89 Merge pull request #307 from khrisrichardson/apimachinery-validation
use apimachinery for annotation/label validation
2018-08-31 09:42:47 -07:00
Khris Richardson
6457162383 use apimachinery for annotation/label validation 2018-08-31 07:40:00 -07:00
Jingfang Liu
7f0e9e3a6a Add patchJson6902 transformer 2018-08-30 15:34:42 -07:00
Jingfang Liu
95cf508b2b Add github.com/krishicks/yaml-patch to vendor 2018-08-30 13:45:25 -07:00
Jeff Regan
4a565ffdb8 Merge pull request #303 from gitirabassi/all-git-repos
if the prefix of the base is 'git::' will make the use of go-getter to download repo
2018-08-30 10:06:46 -07:00
Jeff Regan
17f1779a48 Merge pull request #302 from gitirabassi/storageClassSecret
Storage class secret
2018-08-30 10:03:03 -07:00
gitirabassi
a76cb0b008 force using the git protocol to downlaod every kind of repo non just from github 2018-08-30 11:02:03 +02:00
gitirabassi
9700bc3298 added all the documented secret for storageclasses 2018-08-29 23:05:40 +02:00
gitirabassi
ce31dac24f added storageclass paramether secret for glusterfs configuration with kustomize 2018-08-29 22:55:32 +02:00
k8s-ci-robot
a81b2e32e0 Merge pull request #299 from Liujingfang1/patch
change patches to patchesStrategicMerge in tests and examples
2018-08-28 13:57:00 -07:00
Jingfang Liu
b713d5a1cc change patches to patchesStrategicMerge in tests and examples 2018-08-28 09:40:34 -07:00
k8s-ci-robot
e11ba17248 Merge pull request #286 from Liujingfang1/master
Add patchesJson6902 and patchesStategicMerge to kustomization
2018-08-27 16:09:49 -07:00
Jingfang Liu
3d9d4bd36f address comments 2018-08-27 15:44:42 -07:00
Jingfang Liu
6a3e3c3a71 Add JSONPatch to kustomization 2018-08-27 13:52:21 -07:00
Jeff Regan
633c43a672 Merge pull request #292 from babiel/pdb-matchlabels
Disable creation of PDB matchLabels
2018-08-24 09:27:41 -07:00
Maximilian Gaß
0833693372 Disable creation of PDB matchLabels
Allow for using matchExpressions on its own
2018-08-24 13:51:05 +02:00
Jeff Regan
77c07ba96e Merge pull request #290 from philoserf/patch-1
trivial: Change dep constraint to an override
2018-08-23 17:07:44 -07:00
Mark Ayers
6847bb7924 trivial: Change dep constraint to an override
fixes #289
2018-08-23 15:58:27 -07:00
k8s-ci-robot
f0deaf707d Merge pull request #287 from emosbaugh/fix-gopath-isrepourl
Fix loader loader when run from gopath
2018-08-23 15:08:25 -07:00
Ethan Mosbaugh
e113944027 fix loader loader when run from gopath 2018-08-23 14:54:58 -07:00
k8s-ci-robot
1cf9131ae2 Merge pull request #285 from monopole/declutter
Move some docs to docs dir (declutter the top).
2018-08-23 13:33:06 -07:00
Jeffrey Regan
da142a8e97 Move some docs to docs dir (declutter the top). 2018-08-23 11:33:12 -07:00
Jeff Regan
6c81e3b95f Merge pull request #284 from Liujingfang1/vendor
Add missing files when running dep ensure
2018-08-23 11:27:47 -07:00
Jingfang Liu
a0089a2521 Add missing files when running dep ensure 2018-08-23 11:07:42 -07:00
k8s-ci-robot
11768f6232 Merge pull request #280 from monopole/fixntis
Fix some Go nits.
2018-08-23 10:37:58 -07:00
Jeff Regan
675c17737f Merge pull request #279 from Liujingfang1/quote
fix the double quotation problem in ConfigMapGenerator
2018-08-23 10:35:34 -07:00
Jeffrey Regan
735a93d000 Fix some Go nits. 2018-08-23 10:30:32 -07:00
Jeff Regan
67d2c2ed4a Merge pull request #281 from monopole/addVarCheck
Add varcheck to presubmit.
2018-08-23 10:25:32 -07:00
Jeffrey Regan
f931e15653 Add varcheck to presubmit. 2018-08-23 10:17:37 -07:00
Jingfang Liu
34169174a8 fix the double quotation problem in ConfigMapGenerator 2018-08-23 09:36:50 -07:00
Jeff Regan
ebf33964c7 Merge pull request #276 from kubernetes-sigs/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2018-08-22 20:05:47 -07:00
Jeff Regan
38a5e12d66 Create CODE_OF_CONDUCT.md 2018-08-22 20:05:19 -07:00
k8s-ci-robot
04ab218fa0 Merge pull request #275 from monopole/deletediff
Delete diff command and code it uses.
2018-08-22 18:38:39 -07:00
Jeffrey Regan
950c353f90 Delete diff command and code it uses. 2018-08-22 17:18:39 -07:00
Jeff Regan
aff09b1108 Merge pull request #271 from Liujingfang1/cleanup
cleanup after handling remote bases
2018-08-22 17:14:11 -07:00
Jingfang Liu
6da691f874 cleanup after handling remote bases 2018-08-22 13:22:45 -07:00
Jeff Regan
22c99aa535 Merge pull request #274 from monopole/docsreadme
Tweak docs readme
2018-08-22 12:21:32 -07:00
Jeffrey Regan
5fa209acfa Tweak docs readme 2018-08-22 12:20:13 -07:00
Jeff Regan
d72879e109 Merge pull request #147 from guineveresaenger/labels-and-annotations
Edit add label/annotation
2018-08-22 10:33:00 -07:00
Jeff Regan
337f3631ff Merge pull request #272 from Liujingfang1/docs
Add docs README.md
2018-08-22 10:22:00 -07:00
guineveresaenger
b3993dc874 Adds starter validation framework for semantic validation of inputs. 2018-08-22 18:20:51 +02:00
guineveresaenger
11c04dd6c4 Removes semantic validation from addmetadata.go and tests.
Due to moving some input parsing to the Validate method, it was renamed to reflect this additional purpose.
Tests were removed where appropriate.
2018-08-22 18:15:34 +02:00
Jingfang Liu
b29e449d4a Add docs README.md 2018-08-22 09:05:54 -07:00
Jingfang Liu
430f2f84fb Merge pull request #270 from Liujingfang1/docs
fix bug in the example download links
2018-08-21 12:08:32 -07:00
Jingfang Liu
52c6b5755b fix bug in the example download links 2018-08-21 12:04:53 -07:00
k8s-ci-robot
958bc63293 Merge pull request #269 from Liujingfang1/pvc
Add namereference of PersistentVolume in PersistentVolumeClain
2018-08-21 09:48:33 -07:00
Jingfang Liu
94ed0fe515 Add namereference of PersistentVolume in PersistentVolumeClain 2018-08-21 09:37:25 -07:00
Jeff Regan
bb8233ceff Merge pull request #265 from Liujingfang1/metadata
add typemeta to kustomization
2018-08-20 13:59:43 -07:00
Jingfang Liu
6221bed190 add typemeta to kustomization 2018-08-20 13:47:33 -07:00
k8s-ci-robot
1ffeb181e7 Merge pull request #264 from Liujingfang1/docs
Add example for kustomize build {url} and remote bases
2018-08-20 12:19:00 -07:00
Jingfang Liu
759ba1cbf4 Add example for kustomize build {url} 2018-08-20 09:52:32 -07:00
k8s-ci-robot
12f2c41273 Merge pull request #266 from ahmetb/patch-1
add homebrew package to INSTALL.md
2018-08-17 10:48:01 -07:00
Ahmet Alp Balkan
2174741376 add homebrew package to INSTALL.md 2018-08-17 07:50:28 -07:00
guineveresaenger
31dd8fc5b1 Restructured tests 2018-08-16 13:32:42 -07:00
guineveresaenger
77f4811779 Tests test Validate function 2018-08-16 02:36:11 -07:00
Jeff Regan
7050a45134 Merge pull request #262 from Liujingfang1/repoUrl3
Add all dependency of go-getter
2018-08-15 15:47:35 -07:00
k8s-ci-robot
3b64f1e102 Merge pull request #260 from Liujingfang1/repoUrl2
Add kustomize build {repoUrl}
2018-08-15 15:45:00 -07:00
Jingfang Liu
6c4c79e2cc Merge pull request #263 from Liujingfang1/gc
Add garbage collection KEP link
2018-08-15 15:22:21 -07:00
Jingfang Liu
3975ebc21a Add garbage collection KEP link 2018-08-15 15:19:18 -07:00
Jingfang Liu
ec95e5f97e Add all dependency of go-getter 2018-08-15 11:37:03 -07:00
Jingfang Liu
72b1a4bc5c combine fileLoader.New and NewLoader into one function: NewLoader 2018-08-15 11:04:31 -07:00
k8s-ci-robot
16447efca3 Merge pull request #255 from sethpollack/secret
add docs for envCommand
2018-08-15 09:35:02 -07:00
guineveresaenger
524d593c5c Separate functions for RunnAddLabel and RunAddAnnotation 2018-08-15 03:51:56 -07:00
guineveresaenger
3b644474c4 Parse data into string map for easy access in RunAddMetadata 2018-08-15 03:13:03 -07:00
Seth Pollack
42e6ced2b0 add docs 2018-08-14 20:55:26 -04:00
Jingfang Liu
f018370628 Add kustomize build {repoUrl} 2018-08-14 16:10:51 -07:00
Jeff Regan
c9a8bc1121 Merge pull request #256 from ivan4th/command-timeout-1
Add timeoutSeconds to secretArgs
2018-08-14 14:54:50 -07:00
k8s-ci-robot
8c7cbb12dd Merge pull request #257 from Liujingfang1/repoUrl2
Add dependency: github.com/hashicorp/go-getter
2018-08-14 14:49:29 -07:00
Jingfang Liu
b02f7775c5 manually add dependency on go-getter 2018-08-14 14:37:31 -07:00
Ivan Shvedunov
f9a0e671b7 Add timeoutSeconds to secretArgs 2018-08-14 22:55:59 +03:00
Jeff Regan
70fb22cad6 Merge pull request #250 from ivan4th/fix-resource-load-crash
Don't crash on resource load errors
2018-08-14 12:53:24 -07:00
Ivan Shvedunov
2ae00db6a9 Don't crash on resource load errors 2018-08-14 22:14:12 +03:00
k8s-ci-robot
f9577ab540 Merge pull request #247 from ryane/setnamespace
add support for `kustomize edit set namespace`
2018-08-13 11:17:06 -07:00
guineveresaenger
6a2786a5c4 Remove Complete function and references 2018-08-13 07:49:51 -07:00
guineveresaenger
924aa6fb29 Use iota declaration for constants and implements string method for KindOfAdd metadata 2018-08-13 07:46:06 -07:00
ryane
e2cd44f9d8 add support for kustomize edit set namespace
fixes #246
2018-08-10 22:42:50 -04:00
Jeff Regan
017c4ae0aa Merge pull request #245 from Liujingfang1/output
Add -o flag to kustomize build
2018-08-09 16:49:25 -07:00
Jingfang Liu
7b2baad390 Add -o flag to kustomize build 2018-08-09 13:15:39 -07:00
Jeff Regan
bc2d69f4f9 Merge pull request #241 from sethpollack/secret
add env sources to secrets
2018-08-09 13:05:21 -07:00
Jeff Regan
e913a71fad Merge pull request #244 from Liujingfang1/deprecation
Add deprecation message for namePrefix behavior change
2018-08-09 13:04:36 -07:00
Seth Pollack
7406dda074 fixes 2018-08-09 14:45:56 -04:00
Jingfang Liu
0b4df3d414 Add deprecation message for namePrefix behavior change 2018-08-09 11:25:37 -07:00
Jeff Regan
7d38916d63 Merge pull request #243 from monopole/updateDeps
Automated update of Gopkg.lock via dep ensure
2018-08-09 11:08:47 -07:00
Jeffrey Regan
79d1abe573 dep ensure run 2018-08-09 10:54:29 -07:00
Jeff Regan
9563052094 Merge pull request #233 from Liujingfang1/glob2
preserve order and comments in edit
2018-08-09 09:49:30 -07:00
Seth Pollack
f881c19bb6 add env sources to secrets 2018-08-09 09:17:53 -04:00
Jingfang Liu
8d7b5f82c4 preserve order and comments in edit 2018-08-08 15:03:16 -07:00
Jingfang Liu
7554406c61 Merge pull request #240 from kubernetes-sigs/revert-239-namespace2
Revert "Skip adding nameprefix to namespace"
2018-08-08 13:41:38 -07:00
Jingfang Liu
cf17050170 Revert "Skip adding nameprefix to namespace" 2018-08-08 13:39:01 -07:00
k8s-ci-robot
3857a67701 Merge pull request #239 from Liujingfang1/namespace2
Skip adding nameprefix to namespace
2018-08-08 11:56:15 -07:00
Jingfang Liu
10665c6fc9 Skip adding nameprefix to namespace 2018-08-08 10:02:42 -07:00
k8s-ci-robot
e0a09f4755 Merge pull request #237 from Liujingfang1/ingress
add namepreference for secret in ingress annotation
2018-08-08 09:49:06 -07:00
Jingfang Liu
31c6a55747 add namepreference for secret in ingress annotation 2018-08-07 13:26:39 -07:00
Jeff Regan
8332a70d19 Merge pull request #231 from bendory/master
Container Builder has been renamed Cloud Build
2018-08-03 10:29:23 -07:00
David Bendory
7fe2338acd Container Builder has been renamed Cloud Build 2018-08-03 13:22:49 -04:00
k8s-ci-robot
43d4dbc07a Merge pull request #228 from Liujingfang1/glob2
Change the order of validate and  expandFileSource in add configmap
2018-08-02 16:26:27 -07:00
Jingfang Liu
f0cf4579d2 Change the order of validate and expandFileSource in add configmap subcommand 2018-08-02 11:39:27 -07:00
k8s-ci-robot
68ba37f139 Merge pull request #226 from Liujingfang1/glob2
Add glob support in subcommands `add patch` and `add configmap`
2018-08-02 11:19:27 -07:00
Jingfang Liu
bf73633cda Add glob support in subcommands add patch and add configmap 2018-08-02 11:01:20 -07:00
Jeff Regan
55f8828ba1 Merge pull request #222 from Liujingfang1/glob
Add glob support in edit add resource
2018-08-01 15:51:45 -07:00
Jeff Regan
0e1307dccf Merge pull request #224 from Liujingfang1/imagetag
Use regexp in set imagetag
2018-08-01 15:50:50 -07:00
Jingfang Liu
4471b75912 Use regexp in set imagetag 2018-08-01 11:58:21 -07:00
k8s-ci-robot
75c6204337 Merge pull request #225 from Liujingfang1/pathconfig
Add ingress annotations to the namereference path config
2018-08-01 11:52:40 -07:00
Jingfang Liu
1b7171ac9e Add glob support in edit add resource 2018-08-01 11:43:28 -07:00
Jingfang Liu
5193d6b4a8 Add ingress annotations to the namereference path config 2018-08-01 10:47:01 -07:00
Jeff Regan
6a834b6262 Merge pull request #223 from monopole/noFlags
More description of eschewed features
2018-07-31 11:49:56 -07:00
Jeffrey Regan
083d3cbb65 More description of eschewed features 2018-07-31 11:48:36 -07:00
k8s-ci-robot
e68411b71e Merge pull request #220 from monopole/noglobbing
Eschew globbing doc
2018-07-31 10:04:47 -07:00
Jeff Regan
664774576c Merge pull request #219 from Liujingfang1/glob
remove glob support from kustomization.yaml
2018-07-30 17:03:53 -07:00
Jeffrey Regan
37e97084f9 Eschew globbing doc 2018-07-30 16:57:16 -07:00
Jingfang Liu
de4d8b7dfa remove glob support from kustomization.yaml 2018-07-30 16:28:40 -07:00
k8s-ci-robot
7f97108686 Merge pull request #216 from Liujingfang1/namespace
Add multibases example with different namespace
2018-07-30 15:54:46 -07:00
Jingfang Liu
71f069cf95 Add multibases example with different namespace 2018-07-30 15:21:53 -07:00
k8s-ci-robot
3dbe732cb5 Merge pull request #215 from monopole/eschewed
Enumerate eschewed features in a document.
2018-07-30 15:01:40 -07:00
Jeff Regan
e5aea4423b Merge pull request #214 from Liujingfang1/namespace
add namespace in ResId
2018-07-30 15:00:10 -07:00
Jeff Regan
100f05260e Merge pull request #209 from Liujingfang1/yaml
ignore the empty YAML object
2018-07-30 14:57:15 -07:00
Jeffrey Regan
02f9329747 Enumerate eschewed features in docs 2018-07-30 14:56:20 -07:00
Jingfang Liu
b6abd7600c add namespace in ResId 2018-07-30 14:04:35 -07:00
Jingfang Liu
2e7093e67f ignore the empty YAML object 2018-07-30 12:58:11 -07:00
k8s-ci-robot
3b3a272d27 Merge pull request #213 from Liujingfang1/imagetags
use regexp to determine if the image matched in imagetag transformer
2018-07-30 11:58:56 -07:00
Jingfang Liu
36115a7fa3 use regexp to determin if the image matched in imagetag transformer 2018-07-30 11:09:32 -07:00
k8s-ci-robot
4d9d54e2c7 Merge pull request #204 from Liujingfang1/diamond
Add support for using common base
2018-07-27 14:00:57 -07:00
Jingfang Liu
88aec95628 remove commented code
update multibases/README.md
2018-07-27 13:45:49 -07:00
Jingfang Liu
e30401489d Add example for multibases 2018-07-27 10:43:16 -07:00
Jingfang Liu
58bc4b14a2 Add support for using common base 2018-07-27 10:16:44 -07:00
Jeff Regan
2824c28e08 Merge pull request #203 from mortent/BetterSecretGenErrorMessage
More information in error message when secret gen fails
2018-07-26 15:45:40 -07:00
Morten Torkildsen
d7cbb95d9c More information in error message when secret gen fails 2018-07-26 12:50:07 -07:00
k8s-ci-robot
e771ec1169 Merge pull request #201 from monopole/meh
Combine loaderImpl and fileLoader.
2018-07-26 10:09:56 -07:00
Jeffrey Regan
9e5374e725 Combine loaderImpl and fileLoader. 2018-07-25 17:23:04 -07:00
k8s-ci-robot
4569a09d54 Merge pull request #200 from monopole/deleteDuplicativeCode
Delete duplicative code.
2018-07-25 09:33:55 -07:00
jregan
25d3ad7522 Delete duplicative code. 2018-07-24 20:42:43 -07:00
Jeff Regan
77e18724db Merge pull request #199 from monopole/moarDeletion
Drop the notion of the SchemeLoader
2018-07-24 18:18:25 -07:00
k8s-ci-robot
12d1771bb3 Merge pull request #197 from Liujingfang1/master
Change configmapGenerator to configmap.yaml in helloWorld example
2018-07-24 13:50:56 -07:00
Jeffrey Regan
a78aa22399 Drop useless or duplicative code. 2018-07-24 13:25:26 -07:00
Jingfang Liu
05a91893bf break helloWorld example into two examples:
- one for declaring a ConfigMap as resources
- one for declaring a ConfigMap from ConfigMapGenerator and rolling
update
2018-07-24 11:35:15 -07:00
Jeff Regan
8d420ec3f7 Merge pull request #196 from Liujingfang1/cr
Add docs and demo for imageTags
2018-07-23 16:44:12 -07:00
Jingfang Liu
838a766d12 Add docs and demo for imageTags 2018-07-23 16:35:04 -07:00
k8s-ci-robot
50d79e4d3e Merge pull request #198 from monopole/anotherWayToDelete
Delete some code.
2018-07-23 15:52:24 -07:00
Jeff Regan
4d2d450f6e Merge pull request #191 from babiel/fix-diff-tests-on-macos
Fix wrong path in diff tests on macOS
2018-07-23 15:37:29 -07:00
Jeff Regan
fdc46fb0b1 Delete some code. 2018-07-23 15:23:30 -07:00
k8s-ci-robot
92ac9b5a0e Merge pull request #194 from droot/bugfix/version-fix-issue-148
fixed version info injection in build script
2018-07-23 14:42:18 -07:00
Jeff Regan
857a9df70f Merge pull request #195 from monopole/tightenUp
Pull factories up call stack (make them less often).
2018-07-23 14:02:47 -07:00
Jeffrey Regan
969f4f28fa Pull factories out of the bowels. 2018-07-23 13:48:46 -07:00
Sunil Arora
58aa45c50a fixed version info injection in build script
fixes #148
2018-07-23 11:54:37 -07:00
k8s-ci-robot
5715f4bab4 Merge pull request #192 from Liujingfang1/cr
Add set imagetag command
2018-07-23 10:56:18 -07:00
Jingfang Liu
c8502c78f5 drop complete function from setImageTag subcommand 2018-07-23 10:47:52 -07:00
Jingfang Liu
909de5c94a Add set imagetag command 2018-07-23 10:24:32 -07:00
Maximilian Gaß
2eaeb83ec3 Fix wrong path in diff tests on macOS 2018-07-23 17:00:41 +02:00
k8s-ci-robot
03b9c2a3a3 Merge pull request #188 from Liujingfang1/cr
Enable imageTagTransformer in application
2018-07-20 11:54:56 -07:00
Jingfang Liu
59b98727ec enable imageTagTransformer in application 2018-07-20 11:30:34 -07:00
Jingfang Liu
5851f96524 Add initContainers in imageTagTransformer 2018-07-20 11:30:06 -07:00
k8s-ci-robot
08be3f061e Merge pull request #187 from monopole/secFactory
Introduce secret factory.
2018-07-20 11:17:53 -07:00
k8s-ci-robot
5906aaba19 Merge pull request #184 from Liujingfang1/cr
Add imageTagTransformer
2018-07-20 10:54:07 -07:00
Jingfang Liu
4b6f180d0c address comments 2018-07-20 10:45:17 -07:00
Jeffrey Regan
7f22f187f8 Introduce secret factory. 2018-07-20 10:40:47 -07:00
Jingfang Liu
fa3a64e352 Add imageTagTransformer 2018-07-20 10:23:12 -07:00
Jeff Regan
82f2cf9124 Merge pull request #186 from monopole/secretFactory
Inject a file system object into "Application".
2018-07-20 09:24:19 -07:00
Jeffrey Regan
276693cf0e Make a secret factory. 2018-07-20 09:09:52 -07:00
Jeff Regan
0197c019cc Merge pull request #185 from monopole/evenMoreFix86
Start remerging two forked sets of configmap factory code
2018-07-19 18:44:20 -07:00
Jeffrey Regan
9576a81787 Put the two sets of configmap make codes sidebyside 2018-07-19 18:33:55 -07:00
k8s-ci-robot
ff4a1c0b4f Merge pull request #183 from monopole/moreFix86
Remove a util package; more cleanup for #86
2018-07-19 16:19:10 -07:00
Jeff Regan
7dd28b1fd9 Merge pull request #176 from babiel/do-not-create-networkpolicy-matchlabels
Disable NetworkPolicy podSelector.matchLabels CreateIfNotPresent
2018-07-19 15:51:13 -07:00
Jeffrey Regan
b754557418 Remove a util package; more cleanup for #86 2018-07-19 14:39:18 -07:00
k8s-ci-robot
f305c0d791 Merge pull request #182 from Liujingfang1/cr
Add ContainerRef in kustomization type
2018-07-19 14:34:41 -07:00
Jingfang Liu
3fdaa2e903 Add ImageTags in kustomization type 2018-07-19 14:29:29 -07:00
k8s-ci-robot
964c74fb46 Merge pull request #181 from monopole/fix86
configMap factory refactor for #86
2018-07-19 14:14:53 -07:00
Jeffrey Regan
f14988ff80 configMap factory refactor for #86 2018-07-19 14:06:51 -07:00
k8s-ci-robot
f1adbfdbff Merge pull request #180 from knqyf263/fix_docs
Fix configGeneration.md
2018-07-19 08:37:53 -07:00
knqyf263
072bf992b0 Fix configGeneration.md 2018-07-19 11:09:00 +09:00
Jeff Regan
2d0d09e178 Merge pull request #179 from monopole/nitfixes
Fix cluster of silly Go nits.
2018-07-18 17:49:28 -07:00
Jeffrey Regan
564b0d6827 Fix cluster of silly Go nits. 2018-07-18 17:45:17 -07:00
guineveresaenger
187415430f Removed individual files in favor of combined metadata file 2018-07-18 17:09:41 -07:00
guineveresaenger
afac2fb46a Uses single file for both addLabel and addAnnotation commands, as the code is nearly identical. Tests included. 2018-07-18 17:09:41 -07:00
guineveresaenger
20fd433f75 Add tests 2018-07-18 17:09:41 -07:00
guineveresaenger
1e3824057b Implements labels and annotations as subcommands of edit 2018-07-18 17:09:41 -07:00
k8s-ci-robot
5edae84a9e Merge pull request #177 from monopole/improveFsAbstraction
Replace os.Stat with IsDir and Exists, simplifying FS abstraction.
2018-07-18 13:43:06 -07:00
Jeffrey Regan
9432671887 Replace os.Stat with IsDir, simplifying FS abstraction. 2018-07-18 12:57:53 -07:00
Jeff Regan
8fda0f87ab Merge pull request #159 from Liujingfang1/master
remove adding hash for configmap/secret read from resource yaml files
2018-07-18 11:10:09 -07:00
Jingfang Liu
08bc8637c8 set the default behavior for SecretGenerator and ConfigMapGenerator as create 2018-07-18 10:59:38 -07:00
Jingfang Liu
9645f397ef remove adding hash for configmap/secret read from resource yaml files 2018-07-18 10:57:50 -07:00
Maximilian Gaß
ed9f716361 Add unit test for NetworkPolicy 2018-07-18 14:11:18 +02:00
Maximilian Gaß
9986b65326 Disable creation of NetworkPolicy podSelector.matchLabels 2018-07-18 14:01:22 +02:00
Jingfang Liu
94dab9ddc4 Merge pull request #175 from Liujingfang1/crd
skip adding namespace to CustomResourceDefinitions
2018-07-17 13:31:15 -07:00
Jingfang Liu
81f246ed60 skip adding namespace to CustomResourceDefinitions 2018-07-17 13:18:43 -07:00
Jingfang Liu
30ed50eb27 Merge pull request #166 from Liujingfang1/namespace
Add namespace transformation for subjects.namespace in ClusterRoleBinding
2018-07-17 13:15:40 -07:00
Jingfang Liu
4325401fe7 Add namespace transformation for subjects.namespace in ClusterRoleBinding 2018-07-17 13:10:51 -07:00
Jingfang Liu
65af5c13f1 Merge pull request #146 from babiel/fix-name-hash-in-refvars
Run namehash transformer before resolving names for refvars
2018-07-13 09:15:07 -07:00
Maximilian Gaß
9674fd12b2 Run namehash transformer before resolving names for refvars 2018-07-13 09:45:48 +02:00
Jingfang Liu
2377902a0b Merge pull request #145 from babiel/pod-affinity-label-transformer
Add common labels to pod affinity/anti-affinity label selector
2018-07-12 15:41:58 -07:00
Jingfang Liu
1dbde0b085 Merge pull request #140 from babiel/add-networkpolicy-to-labels
Add NetworkPolicy to label transformer
2018-07-12 15:41:51 -07:00
Jingfang Liu
5920563bbd Merge pull request #158 from george-angel/master
Interpret projected configMap volume names
2018-07-11 14:30:04 -07:00
Jingfang Liu
23201c27f0 Merge pull request #160 from Liujingfang1/helloworld
update helloWorld example: change configmap to configmapGenerator
2018-07-11 14:25:47 -07:00
George Angel
d4c7131f8f fix linter dupl errors 2018-07-11 22:18:49 +01:00
Jingfang Liu
d2b189874b update helloWorld example: change configmap to configmapGenerator 2018-07-11 14:00:07 -07:00
Jingfang Liu
98a38eb290 Merge pull request #151 from Rio/vars-docs
docs(vars): Add some documentation explaining the usage and limits of vars
2018-07-11 09:45:40 -07:00
George Angel
aa729229e2 Interpret projected configMap volume names
Append hashes to configMap names under the projected configMap volume,
for Kind: Deployment and StatefulSet
2018-07-11 10:30:31 +01:00
Rio Kierkels
afbc1b0401 docs(vars): add some docs explaining the usage and limitations of vars 2018-07-11 10:43:11 +02:00
Jingfang Liu
3305be9589 Merge pull request #150 from ryane/fix-pvc-claimname
add PersistentVolumeClaim to name reference transformer
2018-07-09 13:51:52 -07:00
ryane
36772aac89 add PersistentVolumeClaim to name reference transformer
fixes #149
2018-07-03 10:16:58 -04:00
Maximilian Gaß
7755d6cac2 Add common labels to pod affinity/anti-affinity label selector 2018-07-02 16:02:11 +02:00
Jingfang Liu
6f82073d4b Merge pull request #133 from Liujingfang1/loader
Add glob support
2018-06-27 15:20:01 -07:00
Jingfang Liu
2a3f09a2f0 Add integration test for glob support 2018-06-27 14:48:50 -07:00
Jingfang Liu
6392e6629f Add glob support 2018-06-27 10:54:12 -07:00
Jingfang Liu
c25ed7f7bc Merge pull request #137 from babiel/add-cronjob-to-refvars
Add CronJob to refvars transformer
2018-06-26 10:02:38 -07:00
Jingfang Liu
918247d2cc Merge pull request #138 from guineveresaenger/secret-docs
Adds example for secret download using curl
2018-06-26 10:02:01 -07:00
Maximilian Gaß
0c260ef804 Add NetworkPolicy to label transformer 2018-06-26 17:18:50 +02:00
Maximilian Gaß
2a06a174e8 Add CronJob to refvars transformer 2018-06-26 12:20:52 +02:00
guineveresaenger
54e8a014bc Adds example for secret download using curl
It is possible to download secrets from web locations, as the command subfield can execute any terminal command specified.
This is a useful feature that should be highlighted.
2018-06-25 16:39:29 -07:00
Jingfang Liu
5b67b580f2 Merge pull request #129 from fanzhangio/issue114
Enhancement for format error message
2018-06-25 10:33:36 -07:00
fanzhangio
6a67183ed7 Enhancement for format error message
- add yaml format error handler
- silent usage when build command fails
2018-06-25 07:35:43 -07:00
Jingfang Liu
a38befdaa1 Merge pull request #132 from Liujingfang1/order
correct ordering of the k8s objects
2018-06-22 10:33:31 -07:00
Jingfang Liu
0312cdf677 Merge pull request #130 from sethpollack/image-pull-secret
add imagePullSecrets namerefs
2018-06-22 10:22:33 -07:00
Jingfang Liu
991ffbbdfc populate the map from a slice 2018-06-22 10:19:41 -07:00
Seth Pollack
bbd29d9dc1 add test 2018-06-21 23:17:03 -04:00
Jingfang Liu
28953e03a0 Merge pull request #120 from guineveresaenger/edit-add-base
New command: kustomize edit add base
2018-06-21 16:54:15 -07:00
guineveresaenger
37489ec2e9 Adds ability to add multiple base directories to kustomization 2018-06-21 16:39:46 -07:00
Jingfang Liu
636ab874eb update failed test 2018-06-21 16:36:27 -07:00
Jingfang Liu
90d16c2377 correct ordering of the k8s objects:
NameSpace, CRD, ServiceAccount, Role, ClusterRole, RoleBinding,
ClusterRoleBinding
2018-06-21 16:21:31 -07:00
Seth Pollack
5d24dda28a add imagePullSecrets namerefs 2018-06-20 23:23:31 -04:00
Jingfang Liu
dec5109e31 Merge pull request #127 from Liujingfang1/master
remove extra package comment on crds
2018-06-20 13:23:41 -07:00
Jingfang Liu
cc8690381c remove extra package comment on crds 2018-06-20 13:22:17 -07:00
Jingfang Liu
f5f95e3692 Merge pull request #125 from Liujingfang1/order
put namespace objects first in the output
2018-06-19 16:10:48 -07:00
Jingfang Liu
809d5b1fe2 put namespace objects first in the output 2018-06-19 15:44:33 -07:00
Jingfang Liu
38b4365ab3 Merge pull request #121 from traherom/master
Jobs do not create a selector if not already present
2018-06-19 14:22:15 -07:00
Jingfang Liu
d865300fdb Merge pull request #105 from Liujingfang1/crdsupport
Add support for CRDs
2018-06-19 12:04:35 -07:00
Jingfang Liu
e2677cdc8a Merge pull request #123 from Liujingfang1/master
Add variable reference to pod command,args,env
2018-06-19 12:04:06 -07:00
Jingfang Liu
ea00134776 Update pathconfigs library
implement CRD support and add unit tests

Add integration test for crd support

address comments
2018-06-19 11:45:53 -07:00
Jingfang Liu
ad3cd47c25 Add variable reference to pod command,args,env 2018-06-19 11:25:58 -07:00
guineveresaenger
a1dcf3386b Adds kustomize edit add base command
This pull request adds support for editing the kustomization.yaml in the current directory with a base.
2018-06-19 10:09:13 -07:00
Jingfang Liu
e7ecceb0c2 Update vendor 2018-06-19 09:36:30 -07:00
Ryan Morehart
50c40eb80c CronJob transformation fixed
- no longer add labels in an invalid location (#116)
- only have selector added it already present
2018-06-19 06:14:05 -06:00
Ryan Morehart
398ceb0a92 Jobs do not create a selector if not already present 2018-06-18 17:09:23 -06:00
Jingfang Liu
b7be630924 Merge pull request #113 from uthark/unparam
Enable unparam linter and fix found issues
2018-06-18 11:55:57 -07:00
Oleg Atamanenko
f557841e54 Enable unparam linter and fix issues 2018-06-18 14:49:57 -04:00
Jingfang Liu
9fc24634a2 Merge pull request #115 from woop/patch-1
Update example to show correct environment
2018-06-15 12:35:12 -07:00
Jingfang Liu
0617a283a0 Merge pull request #111 from Liujingfang1/master
Add variable reference to container env
2018-06-15 11:20:25 -07:00
Willem Pienaar
f616e30a38 Update example to show correct environment 2018-06-15 23:27:16 +08:00
Jingfang Liu
50b197f329 Merge pull request #110 from uthark/gometalinter
Add gometalinter to pre-commit hook
2018-06-14 18:52:59 -07:00
Oleg Atamanenko
6fd0330b80 Add gometalinter to pre-commit hook
Enable varcheck and fix found issues

Add ineffassign to list of checks and fix found issues

Added nakedret and fixed found issues

Add interfacer check and fix found issue

Add lll and fix found issues

Add deadcode linter, remove unused code
2018-06-14 20:55:20 -04:00
Jingfang Liu
8127b09d12 Merge pull request #73 from guineveresaenger/example-docfix
Clarifies hello-world example documentation
2018-06-14 15:24:25 -07:00
Jingfang Liu
09ab2bb5c0 Add variable reference to container env 2018-06-14 13:38:58 -07:00
Sunil Arora
54ac4e73e7 Merge pull request #108 from Liujingfang1/args
Add variable reference support for args
2018-06-13 14:51:46 -07:00
Jeff Regan
d4ad7f80e0 Merge pull request #104 from monopole/renameExamplesToTestData
Rename examples dir to examplelayout.
2018-06-12 15:07:14 -07:00
Jeffrey Regan
623e21d1c0 Rename examples dir to examplelayout. 2018-06-12 15:03:45 -07:00
Jeff Regan
0c88c43c67 Merge pull request #102 from monopole/upgradeCrypto
Replace deprecated crypto/md5 with crypto/sha256
2018-06-12 13:51:10 -07:00
Jeffrey Regan
c6d8bcb01b Replace deprecated crypto/md5 with crypto/sha256 2018-06-12 13:47:22 -07:00
Jeff Regan
5285e6101f Merge pull request #101 from monopole/moveVersion
Move version.go to commands dir.
2018-06-12 13:10:00 -07:00
Jeffrey Regan
2fb69db685 Move version.go to commands dir. 2018-06-12 13:08:23 -07:00
guineveresaenger
730597b77e grepping for kiwi 2018-06-12 10:33:37 -07:00
guineveresaenger
d488d9804d grepping for configMap name 2018-06-12 10:29:25 -07:00
Jeff Regan
f98bc42cbb Merge pull request #99 from monopole/tempCaptureExec
Absorb exec package from k8s.io/utils.
2018-06-12 09:46:14 -07:00
Jeffrey Regan
d7b9f64c5a Absorb exec package from utils. 2018-06-12 09:22:07 -07:00
Jeff Regan
785291af62 Merge pull request #95 from Liujingfang1/crdsupport
Add skeleton for CRD support
2018-06-12 09:21:10 -07:00
Jingfang Liu
4f05482e00 Add support for CRDs 2018-06-11 21:52:13 -07:00
Jeff Regan
3c3f85e623 Merge pull request #96 from monopole/secContacts
Fixes #33; add SECURITY_CONTACTS
2018-06-11 19:32:10 -07:00
jregan
40bb81142b Fixes #33; add SECURITY_CONTACTS 2018-06-11 19:30:13 -07:00
Jeff Regan
5563f1529b Update README.md 2018-06-11 15:20:20 -07:00
Jeff Regan
a95b26182a Merge pull request #93 from Liujingfang1/configmaps
make generated configmaps composable
2018-06-11 15:04:43 -07:00
Jingfang Liu
934e37d781 add unit test and address comments 2018-06-11 14:52:31 -07:00
Jeff Regan
40bad7783f Merge pull request #94 from monopole/addTODO
Add TODO referencing bug
2018-06-11 14:44:32 -07:00
Jeffrey Regan
44696d5fb9 Add TODO referencing bug 2018-06-11 14:43:22 -07:00
Jeff Regan
9d268de5a0 Merge pull request #90 from Liujingfang1/master
Add README.md for wordpress to show variable reference usage
2018-06-11 14:13:23 -07:00
Jingfang Liu
46e8fd7065 Add variable reference support for args 2018-06-11 13:57:34 -07:00
Jingfang Liu
ab0c9b4118 address comments 2018-06-11 13:52:18 -07:00
guineveresaenger
4e7610a44d Addresses review comments 2018-06-11 12:35:33 -07:00
Jingfang Liu
37720765fc Add a test case 2018-06-11 12:18:26 -07:00
Jingfang Liu
09e64e5991 Merge pull request #81 from sethpollack/skip
refactor namespaces to use PathConfig
2018-06-11 12:08:35 -07:00
Jingfang Liu
e017d04a16 make generated configmaps composable 2018-06-11 12:07:16 -07:00
Jingfang Liu
b6efde13eb Add README.md for wordpress to show variable reference usage 2018-06-11 11:41:09 -07:00
Seth Pollack
f774172927 refactor namespaces to use PathConfig 2018-06-11 14:16:04 -04:00
Jeff Regan
9459665c96 Merge pull request #70 from Liujingfang1/crds
Skip adding nameprefix for CRD
2018-06-11 11:05:05 -07:00
Jeff Regan
7fb4eaec60 Merge pull request #89 from monopole/maybeReduceNameConfusion
Some cleanup refactoring in app package.
2018-06-11 10:34:32 -07:00
jregan
211cda054e Some cleanup refactoring in app package. 2018-06-11 09:51:03 -07:00
Jingfang Liu
5f75564ff5 Skip adding nameprefix for CRD 2018-06-11 09:22:18 -07:00
Jeff Regan
6b5569d5ed Merge pull request #82 from vreon/ingress-tls-secretname
Add Ingress spec.tls.secretName to Secret namerefs
2018-06-10 20:15:52 -07:00
Jeff Regan
e20edaf41e Merge pull request #83 from uthark/returnerror
Return error along with a resource
2018-06-10 20:14:48 -07:00
Jeff Regan
d934a28caf Merge pull request #84 from monopole/troubleWithRawResources
Add more test coverage for RawResources.
2018-06-10 20:14:22 -07:00
jregan
e002b69ffa Add more test coverage for RawResources. 2018-06-10 20:09:31 -07:00
Oleg Atamanenko
bdad67c3ef Return error along with a resource 2018-06-10 21:57:30 -04:00
Jesse Dubay
92864ba0f7 Add Ingress spec.tls.secretName to Secret namerefs 2018-06-10 16:26:50 -07:00
Jeff Regan
ba45b1366a Merge pull request #80 from monopole/fixNameOfPatchTransformer
Rename OverlayTranformer to PatchTransformer.
2018-06-10 11:29:37 -07:00
jregan
d06620c74d Rename OverlayTranformer to PatchTransformer. 2018-06-10 11:23:47 -07:00
Jeff Regan
4f3f76addd Merge pull request #78 from uthark/gocyclo
Fixed gocyclo warnings and added pre-commit hook
2018-06-10 11:11:48 -07:00
Jeff Regan
71b7e07b02 Merge pull request #77 from uthark/golint
Fix go lint error and add golint checks to a pre-commit hook
2018-06-10 10:35:56 -07:00
Jeff Regan
27f652ae8e Merge pull request #76 from monopole/reduceUnstructNoise
Reduce unstruct notation noise in Resource construction.
2018-06-10 09:46:53 -07:00
Oleg Atamanenko
5c8d82aed0 Fixed gocyclo warnings and added pre-commit hook 2018-06-09 23:43:42 -04:00
Oleg Atamanenko
c994130005 Fix go lint error and add golint checks to a pre-commit hook 2018-06-09 23:05:26 -04:00
jregan
ccd255f323 Reduce unstruct notation noise in Resource construction. 2018-06-09 08:10:57 -07:00
Jeff Regan
2b05d39067 Merge pull request #75 from monopole/yada
Handle arb length paths in GetFieldName
2018-06-08 16:24:59 -07:00
Jeffrey Regan
de65503177 Handle arb length paths in GetFieldName 2018-06-08 15:07:57 -07:00
guineveresaenger
5a3c6553fc Clarifies hello-world example documentation
The example documentation had a few minor discrepancies between commands suggested and expected outcomes. This pull request addresses those, making it easier for folks to use the hello-world demo.
2018-06-08 13:27:20 -07:00
Jeff Regan
7c4ca21578 Merge pull request #71 from sethpollack/namespaces
add namespace to the doc
2018-06-08 12:58:31 -07:00
Jeff Regan
efcc167c35 Merge pull request #72 from Liujingfang1/master
Add wordpress example for demonstrating variable reference
2018-06-08 12:58:01 -07:00
Jingfang Liu
1f8e56a210 Add wordpress example for demonstrating variable reference 2018-06-08 11:49:42 -07:00
Seth Pollack
fa8d6f08e2 add namespace to the doc 2018-06-08 12:47:52 -04:00
Jeff Regan
900ac005dd Merge pull request #66 from monopole/reduceIndirection
Reduce indirection in code w/r to the unstruct types.
2018-06-08 08:59:47 -07:00
jregan
a42c72b2e0 Reduce indirection. 2018-06-07 21:53:55 -07:00
Jeff Regan
a82bd23f8f Merge pull request #52 from Liujingfang1/master
variable reference support
2018-06-06 16:43:48 -07:00
Jeff Regan
ea24b3795c Merge pull request #64 from monopole/docErrorPackage
Doc the error package.
2018-06-06 14:43:56 -07:00
Jingfang Liu
95f568b857 add comments in refvar transformer
Refactor change
2018-06-06 14:42:18 -07:00
Jeffrey Regan
708cd7ef17 Doc the error package. 2018-06-06 14:41:43 -07:00
Jeff Regan
ed7261ca01 Merge pull request #63 from monopole/packageDoc
Improve package structure and documentation.
2018-06-06 14:18:31 -07:00
Jeff Regan
8a27162d98 Merge pull request #62 from sethpollack/ingress
add namerefs for ingress
2018-06-06 14:17:29 -07:00
Jeffrey Regan
2e0e43cd76 Improve package doc. 2018-06-06 14:15:50 -07:00
Jeff Regan
ba2866645e Merge pull request #60 from sethpollack/initContainers
add namerefs for initContainers
2018-06-06 14:04:42 -07:00
Jeff Regan
fd2ee6034b Merge pull request #59 from sethpollack/hpa
add namerefs for hpa
2018-06-06 14:03:15 -07:00
Jeff Regan
86241dfd98 Merge pull request #58 from sethpollack/labels
add PodDisruptionBudget labels
2018-06-06 14:01:11 -07:00
Jingfang Liu
1a28f3a391 Address comments: add unit tests, defaulting and update comment 2018-06-06 10:21:15 -07:00
Jingfang Liu
35344c163a Add test case for variable reference 2018-06-06 09:30:12 -07:00
Jingfang Liu
526ba2df0c add varialber reference support 2018-06-06 09:30:12 -07:00
Seth Pollack
db15bc6372 add namerefs for ingress 2018-06-06 12:17:54 -04:00
Seth Pollack
c83b7019f5 add namerefs for initContainers 2018-06-06 12:04:49 -04:00
Seth Pollack
08e2a1047b add namerefs for hpa 2018-06-06 11:24:12 -04:00
Seth Pollack
69d816d5ab add PodDisruptionBudget labels 2018-06-05 22:02:35 -04:00
Jeff Regan
ea2d2c9db1 Merge pull request #56 from Liujingfang1/expansion
Add expansion package
2018-06-05 17:31:40 -07:00
Jingfang Liu
c7ef8a7e4d Add expansion package 2018-06-05 17:04:53 -07:00
Jeff Regan
9bda5cf092 Merge pull request #54 from sethpollack/namespace
kustomize namespace
2018-06-05 16:22:48 -07:00
Seth Pollack
815db033cb add namespace.yaml 2018-06-05 18:41:48 -04:00
Seth Pollack
501e1a406d add regression coverage 2018-06-05 15:32:22 -04:00
Seth Pollack
6e54814b6d kustomize namespace 2018-06-04 22:35:03 -04:00
Jeff Regan
df2407ad3f Merge pull request #49 from monopole/removeAnotherUtil
Remove util and privatize selectByGvk
2018-06-01 14:20:29 -07:00
Jeffrey Regan
d0c6a824c8 Remove util and privatize selectByGvk 2018-06-01 14:17:56 -07:00
Jeff Regan
57f3743be8 Merge pull request #47 from monopole/introduceResourceMap
Introduce ResId and ResMap in resmap package.
2018-06-01 14:02:46 -07:00
jregan
ef71cb478f Introduce ResId and ResMap. 2018-06-01 13:56:43 -07:00
Jeff Regan
9a5c0f5a25 Merge pull request #46 from monopole/dropUtilPackage
Drop the util package.
2018-05-31 17:24:36 -07:00
Jeffrey Regan
0e2c71cd6f Drop the util package. 2018-05-31 17:17:41 -07:00
Jeff Regan
0b3ab31248 Merge pull request #45 from monopole/createDiffPackage
Create and document diff package.
2018-05-31 16:57:11 -07:00
Jeffrey Regan
49f586af39 Create and document diff package. 2018-05-31 16:50:34 -07:00
Jeff Regan
487a6ebee4 Merge pull request #43 from monopole/fixLinkInHelp
Fix URL in help message
2018-05-31 14:18:11 -07:00
Jeff Regan
bee9490129 Merge pull request #44 from monopole/constantsCleanup
Document constants package.
2018-05-31 14:17:54 -07:00
Jeffrey Regan
8afba0b56c Document constants package. 2018-05-31 13:42:03 -07:00
jregan
16fa3403a4 Fix kubernetes-sigs/kustomize#40 2018-05-30 20:28:46 -07:00
Jeff Regan
bcb89ee908 Merge pull request #39 from guineveresaenger/no-secret
Removes help text for `kustomize edit add secret`
2018-05-30 10:11:01 -07:00
Jeff Regan
37f03b4d01 Merge pull request #37 from ahmetb/mv-examples
demos --> examples
2018-05-30 10:08:44 -07:00
guineveresaenger
bc144275b4 Removes help text for kustomize edit add secret
There is currently no support for adding a secret with kustomize. The help text should not show such an option.
Fixes #14.
2018-05-29 10:27:18 -07:00
Ahmet Alp Balkan
7086e4f974 demos --> examples
examples/ is pretty standard whereas demos/ isn't. So I just refactored that.

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2018-05-25 10:07:46 -07:00
Jeff Regan
4d111436aa Merge pull request #35 from monopole/baseOverlayNotes
Base overlay notes
2018-05-24 17:08:24 -07:00
Jeffrey Regan
1583486546 base overlay notes 2018-05-24 17:07:19 -07:00
Jeff Regan
10b4c5db43 Merge pull request #34 from monopole/updateReadme
update readmes
2018-05-24 14:16:13 -07:00
Jeffrey Regan
5a54c96203 update readmes 2018-05-24 14:13:10 -07:00
Jeff Regan
4a5b82333b Merge pull request #31 from droot/release-instructions
add instructions for publishing a release
2018-05-24 10:51:08 -07:00
Sunil Arora
e3934ee69c add instructions for publishing a release 2018-05-23 14:20:09 -07:00
Jeff Regan
24daa9e3dc Merge pull request #29 from monopole/updateReadme
Update README with file layout
2018-05-23 10:06:04 -07:00
Jeffrey Regan
d9b422cc54 Update README with file layout 2018-05-23 10:05:11 -07:00
Jeff Regan
d62fb53472 Merge pull request #28 from monopole/updateworkflow
Update workflow doc
2018-05-22 16:53:47 -07:00
Jeffrey Regan
00e52095d6 Update workflow doc 2018-05-22 16:53:07 -07:00
Jeff Regan
9c6d31d70e Merge pull request #2 from rajatjindal/patch-1
Update README.md
2018-05-22 14:40:14 -07:00
Jeff Regan
a734b96560 Merge pull request #26 from monopole/newFigs
betterFigs
2018-05-22 12:21:25 -07:00
Jeffrey Regan
8f3fe7d4bd betterFigs 2018-05-22 12:21:02 -07:00
Jeff Regan
5f950813c4 Merge pull request #25 from monopole/removeLastInstanceUsage
use variant in figure
2018-05-22 12:15:12 -07:00
Jeffrey Regan
920f53853b use variant in figure 2018-05-22 12:14:33 -07:00
Rajat Jindal
aa88a0563b Update README.md 2018-05-14 13:53:13 -07:00
3779 changed files with 2077885 additions and 6477 deletions

View File

@@ -3,7 +3,7 @@ language: go
go:
- 1.10.x
# go_import_path: k8s.io/kubectl
go_import_path: sigs.k8s.io/kustomize
before_install:
- source ./bin/consider-early-travis-exit.sh
@@ -12,6 +12,8 @@ before_install:
- go get -u golang.org/x/tools/cmd/goimports
- go get -u github.com/onsi/ginkgo/ginkgo
- go get -u github.com/monopole/mdrip
- go get -u github.com/fzipp/gocyclo
- go get -u gopkg.in/alecthomas/gometalinter.v2 && gometalinter.v2 --install
# Install must be set to prevent default `go get` to run.
# The dependencies have already been vendored by `dep` so

410
Gopkg.lock generated
View File

@@ -2,146 +2,526 @@
[[projects]]
digest = "1:8e47871087b94913898333f37af26732faaab30cdb41571136cf7aec9921dae7"
name = "github.com/PuerkitoBio/purell"
packages = ["."]
pruneopts = ""
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
version = "v1.1.0"
[[projects]]
branch = "master"
digest = "1:331a419049c2be691e5ba1d24342fc77c7e767a80c666a18fd8a9f7b82419c1c"
name = "github.com/PuerkitoBio/urlesc"
packages = ["."]
pruneopts = ""
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
[[projects]]
digest = "1:9299ad32dcec0f92ad06773f73426bd46a21efa96f6a8138c287bb185933e77e"
name = "github.com/aws/aws-sdk-go"
packages = [
"aws",
"aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/csm",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"internal/sdkio",
"internal/sdkrand",
"internal/sdkuri",
"internal/shareddefaults",
"private/protocol",
"private/protocol/eventstream",
"private/protocol/eventstream/eventstreamapi",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/restxml",
"private/protocol/xml/xmlutil",
"service/s3",
"service/sts",
]
pruneopts = ""
revision = "daed0c76021ea9c4e659e3ec80bcd2d657297100"
version = "v1.15.12"
[[projects]]
branch = "master"
digest = "1:98e84060475ed245c3b355042afd43a74aa7d32efe50658f4f995977916f9fc3"
name = "github.com/bgentry/go-netrc"
packages = ["netrc"]
pruneopts = ""
revision = "9fd32a8b3d3d3f9d43c341bfe098430e07609480"
[[projects]]
digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b"
name = "github.com/davecgh/go-spew"
packages = ["spew"]
pruneopts = ""
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
digest = "1:971e9ba63a417c5f1f83ab358677bc59e96ff04285f26c6646ff089fb60b15e8"
name = "github.com/emicklei/go-restful"
packages = [
".",
"log",
]
pruneopts = ""
revision = "3658237ded108b4134956c1b3050349d93e7b895"
version = "v2.7.1"
[[projects]]
digest = "1:dcefbadf4534c5ecac8573698fba6e6e601157bfa8f96aafe29df31ae582ef2a"
name = "github.com/evanphx/json-patch"
packages = ["."]
pruneopts = ""
revision = "afac545df32f2287a079e2dfb7ba2745a643747e"
version = "v3.0.0"
[[projects]]
digest = "1:b13707423743d41665fd23f0c36b2f37bb49c30e94adb813319c44188a51ba22"
name = "github.com/ghodss/yaml"
packages = ["."]
pruneopts = ""
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
version = "v1.0.0"
[[projects]]
digest = "1:858b7fe7b0f4bc7ef9953926828f2816ea52d01a88d72d1c45bc8c108f23c356"
name = "github.com/go-ini/ini"
packages = ["."]
pruneopts = ""
revision = "358ee7663966325963d4e8b2e1fbd570c5195153"
version = "v1.38.1"
[[projects]]
branch = "master"
digest = "1:e116a4866bffeec941056a1fcfd37e520fad1ee60e4e3579719f19a43c392e10"
name = "github.com/go-openapi/jsonpointer"
packages = ["."]
pruneopts = ""
revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2"
[[projects]]
branch = "master"
digest = "1:3830527ef0f4f9b268d9286661c0f52f9115f8aefd9f45ee7352516f93489ac9"
name = "github.com/go-openapi/jsonreference"
packages = ["."]
pruneopts = ""
revision = "3fb327e6747da3043567ee86abd02bb6376b6be2"
[[projects]]
branch = "master"
digest = "1:238a056875c4b053b4b29984765ee335bf8c539fdf17e527fd9b7aa72521c8dd"
name = "github.com/go-openapi/spec"
packages = ["."]
pruneopts = ""
revision = "bcff419492eeeb01f76e77d2ebc714dc97b607f5"
[[projects]]
branch = "master"
digest = "1:7b067ca8b94982960860d18c42e29f15bbd0e8d9ae8145a83a218296e75393cf"
name = "github.com/go-openapi/swag"
packages = ["."]
pruneopts = ""
revision = "811b1089cde9dad18d4d0c2d09fbdbf28dbd27a5"
[[projects]]
digest = "1:0a3f6a0c68ab8f3d455f8892295503b179e571b7fefe47cc6c556405d1f83411"
name = "github.com/gogo/protobuf"
packages = ["proto","sortkeys"]
packages = [
"proto",
"sortkeys",
]
pruneopts = ""
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:107b233e45174dbab5b1324201d092ea9448e58243ab9f039e4c0f332e121e3a"
name = "github.com/golang/glog"
packages = ["."]
pruneopts = ""
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
[[projects]]
digest = "1:f958a1c137db276e52f0b50efee41a1a389dcdded59a69711f3e872757dab34b"
name = "github.com/golang/protobuf"
packages = ["proto","ptypes","ptypes/any","ptypes/duration","ptypes/timestamp"]
packages = [
"proto",
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp",
]
pruneopts = ""
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
version = "v1.1.0"
[[projects]]
branch = "master"
digest = "1:754f77e9c839b24778a4b64422236d38515301d2baeb63113aa3edc42e6af692"
name = "github.com/google/gofuzz"
packages = ["."]
pruneopts = ""
revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1"
[[projects]]
digest = "1:2a131706ff80636629ab6373f2944569b8252ecc018cda8040931b05d32e3c16"
name = "github.com/googleapis/gnostic"
packages = ["OpenAPIv2","compiler","extensions"]
packages = [
"OpenAPIv2",
"compiler",
"extensions",
]
pruneopts = ""
revision = "ee43cbb60db7bd22502942cccbc39059117352ab"
version = "v0.1.0"
[[projects]]
branch = "master"
digest = "1:f5d25fd7bdda08e39e01193ef94a1ebf7547b1b931bcdec785d08050598f306c"
name = "github.com/hashicorp/go-cleanhttp"
packages = ["."]
pruneopts = ""
revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
[[projects]]
branch = "master"
digest = "1:fd15b3f6aac9d0fe68c6e38922282e0d2e88cd77b927ac3dd842e363645522c0"
name = "github.com/hashicorp/go-getter"
packages = [
".",
"helper/url",
]
pruneopts = ""
revision = "4bda8fa99001c61db3cad96b421d4c12a81f256d"
[[projects]]
branch = "master"
digest = "1:2cf6c60c74eacadd31652674364af55c8d54a86b8ea193548f1c37f8c9af8f9c"
name = "github.com/hashicorp/go-safetemp"
packages = ["."]
pruneopts = ""
revision = "b1a1dbde6fdc11e3ae79efd9039009e22d4ae240"
[[projects]]
branch = "master"
digest = "1:139bdc2c89779b8ff8b1150be28f889b0ed964e6da96f32cbc9035bd4642881c"
name = "github.com/hashicorp/go-version"
packages = ["."]
pruneopts = ""
revision = "270f2f71b1ee587f3b609f00f422b76a6b28f348"
[[projects]]
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
pruneopts = ""
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
digest = "1:6f49eae0c1e5dab1dafafee34b207aeb7a42303105960944828c2079b92fc88e"
name = "github.com/jmespath/go-jmespath"
packages = ["."]
pruneopts = ""
revision = "0b12d6b5"
[[projects]]
digest = "1:9eab2325abbed0ebcee9d44bb3660a69d5d10e42d5ac4a0e77f7a6ea22bfce88"
name = "github.com/json-iterator/go"
packages = ["."]
pruneopts = ""
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
version = "1.1.3"
[[projects]]
digest = "1:10e1dfc240bcd0fce14366215fd2b070e79d9b9460b27382db4423ad74204f2b"
name = "github.com/krishicks/yaml-patch"
packages = ["."]
pruneopts = ""
revision = "83cc9ac50becbbfafb86a89167f3bc5372e8e530"
version = "v0.0.10"
[[projects]]
branch = "master"
digest = "1:d9e483f4b9e306facf126bd90b02d512bd22ea4471e1568867e32221a8abbb16"
name = "github.com/mailru/easyjson"
packages = [
"buffer",
"jlexer",
"jwriter",
]
pruneopts = ""
revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485"
[[projects]]
branch = "master"
digest = "1:83854f6b1d2ce047b69657e3a87ba7602f4c5505e8bdfd02ab857db8e983bde1"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
pruneopts = ""
revision = "58046073cbffe2f25d425fe1331102f55cf719de"
[[projects]]
branch = "master"
digest = "1:51c98e2c9a8d0a724a69f46421876af14e12132cb02f1d0e144785d752247162"
name = "github.com/mitchellh/go-testing-interface"
packages = ["."]
pruneopts = ""
revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28"
[[projects]]
digest = "1:0c0ff2a89c1bb0d01887e1dac043ad7efbf3ec77482ef058ac423d13497e16fd"
name = "github.com/modern-go/concurrent"
packages = ["."]
pruneopts = ""
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
version = "1.0.3"
[[projects]]
digest = "1:420f9231f816eeca3ff5aab070caac3ed7f27e4d37ded96ce9de3d7a7a2e31ad"
name = "github.com/modern-go/reflect2"
packages = ["."]
pruneopts = ""
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
version = "1.0.0"
[[projects]]
digest = "1:7365acd48986e205ccb8652cc746f09c8b7876030d53710ea6ef7d0bd0dcd7ca"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = ""
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
digest = "1:74c32990510c9f188556aa17600313e867d1d06f5a9db244056a95d144ec34ce"
name = "github.com/spf13/cobra"
packages = ["."]
pruneopts = ""
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
version = "v0.0.2"
[[projects]]
digest = "1:8e243c568f36b09031ec18dff5f7d2769dcf5ca4d624ea511c8e3197dc3d352d"
name = "github.com/spf13/pflag"
packages = ["."]
pruneopts = ""
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
version = "v1.0.1"
[[projects]]
digest = "1:ee723e6a1962a196eeba1b24f82af61a4f60f8821d7aa96d48e787f8337bcffc"
name = "github.com/ulikunitz/xz"
packages = [
".",
"internal/hash",
"internal/xlog",
"lzma",
]
pruneopts = ""
revision = "0c6b41e72360850ca4f98dc341fd999726ea007f"
version = "v0.5.4"
[[projects]]
branch = "master"
digest = "1:9e548233d0dc00e74be262e54a9d1bbe7e4c19e5951083520261740e37daeb02"
name = "golang.org/x/net"
packages = ["http/httpguts","http2","http2/hpack","idna"]
packages = [
"http/httpguts",
"http2",
"http2/hpack",
"idna",
]
pruneopts = ""
revision = "2491c5de3490fced2f6cff376127c667efeed857"
[[projects]]
digest = "1:5acd3512b047305d49e8763eef7ba423901e85d5dd2fd1e71778a0ea8de10bd4"
name = "golang.org/x/text"
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
"width",
]
pruneopts = ""
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
digest = "1:75fb3fcfc73a8c723efde7777b40e8e8ff9babf30d8c56160d01beffea8a95a6"
name = "gopkg.in/inf.v0"
packages = ["."]
pruneopts = ""
revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf"
version = "v0.9.1"
[[projects]]
digest = "1:f0620375dd1f6251d9973b5f2596228cc8042e887cd7f827e4220bc1ce8c30e2"
name = "gopkg.in/yaml.v2"
packages = ["."]
pruneopts = ""
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
version = "v2.2.1"
[[projects]]
branch = "master"
digest = "1:663df6da5560210fc39194a0a2c4fceba09ead717c330f1174bb15597cf18ce8"
name = "k8s.io/api"
packages = ["admissionregistration/v1alpha1","admissionregistration/v1beta1","apps/v1","apps/v1beta1","apps/v1beta2","authentication/v1","authentication/v1beta1","authorization/v1","authorization/v1beta1","autoscaling/v1","autoscaling/v2beta1","batch/v1","batch/v1beta1","batch/v2alpha1","certificates/v1beta1","core/v1","events/v1beta1","extensions/v1beta1","networking/v1","policy/v1beta1","rbac/v1","rbac/v1alpha1","rbac/v1beta1","scheduling/v1alpha1","settings/v1alpha1","storage/v1","storage/v1alpha1","storage/v1beta1"]
packages = [
"admissionregistration/v1alpha1",
"admissionregistration/v1beta1",
"apps/v1",
"apps/v1beta1",
"apps/v1beta2",
"authentication/v1",
"authentication/v1beta1",
"authorization/v1",
"authorization/v1beta1",
"autoscaling/v1",
"autoscaling/v2beta1",
"batch/v1",
"batch/v1beta1",
"batch/v2alpha1",
"certificates/v1beta1",
"core/v1",
"events/v1beta1",
"extensions/v1beta1",
"networking/v1",
"policy/v1beta1",
"rbac/v1",
"rbac/v1alpha1",
"rbac/v1beta1",
"scheduling/v1alpha1",
"settings/v1alpha1",
"storage/v1",
"storage/v1alpha1",
"storage/v1beta1",
]
pruneopts = ""
revision = "53d615ae3f440f957cb9989d989d597f047262d9"
[[projects]]
branch = "master"
digest = "1:bcb2285bb525712de7903a5d254c2789df65c8b58d2cfac5a26d950ad94c2079"
name = "k8s.io/apimachinery"
packages = ["pkg/api/resource","pkg/apis/meta/v1","pkg/apis/meta/v1/unstructured","pkg/conversion","pkg/conversion/queryparams","pkg/fields","pkg/labels","pkg/runtime","pkg/runtime/schema","pkg/runtime/serializer","pkg/runtime/serializer/json","pkg/runtime/serializer/protobuf","pkg/runtime/serializer/recognizer","pkg/runtime/serializer/versioning","pkg/selection","pkg/types","pkg/util/errors","pkg/util/framer","pkg/util/intstr","pkg/util/json","pkg/util/mergepatch","pkg/util/net","pkg/util/runtime","pkg/util/sets","pkg/util/strategicpatch","pkg/util/validation","pkg/util/validation/field","pkg/util/wait","pkg/util/yaml","pkg/watch","third_party/forked/golang/json","third_party/forked/golang/reflect"]
packages = [
"pkg/api/equality",
"pkg/api/meta",
"pkg/api/resource",
"pkg/api/validation",
"pkg/apis/meta/v1",
"pkg/apis/meta/v1/unstructured",
"pkg/apis/meta/v1/validation",
"pkg/apis/meta/v1beta1",
"pkg/conversion",
"pkg/conversion/queryparams",
"pkg/fields",
"pkg/labels",
"pkg/runtime",
"pkg/runtime/schema",
"pkg/runtime/serializer",
"pkg/runtime/serializer/json",
"pkg/runtime/serializer/protobuf",
"pkg/runtime/serializer/recognizer",
"pkg/runtime/serializer/versioning",
"pkg/selection",
"pkg/types",
"pkg/util/errors",
"pkg/util/framer",
"pkg/util/intstr",
"pkg/util/json",
"pkg/util/mergepatch",
"pkg/util/net",
"pkg/util/runtime",
"pkg/util/sets",
"pkg/util/strategicpatch",
"pkg/util/validation",
"pkg/util/validation/field",
"pkg/util/wait",
"pkg/util/yaml",
"pkg/watch",
"third_party/forked/golang/json",
"third_party/forked/golang/reflect",
]
pruneopts = ""
revision = "13b73596e4b63e03203e86f6d9c7bcc1b937c62f"
[[projects]]
digest = "1:071cc2f032b701b9dba26568e040940f26931a49e3a3985f3375f17f7f6d9c5f"
name = "k8s.io/client-go"
packages = ["kubernetes/scheme"]
pruneopts = ""
revision = "23781f4d6632d88e869066eaebb743857aa1ef9b"
version = "v7.0.0"
[[projects]]
branch = "master"
digest = "1:386c5d69077ce740614e8309ddf107dde91a5db25d3d779143f452fb4fbdfd1e"
name = "k8s.io/kube-openapi"
packages = ["pkg/util/proto"]
packages = [
"pkg/common",
"pkg/util/proto",
]
pruneopts = ""
revision = "b3f03f55328800731ce03a164b80973014ecd455"
[[projects]]
branch = "master"
name = "k8s.io/utils"
packages = ["exec"]
revision = "258e2a2fa64568210fbd6267cf1d8fd87c3cb86e"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "6e36daa1798b0dae7f45160f9275ca6bbe6c5667de7cd808d0057cbaf19fc55e"
input-imports = [
"github.com/evanphx/json-patch",
"github.com/ghodss/yaml",
"github.com/golang/glog",
"github.com/hashicorp/go-getter",
"github.com/krishicks/yaml-patch",
"github.com/pkg/errors",
"github.com/spf13/cobra",
"gopkg.in/yaml.v2",
"k8s.io/api/core/v1",
"k8s.io/apimachinery/pkg/api/validation",
"k8s.io/apimachinery/pkg/apis/meta/v1",
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"k8s.io/apimachinery/pkg/apis/meta/v1/validation",
"k8s.io/apimachinery/pkg/runtime",
"k8s.io/apimachinery/pkg/runtime/schema",
"k8s.io/apimachinery/pkg/util/mergepatch",
"k8s.io/apimachinery/pkg/util/sets",
"k8s.io/apimachinery/pkg/util/strategicpatch",
"k8s.io/apimachinery/pkg/util/validation",
"k8s.io/apimachinery/pkg/util/validation/field",
"k8s.io/apimachinery/pkg/util/yaml",
"k8s.io/client-go/kubernetes/scheme",
"k8s.io/kube-openapi/pkg/common",
]
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -49,6 +49,18 @@
name = "k8s.io/client-go"
version = "7.0.0"
[[constraint]]
[[override]]
branch = "master"
name = "k8s.io/utils"
[[override]]
branch = "master"
name = "github.com/go-openapi/spec"
[[constraint]]
branch = "master"
name = "github.com/hashicorp/go-getter"
[[constraint]]
name = "github.com/krishicks/yaml-patch"
version = "0.0.10"

166
README.md
View File

@@ -1,71 +1,141 @@
# kustomize
[applied]: docs/glossary.md#apply
[base]: docs/glossary.md#base
[declarative configuration]: docs/glossary.md#declarative-application-management
[demo]: demos/README.md
[demos]: demos/README.md
[imageBase]: docs/base.jpg
[imageOverlay]: docs/overlay.jpg
[kubernetes style]: docs/glossary.md#kubernetes-style-object
[KEP]: https://github.com/kubernetes/community/blob/master/keps/sig-cli/0008-kustomize.md
[kustomization]: docs/glossary.md#kustomization
[overlay]: docs/glossary.md#overlay
[resources]: docs/glossary.md#resource
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
[workflows]: docs/workflows.md
`kustomize` lets you customize raw, template-free YAML
files for multiple purposes, leaving the original YAML
untouched and usable as is.
`kustomize` is a command line tool supporting
template-free customization of YAML (or JSON) objects
that conform to the [kubernetes style]. If your
objects have a `kind` and a `metadata` field,
`kustomize` can patch them to support configuration
sharing and re-use.
For more details, try a [demo].
`kustomize` targets kubernetes; it understands and can
patch [kubernetes style] API objects. It's like
[`make`], in that what it does is declared in a file,
and it's like [`sed`], in that it emits editted text.
[![Build Status](https://travis-ci.org/kubernetes-sigs/kustomize.svg?branch=master)](https://travis-ci.org/kubernetes-sigs/kustomize)
[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/kustomize)](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize)
## Installation
This assumes [Go](https://golang.org/) (v1.10.1 or higher)
is installed and your `PATH` contains `$GOPATH/bin`:
<!-- @installkustomize @test -->
```
go get github.com/kubernetes-sigs/kustomize
```
**Installation**: Download a binary from the [release
page], or see these [install] notes. Then try one of
the tested [examples].
## Usage
#### 1) Make a base
A [base] configuration is a [kustomization] file listing a set of
k8s [resources] - deployments, services, configmaps,
secrets that serve some common purpose.
### 1) Make a [kustomization] file
In some directory containing your YAML [resource]
files (deployments, services, configmaps, etc.), create a
[kustomization] file.
This file should declare those resources, and any
customization to apply to them, e.g. _add a common
label_.
![base image][imageBase]
#### 2) Customize it with overlays
File structure:
An [overlay] customizes your base along different dimensions
for different purposes or different teams, e.g. for
_development, staging and production_.
> ```
> ~/someApp
> ├── deployment.yaml
> ├── kustomization.yaml
> └── service.yaml
> ```
The resources in this directory could be a fork of
someone else's configuration. If so, you can easily
rebase from the source material to capture
improvements, because you don't modify the resources
directly.
Generate customized YAML with:
```
kustomize build ~/someApp
```
The YAML can be directly [applied] to a cluster:
> ```
> kustomize build ~/someApp | kubectl apply -f -
> ```
### 2) Create [variants] using [overlays]
Manage traditional [variants] of a configuration - like
_development_, _staging_ and _production_ - using
[overlays] that modify a common [base].
![overlay image][imageOverlay]
#### 3) Run kustomize
File structure:
> ```
> ~/someApp
> ├── base
> │   ├── deployment.yaml
> │   ├── kustomization.yaml
> │   └── service.yaml
> └── overlays
> ├── development
> │   ├── cpu_count.yaml
> │   ├── kustomization.yaml
> │   └── replica_count.yaml
> └── production
> ├── cpu_count.yaml
> ├── kustomization.yaml
> └── replica_count.yaml
> ```
Run `kustomize` on your overlay. The result
is printed to `stdout` as a set of complete
resources, ready to be [applied] to a cluster.
See the [demos].
Take the work from step (1) above, move it into a
`someApp` subdirectory called `base`, then
place overlays in a sibling directory.
An overlay is just another kustomization, refering to
the base, and referring to patches to apply to that
base.
This arrangement makes it easy to manage your
configuration with `git`. The base could have files
from an upstream repository managed by someone else.
The overlays could be in a repository you own.
Arranging the repo clones as siblings on disk avoids
the need for git submodules (though that works fine, if
you are a submodule fan).
Generate YAML with
```sh
kustomize build ~/someApp/overlays/production
```
The YAML can be directly [applied] to a cluster:
> ```sh
> kustomize build ~/someApp/overlays/production | kubectl apply -f -
> ```
## About
This project sponsored by [sig-cli] ([KEP]).
This tool is sponsored by [sig-cli] ([KEP]).
[KEP]: https://github.com/kubernetes/community/blob/master/keps/sig-cli/0008-kustomize.md
[`make`]: https://www.gnu.org/software/make
[`sed`]: https://www.gnu.org/software/sed
[applied]: docs/glossary.md#apply
[base]: docs/glossary.md#base
[declarative configuration]: docs/glossary.md#declarative-application-management
[examples]: examples/README.md
[imageBase]: docs/base.jpg
[imageOverlay]: docs/overlay.jpg
[install]: docs/INSTALL.md
[kubernetes style]: docs/glossary.md#kubernetes-style-object
[kustomization]: docs/glossary.md#kustomization
[overlay]: docs/glossary.md#overlay
[overlays]: docs/glossary.md#overlay
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
[resource]: docs/glossary.md#resource
[resources]: docs/glossary.md#resource
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
[variant]: docs/glossary.md#variant
[variants]: docs/glossary.md#variant
[workflows]: docs/workflows.md

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -e
# Make sure, we run in the root of the repo and
# therefore run the tests on all packages
@@ -31,8 +32,32 @@ function testGoFmt {
diff <(echo -n) <(go_dirs | xargs -0 gofmt -s -d -l)
}
function testGoImports {
diff -u <(echo -n) <(go_dirs | xargs -0 goimports -l)
function testGoCyclo {
diff <(echo -n) <(go_dirs | xargs -0 gocyclo -over 15)
}
function testGoLint {
diff -u <(echo -n) <(go_dirs | xargs -0 golint --min_confidence 0.85 )
}
# Not using the 'goimports' check because it reports hyphens in imported
# package names as errors, and we vendor in packages that have
# hyphens in their names.
function testGoMetalinter {
diff -u <(echo -n) <(go_dirs | xargs -0 gometalinter.v2 --disable-all --deadline 5m \
--enable=misspell \
--enable=structcheck \
--enable=deadcode \
--enable=varcheck \
--enable=goconst \
--enable=unparam \
--enable=ineffassign \
--enable=nakedret \
--enable=interfacer \
--enable=misspell \
--line-length=170 --enable=lll \
--dupl-threshold=400 --enable=dupl)
}
function testGoVet {
@@ -43,14 +68,22 @@ function testGoTest {
go test -v ./...
}
function testDemos {
mdrip --mode test --label test README.md ./demos
function testExamples {
mdrip --mode test --label test README.md ./examples
}
runTest testGoFmt
runTest testGoImports
runTest testGoMetalinter
runTest testGoLint
runTest testGoVet
runTest testGoCyclo
runTest testGoTest
runTest testDemos
runTest testExamples
if [ $rc -eq 0 ]; then
echo "SUCCESS!"
else
echo "FAILURE; exit code $rc"
fi
exit $rc

View File

@@ -1,13 +1,45 @@
## Overview
[releases page]: https://github.com/kubernetes-sigs/kustomize/releases
[`cloud-build-local`]: https://github.com/GoogleCloudPlatform/cloud-build-local
[Google Cloud Build]: https://cloud.google.com/cloud-build
This directory contains scripts and configuration files for publishing a
`kustomize` release on [release page](https://github.com/kubernetes-sigs/kustomize/releases)
Scripts and configuration files for publishing a
`kustomize` release on the [releases page].
## Steps to run build a release locally
Install container-builder-local from [github](https://github.com/GoogleCloudPlatform/container-builder-local).
### Build a release locally
```sh
container-builder-local --config=build/cloudbuild_local.yaml --dryrun=false --write-workspace=/tmp/w .
Install [`cloud-build-local`], then run
```
cloud-build-local \
--config=build/cloudbuild_local.yaml \
--dryrun=false --write-workspace=/tmp/w .
```
You will find the build artifacts under `/tmp/w/dist` directory
to build artifacts under `/tmp/w/dist`.
### Publish a Release
Get on an up-to-date master branch:
```
git checkout master
git fetch upstream
git rebase upstream/master
```
Define the version (see [semver principles](https://semver.org)), e.g.:
```
version=v1.0.3
```
Tag the repo:
```
git tag -a $version -m "$version release"
```
Push the tag upstream:
```
git push upstream $version
```
The new tag will trigger a job in [Google Cloud
Build] to put a new release on the [releases page].

View File

@@ -23,10 +23,10 @@ set -x
# - Use /go as the default GOPATH because this is what the image uses
# - Link our current directory (containing the source code) to the package location in the GOPATH
OWNER="kubernetes-sigs"
OWNER="sigs.k8s.io"
REPO="kustomize"
GO_PKG_OWNER=$GOPATH/src/github.com/$OWNER
GO_PKG_OWNER=$GOPATH/src/$OWNER
GO_PKG_PATH=$GO_PKG_OWNER/$REPO
mkdir -p $GO_PKG_OWNER
@@ -56,4 +56,4 @@ case $key in
esac
done
/goreleaser release --config=build/goreleaser.yml --rm-dist --skip-validate ${SNAPSHOT}
/goreleaser release --config=build/goreleaser.yaml --rm-dist --skip-validate ${SNAPSHOT}

View File

@@ -4,7 +4,7 @@ project_name: kustomize
builds:
- main: ./kustomize.go
binary: kustomize
ldflags: -s -X github.com/kubernetes-sigs/kustomize/version.kustomizeVersion={{.Version}} -X github.com/kubernetes-sigs/kustomize/version.gitCommit={{.Commit}} -X github.com/kubernetes-sigs/kustomize/version.buildDate={{.Date}}
ldflags: -s -X sigs.k8s.io/kustomize/pkg/commands.kustomizeVersion={{.Version}} -X sigs.k8s.io/kustomize/pkg/commands.gitCommit={{.Commit}} -X sigs.k8s.io/kustomize/pkg/commands.buildDate={{.Date}}
goos:
- darwin
- linux

View File

@@ -1,33 +0,0 @@
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
project_name: kustomize
builds:
- main: ./kustomize.go
binary: kustomize
ldflags: -s -X github.com/kubernetes-sigs/kustomize/version.kustomizeVersion={{.Version}} -X github.com/kubernetes-sigs/kustomize/version.gitCommit={{.Commit}} -X github.com/kubernetes-sigs/kustomize/version.buildDate={{.Date}}
goos:
- darwin
- linux
- windows
goarch:
- amd64
env:
- CGO_ENABLED=0
checksum:
name_template: 'checksums.txt'
archive:
format: binary
snapshot:
name_template: "master"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- Merge pull request
- Merge branch
release:
github:
owner: kubernetes-sigs
name: kustomize

View File

@@ -1,6 +0,0 @@
[Kubernetes Community Code of Conduct]: https://git.k8s.io/community/code-of-conduct.md
# Code of Conduct
This project has adopted the
[Kubernetes Community Code of Conduct].

View File

@@ -1,24 +0,0 @@
# Demos
These demos assume that `kustomize` is on your `$PATH`.
They are covered by pre-submit tests.
* [hello world](helloWorld/README.md) - Deploy multiple
(differently configured) variants of a simple Hello
World server.
* [LDAP](ldap/README.md) - Deploy multiple
(differently configured) variants of a LDAP server.
* [mySql](mySql/README.md) - Create a MySQL production
configuration from scratch.
* [springboot](springboot/README.md) - Create a Spring Boot
application production configuration from scratch.
* [configGeneration](configGeneration.md) -
Mixing configuration data from different owners
(e.g. devops/SRE and developers).
* [breakfast](breakfast.md) - Customize breakfast for
Alice and Bob.

4
docs/CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,4 @@
# Kustomize Community Code of Conduct
Kustomize contributers expected to adhere to
the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).

View File

@@ -11,12 +11,12 @@
can be considered.
1. Submit an issue describing your proposed change to
the repo in question.
1. The [repo owners](OWNERS) will respond to your issue
1. The [repo owners](../OWNERS) will respond to your issue
promptly.
1. Fork the repo, develop and test your code.
See the [github workflow guide].
1. For _new features_, provide a markdown-based demo following
the pattern established in the [demos](demos) directory.
the pattern established in the [examples](../examples) directory.
Run `bin/pre-commit.sh` to test your demo.
1. Submit a pull request.

33
docs/INSTALL.md Normal file
View File

@@ -0,0 +1,33 @@
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
[Go]: https://golang.org
## Installation
On macOS, you can install kustomize with Homebrew package
manager:
brew install kustomize
For all operating systems, download a binary from the
[release page].
Or try this to grab the latest official release
using the command line:
```
opsys=linux # or darwin, or windows
curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases/latest |\
grep browser_download |\
grep $opsys |\
cut -d '"' -f 4 |\
xargs curl -O -L
mv kustomize_*_${opsys}_amd64 kustomize
chmod u+x kustomize
```
To install from head with [Go] v1.10.1 or higher:
<!-- @installkustomize @test -->
```
go get github.com/kubernetes-sigs/kustomize
```

23
docs/README.md Normal file
View File

@@ -0,0 +1,23 @@
# Kustomize docs
* [installation instructions](INSTALL.md)
* [kustomization.yaml](kustomization.yaml) - Example of a
[kustomization](glossary.md#kustomization)
with explanations of each field.
* [workflow](workflows.md) - Some steps one might take in using
bespoke and off-the-shelf configurations.
* [glossary](glossary.md) - An attempt to disambiguiate terminology.
* [eschewed features](eschewedFeatures.md) - Why certain features are (currently)
not supported in Kustomize.
* [contributing guidelines](CONTRIBUTING.md) - Please read before sending a PR.
* [code of conduct](CODE_OF_CONDUCT.md)

15
docs/SECURITY_CONTACTS Normal file
View File

@@ -0,0 +1,15 @@
# Defined below are the security contacts for this repo.
#
# They are the contact point for the Product Security Team to reach out
# to for triaging and handling of incoming issues.
#
# The below names agree to abide by the
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
# and will be removed and replaced if they violate that agreement.
#
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
# INSTRUCTIONS AT https://kubernetes.io/security/
monopole
Liujingfang1
pwittrock

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 40 KiB

80
docs/eschewedFeatures.md Normal file
View File

@@ -0,0 +1,80 @@
# Eschewed Features
## Removal directives
`kustomize` supports configurations that can be reasoned about as
_compositions_ or _mixins_ - concepts that are widely accepted as
a best practice in various programming languages.
To this end, `kustomize` offers various _addition_ directives. One
can add labels, annotations, patches, resources and bases.
Corresponding _removal_ directives are not offered.
Removal semantics would introduce many possibilities for
inconsistency, and the need to add code to detect, report and
reject it. It would also allow, and possibly encourage,
unnecessarily complex configuration layouts.
When faced with a situation where removal is desirable, it's
always possible to remove things from a base like labels and
annotations, and/or split multi-resource manifests into individual
resource files - then add things back as desired via the
[kustomization].
If the underlying base is outside of one's control, an [OTS
workflow] is the recommended best practice. Fork the base, remove
what you don't want and commit it to your private fork, then use
kustomize on your fork. As often as desired, use _git rebase_ to
capture improvements from the upstream base.
## Build-time side effects from CLI args or env variables
`kustomize` supports the best practice of storing one's
entire configuration in a version control system.
Changing `kustomize build` configuration output as a result
of additional arguments or flags to `build`, or by
consulting shell environment variable values in `build`
code, would violate that goal.
`kustomize` insteads offers [kustomization] file `edit`
commands. Like any shell command, they can accept
environment variable arguments.
For example, to set the tag used on an image to match an
environment variable, run
```
kustomize edit set imagetag nginx:$MY_NGINX_VERSION
```
as part of some encapsulating work flow executed before
`kustomize build`.
## Globs in kustomization files
`kustomize` supports the best practice of storing one's
entire configuration in a version control system.
Globbing the local file system for files not explicitly
declared in the [kustomization] file at `kustomize build` time
would violate that goal.
Allowing globbing in a kustomization file would also introduce
the same problems as allowing globbing in [java import]
declarations or BUILD/Makefile dependency rules.
`kustomize` will instead provide kustomization file editting
commands that accept globbed arguments, expand them at _edit
time_ relative to the local file system, and store the resulting
explicit names into the kustomization file.
In this way the resources, patches and bases used at _build time_
remain explicitly declared in version control.
[base]: glossary.md#base
[kustomization]: glossary.md#kustomization
[OTS workflow]: workflows.md#off-the-shelf-configuration
[java import]: https://www.codebyamir.com/blog/pitfalls-java-import-wildcards

View File

@@ -2,6 +2,7 @@
[DAM]: #declarative-application-management
[JSON]: https://www.json.org/
[JSONPatch]: https://tools.ietf.org/html/rfc6902
[Resource]: #resource
[YAML]: http://www.yaml.org/start.html
[application]: #application
@@ -15,16 +16,19 @@
[kubernetes]: #kubernetes
[kustomize]: #kustomize
[kustomization]: #kustomization
[off-the-shelf]: #off-the-shelf
[off-the-shelf]: #off-the-shelf-configuration
[overlay]: #overlay
[overlays]: #overlay
[patch]: #patch
[patches]: #patch
[patchJson6902]: #patchJson6902
[patchesJson6902]: #patchjson6902
[proposal]: https://github.com/kubernetes/community/pull/1629
[rebase]: https://git-scm.com/docs/git-rebase
[resource]: #resource
[resources]: #resource
[rpm]: https://en.wikipedia.org/wiki/Rpm_(software)
[strategic merge]: https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md
[target]: #target
[variant]: #variant
[variants]: #variant
@@ -68,25 +72,17 @@ management in k8s.
A _base_ is a [target] that some [overlay] modifies.
Any target, including an overlay, can be a base to
Any target, including an [overlay], can be a base to
another target.
A base has no knowledge of the overlays that refer to it.
A base is usable in isolation, i.e. one should
be able to [apply] a base to a cluster directly.
For simple [gitops] management, a base configuration
could be the _sole content of a git repository
dedicated to that purpose_. Same with [overlays].
Changes in a repo could generate a build, test and
deploy cycle.
Some of the demos for [kustomize] will break from this
idiom and store all demo config files in directories
_next_ to the `kustomize` code so that the code and
demos can be more easily maintained by the same group
of people.
## bespoke configuration
@@ -162,10 +158,10 @@ It's often abbreviated as _k8s_.
An object, expressed in a YAML or JSON file, with the
[fields required] by kubernetes. Basically just a
`kind` field to identify the type, a `metadata/name`
field to identify the variant, and an `apiVersion`
field to identify the version (if there's more than one
version).
_kind_ field to identify the type, a _metadata/name_
field to identify the particular instance, and an
_apiVersion_ field to identify the version (if there's
more than one version).
## kustomize
@@ -210,19 +206,24 @@ An _overlay_ is a [target] that modifies (and thus
depends on) another target.
The [kustomization] in an overlay refers to (via file
path, URI or other method) _some other kustomization_,
path, URI or other method) some other kustomization,
known as its [base].
An overlay is unusable without its base.
An overlay supports the typical notion of a
_development_, _QA_, _staging_ and _production_
environment variants.
An overlay may act as a base to another overlay.
The configuration of these environments is specified in
individual overlays (one per environment) that all
refer to a common base that holds common configuration.
One configures the cluster like this:
Overlays make the most sense when there is _more than
one_, because they create different [variants] of a
common base - e.g. _development_, _QA_, _staging_ and
_production_ environment variants.
These variants use the same overall resources, and vary
in relatively simple ways, e.g. the number of replicas
in a deployment, the CPU to a particular pod, the data
source used in a configmap, etc.
One configures a cluster like this:
> ```
> kustomize build someapp/overlays/staging |\
@@ -232,10 +233,9 @@ One configures the cluster like this:
> kubectl apply -f -
> ```
Usage of the base is implicit (the overlay's kustomization
points to the base).
Usage of the base is implicit - the overlay's
kustomization points to the base.
An overlay may act as a base to another overlay.
## package
@@ -258,6 +258,15 @@ dependencies. Since any resource file can be used as a
patch, one cannot reliably distinguish a resource from
a patch just by looking at the file's [YAML].
## patchJson6902
A _patchJson6902_ refers to a kubernetes object and a [JSONPatch]
that can patch the object. A [JSONPatch] contains a list of operations to change the object's field directly.
This is different from [patch], which is
applied to a target kubernetes object by [strategic merge].
_patchesJson6902_ is a field in kustomization. It contains a list of
_patchJson6902_.
## resource
A _resource_, in the context of kustomize, is a path to
@@ -267,7 +276,7 @@ configmap.
More generally, a resource can be any correct YAML file
that [defines an object](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields)
with a `kind` and a `metadata/name` field.
with a _kind_ and a _metadata/name_ field.
A _resource_ in the content of a REST-ful API is the
@@ -289,9 +298,8 @@ The _target_ is the argument to `kustomize build`, e.g.:
> kustomize build $target
> ```
`$target` must be a path to a directory that
immediately contains a file called
`kustomization.yaml` (i.e. a [kustomization]).
`$target` must be a path or a url to a directory that
immediately contains a [kustomization].
The target contains, or refers to, all the information
needed to create customized resources to send to the
@@ -304,15 +312,15 @@ A target is a [base] or an [overlay].
A _variant_ is the outcome, in a cluster, of applying
an [overlay] to a [base].
> E.g., a _staging_ and _production_ overlay both modify some
> common base to create distinct variants.
>
> The _staging_ variant is the set of resources
> exposed to quality assurance testing, or to some
> external users who'd like to see what the next
> version of production will look like.
>
> The _production_ variant is the set of resources
> exposed to production traffic, and thus may employ
> deployments with a large number of replicas and higher
> cpu and memory requests.
E.g., a _staging_ and _production_ overlay both modify
some common base to create distinct variants.
The _staging_ variant is the set of resources exposed
to quality assurance testing, or to some external users
who'd like to see what the next version of production
will look like.
The _production_ variant is the set of resources
exposed to production traffic, and thus may employ
deployments with a large number of replicas and higher
cpu and memory requests.

View File

@@ -32,6 +32,8 @@
# visible in configuration reviews.
# ----------------------------------------------------
# Adds namespace to all resources.
namespace: my-namespace
# Value of this field is prepended to the
# names of all resources, e.g. a deployment named
@@ -80,11 +82,30 @@ secretGenerator:
tls.crt: "cat secret/tls.cert"
tls.key: "cat secret/tls.key"
type: "kubernetes.io/tls"
- name: downloaded_secret
# timeoutSeconds specifies the number of seconds to
# wait for the commands below. It defaults to 5 seconds.
timeoutSeconds: 30
commands:
username: "curl -s https://path/to/secrets/username.yaml"
password: "curl -s https://path/to/secrets/password.yaml"
type: Opaque
- name: env_file_secret
# envCommand is similar to command but outputs lines of key=val pairs
# i.e. a Docker .env file or a .ini file.
# you can only specify one envCommand per secret.
envCommand: printf \"DB_USERNAME=admin\nDB_PASSWORD=somepw\"
type: Opaque
# Each entry in this list should resolve to a directory
# containing a kustomization file, else the
# customization fails.
#
# The entry could be a relative path pointing to a local directory
# or a url pointing to a directory in a remote repo.
# The url should follow hashicorp/go-getter URL format
# https://github.com/hashicorp/go-getter#url-format
#
# The presence of this field means this file (the file
# you a reading) is an _overlay_ that further
# customizes information coming from these _bases_.
@@ -95,6 +116,9 @@ secretGenerator:
# etc. that differ from the common base).
bases:
- ../../base
- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
- github.com/Liujingfang1/mysql
- github.com/Liujingfang1/kustomize//examples/helloWorld?ref=test-branch
# Each entry in this list should resolve to
# a partial or complete resource definition file.
@@ -113,3 +137,122 @@ patches:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml
# Each entry in this list should resolve to
# a kubernetes object and a JSON patch that will be applied
# to the object.
# The JSON patch is documented at https://tools.ietf.org/html/rfc6902
#
# target field points to a kubernetes object within the same kustomization
# by the object's group, version, kind, name and namespace.
# path field is a relative file path of a JSON patch file.
# The content in this patch file can be either in JSON format as
#
# [
# {"op": "add", "path": "/some/new/path", "value": "value"},
# {"op": "replace", "path": "/some/existing/path", "value": "new value"}
# ]
#
# or in YAML format as
#
# - op: add
# path: /some/new/path
# value: value
# - op:replace
# path: /some/existing/path
# value: new value
#
patchesJson6902
- target:
version: v1
kind: Deployment
name: my-deployment
path: add_init_container.yaml
- target:
version: v1
kind: Service
name: my-service
path: add_service_annotation.yaml
# Each entry in this list should be a relative path to
# a file for custom resource definition(CRD).
#
# The presence of this field is to allow kustomize be
# aware of CRDs and apply proper
# transformation for any objects in those types.
#
# Typical use case: A CRD object refers to a ConfigMap object.
# In kustomization, the ConfigMap object name may change by adding namePrefix or hashing
# The name reference for this ConfigMap object in CRD object need to be
# updated with namePrefix or hashing in the same way.
crds:
- crds/typeA.yaml
- crds/typeB.yaml
# Vars are used to insert values from resources that cannot be referenced
# otherwise. For example if you need to pass a Service's name to the arguments
# or environment variables of a program but without hard coding the actual name
# of the Service you'd insert `$(MY_SERVICE_NAME)` into the value field of the
# env var or into the command or args of the container as shown here:
# ```
# containers:
# - image: myimage
# command: ["start", "--host", "$(MY_SERVICE_NAME)"]
# env:
# - name: SECRET_TOKEN
# value: $(SOME_SECRET_NAME)
# ```
#
# Then you'll add an entry to `vars:` like shown below with the same name
# and a reference to the resource from which to pull the field's value.
# The actual field's path is optional and by default it will use
# `metadata.name`. Currently only string type fields are supported, no integers
# or booleans, etc. Also array access is currently not possible. For example getting
# the image field of container number 2 inside of a pod can currently not be done.
#
# Not every location of a variable is supported. To see a complete list of locations
# see the file [refvars.go](https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/refvars.go#L20).
#
# An example of a situation where you'd not use vars is when you'd like to set a
# pod's `serviceAccountName`. In that case you would just reference the ServiceAccount
# by name and Kustomize will resolve it to the eventual name while building the manifests.
vars:
- name: SOME_SECRET_NAME
objref:
kind: Secret
name: my-secret
apiVersion: v1
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-service
apiVersion: v1
fieldref:
fieldpath: metadata.name
- name: ANOTHER_DEPLOYMENTS_POD_RESTART_POLICY
objref:
kind: Deployment
name: my-deployment
apiVersion: apps/v1
fieldref:
fieldpath: spec.template.spec.restartPolicy
# ImageTags modify the tags for images without creating patches.
# E.g. Given this fragment of a Deployment:
# ```
# containers:
# - name: myapp
# image: mycontainerregistry/myimage:v0
# - name: nginxapp
# image: nginx:1.7.9
#```
# one can change the tag of myimage to v1 and the tag of nginx to 1.8.0 with the following:
#
# It also supports digests. If digest is present newTag is ignored.
imageTags:
- name: mycontainerregistry/myimage
newTag: v1
- name: nginx
newTag: 1.8.0
- name: alpine
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1,16 +1,16 @@
[OTS]: glossary.md#off-the-shelf
[OTS]: glossary.md#off-the-shelf-configuration
[apply]: glossary.md#apply
[applying]: glossary.md#apply
[base]: glossary.md#base
[fork]: https://guides.github.com/activities/forking/
[variants]: glossary.md#variant
[kustomization]: glossary.md#kustomization
[off-the-shelf]: glossary.md#off-the-shelf
[off-the-shelf]: glossary.md#off-the-shelf-configuration
[overlays]: glossary.md#overlay
[patch]: glossary.md#patch
[patches]: glossary.md#patch
[rebase]: https://git-scm.com/docs/git-rebase
[resources]: glossary.md#resources
[resources]: glossary.md#resource
[workflowBespoke]: workflowBespoke.jpg
[workflowOts]: workflowOts.jpg
@@ -21,14 +21,17 @@ use and maintain a configuration.
## Bespoke configuration
In this workflow, all configuration files are owned by
the user. No content is incorporated from version
In this workflow, all configuration (resource YAML) files
are owned by the user. No content is incorporated from version
control repositories owned by others.
![bespoke config workflow image][workflowBespoke]
#### 1) create a directory in version control
Speculate some overall cluster application called _ldap_;
we want to keep its configuration in its own repo.
> ```
> git init ~/ldap
> ```
@@ -64,8 +67,8 @@ specified in the base.
Run kustomize, and pipe the output to [apply].
> ```
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
> kustomize ~/ldap/overlays/production | kubectl apply -f -
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
> ```
@@ -85,13 +88,13 @@ is periodically consulted for updates.
The [base] directory is maintained in a repo whose
upstream is an [OTS] configuration, in this case
https://github.com/kinflate/ldap.
some user's `ldap` repo:
> ```
> mkdir ~/ldap
> git clone https://github.com/$USER/ldap ~/ldap/base
> cd ~/ldap/base
> git remote add upstream git@github.com:kustomize/ldap
> git remote add upstream git@github.com:$USER/ldap
> ```
#### 3) create [overlays]
@@ -107,17 +110,19 @@ The [overlays] are siblings to each other and to the
> mkdir -p ~/ldap/overlays/production
> ```
The user can maintain the `overlays` directory in a
distinct repository.
#### 4) bring up [variants]
> ```
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
> kustomize ~/ldap/overlays/production | kubectl apply -f -
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
> ```
#### 5) (optionally) capture changes from upstream
The user can optionally [rebase] their [base] to
The user can periodically [rebase] their [base] to
capture changes made in the upstream repository.
> ```

44
examples/README.md Normal file
View File

@@ -0,0 +1,44 @@
# Examples
These examples assume that `kustomize` is on your `$PATH`.
They are covered by [pre-commit](../bin/pre-commit.sh)
tests, and should work with HEAD
<!-- @installkustomize @test -->
```
go get sigs.k8s.io/kustomize
```
* [hello world](helloWorld/README.md) - Deploy multiple
(differently configured) variants of a simple Hello
World server.
* [LDAP](ldap/README.md) - Deploy multiple
(differently configured) variants of a LDAP server.
* [mySql](mySql/README.md) - Create a MySQL production
configuration from scratch.
* [springboot](springboot/README.md) - Create a Spring Boot
application production configuration from scratch.
* [combineConfigs](combineConfigs.md) -
Mixing configuration data from different owners
(e.g. devops/SRE and developers).
* [configGenerations](configGeneration.md) -
Rolling update when ConfigMapGenerator changes
* [breakfast](breakfast.md) - Customize breakfast for
Alice and Bob.
* [container args](wordpress/README.md) - Injecting k8s runtime data into container arguments (e.g. to point wordpress to a SQL service).
* [image tags](imageTags.md) - Updating image tags without applying a patch.
* [multibases](multibases/README.md) - Composing three variants (dev, staging, production) with a common base.
* [remote target](remoteBuild.md) - Building a kustomization from a github URL
* [json patch](jsonpatch.md) - Apply a json patch in a kustomization

View File

@@ -73,7 +73,7 @@ commonLabels:
who: alice
bases:
- ../../base
patches:
patchesStrategicMerge:
- temperature.yaml
EOF
@@ -96,7 +96,7 @@ commonLabels:
who: bob
bases:
- ../../base
patches:
patchesStrategicMerge:
- topping.yaml
EOF

View File

@@ -113,7 +113,7 @@ A cluster environment is created by
running `kustomize build` on a [target] that happens to
be an [overlay].
[helloworld]: helloworld.md
[helloworld]: helloWorld/README.md
The following example will do that, but will focus on
configMap construction, and not worry about how to

View File

@@ -0,0 +1,208 @@
[patch]: ../docs/glossary.md#patch
[resource]: ../docs/glossary.md#resource
[variant]: ../docs/glossary.md#variant
## ConfigMap generation and rolling updates
Kustomize provides two ways of adding ConfigMap in one `kustomization`, either by declaring ConfigMap as a [resource] or declaring ConfigMap from a ConfigMapGenerator. The formats inside `kustomization.yaml` are
> ```
> # declare ConfigMap as a resource
> resources:
> - configmap.yaml
>
> # declare ConfigMap from a ConfigMapGenerator
> configMapGenerator:
> - name: a-configmap
> files:
> - configs/configfile
> - configs/another_configfile
> ```
The ConfigMaps declared as [resource] are treated the same way as other resources. Kustomize doesn't append any hash to the ConfigMap name. The ConfigMap declared from a ConfigMapGenerator is treated differently. A hash is appended to the name and any change in the ConfigMap will trigger a rolling update.
In this demo, the same [hello_world](helloWorld/README.md) is used while the ConfigMap declared as [resources] is replaced by a ConfigMap declared from a ConfigmapGenerator. The change in this ConfigMap will result in a hash change and a rolling update.
### Establish base and staging
Establish the base with a configMapGenerator
<!-- @establishBase @test -->
```
DEMO_HOME=$(mktemp -d)
BASE=$DEMO_HOME/base
mkdir -p $BASE
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/helloWorld\
/{deployment,service}.yaml"
cat <<'EOF' >$BASE/kustomization.yaml
commonLabels:
app: hello
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: the-map
literals:
- altGreeting=Good Morning!
- enableRisky="false"
EOF
```
Establish the staging with a patch applied to the ConfigMap
<!-- @establishStaging @test -->
```
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
namePrefix: staging-
commonLabels:
variant: staging
org: acmeCorporation
commonAnnotations:
note: Hello, I am staging!
bases:
- ../../base
patchesStrategicMerge:
- map.yaml
EOF
cat <<EOF >$OVERLAYS/staging/map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: the-map
data:
altGreeting: "Have a pineapple!"
enableRisky: "true"
EOF
```
### Review
The _hello-world_ deployment running in this cluster is
configured with data from a configMap.
The deployment refers to this map by name:
<!-- @showDeployment @test -->
```
grep -C 2 configMapKeyRef $BASE/deployment.yaml
```
Changing the data held by a live configMap in a cluster
is considered bad practice. Deployments have no means
to know that the configMaps they refer to have
changed, so such updates have no effect.
The recommended way to change a deployment's
configuration is to
1. create a new configMap with a new name,
1. patch the _deployment_, modifying the name value of
the appropriate `configMapKeyRef` field.
This latter change initiates rolling update to the pods
in the deployment. The older configMap, when no longer
referenced by any other resource, is eventually [garbage
collected](https://github.com/kubernetes-sigs/kustomize/issues/242).
### How this works with kustomize
The _staging_ [variant] here has a configMap [patch]:
<!-- @showMapPatch @test -->
```
cat $OVERLAYS/staging/map.yaml
```
This patch is by definition a named but not necessarily
complete resource spec intended to modify a complete
resource spec.
The ConfigMap it modifies is declared from a configMapGenerator.
<!-- @showMapBase @test -->
```
grep -C 4 configMapGenerator $BASE/kustomization.yaml
```
For a patch to work, the names in the `metadata/name`
fields must match.
However, the name values specified in the file are
_not_ what gets used in the cluster. By design,
kustomize modifies names of ConfigMaps declared from ConfigMapGenerator. To see the names
ultimately used in the cluster, just run kustomize:
<!-- @grepStagingName @test -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
```
The configMap name is prefixed by _staging-_, per the
`namePrefix` field in
`$OVERLAYS/staging/kustomization.yaml`.
The suffix to the configMap name is generated from a
hash of the maps content - in this case the name suffix
is _hhhhkfmgmk_:
<!-- @grepStagingHash @test -->
```
kustomize build $OVERLAYS/staging | grep hhhhkfmgmk
```
Now modify the map patch, to change the greeting
the server will use:
<!-- @changeMap @test -->
```
sed -i 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
```
See the new greeting:
```
kustomize build $OVERLAYS/staging |\
grep -B 2 -A 3 kiwi
```
Run kustomize again to see the new configMap names:
<!-- @grepStagingName @test -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
```
Confirm that the change in configMap content resulted
in three new names ending in _khk45ktkd9_ - one in the
configMap name itself, and two in the deployment that
uses the map:
<!-- @countHashes @test -->
```
test 3 == \
$(kustomize build $OVERLAYS/staging | grep khk45ktkd9 | wc -l); \
echo $?
```
Applying these resources to the cluster will result in
a rolling update of the deployments pods, retargetting
them from the _hhhhkfmgmk_ maps to the _khk45ktkd9_
maps. The system will later garbage collect the
unused maps.
## Rollback
To rollback, one would undo whatever edits were made to
the configuation in source control, then rerun kustomize
on the reverted configuration and apply it to the
cluster.

View File

@@ -51,7 +51,7 @@ mkdir -p $BASE
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/demos/helloWorld\
/master/examples/helloWorld\
/{configMap,deployment,kustomization,service}.yaml"
```
@@ -112,6 +112,12 @@ sed -i 's/app: hello/app: my-hello/' \
$BASE/kustomization.yaml
```
On a Mac, use:
```
sed -i '' $pattern $file
```
to get in-place editing.
See the effect:
<!-- @checkLabel @test -->
```
@@ -150,7 +156,7 @@ commonAnnotations:
note: Hello, I am staging!
bases:
- ../../base
patches:
patchesStrategicMerge:
- map.yaml
EOF
```
@@ -191,7 +197,7 @@ commonAnnotations:
note: Hello, I am production!
bases:
- ../../base
patches:
patchesStrategicMerge:
- deployment.yaml
EOF
```
@@ -309,122 +315,3 @@ To deploy, pipe the above commands to kubectl apply:
> kustomize build $OVERLAYS/production |\
> kubectl apply -f -
> ```
## Rolling updates
### Review
The _hello-world_ deployment running in this cluster is
configured with data from a configMap.
The deployment refers to this map by name:
<!-- @showDeployment @test -->
```
grep -C 2 configMapKeyRef $DEMO_HOME/base/deployment.yaml
```
Changing the data held by a live configMap in a cluster
is considered bad practice. Deployments have no means
to know that the configMaps they refer to have
changed, so such updates have no effect.
The recommended way to change a deployment's
configuration is to
1. create a new configMap with a new name,
1. patch the _deployment_, modifying the name value of
the appropriate `configMapKeyRef` field.
This latter change initiates rolling update to the pods
in the deployment. The older configMap, when no longer
referenced by any other resource, is eventually garbage
collected.
### How this works with kustomize
The _staging_ [variant] here has a configMap [patch]:
<!-- @showMapPatch @test -->
```
cat $OVERLAYS/staging/map.yaml
```
This patch is by definition a named but not necessarily
complete resource spec intended to modify a complete
resource spec.
The resource it modifies is here:
<!-- @showMapBase @test -->
```
cat $DEMO_HOME/base/configMap.yaml
```
For a patch to work, the names in the `metadata/name`
fields must match.
However, the name values specified in the file are
_not_ what gets used in the cluster. By design,
kustomize modifies these names. To see the names
ultimately used in the cluster, just run kustomize:
<!-- @grepStagingName @test -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
```
The configMap name is prefixed by _staging-_, per the
`namePrefix` field in
`$OVERLAYS/staging/kustomization.yaml`.
The suffix to the configMap name is generated from a
hash of the maps content - in this case the name suffix
is _hhhhkfmgmk_:
<!-- @grepStagingHash @test -->
```
kustomize build $OVERLAYS/staging | grep hhhhkfmgmk
```
Now modify the map patch, to change the greeting
the server will use:
<!-- @changeMap @test -->
```
sed -i 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
```
Run kustomize again to see the new names:
<!-- @grepStagingName @test -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
```
Confirm that the change in configMap content resulted
in three new names ending in _khk45ktkd9_ - one in the
configMap name itself, and two in the deployment that
uses the map:
<!-- @countHashes @test -->
```
test 3 == \
$(kustomize build $OVERLAYS/staging | grep khk45ktkd9 | wc -l)
```
Applying these resources to the cluster will result in
a rolling update of the deployments pods, retargetting
them from the _hhhhkfmgmk_ maps to the _khk45ktkd9_
maps. The system will later garbage collect the
unused maps.
## Rollback
To rollback, one would undo whatever edits were made to
the configuation in source control, then rerun kustomize
on the reverted configuration and apply it to the
cluster.

View File

@@ -5,5 +5,5 @@ commonLabels:
resources:
- deployment.yaml
- configMap.yaml
- service.yaml
- configMap.yaml

75
examples/imageTags.md Normal file
View File

@@ -0,0 +1,75 @@
# Demo: change image tags
Define a place to work:
<!-- @makeWorkplace @test -->
```
DEMO_HOME=$(mktemp -d)
```
Make a `kustomization` containing a pod resource
<!-- @createKustomization @test -->
```
cat <<EOF >$DEMO_HOME/kustomization.yaml
resources:
- pod.yaml
EOF
```
Declare the pod resource
<!-- @createDeployment @test -->
```
cat <<EOF >$DEMO_HOME/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.29.0
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-mydb
image: busybox:1.29.0
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
EOF
```
The `myapp-pod` resource declares an initContainer and a container, both use the image `busybox:1.29.0`.
The tag `1.29.0` can be changed by adding `imageTags` in `kustomization.yaml`.
Add `imageTags`:
<!-- @addImageTags @test -->
```
cd $DEMO_HOME
kustomize edit set imagetag busybox:1.29.1
```
The `kustomization.yaml` will be added following `imageTags`.
> ```
> imageTags:
> - name: busybox
> newTag: 1.29.1
> ```
Now build this `kustomization`
<!-- @kustomizeBuild @test -->
```
kustomize build $DEMO_HOME
```
Confirm that this replaces _both_ busybox tags:
<!-- @confirmTags @test -->
```
test 2 == \
$(kustomize build $DEMO_HOME | grep busybox:1.29.1 | wc -l); \
echo $?
```

View File

@@ -24,7 +24,7 @@
#
# This script assumes that the process running it has
# checked out the kubernetes-sigs/kustomize repo, and
# has cd'ed into it (i.e. the directory above "demos")
# has cd'ed into it (i.e. the directory above "examples")
# before running it.
#
# At time of writing, its 'call point' was in
@@ -79,6 +79,6 @@ function runTest {
setUpEnv
pushd demos
pushd examples
runTest ldap/integration_test.sh ldap/base
popd

77
examples/jsonpatch.md Normal file
View File

@@ -0,0 +1,77 @@
# Demo: applying a json patch
A kustomization file supports customizing resources via [JSON patches](https://tools.ietf.org/html/rfc6902).
The example below modifies an `Ingress` object with such a patch.
Make a `kustomization` containing an ingress resource.
<!-- @createIngress @test -->
```
DEMO_HOME=$(mktemp -d)
cat <<EOF >$DEMO_HOME/kustomization.yaml
resources:
- ingress.yaml
EOF
cat <<EOF >$DEMO_HOME/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: my-api
servicePort: 80
EOF
```
Declare a JSON patch file to update two fields of the Ingress object:
- change host from `foo.bar.com` to `foo.bar.io`
- change servicePort from `80` to `8080`
<!-- @addJsonPatch @test -->
```
cat <<EOF >$DEMO_HOME/ingress_patch.json
[
{"op": "replace", "path": "/spec/rules/0/host", "value": "foo.bar.io"},
{"op": "replace", "path": "/spec/rules/0/http/paths/0/backend/servicePort", "value": 8080}
]
EOF
```
Apply the patch by adding _patchesJson6902_ field in kustomization.yaml
<!-- @applyJsonPatch @test -->
```
cat <<EOF >>$DEMO_HOME/kustomization.yaml
patchesJson6902:
- target:
group: extensions
version: v1beta1
kind: Ingress
name: my-ingress
path: ingress_patch.json
EOF
```
Running `kustomize build $DEMO_HOME`, in the ourput confirm that host has been updated correctly.
<!-- @confirmHost @test -->
```
test 1 == \
$(kustomize build $DEMO_HOME | grep "host: foo.bar.io" | wc -l); \
echo $?
```
Running `kustomize build $DEMO_HOME`, in the ourput confirm that the servicePort has been updated correctly.
<!-- @confirmServicePort @test -->
```
test 1 == \
$(kustomize build $DEMO_HOME | grep "servicePort: 8080" | wc -l); \
echo $?
```

View File

@@ -45,7 +45,7 @@ mkdir -p $BASE
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/demos/ldap"
/master/examples/ldap"
curl -s -o "$BASE/#1" "$CONTENT/base\
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"

View File

@@ -1,5 +1,5 @@
bases:
- ../../base
patches:
patchesStrategicMerge:
- deployment.yaml
namePrefix: production-

View File

@@ -1,6 +1,6 @@
bases:
- ../../base
patches:
patchesStrategicMerge:
- deployment.yaml
nameprefix: staging-
configMapGenerator:

View File

@@ -0,0 +1,127 @@
# Demo: multibases with a common base
`kustomize` encourages defining multiple variants - e.g. dev, staging and prod, as overlays on a common base.
It's possible to create an additional overlay to compose these variants together - just declare the overlays as the bases of a new kustomization.
This is also a means to apply a common label or annotation across the variants, if for some reason the base isn't under your control. It also allows one to define a left-most namePrefix across the variants - something that cannot be done by modifying the common base.
The following demonstrates this using a base that's just one pod.
Define a place to work:
<!-- @makeWorkplace @test -->
```
DEMO_HOME=$(mktemp -d)
```
Define a common base:
<!-- @makeBase @test -->
```
BASE=$DEMO_HOME/base
mkdir $BASE
cat <<EOF >$BASE/kustomization.yaml
resources:
- pod.yaml
EOF
cat <<EOF >$BASE/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.7.9
EOF
```
Define a dev variant overlaying base:
<!-- @makeDev @test -->
```
DEV=$DEMO_HOME/dev
mkdir $DEV
cat <<EOF >$DEV/kustomization.yaml
bases:
- ./../base
namePrefix: dev-
EOF
```
Define a staging variant overlaying base:
<!-- @makeStaging @test -->
```
STAG=$DEMO_HOME/staging
mkdir $STAG
cat <<EOF >$STAG/kustomization.yaml
bases:
- ./../base
namePrefix: stag-
EOF
```
Define a production variant overlaying base:
<!-- @makeProd @test -->
```
PROD=$DEMO_HOME/production
mkdir $PROD
cat <<EOF >$PROD/kustomization.yaml
bases:
- ./../base
namePrefix: prod-
EOF
```
Then define a _Kustomization_ composing three variants together:
<!-- @makeTopLayer @test -->
```
cat <<EOF >$DEMO_HOME/kustomization.yaml
bases:
- ./dev
- ./staging
- ./production
namePrefix: cluster-a-
EOF
```
Now the workspace has following directories
> ```
> .
> ├── base
> │   ├── kustomization.yaml
> │   └── pod.yaml
> ├── dev
> │   └── kustomization.yaml
> ├── kustomization.yaml
> ├── production
> │   └── kustomization.yaml
> └── staging
> └── kustomization.yaml
> ```
Confirm that the `kustomize build` output contains three pod objects from dev, staging and production variants.
<!-- @confirmVariants @test -->
```
test 1 == \
$(kustomize build $DEMO_HOME | grep cluster-a-dev-myapp-pod | wc -l); \
echo $?
test 1 == \
$(kustomize build $DEMO_HOME | grep cluster-a-stag-myapp-pod | wc -l); \
echo $?
test 1 == \
$(kustomize build $DEMO_HOME | grep cluster-a-prod-myapp-pod | wc -l); \
echo $?
```
Similarly to adding different `namePrefix` in different variants, one can also add different `namespace` and compose those variants in
one _kustomization_. For more details, take a look at [multi-namespaces](multi-namespace.md).

View File

@@ -0,0 +1,2 @@
resources:
- pod.yaml

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.7.9

View File

@@ -0,0 +1,4 @@
bases:
- ./../base
namePrefix: dev-

View File

@@ -0,0 +1,6 @@
bases:
- ./dev
- ./staging
- ./production
namePrefix: cluster-a-

View File

@@ -0,0 +1,115 @@
# Demo: multi namespaces with a common base
`kustomize` supports defining multiple variants with different namespace, as overlays on a common base.
It's possible to create an additional overlay to compose these variants together - just declare the overlays as the bases of a new kustomization. The following demonstrates this using a base that's just one pod.
Define a place to work:
<!-- @makeWorkplace @test -->
```
DEMO_HOME=$(mktemp -d)
```
Define a common base:
<!-- @makeBase @test -->
```
BASE=$DEMO_HOME/base
mkdir $BASE
cat <<EOF >$BASE/kustomization.yaml
resources:
- pod.yaml
EOF
cat <<EOF >$BASE/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.7.9
EOF
```
Define a variant in namespace-a overlaying base:
<!-- @makeNamespaceA @test -->
```
NSA=$DEMO_HOME/namespace-a
mkdir $NSA
cat <<EOF >$NSA/kustomization.yaml
bases:
- ./../base
resources:
- namespace.yaml
namespace: namespace-a
EOF
cat <<EOF >$NSA/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: namespace-a
EOF
```
Define a variant in namespace-b overlaying base:
<!-- @makeNamespaceB @test -->
```
NSB=$DEMO_HOME/namespace-b
mkdir $NSB
cat <<EOF >$NSB/kustomization.yaml
bases:
- ./../base
resources:
- namespace.yaml
namespace: namespace-b
EOF
cat <<EOF >$NSB/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: namespace-b
EOF
```
Then define a _Kustomization_ composing two variants together:
<!-- @makeTopLayer @test -->
```
cat <<EOF >$DEMO_HOME/kustomization.yaml
bases:
- ./namespace-a
- ./namespace-b
EOF
```
Now the workspace has following directories
> ```
> .
> ├── base
> │   ├── kustomization.yaml
> │   └── pod.yaml
> ├── kustomization.yaml
> ├── namespace-a
> │   ├── kustomization.yaml
> │   └── namespace.yaml
> └── namespace-b
> ├── kustomization.yaml
> └── namespace.yaml
> ```
Confirm that the `kustomize build` output contains two pod objects from namespace-a and namespace-b.
<!-- @confirmVariants @test -->
```
test 2 == \
$(kustomize build $DEMO_HOME| grep -B 4 "namespace: namespace-[ab]" | grep "name: myapp-pod" | wc -l); \
echo $?
```

View File

@@ -0,0 +1,4 @@
bases:
- ./../base
namePrefix: prod-

View File

@@ -0,0 +1,4 @@
bases:
- ./../base
namePrefix: staging-

View File

@@ -29,7 +29,7 @@ Download them:
```
curl -s -o "$DEMO_HOME/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/demos/mySql\
/master/examples/mySql\
/{deployment,secret,service}.yaml"
```
@@ -150,7 +150,7 @@ Off the shelf MySQL uses `emptyDir` type volume, which
gets wiped away if the MySQL Pod is recreated, and that
is certainly not desirable for production
environment. So we want to use Persistent Disk in
production. kustomize lets you apply `patches` to the
production. kustomize lets you apply `patchesStrategicMerge` to the
resources.
<!-- @createPatchFile @test -->
@@ -176,7 +176,7 @@ Add the patch file to `kustomization.yaml`:
<!-- @specifyPatch @test -->
```
cat <<'EOF' >> $DEMO_HOME/kustomization.yaml
patches:
patchesStrategicMerge:
- persistent-disk.yaml
EOF
```
@@ -188,7 +188,7 @@ Lets break this down:
in deployment.yaml
- Then we added `persistent-disk.yaml` to list of
`patches` in `kustomization.yaml`. `kustomize build`
`patchesStrategicMerge` in `kustomization.yaml`. `kustomize build`
will apply this patch to the deployment resource with
the name `mysql` as defined in the patch.

69
examples/remoteBuild.md Normal file
View File

@@ -0,0 +1,69 @@
# remote targets
`kustomize build` can be run against a url. The effect is the same as cloing the repo, checking out the specified ref,
then running `kustomize build` against the desired directory in the local copy.
Take `github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6` as an example.
According to [multibases](multibases/README.md) demo, this kustomization contains three Pod objects with names as
`cluster-a-dev-myapp-pod`, `cluster-a-stag-myapp-pod`, `cluster-a-prod-myapp-pod`.
Running `kustomize build` against the url gives the same output.
<!-- @remoteBuild @test -->
```
target=github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
test 3 == \
$(kustomize build $target | grep cluster-a-.*-myapp-pod | wc -l); \
echo $?
```
Overlays can be remote as well:
<!-- @remoteOverlayBuild @test -->
```
target=github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6
test 1 == \
$(kustomize build $target | grep cluster-a-dev-myapp-pod | wc -l); \
echo $?
```
A base can also be specified as a URL:
<!-- @createOverlay @test -->
```
DEMO_HOME=$(mktemp -d)
cat <<EOF >$DEMO_HOME/kustomization.yaml
bases:
- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
namePrefix: remote-
EOF
```
Running `kustomize build $DEMO_HOME` and confirm the output contains three Pods and all have `remote-` prefix.
<!-- @remoteBases @test -->
```
test 3 == \
$(kustomize build $DEMO_HOME | grep remote-.*-myapp-pod | wc -l); \
echo $?
```
## URL format
The url should follow
[hashicorp/go-getter URL format](https://github.com/hashicorp/go-getter#url-format).
Here are some example urls pointing to Github repos following this convention.
- a repo with a root level kustomization.yaml
`github.com/Liujingfang1/mysql`
- a repo with a root level kustomization.yaml on branch test
`github.com/Liujingfang1/mysql?ref=test`
- a subdirectory in a repo on version v1.0.6
`github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6`
- a subdirectory in a repo on branch repoUrl2
`github.com/Liujingfang1/kustomize//examples/helloWorld?ref=repoUrl2`
- a subdirectory in a repo on commit `7050a45134e9848fca214ad7e7007e96e5042c03`
`github.com/Liujingfang1/kustomize//examples/helloWorld?ref=7050a45134e9848fca214ad7e7007e96e5042c03`

View File

@@ -31,7 +31,7 @@ Download them:
```
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/demos/springboot"
/master/examples/springboot"
curl -s -o "$DEMO_HOME/#1.yaml" \
"$CONTENT/base/{deployment,service}.yaml"
@@ -291,7 +291,7 @@ kustomize edit add patch healthcheck_patch.yaml
`kustomization.yaml` should have patches field:
> ```
> patches:
> patchesStrategicMerge:
> - patch.yaml
> - memorylimit_patch.yaml
> - healthcheck_patch.yaml

View File

@@ -1,6 +1,6 @@
bases:
- ../../base
patches:
patchesStrategicMerge:
- patch.yaml
- healthcheck_patch.yaml
- memorylimit_patch.yaml

View File

@@ -4,7 +4,7 @@ metadata:
name: demo-configmap
data:
application.properties: |
app.name=Staging Kinflate Demo
app.name=Production Kinflate Demo
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://<production_db_ip>:3306/db_example
spring.datasource.username=root

View File

@@ -0,0 +1,146 @@
# Demo: Injecting k8s runtime data into containers
In this tutorial, you will learn how to use `kustomize` to declare a variable reference and substitute it in container's command.
To run WordPress, it's necessary to
- connect WordPress with a MySQL database
- access the service name of MySQL database from WordPress container
First make a place to work:
<!-- @makeDemoHome @test -->
```
DEMO_HOME=$(mktemp -d)
MYSQL_HOME=$DEMO_HOME/mysql
mkdir -p $MYSQL_HOME
WORDPRESS_HOME=$DEMO_HOME/wordpress
mkdir -p $WORDPRESS_HOME
```
### Download resources
Download the resources and `kustomization.yaml` for WordPress.
<!-- @downloadResources @test -->
```
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/wordpress/wordpress"
curl -s -o "$WORDPRESS_HOME/#1.yaml" \
"$CONTENT/{deployment,service,kustomization}.yaml"
```
Download the resources and `kustomization.yaml` for MySQL.
<!-- @downloadResources @test -->
```
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/wordpress/mysql"
curl -s -o "$MYSQL_HOME/#1.yaml" \
"$CONTENT/{deployment,service,secret,kustomization}.yaml"
```
### Create kustomization.yaml
Create a new kustomization with two bases:
<!-- @createKustomization @test -->
```
cat <<EOF >$DEMO_HOME/kustomization.yaml
bases:
- wordpress
- mysql
namePrefix: demo-
patchesStrategicMerge:
- patch.yaml
EOF
```
### Download patch for WordPress
In the new kustomization, apply a patch for wordpress deployment. The patch does two things
- Add an initial container to show the mysql service name
- Add environment variable that allow wordpress to find the mysql database
<!-- @downloadPatch @test -->
```
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/wordpress"
curl -s -o "$DEMO_HOME/#1.yaml" \
"$CONTENT/{patch}.yaml"
```
The patch has following content
> ```
> apiVersion: apps/v1beta2
> kind: Deployment
> metadata:
> name: wordpress
> spec:
> template:
> spec:
> initContainers:
> - name: init-command
> image: debian
> command:
> - "echo $(WORDPRESS_SERVICE)"
> - "echo $(MYSQL_SERVICE)"
> containers:
> - name: wordpress
> env:
> - name: WORDPRESS_DB_HOST
> value: $(MYSQL_SERVICE)
> - name: WORDPRESS_DB_PASSWORD
> valueFrom:
> secretKeyRef:
> name: mysql-pass
> key: password
> ```
The init container's command requires information that depends on k8s resource object fields, represented by the placeholder variables
$(WORDPRESS_SERVICE) and $(MYSQL_SERVICE).
### Bind the Variables to k8s Object Fields
<!-- @addVarRef @test -->
```
cat <<EOF >>$DEMO_HOME/kustomization.yaml
vars:
- name: WORDPRESS_SERVICE
objref:
kind: Service
name: wordpress
apiVersion: v1
fieldref:
fieldpath: metadata.name
- name: MYSQL_SERVICE
objref:
kind: Service
name: mysql
apiVersion: v1
EOF
```
`WORDPRESS_SERVICE` is from the field `metadata.name` of Service `wordpress`. If we don't specify `fieldref`, the default is `metadata.name`. So `MYSQL_SERVICE` is from the field `metadata.name` of Service `mysql`.
### Substitution
Confirm the variable substitution:
<!-- @kustomizeBuild @test -->
```
kustomize build $DEMO_HOME
```
Expect this in the output:
> ```
> (truncated)
> ...
> initContainers:
> - command:
> - echo demo-wordpress
> - echo demo-mysql
> image: debian
> name: init-command
>
> ```

View File

@@ -0,0 +1,19 @@
bases:
- wordpress
- mysql
patchesStrategicMerge:
- patch.yaml
namePrefix: demo-
vars:
- name: WORDPRESS_SERVICE
objref:
kind: Service
name: wordpress
apiVersion: v1
- name: MYSQL_SERVICE
objref:
kind: Service
name: mysql
apiVersion: v1

View File

@@ -0,0 +1,35 @@
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
emptyDir: {}

View File

@@ -0,0 +1,4 @@
resources:
- deployment.yaml
- service.yaml
- secret.yaml

View File

@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: mysql-pass
type: Opaque
data:
# Default password is "admin".
password: YWRtaW4=

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql

View File

@@ -0,0 +1,23 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: wordpress
spec:
template:
spec:
initContainers:
- name: init-command
image: debian
command:
- "echo $(WORDPRESS_SERVICE)"
- "echo $(MYSQL_SERVICE)"
containers:
- name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: $(MYSQL_SERVICE)
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password

View File

@@ -0,0 +1,29 @@
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
emptyDir: {}

View File

@@ -0,0 +1,3 @@
resources:
- deployment.yaml
- service.yaml

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
type: LoadBalancer

View File

@@ -21,7 +21,7 @@ import (
"github.com/golang/glog"
"github.com/kubernetes-sigs/kustomize/pkg/commands"
"sigs.k8s.io/kustomize/pkg/commands"
)
func main() {

View File

@@ -14,45 +14,46 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package app implements state for the set of all resources being customized.
// Should rename this - there's nothing "app"y about it.
package app
import (
"bytes"
"encoding/json"
"fmt"
"github.com/ghodss/yaml"
"github.com/golang/glog"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
interror "github.com/kubernetes-sigs/kustomize/pkg/internal/error"
"github.com/kubernetes-sigs/kustomize/pkg/loader"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/transformers"
"github.com/kubernetes-sigs/kustomize/pkg/types"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/pkg/configmapandsecret"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/crds"
"sigs.k8s.io/kustomize/pkg/fs"
interror "sigs.k8s.io/kustomize/pkg/internal/error"
"sigs.k8s.io/kustomize/pkg/loader"
"sigs.k8s.io/kustomize/pkg/patch"
patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
"sigs.k8s.io/kustomize/pkg/transformers"
"sigs.k8s.io/kustomize/pkg/types"
)
type Application interface {
// Resources computes and returns the resources for the app.
Resources() (resource.ResourceCollection, error)
// SemiResources computes and returns the resources without name hash and name reference for the app
SemiResources() (resource.ResourceCollection, error)
// RawResources computes and returns the raw resources from the kustomization file.
// It contains resources from
// 1) untransformed resources from current kustomization file
// 2) transformed resources from sub packages
RawResources() (resource.ResourceCollection, error)
}
var _ Application = &applicationImpl{}
// Private implementation of the Application interface
type applicationImpl struct {
// Application implements the guts of the kustomize 'build' command.
// TODO: Change name, as "application" is overloaded and somewhat
// misleading (one can customize an RBAC policy). Perhaps "Target"
// https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#target
type Application struct {
kustomization *types.Kustomization
loader loader.Loader
ldr loader.Loader
fSys fs.FileSystem
}
// NewApp parses the kustomization file at the path using the loader.
func New(loader loader.Loader) (Application, error) {
content, err := loader.Load(constants.KustomizationFileName)
// NewApplication returns a new instance of Application primed with a Loader.
func NewApplication(ldr loader.Loader, fSys fs.FileSystem) (*Application, error) {
content, err := ldr.Load(constants.KustomizationFileName)
if err != nil {
return nil, err
}
@@ -62,186 +63,7 @@ func New(loader loader.Loader) (Application, error) {
if err != nil {
return nil, err
}
return &applicationImpl{kustomization: &m, loader: loader}, nil
}
// Resources computes and returns the resources from the kustomization file.
// The namehashing for configmap/secrets and resolving name reference is only done
// in the most top overlay once at the end of getting resources.
func (a *applicationImpl) Resources() (resource.ResourceCollection, error) {
res, err := a.SemiResources()
if err != nil {
return nil, err
}
t, err := a.getHashAndReferenceTransformer()
if err != nil {
return nil, err
}
err = t.Transform(res)
if err != nil {
return nil, err
}
return res, nil
}
// SemiResources computes and returns the resources without name hash and name reference for the app
func (a *applicationImpl) SemiResources() (resource.ResourceCollection, error) {
errs := &interror.KustomizationErrors{}
raw, err := a.rawResources()
if err != nil {
errs.Append(err)
}
cms, err := resource.NewFromConfigMaps(a.loader, a.kustomization.ConfigMapGenerator)
if err != nil {
errs.Append(err)
}
secrets, err := resource.NewFromSecretGenerators(a.loader.Root(), a.kustomization.SecretGenerator)
if err != nil {
errs.Append(err)
}
res, err := resource.Merge(cms, secrets)
if err != nil {
return nil, err
}
allRes, err := resource.MergeWithOverride(raw, res)
if err != nil {
return nil, err
}
patches, err := resource.NewFromPatches(a.loader, a.kustomization.Patches)
if err != nil {
errs.Append(err)
}
if len(errs.Get()) > 0 {
return nil, errs
}
t, err := a.getTransformer(patches)
if err != nil {
return nil, err
}
err = t.Transform(allRes)
if err != nil {
return nil, err
}
return allRes, nil
}
// RawResources computes and returns the raw resources from the kustomization file.
// The namehashing for configmap/secrets and resolving name reference is only done
// in the most top overlay once at the end of getting resources.
func (a *applicationImpl) RawResources() (resource.ResourceCollection, error) {
res, err := a.rawResources()
if err != nil {
return nil, err
}
t, err := a.getHashAndReferenceTransformer()
if err != nil {
return nil, err
}
err = t.Transform(res)
if err != nil {
return nil, err
}
return res, nil
}
func (a *applicationImpl) rawResources() (resource.ResourceCollection, error) {
subAppResources, errs := a.subAppResources()
resources, err := resource.NewFromResources(a.loader, a.kustomization.Resources)
if err != nil {
errs.Append(err)
}
if len(errs.Get()) > 0 {
return nil, errs
}
return resource.Merge(resources, subAppResources)
}
func (a *applicationImpl) subAppResources() (resource.ResourceCollection, *interror.KustomizationErrors) {
sliceOfSubAppResources := []resource.ResourceCollection{}
errs := &interror.KustomizationErrors{}
for _, pkgPath := range a.kustomization.Bases {
subloader, err := a.loader.New(pkgPath)
if err != nil {
errs.Append(err)
continue
}
subapp, err := New(subloader)
if err != nil {
errs.Append(err)
continue
}
// Gather all transformed resources from subpackages.
subAppResources, err := subapp.SemiResources()
if err != nil {
errs.Append(err)
continue
}
sliceOfSubAppResources = append(sliceOfSubAppResources, subAppResources)
}
allResources, err := resource.Merge(sliceOfSubAppResources...)
if err != nil {
errs.Append(err)
}
return allResources, errs
}
// getTransformer generates the following transformers:
// 1) apply overlay
// 2) name prefix
// 3) apply labels
// 4) apply annotations
func (a *applicationImpl) getTransformer(patches []*resource.Resource) (transformers.Transformer, error) {
ts := []transformers.Transformer{}
ot, err := transformers.NewOverlayTransformer(patches)
if err != nil {
return nil, err
}
ts = append(ts, ot)
npt, err := transformers.NewDefaultingNamePrefixTransformer(string(a.kustomization.NamePrefix))
if err != nil {
return nil, err
}
ts = append(ts, npt)
lt, err := transformers.NewDefaultingLabelsMapTransformer(a.kustomization.CommonLabels)
if err != nil {
return nil, err
}
ts = append(ts, lt)
at, err := transformers.NewDefaultingAnnotationsMapTransformer(a.kustomization.CommonAnnotations)
if err != nil {
return nil, err
}
ts = append(ts, at)
return transformers.NewMultiTransformer(ts), nil
}
// getHashAndReferenceTransformer generates the following transformers:
// 1) name hash for configmap and secrests
// 2) apply name reference
func (a *applicationImpl) getHashAndReferenceTransformer() (transformers.Transformer, error) {
ts := []transformers.Transformer{}
nht := transformers.NewNameHashTransformer()
ts = append(ts, nht)
nrt, err := transformers.NewDefaultingNameReferenceTransformer()
if err != nil {
return nil, err
}
ts = append(ts, nrt)
return transformers.NewMultiTransformer(ts), nil
return &Application{kustomization: &m, ldr: ldr, fSys: fSys}, nil
}
func unmarshal(y []byte, o interface{}) error {
@@ -254,3 +76,255 @@ func unmarshal(y []byte, o interface{}) error {
dec.DisallowUnknownFields()
return dec.Decode(o)
}
// MakeCustomizedResMap creates a ResMap per kustomization instructions.
// The Resources in the returned ResMap are fully customized.
func (a *Application) MakeCustomizedResMap() (resmap.ResMap, error) {
m, err := a.loadCustomizedResMap()
if err != nil {
return nil, err
}
return a.resolveRefsToGeneratedResources(m)
}
// resolveRefsToGeneratedResources fixes all name references.
func (a *Application) resolveRefsToGeneratedResources(m resmap.ResMap) (resmap.ResMap, error) {
err := transformers.NewNameHashTransformer().Transform(m)
if err != nil {
return nil, err
}
var r []transformers.Transformer
t, err := transformers.NewDefaultingNameReferenceTransformer()
if err != nil {
return nil, err
}
r = append(r, t)
refVars, err := a.resolveRefVars(m)
if err != nil {
return nil, err
}
t, err = transformers.NewRefVarTransformer(refVars)
if err != nil {
return nil, err
}
r = append(r, t)
err = transformers.NewMultiTransformer(r).Transform(m)
if err != nil {
return nil, err
}
return m, nil
}
// loadCustomizedResMap loads and customizes resources to build a ResMap.
func (a *Application) loadCustomizedResMap() (resmap.ResMap, error) {
errs := &interror.KustomizationErrors{}
result, err := a.loadResMapFromBasesAndResources()
if err != nil {
errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources"))
}
err = crds.RegisterCRDs(a.ldr, a.kustomization.Crds)
if err != nil {
errs.Append(errors.Wrap(err, "RegisterCRDs"))
}
cms, err := resmap.NewResMapFromConfigMapArgs(
configmapandsecret.NewConfigMapFactory(a.fSys, a.ldr),
a.kustomization.ConfigMapGenerator)
if err != nil {
errs.Append(errors.Wrap(err, "NewResMapFromConfigMapArgs"))
}
secrets, err := resmap.NewResMapFromSecretArgs(
configmapandsecret.NewSecretFactory(a.fSys, a.ldr.Root()),
a.kustomization.SecretGenerator)
if err != nil {
errs.Append(errors.Wrap(err, "NewResMapFromSecretArgs"))
}
res, err := resmap.MergeWithoutOverride(cms, secrets)
if err != nil {
return nil, errors.Wrap(err, "Merge")
}
result, err = resmap.MergeWithOverride(result, res)
if err != nil {
return nil, err
}
a.kustomization.PatchesStrategicMerge = patch.Append(a.kustomization.PatchesStrategicMerge, a.kustomization.Patches...)
patches, err := resmap.NewResourceSliceFromPatches(a.ldr, a.kustomization.PatchesStrategicMerge)
if err != nil {
errs.Append(errors.Wrap(err, "NewResourceSliceFromPatches"))
}
if len(errs.Get()) > 0 {
return nil, errs
}
var r []transformers.Transformer
t, err := a.newTransformer(patches)
if err != nil {
return nil, err
}
r = append(r, t)
t, err = patchtransformer.NewPatchJson6902Factory(a.ldr).MakePatchJson6902Transformer(a.kustomization.PatchesJson6902)
if err != nil {
return nil, err
}
r = append(r, t)
t, err = transformers.NewImageTagTransformer(a.kustomization.ImageTags)
if err != nil {
return nil, err
}
r = append(r, t)
err = transformers.NewMultiTransformer(r).Transform(result)
if err != nil {
return nil, err
}
return result, nil
}
// Gets Bases and Resources as advertised.
func (a *Application) loadResMapFromBasesAndResources() (resmap.ResMap, error) {
bases, errs := a.loadCustomizedBases()
resources, err := resmap.NewResMapFromFiles(a.ldr, a.kustomization.Resources)
if err != nil {
errs.Append(errors.Wrap(err, "rawResources failed to read Resources"))
}
if len(errs.Get()) > 0 {
return nil, errs
}
return resmap.MergeWithoutOverride(resources, bases)
}
// Loop through the Bases of this kustomization recursively loading resources.
// Combine into one ResMap, demanding unique Ids for each resource.
func (a *Application) loadCustomizedBases() (resmap.ResMap, *interror.KustomizationErrors) {
var list []resmap.ResMap
errs := &interror.KustomizationErrors{}
for _, path := range a.kustomization.Bases {
ldr, err := a.ldr.New(path)
if err != nil {
errs.Append(errors.Wrap(err, "couldn't make ldr for "+path))
continue
}
app, err := NewApplication(ldr, a.fSys)
if err != nil {
errs.Append(errors.Wrap(err, "couldn't make app for "+path))
continue
}
resMap, err := app.loadCustomizedResMap()
if err != nil {
errs.Append(errors.Wrap(err, "SemiResources"))
continue
}
ldr.Cleanup()
list = append(list, resMap)
}
result, err := resmap.MergeWithoutOverride(list...)
if err != nil {
errs.Append(errors.Wrap(err, "Merge failed"))
}
return result, errs
}
func (a *Application) loadBasesAsFlatList() ([]*Application, error) {
var result []*Application
errs := &interror.KustomizationErrors{}
for _, path := range a.kustomization.Bases {
ldr, err := a.ldr.New(path)
if err != nil {
errs.Append(err)
continue
}
a, err := NewApplication(ldr, a.fSys)
if err != nil {
errs.Append(err)
continue
}
result = append(result, a)
}
if len(errs.Get()) > 0 {
return nil, errs
}
return result, nil
}
// newTransformer makes a Transformer that does everything except resolve generated names.
func (a *Application) newTransformer(patches []*resource.Resource) (transformers.Transformer, error) {
var r []transformers.Transformer
t, err := transformers.NewPatchTransformer(patches)
if err != nil {
return nil, err
}
r = append(r, t)
r = append(r, transformers.NewNamespaceTransformer(string(a.kustomization.Namespace)))
t, err = transformers.NewDefaultingNamePrefixTransformer(string(a.kustomization.NamePrefix))
if err != nil {
return nil, err
}
r = append(r, t)
t, err = transformers.NewDefaultingLabelsMapTransformer(a.kustomization.CommonLabels)
if err != nil {
return nil, err
}
r = append(r, t)
t, err = transformers.NewDefaultingAnnotationsMapTransformer(a.kustomization.CommonAnnotations)
if err != nil {
return nil, err
}
r = append(r, t)
return transformers.NewMultiTransformer(r), nil
}
func (a *Application) resolveRefVars(m resmap.ResMap) (map[string]string, error) {
result := map[string]string{}
vars, err := a.getAllVars()
if err != nil {
return result, err
}
for _, v := range vars {
id := resource.NewResId(v.ObjRef.GroupVersionKind(), v.ObjRef.Name)
if r, found := m.DemandOneMatchForId(id); found {
s, err := r.GetFieldValue(v.FieldRef.FieldPath)
if err != nil {
return nil, fmt.Errorf("failed to resolve referred var: %+v", v)
}
result[v.Name] = s
} else {
glog.Infof("couldn't resolve v: %v", v)
}
}
return result, nil
}
// getAllVars returns all the "environment" style Var instances defined in the app.
func (a *Application) getAllVars() ([]types.Var, error) {
var result []types.Var
errs := &interror.KustomizationErrors{}
bases, err := a.loadBasesAsFlatList()
if err != nil {
return nil, err
}
// TODO: computing vars and resources for bases can be combined
for _, b := range bases {
vars, err := b.getAllVars()
if err != nil {
errs.Append(err)
continue
}
b.ldr.Cleanup()
result = append(result, vars...)
}
for _, v := range a.kustomization.Vars {
v.Defaulting()
result = append(result, v)
}
if len(errs.Get()) > 0 {
return nil, errs
}
return result, nil
}

View File

@@ -18,29 +18,31 @@ package app
import (
"encoding/base64"
"fmt"
"reflect"
"strings"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/loader"
"github.com/kubernetes-sigs/kustomize/pkg/loader/loadertest"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/types"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
"sigs.k8s.io/kustomize/pkg/loader"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
)
func setupTest(t *testing.T) loader.Loader {
kustomizationContent := []byte(`
const (
kustomizationContent1 = `
namePrefix: foo-
namespace: ns1
commonLabels:
app: nginx
commonAnnotations:
note: This is a test annotation
resources:
- deployment.yaml
- namespace.yaml
configMapGenerator:
- name: literalConfigMap
literals:
@@ -52,184 +54,210 @@ secretGenerator:
DB_USERNAME: "printf admin"
DB_PASSWORD: "printf somepw"
type: Opaque
`)
deploymentContent := []byte(`apiVersion: apps/v1
kind: Deployment
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: dply1
path: jsonpatch.json
`
kustomizationContent2 = `
secretGenerator:
- name: secret
timeoutSeconds: 1
commands:
USER: "sleep 2"
type: Opaque
`
deploymentContent = `apiVersion: apps/v1
metadata:
name: dply1
`)
kind: Deployment
`
namespaceContent = `apiVersion: v1
kind: Namespace
metadata:
name: ns1
`
jsonpatchContent = `[
{"op": "add", "path": "/spec/replica", "value": "3"}
]`
)
loader := loadertest.NewFakeLoader("/testpath")
err := loader.AddFile("/testpath/"+constants.KustomizationFileName, kustomizationContent)
func makeLoader1(t *testing.T) loader.Loader {
ldr := loadertest.NewFakeLoader("/testpath")
err := ldr.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1))
if err != nil {
t.Fatalf("Failed to setup fake loader.")
t.Fatalf("Failed to setup fake ldr.")
}
err = loader.AddFile("/testpath/deployment.yaml", deploymentContent)
err = ldr.AddFile("/testpath/deployment.yaml", []byte(deploymentContent))
if err != nil {
t.Fatalf("Failed to setup fake loader.")
t.Fatalf("Failed to setup fake ldr.")
}
return loader
err = ldr.AddFile("/testpath/namespace.yaml", []byte(namespaceContent))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
err = ldr.AddFile("/testpath/jsonpatch.json", []byte(jsonpatchContent))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
return ldr
}
func TestResources(t *testing.T) {
expected := resource.ResourceCollection{
types.GroupVersionKindName{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "dply1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "foo-dply1",
"labels": map[string]interface{}{
var deploy = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"}
var cmap = schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}
var secret = schema.GroupVersionKind{Version: "v1", Kind: "Secret"}
var ns = schema.GroupVersionKind{Version: "v1", Kind: "Namespace"}
func TestResources1(t *testing.T) {
expected := resmap.ResMap{
resource.NewResIdWithPrefixNamespace(deploy, "dply1", "foo-", "ns1"): resource.NewResourceFromMap(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "foo-dply1",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
},
"spec": map[string]interface{}{
"replica": "3",
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
},
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"labels": map[string]interface{}{
"app": "nginx",
},
},
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"labels": map[string]interface{}{
"app": "nginx",
},
},
},
},
},
},
},
types.GroupVersionKindName{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "literalConfigMap",
}: &resource.Resource{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "foo-literalConfigMap-mc92bgcbh5",
"labels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"creationTimestamp": nil,
}),
resource.NewResIdWithPrefixNamespace(cmap, "literalConfigMap", "foo-", "ns1"): resource.NewResourceFromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "foo-literalConfigMap-mc92bgcbh5",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
},
"data": map[string]interface{}{
"DB_USERNAME": "admin",
"DB_PASSWORD": "somepw",
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"creationTimestamp": nil,
},
"data": map[string]interface{}{
"DB_USERNAME": "admin",
"DB_PASSWORD": "somepw",
},
}).SetBehavior(resource.BehaviorCreate),
resource.NewResIdWithPrefixNamespace(secret, "secret", "foo-", "ns1"): resource.NewResourceFromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
"metadata": map[string]interface{}{
"name": "foo-secret-877fcfhgt5",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"creationTimestamp": nil,
},
"type": string(corev1.SecretTypeOpaque),
"data": map[string]interface{}{
"DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")),
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
},
}).SetBehavior(resource.BehaviorCreate),
resource.NewResIdWithPrefixNamespace(ns, "ns1", "foo-", ""): resource.NewResourceFromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": map[string]interface{}{
"name": "foo-ns1",
"labels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
},
},
},
types.GroupVersionKindName{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Secret"},
Name: "secret",
}: &resource.Resource{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
"metadata": map[string]interface{}{
"name": "foo-secret-877fcfhgt5",
"labels": map[string]interface{}{
"app": "nginx",
},
"annotations": map[string]interface{}{
"note": "This is a test annotation",
},
"creationTimestamp": nil,
},
"type": string(corev1.SecretTypeOpaque),
"data": map[string]interface{}{
"DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")),
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
},
},
},
},
}),
}
l := setupTest(t)
app, err := New(l)
l := makeLoader1(t)
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
app, err := NewApplication(l, fakeFs)
if err != nil {
t.Fatalf("Unexpected error %v", err)
t.Fatalf("Unexpected construction error %v", err)
}
actual, err := app.Resources()
actual, err := app.MakeCustomizedResMap()
if err != nil {
t.Fatalf("Unexpected error %v", err)
t.Fatalf("Unexpected Resources error %v", err)
}
if !reflect.DeepEqual(actual, expected) {
err = compareMap(actual, expected)
t.Fatalf("unexpected error: %v", err)
err = expected.ErrorIfNotEqual(actual)
t.Fatalf("unexpected inequality: %v", err)
}
}
func TestRawResources(t *testing.T) {
expected := resource.ResourceCollection{
types.GroupVersionKindName{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "dply1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "dply1",
},
},
},
},
}
l := setupTest(t)
app, err := New(l)
func TestResourceNotFound(t *testing.T) {
l := loadertest.NewFakeLoader("/testpath")
err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1))
if err != nil {
t.Fatalf("Unexpected error %v", err)
t.Fatalf("Failed to setup fake ldr.")
}
actual, err := app.RawResources()
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
app, err := NewApplication(l, fakeFs)
if err != nil {
t.Fatalf("Unexpected error %v", err)
t.Fatalf("Unexpected construction error %v", err)
}
if err := compareMap(actual, expected); err != nil {
t.Fatalf("unexpected error: %v", err)
_, err = app.MakeCustomizedResMap()
if err == nil {
t.Fatalf("Didn't get the expected error for an unknown resource")
}
if !strings.Contains(err.Error(), `cannot read file "/testpath/deployment.yaml"`) {
t.Fatalf("Unpexpected error message %q", err)
}
}
func compareMap(m1, m2 resource.ResourceCollection) error {
if len(m1) != len(m2) {
keySet1 := []types.GroupVersionKindName{}
keySet2 := []types.GroupVersionKindName{}
for GVKn := range m1 {
keySet1 = append(keySet1, GVKn)
}
for GVKn := range m1 {
keySet2 = append(keySet2, GVKn)
}
return fmt.Errorf("maps has different number of entries: %#v doesn't equals %#v", keySet1, keySet2)
func TestSecretTimeout(t *testing.T) {
l := loadertest.NewFakeLoader("/testpath")
err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent2))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
for GVKn, obj1 := range m1 {
obj2, found := m2[GVKn]
if !found {
return fmt.Errorf("%#v doesn't exist in %#v", GVKn, m2)
}
if !reflect.DeepEqual(obj1, obj2) {
return fmt.Errorf("%#v doesn't match %#v", obj1, obj2)
}
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
app, err := NewApplication(l, fakeFs)
if err != nil {
t.Fatalf("Unexpected construction error %v", err)
}
_, err = app.MakeCustomizedResMap()
if err == nil {
t.Fatalf("Didn't get the expected error for an unknown resource")
}
if !strings.Contains(err.Error(), "killed") {
t.Fatalf("Unpexpected error message %q", err)
}
return nil
}

98
pkg/commands/addbase.go Normal file
View File

@@ -0,0 +1,98 @@
/*
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.
*/
package commands
import (
"errors"
"fmt"
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
type addBaseOptions struct {
baseDirectoryPaths string
}
// newCmdAddBase adds the file path of the kustomize base to the kustomization file.
func newCmdAddBase(fsys fs.FileSystem) *cobra.Command {
var o addBaseOptions
cmd := &cobra.Command{
Use: "base",
Short: "Adds one or more bases to the kustomization.yaml in current directory",
Example: `
add base {filepath1},{filepath2}`,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
if err != nil {
return err
}
err = o.Complete(cmd, args)
if err != nil {
return err
}
return o.RunAddBase(fsys)
},
}
return cmd
}
// Validate validates addBase command.
func (o *addBaseOptions) Validate(args []string) error {
if len(args) != 1 {
return errors.New("must specify a base directory")
}
o.baseDirectoryPaths = args[0]
return nil
}
// Complete completes addBase command.
func (o *addBaseOptions) Complete(cmd *cobra.Command, args []string) error {
return nil
}
// RunAddBase runs addBase command (do real work).
func (o *addBaseOptions) RunAddBase(fsys fs.FileSystem) error {
mf, err := newKustomizationFile(constants.KustomizationFileName, fsys)
if err != nil {
return err
}
m, err := mf.read()
if err != nil {
return err
}
// split directory paths
paths := strings.Split(o.baseDirectoryPaths, ",")
for _, path := range paths {
if !fsys.Exists(path) {
return errors.New(path + " does not exist")
}
if stringInSlice(path, m.Bases) {
return fmt.Errorf("base %s already in kustomization file", path)
}
m.Bases = append(m.Bases, path)
}
return mf.write(m)
}

View File

@@ -0,0 +1,100 @@
/*
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.
*/
package commands
import (
"testing"
"strings"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
const (
baseDirectoryPaths = "my/path/to/wonderful/base,other/path/to/even/more/wonderful/base"
)
func TestAddBaseHappyPath(t *testing.T) {
fakeFS := fs.MakeFakeFS()
bases := strings.Split(baseDirectoryPaths, ",")
for _, base := range bases {
fakeFS.Mkdir(base)
}
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddBase(fakeFS)
args := []string{baseDirectoryPaths}
err := cmd.RunE(cmd, args)
if err != nil {
t.Errorf("unexpected cmd error: %v", err)
}
content, err := fakeFS.ReadFile(constants.KustomizationFileName)
if err != nil {
t.Errorf("unexpected read error: %v", err)
}
for _, base := range bases {
if !strings.Contains(string(content), base) {
t.Errorf("expected base name in kustomization")
}
}
}
func TestAddBaseAlreadyThere(t *testing.T) {
fakeFS := fs.MakeFakeFS()
// Create fake directories
bases := strings.Split(baseDirectoryPaths, ",")
for _, base := range bases {
fakeFS.Mkdir(base)
}
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddBase(fakeFS)
args := []string{baseDirectoryPaths}
err := cmd.RunE(cmd, args)
if err != nil {
t.Fatalf("unexpected cmd error: %v", err)
}
// adding an existing base should return an error
err = cmd.RunE(cmd, args)
if err == nil {
t.Errorf("expected already there problem")
}
var expectedErrors []string
for _, base := range bases {
msg := "base " + base + " already in kustomization file"
expectedErrors = append(expectedErrors, msg)
if !stringInSlice(msg, expectedErrors) {
t.Errorf("unexpected error %v", err)
}
}
}
func TestAddBaseNoArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
cmd := newCmdAddBase(fakeFS)
err := cmd.Execute()
if err == nil {
t.Errorf("expected error: %v", err)
}
if err.Error() != "must specify a base directory" {
t.Errorf("incorrect error: %v", err.Error())
}
}

175
pkg/commands/addmetadata.go Normal file
View File

@@ -0,0 +1,175 @@
/*
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.
*/
package commands
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/types"
"sigs.k8s.io/kustomize/pkg/validators"
)
// kindOfAdd is the kind of metadata being added: label or annotation
type kindOfAdd int
const (
annotation kindOfAdd = iota
label
)
func (k kindOfAdd) String() string {
kinds := [...]string{
"annotation",
"label",
}
if k < 0 || k > 1 {
return "Unknown metadatakind"
}
return kinds[k]
}
type addMetadataOptions struct {
metadata map[string]string
mapValidator validators.MapValidatorFunc
kind kindOfAdd
}
// newCmdAddAnnotation adds one or more commonAnnotations to the kustomization file.
func newCmdAddAnnotation(fSys fs.FileSystem, v validators.MapValidatorFunc) *cobra.Command {
var o addMetadataOptions
o.kind = annotation
o.mapValidator = v
cmd := &cobra.Command{
Use: "annotation",
Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileName,
Example: `
add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`,
RunE: func(cmd *cobra.Command, args []string) error {
return o.runE(args, fSys, o.addAnnotations)
},
}
return cmd
}
// newCmdAddLabel adds one or more commonLabels to the kustomization file.
func newCmdAddLabel(fSys fs.FileSystem, v validators.MapValidatorFunc) *cobra.Command {
var o addMetadataOptions
o.kind = label
o.mapValidator = v
cmd := &cobra.Command{
Use: "label",
Short: "Adds one or more commonLabels to " + constants.KustomizationFileName,
Example: `
add label {labelKey1:labelValue1},{labelKey2:labelValue2}`,
RunE: func(cmd *cobra.Command, args []string) error {
return o.runE(args, fSys, o.addLabels)
},
}
return cmd
}
func (o *addMetadataOptions) runE(
args []string, fSys fs.FileSystem, adder func(*types.Kustomization) error) error {
err := o.validateAndParse(args)
if err != nil {
return err
}
kf, err := newKustomizationFile(constants.KustomizationFileName, fSys)
if err != nil {
return err
}
m, err := kf.read()
if err != nil {
return err
}
err = adder(m)
if err != nil {
return err
}
return kf.write(m)
}
// validateAndParse validates `add` commands and parses them into o.metadata
func (o *addMetadataOptions) validateAndParse(args []string) error {
if len(args) < 1 {
return fmt.Errorf("must specify %s", o.kind)
}
if len(args) > 1 {
return fmt.Errorf("%ss must be comma-separated, with no spaces", o.kind)
}
m, err := o.convertToMap(args[0])
if err != nil {
return err
}
if err = o.mapValidator(m); err != nil {
return err
}
o.metadata = m
return nil
}
func (o *addMetadataOptions) convertToMap(arg string) (map[string]string, error) {
result := make(map[string]string)
inputs := strings.Split(arg, ",")
for _, input := range inputs {
kv := strings.Split(input, ":")
if len(kv[0]) < 1 {
return nil, o.makeError(input, "empty key")
}
if len(kv) > 2 {
return nil, o.makeError(input, "too many colons")
}
if len(kv) > 1 {
result[kv[0]] = kv[1]
} else {
result[kv[0]] = ""
}
}
return result, nil
}
func (o *addMetadataOptions) addAnnotations(m *types.Kustomization) error {
if m.CommonAnnotations == nil {
m.CommonAnnotations = make(map[string]string)
}
return o.writeToMap(m.CommonAnnotations, annotation)
}
func (o *addMetadataOptions) addLabels(m *types.Kustomization) error {
if m.CommonLabels == nil {
m.CommonLabels = make(map[string]string)
}
return o.writeToMap(m.CommonLabels, label)
}
func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) error {
for k, v := range o.metadata {
if _, ok := m[k]; ok {
return fmt.Errorf("%s %s already in kustomization file", kind, k)
}
m[k] = v
}
return nil
}
func (o *addMetadataOptions) makeError(input string, message string) error {
return fmt.Errorf("invalid %s: %s (%s)", o.kind, input, message)
}

View File

@@ -0,0 +1,273 @@
/*
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.
*/
package commands
import (
"testing"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/types"
"sigs.k8s.io/kustomize/pkg/validators"
)
func makeKustomization(t *testing.T) *types.Kustomization {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
kf, err := newKustomizationFile(constants.KustomizationFileName, fakeFS)
if err != nil {
t.Errorf("unexpected new error %v", err)
}
m, err := kf.read()
if err != nil {
t.Errorf("unexpected read error %v", err)
}
return m
}
func TestRunAddAnnotation(t *testing.T) {
var o addMetadataOptions
o.metadata = map[string]string{"owls": "cute", "otters": "adorable"}
m := makeKustomization(t)
err := o.addAnnotations(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
// adding the same test input should not work
err = o.addAnnotations(m)
if err == nil {
t.Errorf("expected already in kustomization file error")
}
// adding new annotations should work
o.metadata = map[string]string{"new": "annotation"}
err = o.addAnnotations(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
}
func TestAddAnnotationNoArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
err := cmd.Execute()
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "must specify annotation" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddAnnotationInvalidFormat(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeSadMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{"whatever:whatever"}
err := cmd.RunE(cmd, args)
v.VerifyCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != validators.SAD {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddAnnotationManyArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{"k1:v1,k2:v2,k3:v3,k4:v5"}
err := cmd.RunE(cmd, args)
v.VerifyCall()
if err != nil {
t.Errorf("unexpected error: %v", err.Error())
}
}
func TestAddAnnotationNoKey(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{":nokey"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "invalid annotation: :nokey (empty key)" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddAnnotationTooManyColons(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{"key:v1:v2"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "invalid annotation: key:v1:v2 (too many colons)" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddAnnotationNoValue(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{"no:,value"}
err := cmd.RunE(cmd, args)
v.VerifyCall()
if err != nil {
t.Errorf("unexpected error: %v", err.Error())
}
}
func TestAddAnnotationMultipleArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddAnnotation(fakeFS, v.Validator)
args := []string{"this:annotation", "has:spaces"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "annotations must be comma-separated, with no spaces" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestRunAddLabel(t *testing.T) {
var o addMetadataOptions
o.metadata = map[string]string{"owls": "cute", "otters": "adorable"}
m := makeKustomization(t)
err := o.addLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
// adding the same test input should not work
err = o.addLabels(m)
if err == nil {
t.Errorf("expected already in kustomization file error")
}
// adding new labels should work
o.metadata = map[string]string{"new": "label"}
err = o.addLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
}
func TestAddLabelNoArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
err := cmd.Execute()
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "must specify label" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddLabelInvalidFormat(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeSadMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
args := []string{"exclamation!:point"}
err := cmd.RunE(cmd, args)
v.VerifyCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != validators.SAD {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddLabelNoKey(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
args := []string{":nokey"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "invalid label: :nokey (empty key)" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddLabelTooManyColons(t *testing.T) {
fakeFS := fs.MakeFakeFS()
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
args := []string{"key:v1:v2"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "invalid label: key:v1:v2 (too many colons)" {
t.Errorf("incorrect error: %v", err.Error())
}
}
func TestAddLabelNoValue(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
args := []string{"no,value:"}
err := cmd.RunE(cmd, args)
v.VerifyCall()
if err != nil {
t.Errorf("unexpected error: %v", err.Error())
}
}
func TestAddLabelMultipleArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
v := validators.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fakeFS, v.Validator)
args := []string{"this:input", "has:spaces"}
err := cmd.RunE(cmd, args)
v.VerifyNoCall()
if err == nil {
t.Errorf("expected an error")
}
if err.Error() != "labels must be comma-separated, with no spaces" {
t.Errorf("incorrect error: %v", err.Error())
}
}

View File

@@ -18,21 +18,21 @@ package commands
import (
"errors"
"fmt"
"io"
"log"
"github.com/spf13/cobra"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/patch"
)
type addPatchOptions struct {
patchFilePath string
patchFilePaths []string
}
// newCmdAddPatch adds the name of a file containing a patch to the kustomization file.
func newCmdAddPatch(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
func newCmdAddPatch(fsys fs.FileSystem) *cobra.Command {
var o addPatchOptions
cmd := &cobra.Command{
@@ -49,7 +49,7 @@ func newCmdAddPatch(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
if err != nil {
return err
}
return o.RunAddPatch(out, errOut, fsys)
return o.RunAddPatch(fsys)
},
}
return cmd
@@ -57,10 +57,10 @@ func newCmdAddPatch(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
// Validate validates addPatch command.
func (o *addPatchOptions) Validate(args []string) error {
if len(args) != 1 {
if len(args) == 0 {
return errors.New("must specify a patch file")
}
o.patchFilePath = args[0]
o.patchFilePaths = args
return nil
}
@@ -70,11 +70,14 @@ func (o *addPatchOptions) Complete(cmd *cobra.Command, args []string) error {
}
// RunAddPatch runs addPatch command (do real work).
func (o *addPatchOptions) RunAddPatch(out, errOut io.Writer, fsys fs.FileSystem) error {
_, err := fsys.Stat(o.patchFilePath)
func (o *addPatchOptions) RunAddPatch(fsys fs.FileSystem) error {
patches, err := globPatterns(fsys, o.patchFilePaths)
if err != nil {
return err
}
if len(patches) == 0 {
return nil
}
mf, err := newKustomizationFile(constants.KustomizationFileName, fsys)
if err != nil {
@@ -86,11 +89,13 @@ func (o *addPatchOptions) RunAddPatch(out, errOut io.Writer, fsys fs.FileSystem)
return err
}
if stringInSlice(o.patchFilePath, m.Patches) {
return fmt.Errorf("patch %s already in kustomization file", o.patchFilePath)
for _, p := range patches {
if patch.Exist(m.PatchesStrategicMerge, p) || stringInSlice(p, m.Patches) {
log.Printf("patch %s already in kustomization file", p)
continue
}
m.PatchesStrategicMerge = patch.Append(m.PatchesStrategicMerge, p)
}
m.Patches = append(m.Patches, o.patchFilePath)
return mf.write(m)
}

View File

@@ -17,14 +17,12 @@ limitations under the License.
package commands
import (
"bytes"
"os"
"testing"
"strings"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
const (
@@ -36,13 +34,13 @@ sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
func TestAddPatchHappyPath(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(patchFileName, []byte(patchFileContent))
fakeFS.WriteFile(patchFileName+"another", []byte(patchFileContent))
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddPatch(buf, os.Stderr, fakeFS)
args := []string{patchFileName}
cmd := newCmdAddPatch(fakeFS)
args := []string{patchFileName + "*"}
err := cmd.RunE(cmd, args)
if err != nil {
t.Errorf("unexpected cmd error: %v", err)
@@ -54,36 +52,34 @@ func TestAddPatchHappyPath(t *testing.T) {
if !strings.Contains(string(content), patchFileName) {
t.Errorf("expected patch name in kustomization")
}
if !strings.Contains(string(content), patchFileName+"another") {
t.Errorf("expected patch name in kustomization")
}
}
func TestAddPatchAlreadyThere(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(patchFileName, []byte(patchFileContent))
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddPatch(buf, os.Stderr, fakeFS)
cmd := newCmdAddPatch(fakeFS)
args := []string{patchFileName}
err := cmd.RunE(cmd, args)
if err != nil {
t.Fatalf("unexpected cmd error: %v", err)
}
// adding an existing patch should return an error
// adding an existing patch shouldn't return an error
err = cmd.RunE(cmd, args)
if err == nil {
t.Errorf("expected already there problem")
}
if err.Error() != "patch "+patchFileName+" already in kustomization file" {
t.Errorf("unexpected error %v", err)
if err != nil {
t.Errorf("unexpected cmd error: %v", err)
}
}
func TestAddPatchNoArgs(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
cmd := newCmdAddPatch(buf, os.Stderr, fakeFS)
cmd := newCmdAddPatch(fakeFS)
err := cmd.Execute()
if err == nil {
t.Errorf("expected error: %v", err)

View File

@@ -18,21 +18,20 @@ package commands
import (
"errors"
"fmt"
"io"
"log"
"github.com/spf13/cobra"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
type addResourceOptions struct {
resourceFilePath string
resourceFilePaths []string
}
// newCmdAddResource adds the name of a file containing a resource to the kustomization file.
func newCmdAddResource(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
func newCmdAddResource(fsys fs.FileSystem) *cobra.Command {
var o addResourceOptions
cmd := &cobra.Command{
@@ -49,7 +48,7 @@ func newCmdAddResource(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command
if err != nil {
return err
}
return o.RunAddResource(out, errOut, fsys)
return o.RunAddResource(fsys)
},
}
return cmd
@@ -57,10 +56,10 @@ func newCmdAddResource(out, errOut io.Writer, fsys fs.FileSystem) *cobra.Command
// Validate validates addResource command.
func (o *addResourceOptions) Validate(args []string) error {
if len(args) != 1 {
if len(args) == 0 {
return errors.New("must specify a resource file")
}
o.resourceFilePath = args[0]
o.resourceFilePaths = args
return nil
}
@@ -70,11 +69,14 @@ func (o *addResourceOptions) Complete(cmd *cobra.Command, args []string) error {
}
// RunAddResource runs addResource command (do real work).
func (o *addResourceOptions) RunAddResource(out, errOut io.Writer, fsys fs.FileSystem) error {
_, err := fsys.Stat(o.resourceFilePath)
func (o *addResourceOptions) RunAddResource(fsys fs.FileSystem) error {
resources, err := globPatterns(fsys, o.resourceFilePaths)
if err != nil {
return err
}
if len(resources) == 0 {
return nil
}
mf, err := newKustomizationFile(constants.KustomizationFileName, fsys)
if err != nil {
@@ -86,11 +88,13 @@ func (o *addResourceOptions) RunAddResource(out, errOut io.Writer, fsys fs.FileS
return err
}
if stringInSlice(o.resourceFilePath, m.Resources) {
return fmt.Errorf("resource %s already in kustomization file", o.resourceFilePath)
for _, resource := range resources {
if stringInSlice(resource, m.Resources) {
log.Printf("resource %s already in kustomization file", resource)
continue
}
m.Resources = append(m.Resources, resource)
}
m.Resources = append(m.Resources, o.resourceFilePath)
return mf.write(m)
}

View File

@@ -17,14 +17,11 @@ limitations under the License.
package commands
import (
"bytes"
"os"
"strings"
"testing"
"strings"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
const (
@@ -52,13 +49,13 @@ secretGenerator: []
)
func TestAddResourceHappyPath(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(resourceFileName, []byte(resourceFileContent))
fakeFS.WriteFile(resourceFileName+"another", []byte(resourceFileContent))
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddResource(buf, os.Stderr, fakeFS)
args := []string{resourceFileName}
cmd := newCmdAddResource(fakeFS)
args := []string{resourceFileName + "*"}
err := cmd.RunE(cmd, args)
if err != nil {
t.Errorf("unexpected cmd error: %v", err)
@@ -70,36 +67,34 @@ func TestAddResourceHappyPath(t *testing.T) {
if !strings.Contains(string(content), resourceFileName) {
t.Errorf("expected resource name in kustomization")
}
if !strings.Contains(string(content), resourceFileName+"another") {
t.Errorf("expected resource name in kustomization")
}
}
func TestAddResourceAlreadyThere(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(resourceFileName, []byte(resourceFileContent))
fakeFS.WriteFile(constants.KustomizationFileName, []byte(kustomizationContent))
cmd := newCmdAddResource(buf, os.Stderr, fakeFS)
cmd := newCmdAddResource(fakeFS)
args := []string{resourceFileName}
err := cmd.RunE(cmd, args)
if err != nil {
t.Fatalf("unexpected cmd error: %v", err)
}
// adding an existing resource should return an error
// adding an existing resource doesn't return an error
err = cmd.RunE(cmd, args)
if err == nil {
t.Errorf("expected already there problem")
}
if err.Error() != "resource "+resourceFileName+" already in kustomization file" {
t.Errorf("unexpected error %v", err)
if err != nil {
t.Errorf("unexpected cmd error :%v", err)
}
}
func TestAddResourceNoArgs(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
fakeFS := fs.MakeFakeFS()
cmd := newCmdAddResource(buf, os.Stderr, fakeFS)
cmd := newCmdAddResource(fakeFS)
err := cmd.Execute()
if err == nil {
t.Errorf("expected error: %v", err)

View File

@@ -18,40 +18,58 @@ package commands
import (
"io"
"path/filepath"
"github.com/spf13/cobra"
"errors"
"github.com/kubernetes-sigs/kustomize/pkg/app"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/loader"
kutil "github.com/kubernetes-sigs/kustomize/pkg/util"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/app"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/loader"
)
type buildOptions struct {
kustomizationPath string
outputPath string
}
var examples = `
Use the file somedir/kustomization.yaml to generate a set of api resources:
build somedir
Use a url pointing to a remote directory/kustomization.yaml to generate a set of api resources:
build url
The url should follow hashicorp/go-getter URL format described in
https://github.com/hashicorp/go-getter#url-format
url examples:
sigs.k8s.io/kustomize//examples/multibases?ref=v1.0.6
github.com/Liujingfang1/mysql
github.com/Liujingfang1/kustomize//examples/helloWorld?ref=repoUrl2
`
// newCmdBuild creates a new build command.
func newCmdBuild(out, errOut io.Writer, fs fs.FileSystem) *cobra.Command {
func newCmdBuild(out io.Writer, fs fs.FileSystem) *cobra.Command {
var o buildOptions
cmd := &cobra.Command{
Use: "build [path]",
Short: "Print current configuration per contents of " + constants.KustomizationFileName,
Example: "Use the file somedir/" + constants.KustomizationFileName +
" to generate a set of api resources:\nbuild somedir/",
Use: "build [path]",
Short: "Print current configuration per contents of " + constants.KustomizationFileName,
Example: examples,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
if err != nil {
return err
}
return o.RunBuild(out, errOut, fs)
return o.RunBuild(out, fs)
},
}
cmd.Flags().StringVarP(
&o.outputPath,
"output", "o", "",
"If specified, write the build output to this path.")
return cmd
}
@@ -69,35 +87,33 @@ func (o *buildOptions) Validate(args []string) error {
}
// RunBuild runs build command.
func (o *buildOptions) RunBuild(out, errOut io.Writer, fs fs.FileSystem) error {
l := loader.Init([]loader.SchemeLoader{loader.NewFileLoader(fs)})
func (o *buildOptions) RunBuild(out io.Writer, fSys fs.FileSystem) error {
rootLoader, err := loader.NewLoader(o.kustomizationPath, "", fSys)
if err != nil {
return err
}
defer rootLoader.Cleanup()
absPath, err := filepath.Abs(o.kustomizationPath)
application, err := app.NewApplication(rootLoader, fSys)
if err != nil {
return err
}
rootLoader, err := l.New(absPath)
if err != nil {
return err
}
application, err := app.New(rootLoader)
if err != nil {
return err
}
allResources, err := application.Resources()
allResources, err := application.MakeCustomizedResMap()
if err != nil {
return err
}
// Output the objects.
res, err := kutil.Encode(allResources)
res, err := allResources.EncodeAsYaml()
if err != nil {
return err
}
if o.outputPath != "" {
return fSys.WriteFile(o.outputPath, res)
}
_, err = out.Write(res)
return err
}

View File

@@ -27,9 +27,9 @@ import (
"github.com/ghodss/yaml"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
type buildTestCase struct {
@@ -79,7 +79,7 @@ func TestBuildValidate(t *testing.T) {
func TestBuild(t *testing.T) {
const updateEnvVar = "UPDATE_KUSTOMIZE_EXPECTED_DATA"
updateKustomizeExpected := os.Getenv(updateEnvVar) == "true"
fs := fs.MakeRealFS()
fSys := fs.MakeRealFS()
testcases := sets.NewString()
filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
@@ -104,49 +104,51 @@ func TestBuild(t *testing.T) {
}
for _, testcaseName := range testcases.List() {
t.Run(testcaseName, func(t *testing.T) {
name := testcaseName
testcase := buildTestCase{}
testcaseDir := filepath.Join("testdata", "testcase-"+name)
testcaseData, err := ioutil.ReadFile(filepath.Join(testcaseDir, "test.yaml"))
if err != nil {
t.Fatalf("%s: %v", name, err)
}
if err := yaml.Unmarshal(testcaseData, &testcase); err != nil {
t.Fatalf("%s: %v", name, err)
}
ops := &buildOptions{
kustomizationPath: testcase.Filename,
}
buf := bytes.NewBuffer([]byte{})
err = ops.RunBuild(buf, os.Stderr, fs)
switch {
case err != nil && len(testcase.ExpectedError) == 0:
t.Errorf("unexpected error: %v", err)
case err != nil && len(testcase.ExpectedError) != 0:
if !strings.Contains(err.Error(), testcase.ExpectedError) {
t.Errorf("expected error to contain %q but got: %v", testcase.ExpectedError, err)
}
return
case err == nil && len(testcase.ExpectedError) != 0:
t.Errorf("unexpected no error")
}
actualBytes := buf.Bytes()
if !updateKustomizeExpected {
expectedBytes, err := ioutil.ReadFile(testcase.ExpectedStdout)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !reflect.DeepEqual(actualBytes, expectedBytes) {
t.Errorf("%s\ndoesn't equal expected:\n%s\n", actualBytes, expectedBytes)
}
} else {
ioutil.WriteFile(testcase.ExpectedStdout, actualBytes, 0644)
}
})
t.Run(testcaseName, func(t *testing.T) { runBuildTestCase(t, testcaseName, updateKustomizeExpected, fSys) })
}
}
func runBuildTestCase(t *testing.T, testcaseName string, updateKustomizeExpected bool, fSys fs.FileSystem) {
name := testcaseName
testcase := buildTestCase{}
testcaseDir := filepath.Join("testdata", "testcase-"+name)
testcaseData, err := ioutil.ReadFile(filepath.Join(testcaseDir, "test.yaml"))
if err != nil {
t.Fatalf("%s: %v", name, err)
}
if err := yaml.Unmarshal(testcaseData, &testcase); err != nil {
t.Fatalf("%s: %v", name, err)
}
ops := &buildOptions{
kustomizationPath: testcase.Filename,
}
buf := bytes.NewBuffer([]byte{})
err = ops.RunBuild(buf, fSys)
switch {
case err != nil && len(testcase.ExpectedError) == 0:
t.Errorf("unexpected error: %v", err)
case err != nil && len(testcase.ExpectedError) != 0:
if !strings.Contains(err.Error(), testcase.ExpectedError) {
t.Errorf("expected error to contain %q but got: %v", testcase.ExpectedError, err)
}
return
case err == nil && len(testcase.ExpectedError) != 0:
t.Errorf("unexpected no error")
}
actualBytes := buf.Bytes()
if !updateKustomizeExpected {
expectedBytes, err := ioutil.ReadFile(testcase.ExpectedStdout)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !reflect.DeepEqual(actualBytes, expectedBytes) {
t.Errorf("%s\ndoesn't equal expected:\n%s\n", actualBytes, expectedBytes)
}
} else {
ioutil.WriteFile(testcase.ExpectedStdout, actualBytes, 0644)
}
}

View File

@@ -18,10 +18,12 @@ package commands
import (
"fmt"
"sigs.k8s.io/kustomize/pkg/fs"
)
// dataConfig encapsulates the options for add configmap/Secret commands.
type dataConfig struct {
// cMapFlagsAndArgs encapsulates the options for add configmap commands.
type cMapFlagsAndArgs struct {
// Name of configMap/Secret (required)
Name string
// FileSources to derive the configMap/Secret from (optional)
@@ -34,7 +36,7 @@ type dataConfig struct {
}
// Validate validates required fields are set to support structured generation.
func (a *dataConfig) Validate(args []string) error {
func (a *cMapFlagsAndArgs) Validate(args []string) error {
if len(args) != 1 {
return fmt.Errorf("name must be specified once")
}
@@ -48,3 +50,12 @@ func (a *dataConfig) Validate(args []string) error {
// TODO: Should we check if the path exists? if it's valid, if it's within the same (sub-)directory?
return nil
}
func (a *cMapFlagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error {
result, err := globPatterns(fSys, a.FileSources)
if err != nil {
return err
}
a.FileSources = result
return nil
}

View File

@@ -17,11 +17,14 @@ limitations under the License.
package commands
import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/pkg/fs"
)
func TestDataConfigValidation_NoName(t *testing.T) {
config := dataConfig{}
config := cMapFlagsAndArgs{}
if config.Validate([]string{}) == nil {
t.Fatal("Validation should fail if no name is specified")
@@ -29,7 +32,7 @@ func TestDataConfigValidation_NoName(t *testing.T) {
}
func TestDataConfigValidation_MoreThanOneName(t *testing.T) {
config := dataConfig{}
config := cMapFlagsAndArgs{}
if config.Validate([]string{"name", "othername"}) == nil {
t.Fatal("Validation should fail if more than one name is specified")
@@ -39,12 +42,12 @@ func TestDataConfigValidation_MoreThanOneName(t *testing.T) {
func TestDataConfigValidation_Flags(t *testing.T) {
tests := []struct {
name string
config dataConfig
config cMapFlagsAndArgs
shouldFail bool
}{
{
name: "env-file-source and literal are both set",
config: dataConfig{
config: cMapFlagsAndArgs{
LiteralSources: []string{"one", "two"},
EnvFileSource: "three",
},
@@ -52,7 +55,7 @@ func TestDataConfigValidation_Flags(t *testing.T) {
},
{
name: "env-file-source and from-file are both set",
config: dataConfig{
config: cMapFlagsAndArgs{
FileSources: []string{"one", "two"},
EnvFileSource: "three",
},
@@ -60,12 +63,12 @@ func TestDataConfigValidation_Flags(t *testing.T) {
},
{
name: "we don't have any option set",
config: dataConfig{},
config: cMapFlagsAndArgs{},
shouldFail: true,
},
{
name: "we have from-file and literal ",
config: dataConfig{
config: cMapFlagsAndArgs{
LiteralSources: []string{"one", "two"},
FileSources: []string{"three", "four"},
},
@@ -81,3 +84,21 @@ func TestDataConfigValidation_Flags(t *testing.T) {
}
}
}
func TestExpandFileSource(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.Create("dir/config1")
fakeFS.Create("dir/config2")
fakeFS.Create("dir/reademe")
config := cMapFlagsAndArgs{
FileSources: []string{"dir/config*"},
}
config.ExpandFileSource(fakeFS)
expected := []string{
"dir/config1",
"dir/config2",
}
if !reflect.DeepEqual(config.FileSources, expected) {
t.Fatalf("FileSources is not correctly expanded: %v", config.FileSources)
}
}

View File

@@ -14,22 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package commands holds the CLI glue mapping textual commands/args to method calls.
package commands
import (
"flag"
"io"
"os"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"github.com/kubernetes-sigs/kustomize/version"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/validators"
)
// NewDefaultCommand returns the default (aka root) command for kustomize command.
func NewDefaultCommand() *cobra.Command {
fsys := fs.MakeRealFS()
stdOut, stdErr := os.Stdout, os.Stderr
stdOut := os.Stdout
c := &cobra.Command{
Use: "kustomize",
@@ -37,15 +37,15 @@ func NewDefaultCommand() *cobra.Command {
Long: `
kustomize manages declarative configuration of Kubernetes.
More info at https://github.com/kubernetes/kubectl/tree/master/cmd/kustomize
See https://sigs.k8s.io/kustomize
`,
}
c.AddCommand(
newCmdBuild(stdOut, stdErr, fsys),
newCmdDiff(stdOut, stdErr, fsys),
newCmdEdit(stdOut, stdErr, fsys),
version.NewCmdVersion(stdOut),
// TODO: Make consistent API for newCmd* functions.
newCmdBuild(stdOut, fsys),
newCmdEdit(fsys),
newCmdVersion(stdOut),
)
c.PersistentFlags().AddGoFlagSet(flag.CommandLine)
@@ -56,7 +56,7 @@ More info at https://github.com/kubernetes/kubectl/tree/master/cmd/kustomize
}
// newCmdEdit returns an instance of 'edit' subcommand.
func newCmdEdit(stdOut, stdErr io.Writer, fsys fs.FileSystem) *cobra.Command {
func newCmdEdit(fsys fs.FileSystem) *cobra.Command {
c := &cobra.Command{
Use: "edit",
Short: "Edits a kustomization file",
@@ -71,43 +71,53 @@ func newCmdEdit(stdOut, stdErr io.Writer, fsys fs.FileSystem) *cobra.Command {
Args: cobra.MinimumNArgs(1),
}
c.AddCommand(
newCmdAdd(stdOut, stdErr, fsys),
newCmdSet(stdOut, stdErr, fsys),
newCmdAdd(fsys),
newCmdSet(fsys),
)
return c
}
// newAddCommand returns an instance of 'add' subcommand.
func newCmdAdd(stdOut, stdErr io.Writer, fsys fs.FileSystem) *cobra.Command {
func newCmdAdd(fsys fs.FileSystem) *cobra.Command {
c := &cobra.Command{
Use: "add",
Short: "Adds configmap/resource/secret to the kustomization file.",
Short: "Adds configmap/resource/patch/base to the kustomization file.",
Long: "",
Example: `
# Adds a configmap to the kustomization file
kustomize edit add configmap NAME --from-literal=k=v
# Adds a secret to the kustomization file
kustomize edit add secret NAME --from-literal=k=v
# Adds a resource to the kustomization
kustomize edit add resource <filepath>
# Adds a patch to the kustomization
kustomize edit add patch <filepath>
# Adds one or more base directories to the kustomization
kustomize edit add base <filepath>
kustomize edit add base <filepath1>,<filepath2>,<filepath3>
# Adds one or more commonLabels to the kustomization
kustomize edit add label {labelKey1:labelValue1},{labelKey2:labelValue2}
# Adds one or more commonAnnotations to the kustomization
kustomize edit add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}
`,
Args: cobra.MinimumNArgs(1),
}
c.AddCommand(
newCmdAddResource(stdOut, stdErr, fsys),
newCmdAddPatch(stdOut, stdErr, fsys),
newCmdAddConfigMap(stdErr, fsys),
newCmdAddResource(fsys),
newCmdAddPatch(fsys),
newCmdAddConfigMap(fsys),
newCmdAddBase(fsys),
newCmdAddLabel(fsys, validators.MakeLabelValidator()),
newCmdAddAnnotation(fsys, validators.MakeAnnotationValidator()),
)
return c
}
// newSetCommand returns an instance of 'set' subcommand.
func newCmdSet(stdOut, stdErr io.Writer, fsys fs.FileSystem) *cobra.Command {
func newCmdSet(fsys fs.FileSystem) *cobra.Command {
c := &cobra.Command{
Use: "set",
Short: "Sets the value of different fields in kustomization file.",
@@ -120,7 +130,9 @@ func newCmdSet(stdOut, stdErr io.Writer, fsys fs.FileSystem) *cobra.Command {
}
c.AddCommand(
newCmdSetNamePrefix(stdOut, stdErr, fsys),
newCmdSetNamePrefix(fsys),
newCmdSetNamespace(fsys),
newCmdSetImageTag(fsys),
)
return c
}

View File

@@ -18,18 +18,18 @@ package commands
import (
"fmt"
"io"
"github.com/spf13/cobra"
"github.com/kubernetes-sigs/kustomize/pkg/configmapandsecret"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/types"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/configmapandsecret"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/loader"
"sigs.k8s.io/kustomize/pkg/types"
)
func newCmdAddConfigMap(errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
var config dataConfig
func newCmdAddConfigMap(fSys fs.FileSystem) *cobra.Command {
var flagsAndArgs cMapFlagsAndArgs
cmd := &cobra.Command{
Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1]",
Short: "Adds a configmap to the kustomization file.",
@@ -45,45 +45,55 @@ func newCmdAddConfigMap(errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
kustomize edit add configmap my-configmap --from-env-file=env/path.env
`,
RunE: func(_ *cobra.Command, args []string) error {
err := config.Validate(args)
err := flagsAndArgs.ExpandFileSource(fSys)
if err != nil {
return err
}
// Load in the kustomization file.
mf, err := newKustomizationFile(constants.KustomizationFileName, fsys)
err = flagsAndArgs.Validate(args)
if err != nil {
return err
}
m, err := mf.read()
// Load the kustomization file.
mf, err := newKustomizationFile(constants.KustomizationFileName, fSys)
if err != nil {
return err
}
// Add the config map to the kustomization file.
err = addConfigMap(m, config)
kustomization, err := mf.read()
if err != nil {
return err
}
// Add the flagsAndArgs map to the kustomization file.
err = addConfigMap(
kustomization, flagsAndArgs,
configmapandsecret.NewConfigMapFactory(
fSys, loader.NewFileLoader(fSys)))
if err != nil {
return err
}
// Write out the kustomization file with added configmap.
return mf.write(m)
return mf.write(kustomization)
},
}
cmd.Flags().StringSliceVar(
&config.FileSources,
&flagsAndArgs.FileSources,
"from-file",
[]string{},
"Key file can be specified using its file path, in which case file basename will be used as configmap key, or optionally with a key and file path, in which case the given key will be used. Specifying a directory will iterate each named file in the directory whose basename is a valid configmap key.")
"Key file can be specified using its file path, in which case file basename will be used as configmap "+
"key, or optionally with a key and file path, in which case the given key will be used. Specifying a "+
"directory will iterate each named file in the directory whose basename is a valid configmap key.")
cmd.Flags().StringArrayVar(
&config.LiteralSources,
&flagsAndArgs.LiteralSources,
"from-literal",
[]string{},
"Specify a key and literal value to insert in configmap (i.e. mykey=somevalue)")
cmd.Flags().StringVar(
&config.EnvFileSource,
&flagsAndArgs.EnvFileSource,
"from-env-file",
"",
"Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker .env file).")
@@ -91,27 +101,27 @@ func newCmdAddConfigMap(errOut io.Writer, fsys fs.FileSystem) *cobra.Command {
return cmd
}
// addConfigMap updates a configmap within a kustomization file, using the data in config.
// Note: error may leave kustomization file in an undefined state. Suggest passing a copy
// of kustomization file.
func addConfigMap(m *types.Kustomization, config dataConfig) error {
cm := getOrCreateConfigMap(m, config.Name)
err := mergeData(&cm.DataSources, config)
// addConfigMap adds a configmap to a kustomization file.
// Note: error may leave kustomization file in an undefined state.
// Suggest passing a copy of kustomization file.
func addConfigMap(
k *types.Kustomization,
flagsAndArgs cMapFlagsAndArgs,
factory *configmapandsecret.ConfigMapFactory) error {
cmArgs := makeConfigMapArgs(k, flagsAndArgs.Name)
err := mergeFlagsIntoCmArgs(&cmArgs.DataSources, flagsAndArgs)
if err != nil {
return err
}
// Validate by trying to create corev1.configmap.
_, _, err = configmapandsecret.MakeConfigmapAndGenerateName(*cm)
_, _, err = factory.MakeUnstructAndGenerateName(cmArgs)
if err != nil {
return err
}
return nil
}
func getOrCreateConfigMap(m *types.Kustomization, name string) *types.ConfigMapArgs {
func makeConfigMapArgs(m *types.Kustomization, name string) *types.ConfigMapArgs {
for i, v := range m.ConfigMapGenerator {
if name == v.Name {
return &m.ConfigMapGenerator[i]
@@ -123,13 +133,12 @@ func getOrCreateConfigMap(m *types.Kustomization, name string) *types.ConfigMapA
return &m.ConfigMapGenerator[len(m.ConfigMapGenerator)-1]
}
func mergeData(src *types.DataSources, config dataConfig) error {
src.LiteralSources = append(src.LiteralSources, config.LiteralSources...)
src.FileSources = append(src.FileSources, config.FileSources...)
if src.EnvSource != "" && src.EnvSource != config.EnvFileSource {
return fmt.Errorf("updating existing env source '%s' not allowed.", src.EnvSource)
func mergeFlagsIntoCmArgs(src *types.DataSources, flags cMapFlagsAndArgs) error {
src.LiteralSources = append(src.LiteralSources, flags.LiteralSources...)
src.FileSources = append(src.FileSources, flags.FileSources...)
if src.EnvSource != "" && src.EnvSource != flags.EnvFileSource {
return fmt.Errorf("updating existing env source '%s' not allowed", src.EnvSource)
}
src.EnvSource = config.EnvFileSource
src.EnvSource = flags.EnvFileSource
return nil
}

View File

@@ -19,17 +19,17 @@ package commands
import (
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/types"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/types"
)
func TestNewAddConfigMapIsNotNil(t *testing.T) {
if newCmdAddConfigMap(nil, fs.MakeFakeFS()) == nil {
if newCmdAddConfigMap(fs.MakeFakeFS()) == nil {
t.Fatal("newCmdAddConfigMap shouldn't be nil")
}
}
func TestGetOrCreateConfigMap(t *testing.T) {
func TestMakeConfigMapArgs(t *testing.T) {
cmName := "test-config-name"
kustomization := &types.Kustomization{
@@ -39,24 +39,24 @@ func TestGetOrCreateConfigMap(t *testing.T) {
if len(kustomization.ConfigMapGenerator) != 0 {
t.Fatal("Initial kustomization should not have any configmaps")
}
cm := getOrCreateConfigMap(kustomization, cmName)
args := makeConfigMapArgs(kustomization, cmName)
if cm == nil {
t.Fatalf("ConfigMap should always be non-nil")
if args == nil {
t.Fatalf("args should always be non-nil")
}
if len(kustomization.ConfigMapGenerator) != 1 {
t.Fatalf("Kustomization should have newly created configmap")
}
if &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1] != cm {
t.Fatalf("Pointer address for newly inserted configmap should be same")
if &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1] != args {
t.Fatalf("Pointer address for newly inserted configmap generator should be same")
}
existingCM := getOrCreateConfigMap(kustomization, cmName)
args2 := makeConfigMapArgs(kustomization, cmName)
if existingCM != cm {
t.Fatalf("should have returned an existing cm with name: %v", cmName)
if args2 != args {
t.Fatalf("should have returned an existing args with name: %v", cmName)
}
if len(kustomization.ConfigMapGenerator) != 1 {
@@ -64,10 +64,10 @@ func TestGetOrCreateConfigMap(t *testing.T) {
}
}
func TestMergeData_LiteralSources(t *testing.T) {
func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) {
ds := &types.DataSources{}
err := mergeData(ds, dataConfig{LiteralSources: []string{"k1=v1"}})
err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{LiteralSources: []string{"k1=v1"}})
if err != nil {
t.Fatalf("Merge initial literal source should not return error")
}
@@ -76,7 +76,7 @@ func TestMergeData_LiteralSources(t *testing.T) {
t.Fatalf("Initial literal source should have been added")
}
err = mergeData(ds, dataConfig{LiteralSources: []string{"k2=v2"}})
err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{LiteralSources: []string{"k2=v2"}})
if err != nil {
t.Fatalf("Merge second literal source should not return error")
}
@@ -86,10 +86,10 @@ func TestMergeData_LiteralSources(t *testing.T) {
}
}
func TestMergeData_FileSources(t *testing.T) {
func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) {
ds := &types.DataSources{}
err := mergeData(ds, dataConfig{FileSources: []string{"file1"}})
err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{FileSources: []string{"file1"}})
if err != nil {
t.Fatalf("Merge initial file source should not return error")
}
@@ -98,7 +98,7 @@ func TestMergeData_FileSources(t *testing.T) {
t.Fatalf("Initial file source should have been added")
}
err = mergeData(ds, dataConfig{FileSources: []string{"file2"}})
err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{FileSources: []string{"file2"}})
if err != nil {
t.Fatalf("Merge second file source should not return error")
}
@@ -108,12 +108,12 @@ func TestMergeData_FileSources(t *testing.T) {
}
}
func TestMergeData_EnvSource(t *testing.T) {
func TestMergeFlagsIntoCmArgs_EnvSource(t *testing.T) {
envFileName := "env1"
envFileName2 := "env2"
ds := &types.DataSources{}
err := mergeData(ds, dataConfig{EnvFileSource: envFileName})
err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{EnvFileSource: envFileName})
if err != nil {
t.Fatalf("Merge initial env source should not return error")
}
@@ -122,7 +122,7 @@ func TestMergeData_EnvSource(t *testing.T) {
t.Fatalf("Initial env source filename should have been added")
}
err = mergeData(ds, dataConfig{EnvFileSource: envFileName2})
err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{EnvFileSource: envFileName2})
if err == nil {
t.Fatalf("Updating env source should return an error")
}

View File

@@ -1,116 +0,0 @@
/*
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.
*/
package commands
import (
"errors"
"io"
"path/filepath"
"github.com/spf13/cobra"
"github.com/kubernetes-sigs/kustomize/pkg/app"
"github.com/kubernetes-sigs/kustomize/pkg/constants"
"github.com/kubernetes-sigs/kustomize/pkg/loader"
"github.com/kubernetes-sigs/kustomize/pkg/util"
"github.com/kubernetes-sigs/kustomize/pkg/util/fs"
"k8s.io/utils/exec"
)
type diffOptions struct {
kustomizationPath string
}
// newCmdDiff makes the diff command.
func newCmdDiff(out, errOut io.Writer, fs fs.FileSystem) *cobra.Command {
var o diffOptions
cmd := &cobra.Command{
Use: "diff [path]",
Short: "diff between customized resources and uncustomized resources",
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(cmd, args)
if err != nil {
return err
}
return o.RunDiff(out, errOut, fs)
},
}
return cmd
}
// Validate validates diff command.
func (o *diffOptions) Validate(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("specify one path to " + constants.KustomizationFileName)
}
if len(args) == 0 {
o.kustomizationPath = "./"
return nil
}
o.kustomizationPath = args[0]
return nil
}
// RunDiff gets the differences between Application.Resources() and Application.RawResources().
func (o *diffOptions) RunDiff(out, errOut io.Writer, fs fs.FileSystem) error {
printer := util.Printer{}
diff := util.DiffProgram{
Exec: exec.New(),
Stdout: out,
Stderr: errOut,
}
l := loader.Init([]loader.SchemeLoader{loader.NewFileLoader(fs)})
absPath, err := filepath.Abs(o.kustomizationPath)
if err != nil {
return err
}
rootLoader, err := l.New(absPath)
if err != nil {
return err
}
application, err := app.New(rootLoader)
if err != nil {
return err
}
resources, err := application.Resources()
if err != nil {
return err
}
rawResources, err := application.RawResources()
if err != nil {
return err
}
transformedDir, err := util.WriteToDir(resources, "transformed", printer)
if err != nil {
return err
}
defer transformedDir.Delete()
noopDir, err := util.WriteToDir(rawResources, "noop", printer)
if err != nil {
return err
}
defer noopDir.Delete()
return diff.Run(noopDir.Name, transformedDir.Name)
}

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