Compare commits
443 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af67c893d8 | ||
|
|
71f44d646f | ||
|
|
9edecffcc8 | ||
|
|
d2c93065d5 | ||
|
|
7dd02c1766 | ||
|
|
93a97950e7 | ||
|
|
f17698a8ea | ||
|
|
2cb9f81bab | ||
|
|
ed03818e20 | ||
|
|
cc531af665 | ||
|
|
0dbe78149d | ||
|
|
4bc31f4b2a | ||
|
|
a5253adb9c | ||
|
|
ae3700a193 | ||
|
|
a56604154d | ||
|
|
000f81b21c | ||
|
|
a9583fc6ec | ||
|
|
57eecd7497 | ||
|
|
6803cc4788 | ||
|
|
2796e54540 | ||
|
|
06c23b7742 | ||
|
|
7ce6181bce | ||
|
|
ec31bcbe62 | ||
|
|
0b555e1b2c | ||
|
|
ed21e77fb1 | ||
|
|
3f8b1fe05b | ||
|
|
8d4b6452d4 | ||
|
|
05e3dead7b | ||
|
|
3a01a63a01 | ||
|
|
624aa5290e | ||
|
|
8d9897d5a5 | ||
|
|
16a9975e84 | ||
|
|
755dd3d024 | ||
|
|
ba49fd4c18 | ||
|
|
08b6f6f4e4 | ||
|
|
3128b25236 | ||
|
|
5e054c9d31 | ||
|
|
4bb4a85037 | ||
|
|
b24d813f0f | ||
|
|
7e12918f75 | ||
|
|
11bb176a3f | ||
|
|
fcc3082231 | ||
|
|
49d94f5318 | ||
|
|
fa23026b80 | ||
|
|
0fa2d9c32c | ||
|
|
15a77fd2bb | ||
|
|
9c36ac28fa | ||
|
|
e1e622d985 | ||
|
|
3e86ebc3cf | ||
|
|
6d309b52a5 | ||
|
|
52faa01ecf | ||
|
|
a79c888e0c | ||
|
|
449175e3a6 | ||
|
|
2fce1a6d25 | ||
|
|
798b61c8ef | ||
|
|
84efd367d2 | ||
|
|
d9b0c4c84c | ||
|
|
c9300edead | ||
|
|
4502e8fffb | ||
|
|
51d82bece3 | ||
|
|
0e4f9acb6e | ||
|
|
aa2d8b20cd | ||
|
|
c63ebbdfc4 | ||
|
|
c094780aae | ||
|
|
4162dbc2d8 | ||
|
|
c250f75d1d | ||
|
|
af57fc3ece | ||
|
|
985abd1456 | ||
|
|
0375137296 | ||
|
|
e4956c5500 | ||
|
|
53377cdddc | ||
|
|
81c98c855f | ||
|
|
115a0bc560 | ||
|
|
2744e058b6 | ||
|
|
b6139f74de | ||
|
|
d925939795 | ||
|
|
d4842ebd90 | ||
|
|
5000a2e503 | ||
|
|
109988d105 | ||
|
|
b07bea40f7 | ||
|
|
e287f615f4 | ||
|
|
d2103dbf39 | ||
|
|
7a54d998d4 | ||
|
|
3168b2a1ed | ||
|
|
e0d2fa5701 | ||
|
|
4b4c799129 | ||
|
|
b2c8752211 | ||
|
|
4e9436eb80 | ||
|
|
8c133ef048 | ||
|
|
142879ec30 | ||
|
|
c4f79eff51 | ||
|
|
1dd448e65c | ||
|
|
ab3fed06c7 | ||
|
|
b4dbac1b84 | ||
|
|
e1b59c93de | ||
|
|
0adfd2751e | ||
|
|
fd2248e7c2 | ||
|
|
dd75392d98 | ||
|
|
af2b101fe2 | ||
|
|
62cef3de98 | ||
|
|
03e518f0ea | ||
|
|
7765bdd967 | ||
|
|
cd19d4262b | ||
|
|
4812ddff9f | ||
|
|
df52b51f67 | ||
|
|
a2e4f6cf68 | ||
|
|
ee728d58f5 | ||
|
|
6be6ade6d7 | ||
|
|
d4305ab9da | ||
|
|
ca478016c9 | ||
|
|
a7a2589e81 | ||
|
|
02e4f7305d | ||
|
|
f777ba8aa9 | ||
|
|
7e9eaf41c9 | ||
|
|
bb9b3163ee | ||
|
|
e6d1de0d72 | ||
|
|
e2a660c787 | ||
|
|
c9a5c03eaa | ||
|
|
c2eda0a172 | ||
|
|
c470982ce5 | ||
|
|
68f6b0be6e | ||
|
|
02f379536c | ||
|
|
e239d5f909 | ||
|
|
47c965481f | ||
|
|
3af0f9776f | ||
|
|
c116a28e67 | ||
|
|
6a10654618 | ||
|
|
a42b0bd574 | ||
|
|
404884e295 | ||
|
|
e17d303392 | ||
|
|
e4205c125c | ||
|
|
fdee15e523 | ||
|
|
c9d903cc36 | ||
|
|
e5a0a12ffd | ||
|
|
78cdff6d09 | ||
|
|
a64baed428 | ||
|
|
d8f3bffe63 | ||
|
|
a09b42b364 | ||
|
|
fe67bcdb8b | ||
|
|
7dc1eae40f | ||
|
|
e13896496e | ||
|
|
f864c912ad | ||
|
|
b28aaae66b | ||
|
|
fb872be04a | ||
|
|
8f413f523c | ||
|
|
89243aed37 | ||
|
|
f212deab4d | ||
|
|
79906d73d0 | ||
|
|
d4e3cd31a4 | ||
|
|
f621543d9c | ||
|
|
e801b3a75d | ||
|
|
5f93266e2c | ||
|
|
9b6f8f0c74 | ||
|
|
a352ff3923 | ||
|
|
812ae77257 | ||
|
|
b4efc833c7 | ||
|
|
5e33ac4a09 | ||
|
|
72f565d55d | ||
|
|
b92ee25696 | ||
|
|
a2d4423630 | ||
|
|
897d434673 | ||
|
|
0df5883853 | ||
|
|
84c5e44345 | ||
|
|
aafc23a615 | ||
|
|
49bd56d012 | ||
|
|
45901219b7 | ||
|
|
6ba6f305cc | ||
|
|
5653ae69e4 | ||
|
|
31534fe47d | ||
|
|
3a85fcd365 | ||
|
|
f9c631e9ee | ||
|
|
621bb7c6c5 | ||
|
|
9590eaf342 | ||
|
|
939de0cdbe | ||
|
|
c8be17c91f | ||
|
|
c6476d16e7 | ||
|
|
14668f794d | ||
|
|
efcf8757b0 | ||
|
|
ac9f2ded6e | ||
|
|
c836de5ca8 | ||
|
|
2aa7e30aff | ||
|
|
c724cb7178 | ||
|
|
858c7493df | ||
|
|
8b433b0ff9 | ||
|
|
5614649d14 | ||
|
|
9a4cb6c991 | ||
|
|
2a090e9118 | ||
|
|
7fa02ce5b3 | ||
|
|
44ac9a9f44 | ||
|
|
95e4cc1aec | ||
|
|
fa4dc14c97 | ||
|
|
69f59bfb2a | ||
|
|
eb2bdc3105 | ||
|
|
e079c20ceb | ||
|
|
27324c8236 | ||
|
|
2e71a3b862 | ||
|
|
06acd3caa9 | ||
|
|
4df576869f | ||
|
|
61d46c26b8 | ||
|
|
8eee69bd8f | ||
|
|
e4159d9411 | ||
|
|
7ab4d284ee | ||
|
|
3e6ee23a17 | ||
|
|
faaf600276 | ||
|
|
ca6228b526 | ||
|
|
16924d7913 | ||
|
|
540e4023da | ||
|
|
2ecb2e3c80 | ||
|
|
2675bf4b73 | ||
|
|
01df12cf3c | ||
|
|
7295a9b32e | ||
|
|
607eb13a52 | ||
|
|
2d70526eab | ||
|
|
e29261033f | ||
|
|
9390860288 | ||
|
|
c6764ab31f | ||
|
|
2825888ffd | ||
|
|
34e8de3fc8 | ||
|
|
86f0f9a435 | ||
|
|
03ad8efcba | ||
|
|
bcc7412ef2 | ||
|
|
c1e2b27c60 | ||
|
|
8c5d4128e0 | ||
|
|
f2295acfdd | ||
|
|
529db0493b | ||
|
|
a8c476f7c0 | ||
|
|
f38d0c690c | ||
|
|
e42933ec54 | ||
|
|
ad7ca6977b | ||
|
|
0045d7b716 | ||
|
|
64bd069290 | ||
|
|
70def86613 | ||
|
|
cff5349426 | ||
|
|
54d1c557b2 | ||
|
|
a889f97fd1 | ||
|
|
9ffe20a18b | ||
|
|
9bd456c6df | ||
|
|
a43dffdeda | ||
|
|
61cf67fb95 | ||
|
|
09f2157a92 | ||
|
|
ca4aea173c | ||
|
|
76d370a8f2 | ||
|
|
f4364eb990 | ||
|
|
865348695f | ||
|
|
2ec8189c1c | ||
|
|
a5dfc65440 | ||
|
|
45302f0790 | ||
|
|
1afc6c775b | ||
|
|
ca4d5ed42b | ||
|
|
cd9572e0bb | ||
|
|
ac3ea4d6f3 | ||
|
|
030824b196 | ||
|
|
cfb0c5efad | ||
|
|
b67d713bc0 | ||
|
|
0ac48f60a5 | ||
|
|
445f739234 | ||
|
|
fc8063f752 | ||
|
|
d5abe39d53 | ||
|
|
520acc7d97 | ||
|
|
ae0510f648 | ||
|
|
0f50be877c | ||
|
|
5b18c4de0c | ||
|
|
72fd31fd20 | ||
|
|
256ffdb932 | ||
|
|
8991bcb399 | ||
|
|
185ae510e8 | ||
|
|
40303cb329 | ||
|
|
38ec207609 | ||
|
|
1545e07dd6 | ||
|
|
f123380917 | ||
|
|
b4fc1e4357 | ||
|
|
76a3179868 | ||
|
|
c9bf70fd4b | ||
|
|
9a85071085 | ||
|
|
a6f41bb96d | ||
|
|
3f2acc90aa | ||
|
|
aba9f7d1e5 | ||
|
|
3b8c5ee96d | ||
|
|
a5bb5479fb | ||
|
|
3c58c9d132 | ||
|
|
1b1f91580e | ||
|
|
644dc4b9a7 | ||
|
|
96707645e2 | ||
|
|
b878e5f10d | ||
|
|
a914570240 | ||
|
|
b3d2ab29e9 | ||
|
|
3ff5c793e3 | ||
|
|
c752660aa6 | ||
|
|
efded10e26 | ||
|
|
8767495b5a | ||
|
|
403ede788c | ||
|
|
c444f93eb5 | ||
|
|
ed146f656e | ||
|
|
bcb697eb0b | ||
|
|
3ac66049c7 | ||
|
|
7a1a231041 | ||
|
|
748c88c276 | ||
|
|
6f4b104c9e | ||
|
|
867201a075 | ||
|
|
2545ea1019 | ||
|
|
5be42092af | ||
|
|
50c076eb3f | ||
|
|
fb9e00bf33 | ||
|
|
b9007fcc29 | ||
|
|
f6e01cfda7 | ||
|
|
9203478a8a | ||
|
|
28cb6daec7 | ||
|
|
e191ff53dd | ||
|
|
177297c0ef | ||
|
|
e5d730e1fe | ||
|
|
ba43ecbcb7 | ||
|
|
ee68a9c450 | ||
|
|
175c754f61 | ||
|
|
e8eed838b5 | ||
|
|
e9a3f9f5f6 | ||
|
|
826affb8dd | ||
|
|
4937b1c75e | ||
|
|
ffc16d51e0 | ||
|
|
1623f1e4c0 | ||
|
|
b32e041bfe | ||
|
|
38029d1836 | ||
|
|
b2dd74ab97 | ||
|
|
16fe7ced6a | ||
|
|
cb4af7a9d4 | ||
|
|
7493732176 | ||
|
|
2cf8371add | ||
|
|
a575c24a24 | ||
|
|
9e8d06e7ce | ||
|
|
4f1a2350ce | ||
|
|
cefb64b6a9 | ||
|
|
440d036176 | ||
|
|
53f0deec8f | ||
|
|
3c495e3b23 | ||
|
|
deaf0779a1 | ||
|
|
fd7a353df6 | ||
|
|
927b497feb | ||
|
|
237c54f47e | ||
|
|
8c23db47a7 | ||
|
|
7971ac1cb8 | ||
|
|
2490e605c3 | ||
|
|
21a0cba43e | ||
|
|
42d9287985 | ||
|
|
4848987a1f | ||
|
|
53a22cbe9b | ||
|
|
c3700e0c88 | ||
|
|
58d9a51040 | ||
|
|
8f395ad86f | ||
|
|
99391157ec | ||
|
|
99406d4412 | ||
|
|
c1dea6676f | ||
|
|
afa4664511 | ||
|
|
267eec5509 | ||
|
|
9764eb2f83 | ||
|
|
9a12b55139 | ||
|
|
f8cffef977 | ||
|
|
822420e4ab | ||
|
|
b60fca05bd | ||
|
|
1a35071672 | ||
|
|
bfc3655bad | ||
|
|
2c0c0c9497 | ||
|
|
46bd38e89d | ||
|
|
9fc4d388ce | ||
|
|
2965134f89 | ||
|
|
3a7c8a03f4 | ||
|
|
449b1b68e0 | ||
|
|
dd59eb38d0 | ||
|
|
a8465c95e1 | ||
|
|
df2f67b191 | ||
|
|
7764dee59d | ||
|
|
6465a36176 | ||
|
|
103c1b3a4f | ||
|
|
29cbec37b8 | ||
|
|
2c9e4507a7 | ||
|
|
d5d5c076a7 | ||
|
|
f09bbff35c | ||
|
|
2627e2507b | ||
|
|
1bd7afe6e7 | ||
|
|
e6c1b14108 | ||
|
|
7130e3ff1d | ||
|
|
abf538d80d | ||
|
|
f311ba8d4f | ||
|
|
3e85c4589b | ||
|
|
d0cf047381 | ||
|
|
31091a8df2 | ||
|
|
e207ae4c01 | ||
|
|
3011f18047 | ||
|
|
388d5c2d7c | ||
|
|
5c4719651e | ||
|
|
f850ca63f4 | ||
|
|
65886f1258 | ||
|
|
942e36e19f | ||
|
|
7b82154c4c | ||
|
|
284efc709c | ||
|
|
56965a0046 | ||
|
|
18f6328284 | ||
|
|
e7be999bc9 | ||
|
|
c06b95077d | ||
|
|
c4da063934 | ||
|
|
62d3200e4f | ||
|
|
9a419824ae | ||
|
|
a94eab0398 | ||
|
|
01b8ab8524 | ||
|
|
fa552d7773 | ||
|
|
7acbd4d3e0 | ||
|
|
9811123e2e | ||
|
|
f7cd44be42 | ||
|
|
9a4692e6ee | ||
|
|
3d0e29075d | ||
|
|
0f571b9120 | ||
|
|
3a44508d6f | ||
|
|
5294355c98 | ||
|
|
559efd6477 | ||
|
|
a59577c08d | ||
|
|
4f429d6b86 | ||
|
|
5e7ddc8616 | ||
|
|
a6f6514412 | ||
|
|
31ee38b1a1 | ||
|
|
46c7d6d39a | ||
|
|
78cbff16ef | ||
|
|
28cefb3bd1 | ||
|
|
e666630d36 | ||
|
|
ed2ad860c6 | ||
|
|
a341c24b2a | ||
|
|
0101d6e393 | ||
|
|
e429d8ca10 | ||
|
|
45ba785641 | ||
|
|
ea3d5e68db | ||
|
|
eb75203926 | ||
|
|
1303ea3969 | ||
|
|
bb69e9e70b | ||
|
|
16d1b20ed6 | ||
|
|
b0c3cd75e1 | ||
|
|
f4eef1dc0b | ||
|
|
76c6655520 | ||
|
|
d5c8734555 | ||
|
|
62ee138173 | ||
|
|
ff6cd3ca55 | ||
|
|
852e7ed5aa | ||
|
|
b7e8042a02 | ||
|
|
6bfd7cff72 | ||
|
|
9d77cbea8c | ||
|
|
8bbe147c14 | ||
|
|
1d65f24b04 |
1
.gitignore
vendored
@@ -4,7 +4,6 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
kustomize
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
47
.travis.yml
@@ -1,34 +1,43 @@
|
||||
language: go
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
# TODO: Uncomment when tests running on Windows.
|
||||
# - windows
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
|
||||
go_import_path: sigs.k8s.io/kustomize
|
||||
|
||||
# Maybe, maybe not.
|
||||
# sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- tree
|
||||
homebrew:
|
||||
packages:
|
||||
- tree
|
||||
update: true
|
||||
|
||||
# Only clone the most recent commit.
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
env:
|
||||
- GOLANGCI_RELEASE="v1.10.2"
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.12"
|
||||
|
||||
go_import_path: sigs.k8s.io/kustomize
|
||||
|
||||
before_install:
|
||||
- source ./bin/consider-early-travis-exit.sh
|
||||
- sudo apt-get install tree
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin ${GOLANGCI_RELEASE}
|
||||
- source ./travis/consider-early-travis-exit.sh
|
||||
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.17.1
|
||||
- go get -u github.com/monopole/mdrip
|
||||
# The following would install Helm if needed for some reason.
|
||||
# - wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz
|
||||
# - tar -xvzf helm-v2.13.1-linux-amd64.tar.gz
|
||||
# - sudo mv linux-amd64/helm /usr/local/bin/helm
|
||||
|
||||
# Install must be set to prevent default `go get` to run.
|
||||
# The dependencies have already been vendored by `dep` so
|
||||
# we don't need to fetch them.
|
||||
install:
|
||||
-
|
||||
# Skip the install process; let pre-commit.sh do it.
|
||||
install: true
|
||||
|
||||
script:
|
||||
- ./bin/pre-commit.sh
|
||||
- ./travis/pre-commit.sh
|
||||
|
||||
# TBD. Suppressing for now.
|
||||
notifications:
|
||||
|
||||
388
Gopkg.lock
generated
@@ -1,388 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d8ebbd207f3d3266d4423ce4860c9f3794956306ded6c7ba312ecc69cdfbf04c"
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8098cd40cd09879efbf12e33bcd51ead4a66006ac802cd563a66c4f3373b9727"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = "NUT"
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f8e6f07329067bc182633dcb19a3df53ce5d454b551e1b5a1cac2163748648d9"
|
||||
name = "github.com/emicklei/go-restful"
|
||||
packages = [
|
||||
".",
|
||||
"log",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "3658237ded108b4134956c1b3050349d93e7b895"
|
||||
version = "v2.7.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ad32dc29f37281bacb5dcedff17c9461dc1739dc8a5f63a71ab491c6e92edf8d"
|
||||
name = "github.com/evanphx/json-patch"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "afac545df32f2287a079e2dfb7ba2745a643747e"
|
||||
version = "v3.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:81466b4218bf6adddac2572a30ac733a9255919bc2f470b4827a317bd4ee1756"
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:260f7ebefc63024c8dfe2c9f1a2935a89fa4213637a1f522f592f80c001cc441"
|
||||
name = "github.com/go-openapi/jsonpointer"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:98abd61947ff5c7c6fcfec5473d02a4821ed3a2dd99a4fbfdb7925b0dd745546"
|
||||
name = "github.com/go-openapi/jsonreference"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3fb327e6747da3043567ee86abd02bb6376b6be2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e95b560c49fb849a61957a5fb3346ce23b3f67426e00e01179e5396cabc9a12c"
|
||||
name = "github.com/go-openapi/spec"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "bcff419492eeeb01f76e77d2ebc714dc97b607f5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a610c604eb06f0be4b0fc667388b7a221155d77d7f9089f70ac142a4a9daf014"
|
||||
name = "github.com/go-openapi/swag"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "811b1089cde9dad18d4d0c2d09fbdbf28dbd27a5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1b3dd24f14a5280710fc7a3aa2480b6e4d20fdfc905841de9a3aa2aa2f1d4ee9"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"sortkeys",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e2b86e41f3d669fc36b50d31d32d22c8ac656c75aa5ea89717ce7177e134ff2a"
|
||||
name = "github.com/golang/glog"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:03e14cff610a8a58b774e36bd337fa979482be86aab01be81fb8bbd6d0f07fc8"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:52c5834e2bebac9030c97cc0798ac11c3aa8a39f098aeb419f142533da6cd3cc"
|
||||
name = "github.com/google/gofuzz"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3d7c1446fc5c710351b246c0dc6700fae843ca27f5294d0bd9f68bab2a810c44"
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = [
|
||||
"OpenAPIv2",
|
||||
"compiler",
|
||||
"extensions",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "ee43cbb60db7bd22502942cccbc39059117352ab"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:406338ad39ab2e37b7f4452906442a3dbf0eb3379dd1f06aafb5c07e769a5fbb"
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:42c47ace7ccb114261ef7e0d418d274921514ab50a3bf6bdb9e51c3dde8ce13d"
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
|
||||
version = "1.1.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ada518b8c338e10e0afa443d84671476d3bd1d926e13713938088e8ddbee1a3e"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2f42fa12d6911c7b7659738758631bec870b7e9b4c6be5444f963cdcfccc191f"
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
version = "1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:314a5881fab303a80d6d2e35a77000f2224bb50f09ef63a9aa4c1f9eaef985d8"
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0f156dbd01b40676bdcbc64e51535c09b50f83c9cca5faef3090f82f18bda3c2"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:15e5c398fbd9d2c439b635a08ac161b13d04f0c2aa587fe256b65dc0c3efe8b7"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d1a6ebe75268a41b6fbb1d43947cf8688d8580423b7484fa5ae608beef6df24d"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"lex/httplex",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1c05540f6879653db88113bc4a2b70aec4bd491f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e33513a825fcd765e97b5de639a2f7547542d1a8245df0cef18e1fd390b778a9"
|
||||
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",
|
||||
"width",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a"
|
||||
name = "gopkg.in/inf.v0"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf"
|
||||
version = "v0.9.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d895c7c24a0dd1ed2ecd061fd88dfea9e1e84d6f280ed859942a2d1aabee10ec"
|
||||
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",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "53d615ae3f440f957cb9989d989d597f047262d9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:dff69dd9d9fc681ae077ce5a409aca3c24894d09102ab0395ca7972f6ec01811"
|
||||
name = "k8s.io/apimachinery"
|
||||
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 = "NUT"
|
||||
revision = "13b73596e4b63e03203e86f6d9c7bcc1b937c62f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ae9ced9ef7b8eb2794a4f80bc3af9d2bc38ec7d60337367bad9a655c1d641458"
|
||||
name = "k8s.io/client-go"
|
||||
packages = ["kubernetes/scheme"]
|
||||
pruneopts = "NUT"
|
||||
revision = "23781f4d6632d88e869066eaebb743857aa1ef9b"
|
||||
version = "v7.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f4fb3421360af5c51070bfe0c1c7467f8809fa70e278e129f068f5106b5c8a65"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = [
|
||||
"pkg/common",
|
||||
"pkg/util/proto",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b3f03f55328800731ce03a164b80973014ecd455"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/evanphx/json-patch",
|
||||
"github.com/ghodss/yaml",
|
||||
"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/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
|
||||
58
Gopkg.toml
@@ -1,58 +0,0 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
# prune out unused content from vendor
|
||||
[prune]
|
||||
go-tests = true
|
||||
non-go = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/evanphx/json-patch"
|
||||
version = "3.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/ghodss/yaml"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cobra"
|
||||
version = "0.0.2"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "k8s.io/api"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "k8s.io/apimachinery"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "7.0.0"
|
||||
|
||||
[[override]]
|
||||
branch = "master"
|
||||
name = "k8s.io/utils"
|
||||
|
||||
[[override]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/spec"
|
||||
66
README.md
@@ -16,9 +16,14 @@ inspired by [DAM].
|
||||
[](https://travis-ci.org/kubernetes-sigs/kustomize)
|
||||
[](https://goreportcard.com/report/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].
|
||||
Download a binary from the [release page], or see
|
||||
these [instructions](docs/INSTALL.md).
|
||||
|
||||
Browse the [docs](docs) or jump right into the
|
||||
tested [examples](examples).
|
||||
|
||||
kustomize [v2.0.3] is available in [kubectl v1.14][kubectl].
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -119,51 +124,10 @@ The YAML can be directly [applied] to a cluster:
|
||||
|
||||
## Community
|
||||
|
||||
### Filing bug reports
|
||||
|
||||
|
||||
##### A good report specifies
|
||||
|
||||
* the output of `kustomize version`,
|
||||
* the input (the content of `kustomization.yaml`
|
||||
and any files it refers to),
|
||||
* the expected YAML output.
|
||||
|
||||
##### A _great_ report is a bug reproduction test
|
||||
|
||||
Kustomize has a simple test harness in the
|
||||
[target package] for specifying a kustomization's
|
||||
input and the expected output.
|
||||
See this [example of a target test].
|
||||
|
||||
The pattern is
|
||||
* call `NewKustTestHarness`
|
||||
* specify kustomization input data (resources,
|
||||
patches, etc.) as inline strings,
|
||||
* call `makeKustTarget().MakeCustomizedResMap()`
|
||||
* compare the actual output to expected output
|
||||
|
||||
In a bug reproduction test, the expected output string
|
||||
initially contains the _wrong_ (unexpected) output,
|
||||
thus unambiguously reproducing the bug.
|
||||
|
||||
Nearby comments should explain what the output
|
||||
_should_ be, and have a TODO pointing to the related
|
||||
issue.
|
||||
|
||||
The person who fixes the bug then has a clear
|
||||
bug reproduction and a test to modify when
|
||||
the bug is fixed.
|
||||
|
||||
The bug reporter can then see the bug was fixed,
|
||||
and has permanent regression coverage to prevent
|
||||
its reintroduction.
|
||||
|
||||
### Feature requests
|
||||
|
||||
Feature requests are welcome.
|
||||
To file bugs please read [this](docs/bugs.md).
|
||||
|
||||
Before working on an implementation, please
|
||||
|
||||
* Read the [eschewed feature list].
|
||||
* File an issue describing
|
||||
how the new feature would behave
|
||||
@@ -192,12 +156,10 @@ is governed by the [Kubernetes Code of Conduct].
|
||||
[community page]: http://kubernetes.io/community/
|
||||
[declarative configuration]: docs/glossary.md#declarative-application-management
|
||||
[eschewed feature list]: docs/eschewedFeatures.md
|
||||
[example of a target test]: https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/target/baseandoverlaysmall_test.go
|
||||
[examples]: examples/README.md
|
||||
[imageBase]: docs/base.jpg
|
||||
[imageOverlay]: docs/overlay.jpg
|
||||
[install]: docs/INSTALL.md
|
||||
[imageBase]: docs/images/base.jpg
|
||||
[imageOverlay]: docs/images/overlay.jpg
|
||||
[kind/feature]: https://github.com/kubernetes-sigs/kustomize/labels/kind%2Ffeature
|
||||
[kubectl]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubernetes style]: docs/glossary.md#kubernetes-style-object
|
||||
[kustomization]: docs/glossary.md#kustomization
|
||||
[overlay]: docs/glossary.md#overlay
|
||||
@@ -206,7 +168,7 @@ is governed by the [Kubernetes Code of Conduct].
|
||||
[resource]: docs/glossary.md#resource
|
||||
[resources]: docs/glossary.md#resource
|
||||
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
||||
[target package]: https://github.com/kubernetes-sigs/kustomize/tree/master/pkg/target
|
||||
[variant]: docs/glossary.md#variant
|
||||
[variants]: docs/glossary.md#variant
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[workflows]: docs/workflows.md
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Make sure, we run in the root of the repo and
|
||||
# therefore run the tests on all packages
|
||||
base_dir="$( cd "$(dirname "$0")/.." && pwd )"
|
||||
cd "$base_dir" || {
|
||||
echo "Cannot cd to '$base_dir'. Aborting." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
rc=0
|
||||
|
||||
function runTest {
|
||||
local name=$1
|
||||
local result="SUCCESS"
|
||||
printf "============== begin %s\n" "$name"
|
||||
$name
|
||||
local code=$?
|
||||
rc=$((rc || $code))
|
||||
if [ $code -ne 0 ]; then
|
||||
result="FAILURE"
|
||||
fi
|
||||
printf "============== end %s : %s code=%d\n\n\n" "$name" "$result" $code
|
||||
}
|
||||
|
||||
function testGoLangCILint {
|
||||
golangci-lint run ./...
|
||||
}
|
||||
|
||||
function testGoTest {
|
||||
go test -v ./...
|
||||
}
|
||||
|
||||
function testExamples {
|
||||
mdrip --mode test --label test README.md ./examples
|
||||
}
|
||||
|
||||
runTest testGoLangCILint
|
||||
runTest testGoTest
|
||||
runTest testExamples
|
||||
|
||||
if [ $rc -eq 0 ]; then
|
||||
echo "SUCCESS!"
|
||||
else
|
||||
echo "FAILURE; exit code $rc"
|
||||
fi
|
||||
|
||||
exit $rc
|
||||
@@ -10,12 +10,10 @@ Scripts and configuration files for publishing a
|
||||
Install [`cloud-build-local`], then run
|
||||
|
||||
```
|
||||
cloud-build-local \
|
||||
--config=build/cloudbuild_local.yaml \
|
||||
--dryrun=false --write-workspace=/tmp/w .
|
||||
./build/localbuild.sh
|
||||
```
|
||||
|
||||
to build artifacts under `/tmp/w/dist`.
|
||||
to build artifacts under `./dist`.
|
||||
|
||||
### Publish a Release
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Google Container Builder automatically checks out all the code under the /workspace directory,
|
||||
# but we actually want it to under the correct expected package in the GOPATH (/go)
|
||||
# - Create the directory to host the code that matches the expected GOPATH package locations
|
||||
# - 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="sigs.k8s.io"
|
||||
REPO="kustomize"
|
||||
|
||||
GO_PKG_OWNER=$GOPATH/src/$OWNER
|
||||
GO_PKG_PATH=$GO_PKG_OWNER/$REPO
|
||||
|
||||
mkdir -p $GO_PKG_OWNER
|
||||
ln -sf $(pwd) $GO_PKG_PATH
|
||||
|
||||
# When invoked in container builder, this script runs under /workspace which is
|
||||
# not under $GOPATH, so we need to `cd` to repo under GOPATH for it to build
|
||||
cd $GO_PKG_PATH
|
||||
|
||||
|
||||
# NOTE: if snapshot is enabled, release is not published to GitHub and the build
|
||||
# is available under workspace/dist directory.
|
||||
SNAPSHOT=""
|
||||
|
||||
# parse commandline args copied from the link below
|
||||
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
case $key in
|
||||
--snapshot)
|
||||
SNAPSHOT="--snapshot"
|
||||
shift # past argument
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
/goreleaser release --config=build/goreleaser.yaml --rm-dist --skip-validate ${SNAPSHOT}
|
||||
59
build/cloudbuild.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Google Container Builder automatically checks
|
||||
# out all the code under the /workspace directory,
|
||||
# but we actually want it to under the correct
|
||||
# expected package in the GOPATH (/go)
|
||||
#
|
||||
# - Create the directory to host the code that
|
||||
# matches the expected GOPATH package locations
|
||||
#
|
||||
# - 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="sigs.k8s.io"
|
||||
REPO="kustomize"
|
||||
|
||||
GO_PKG_OWNER=$GOPATH/src/$OWNER
|
||||
GO_PKG_PATH=$GO_PKG_OWNER/$REPO
|
||||
|
||||
mkdir -p $GO_PKG_OWNER
|
||||
ln -sf $(pwd) $GO_PKG_PATH
|
||||
|
||||
# When invoked in container builder, this script runs under /workspace which is
|
||||
# not under $GOPATH, so we need to `cd` to repo under GOPATH for it to build
|
||||
cd $GO_PKG_PATH
|
||||
|
||||
|
||||
# If snapshot is enabled, release is not published
|
||||
# to GitHub and the build is available under
|
||||
# workspace/dist directory.
|
||||
|
||||
SNAPSHOT=""
|
||||
|
||||
# parse commandline args copied from the link below
|
||||
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
case $key in
|
||||
--snapshot)
|
||||
SNAPSHOT="--snapshot"
|
||||
shift # past argument
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
/goreleaser \
|
||||
release \
|
||||
--config=build/goreleaser.yaml \
|
||||
--rm-dist \
|
||||
--skip-validate ${SNAPSHOT}
|
||||
@@ -1,23 +1,8 @@
|
||||
# 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.
|
||||
|
||||
# TODO(droot): add instructions for running in production.
|
||||
steps:
|
||||
- name: "gcr.io/cloud-builders/git"
|
||||
args: [fetch, --tags, --depth=100]
|
||||
- name: "gcr.io/kustomize-199618/golang_with_goreleaser:1.10-stretch"
|
||||
args: ["bash", "build/build.sh"]
|
||||
- name: "gcr.io/kubebuilder/goreleaser_with_go_1.12.5:0.0.1"
|
||||
args: ["bash", "build/cloudbuild.sh"]
|
||||
secretEnv: ['GITHUB_TOKEN']
|
||||
secrets:
|
||||
- kmsKeyName: projects/kustomize-199618/locations/global/keyRings/github-tokens/cryptoKeys/gh-release-token
|
||||
|
||||
@@ -1,30 +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.
|
||||
|
||||
# Instructions to run locally:
|
||||
# Download google container builder: https://github.com/kubernetes-sigs/container-builder-local
|
||||
# Set you GOOS and GOARCH vars to match your system
|
||||
# Set OUTPUT to the location to write the directory containing the tar.gz
|
||||
# $ container-builder-local --config=build/cloudbuild_local.yaml --dryrun=false \
|
||||
# --substitutions=_GOOS=$GOOS,_GOARCH=$GOARCH --write-workspace=$OUTPUT .
|
||||
# Release tar will be in $OUTPUT
|
||||
|
||||
steps:
|
||||
- name: "gcr.io/kustomize-199618/golang_with_goreleaser:1.10-stretch"
|
||||
args: ["bash", "build/build.sh", "--snapshot"]
|
||||
secretEnv: ['GITHUB_TOKEN']
|
||||
secrets:
|
||||
- kmsKeyName: projects/kustomize-199618/locations/global/keyRings/github-tokens/cryptoKeys/gh-release-token
|
||||
secretEnv:
|
||||
GITHUB_TOKEN: CiQAyrREbPgXJOeT7M3t+WlxkhXwlMPudixBeiyWTjmLOMLqdK4SUQA0W+xUmDJKAhyfHCcwqSEzUn9OwKC7XAYcmwe0CCKTCbPbDgmioDK24q3LVapndXNvnnHvCjhOJNEr1o+P1DCF+LlzYV2YL8lP09rrKrslPg==
|
||||
@@ -1,18 +1,22 @@
|
||||
# This is an example goreleaser.yaml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
# Documentation at http://goreleaser.com
|
||||
# By default, output sent to ./dist (see docs).
|
||||
#
|
||||
# 2019-may-29: windows removed because of error
|
||||
# pkg/plugins/execplugin.go:111:2: undefined: syscall.Mkfifo
|
||||
#
|
||||
project_name: kustomize
|
||||
builds:
|
||||
- main: ./kustomize.go
|
||||
- main: ./cmd/kustomize/main.go
|
||||
binary: kustomize
|
||||
ldflags: -s -X sigs.k8s.io/kustomize/pkg/commands/misc.kustomizeVersion={{.Version}} -X sigs.k8s.io/kustomize/pkg/commands/misc.gitCommit={{.Commit}} -X sigs.k8s.io/kustomize/pkg/commands/misc.buildDate={{.Date}}
|
||||
goos:
|
||||
- darwin
|
||||
- linux
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GO111MODULE=on
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
archive:
|
||||
|
||||
66
build/localbuild.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage
|
||||
#
|
||||
# ./build/localbuild.sh
|
||||
#
|
||||
# The script attempts to use cloudbuild configuration
|
||||
# to create a release "locally".
|
||||
#
|
||||
# See https://cloud.google.com/cloud-build/docs/build-debug-locally
|
||||
#
|
||||
# At the time of writing,
|
||||
#
|
||||
# https://pantheon.corp.google.com/cloud-build/triggers?project=kustomize-199618
|
||||
#
|
||||
# has a trigger such that whenever a git tag is
|
||||
# applied to the kustomize repo, the cloud builder
|
||||
# reads the repository-relative file
|
||||
#
|
||||
# build/cloudbuild.yaml
|
||||
#
|
||||
# Inside this yaml file is a reference to the script
|
||||
#
|
||||
# build/cloudbuild.sh
|
||||
#
|
||||
# The script you are reading now does something
|
||||
# analogous via docker tricks.
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z ${GOPATH+x} ]; then
|
||||
echo GOPATH is unset; cannot proceed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd $GOPATH/src/sigs.k8s.io/kustomize
|
||||
pwd
|
||||
|
||||
# The first "step" in the following uses a special
|
||||
# goreleaser container image that the kubebuilder folks made.
|
||||
# TODO: On a rainy day, switch to something more standard.
|
||||
|
||||
config=$(mktemp)
|
||||
cat <<EOF >$config
|
||||
steps:
|
||||
- name: "gcr.io/kubebuilder/goreleaser_with_go_1.12.5:0.0.1"
|
||||
args: ["bash", "build/cloudbuild.sh", "--snapshot"]
|
||||
secretEnv: ['GITHUB_TOKEN']
|
||||
secrets:
|
||||
- kmsKeyName: projects/kustomize-199618/locations/global/keyRings/github-tokens/cryptoKeys/gh-release-token
|
||||
secretEnv:
|
||||
GITHUB_TOKEN: CiQAyrREbPgXJOeT7M3t+WlxkhXwlMPudixBeiyWTjmLOMLqdK4SUQA0W+xUmDJKAhyfHCcwqSEzUn9OwKC7XAYcmwe0CCKTCbPbDgmioDK24q3LVapndXNvnnHvCjhOJNEr1o+P1DCF+LlzYV2YL8lP09rrKrslPg==
|
||||
EOF
|
||||
|
||||
cloud-build-local \
|
||||
--config=$config \
|
||||
--bind-mount-source \
|
||||
--dryrun=false \
|
||||
.
|
||||
|
||||
# Print results of local build, which went to ./dist
|
||||
echo "##########################################"
|
||||
tree ./dist
|
||||
echo "##########################################"
|
||||
|
||||
popd
|
||||
17
cmd/kustomize/main.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/commands"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := commands.NewDefaultCommand().Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
132
cmd/pluginator/main.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// See /plugin/doc.go for an explanation.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||
"sigs.k8s.io/kustomize/pkg/plugins"
|
||||
)
|
||||
|
||||
func main() {
|
||||
root := inputFileRoot()
|
||||
file, err := os.Open(root + ".go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
readToPackageMain(scanner, file.Name())
|
||||
|
||||
w := NewWriter(root)
|
||||
defer w.close()
|
||||
|
||||
// This particular phrasing is required.
|
||||
w.write(
|
||||
fmt.Sprintf(
|
||||
"// Code generated by pluginator on %s; DO NOT EDIT.",
|
||||
root))
|
||||
w.write("package builtin")
|
||||
|
||||
for scanner.Scan() {
|
||||
l := scanner.Text()
|
||||
if strings.HasPrefix(l, "//go:generate") {
|
||||
continue
|
||||
}
|
||||
if l == "var "+plugins.PluginSymbol+" plugin" {
|
||||
w.write("func New" + root + "Plugin() *" + root + "Plugin {")
|
||||
w.write(" return &" + root + "Plugin{}")
|
||||
w.write("}")
|
||||
continue
|
||||
}
|
||||
w.write(l)
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func inputFileRoot() string {
|
||||
n := os.Getenv("GOFILE")
|
||||
if !strings.HasSuffix(n, ".go") {
|
||||
log.Fatalf("expecting .go suffix on %s", n)
|
||||
}
|
||||
return n[:len(n)-len(".go")]
|
||||
}
|
||||
|
||||
func readToPackageMain(s *bufio.Scanner, f string) {
|
||||
gotMain := false
|
||||
for !gotMain && s.Scan() {
|
||||
gotMain = strings.HasPrefix(s.Text(), "package main")
|
||||
}
|
||||
if !gotMain {
|
||||
log.Fatalf("%s missing package main", f)
|
||||
}
|
||||
}
|
||||
|
||||
type writer struct {
|
||||
root string
|
||||
f *os.File
|
||||
}
|
||||
|
||||
func NewWriter(r string) *writer {
|
||||
n := makeOutputFileName(r)
|
||||
f, err := os.Create(n)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to create `%s`; %v", n, err)
|
||||
}
|
||||
return &writer{root: r, f: f}
|
||||
}
|
||||
|
||||
func makeOutputFileName(root string) string {
|
||||
return filepath.Join(
|
||||
os.Getenv("GOPATH"),
|
||||
"src",
|
||||
pgmconfig.DomainName,
|
||||
pgmconfig.ProgramName,
|
||||
pgmconfig.PluginRoot,
|
||||
"builtin",
|
||||
root+".go")
|
||||
}
|
||||
|
||||
func (w *writer) close() {
|
||||
fmt.Println("Generated " + w.root)
|
||||
w.f.Close()
|
||||
}
|
||||
|
||||
func (w *writer) write(line string) {
|
||||
_, err := w.f.WriteString(w.filter(line) + "\n")
|
||||
if err != nil {
|
||||
log.Printf("Trouble writing: %s", line)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *writer) filter(in string) string {
|
||||
if ok, newer := w.replace(in, "type plugin struct"); ok {
|
||||
return newer
|
||||
}
|
||||
if ok, newer := w.replace(in, "*plugin)"); ok {
|
||||
return newer
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
// replace 'plugin' with 'FooPlugin' in context
|
||||
// sensitive manner.
|
||||
func (w *writer) replace(in, target string) (bool, string) {
|
||||
if !strings.Contains(in, target) {
|
||||
return false, ""
|
||||
}
|
||||
newer := strings.Replace(
|
||||
target, "plugin", w.root+"Plugin", 1)
|
||||
return true, strings.Replace(in, target, newer, 1)
|
||||
}
|
||||
39
docs/FAQ.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# FAQ
|
||||
|
||||
## security: file 'foo' is not in or below 'bar'
|
||||
|
||||
v2.0 added a security check that prevents
|
||||
kustomizations from reading files outside their own
|
||||
directory root.
|
||||
|
||||
This was meant to help protect the person inclined to
|
||||
download kustomization directories from the web and use
|
||||
them without inspection to control their production
|
||||
cluster
|
||||
(see [#693](https://github.com/kubernetes-sigs/kustomize/issues/693),
|
||||
[#700](https://github.com/kubernetes-sigs/kustomize/pull/700),
|
||||
[#995](https://github.com/kubernetes-sigs/kustomize/pull/995) and
|
||||
[#998](https://github.com/kubernetes-sigs/kustomize/pull/998))
|
||||
|
||||
Resources (including configmap and secret generators)
|
||||
can _still be shared_ via the recommended best practice
|
||||
of placing them in a directory with their own
|
||||
kustomization file, and refering to this directory as a
|
||||
[`base`](glossary.md#base) from any kustomization that
|
||||
wants to use it. This encourages modularity and
|
||||
relocatability.
|
||||
|
||||
At the moment (in v2.0.3), however, there's no
|
||||
(released) analogous way to share patch files and other
|
||||
transformer configuration data between kustomizations.
|
||||
|
||||
As a stop-gap until we add base-like behavior for
|
||||
transformers, we've added a flag to disable the check:
|
||||
|
||||
|
||||
```
|
||||
kustomize build --load_restrictor none $target
|
||||
```
|
||||
|
||||
This flag is not in v2.0.3, but is available from head
|
||||
(`go install sigs.k8s.io/kustomize`).
|
||||
@@ -3,17 +3,11 @@
|
||||
|
||||
## Installation
|
||||
|
||||
On macOS, you can install kustomize with Homebrew package
|
||||
manager:
|
||||
|
||||
brew install kustomize
|
||||
|
||||
For all operating systems, download a binary from the
|
||||
For linux, macOs and Windows,
|
||||
download a binary from the
|
||||
[release page].
|
||||
|
||||
Or try this to grab the latest official release
|
||||
using the command line:
|
||||
|
||||
Or try this command:
|
||||
```
|
||||
opsys=linux # or darwin, or windows
|
||||
curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases/latest |\
|
||||
@@ -25,9 +19,29 @@ mv kustomize_*_${opsys}_amd64 kustomize
|
||||
chmod u+x kustomize
|
||||
```
|
||||
|
||||
To install from head with [Go] v1.10.1 or higher:
|
||||
To install from head with [Go] v1.12 or higher:
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
go install sigs.k8s.io/kustomize/cmd/kustomize
|
||||
```
|
||||
|
||||
### Other methods
|
||||
|
||||
#### macOS
|
||||
|
||||
```
|
||||
brew install kustomize
|
||||
```
|
||||
|
||||
#### windows
|
||||
|
||||
```
|
||||
choco install kustomize
|
||||
```
|
||||
|
||||
For support on the chocolatey package
|
||||
and prior releases, see:
|
||||
- [Choco Package](https://chocolatey.org/packages/kustomize)
|
||||
- [Package Source](https://github.com/kenmaglio/choco-kustomize)
|
||||
|
||||
|
||||
@@ -1,28 +1,50 @@
|
||||
# Kustomize docs
|
||||
|
||||
* [installation instructions](INSTALL.md)
|
||||
|
||||
* [kustomization.yaml](kustomization.yaml) - Example of a
|
||||
[kustomization](glossary.md#kustomization)
|
||||
with explanations of each field.
|
||||
English | [简体中文](zh/README.md)
|
||||
|
||||
* [versioning policy](versioningPolicy.md) - How the code and the kustomization
|
||||
file evolve in time.
|
||||
|
||||
* [version 2.0.0](version2.0.0.md) - Release note of Kustomize 2.0.0.
|
||||
# Documentation
|
||||
|
||||
* [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.
|
||||
* [Installation](INSTALL.md)
|
||||
|
||||
* [contributing guidelines](../CONTRIBUTING.md) - Please read before sending a PR.
|
||||
|
||||
* [code of conduct](../code-of-conduct.md)
|
||||
|
||||
|
||||
|
||||
|
||||
* [Examples](../examples) - detailed walkthroughs of various
|
||||
workflows and concepts.
|
||||
|
||||
* [Glossary](glossary.md) - the word of the day is [_root_](glossary.md#kustomization-root).
|
||||
|
||||
* [Kustomize Fields](fields.md) - explanations of the fields
|
||||
in a [kustomization](glossary.md#kustomization) file.
|
||||
|
||||
* [Plugins](plugins.md) - extending kustomize with
|
||||
custom generators and transformers.
|
||||
|
||||
* [Workflows](workflows.md) - steps one might take in
|
||||
using bespoke and off-the-shelf configurations.
|
||||
|
||||
* [FAQ](FAQ.md)
|
||||
|
||||
|
||||
## Release notes
|
||||
|
||||
* [2.1](v_2.1.0.md) - Date TBD, target late May 2019
|
||||
|
||||
* [2.0](v_2.0.0.md) - Mar 2019.
|
||||
kustomize [v2.0.3] is available in [kubectl v1.14][kubectl].
|
||||
|
||||
* [1.0](v_1.0.1.md) - May 2018. Initial release after development
|
||||
in the [kubectl repository].
|
||||
|
||||
|
||||
## Policies
|
||||
|
||||
* [Versioning](versioningPolicy.md) - how the code and
|
||||
the kustomization file evolve in time.
|
||||
|
||||
* [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)
|
||||
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[kubectl]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubectl repository]: https://github.com/kubernetes/kubectl
|
||||
|
||||
46
docs/bugs.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Filing bugs
|
||||
|
||||
[target package]: https://github.com/kubernetes-sigs/kustomize/tree/master/pkg/target
|
||||
[example of a target test]: https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/target/baseandoverlaysmall_test.go
|
||||
|
||||
File issues as desired, but
|
||||
if you've found a problem with how
|
||||
`kustomize build` works, consider the
|
||||
following to improve response time.
|
||||
|
||||
## A good report specifies
|
||||
|
||||
* the output of `kustomize version`,
|
||||
* the input (the content of `kustomization.yaml`
|
||||
and any files it refers to),
|
||||
* the expected YAML output.
|
||||
|
||||
## A great report is a bug reproduction test
|
||||
|
||||
kustomize has a simple test harness in the
|
||||
[target package] for specifying a kustomization's
|
||||
input and the expected output.
|
||||
See this [example of a target test].
|
||||
|
||||
The pattern is
|
||||
* call `NewKustTestHarness`
|
||||
* specify kustomization input data (resources,
|
||||
patches, etc.) as inline strings,
|
||||
* call `makeKustTarget().MakeCustomizedResMap()`
|
||||
* compare the actual output to expected output
|
||||
|
||||
In a bug reproduction test, the expected output
|
||||
string initially contains the _wrong_ (unexpected)
|
||||
output, thus unambiguously reproducing the bug.
|
||||
|
||||
Nearby comments should explain what the output
|
||||
should be, and have a TODO pointing to the related
|
||||
issue.
|
||||
|
||||
The person who fixes the bug then has a clear bug
|
||||
reproduction and a test to modify when the bug is
|
||||
fixed.
|
||||
|
||||
The bug reporter can then see the bug was fixed,
|
||||
and has permanent regression coverage to prevent
|
||||
its reintroduction.
|
||||
504
docs/fields.md
Normal file
@@ -0,0 +1,504 @@
|
||||
# Kustomization File Fields
|
||||
|
||||
An explanation of the fields in a [kustomization.yaml](glossary.md#kustomization) file.
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
What existing things should be customized.
|
||||
|
||||
| Field | Type | Explanation |
|
||||
|---|---|---|
|
||||
|[resources](#resources) | list |Files containing k8s API objects, or directories containing other kustomizations. |
|
||||
|[CRDs](#crds)| list |Custom resource definition files, to allow specification of the custom resources in the resources list. |
|
||||
|
||||
## Generators
|
||||
|
||||
What things should be created (and optionally subsequently customized)?
|
||||
|
||||
| Field | Type | Explanation |
|
||||
|---|---|---|
|
||||
|[configMapGenerator](#configmapgenerator)| list |Each entry in this list results in the creation of one ConfigMap resource (it's a generator of n maps).|
|
||||
|[secretGenerator](#secretgenerator)| list |Each entry in this list results in the creation of one Secret resource (it's a generator of n secrets)|
|
||||
|[generatorOptions](#generatoroptions)|string|generatorOptions modify behavior of all ConfigMap and Secret generators|
|
||||
|[generators](#generators)|list|[plugin](plugins.md) configuration files|
|
||||
|
||||
|
||||
## Transformers
|
||||
|
||||
What transformations (customizations) should be applied?
|
||||
|
||||
| Field | Type | Explanation |
|
||||
|---|---|---|
|
||||
| [commonLabels](#commonlabels) | string | Adds labels and some corresponding label selectors to all resources. |
|
||||
| [commonAnnotations](#commonannotations) | string | Adds annotions (non-identifying metadata) to add all resources. |
|
||||
| [images](#images) | list | Images modify the name, tags and/or digest for images without creating patches. |
|
||||
| [inventory](#inventory) | struct | Specify an object who's annotations will contain a build result summary. |
|
||||
| [namespace](#namespace) | string | Adds namespace to all resources |
|
||||
| [namePrefix](#nameprefix) | string | Prepends value to the names of all resources |
|
||||
| [nameSuffix](#namesuffix) | string | The value is appended to the names of all resources. |
|
||||
| [replicas](#replicas) | list | Replicas modifies the number of replicas of a resource. |
|
||||
|[patchesStrategicMerge](#patchesstrategicmerge)| list |Each entry in this list should resolve to a partial or complete resource definition file.|
|
||||
|[patchesJson6902](#patchesjson6902)| list |Each entry in this list should resolve to a kubernetes object and a JSON patch that will be applied to the object.|
|
||||
|[transformers](#transformers)|list|[plugin](plugins.md) configuration files|
|
||||
|
||||
|
||||
## Meta
|
||||
|
||||
[k8s metadata]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
|
||||
|
||||
|Field|Type|Explanation|
|
||||
|---|---|---|
|
||||
| [vars](#vars) | string | Vars capture text from one resource's field and insert that text elsewhere. |
|
||||
| [apiVersion](#apiversion) | string | [k8s metadata] field. |
|
||||
| [kind](#kind) | string | [k8s metadata] field. |
|
||||
|
||||
----
|
||||
|
||||
### apiVersion
|
||||
|
||||
If missing, this field's value defaults to
|
||||
```
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
```
|
||||
|
||||
### bases
|
||||
|
||||
The `bases` field was deprecated in v2.1.0.
|
||||
|
||||
Move entries into the [resources](#resources)
|
||||
field. This allows bases - which are still a
|
||||
[central concept](glossary.md#base) - to be
|
||||
ordered relative to other input resources.
|
||||
|
||||
### commonLabels
|
||||
|
||||
Adds labels to all resources and selectors
|
||||
```
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
```
|
||||
|
||||
### commonAnnotations
|
||||
|
||||
Adds annotions (non-identifying metadata) to add
|
||||
all resources. Like labels, these are key value
|
||||
pairs.
|
||||
|
||||
```
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
```
|
||||
|
||||
### configMapGenerator
|
||||
|
||||
Each entry in this list results in the creation of
|
||||
one ConfigMap resource (it's a generator of n maps).
|
||||
|
||||
The example below creates two ConfigMaps. One with the
|
||||
names and contents of the given files, the other with
|
||||
key/value as data.
|
||||
|
||||
Each configMapGenerator item accepts a parameter of
|
||||
`behavior: [create|replace|merge]`.
|
||||
This allows an overlay to modify or
|
||||
replace an existing configMap from the parent.
|
||||
|
||||
```
|
||||
configMapGenerator:
|
||||
- name: myJavaServerProps
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
- name: myJavaServerEnvVars
|
||||
literals:
|
||||
- JAVA_HOME=/opt/java/jdk
|
||||
- JAVA_TOOL_OPTIONS=-agentlib:hprof
|
||||
```
|
||||
|
||||
### crds
|
||||
|
||||
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 a kustomization, the ConfigMap
|
||||
object name may change by adding namePrefix,
|
||||
nameSuffix, or hashing. The name reference for this
|
||||
ConfigMap object in CRD object need to be updated
|
||||
with namePrefix, nameSuffix, or hashing in the
|
||||
same way.
|
||||
|
||||
The annotations can be put into openAPI definitions are:
|
||||
- "x-kubernetes-annotation": ""
|
||||
- "x-kubernetes-label-selector": ""
|
||||
- "x-kubernetes-identity": ""
|
||||
- "x-kubernetes-object-ref-api-version": "v1",
|
||||
- "x-kubernetes-object-ref-kind": "Secret",
|
||||
- "x-kubernetes-object-ref-name-key": "name",
|
||||
|
||||
|
||||
```
|
||||
|
||||
crds:
|
||||
- crds/typeA.yaml
|
||||
- crds/typeB.yaml
|
||||
```
|
||||
|
||||
|
||||
### generatorOptions
|
||||
|
||||
Modifies behavior of all [ConfigMap](#configmapgenerator)
|
||||
and [Secret](#secretgenerator) generators.
|
||||
|
||||
```
|
||||
generatorOptions:
|
||||
# labels to add to all generated resources
|
||||
labels:
|
||||
kustomize.generated.resources: somevalue
|
||||
# annotations to add to all generated resources
|
||||
annotations:
|
||||
kustomize.generated.resource: somevalue
|
||||
# disableNameSuffixHash is true disables the default behavior of adding a
|
||||
# suffix to the names of generated resources that is a hash of
|
||||
# the resource contents.
|
||||
disableNameSuffixHash: true
|
||||
```
|
||||
|
||||
### generators
|
||||
|
||||
A list of generator [plugin](plugins.md) configuration files.
|
||||
|
||||
```
|
||||
generators:
|
||||
- mySecretGeneratorPlugin.yaml
|
||||
- myAppGeneratorPlugin.yaml
|
||||
```
|
||||
|
||||
### images
|
||||
|
||||
Images modify the name, tags and/or digest for images without creating patches.
|
||||
E.g. Given this kubernetes Deployment fragment:
|
||||
|
||||
```
|
||||
containers:
|
||||
- name: mypostgresdb
|
||||
image: postgres:8
|
||||
- name: nginxapp
|
||||
image: nginx:1.7.9
|
||||
- name: myapp
|
||||
image: my-demo-app:latest
|
||||
- name: alpine-app
|
||||
image: alpine:3.7
|
||||
```
|
||||
|
||||
one can change the `image` in the following ways:
|
||||
|
||||
- `postgres:8` to `my-registry/my-postgres:v1`,
|
||||
- nginx tag `1.7.9` to `1.8.0`,
|
||||
- image name `my-demo-app` to `my-app`,
|
||||
- alpine's tag `3.7` to a digest value
|
||||
|
||||
all with the following *kustomization*:
|
||||
|
||||
```
|
||||
images:
|
||||
- name: postgres
|
||||
newName: my-registry/my-postgres
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: my-demo-app
|
||||
newName: my-app
|
||||
- name: alpine
|
||||
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
||||
```
|
||||
|
||||
### inventory
|
||||
|
||||
See [inventory object](inventory_object.md).
|
||||
|
||||
### kind
|
||||
|
||||
If missing, this field's value defaults to
|
||||
|
||||
```
|
||||
kind: Kustomization
|
||||
```
|
||||
|
||||
|
||||
### namespace
|
||||
|
||||
Adds namespace to all resources
|
||||
|
||||
```
|
||||
namespace: my-namespace
|
||||
```
|
||||
|
||||
### namePrefix
|
||||
|
||||
Prepends value to the names of all resources
|
||||
Ex. a deployment named `wordpress` would become `alices-wordpress`
|
||||
|
||||
```
|
||||
namePrefix: alices-
|
||||
```
|
||||
|
||||
### nameSuffix
|
||||
|
||||
The value is appended to the names of all
|
||||
resources. Ex. A deployment named `wordpress`
|
||||
would become `wordpress-v2`.
|
||||
|
||||
The suffix is appended before content has if
|
||||
resource type is ConfigMap or Secret.
|
||||
|
||||
```
|
||||
nameSuffix: -v2
|
||||
```
|
||||
|
||||
### patchesStrategicMerge
|
||||
|
||||
Each entry in this list should be a relative path
|
||||
resolving to a partial or complete resource
|
||||
definition file.
|
||||
|
||||
The names in these (possibly partial) resource
|
||||
files must match names already loaded via the
|
||||
`resources` field. These entries are used to
|
||||
_patch_ (modify) the known resources.
|
||||
|
||||
Small patches that do one thing are best, e.g. modify
|
||||
a memory request/limit, change an env var in a
|
||||
ConfigMap, etc. Small patches are easy to review and
|
||||
easy to mix together in overlays.
|
||||
|
||||
```
|
||||
patchesStrategicMerge:
|
||||
- service_port_8888.yaml
|
||||
- deployment_increase_replicas.yaml
|
||||
- deployment_increase_memory.yaml
|
||||
```
|
||||
|
||||
### patchesJson6902
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### replicas
|
||||
|
||||
Replicas modified the number of replicas for a resource.
|
||||
|
||||
E.g. Given this kubernetes Deployment fragment:
|
||||
|
||||
```
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-name
|
||||
spec:
|
||||
replicas: 3
|
||||
```
|
||||
|
||||
one can change the number of replicas to 5
|
||||
by adding the following to your kustomization:
|
||||
|
||||
```
|
||||
replicas:
|
||||
- name: deployment-name
|
||||
count: 5
|
||||
```
|
||||
|
||||
This field accepts a list, so many resources can
|
||||
be modified at the same time.
|
||||
|
||||
|
||||
#### Limitation
|
||||
As this declaration does not take in a `kind:` nor a `group:`
|
||||
it will match any `group` and `kind` that has a matching name and
|
||||
that is one of:
|
||||
- `Deployment`
|
||||
- `ReplicationController`
|
||||
- `ReplicaSet`
|
||||
- `StatefulSet`
|
||||
|
||||
For more complex use cases, revert to using a patch.
|
||||
|
||||
|
||||
### resources
|
||||
|
||||
Each entry in this list must be a path to a
|
||||
_file_, or a path (or URL) refering to another
|
||||
kustomization _directory_, e.g.
|
||||
|
||||
```
|
||||
resource:
|
||||
- myNamespace.yaml
|
||||
- sub-dir/some-deployment.yaml
|
||||
- ../../commonbase
|
||||
- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
|
||||
- deployment.yaml
|
||||
- github.com/kubernets-sigs/kustomize//examples/helloWorld?ref=test-branch
|
||||
```
|
||||
|
||||
Resources will be read and processed in
|
||||
depth-first order.
|
||||
|
||||
Files should contain k8s resources in YAML form.
|
||||
A file may contain multiple resources separated by
|
||||
the document marker `---`. File paths should be
|
||||
specified _relative_ to the directory holding the
|
||||
kustomization file containing the `resources`
|
||||
field.
|
||||
|
||||
[hashicorp URL]: https://github.com/hashicorp/go-getter#url-format
|
||||
|
||||
Directory specification can be relative, absolute,
|
||||
or part of a URL. URL specifications should
|
||||
follow the [hashicorp URL] format. The directory
|
||||
must contain a `kustomization.yaml` file.
|
||||
|
||||
|
||||
### secretGenerator
|
||||
|
||||
Each entry in this list results in the creation of
|
||||
one Secret resource (it's a generator of n secrets).
|
||||
|
||||
```
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: app-tls-namespaced
|
||||
# you can define a namespace to generate secret in, defaults to: "default"
|
||||
namespace: apps
|
||||
files:
|
||||
- tls.crt=catsecret/tls.cert
|
||||
- tls.key=secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: env_file_secret
|
||||
envs:
|
||||
- env.txt
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
### vars
|
||||
|
||||
Vars are used to capture text from one resource's field
|
||||
and insert that text elsewhere - a reflection feature.
|
||||
|
||||
For example, suppose one specifies the name of a k8s Service
|
||||
object in a container's command line, and the name of a
|
||||
k8s Secret object in a container's environment variable,
|
||||
so that the following would work:
|
||||
|
||||
```
|
||||
containers:
|
||||
- image: myimage
|
||||
command: ["start", "--host", "$(MY_SERVICE_NAME)"]
|
||||
env:
|
||||
- name: SECRET_TOKEN
|
||||
value: $(SOME_SECRET_NAME)
|
||||
```
|
||||
|
||||
To do so, add an entry to `vars:` as follows:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
A var is a tuple of variable name, object
|
||||
reference and field reference within that object.
|
||||
That's where the text is found.
|
||||
|
||||
The field reference is optional; it defaults to
|
||||
`metadata.name`, a normal default, since kustomize
|
||||
is used to generate or modify the names of
|
||||
resources.
|
||||
|
||||
At time of writing, only string type fields are
|
||||
supported. No ints, bools, arrays etc. It's not
|
||||
possible to, say, extract the name of the image in
|
||||
container number 2 of some pod template.
|
||||
|
||||
A variable reference, i.e. the string '$(FOO)',
|
||||
can only be placed in particular fields of
|
||||
particular objects as specified by kustomize's
|
||||
configuration data.
|
||||
|
||||
The default config data for vars is at
|
||||
https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go
|
||||
Long story short, the default targets are all
|
||||
container command args and env value fields.
|
||||
|
||||
Vars should _not_ be used for inserting names in
|
||||
places where kustomize is already handling that
|
||||
job. E.g., a Deployment may reference a ConfigMap
|
||||
by name, and if kustomize changes the name of a
|
||||
ConfigMap, it knows to change the name reference
|
||||
in the Deployment.
|
||||
|
||||
|
||||
192
docs/glossary.md
@@ -19,6 +19,7 @@
|
||||
[kubernetes]: #kubernetes
|
||||
[kustomize]: #kustomize
|
||||
[kustomization]: #kustomization
|
||||
[kustomizations]: #kustomization
|
||||
[off-the-shelf]: #off-the-shelf-configuration
|
||||
[overlay]: #overlay
|
||||
[overlays]: #overlay
|
||||
@@ -31,8 +32,9 @@
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resource]: #resource
|
||||
[resources]: #resource
|
||||
[root]: #kustomization-root
|
||||
[rpm]: https://en.wikipedia.org/wiki/Rpm_(software)
|
||||
[strategic-merge]: https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md
|
||||
[strategic-merge]: https://git.k8s.io/community/contributors/devel/sig-api-machinery/strategic-merge-patch.md
|
||||
[target]: #target
|
||||
[variant]: #variant
|
||||
[variants]: #variant
|
||||
@@ -74,10 +76,11 @@ management in k8s.
|
||||
|
||||
## base
|
||||
|
||||
A _base_ is a [target] that some [overlay] modifies.
|
||||
A _base_ is a [kustomization] referred to
|
||||
by some other [kustomization].
|
||||
|
||||
Any target, including an [overlay], can be a base to
|
||||
another target.
|
||||
Any kustomization, including an [overlay], can be a base to
|
||||
another kustomization.
|
||||
|
||||
A base has no knowledge of the overlays that refer to it.
|
||||
|
||||
@@ -134,6 +137,12 @@ In brief, kustomize should
|
||||
specific languages, etc., frustrating the other
|
||||
goals.
|
||||
|
||||
## generator
|
||||
|
||||
A generator makes resources that can be used as is,
|
||||
or fed into a [transformer].
|
||||
|
||||
|
||||
## gitops
|
||||
|
||||
Devops or CICD workflows that use a git repository as a
|
||||
@@ -142,31 +151,103 @@ test or deploy) when that truth changes.
|
||||
|
||||
## kustomization
|
||||
|
||||
A _kustomization_ is a file called `kustomization.yaml` that
|
||||
describes a configuration consumable by [kustomize].
|
||||
The term _kustomization_ refers to a
|
||||
`kustomization.yaml` file, or more generally to a
|
||||
directory (the [root]) containing the
|
||||
`kustomization.yaml` file and all the relative file
|
||||
paths that it immediately references (all the local
|
||||
data that doesn't require a URL specification).
|
||||
|
||||
I.e. if someone gives you a _kustomization_ for use
|
||||
with [kustomize], it could be in the form of
|
||||
|
||||
* one file called `kustomization.yaml`,
|
||||
* a tarball (containing that YAML file plus what it references),
|
||||
* a git archive (ditto),
|
||||
* a URL to a git repo (ditto), etc.
|
||||
|
||||
A kustomization file contains [fields](fields.md)
|
||||
falling into four categories:
|
||||
|
||||
* _resources_ - what existing [resources] are to be customized.
|
||||
Example fields: _resources_, _crds_.
|
||||
|
||||
* _generators_ - what _new_ resources should be created.
|
||||
Example fields: _configMapGenerator_ (legacy),
|
||||
_secretGenerator_ (legacy), _generators_ (v2.1).
|
||||
|
||||
* _transformers_ - what to _do_ to the aforementioned resources.
|
||||
Example fields: _namePrefix_, _nameSuffix_, _images_,
|
||||
_commonLabels_, _patchesJson6902_, etc. and the more
|
||||
general _transformers_ (v2.1) field.
|
||||
|
||||
* _meta_ - fields which may influence all or some of
|
||||
the above. Example fields: _vars_, _namespace_,
|
||||
_apiVersion_, _kind_, etc.
|
||||
|
||||
|
||||
Here's an [example](kustomization.yaml).
|
||||
## kustomization root
|
||||
|
||||
A kustomization contains fields falling into these categories:
|
||||
The directory that immediately contains a
|
||||
`kustomization.yaml` file.
|
||||
|
||||
* _Customization operators_ for modifying operands, e.g.
|
||||
_namePrefix_, _nameSuffix_, _commonLabels_, _patches_, etc.
|
||||
When a kustomization file is processed, it may or may
|
||||
not be able to access files outside its root.
|
||||
|
||||
* _Customization operands_:
|
||||
* [resources] - completely specified k8s API objects,
|
||||
e.g. `deployment.yaml`, `configmap.yaml`, etc.
|
||||
* [bases] - paths or github URLs specifying directories
|
||||
containing a [kustomization]. These bases may
|
||||
be subjected to more customization, or merely
|
||||
included in the output.
|
||||
* [CRD]s - custom resource definition files, to allow use
|
||||
of _custom_ resources in the _resources_ list.
|
||||
Not an actual operand - but allows the use of new operands.
|
||||
Data files like resource YAML files, or text files
|
||||
containing _name=value_ pairs intended for a ConfigMap
|
||||
or Secret, or files representing a patch to be used in
|
||||
a patch transformation, must live _within or below_ the
|
||||
root, and as such are specified via _relative
|
||||
paths_ exclusively.
|
||||
|
||||
* Generators, for creating more resources
|
||||
(configmaps and secrets) which can then be
|
||||
customized.
|
||||
A special flag (in v2.1), `--load_restrictions none`,
|
||||
is provided to relax this security feature, to, say,
|
||||
allow a patch file to be shared by more than one
|
||||
kustomization.
|
||||
|
||||
Other kustomizations (other directories containing a
|
||||
`kustomization.yaml` file) may be referred to by URL, by
|
||||
absolute path, or by relative path.
|
||||
|
||||
If kustomization __A__ depends on kustomization __B__, then
|
||||
|
||||
* __B__ may not _contain_ __A__.
|
||||
* __B__ may not _depend on_ __A__, even transitively.
|
||||
|
||||
__A__ may contain __B__, but in this case it might be
|
||||
simplest to have __A__ directly depend on __B__'s
|
||||
resources and eliminate __B__'s kustomization.yaml file
|
||||
(i.e. absorb __B__ into __A__).
|
||||
|
||||
Conventionally, __B__ is in a directory that's sibling
|
||||
to __A__, or __B__ is off in a completely independent
|
||||
git repository, referencable from any kustomization.
|
||||
|
||||
|
||||
A common layout is
|
||||
|
||||
> ```
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── dev
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── patch.yaml
|
||||
> ├── prod
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── patch.yaml
|
||||
> └── staging
|
||||
> ├── kustomization.yaml
|
||||
> └── patch.yaml
|
||||
> ```
|
||||
|
||||
The three roots `dev`, `prod` and `staging`
|
||||
(presumably) all refer to the `base` root. One would
|
||||
have to inspect the `kustomization.yaml` files to be
|
||||
sure.
|
||||
|
||||
## kubernetes
|
||||
|
||||
@@ -189,14 +270,14 @@ more than one version).
|
||||
|
||||
## kustomize
|
||||
|
||||
_kustomize_ is a command line tool supporting template-free
|
||||
customization of declarative configuration targetted to
|
||||
k8s-style objects.
|
||||
_kustomize_ is a command line tool supporting
|
||||
template-free, structured customization of declarative
|
||||
configuration targetted to k8s-style objects.
|
||||
|
||||
_Targetted to k8s means_ that kustomize may need some
|
||||
limited understanding of API resources, k8s concepts
|
||||
like names, labels, namespaces, etc. and the semantics
|
||||
of resource patching.
|
||||
_Targetted to k8s means_ that kustomize has some
|
||||
understanding of API resources, k8s concepts like
|
||||
names, labels, namespaces, etc. and the semantics of
|
||||
resource patching.
|
||||
|
||||
kustomize is an implementation of [DAM].
|
||||
|
||||
@@ -226,14 +307,13 @@ own [overlays] to do further customization.
|
||||
|
||||
## overlay
|
||||
|
||||
An _overlay_ is a [target] that modifies (and thus
|
||||
depends on) another target.
|
||||
An _overlay_ is a kustomization that depends on
|
||||
another kustomization.
|
||||
|
||||
The [kustomization] in an overlay refers to (via file
|
||||
path, URI or other method) some other kustomization,
|
||||
known as its [base].
|
||||
The [kustomizations] an overlay refers to (via file
|
||||
path, URI or other method) are called [bases].
|
||||
|
||||
An overlay is unusable without its base.
|
||||
An overlay is unusable without its bases.
|
||||
|
||||
An overlay may act as a base to another overlay.
|
||||
|
||||
@@ -245,7 +325,7 @@ _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.
|
||||
source used in a ConfigMap, etc.
|
||||
|
||||
One configures a cluster like this:
|
||||
|
||||
@@ -260,6 +340,7 @@ One configures a cluster like this:
|
||||
Usage of the base is implicit - the overlay's
|
||||
kustomization points to the base.
|
||||
|
||||
See also [root].
|
||||
|
||||
## package
|
||||
|
||||
@@ -290,11 +371,11 @@ value, e.g. an image tag.
|
||||
|
||||
By default, an SMP _replaces_ values. This
|
||||
usually desired when the target value is a simple
|
||||
string, but may not be desired when the target
|
||||
string, but may not be desired when the target
|
||||
value is a list.
|
||||
|
||||
To change this
|
||||
default behavior, add a _directive_. Recognized
|
||||
To change this
|
||||
default behavior, add a _directive_. Recognized
|
||||
directives include _replace_ (the default), _merge_
|
||||
(avoid replacing a list), _delete_ and a few more
|
||||
(see [these notes][strategic-merge]).
|
||||
@@ -318,6 +399,14 @@ A _patchJson6902_ can do almost everything a
|
||||
_patchStrategicMerge_ can do, but with a briefer
|
||||
syntax. See this [example][patchExampleJson6902].
|
||||
|
||||
## plugin
|
||||
|
||||
A chunk of code used by kustomize, but not necessarily
|
||||
compiled into kustomize, to generate and/or transform a
|
||||
kubernetes resource as part of a kustomization.
|
||||
|
||||
Details [here](plugins.md).
|
||||
|
||||
## resource
|
||||
|
||||
A _resource_ in the context of a REST-ful API is the
|
||||
@@ -325,15 +414,19 @@ target object of an HTTP operation like _GET_, _PUT_ or
|
||||
_POST_. k8s offers a REST-ful API surface to interact
|
||||
with clients.
|
||||
|
||||
A _resource_, in the context of kustomization file,
|
||||
is a path to a [YAML] or [JSON] file describing
|
||||
a k8s API object, like a Deployment or a
|
||||
ConfigmMap.
|
||||
A _resource_, in the context of a kustomization, is a
|
||||
[root] relative path to a [YAML] or [JSON] file
|
||||
describing a k8s API object, like a Deployment or a
|
||||
ConfigMap, or it's a path to a kustomization, or a URL
|
||||
that resolves to a kustomization.
|
||||
|
||||
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.
|
||||
|
||||
## root
|
||||
|
||||
See [kustomization root][root].
|
||||
|
||||
## sub-target / sub-application / sub-package
|
||||
|
||||
@@ -348,14 +441,19 @@ The _target_ is the argument to `kustomize build`, e.g.:
|
||||
> kustomize build $target
|
||||
> ```
|
||||
|
||||
`$target` must be a path or a url to a directory that
|
||||
immediately contains a [kustomization].
|
||||
`$target` must be a path or a url to a [kustomization].
|
||||
|
||||
The target contains, or refers to, all the information
|
||||
needed to create customized resources to send to the
|
||||
[apply] operation.
|
||||
|
||||
A target is a [base] or an [overlay].
|
||||
A target can be a [base] or an [overlay].
|
||||
|
||||
## transformer
|
||||
|
||||
A transformer can modify a resource, or merely
|
||||
visit it and collect information about it in the
|
||||
course of a `kustomize build`.
|
||||
|
||||
## variant
|
||||
|
||||
|
||||
54
docs/howtowindows.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# How To Windows
|
||||
|
||||
This is the PowerShell script to run all go tests for Kustomize on a windows based platform which mimics /build/pre-commit.sh
|
||||
|
||||
## Pre-Reqs:
|
||||
- (obviously) PowerShell installed
|
||||
- PowerShell Core is supported
|
||||
- go installed
|
||||
- golangci-lint installed
|
||||
- mdrip installed
|
||||
|
||||
This script should output to the current console and return an exit code if all tests are successful(0) or any failed(1).
|
||||
|
||||
### If you are tryin to run these tests locally you can follow these instructions.
|
||||
|
||||
Assume:
|
||||
- Running a stock Windows 10 system
|
||||
- Local Admin rights.
|
||||
- You can open [PowerShell as administrator](http://lmgtfy.com/?iie=1&q=How+to+open+powershell+as+administrator)
|
||||
- You should be knowledgeable enough to pull source for packages into your GO ```src``` directory
|
||||
- Yes, this means you also need to know a bit about **git** usually
|
||||
|
||||
|
||||
#### Step 1 - Install Go
|
||||
- [Install Go](https://golang.org/dl/) - please use the msi
|
||||
- If you use chocolatey - it's using the zip not msi and assumptions on where go is located are made for you.
|
||||
#### Step 2 - Install Go Packages
|
||||
- Open new PowerShell Administrative window
|
||||
- Install golangci-lint
|
||||
- ```go get -u github.com/golangci/golangci-lint/cmd/golangci-lint```
|
||||
- Install mdrip
|
||||
- ```go get github.com/monopole/mdrip```
|
||||
|
||||
You should now be able to issue these commands and see comparable responses
|
||||
|
||||
```
|
||||
C:\...> golangci-lint --help
|
||||
Smart, fast linters runner. Run it in cloud for every GitHub pull request on https://golangci.com
|
||||
...
|
||||
|
||||
C:\...> mdrip --help
|
||||
Usage: C:\_go\bin\mdrip.exe {fileName}...
|
||||
...
|
||||
```
|
||||
|
||||
#### Step 3 - Get Source and Test
|
||||
- In your GoRoot src
|
||||
- ```Example: C:\_go\src```
|
||||
- Navigate to the Kustomize `travis` directory
|
||||
- ```Example: C:\_go\src\sigs.k8s.io\kustomize\travis```
|
||||
- Now Execute:
|
||||
- ```.\Invoke-PreCommit.ps1```
|
||||
|
||||
This should run all pre-commit tests thus defined in the script.
|
||||
BIN
docs/images/abandonedTrainingWheels.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
BIN
docs/images/goModules.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
BIN
docs/images/plugins.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
docs/images/pruning.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
docs/images/sorted.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
189
docs/inventory_object.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# inventory directive in kustomization.yaml
|
||||
|
||||
New in v2.1.0, a kustomization file may have an `inventory` field:
|
||||
```yaml
|
||||
inventory:
|
||||
type: ConfigMap
|
||||
configMap:
|
||||
name: prune-cm-name
|
||||
namespace: some-namespace
|
||||
```
|
||||
|
||||
### Motivation
|
||||
|
||||
If present, `kustomize build` will make an _inventory_ object,
|
||||
which could be a ConfigMap, or an App (to be added),
|
||||
which can be consumed by a client such as those under development in
|
||||
[cli-experimental](https://github.com/kubernetes-sigs/cli-experimental).
|
||||
|
||||
The client can recognize this object by name and use it to do a better job
|
||||
with actions like `apply`, `prune` and `delete`.
|
||||
|
||||
|
||||
### Implementation
|
||||
|
||||
The _inventory_ ConfigMap contains two special annotations:
|
||||
|
||||
- kustomize.config.k8s.io/Inventory
|
||||
The value of this annotation is the JSON blob
|
||||
for an Inventory object. The Inventory is a
|
||||
struct that contains following information
|
||||
- all objects within this kustomization target
|
||||
- all objects that reference within this kustomization target
|
||||
|
||||
Here is an example of an Inventory object
|
||||
```json
|
||||
{
|
||||
"current":
|
||||
{
|
||||
"apps_v1_Deployment|default|mysql":null,
|
||||
"~G_v1_Secret|default|pass-dfg7h97cf6":
|
||||
[
|
||||
{
|
||||
"group":"apps",
|
||||
"version":"v1",
|
||||
"kind":"Deployment",
|
||||
"name":"mysql",
|
||||
"namespace":"default"
|
||||
}
|
||||
],
|
||||
"~G_v1_Service|default|mysql":null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- kustomize.config.k8s.io/InventoryHash
|
||||
The value of this annotation is a hash that is
|
||||
computed from the list of items in the Inventory
|
||||
|
||||
Basically, this inventory object acts a record of objects that are applied as a group.
|
||||
This object can be consumed by a client such as
|
||||
[cli-experimental](https://github.com/kubernetes-sigs/cli-experimental).
|
||||
The client can recognize the inventory annotations and take proper actions
|
||||
when running apply, prune and delete.
|
||||
|
||||
### Example
|
||||
Take following `kustomization.yaml` as an example
|
||||
```yaml
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
|
||||
|
||||
secretGenerator:
|
||||
- name: pass
|
||||
literals:
|
||||
- password=secret
|
||||
|
||||
inventory:
|
||||
type: ConfigMap
|
||||
configMap:
|
||||
name: root-cm
|
||||
namespace: default
|
||||
|
||||
namespace: default
|
||||
```
|
||||
|
||||
where the `deployment.yaml` is
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
revisionHistoryLimit: 2
|
||||
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: pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
volumeMounts:
|
||||
- name: mysql-persistent-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: {}
|
||||
```
|
||||
|
||||
and the `service.yaml` is
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
```
|
||||
|
||||
Running `kustomize build` gives 4 objects.
|
||||
Besides the Deployment `mysql`, the Service `mysql`,
|
||||
and the Secret `pass`, the output also contains a
|
||||
ConfigMap object as
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
kustomize.config.k8s.io/Inventory: '{"current":{"apps_v1_Deployment|default|mysql":null,"~G_v1_Secret|default|pass-dfg7h97cf6":[{"group":"apps","version":"v1","kind":"Deployment","name":"mysql","namespace":"default"}],"~G_v1_Service|default|mysql":null}}'
|
||||
kustomize.config.k8s.io/InventoryHash: 7mgt867b75
|
||||
name: haha
|
||||
namespace: default
|
||||
```
|
||||
|
||||
It is clear that this ConfigMap contains an `Inventory` annotation.
|
||||
|
||||
|
||||
### Hash
|
||||
Note that in the ConfigMap generated from `inventory` field, there is a hash
|
||||
`b965tb9c7d`. It is the value for annotation `kustomize.config.k8s.io/InventoryHash`.
|
||||
|
||||
This hash is computed by hashing all the keys in data field, which is the following list
|
||||
in this example.
|
||||
```yaml
|
||||
apps_v1_Deployment|default|mysql
|
||||
~G_v1_Secret|default|pass-dfg7h97cf6
|
||||
~G_v1_Service|default|mysql
|
||||
```
|
||||
When any object is added or removed from the kustomzation target, the hash changes. Thus by simply comparing the hash in the inventory objects, one can determine if the list of objects has changed.
|
||||
|
||||
|
||||
### How prune works
|
||||
In [cli-experimental](https://github.com/kubernetes-sigs/cli-experimental), there are different subcommands, `apply` and `prune`. Both are able to recognize an _inventory_ object and looking for its existing object on the cluster.
|
||||
|
||||
the `apply` command
|
||||
recognizes the _inventory_ object by the annotation `kustomize.config.k8s.io/InventoryHash`. It then compares the current hash with the hash for the same object in the cluster. Since the hash reflects if there is any object added or removed, `apply` takes different actions correspondingly.
|
||||
- When there is no existing _inventory_ object in the cluster, apply creates the inventory object.
|
||||
- When the current hash is the same as the one in cluster, apply doesn't change the existing object in the cluster.
|
||||
- when the current hash is different, apply merges the inventory annotation of the existing object in the cluster and the incoming object. The hash is updated to the latest hash.
|
||||
|
||||
|
||||
The `prune` command parses the value of `kustomize.config.k8s.io/Inventory` of the existing _inventory_ object and computes two sets of objects based on the parsed data.
|
||||
To be simple,
|
||||
- The items in `Inventory.Current` will be kept
|
||||
- The items in `Inventory.Previous` will be pruned when they
|
||||
are not needed.
|
||||
|
||||
@@ -1,316 +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.
|
||||
#
|
||||
# ----------------------------------------------------
|
||||
# Example kustomization.yaml content.
|
||||
#
|
||||
# This file declares the customization provided by
|
||||
# the kustomize program.
|
||||
#
|
||||
# Since customization is, by definition, _custom_,
|
||||
# there are no sensible default values for the fields
|
||||
# in this file.
|
||||
#
|
||||
# The field values used below are merely examples, not
|
||||
# to be copied literally. The values won't work if
|
||||
# they happen to be references to external files that
|
||||
# don't exist.
|
||||
#
|
||||
# In practice, fields with no value should simply be
|
||||
# omitted from kustomization.yaml to reduce the content
|
||||
# visible in configuration reviews.
|
||||
# ----------------------------------------------------
|
||||
# apiVersion and kind of Kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
# 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
|
||||
# "wordpress" becomes "alices-wordpress".
|
||||
namePrefix: alices-
|
||||
|
||||
# Value of this field is appended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "wordpress-v2".
|
||||
# The suffix is appended before content hash
|
||||
# if resource type is ConfigMap or Secret.
|
||||
nameSuffix: -v2
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
|
||||
# Annotations (non-identifying metadata)
|
||||
# to add to all resources. Like labels,
|
||||
# these are key value pairs.
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
|
||||
# Each entry in this list must resolve to an existing
|
||||
# resource definition in YAML. These are the resource
|
||||
# files that kustomize reads, modifies and emits as a
|
||||
# YAML string, with resources separated by document
|
||||
# markers ("---").
|
||||
resources:
|
||||
- some-service.yaml
|
||||
- sub-dir/some-deployment.yaml
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one ConfigMap resource (it's a generator of n maps).
|
||||
# The example below creates two ConfigMaps. One with the
|
||||
# names and contents of the given files, the other with
|
||||
# key/value as data.
|
||||
# Each configMapGenerator item accepts a parameter of
|
||||
# behavior: [create|replace|merge]. This allows an overlay to modify or
|
||||
# replace an existing configMap from the parent.
|
||||
configMapGenerator:
|
||||
- name: myJavaServerProps
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
- name: myJavaServerEnvVars
|
||||
literals:
|
||||
- JAVA_HOME=/opt/java/jdk
|
||||
- JAVA_TOOL_OPTIONS=-agentlib:hprof
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one Secret resource (it's a generator of n secrets).
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: app-tls-namespaced
|
||||
# you can define a namespace to generate secret in, defaults to: "default"
|
||||
namespace: apps
|
||||
files:
|
||||
- tls.crt=catsecret/tls.cert
|
||||
- tls.key=secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: env_file_secret
|
||||
# env is a path to a file to read lines of key=val
|
||||
# you can only specify one env file per secret.
|
||||
env: env.txt
|
||||
type: Opaque
|
||||
|
||||
# generatorOptions modify behavior of all ConfigMap and Secret generators
|
||||
generatorOptions:
|
||||
# labels to add to all generated resources
|
||||
labels:
|
||||
kustomize.generated.resources: somevalue
|
||||
# annotations to add to all generated resources
|
||||
annotations:
|
||||
kustomize.generated.resource: somevalue
|
||||
# disableNameSuffixHash is true disables the default behavior of adding a
|
||||
# suffix to the names of generated resources that is a hash of
|
||||
# the resource contents.
|
||||
disableNameSuffixHash: true
|
||||
|
||||
# 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_.
|
||||
#
|
||||
# Typical use case: a dev, staging and production
|
||||
# environment that are mostly identical but differing
|
||||
# crucial ways (image tags, a few server arguments,
|
||||
# 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.
|
||||
#
|
||||
# The names in these (possibly partial) resource files
|
||||
# must match names already loaded via the `resources`
|
||||
# field or via `resources` loaded transitively via the
|
||||
# `bases` entries. These entries are used to _patch_
|
||||
# (modify) the known resources.
|
||||
#
|
||||
# Small patches that do one thing are best, e.g. modify
|
||||
# a memory request/limit, change an env var in a
|
||||
# ConfigMap, etc. Small patches are easy to review and
|
||||
# easy to mix together in overlays.
|
||||
patchesStrategicMerge:
|
||||
- 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, nameSuffix, or hashing
|
||||
# The name reference for this ConfigMap object in CRD object need to be
|
||||
# updated with namePrefix, nameSuffix, or hashing in the same way.
|
||||
crds:
|
||||
- crds/typeA.yaml
|
||||
- crds/typeB.yaml
|
||||
|
||||
# Vars are used to capture text from one resource's field
|
||||
# and insert that text elsewhere.
|
||||
#
|
||||
# For example, suppose someone specifies the name of a k8s Service
|
||||
# object in a container's command line, and the name of a
|
||||
# k8s Secret object in a container's environment variable,
|
||||
# so that the following would work:
|
||||
# ```
|
||||
# containers:
|
||||
# - image: myimage
|
||||
# command: ["start", "--host", "$(MY_SERVICE_NAME)"]
|
||||
# env:
|
||||
# - name: SECRET_TOKEN
|
||||
# value: $(SOME_SECRET_NAME)
|
||||
# ```
|
||||
#
|
||||
# To do so, add an entry to `vars:` as follows:
|
||||
#
|
||||
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
|
||||
#
|
||||
# A var is a tuple of variable name, object reference and field
|
||||
# reference within that object. That's where the text is found.
|
||||
#
|
||||
# The field reference is optional; it defaults to `metadata.name`,
|
||||
# a normal default, since kustomize is used to generate or
|
||||
# modify the names of resources.
|
||||
#
|
||||
# At time of writing, only string type fields are supported.
|
||||
# No ints, bools, arrays etc. It's not possible to, say,
|
||||
# extract the name of the image in container number 2 of
|
||||
# some pod template.
|
||||
#
|
||||
# A variable reference, i.e. the string '$(FOO)', can only
|
||||
# be placed in particular fields of particular objects as
|
||||
# specified by kustomize's configuration data.
|
||||
#
|
||||
# The default config data for vars is at
|
||||
# https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go
|
||||
# Long story short, the default targets are all
|
||||
# container command args and env value fields.
|
||||
#
|
||||
# Vars should _not_ be used for inserting names in places
|
||||
# where kustomize is already handling that job. E.g.,
|
||||
# a Deployment may reference a ConfigMap by name, and
|
||||
# if kustomize changes the name of a ConfigMap, it knows
|
||||
# to change the name reference in the Deployment.
|
||||
|
||||
|
||||
# Images modify the name, tags and/or digest for images without creating patches.
|
||||
# E.g. Given this kubernetes Deployment fragment:
|
||||
# ```
|
||||
# containers:
|
||||
# - name: mypostgresdb
|
||||
# image: postgres:8
|
||||
# - name: nginxapp
|
||||
# image: nginx:1.7.9
|
||||
# - name: myapp
|
||||
# image: my-demo-app:latest
|
||||
# - name: alpine-app
|
||||
# image: alpine:3.7
|
||||
#```
|
||||
# one can change the `image` in the following ways:
|
||||
#
|
||||
# - `postgres:8` to `my-registry/my-postgres:v1`,
|
||||
# - nginx tag `1.7.9` to `1.8.0`,
|
||||
# - image name `my-demo-app` to `my-app`,
|
||||
# - alpine's tag `3.7` to a digest value
|
||||
#
|
||||
# all with the following *kustomization*:
|
||||
|
||||
images:
|
||||
- name: postgres
|
||||
newName: my-registry/my-postgres
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: my-demo-app
|
||||
newName: my-app
|
||||
- name: alpine
|
||||
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
||||
348
docs/plugins.md
Normal file
@@ -0,0 +1,348 @@
|
||||
# kustomize plugins
|
||||
|
||||
Kustomize offers a plugin framework allowing
|
||||
people to write their own resource _generators_
|
||||
and _transformers_.
|
||||
|
||||
[generator options]: ../examples/generatorOptions.md
|
||||
[transformer configs]: ../examples/transformerconfigs
|
||||
|
||||
Write a plugin when changing [generator options]
|
||||
or [transformer configs] doesn't meet your needs.
|
||||
|
||||
[12-factor]: https://12factor.net
|
||||
|
||||
* A _generator_ plugin could be a helm chart
|
||||
inflator, or a plugin that emits all the
|
||||
components (deployment, service, scaler,
|
||||
ingress, etc.) needed by someone's [12-factor]
|
||||
application, based on a smaller number of free
|
||||
variables.
|
||||
|
||||
* A _transformer_ plugin might perform special
|
||||
container command line edits, or any other
|
||||
transformation that exceeds the power of the
|
||||
builtin transformations (`namePrefix`,
|
||||
`commonLabels`, etc.).
|
||||
|
||||
## Specification in `kustomization.yaml`
|
||||
|
||||
Start by adding a `generators` and/or `transformers`
|
||||
field to your kustomization.
|
||||
|
||||
Each field accepts a string list:
|
||||
|
||||
> ```
|
||||
> generators:
|
||||
> - relative/path/to/some/file.yaml
|
||||
> - relative/path/to/some/kustomization
|
||||
> - /absolute/path/to/some/kustomization
|
||||
> - https://github.com/org/repo/some/kustomization
|
||||
>
|
||||
> transformers:
|
||||
> - {as above}
|
||||
> ```
|
||||
|
||||
This is exactly like the syntax of the `resources`
|
||||
field.
|
||||
|
||||
The value of each entry in a `resources`,
|
||||
`generators` or `transformers` list must be a
|
||||
relative path to a YAML file, or a path or URL
|
||||
to a [kustomization].
|
||||
|
||||
[kustomization]: glossary.md#kustomization
|
||||
|
||||
In the former case the YAML is read from disk directly,
|
||||
and in the latter case a kustomization is performed,
|
||||
and its YAML output is merged with the YAML read
|
||||
directly from files. The net result in all three cases
|
||||
is a set of YAML objects.
|
||||
|
||||
Each object resulting from a `generators` or
|
||||
`transformers` field is now further interpreted by
|
||||
kustomize as a _plugin configuration_ object.
|
||||
|
||||
## Configuration
|
||||
|
||||
A kustomization file could have the following lines:
|
||||
|
||||
```
|
||||
generators:
|
||||
- chartInflator.yaml
|
||||
```
|
||||
|
||||
Given this, the kustomization process would expect to
|
||||
find a file called `chartInflator.yaml` in the
|
||||
kustomization [root](glossary.md#kustomization-root).
|
||||
|
||||
This is the _plugin's configuration file_.
|
||||
|
||||
The file `chartInflator.yaml` could contain:
|
||||
|
||||
```
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: ChartInflator
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
chartName: minecraft
|
||||
```
|
||||
|
||||
__The `apiVersion` and `kind` fields are
|
||||
used to locate the plugin.__
|
||||
|
||||
[k8s object]: glossary.md#kubernetes-style-object
|
||||
|
||||
> Thus, these fields are required. They are also
|
||||
> required because a kustomize plugin
|
||||
> configuration object is also a [k8s object].
|
||||
|
||||
To get the plugin ready to generator or transform,
|
||||
it is given the entire contents of the
|
||||
configuration file.
|
||||
|
||||
[NameTransformer]: ../plugin/builtin/prefixsuffixtransformer/PrefixSuffixTransformer_test.go
|
||||
[ChartInflator]: ../plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
|
||||
[plugins]: ../plugin/builtin
|
||||
|
||||
For more examples of plugin configuration YAML,
|
||||
browse the unit tests below the [plugins] root,
|
||||
e.g. the tests for [ChartInflator] or
|
||||
[NameTransformer].
|
||||
|
||||
|
||||
## Placement
|
||||
|
||||
Each plugin gets its own dedicated directory named
|
||||
|
||||
```
|
||||
$XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
```
|
||||
|
||||
The default value of `XDG_CONFIG_HOME` is
|
||||
`$HOME/.config`.
|
||||
|
||||
The one-plugin-per-directory requirement eases
|
||||
creation of a plugin tarball (source, test, plugin
|
||||
data files, etc.) for sharing.
|
||||
|
||||
In the case of a [Go plugin](#go-plugins), it also
|
||||
allows one to provide a `go.mod` file for the
|
||||
single plugin, easing resolution of package
|
||||
version dependency skew.
|
||||
|
||||
When loading, kustomize will first look for an
|
||||
_executable_ file called
|
||||
|
||||
```
|
||||
$XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})/${kind}
|
||||
```
|
||||
|
||||
If this file is not found or is not executable,
|
||||
kustomize will look for a file called `${kind}.so`
|
||||
in the same directory and attempt to load it as a
|
||||
[Go plugin](#go-plugins).
|
||||
|
||||
If both checks fail, the plugin load fails the overall
|
||||
`kustomize build`.
|
||||
|
||||
## Execution
|
||||
|
||||
Plugins are only used during a run of the
|
||||
`kustomize build` command.
|
||||
|
||||
Generator plugins are run after processing the
|
||||
`resources` field (which itself is in some sense a
|
||||
generator in that it emits resources for further
|
||||
processing).
|
||||
|
||||
The full set of resources is then passed into the
|
||||
transformation pipeline, wherein builtin
|
||||
transformations like `namePrefix` and
|
||||
`commonLabel` are applied (if they were specified
|
||||
in the kustomization file), followed by the
|
||||
user-specified transformers in the `transformers`
|
||||
field.
|
||||
|
||||
The specified order of transformers in the
|
||||
`transformers` field should be respected, as
|
||||
transformers cannot be expected to be commutative.
|
||||
|
||||
A `kustomize build` that tries to use plugins but
|
||||
omits the flag
|
||||
|
||||
> `--enable_alpha_plugins`
|
||||
|
||||
will fail with a warning about plugin use.
|
||||
|
||||
Flag use is an opt-in acknowledging the absence of
|
||||
plugin provenance. It's meant to give pause to
|
||||
someone who blindly downloads a kustomization from
|
||||
the internet and attempts to run it, without
|
||||
realizing that it might attempt to run 3rd party
|
||||
code in plugin form. The plugin would have to be
|
||||
installed already, but nevertheless the flag is a
|
||||
reminder.
|
||||
|
||||
|
||||
## Writing plugins
|
||||
|
||||
### Exec plugins
|
||||
|
||||
A _exec plugin_ is any executable that accepts a
|
||||
single argument on its command line - the name of
|
||||
a YAML file containing its configuration (the file name
|
||||
provided in the kustomization file).
|
||||
|
||||
> TODO: more restrictions on plugin to allow the same exec
|
||||
> plugin to be specified in a config under both the
|
||||
> `generators` and `transformers` fields.
|
||||
> - first arg could be the fixed string
|
||||
> `generate` or `transform`,
|
||||
> (the name of the configuration file moves to
|
||||
> the 2nd arg), or
|
||||
> - by default an exec plugin behaves as a tranformer
|
||||
> unless a flag `-g` is provided, switching the
|
||||
> exec plugin to behave as a generator.
|
||||
|
||||
[helm chart inflator]: ../plugin/someteam.example.com/v1/chartinflator
|
||||
[bashed config map]: ../plugin/someteam.example.com/v1/bashedconfigmap
|
||||
[sed transformer]: ../plugin/someteam.example.com/v1/sedtransformer
|
||||
|
||||
#### Examples
|
||||
|
||||
* [helm chart inflator] - A generator that inflates a helm chart.
|
||||
* [bashed config map] - Super simple configMap generation from bash.
|
||||
* [sed transformer] - Define your unstructured edits using a
|
||||
plugin like this one.
|
||||
|
||||
|
||||
A generator plugin accepts nothing on `stdin`, but emits
|
||||
generated resources to `stdout`.
|
||||
|
||||
A transformer plugin accepts resource YAML on `stdin`,
|
||||
and emits those resources, presumably transformed, to
|
||||
`stdout`.
|
||||
|
||||
kustomize uses an exec plugin adapter to provide
|
||||
marshalled resources on `stdin` and capture
|
||||
`stdout` for further processing.
|
||||
|
||||
### Go plugins
|
||||
|
||||
[Go plugin]: https://golang.org/pkg/plugin/
|
||||
|
||||
A [Go plugin] for kustomize looks like this:
|
||||
|
||||
> ```
|
||||
> package main
|
||||
>
|
||||
> import (
|
||||
> "sigs.k8s.io/kustomize/pkg/ifc"
|
||||
> "sigs.k8s.io/kustomize/pkg/resmap"
|
||||
> ...
|
||||
> )
|
||||
>
|
||||
> type plugin struct {...}
|
||||
>
|
||||
> var KustomizePlugin plugin
|
||||
>
|
||||
> func (p *plugin) Config(
|
||||
> ldr ifc.Loader,
|
||||
> rf *resmap.Factory,
|
||||
> c []byte) error {...}
|
||||
>
|
||||
> func (p *plugin) Generate() (resmap.ResMap, error) {...}
|
||||
>
|
||||
> func (p *plugin) Transform(m resmap.ResMap) error {...}
|
||||
> ```
|
||||
|
||||
Use of the identifiers `plugin`, `KustomizePlugin`
|
||||
and implementation of the method signature
|
||||
`Config` is required.
|
||||
|
||||
Implementing the `Generator` or `Transformer`
|
||||
method allows (respectively) the plugin's config
|
||||
file to be added to the `generators` or
|
||||
`transformers` field in the kustomization file.
|
||||
Do one or the other or both as desired.
|
||||
|
||||
[secret generator]: ../plugin/someteam.example.com/v1/secretsfromdatabase
|
||||
[service generator]: ../plugin/someteam.example.com/v1/someservicegenerator
|
||||
[string prefixer]: ../plugin/someteam.example.com/v1/stringprefixer
|
||||
[date prefixer]: ../plugin/someteam.example.com/v1/dateprefixer
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
* [secret generator] - Generate secrets from a database.
|
||||
* [service generator] - Generate a service from a name and port argument.
|
||||
* [string prefixer] - uses the value in `metadata/name` as the prefix.
|
||||
This particular example exists to show how a plugin can
|
||||
transform the behavior of a plugin. See the
|
||||
`TestTransformedTransformers` test in the `target` package.
|
||||
* [date prefixer] - prefix the current date to resource names, a simple
|
||||
example used to modify the string prefixer plugin just mentioned.
|
||||
* All the builtin plugins [here](../plugin/builtin).
|
||||
User authored plugins are
|
||||
on the same footing as builtin operations.
|
||||
|
||||
A plugin can be both a generator and a
|
||||
transformer. The `Generate` method will run along
|
||||
with all the other generators before the
|
||||
`Transform` method runs.
|
||||
|
||||
Here's a build command that sensibly assumes the
|
||||
plugin source code sits in the directory where
|
||||
kustomize expects to find `.so` files:
|
||||
|
||||
```
|
||||
d=$XDG_CONFIG_HOME/kustomize/plugin\
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
|
||||
go build -buildmode plugin \
|
||||
-o $d/${kind}.so $d/${kind}.go
|
||||
```
|
||||
|
||||
#### Caveats
|
||||
|
||||
Go plugins allow kustomize extensions that run
|
||||
without the cost marshalling/unmarshalling all
|
||||
resource data to/from a subprocess for each plugin
|
||||
run.
|
||||
|
||||
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
|
||||
Go plugins work as [defined][Go plugin], but fall
|
||||
short of common notions associated with the word
|
||||
_plugin_. Go plugin compilation creates an [ELF]
|
||||
formatted `.so` file, which by definition has no
|
||||
information about the provenance of the object
|
||||
code. Skew between the compilation conditions
|
||||
(versions of package dependencies, `GOOS`,
|
||||
`GOARCH`) of the main program ELF and the plugin
|
||||
ELF will cause plugin load failure.
|
||||
|
||||
Exec plugins also lack provenance, but won't
|
||||
complain about compilation skew.
|
||||
|
||||
In either case, a sensible way to share a plugin
|
||||
is as a tar file of source code, tests and
|
||||
associated data, unpackable under
|
||||
`$XDG_CONFIG_HOME/kustomize/plugin` (exactly where
|
||||
one would develop a plugin).
|
||||
|
||||
[Go modules]: https://github.com/golang/go/wiki/Modules
|
||||
|
||||
In the case of a Go plugin, an end user accepting
|
||||
a shared plugin must compile both kustomize and
|
||||
the plugin. Tooling could be built to make Go
|
||||
_plugin sharing_ easier, but this requires some
|
||||
critical mass of _plugin authoring_, which in turn
|
||||
is hampered by confusion around sharing.
|
||||
[Go modules], once they are more widely adopted,
|
||||
will solve one of the biggest plugin sharing
|
||||
difficulties - ambiguous plugin vs host
|
||||
dependencies.
|
||||
18
docs/v_1.0.1.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# kustomize 1.0.1
|
||||
|
||||
Initial release after move from
|
||||
[github.com/kubernetes/kubectl]
|
||||
to [github.com/kubernetes-sigs/kustomize].
|
||||
|
||||
History
|
||||
|
||||
* May 2018: v1.0 after move to [github.com/kubernetes-sigs/kubectl]
|
||||
from [github.com/kubernetes/kubectl].
|
||||
Has kustomization file, bases, overlays, basic transforms.
|
||||
* Apr 2018: s/kinflate/kustomize/, s/manifest/kustomization/
|
||||
* Oct 2017: s/kexpand/kinflate/
|
||||
* Sep 2017: kexpand [starts](https://github.com/kubernetes/kubectl/pull/65)
|
||||
in [github.com/kubernetes/kubectl]
|
||||
* Aug 2018: [DAM] authored by Brian Grant
|
||||
|
||||
[DAM]: https://docs.google.com/document/d/1cLPGweVEYrVqQvBLJg6sxV-TrE5Rm2MNOBA_cxZP2WU
|
||||
131
docs/v_2.0.0.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# kustomize 2.0.0
|
||||
|
||||
[security concern]: https://docs.google.com/document/d/1FYgLVdq-siB_Cef9yuQBmit0PbrE8lsyTBdGI2eA2y8/edit
|
||||
|
||||
After security review, a field used in secret
|
||||
generation (see below) was removed from the
|
||||
definition of a kustomization file with no
|
||||
mechanism to convert it to a new form. Also, the
|
||||
set of files accessible from a kustomization file
|
||||
has been further constrained.
|
||||
|
||||
Per the [versioning policy](versioningPolicy.md),
|
||||
backward incompatible changes trigger an increment
|
||||
of the major version number, hence we go
|
||||
from 1.0.11 to 2.0.0. We're taking this major
|
||||
version increment opportunity to remove some
|
||||
already deprecated fields, and the code paths
|
||||
associated with them.
|
||||
|
||||
## Backward Incompatible Changes
|
||||
|
||||
### Kustomization Path Constraints
|
||||
|
||||
A kustomization file can specify paths to other
|
||||
files, including resources, patches, configmap
|
||||
generation data, secret generation data and
|
||||
bases. In the case of a base, the path can be a
|
||||
git URL instead.
|
||||
|
||||
In 1.x, these paths had to be relative to the
|
||||
current kustomization directory (the location of
|
||||
the kustomization file used in the `build`
|
||||
command).
|
||||
|
||||
In 2.0, bases can continue to specify, via
|
||||
relative paths, kustomizations outside the current
|
||||
kustomization directory. But non-base paths are
|
||||
constrained to terminate in or below the current
|
||||
kustomization directory. Further, bases specified
|
||||
via a git URL may not reference files outside of
|
||||
the directory used to clone the repository.
|
||||
|
||||
### Kustomization Field Removals
|
||||
|
||||
#### patches
|
||||
|
||||
`patches` was deprecated and replaced by
|
||||
`patchesStrategicMerge` when `patchesJson6902` was
|
||||
introduced. In Kustomize 2.0.0, `patches` is
|
||||
removed. Please use `patchesStrategicMerge`
|
||||
instead.
|
||||
|
||||
#### imageTags
|
||||
|
||||
`imageTags` is replaced by `images` since `images`
|
||||
can provide more features to change image names,
|
||||
registries, tags and digests.
|
||||
|
||||
#### secretGenerator/commands
|
||||
|
||||
`commands` is removed from SecretGenerator due to
|
||||
a [security concern]. One can use `files` or
|
||||
`literals`, similar to ConfigMapGenerator, to
|
||||
generate a secret.
|
||||
|
||||
```
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
```
|
||||
|
||||
## Compatible Changes (New Features)
|
||||
|
||||
As this release is triggered by a security change,
|
||||
there are no major new features to announce. A few
|
||||
things that are worth mentioning in this release
|
||||
are:
|
||||
|
||||
* More than _40_ issues closed since 1.0.11
|
||||
release (including many extensions to
|
||||
transformation rules).
|
||||
|
||||
* Users can run `kustomize edit fix` to migrate a
|
||||
kustomization file working with previous
|
||||
versions to one working with 2.0.0. For example,
|
||||
a kustomization.yaml with following content
|
||||
|
||||
```
|
||||
patches:
|
||||
- deployment-patch.yaml
|
||||
imageTags:
|
||||
- name: postgres
|
||||
newTag: v1
|
||||
```
|
||||
|
||||
will be converted to
|
||||
|
||||
```
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
patchesStrategicMerge:
|
||||
- deployment-patch.yaml
|
||||
images:
|
||||
- name: postgres
|
||||
newTag: v1
|
||||
```
|
||||
|
||||
* Kustomization filename
|
||||
|
||||
In previous versions, the name of a
|
||||
kustomization file had to be
|
||||
`kustomization.yaml`.
|
||||
Kustomize allows `kustomization.yaml`,
|
||||
`kustomization.yml` and
|
||||
`Kustomization`. In a directory, only one of
|
||||
those filenames is allowed. If there are more
|
||||
than one found, Kustomize will exit with an
|
||||
error. Please select the best filename for your
|
||||
use cases.
|
||||
|
||||
* Cancelled plans to deprecate applying prefix/suffix to namespace.
|
||||
The deprecation warning
|
||||
|
||||
```
|
||||
Adding nameprefix and namesuffix to Namespace resource will be deprecated in next release.
|
||||
```
|
||||
|
||||
was removed.
|
||||
242
docs/v_2.1.0.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# kustomize 2.1.0
|
||||
|
||||
|
||||
[Go modules]: https://github.com/golang/go/wiki/Modules
|
||||
[generator options]: ../examples/generatorOptions.md
|
||||
[imgModules]: images/goModules.png
|
||||
[imgPlugins]: images/plugins.png
|
||||
[imgPruning]: images/pruning.png
|
||||
[imgSorted]: images/sorted.png
|
||||
[imgWheels]: images/abandonedTrainingWheels.png
|
||||
[kustomization]: glossary.md#kustomization
|
||||
[_kustomization_]: glossary.md#kustomization
|
||||
[base]: glossary.md#base
|
||||
[bases]: glossary.md#base
|
||||
[_base_]: glossary.md#base
|
||||
[kustomize inventory object documentation]: inventory_object.md
|
||||
[kustomize plugin documentation]: plugins.md
|
||||
[root]: glossary.md#kustomization-root
|
||||
[transformer configs]: ../examples/transformerconfigs
|
||||
[v1.0.9]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v1.0.9
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[v2.1.0]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.1.0
|
||||
[versioning policy]: versioningPolicy.md
|
||||
|
||||
Go modules, resource ordering respected, generator and transformer plugins, eased
|
||||
loading restrictions, the notion of inventory, eased replica count modification.
|
||||
About ~90 issues closed since [v2.0.3] in ~400 commits.
|
||||
|
||||
## Go modules
|
||||
|
||||
![gopher with boxes][imgModules]
|
||||
|
||||
Kustomize now defines its dependencies in a top
|
||||
level `go.mod` file. This is the first step
|
||||
towards a package structure intentially exported
|
||||
as one or more [Go modules] for use in other
|
||||
programs (kubectl, kubebuilder, etc.) and in
|
||||
kustomize plugins (see below).
|
||||
|
||||
## Resource ordering
|
||||
|
||||
![sort order retained][imgSorted]
|
||||
|
||||
Kustomize now retains the depth-first order of
|
||||
resources as read, a frequently requested
|
||||
feature.
|
||||
|
||||
This means resource order can be controlled
|
||||
by editting kustomization files. This is
|
||||
also vital to applying user-defined
|
||||
transformations (plugins) in a particular
|
||||
order.
|
||||
|
||||
Nothing needs to be done to activate this;
|
||||
it happens automatically.
|
||||
|
||||
The `build` command now accepts a `--reorder`
|
||||
flag with values `legacy` and `none`,
|
||||
with a default value of `legacy`.
|
||||
|
||||
`legacy` means apply an ordering based on
|
||||
GVK, that currently emits `Namespace` objects
|
||||
first, and `ValidatingWebhookConfiguration`
|
||||
objects last. This means that despite
|
||||
automatic retention of load order, your
|
||||
`build` output won't change by default.
|
||||
|
||||
`none` means _don't_ reorder the resources before
|
||||
output. Specify this to see output order
|
||||
respect input order.
|
||||
|
||||
## Generator and transformer plugins
|
||||
|
||||
![kid putting knife in electrical outlet][imgPlugins]
|
||||
|
||||
Since the beginning (as `kinflate` back in Sep
|
||||
2017), kustomize has read or generated resources,
|
||||
applied a series of pipelined transformation to
|
||||
them, and emitted the result to `stdout`.
|
||||
|
||||
At that time, the only way to change the behavior
|
||||
of a generator (e.g. a secret generator), or
|
||||
change the behavior of a transformer (e.g. a name
|
||||
changer, or json patcher), was to modify source
|
||||
code and put out a release.
|
||||
|
||||
[v1.0.9] introduced [generator options] as a means
|
||||
to change the behavior of the only two generators
|
||||
available at the time - Secret and ConfigMap
|
||||
generators. It also introduced
|
||||
[transformer configs] as a way to fine tune the
|
||||
targets of transformations (e.g. to which fields
|
||||
_selectors_ should be added). Most of the feature
|
||||
requests for kustomize revolve around changing the
|
||||
behavior of the builtin generators and
|
||||
transformers.
|
||||
|
||||
[v2.1.0] adds an _alpha_ plugin framework, that
|
||||
encourages users to write their own generators or
|
||||
transformers, _declaring them as kubernetes
|
||||
objects just like everything else_, and apply them
|
||||
as part of the `kustomize build` process.
|
||||
|
||||
To inform the API exposed to plugins, and to
|
||||
confirm that the plugin framework can offer plugin
|
||||
authors the same capabilities as builtin
|
||||
operations, all the builtin generators and
|
||||
tranformers have been converted to plugin form
|
||||
(with one exceptions awaiting Go module
|
||||
refinements). This means that adding, say, a
|
||||
`secretGenerator` or `commonAnnotations` directive
|
||||
to your kustomization will (in [v2.1.0]) trigger
|
||||
execution of
|
||||
[code committed as a plugin](../plugin/builtin).
|
||||
|
||||
For more information, see the
|
||||
[kustomize plugin documentation].
|
||||
|
||||
## Remove load restrictions
|
||||
|
||||
![removed training wheels][imgWheels]
|
||||
|
||||
The following usage:
|
||||
|
||||
```
|
||||
kustomize build --load_restrictions none $target
|
||||
```
|
||||
|
||||
allows a `kustomization.yaml` file used in this
|
||||
build to refer to files outside its own directory
|
||||
(i.e. outside its [root]).
|
||||
|
||||
This is an opt-in to suppress a security feature
|
||||
that denies this precise behavior.
|
||||
|
||||
This feature should only be used to allow multiple
|
||||
overlays (e.g. prod, staging and dev) to share a
|
||||
patch file. To share _resources_, use a relative
|
||||
path or URL to a kustomization directory in the
|
||||
`resources` directive.
|
||||
|
||||
## Inventory generation for pruning
|
||||
|
||||
![pruning dead branches][imgPruning]
|
||||
|
||||
_Alpha_
|
||||
|
||||
Users can add an `inventory` stanza to their
|
||||
kustomization file, to add a special _inventory
|
||||
object_ to the `build` result.
|
||||
|
||||
This object applies to the cluster along with
|
||||
everything else in the build result and can be
|
||||
used by other clients to intelligently _prune_
|
||||
orphaned cluster resources.
|
||||
|
||||
For more information see the
|
||||
[kustomize inventory object documentation].
|
||||
|
||||
|
||||
## Field changes / deprecations
|
||||
|
||||
### `resources` expanded, `bases` deprecated
|
||||
|
||||
The `resources` field has been generalized; it now
|
||||
accepts what formerly could only be specified in
|
||||
the `bases` field.
|
||||
|
||||
This change was made to allow users fine control
|
||||
over resource processing order. With a distinct
|
||||
`bases` field, bases had to be loaded separately
|
||||
from resources as a group. Now, base loading may
|
||||
be interleaved as desired with the loading of
|
||||
resource files from the current
|
||||
directory. [Resource ordering](#resource-ordering)
|
||||
had to be respected before this feature could be
|
||||
introduced.
|
||||
|
||||
The `bases` field is now deprecated, and will be
|
||||
deleted in some future major release. Manage the
|
||||
deprecation simply moving the arguments of the
|
||||
`bases` field to the `resources` field in the
|
||||
desired order, e.g.
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - someResouceFile.yaml
|
||||
> - someOtherResourceFile.yaml
|
||||
> bases:
|
||||
> - ../../someBaseDir
|
||||
> ```
|
||||
|
||||
could become
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - someResouceFile.yaml
|
||||
> - ../../someBaseDir
|
||||
> - someOtherResourceFile.yaml
|
||||
> ```
|
||||
|
||||
The `kustomized edit fix` command will do this for
|
||||
you, though it will always put the bases at the
|
||||
end.
|
||||
|
||||
As an aside, the `resources`, `generators` and
|
||||
`transformers` fields now all accept the same
|
||||
argument format.
|
||||
|
||||
> Each field's argument is a _string list_,
|
||||
> where each entry is either a _resource_ (a
|
||||
> relative path to a YAML file) or a
|
||||
> [_kustomization_] (a path or URL
|
||||
> pointing to a directory with a kustomization
|
||||
> file). A kustomization directory used in this
|
||||
> context is called a [_base_].
|
||||
|
||||
The fact that the `generators` and `transformers`
|
||||
field accept [bases] and the fact that generator
|
||||
and transformer configuration objects are just
|
||||
normal k8s resources means that one can generate
|
||||
or transform a generator or a transformer (see
|
||||
[TestTransformerTransformers]).
|
||||
|
||||
[TestTransformerTransformers]: ../pkg/target/transformerplugin_test.go
|
||||
|
||||
### `replicas` field
|
||||
|
||||
The common task of patching a deployment to edit
|
||||
the number of replicas is now made easier
|
||||
with the new [replicas](fields.md#replicas) field.
|
||||
|
||||
### `envs` field
|
||||
|
||||
An `envs` sub-field has been added to both
|
||||
`configMapGenerator` and `secretGenerator`,
|
||||
replacing the now deprecated (and singular)
|
||||
`env` field. The new field accepts lists, just
|
||||
like its sibling fields `files` and `literals`.
|
||||
|
||||
Optionally use `kustomize edit fix` to merge
|
||||
singular `env` field into a plural field.
|
||||
@@ -1,70 +0,0 @@
|
||||
# Kustomize 2.0.0
|
||||
|
||||
After security review, a field used in secret generation (see below) was removed from the definition of a kustomization file with no mechanism to convert it to a new form. Also, the set of files accessible from a kustomization file has been further constrained.
|
||||
|
||||
Per the [versioning policy](versioningPolicy.md), backward incompatible changes trigger an increment of the major version number, hence we go from 1.0.11 to 2.0.0. We're taking this major version increment opportunity to remove some already deprecated fields, and the code paths associated with them.
|
||||
|
||||
## Backward Incompatible Changes
|
||||
|
||||
### Kustomization Path Constraints
|
||||
A kustomization file can specify paths to other files, including resources, patches, configmap generation data, secret generation data and bases. In the case of a base, the path can be a git URL instead.
|
||||
|
||||
In 1.x, these paths had to be relative to the current kustomization directory (the location of the kustomization file used in the `build` command).
|
||||
|
||||
In 2.0, bases can continue to specify, via relative paths, kustomizations outside the current kustomization directory.
|
||||
But non-base paths are constrained to terminate in or below the current kustomization directory. Further, bases specified via a git URL may not reference files outside of the directory used to clone the repository.
|
||||
|
||||
### Kustomization Field Removals
|
||||
|
||||
#### patches
|
||||
`patches` was deprecated and replaced by `patchesStrategicMerge` when `patchesJson6902` was introduced.
|
||||
In Kustomize 2.0.0, `patches` is removed. Please use `patchesStrategicMerge` instead.
|
||||
|
||||
#### imageTags
|
||||
`imageTags` is replaced by `images` since `images` can provide more features to change image names, registries, tags and digests.
|
||||
|
||||
#### secretGenerator/commands
|
||||
`commands` is removed from SecretGenerator due to [security concern](https://docs.google.com/document/d/1FYgLVdq-siB_Cef9yuQBmit0PbrE8lsyTBdGI2eA2y8/edit). One can use `files` or `literals`, similar to ConfigMapGenerator, to generate a secret.
|
||||
```
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
```
|
||||
|
||||
## Compatible Changes (New Features)
|
||||
As this release is triggered by a security change,
|
||||
there are no major new features to announce. A few things that are worth mentioning in this release are:
|
||||
|
||||
* More than _40_ issues closed since 1.0.11 release (including many extensions to transformation rules).
|
||||
* Users can run `kustomize edit fix` to migrate a kustomization file working with previous versions to one working with 2.0.0. For example, a kustomization.yaml with following content
|
||||
```
|
||||
patches:
|
||||
- deployment-patch.yaml
|
||||
imageTags:
|
||||
- name: postgres
|
||||
newTag: v1
|
||||
```
|
||||
|
||||
will be converted to
|
||||
|
||||
```
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
patchesStrategicMerge:
|
||||
- deployment-patch.yaml
|
||||
images:
|
||||
- name: postgres
|
||||
newTag: v1
|
||||
```
|
||||
|
||||
* Kustomization filename
|
||||
|
||||
In previous versions, the canonical name of a kustomization file is `kustomization.yaml`. Kustomize 2.0.0 is extended to recognize more file names: `kustomization.yaml`, `kustomization.yml` and `Kustomization`. In a directory, only one of those filenames is allowed. If there are more than one found, Kustomize will exit with an error. Please select the best filename for your use cases.
|
||||
* No longer planning to deprecate namespace prefix/suffix. The deprecation warning
|
||||
```
|
||||
Adding nameprefix and namesuffix to Namespace resource will be deprecated in next release.
|
||||
```
|
||||
is removed. Since changing this behavior will break many users' workflow. Kustomize will continue with adding nameprefix and namesuffix to Namespace resources.
|
||||
@@ -19,14 +19,14 @@ number are bumped per semver.
|
||||
|
||||
At the time of writing (circa release of v2.0.0):
|
||||
|
||||
- A [kustomization] file is just a YAML file that
|
||||
can be successfully parsed into a particular Go
|
||||
struct defined in the `kustomize` binary.
|
||||
- A [kustomization] file is just a YAML file that
|
||||
can be successfully parsed into a particular Go
|
||||
struct defined in the `kustomize` binary.
|
||||
|
||||
- This struct does not have a version number,
|
||||
which is the same as saying that its version
|
||||
number matches the program's version number,
|
||||
since it's compiled in.
|
||||
- This struct does not have a version number,
|
||||
which is the same as saying that its version
|
||||
number matches the program's version number,
|
||||
since it's compiled in.
|
||||
|
||||
### Field Change Policy
|
||||
|
||||
@@ -64,13 +64,13 @@ deprecations fixable via `edit fix`.
|
||||
With the 2.0.0 release, there were three field
|
||||
removals:
|
||||
|
||||
- `imageTag` was deprecated when `image` was
|
||||
- `imageTag` was deprecated when `images` was
|
||||
introduced, because the latter offers more
|
||||
general features for image data manipulation.
|
||||
`imageTag` was removed in v2.0.0.
|
||||
|
||||
- `patches` was deprecated and replaced by
|
||||
`PatchesStrategicMerge` when `PatchesJson6902`
|
||||
`patchesStrategicMerge` when `patchesJson6902`
|
||||
was introduced, to make a clearer
|
||||
distinction between patch specification formats.
|
||||
`patches` was removed in v2.0.0.
|
||||
@@ -92,16 +92,16 @@ process for making [changes].
|
||||
The presence of an `apiVersion` field in a k8s
|
||||
native type signals:
|
||||
|
||||
- its reliability level (alpha vs beta vs
|
||||
generally available),
|
||||
- its reliability level (alpha vs beta vs
|
||||
generally available),
|
||||
|
||||
- the existence of code to provide default values
|
||||
to fields not present in a serialization,
|
||||
|
||||
- the existence of code to provide both forward
|
||||
and backward conversion between different
|
||||
versions of types.
|
||||
|
||||
- the existence of code to provide default values
|
||||
to fields not present in a serialization,
|
||||
|
||||
- the existence of code to provide both forward
|
||||
and backward conversion between different
|
||||
versions of types.
|
||||
|
||||
The k8s API promises a lossless _conversion_
|
||||
between versions over a specific range. This
|
||||
means that a recent client can write an object
|
||||
@@ -124,13 +124,13 @@ defaulting and conversions).
|
||||
The critical difference between k8s API versioning
|
||||
and kustomization file versioning is
|
||||
|
||||
- A k8s API server is able to go _forward_ and
|
||||
_backward_ in versioning, to work with older
|
||||
clients, over [some range].
|
||||
- A k8s API server is able to go _forward_ and
|
||||
_backward_ in versioning, to work with older
|
||||
clients, over [some range].
|
||||
|
||||
- The `kustomize edit fix` command only moves
|
||||
_forward_ within a _major_ program
|
||||
version.
|
||||
- The `kustomize edit fix` command only moves
|
||||
_forward_ within a _major_ program
|
||||
version.
|
||||
|
||||
At the time of writing, the YAML in a
|
||||
kustomization file does not represent a [k8s API]
|
||||
@@ -160,7 +160,7 @@ a kustomization file: [`kind`] and [`apiVersion`].
|
||||
If either field is present, they both must be, and
|
||||
they must have the following values:
|
||||
|
||||
```
|
||||
``` yaml
|
||||
kind: Kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
```
|
||||
@@ -171,7 +171,7 @@ domain-squatting behavior for some future API. A
|
||||
kustomize user gains nothing from adding these
|
||||
fields to a kustomization file.
|
||||
|
||||
### Why not require `kind` and `apiVersion`?
|
||||
### Why not require `kind` and `apiVersion`
|
||||
|
||||
#### Ease of use and setting proper expectations
|
||||
|
||||
@@ -203,7 +203,6 @@ locked into `/v1beta1` or `/v1` and the `kind`
|
||||
and `apiVersion` fields can be required from that
|
||||
moment forward.
|
||||
|
||||
|
||||
[field change policy]: #field-change-policy
|
||||
[some range]: https://kubernetes.io/docs/reference/using-api/deprecation-policy
|
||||
[proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/customresources-versioning.md
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
[patches]: glossary.md#patch
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resources]: glossary.md#resource
|
||||
[workflowBespoke]: workflowBespoke.jpg
|
||||
[workflowOts]: workflowOts.jpg
|
||||
[workflowBespoke]: images/workflowBespoke.jpg
|
||||
[workflowOts]: images/workflowOts.jpg
|
||||
[kubectl-v1.14.0]:https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/
|
||||
|
||||
# workflows
|
||||
|
||||
@@ -71,6 +72,11 @@ Run kustomize, and pipe the output to [apply].
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
You can also use [kubectl-v1.14.0] to apply your [variants].
|
||||
> ```
|
||||
> kubectl apply -k ~/ldap/overlays/staging
|
||||
> kubectl apply -k ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
## Off-the-shelf configuration
|
||||
|
||||
@@ -120,6 +126,12 @@ distinct repository.
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
You can also use [kubectl-v1.14.0] to apply your [variants].
|
||||
> ```
|
||||
> kubectl apply -k ~/ldap/overlays/staging
|
||||
> kubectl apply -k ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
#### 5) (optionally) capture changes from upstream
|
||||
|
||||
The user can periodically [rebase] their [base] to
|
||||
|
||||
39
docs/zh/INSTALL.md
Normal file
@@ -0,0 +1,39 @@
|
||||
[release 页面]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||
[Go]: https://golang.org
|
||||
[golang.org]: https://golang.org
|
||||
|
||||
## 安装
|
||||
|
||||
在 macOS ,您可以使用软件包管理器 Homebrew 来安装 kustomize 。
|
||||
|
||||
brew install kustomize
|
||||
|
||||
在 windows ,您可以使用软件包管理器 Chocolatey 来安装 kustomize 。
|
||||
|
||||
choco install kustomize
|
||||
|
||||
有关软件包管理器 chocolatey 的使用以及对之前版本的支持,请参考以下链接:
|
||||
- [Choco Package](https://chocolatey.org/packages/kustomize)
|
||||
- [Package Source](https://github.com/kenmaglio/choco-kustomize)
|
||||
|
||||
对于其他系统,请在 [release 页面] 下载相应系统的二进制文件。
|
||||
|
||||
或者使用命令行获取最新的官方版本:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
使用 [Go] v1.10.1 或更高版本安装(如果可以访问 [golang.org]):
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
```
|
||||
46
docs/zh/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
[English](../README.md) | 简体中文
|
||||
|
||||
# 文档
|
||||
|
||||
* [安装说明](INSTALL.md)
|
||||
|
||||
* [示例](../../examples) - 各种使用流程和概念的详细演示。
|
||||
|
||||
* [术语表](../glossary.md) - 用于消除术语歧义。
|
||||
|
||||
* [kustomization.yaml](kustomization.yaml) - 包含
|
||||
[kustomization](../glossary.md#kustomization) 所有字段的示例文件。
|
||||
|
||||
* [插件](../plugins.md) - 使用自定义的资源生成器和资源转换器来拓展 kustomize 功能。
|
||||
|
||||
* [工作流](workflows.md) - 使用定制及使用现成配置使用的一些步骤。
|
||||
|
||||
* [FAQ](../FAQ.md)
|
||||
|
||||
|
||||
## 发行说明
|
||||
|
||||
* [2.1](../v_2.1.0.md) - 日期待定,预计2019年5月下旬。
|
||||
|
||||
* [2.0](../v_2.0.0.md) - 2019年3月
|
||||
可以在 [kubectl v1.14][kubectl] 中使用 kustomize [v2.0.3] 。
|
||||
|
||||
* [1.0](../v_1.0.1.md) - 2018年5月
|
||||
于 [kubectl repository] 开发后的首发版本。
|
||||
|
||||
|
||||
## 政策
|
||||
|
||||
* [版本控制](../versioningPolicy.md) - kustomize 代码及 kustomization 文件的版本控制策略。
|
||||
|
||||
* [规避功能](../eschewedFeatures.md) - 目前 Kustomize 不支持某些功能的原因。
|
||||
|
||||
* [贡献指南](../../CONTRIBUTING.md) - 请在提交 PR 之前阅读。
|
||||
|
||||
* [行为准则](../../code-of-conduct.md)
|
||||
|
||||
>声明:部分文档可能稍微滞后于英文版本,同步工作持续进行中
|
||||
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[kubectl]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubectl repository]: https://github.com/kubernetes/kubectl
|
||||
287
docs/zh/kustomization.yaml
Normal file
@@ -0,0 +1,287 @@
|
||||
# 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.
|
||||
#
|
||||
# ----------------------------------------------------
|
||||
# Example kustomization.yaml content.
|
||||
#
|
||||
# This file declares the customization provided by
|
||||
# the kustomize program.
|
||||
#
|
||||
# Since customization is, by definition, _custom_,
|
||||
# there are no sensible default values for the fields
|
||||
# in this file.
|
||||
#
|
||||
# The field values used below are merely examples, not
|
||||
# to be copied literally. The values won't work if
|
||||
# they happen to be references to external files that
|
||||
# don't exist.
|
||||
#
|
||||
# In practice, fields with no value should simply be
|
||||
# omitted from kustomization.yaml to reduce the content
|
||||
# visible in configuration reviews.
|
||||
# ----------------------------------------------------
|
||||
# Kustomization 的 apiVersion 和 kind
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
# 为所有 resources 添加 namespace
|
||||
namespace: my-namespace
|
||||
|
||||
# 该字段的值将添加在所有资源的名称之前
|
||||
# 例如 将资源名称 “wordpress” 变为 “alices-wordpress”
|
||||
namePrefix: alices-
|
||||
|
||||
# 该字段的值将添加在所有资源的名称后面
|
||||
# 例如 将资源名称 “wordpress” 变为 “wordpress-v2”
|
||||
# 如果资源类型为 ConfigMap 或 Secret ,则在哈希值之前附加后缀
|
||||
nameSuffix: -v2
|
||||
|
||||
# 为所有资源和 selectors 增加 Labels
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
|
||||
# 和 Labels 一样, 增加 Annotations
|
||||
# 为 key:value 键值对
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
|
||||
# 此列表中的每条记录都必须是一个存在的 YAML 资源描述文件
|
||||
# 一个 YAML 资源描述文件可以含有多个由(“---”)分隔的资源。
|
||||
# kustomize 将读取这些YAML文件中的资源,对其进行修改并
|
||||
# 发布在 kustomize 的输出中。
|
||||
#
|
||||
# 此列表中的每个条目都应解析为包含 kustomization 文件的目录,否则定制将失败
|
||||
#
|
||||
# 该条目可以是指向本地目录的相对路径
|
||||
# 也可以是指向远程仓库中的目录的 URL
|
||||
# URL 应该遵循 hashicorp/go-getter 中的 URL 格式
|
||||
# https://github.com/hashicorp/go-getter#url-format
|
||||
#
|
||||
# 此字段的存在意味着此文件(您正在阅读的文件)是 _overlay_
|
||||
# 它将进一步定制这些来自 _bases_ 文件中的配置
|
||||
#
|
||||
# 典型用例:开发,演示和生产环境
|
||||
# 这些环境大部分相同但有些关键方式存在差异(镜像标签,一些服务器参数等,与公共 base 不同的配置)
|
||||
resources:
|
||||
- some-service.yaml
|
||||
- sub-dir/some-deployment.yaml
|
||||
- ../../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
|
||||
|
||||
# 列表中的每个条目都将创建一个 ConfigMap (它是n个 ConfigMap 的生成器)
|
||||
# 下面的示例创建了两个 ConfigMaps
|
||||
# 一个具有给定文件的名称和内容
|
||||
# 另一个包含 key/value 键值对数据
|
||||
# 每个 configMapGenerator 项都可以使用 [create | replace | merge] 参数
|
||||
# 允许 overlay 从父级修改或替换现有的 configMap
|
||||
configMapGenerator:
|
||||
- name: myJavaServerProps
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
- name: myJavaServerEnvVars
|
||||
literals:
|
||||
- JAVA_HOME=/opt/java/jdk
|
||||
- JAVA_TOOL_OPTIONS=-agentlib:hprof
|
||||
|
||||
# 此列表中的每个条目都会导致创建一个Secret资源(n个 secrets 的生成器)
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: app-tls-namespaced
|
||||
# 你可以给生成的 secret 定义一个 namespace ,默认为 ”default“
|
||||
namespace: apps
|
||||
files:
|
||||
- tls.crt=catsecret/tls.cert
|
||||
- tls.key=secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: env_file_secret
|
||||
# 文件路径以 k=v 键值对的形式,每行一个键值对
|
||||
envs:
|
||||
- env.txt
|
||||
type: Opaque
|
||||
|
||||
# generatorOptions 修改所有 ConfigMapGenerator 和 SecretGenerator 的行为
|
||||
generatorOptions:
|
||||
# 为所有生成的资源添加 labels
|
||||
labels:
|
||||
kustomize.generated.resources: somevalue
|
||||
# 为所有生成的资源添加 annotations
|
||||
annotations:
|
||||
kustomize.generated.resource: somevalue
|
||||
# disableNameSuffixHash 为 true 时将禁止默认的在名称后添加哈希值后缀的行为
|
||||
disableNameSuffixHash: true
|
||||
|
||||
# 此列表中的每个条目都应可以解析为部分或完整的资源定义文件
|
||||
#
|
||||
# 这些(也可能是部分的)资源文件中的 name 必须与已经通过 `resources` 加载的 name 字段匹配
|
||||
# 或者通过 `bases` 中的 name 字段匹配
|
||||
# 这些条目将用于 _patch_(修改)已知资源
|
||||
#
|
||||
# 推荐使用小的 patches
|
||||
# 例如:修改内存的 request/limit,更改 ConfigMap 中的 env 变量等
|
||||
# 小的 patches 易于维护和查看,并且易于在 overlays 中混合使用
|
||||
patchesStrategicMerge:
|
||||
- service_port_8888.yaml
|
||||
- deployment_increase_replicas.yaml
|
||||
- deployment_increase_memory.yaml
|
||||
|
||||
# patchesJson6902 列表中的每个条目都应可以解析为 kubernetes 对象和将应用于该对象的 JSON patch
|
||||
# JSON patch 的文档地址:https://tools.ietf.org/html/rfc6902
|
||||
#
|
||||
# 目标字段指向的 kubernetes 对象的 group、 version、 kind、 name 和 namespace 在同一 kustomization 内
|
||||
# path 字段内容是 JSON patch 文件的相对路径
|
||||
# patch 文件中的内容可以如下这种 JSON 格式:
|
||||
#
|
||||
# [
|
||||
# {"op": "add", "path": "/some/new/path", "value": "value"},
|
||||
# {"op": "replace", "path": "/some/existing/path", "value": "new value"}
|
||||
# ]
|
||||
#
|
||||
# 也可以使用 YAML 格式表示:
|
||||
#
|
||||
# - 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
|
||||
|
||||
# 此列表中的每个条目都应该是 openAPI 定义中自定义资源定义(CRD)文件的相对路径
|
||||
#
|
||||
# 该字段的存在是为了让 kustomize 知道用户自定义的 CRD
|
||||
# 并对这些类型中的对象应用适当的转换
|
||||
#
|
||||
# 典型用例:CRD 引用 ConfigMap 对象
|
||||
# 在 kustomization 中,ConfigMap 对象名称可能会通过 namePrefix 、nameSuffix 或 hashing 来更改 CRD 对象中此 ConfigMap 对象的名称
|
||||
# 引用时需要以相同的方式使用 namePrefix 、 nameSuffix 或 hashing 来进行更新
|
||||
#
|
||||
# Annotations 可以放入 openAPI 的定义中:
|
||||
# "x-kubernetes-annotation": ""
|
||||
# "x-kubernetes-label-selector": ""
|
||||
# "x-kubernetes-identity": ""
|
||||
# "x-kubernetes-object-ref-api-version": "v1",
|
||||
# "x-kubernetes-object-ref-kind": "Secret",
|
||||
# "x-kubernetes-object-ref-name-key": "name",
|
||||
crds:
|
||||
- crds/typeA.json
|
||||
- crds/typeB.json
|
||||
|
||||
# Vars 用于从一个 resource 字段中获取文本
|
||||
# 并将该文本插入指定位置
|
||||
#
|
||||
# 例如,假设需要在容器的 command 中指定了 Service 对象的名称
|
||||
# 并在容器的 env 中指定了 Secret 对象的名称
|
||||
# 来确保以下内容可以正常工作:
|
||||
# ```
|
||||
# containers:
|
||||
# - image: myimage
|
||||
# command: ["start", "--host", "$(MY_SERVICE_NAME)"]
|
||||
# env:
|
||||
# - name: SECRET_TOKEN
|
||||
# value: $(SOME_SECRET_NAME)
|
||||
# ```
|
||||
#
|
||||
# 则可以在 `vars:` 中添加如下内容:
|
||||
#
|
||||
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
|
||||
#
|
||||
# var 是包含该对象的变量名、对象引用和字段引用的元组
|
||||
#
|
||||
# 字段引用是可选的,默认为 `metadata.name`
|
||||
# 这是正常的默认值,因为 kustomize 用于生成或修改 resources 的名称
|
||||
#
|
||||
# 在撰写本文档时,仅支持字符串类型字段
|
||||
# 不支持 ints,bools,arrays 等
|
||||
#
|
||||
# 变量引用,即字符串 '$(FOO)' ,只能放在 kustomize 配置指定的特定对象的特定字段中
|
||||
#
|
||||
# 关于 vars 的默认配置数据可以查看:
|
||||
# https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go
|
||||
# 默认目标是所有容器 command args 和 env 字段
|
||||
#
|
||||
# Vars _不应该_ 被用于 kustomize 已经处理过的配置中插入 names
|
||||
# 例如, Deployment 可以通过 name 引用 ConfigMap
|
||||
# 如果 kustomize 更改 ConfigMap 的名称,则知道更改 Deployment 中的引用的 name
|
||||
|
||||
# 修改镜像的名称、tag 或 image digest ,而无需使用 patches
|
||||
# 例如,对于这种 kubernetes Deployment 片段:
|
||||
# ```
|
||||
# containers:
|
||||
# - name: mypostgresdb
|
||||
# image: postgres:8
|
||||
# - name: nginxapp
|
||||
# image: nginx:1.7.9
|
||||
# - name: myapp
|
||||
# image: my-demo-app:latest
|
||||
# - name: alpine-app
|
||||
# image: alpine:3.7
|
||||
#```
|
||||
# 想对 `image` 完成以下修改:
|
||||
#
|
||||
# - 将 `postgres:8` 修改为 `my-registry/my-postgres:v1`,
|
||||
# - 将 nginx 的 tag 从 `1.7.9` 修改为 `1.8.0`,
|
||||
# - 将 镜像名称从 `my-demo-app` 修改为 `my-app`,
|
||||
# - 将 alpine 的 tag 从 `3.7` 修改为 digest 值
|
||||
#
|
||||
# 可以在 *kustomization* 中添加以下内容:
|
||||
|
||||
images:
|
||||
- name: postgres
|
||||
newName: my-registry/my-postgres
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: my-demo-app
|
||||
newName: my-app
|
||||
- name: alpine
|
||||
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
||||
127
docs/zh/workflows.md
Normal file
@@ -0,0 +1,127 @@
|
||||
[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-configuration
|
||||
[overlays]: ../glossary.md#overlay
|
||||
[patch]: ../glossary.md#patch
|
||||
[patches]: ../glossary.md#patch
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resources]: ../glossary.md#resource
|
||||
[workflowBespoke]: ../images/workflowBespoke.jpg
|
||||
[workflowOts]: ../images/workflowOts.jpg
|
||||
[kubectl-v1.14.0]:https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/
|
||||
|
||||
# 工作流
|
||||
|
||||
工作流是 kustomize 运行和维护配置的步骤。
|
||||
|
||||
## 配置定制(Bespoke configuration)
|
||||
|
||||
在这个工作流方式中,所有的配置文件( YAML 资源)都为用户所有,存储在用户的私有 repo 中。其他用户是无法使用的。
|
||||
|
||||
![bespoke config workflow image][workflowBespoke]
|
||||
|
||||
#### 1) 创建一个目录用于版本控制
|
||||
|
||||
我们希望将一个名为 _ldap_ 的 Kubernetes 集群应用的配置保存在自己的 repo 中。
|
||||
这里使用 git 进行版本控制。
|
||||
|
||||
> ```
|
||||
> git init ~/ldap
|
||||
> ```
|
||||
|
||||
#### 2) 创建一个 [base]
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/base
|
||||
> ```
|
||||
|
||||
在这个目录中创建并提交 [kustomization] 文件及一组资源配置。
|
||||
|
||||
#### 3) 创建 [overlays]
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/overlays/staging
|
||||
> mkdir -p ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
每个目录都包含需要一个 [kustomization] 文件以及一或多个 [patches]。
|
||||
|
||||
在 _staging_ 目录可能会有一个用于在 configmap 中打开一个实验标记的补丁。
|
||||
|
||||
在 _production_ 目录可能会有一个在 deployment 中增加副本数的补丁。
|
||||
|
||||
#### 4) 生成 [variants]
|
||||
|
||||
运行 kustomize,将生成的配置用于 kubernetes 应用发布。
|
||||
|
||||
> ```
|
||||
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
也可以在 [kubectl-v1.14.0] 版,使用 ```kubectl``` 命令发布你的 [variants] 。
|
||||
> ```
|
||||
> kubectl apply -k ~/ldap/overlays/staging
|
||||
> kubectl apply -k ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
## 使用现成的配置(Off-the-shelf configuration)
|
||||
|
||||
在这个工作流方式中,可从别人的 repo 中 fork kustomize 配置,并根据自己的需求来配置。
|
||||
|
||||
|
||||
![off-the-shelf config workflow image][workflowOts]
|
||||
|
||||
#### 1) 寻找并且 [fork] 一个 [OTS] 配置
|
||||
|
||||
#### 2) 将其克隆为你自己的 [base]
|
||||
|
||||
这个 [base] 目录维护在上游为 [OTS] 配置的 repo ,在这个例子使用 `ladp` 的 repo 。
|
||||
|
||||
> ```
|
||||
> mkdir ~/ldap
|
||||
> git clone https://github.com/$USER/ldap ~/ldap/base
|
||||
> cd ~/ldap/base
|
||||
> git remote add upstream git@github.com:$USER/ldap
|
||||
> ```
|
||||
|
||||
#### 3) 创建 [overlays]
|
||||
|
||||
如配置定制方法一样,创建并完善 _overlays_ 目录中的内容。
|
||||
|
||||
所有的 [overlays] 都依赖于 [base] 。
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/overlays/staging
|
||||
> mkdir -p ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
用户可以将 `overlays` 维护在不同的 repo 中。
|
||||
|
||||
#### 4) 生成 [variants]
|
||||
|
||||
> ```
|
||||
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
也可以在 [kubectl-v1.14.0] 版,使用 ```kubectl``` 命令发布你的 [variants] 。
|
||||
> ```
|
||||
> kubectl apply -k ~/ldap/overlays/staging
|
||||
> kubectl apply -k ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
#### 5) (可选)从上游更新
|
||||
|
||||
用户可以定期从上游 repo 中 [rebase] 他们的 [base] 以保证及时更新。
|
||||
|
||||
> ```
|
||||
> cd ~/ldap/base
|
||||
> git fetch upstream
|
||||
> git rebase upstream/master
|
||||
> ```
|
||||
@@ -1,49 +1,72 @@
|
||||
English | [简体中文](zh/README.md)
|
||||
|
||||
# Examples
|
||||
|
||||
These examples assume that `kustomize` is on your `$PATH`.
|
||||
|
||||
They are covered by [pre-commit](../bin/pre-commit.sh)
|
||||
They are covered by [pre-commit](../travis/pre-commit.sh)
|
||||
tests, and should work with HEAD
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
go get sigs.k8s.io/kustomize/cmd/kustomize
|
||||
```
|
||||
|
||||
* [hello world](helloWorld/README.md) - Deploy multiple
|
||||
(differently configured) variants of a simple Hello
|
||||
World server.
|
||||
Basic Usage
|
||||
|
||||
* [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) -
|
||||
* [configGenerations](configGeneration.md) -
|
||||
Rolling update when ConfigMapGenerator changes.
|
||||
|
||||
* [combineConfigs](combineConfigs.md) -
|
||||
Mixing configuration data from different owners
|
||||
(e.g. devops/SRE and developers).
|
||||
|
||||
* [generatorOptions](generatorOptions.md) -
|
||||
Modifying behavior of all ConfigMap and Secret generators.
|
||||
|
||||
* [vars](wordpress/README.md) - Injecting k8s runtime data into
|
||||
container arguments (e.g. to point wordpress to a SQL service) by vars.
|
||||
|
||||
* [image names and tags](image.md) - Updating image names and tags without applying a patch.
|
||||
|
||||
* [remote target](remoteBuild.md) - Building a kustomization from a github URL
|
||||
|
||||
* [json patch](jsonpatch.md) - Apply a json patch in a kustomization
|
||||
|
||||
Advanced Usage
|
||||
|
||||
- generator plugins:
|
||||
|
||||
* [last mile helm](chart.md) - Make last mile modifications to
|
||||
a helm chart.
|
||||
|
||||
* [secret generation](secretGeneratorPlugin.md) - Generating secrets from a plugin.
|
||||
|
||||
- transformer plugins:
|
||||
* [validation transformer](validationTransformer/README.md) -
|
||||
validate resources through a transformer
|
||||
|
||||
- customize builtin transformer configurations
|
||||
|
||||
* [transformer configs](transformerconfigs/README.md) - Customize transformer configurations
|
||||
|
||||
* [configGenerations](configGeneration.md) -
|
||||
Rolling update when ConfigMapGenerator changes
|
||||
|
||||
* [generatorOptions](generatorOptions.md) - Modifying behavior of all ConfigMap and Secret generators.
|
||||
|
||||
* [breakfast](breakfast.md) - Customize breakfast for
|
||||
Alice and Bob.
|
||||
|
||||
* [vars](wordpress/README.md) - Injecting k8s runtime data into container arguments (e.g. to point wordpress to a SQL service) by vars.
|
||||
|
||||
* [image names and tags](image.md) - Updating image names and tags without applying a patch.
|
||||
Multi Variant Examples
|
||||
|
||||
* [multibases](multibases/README.md) - Composing three variants (dev, staging, production) with a common base.
|
||||
* [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.
|
||||
|
||||
* [springboot](springboot/README.md) - Create a Spring Boot
|
||||
application production configuration from scratch.
|
||||
|
||||
* [remote target](remoteBuild.md) - Building a kustomization from a github URL
|
||||
|
||||
* [json patch](jsonpatch.md) - Apply a json patch in a kustomization
|
||||
|
||||
* [transformer configs](transformerconfigs/README.md) - Customize transformer configurations
|
||||
* [mySql](mySql/README.md) - Create a MySQL production
|
||||
configuration from scratch.
|
||||
|
||||
* [breakfast](breakfast.md) - Customize breakfast for
|
||||
Alice and Bob.
|
||||
|
||||
* [multibases](multibases/README.md) - Composing three variants (dev, staging, production) with a common base.
|
||||
@@ -71,7 +71,7 @@ mkdir -p $DEMO_HOME/breakfast/overlays/alice
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/alice/kustomization.yaml
|
||||
commonLabels:
|
||||
who: alice
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- temperature.yaml
|
||||
@@ -94,7 +94,7 @@ mkdir -p $DEMO_HOME/breakfast/overlays/bob
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/bob/kustomization.yaml
|
||||
commonLabels:
|
||||
who: bob
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- topping.yaml
|
||||
|
||||
255
examples/chart.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# kustomization of a helm chart
|
||||
|
||||
[last mile]: https://testingclouds.wordpress.com/2018/07/20/844/
|
||||
[stable chart]: https://github.com/helm/charts/tree/master/stable
|
||||
[Helm charts]: https://github.com/helm/charts
|
||||
[_minecraft_]: https://github.com/helm/charts/tree/master/stable/minecraft
|
||||
[plugin]: ../docs/plugins.md
|
||||
|
||||
[Helm charts] aren't natively read by kustomize, but
|
||||
kustomize has a [plugin] system that allows one to
|
||||
access helm charts.
|
||||
|
||||
One pattern combining kustomize and helm is
|
||||
the [last mile] modification, where
|
||||
one uses an inflated chart as a base, then
|
||||
modifies it on the way to the cluster using
|
||||
kustomize.
|
||||
|
||||
The plugin used in the example below is coded to work
|
||||
only for charts found in the [stable chart] repo. The
|
||||
example arbitrarily uses [_minecraft_], but should work
|
||||
for any chart.
|
||||
|
||||
The following example assumes you have `helm`
|
||||
on your `$PATH`.
|
||||
|
||||
Make a place to work:
|
||||
|
||||
<!-- @makeWorkplace @helmtest -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
mkdir -p $DEMO_HOME/base
|
||||
mkdir -p $DEMO_HOME/dev
|
||||
mkdir -p $DEMO_HOME/prod
|
||||
```
|
||||
|
||||
## Use a remote chart
|
||||
|
||||
Define a kustomization representing your _development_
|
||||
variant (aka environment).
|
||||
|
||||
This could involve any number of kustomizations (see
|
||||
other examples), but in this case just add the name
|
||||
prefix `dev-` to all resources:
|
||||
|
||||
<!-- @writeKustDev @helmtest -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/dev/kustomization.yaml
|
||||
namePrefix: dev-
|
||||
resources:
|
||||
- ../base
|
||||
EOF
|
||||
```
|
||||
|
||||
Likewise define a _production_ variant, with a name
|
||||
prefix `prod-`:
|
||||
|
||||
<!-- @writeKustProd @helmtest -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/prod/kustomization.yaml
|
||||
namePrefix: prod-
|
||||
resources:
|
||||
- ../base
|
||||
EOF
|
||||
```
|
||||
|
||||
These two variants refer to a common base.
|
||||
|
||||
Define this base:
|
||||
|
||||
<!-- @writeKustDev @helmtest -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/base/kustomization.yaml
|
||||
generators:
|
||||
- chartInflator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
The base refers to a generator configuration file
|
||||
called `chartInflator.yaml`.
|
||||
|
||||
This file lets one specify the name of a [stable chart],
|
||||
and other things like a path to a values file, defaulting
|
||||
to the `values.yaml` that comes with the chart.
|
||||
|
||||
Create the config file `chartInflator.yaml`, specifying
|
||||
the arbitrarily chosen chart name _minecraft_:
|
||||
|
||||
<!-- @writeGeneratorConfig @helmtest -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/base/chartInflator.yaml
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: ChartInflator
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
chartName: minecraft
|
||||
EOF
|
||||
```
|
||||
|
||||
Because this particular YAML file is listed in the
|
||||
`generators:` stanza of a kustomization file, it is
|
||||
treated as the binding between a generator plugin -
|
||||
identified by the _apiVersion_ and _kind_ fields - and
|
||||
other fields that configure the plugin.
|
||||
|
||||
Download the plugin to your `DEMO_HOME` and make it
|
||||
executable:
|
||||
|
||||
<!-- @installPlugin @helmtest -->
|
||||
```
|
||||
plugin=plugin/someteam.example.com/v1/chartinflator/ChartInflator
|
||||
curl -s --create-dirs -o \
|
||||
"$DEMO_HOME/kustomize/$plugin" \
|
||||
"https://raw.githubusercontent.com/\
|
||||
kubernetes-sigs/kustomize/master/$plugin"
|
||||
|
||||
chmod a+x $DEMO_HOME/kustomize/$plugin
|
||||
```
|
||||
|
||||
Check the directory layout:
|
||||
|
||||
<!-- @tree -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/whatever
|
||||
> ├── base
|
||||
> │ ├── chartInflator.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> ├── dev
|
||||
> │ └── kustomization.yaml
|
||||
> ├── kustomize
|
||||
> │ └── plugin
|
||||
> │ └── someteam.example.com
|
||||
> │ └── v1
|
||||
> │ └── chartinflator
|
||||
> │ └── ChartInflator
|
||||
> └── prod
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
Define a helper function to run kustomize with the
|
||||
correct environment and flags for plugins:
|
||||
|
||||
<!-- @defineKustomizeIt @helmtest -->
|
||||
```
|
||||
function kustomizeIt {
|
||||
XDG_CONFIG_HOME=$DEMO_HOME \
|
||||
kustomize build --enable_alpha_plugins \
|
||||
$DEMO_HOME/$1
|
||||
}
|
||||
```
|
||||
|
||||
Finally, build the `prod` variant. Notice that all
|
||||
resource names now have the `prod-` prefix:
|
||||
|
||||
<!-- @doProd @helmtest -->
|
||||
```
|
||||
clear
|
||||
kustomizeIt prod
|
||||
```
|
||||
|
||||
Compare `dev` to `prod`:
|
||||
|
||||
<!-- @doCompare -->
|
||||
```
|
||||
diff <(kustomizeIt dev) <(kustomizeIt prod) | more
|
||||
```
|
||||
|
||||
To see the unmodified but inflated chart, run kustomize
|
||||
on the base. Every invocation here is re-downloading
|
||||
and re-inflating the chart.
|
||||
|
||||
<!-- @showBase @helmtest -->
|
||||
```
|
||||
kustomizeIt base
|
||||
```
|
||||
|
||||
|
||||
## Use a local chart
|
||||
|
||||
The example above fetches a new copy of the chart
|
||||
to a temporary directory with each kustomize
|
||||
build, because a local chart home isn't specified
|
||||
in the configuration.
|
||||
|
||||
To suppress fetching, specify a _chart home_
|
||||
explicitly, and just make sure the chart is already
|
||||
there.
|
||||
|
||||
To demo this so that it won't interfere with your
|
||||
existing helm environment, do this:
|
||||
|
||||
<!-- @helmInit @helmtest -->
|
||||
```
|
||||
helmHome=$DEMO_HOME/dothelm
|
||||
chartHome=$DEMO_HOME/base/charts
|
||||
|
||||
function doHelm {
|
||||
helm --home $helmHome $@
|
||||
}
|
||||
|
||||
# Create helm config files in a new location.
|
||||
# The init command is extremely chatty
|
||||
doHelm init --client-only >& /dev/null
|
||||
```
|
||||
|
||||
Now download a chart; again use _minecraft_
|
||||
(but you could use anything):
|
||||
|
||||
<!-- @fetchChart @helmtest -->
|
||||
```
|
||||
doHelm fetch --untar \
|
||||
--untardir $chartHome \
|
||||
stable/minecraft
|
||||
```
|
||||
|
||||
The tree has more stuff now; helm config data
|
||||
and a complete copy of the chart:
|
||||
<!-- @tree -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
|
||||
Add a `chartHome` field to the generator config file so
|
||||
that it knows where to find the local chart:
|
||||
|
||||
<!-- @modifyGenConfig @helmtest -->
|
||||
```
|
||||
echo "chartHome: $chartHome" >>$DEMO_HOME/base/chartInflator.yaml
|
||||
```
|
||||
|
||||
Change the values file, to show that the results
|
||||
generated below are from the _locally_ stored chart:
|
||||
|
||||
<!-- @valueChange @helmtest -->
|
||||
```
|
||||
sed -i 's/CHANGEME!/SOMETHINGELSE/' $chartHome/minecraft/values.yaml
|
||||
sed -i 's/LoadBalancer/NodePort/' $chartHome/minecraft/values.yaml
|
||||
```
|
||||
|
||||
Finally, built it
|
||||
|
||||
<!-- @finalProd @helmtest -->
|
||||
```
|
||||
kustomizeIt prod
|
||||
```
|
||||
|
||||
and observe the change from `LoadBalancer` to `NodePort`, and
|
||||
the change in the encoded password.
|
||||
@@ -191,7 +191,7 @@ dbpassword=mothersMaidenName
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
namePrefix: dev-
|
||||
nameSuffix: -v1
|
||||
@@ -273,7 +273,7 @@ dbpassword=thisShouldProbablyBeInASecretInstead
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
namePrefix: prod-
|
||||
configMapGenerator:
|
||||
|
||||
@@ -66,7 +66,7 @@ commonLabels:
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- map.yaml
|
||||
|
||||
@@ -148,7 +148,7 @@ commonLabels:
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- map.yaml
|
||||
@@ -189,7 +189,7 @@ commonLabels:
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am production!
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
|
||||
@@ -53,7 +53,7 @@ function setUpEnv {
|
||||
exitWith "Script must be run from $expectedRepo"
|
||||
fi
|
||||
|
||||
go install . || \
|
||||
GO111MODULE=on go install . || \
|
||||
{ exitWith "Failed to install kustomize."; }
|
||||
|
||||
PATH=$GOPATH/bin:$PATH
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
bases:
|
||||
- ../../base
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
nameprefix: staging-
|
||||
- deployment.yaml
|
||||
namePrefix: staging-
|
||||
configMapGenerator:
|
||||
- name: env-config
|
||||
files:
|
||||
- config.env
|
||||
- name: env-config
|
||||
files:
|
||||
- config.env
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
# Demo: multibases with a common base
|
||||
|
||||
`kustomize` encourages defining multiple variants - e.g. dev, staging and prod, as overlays on 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.
|
||||
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.
|
||||
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.
|
||||
The following demonstrates this using a base
|
||||
that is just a single pod.
|
||||
|
||||
Define a place to work:
|
||||
|
||||
@@ -47,7 +57,7 @@ DEV=$DEMO_HOME/dev
|
||||
mkdir $DEV
|
||||
|
||||
cat <<EOF >$DEV/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ./../base
|
||||
namePrefix: dev-
|
||||
EOF
|
||||
@@ -60,7 +70,7 @@ STAG=$DEMO_HOME/staging
|
||||
mkdir $STAG
|
||||
|
||||
cat <<EOF >$STAG/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ./../base
|
||||
namePrefix: stag-
|
||||
EOF
|
||||
@@ -73,7 +83,7 @@ PROD=$DEMO_HOME/production
|
||||
mkdir $PROD
|
||||
|
||||
cat <<EOF >$PROD/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ./../base
|
||||
namePrefix: prod-
|
||||
EOF
|
||||
@@ -83,7 +93,7 @@ Then define a _Kustomization_ composing three variants together:
|
||||
<!-- @makeTopLayer @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- ./dev
|
||||
- ./staging
|
||||
- ./production
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
namePrefix: dev-
|
||||
resources:
|
||||
- ../base
|
||||
namePrefix: dev-
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
bases:
|
||||
- ./dev
|
||||
- ./staging
|
||||
- ./production
|
||||
|
||||
resources:
|
||||
- dev
|
||||
- staging
|
||||
- production
|
||||
namePrefix: cluster-a-
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
`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.
|
||||
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:
|
||||
|
||||
@@ -43,10 +45,9 @@ NSA=$DEMO_HOME/namespace-a
|
||||
mkdir $NSA
|
||||
|
||||
cat <<EOF >$NSA/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- ../base
|
||||
namespace: namespace-a
|
||||
EOF
|
||||
|
||||
@@ -65,10 +66,9 @@ NSB=$DEMO_HOME/namespace-b
|
||||
mkdir $NSB
|
||||
|
||||
cat <<EOF >$NSB/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- ../base
|
||||
namespace: namespace-b
|
||||
EOF
|
||||
|
||||
@@ -84,9 +84,9 @@ Then define a _Kustomization_ composing two variants together:
|
||||
<!-- @makeTopLayer @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- ./namespace-a
|
||||
- ./namespace-b
|
||||
resources:
|
||||
- namespace-a
|
||||
- namespace-b
|
||||
EOF
|
||||
```
|
||||
|
||||
@@ -112,4 +112,4 @@ Confirm that the `kustomize build` output contains two pod objects from namespac
|
||||
test 2 == \
|
||||
$(kustomize build $DEMO_HOME| grep -B 4 "namespace: namespace-[ab]" | grep "name: myapp-pod" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
resources:
|
||||
- ../base
|
||||
namePrefix: prod-
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
resources:
|
||||
- ../base
|
||||
namePrefix: staging-
|
||||
|
||||
@@ -1,45 +1,53 @@
|
||||
# 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.
|
||||
`kustomize build` can be run on a URL.
|
||||
|
||||
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.
|
||||
The effect is the same as cloning the repo, checking out a particular
|
||||
_ref_ (commit hash, branch name, release tag, etc.),
|
||||
then running `kustomize build` against the desired
|
||||
directory in the local copy.
|
||||
|
||||
To try this immediately, run a build against the kustomization
|
||||
in the [multibases](multibases/README.md) example. There's
|
||||
one pod in the output:
|
||||
|
||||
<!-- @remoteOverlayBuild @test -->
|
||||
|
||||
```
|
||||
target="github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6"
|
||||
test 1 == \
|
||||
$(kustomize build $target | grep dev-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
Run against the overlay in that example to get three pods
|
||||
(the overlay combines the dev, staging and prod bases for
|
||||
someone who wants to send them all at the same time):
|
||||
|
||||
<!-- @remoteBuild @test -->
|
||||
```
|
||||
target=github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
|
||||
target="https://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:
|
||||
A base can be a URL:
|
||||
|
||||
<!-- @createOverlay @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
resources:
|
||||
- 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.
|
||||
|
||||
Build this to confirm that all three pods from the base
|
||||
have the `remote-` prefix.
|
||||
|
||||
<!-- @remoteBases @test -->
|
||||
```
|
||||
test 3 == \
|
||||
@@ -48,6 +56,7 @@ test 3 == \
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
223
examples/secretGeneratorPlugin.md
Normal file
@@ -0,0 +1,223 @@
|
||||
[ConfigMaps]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#configmap-v1-core
|
||||
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
[Go plugin]: https://golang.org/pkg/plugin
|
||||
[Secrets]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#secret-v1-core
|
||||
[base64]: https://tools.ietf.org/html/rfc4648#section-4
|
||||
[configuration directory]: https://wiki.archlinux.org/index.php/XDG_Base_Directory#Specification
|
||||
[grpc]: https://grpc.io
|
||||
[tag]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[`exec.Command`]: https://golang.org/pkg/os/exec/#Command
|
||||
|
||||
# Generating Secrets
|
||||
|
||||
## What's a Secret?
|
||||
|
||||
Kubernetes [ConfigMaps] and [Secrets] are both
|
||||
key:value maps, but the latter is intended to
|
||||
signal that its values have a sensitive nature -
|
||||
e.g. pass phrases or ssh keys.
|
||||
|
||||
Kubernetes developers work in various ways to hide
|
||||
the information in a Secret more carefully than
|
||||
the information held by ConfigMaps, Deployments,
|
||||
etc.
|
||||
|
||||
## Make a place to work
|
||||
|
||||
<!-- @establishBase @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
## Secret values from local files
|
||||
|
||||
kustomize has three different (builtin) ways to
|
||||
generate a secret from local files:
|
||||
|
||||
* get them from so-called _env_ files (`NAME=VALUE`, one per line),
|
||||
* consume the entire contents of a file to make one secret value,
|
||||
* get literal values from the kustomization file itself.
|
||||
|
||||
Here's an example combining all three methods:
|
||||
|
||||
Make an env file with some short secrets:
|
||||
|
||||
<!-- @makeEnvFile @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/foo.env
|
||||
ROUTER_PASSWORD=admin
|
||||
DB_PASSWORD=iloveyou
|
||||
EOF
|
||||
```
|
||||
|
||||
Make a text file with a long secret:
|
||||
|
||||
<!-- @makeLongSecretFile @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/longsecret.txt
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt
|
||||
ut labore et dolore magna aliqua.
|
||||
EOF
|
||||
```
|
||||
|
||||
And make a kustomization file referring to the
|
||||
above and _additionally_ defining some literal KV
|
||||
pairs in line:
|
||||
|
||||
<!-- @makeKustomization1 @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
|
||||
secretGenerator:
|
||||
- name: mysecrets
|
||||
envs:
|
||||
- foo.env
|
||||
files:
|
||||
- longsecret.txt
|
||||
literals:
|
||||
- FRUIT=apple
|
||||
- VEGETABLE=carrot
|
||||
EOF
|
||||
```
|
||||
|
||||
Now generate the Secret:
|
||||
|
||||
<!-- @build1 @test -->
|
||||
```
|
||||
result=$(kustomize build $DEMO_HOME)
|
||||
echo "$result"
|
||||
# Spot check the result:
|
||||
test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=")
|
||||
```
|
||||
|
||||
This emits something like
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> kind: Secret
|
||||
> metadata:
|
||||
> name: mysecrets-hfb5df789h
|
||||
> type: Opaque
|
||||
> data:
|
||||
> FRUIT: YXBwbGU=
|
||||
> VEGETABLE: Y2Fycm90
|
||||
> ROUTER_PASSWORD: YWRtaW4=
|
||||
> DB_PASSWORD: aWxvdmV5b3U=
|
||||
> longsecret.txt: TG9yZW0gaXBzdW0gZG9sb3Igc2l0I... (elided)
|
||||
> ```
|
||||
|
||||
The name of the resource is the prefix `mysecrets`
|
||||
(as specfied in the kustomization file), followed
|
||||
by a hash of its contents.
|
||||
|
||||
Use your favorite base64 decoder to confirm the raw
|
||||
versions of any of these values.
|
||||
|
||||
The problem that these three approaches share is
|
||||
that the purported secrets must live on disk.
|
||||
|
||||
This adds additional security questions - who can
|
||||
see the files, who installs them, who deletes
|
||||
them, etc.
|
||||
|
||||
|
||||
## Secret values from anywhere
|
||||
|
||||
> New _alpha_ behavior at HEAD, for v2.1+
|
||||
|
||||
A general alternative is to enshrine secret
|
||||
value generation in a [plugin](../docs/plugins.md).
|
||||
|
||||
The values can then come in via, say, an
|
||||
authenticated and authorized RPC to a password
|
||||
vault service.
|
||||
|
||||
[sgp]: ../plugin/someteam.example.com/v1/secretsfromdatabase
|
||||
|
||||
Here's a [secret generator plugin][sgp]
|
||||
that pretends to pull the values of a map
|
||||
from a database.
|
||||
|
||||
|
||||
Download it
|
||||
|
||||
<!-- @copyPlugin @test -->
|
||||
```
|
||||
repo=https://raw.githubusercontent.com/kubernetes-sigs/kustomize
|
||||
pPath=plugin/someteam.example.com/v1/secretsfromdatabase
|
||||
dir=$DEMO_HOME/kustomize/$pPath
|
||||
|
||||
mkdir -p $dir
|
||||
|
||||
curl -s -o $dir/SecretsFromDatabase.go \
|
||||
${repo}/master/$pPath/SecretsFromDatabase.go
|
||||
```
|
||||
|
||||
Compile it
|
||||
|
||||
<!-- @compilePlugin @xtest -->
|
||||
```
|
||||
go build -buildmode plugin \
|
||||
-o $dir/SecretsFromDatabase.so \
|
||||
$dir/SecretsFromDatabase.go
|
||||
```
|
||||
|
||||
|
||||
Create a configuration file for it:
|
||||
|
||||
<!-- @makeConfiguration @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/secretFromDb.yaml
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: SecretsFromDatabase
|
||||
metadata:
|
||||
name: mySecretGenerator
|
||||
name: forbiddenValues
|
||||
namespace: production
|
||||
keys:
|
||||
- ROCKET
|
||||
- VEGETABLE
|
||||
EOF
|
||||
```
|
||||
|
||||
Create a new kustomization file
|
||||
referencing this plugin:
|
||||
|
||||
<!-- @makeKustomization2 @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
|
||||
generators:
|
||||
- secretFromDb.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Finally, generate the secret, setting
|
||||
`XDG_CONFIG_HOME` so that the plugin
|
||||
can be found under `$DEMO_HOME`:
|
||||
|
||||
<!-- @build2 @xtest -->
|
||||
```
|
||||
result=$( \
|
||||
XDG_CONFIG_HOME=$DEMO_HOME \
|
||||
kustomize build --enable_alpha_plugins $DEMO_HOME )
|
||||
echo "$result"
|
||||
# Spot check the result:
|
||||
test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=")
|
||||
```
|
||||
|
||||
This should emit something like:
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> kind: Secret
|
||||
> metadata:
|
||||
> name: mysecrets-bdt27dbkd6
|
||||
> type: Opaque
|
||||
> data:
|
||||
> FRUIT: YXBwbGU=
|
||||
> VEGETABLE: Y2Fycm90
|
||||
> ```
|
||||
|
||||
i.e. a subset of the same values as above.
|
||||
@@ -1,4 +1,4 @@
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
bases:
|
||||
resources:
|
||||
- ../../base
|
||||
namePrefix: staging-
|
||||
configMapGenerator:
|
||||
|
||||
@@ -1,37 +1,85 @@
|
||||
# Transformer Configurations
|
||||
|
||||
Kustomize computes the resources by applying a series of transformers:
|
||||
- namespace transformer
|
||||
- prefix/suffix transformer
|
||||
- label transformer
|
||||
- annotation transformer
|
||||
- name reference transformer
|
||||
- variable reference transformer
|
||||
Kustomize creates new resources by applying a series of transformations to an original
|
||||
set of resources. Kustomize provides the following default transformers:
|
||||
|
||||
Each transformer takes a list of resources and modifies certain fields. The modification is based on the transformer's rule.
|
||||
The fields to update is the transformer's configuration, which is a list of filedspec that can be represented in YAML format.
|
||||
- annotations
|
||||
- images
|
||||
- labels
|
||||
- name reference
|
||||
- namespace
|
||||
- prefix/suffix
|
||||
- variable reference
|
||||
|
||||
## fieldSpec
|
||||
FieldSpec is a type to represent a path to a field in one kind of resources. It has following format
|
||||
```
|
||||
A `fieldSpec` list, in a transformer's configuration, determines which resource types and which fields
|
||||
within those types the transformer can modify.
|
||||
|
||||
## FieldSpec
|
||||
|
||||
FieldSpec is a type that represents a path to a field in one kind of resource.
|
||||
|
||||
```yaml
|
||||
group: some-group
|
||||
version: some-version
|
||||
kind: some-kind
|
||||
path: path/to/the/field
|
||||
create: false
|
||||
```
|
||||
If `create` is set to true, it indicates the transformer to create the path if it is not found in the resources. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation.
|
||||
|
||||
## prefix/suffix transformer
|
||||
Name prefix suffix transformer adds prefix and suffix to the `metadata/name` field for all resources with following configuration:
|
||||
If `create` is set to `true`, the transformer creates the path to the field in the resource if the path is not already found. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation.
|
||||
|
||||
## Images transformer
|
||||
|
||||
The default images transformer updates the specified image key values found in paths that include
|
||||
`containers` and `initcontainers` sub-paths.
|
||||
If found, the `image` key value is customized by the values set in the `newName`, `newTag`, and `digest` fields.
|
||||
The `name` field should match the `image` key value in a resource.
|
||||
|
||||
Example kustomization.yaml:
|
||||
|
||||
```yaml
|
||||
images:
|
||||
- name: postgres
|
||||
newName: my-registry/my-postgres
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: my-demo-app
|
||||
newName: my-app
|
||||
- name: alpine
|
||||
digest: sha256:25a0d4
|
||||
```
|
||||
|
||||
Image transformer configurations can be customized by creating a list of `images` containing the `path` and `kind` fields.
|
||||
The images transformation tutorial shows how to specify the default images transformer and customize the [images transformer configuration](images/README.md).
|
||||
|
||||
## Prefix/suffix transformer
|
||||
|
||||
The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is the default prefix transformer configuration:
|
||||
|
||||
```yaml
|
||||
namePrefix:
|
||||
- path: metadata/name
|
||||
```
|
||||
|
||||
## label transformer
|
||||
Label transformer adds labels to `metadata/labels` field for all resources. It also adds labels to `spec/selector` field in all Service and to `spec/selector/matchLabels` field in all Deployment.
|
||||
Example kustomization.yaml:
|
||||
|
||||
```yaml
|
||||
|
||||
namePrefix:
|
||||
alices-
|
||||
|
||||
nameSuffix:
|
||||
-v2
|
||||
```
|
||||
|
||||
## Labels transformer
|
||||
|
||||
The labels transformer adds labels to the `metadata/labels` field for all resources. It also adds labels to the `spec/selector` field in all Service resources as well as the `spec/selector/matchLabels` field in all Deployment resources.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
commonLabels:
|
||||
- path: metadata/labels
|
||||
create: true
|
||||
@@ -44,15 +92,39 @@ commonLabels:
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
kind: Deployment
|
||||
(etc.)
|
||||
```
|
||||
|
||||
## name reference transformer
|
||||
Name reference transformer's configuration is different from all other transformers. It contains a list of namebackreferences, which represented all the possible fields that a type could be used as a reference in other types of resources. A namebackreference contains a type such as ConfigMap as well as a list of FieldSpecs where ConfigMap is referenced. Here is an example.
|
||||
Example kustomization.yaml:
|
||||
|
||||
```yaml
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
```
|
||||
|
||||
## Annotations transformer
|
||||
|
||||
The annotations transformer adds annotations to the `metadata/annotations` field for all resources.
|
||||
Annotations are also added to `spec/template/metadata/annotations` for Deployment,
|
||||
ReplicaSet, DaemonSet, StatefulSet, Job, and CronJob resources, and `spec/jobTemplate/spec/template/metadata/annotations`
|
||||
for CronJob resources.
|
||||
|
||||
Example kustomization.yaml
|
||||
|
||||
```yaml
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
```
|
||||
|
||||
## Name reference transformer
|
||||
|
||||
Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example:
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
version: v1
|
||||
FieldSpecs:
|
||||
fieldSpecs:
|
||||
- kind: Pod
|
||||
version: v1
|
||||
path: spec/volumes/configMap/name
|
||||
@@ -60,10 +132,11 @@ FieldSpecs:
|
||||
path: spec/template/spec/volumes/configMap/name
|
||||
- kind: Job
|
||||
path: spec/template/spec/volumes/configMap/name
|
||||
(etc.)
|
||||
```
|
||||
Name reference transformer configuration contains a list of such namebackreferences for ConfigMap, Secret, Service, Role, ServiceAccount and so on.
|
||||
```
|
||||
|
||||
Name reference transformer's configuration contains a list of `nameReferences` for resources such as ConfigMap, Secret, Service, Role, and ServiceAccount. Here is an example configuration:
|
||||
|
||||
```yaml
|
||||
nameReference:
|
||||
- kind: ConfigMap
|
||||
version: v1
|
||||
@@ -74,7 +147,7 @@ nameReference:
|
||||
- path: spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
(etc.)
|
||||
# ...
|
||||
- kind: Secret
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
@@ -84,13 +157,22 @@ nameReference:
|
||||
- path: spec/containers/env/valueFrom/secretKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
(etc.)
|
||||
```
|
||||
|
||||
## customizing transformer configurations
|
||||
## Customizing transformer configurations
|
||||
|
||||
In addition to the default transformers, you can create custom transformer configurations. Save the default transformer configurations to a local directory by calling `kustomize config save -d`, and modify and use these configurations. This tutorial shows how to create custom transformer configurations:
|
||||
|
||||
Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to
|
||||
- [support a CRD type](crd/README.md)
|
||||
- disabling adding commonLabels to fields in some kind of resources
|
||||
- add extra fields for variable substitution
|
||||
- add extra fields for name reference
|
||||
|
||||
|
||||
## Supporting escape characters in CRD path
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
foo.k8s.io/bar: baz
|
||||
```
|
||||
Kustomize supports escaping special characters in path, e.g `matadata/annotations/foo.k8s.io\/bar`
|
||||
|
||||
@@ -8,38 +8,6 @@ Create a workspace by
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Get the native config as a starting point
|
||||
|
||||
Get the default transformer configurations using this command:
|
||||
|
||||
<!-- @saveConfig @test -->
|
||||
```
|
||||
kustomize config save -d $DEMO_HOME/kustomizeconfig
|
||||
```
|
||||
The default configurations are saved
|
||||
in the directory `$DEMO_HOME/kustomizeconfig` as several files
|
||||
|
||||
> ```
|
||||
> commonannotations.yaml
|
||||
> commonlabels.yaml
|
||||
> nameprefix.yaml
|
||||
> namereference.yaml
|
||||
> namespace.yaml
|
||||
> varreference.yaml
|
||||
> ```
|
||||
|
||||
These files contain the field specifications for native resources
|
||||
that transformation directives like `namePrefix`, `commonLabels`, etc.
|
||||
need to do their work.
|
||||
|
||||
These default configurations already include some common
|
||||
field specifictions for all types:
|
||||
|
||||
- nameprefix is added to `.metadata.name`
|
||||
- namespace is added to `.metadata.namespace`
|
||||
- labels is added to `.metadata.labels`
|
||||
- annotations is added to `.metadata.annotations`
|
||||
|
||||
### Adding a custom resource
|
||||
|
||||
Consider a CRD of kind `MyKind` with fields
|
||||
@@ -51,6 +19,7 @@ Consider a CRD of kind `MyKind` with fields
|
||||
Add the following file to configure the transformers for the above fields
|
||||
<!-- @addConfig @test -->
|
||||
```
|
||||
mkdir $DEMO_HOME/kustomizeconfig
|
||||
cat > $DEMO_HOME/kustomizeconfig/mykind.yaml << EOF
|
||||
|
||||
commonLabels:
|
||||
@@ -148,12 +117,6 @@ in the kustomization file:
|
||||
cat >> $DEMO_HOME/kustomization.yaml << EOF
|
||||
configurations:
|
||||
- kustomizeconfig/mykind.yaml
|
||||
- kustomizeconfig/commonannotations.yaml
|
||||
- kustomizeconfig/commonlabels.yaml
|
||||
- kustomizeconfig/nameprefix.yaml
|
||||
- kustomizeconfig/namereference.yaml
|
||||
- kustomizeconfig/namespace.yaml
|
||||
- kustomizeconfig/varreference.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
128
examples/transformerconfigs/images/README.md
Normal file
@@ -0,0 +1,128 @@
|
||||
## Images transformations
|
||||
|
||||
This tutorial shows how to modify images in resources, and create a custom images transformer configuration.
|
||||
|
||||
Create a workspace by
|
||||
<!-- @createws @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Adding a custom resource
|
||||
|
||||
Consider a Custom Resource Definition(CRD) of kind `MyKind` with field
|
||||
- `.spec.runLatest.container.image` referencing an image
|
||||
|
||||
Add the following file to configure the images transformer for the CRD:
|
||||
|
||||
<!-- @addConfig @test -->
|
||||
```
|
||||
mkdir $DEMO_HOME/kustomizeconfig
|
||||
cat > $DEMO_HOME/kustomizeconfig/mykind.yaml << EOF
|
||||
|
||||
images:
|
||||
- path: spec/runLatest/container/image
|
||||
kind: MyKind
|
||||
EOF
|
||||
```
|
||||
|
||||
### Apply config
|
||||
|
||||
Create a file with some resources that includes an instance of `MyKind`:
|
||||
|
||||
<!-- @createResource @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/resources.yaml << EOF
|
||||
|
||||
apiVersion: config/v1
|
||||
kind: MyKind
|
||||
metadata:
|
||||
name: testSvc
|
||||
spec:
|
||||
runLatest:
|
||||
container:
|
||||
image: crd-image
|
||||
containers:
|
||||
- image: docker
|
||||
name: ecosystem
|
||||
- image: my-mysql
|
||||
name: testing-1
|
||||
---
|
||||
group: apps
|
||||
apiVersion: v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy1
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
initContainers:
|
||||
- name: nginx2
|
||||
image: my-app
|
||||
- name: init-alpine
|
||||
image: alpine:1.8.0
|
||||
EOF
|
||||
```
|
||||
|
||||
Create a kustomization.yaml referring to it:
|
||||
|
||||
<!-- @createKustomization @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/kustomization.yaml << EOF
|
||||
resources:
|
||||
- resources.yaml
|
||||
|
||||
images:
|
||||
- name: crd-image
|
||||
newName: new-crd-image
|
||||
newTag: new-v1-tag
|
||||
- name: my-app
|
||||
newName: new-app-1
|
||||
newTag: MYNEWTAG-1
|
||||
- name: my-mysql
|
||||
newName: prod-mysql
|
||||
newTag: v3
|
||||
- name: docker
|
||||
newName: my-docker2
|
||||
digest: sha256:25a0d4
|
||||
EOF
|
||||
```
|
||||
|
||||
Use the customized transformer configurations by specifying them
|
||||
in the kustomization file:
|
||||
<!-- @addTransformerConfigs @test -->
|
||||
```
|
||||
cat >> $DEMO_HOME/kustomization.yaml << EOF
|
||||
configurations:
|
||||
- kustomizeconfig/mykind.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Run `kustomize build` and verify that the images have been updated.
|
||||
|
||||
<!-- @build @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "new-crd-image:new-v1-tag" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
<!-- @build @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "new-app-1:MYNEWTAG-1" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
<!-- @build @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "my-docker2@sha" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
<!-- @build @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "prod-mysql:v3" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
19
examples/transformerconfigs/images/kustomization.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
resources:
|
||||
- resources.yaml
|
||||
|
||||
configurations:
|
||||
- kustomizeconfig/mykind.yaml
|
||||
|
||||
images:
|
||||
- name: crd-image
|
||||
newName: new-crd-image
|
||||
newTag: new-v1-tag
|
||||
- name: my-app
|
||||
newName: new-app-1
|
||||
newTag: MYNEWTAG-1
|
||||
- name: my-mysql
|
||||
newName: prod-mysql
|
||||
newTag: v3
|
||||
- name: docker
|
||||
newName: my-docker2
|
||||
digest: sha256:25a0d4
|
||||
3
examples/transformerconfigs/images/mykind.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
images:
|
||||
- path: spec/runLatest/container/image
|
||||
kind: MyKind
|
||||
27
examples/transformerconfigs/images/resources.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: config/v1
|
||||
kind: MyKind
|
||||
metadata:
|
||||
name: testSvc
|
||||
spec:
|
||||
runLatest:
|
||||
container:
|
||||
image: crd-image
|
||||
containers:
|
||||
- image: docker
|
||||
name: ecosystem
|
||||
- image: my-mysql
|
||||
name: testing-1
|
||||
---
|
||||
group: apps
|
||||
apiVersion: v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy1
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
initContainers:
|
||||
- name: nginx2
|
||||
image: my-app
|
||||
- name: init-alpine
|
||||
image: alpine:1.8.0
|
||||
221
examples/validationTransformer/README.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# a transformer plugin performing validation
|
||||
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[kubeval]: https://github.com/instrumenta/kubeval
|
||||
[plugin]: ../../docs/plugins.md
|
||||
|
||||
kustomize doesn't validate either its input or
|
||||
output beyond the validation provided by the
|
||||
marshalling/unmarshalling packages it depends on.
|
||||
|
||||
Another tool, [kubeval], goes beyond this to do
|
||||
k8s aware validation. Here's a usage example:
|
||||
|
||||
```shell
|
||||
$ kubeval my-invalid-rc.yaml
|
||||
The document my-invalid-rc.yaml contains an invalid ReplicationController
|
||||
--> spec.replicas: Invalid type. Expected: integer, given: string
|
||||
```
|
||||
|
||||
One can write a Kustomize transformer [plugin] to
|
||||
run [kubeval] against the resources that have been
|
||||
loaded by Kustomize.
|
||||
|
||||
|
||||
Make a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
mkdir -p $DEMO_HOME/valid
|
||||
mkdir -p $DEMO_HOME/invalid
|
||||
PLUGINDIR=$DEMO_HOME/kustomize/plugin/someteam.example.com/v1/validator
|
||||
mkdir -p $PLUGINDIR
|
||||
```
|
||||
|
||||
## write a transformer plugin
|
||||
|
||||
Download the [kubeval] binary depending on the operating system
|
||||
and add it to $PATH.
|
||||
|
||||
<!-- @downloadKubeval @test -->
|
||||
```
|
||||
OS=`uname | sed -e 's/Linux/linux/' -e 's/Darwin/darwin/'`
|
||||
wget https://github.com/instrumenta/kubeval/releases/download/0.9.2/kubeval-${OS}-amd64.tar.gz
|
||||
tar xf kubeval-${OS}-amd64.tar.gz
|
||||
export PATH=$PATH:`pwd`
|
||||
```
|
||||
|
||||
Kustomize has the following assumption of a transformer plugin:
|
||||
- The resources are passed to the transformer plugin from stdin.
|
||||
- The configuration file for the transformer plugin is passed in
|
||||
as the first argument.
|
||||
- The working directory of the plugin is the kustomization
|
||||
directory where it is used as a transformer.
|
||||
- The transformed resources are written to stdout by the plugin.
|
||||
- If the return code of the transformer plugin is non zero,
|
||||
Kustomize regards there is an error during the transformation.
|
||||
|
||||
A transformer plugin for the validation can be written as a
|
||||
bash script, which execute the [kubeval] binary and return proper
|
||||
output and exit code.
|
||||
|
||||
<!-- @writePlugin @test -->
|
||||
```
|
||||
cat <<'EOF' > $PLUGINDIR/Validator
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -x "$(command -v kubeval)" ]; then
|
||||
echo "Error: kubeval is not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
temp_file=$(mktemp)
|
||||
output_file=$(mktemp)
|
||||
cat - > $temp_file
|
||||
|
||||
kubeval $temp_file > $output_file
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
cat $temp_file
|
||||
rm $temp_file $output_file
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat $output_file
|
||||
rm $temp_file $output_file
|
||||
exit 1
|
||||
|
||||
EOF
|
||||
chmod +x $PLUGINDIR/Validator
|
||||
```
|
||||
|
||||
## use the transformer plugin
|
||||
|
||||
Define a kustomization containing a valid ConfigMap
|
||||
and the transformer plugin.
|
||||
|
||||
<!-- @writeKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/valid/configmap.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm
|
||||
data:
|
||||
foo: bar
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >$DEMO_HOME/valid/validation.yaml
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: Validator
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >$DEMO_HOME/valid/kustomization.yaml
|
||||
resources:
|
||||
- configmap.yaml
|
||||
|
||||
transformers:
|
||||
- validation.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a kustomization containing an invalid ConfigMap
|
||||
and the transformer plugin.
|
||||
|
||||
<!-- @writeKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/invalid/configmap.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm
|
||||
data:
|
||||
- foo: bar
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >$DEMO_HOME/invalid/validation.yaml
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: Validator
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >$DEMO_HOME/invalid/kustomization.yaml
|
||||
resources:
|
||||
- configmap.yaml
|
||||
|
||||
transformers:
|
||||
- validation.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
The directory structure is as the following:
|
||||
|
||||
```
|
||||
/tmp/tmp.fAYMfLZJs4
|
||||
├── invalid
|
||||
│ ├── configmap.yaml
|
||||
│ ├── kustomization.yaml
|
||||
│ └── validation.yaml
|
||||
├── kustomize
|
||||
│ └── plugin
|
||||
│ └── someteam.example.com
|
||||
│ └── v1
|
||||
│ ├── kubeval
|
||||
│ └── Validator
|
||||
└── valid
|
||||
├── configmap.yaml
|
||||
├── kustomization.yaml
|
||||
└── validation.yaml
|
||||
```
|
||||
|
||||
Define a helper function to run kustomize with the
|
||||
correct environment and flags for plugins:
|
||||
|
||||
<!-- @defineKustomizeBd @test -->
|
||||
```
|
||||
function kustomizeBd {
|
||||
XDG_CONFIG_HOME=$DEMO_HOME \
|
||||
kustomize build \
|
||||
--enable_alpha_plugins \
|
||||
$DEMO_HOME/$1
|
||||
}
|
||||
```
|
||||
|
||||
Build the valid variant
|
||||
|
||||
<!-- @buildValid @test -->
|
||||
```
|
||||
kustomizeBd valid
|
||||
```
|
||||
The output contains a ConfigMap as
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
foo: bar
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm
|
||||
```
|
||||
|
||||
Build the invalid variant
|
||||
|
||||
```
|
||||
kustomizeBd invalid
|
||||
```
|
||||
|
||||
The output is an error as
|
||||
```shell
|
||||
data: Invalid type. Expected: object, given: array
|
||||
```
|
||||
|
||||
## cleanup
|
||||
|
||||
<!-- @cleanup @test -->
|
||||
```shell
|
||||
rm -rf $DEMO_HOME
|
||||
```
|
||||
6
examples/validationTransformer/invalid.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm
|
||||
data:
|
||||
- foo: bar
|
||||
6
examples/validationTransformer/valid.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm
|
||||
data:
|
||||
foo: bar
|
||||
@@ -44,17 +44,19 @@ curl -s -o "$MYSQL_HOME/#1.yaml" \
|
||||
```
|
||||
|
||||
### Create kustomization.yaml
|
||||
Create a new kustomization with two bases:
|
||||
|
||||
Create a new kustomization with two bases,
|
||||
`wordpress` and `mysql`:
|
||||
|
||||
<!-- @createKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- wordpress
|
||||
- mysql
|
||||
resources:
|
||||
- wordpress
|
||||
- mysql
|
||||
namePrefix: demo-
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
- patch.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
@@ -143,4 +145,4 @@ Expect this in the output:
|
||||
> image: debian
|
||||
> name: init-command
|
||||
>
|
||||
> ```
|
||||
> ```
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
bases:
|
||||
- wordpress
|
||||
- mysql
|
||||
resources:
|
||||
- wordpress
|
||||
- mysql
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
- 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
|
||||
- name: WORDPRESS_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: wordpress
|
||||
apiVersion: v1
|
||||
- name: MYSQL_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: mysql
|
||||
apiVersion: v1
|
||||
|
||||
|
||||
55
examples/zh/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
[English](../README.md) | 简体中文
|
||||
|
||||
# 示例
|
||||
|
||||
这些示例默认 `kustomize` 在您的 `$PATH` 中。
|
||||
|
||||
这些示例通过了 [pre-commit](../../travis/pre-commit.sh) 测试,并且应该与 HEAD 一起使用。
|
||||
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
```
|
||||
|
||||
基本用法
|
||||
|
||||
* [configGenerations](../configGeneration.md) - 当 ConfigMapGenerator 修改时进行滚动更新。
|
||||
|
||||
* [combineConfigs](../combineConfigs.md) - 融合来自不同用户的配置数据(例如来自 devops/SRE 和 developers)。
|
||||
|
||||
* [generatorOptions](../generatorOptions.md) -修改所有 ConfigMapGenerator 和 SecretGenerator 的行为。
|
||||
|
||||
* [vars](../wordpress/README.md) - 通过 vars 将一个资源的数据注入另一个资源的容器参数 (例如,为 wordpress 指定 SQL 服务)。
|
||||
|
||||
* [image names and tags](../image.md) - 在不使用 patch 的情况下更新镜像名称和标签。
|
||||
|
||||
* [remote target](../remoteBuild.md) - 通过 github URL 来构建 kustomization 。
|
||||
|
||||
* [json patch](../jsonpatch.md) -在 kustomization 中应用 json patch 。
|
||||
|
||||
高级用法
|
||||
|
||||
- generator 插件:
|
||||
|
||||
* [last mile helm](../chart.md) - 对 helm chart 进行 last mile 修改。
|
||||
|
||||
* [secret generation](../secretGeneratorPlugin.md) - 生成 Secret。
|
||||
|
||||
- 定制内建 transformer 配置
|
||||
|
||||
* [transformer configs](../transformerconfigs/README.md) - 自定义 transformer 配置。
|
||||
|
||||
多 Variant 示例
|
||||
|
||||
* [hello world](helloWorld.md) - 部署多个不同配置的 Hello World 服务。
|
||||
|
||||
* [LDAP](../ldap/README.md) - 部署多个配置不同的 LDAP 服务。
|
||||
|
||||
* [springboot](../springboot/README.md) - 从头开始创建一个 Spring Boot 项目的生产配置。
|
||||
|
||||
* [mySql](../mySql/README.md) - 从头开始创建一个 MySQL 的生产配置。
|
||||
|
||||
* [breakfast](../breakfast.md) - 给 Alice 和 Bob 定制一顿早餐 :)
|
||||
|
||||
* [multibases](../multibases/README.md) - 使用相同的 base 生成三个 variants(dev,staging,production)。
|
||||
|
||||
>声明:部分文档可能稍微滞后于英文版本,同步工作持续进行中
|
||||
301
examples/zh/helloWorld.md
Normal file
@@ -0,0 +1,301 @@
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[config]: https://github.com/kinflate/example-hello
|
||||
[gitops]: ../../docs/glossary.md#gitops
|
||||
[hello]: https://github.com/monopole/hello
|
||||
[kustomization]: ../../docs/glossary.md#kustomization
|
||||
[original]: https://github.com/kinflate/example-hello
|
||||
[overlay]: ../../docs/glossary.md#overlay
|
||||
[overlays]: ../../docs/glossary.md#overlay
|
||||
[patch]: ../../docs/glossary.md#patch
|
||||
[variant]: ../../docs/glossary.md#variant
|
||||
[variants]: ../../docs/glossary.md#variant
|
||||
|
||||
# Demo: hello world with variants
|
||||
|
||||
步骤:
|
||||
|
||||
1. 下载 [base] 配置。
|
||||
2. 进行定制。
|
||||
3. 基于定制后的 base 新建2个不同的 [overlays] (_staging_ 和 _production_)。
|
||||
4. 运行 kustomize 和 kubectl 来部署 staging 和 production 。
|
||||
|
||||
首先创建一个工作空间:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/hello
|
||||
> ```
|
||||
|
||||
## 创建 base
|
||||
|
||||
如果要使用 [overlays] 创建 [variants] ,必须先创建一个共同的 [base] 。
|
||||
|
||||
为了使本文档保持简洁,base 的资源位于补充目录中,并不在此处,请按照下面的方法下载它们:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/helloWorld\
|
||||
/{configMap,deployment,kustomization,service}.yaml"
|
||||
```
|
||||
|
||||
观察该目录:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
可以看到:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── configMap.yaml
|
||||
> ├── deployment.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
这些 resources 可以立即在 k8s 集群中部署:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
实例化 _hello_ 服务, `kubectl` 只能识别 resources 文件。
|
||||
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
`base` 目录中包含一个 [kustomization] 文件:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
(可选)在 base 目录上运行 `kustomize` 将定制过的 resources 打印到标准输出:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### 定制 base
|
||||
|
||||
定制 _app label_ 并应用于所有的 resources :
|
||||
|
||||
<!-- @addLabel @test -->
|
||||
```
|
||||
sed -i.bak 's/app: hello/app: my-hello/' \
|
||||
$BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
查看效果:
|
||||
<!-- @checkLabel @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 app:
|
||||
```
|
||||
|
||||
## 创建 Overlays
|
||||
|
||||
创建包含 _staging_ 和 _production_ 的 [overlay]:
|
||||
|
||||
* _Staging_ 包含生产环境中无法应用的带有风险的功能。
|
||||
* _Production_ 包含更多的副本数。
|
||||
* 来自这些集群 [variants] 的问候消息将与来自其他集群的不同。
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
在 `staging` 目录中创建一个 kustomization 文件,用来定义一个新的名称前缀和一些不同的 labels 。
|
||||
|
||||
<!-- @makeStagingKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||
namePrefix: staging-
|
||||
commonLabels:
|
||||
variant: staging
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- map.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Staging Patch
|
||||
|
||||
新增一个自定义的 configMap 将问候消息从 _Good Morning!_ 改为 _Have a pineapple!_ 。
|
||||
|
||||
同时,将 _risky_ 标记设置为 true 。
|
||||
|
||||
<!-- @stagingMap @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Have a pineapple!"
|
||||
enableRisky: "true"
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
在 `production` 目录中创建一个 kustomization 文件,用来定义一个新的名称前缀和 labels 。
|
||||
|
||||
<!-- @makeProductionKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
namePrefix: production-
|
||||
commonLabels:
|
||||
variant: production
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am production!
|
||||
resources:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
#### Production Patch
|
||||
|
||||
因为生产环境需要处理更多的流量,新建一个 production patch 来增加副本数。
|
||||
|
||||
<!-- @productionDeployment @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 10
|
||||
EOF
|
||||
```
|
||||
|
||||
## 比较 overlays
|
||||
|
||||
|
||||
`DEMO_HOME` 现在包含:
|
||||
|
||||
- _base_ 目录:对拉取到的源配置进行了简单定制
|
||||
|
||||
- _overlays_ 目录:包含在集群中创建不同 _staging_ 和 _production_ [variants] 的 kustomizations 和 patches 。
|
||||
|
||||
查看目录结构和差异:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
可以看到:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── configMap.yaml
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── kustomization.yaml
|
||||
> └── map.yaml
|
||||
> ```
|
||||
|
||||
直接比较 _staging_ 和 _production_ 输出的不同:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
部分比较输出:
|
||||
|
||||
> ```diff
|
||||
> < altGreeting: Have a pineapple!
|
||||
> < enableRisky: "true"
|
||||
> ---
|
||||
> > altGreeting: Good Morning!
|
||||
> > enableRisky: "false"
|
||||
> 8c8
|
||||
> < note: Hello, I am staging!
|
||||
> ---
|
||||
> > note: Hello, I am production!
|
||||
> 11c11
|
||||
> < variant: staging
|
||||
> ---
|
||||
> > variant: production
|
||||
> 13c13
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## 部署
|
||||
|
||||
输出不同 _overlys_ 的配置:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
将上述命令传递给 kubectl 进行部署:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
也可使用 `kubectl` (v1.14.0 以上版本):
|
||||
|
||||
> ```
|
||||
> kubectl apply -k $OVERLAYS/staging
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kubectl apply -k $OVERLAYS/production
|
||||
> ```
|
||||
38
go.mod
Normal file
@@ -0,0 +1,38 @@
|
||||
module sigs.k8s.io/kustomize
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/purell v1.1.0 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/emicklei/go-restful v2.9.3+incompatible // indirect
|
||||
github.com/evanphx/json-patch v3.0.0+incompatible
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa // indirect
|
||||
github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d // indirect
|
||||
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee
|
||||
github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 // indirect
|
||||
github.com/gogo/protobuf v1.0.0 // indirect
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
|
||||
github.com/googleapis/gnostic v0.1.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81 // indirect
|
||||
github.com/onsi/ginkgo v1.8.0 // indirect
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/spf13/cobra v0.0.2
|
||||
github.com/spf13/pflag v1.0.1
|
||||
github.com/stretchr/testify v1.3.0 // indirect
|
||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
k8s.io/api v0.0.0-20180510062335-53d615ae3f44
|
||||
k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6
|
||||
k8s.io/client-go v7.0.0+incompatible
|
||||
k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
)
|
||||
99
go.sum
Normal file
@@ -0,0 +1,99 @@
|
||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emicklei/go-restful v2.9.3+incompatible h1:2OwhVdhtzYUp5P5wuGsVDPagKSRd9JK72sJCHVCXh5g=
|
||||
github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v3.0.0+incompatible h1:l91aby7TzBXBdmF8heZqjskeH9f3g7ZOL8/sSe+vTlU=
|
||||
github.com/evanphx/json-patch v3.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa h1:hr8WVDjg4JKtQptZpzyb196TmruCs7PIsdJz8KAOZp8=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d h1:k3UQ7Z8yFYq0BNkYykKIheY0HlZBl1Hku+pO9HE9FNU=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee h1:eo0HQoNFtbiEc7+1gRF9pgW6azx8a1cO2fXcqq1MuD0=
|
||||
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 h1:+vsw187FKvA2QUGAcE+vQSfyxqLbUXixPYRRMAzwu04=
|
||||
github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece h1:3HJXp/18JmMk5sjBP3LDUBtWjczCvynxaeAF6b6kWp8=
|
||||
github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 h1:hOnidOuIWNsFRPcxxStGeN3NNm4n4+w6KJ9cVJIh70o=
|
||||
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81 h1:ImOHKpmdLPXWX5KSYquUWXKaopEPuY7TPPUo18u9aOI=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/spf13/cobra v0.0.2 h1:NfkwRbgViGoyjBKsLI0QMDcuMnhM+SBg3T0cGfpvKDE=
|
||||
github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190225153610-fe579d43d832 h1:2IdId8zoI92l1bUzjAOygcAOkmCe13HY1j0rqPPPzB8=
|
||||
golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d h1:bt+R27hbE7uVf7PY9S6wpNg9Xo2WRe/XQT0uGq9RQQw=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 h1:sU3tSV6wDhWsvf9NjL0FzRjgAmYnQL5NEhdmcN16UEg=
|
||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
k8s.io/api v0.0.0-20180510062335-53d615ae3f44 h1:zQ8YhMpuc1QJoor+Vm1moP9iEOyaQgOjSj3bo/zUEXE=
|
||||
k8s.io/api v0.0.0-20180510062335-53d615ae3f44/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6 h1:pJrzRmry9HLPxkVGMk57cfeGRy/WG0oYXuji9t4zD1M=
|
||||
k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/client-go v7.0.0+incompatible h1:kiH+Y6hn+pc78QS/mtBfMJAMIIaWevHi++JvOGEEQp4=
|
||||
k8s.io/client-go v7.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288 h1:AhFqcaw5JbAAaZHxTe1fT+Jtek0pZmIwwt6FbsMA9to=
|
||||
k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
// Package error has contextual error types.
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import "fmt"
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import "fmt"
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import "fmt"
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
// Package error has contextual error types.
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
package kusterr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,18 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package loadertest holds a fake for the Loader interface.
|
||||
package loadertest
|
||||
@@ -22,6 +9,8 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
"sigs.k8s.io/kustomize/pkg/validators"
|
||||
)
|
||||
|
||||
// FakeLoader encapsulates the delegate Loader and the fake file system.
|
||||
@@ -31,12 +20,23 @@ type FakeLoader struct {
|
||||
}
|
||||
|
||||
// NewFakeLoader returns a Loader that uses a fake filesystem.
|
||||
// The argument should be an absolute file path.
|
||||
// The loader will be restricted to root only.
|
||||
// The initialDir argument should be an absolute file path.
|
||||
func NewFakeLoader(initialDir string) FakeLoader {
|
||||
return NewFakeLoaderWithRestrictor(
|
||||
loader.RestrictionRootOnly, initialDir)
|
||||
}
|
||||
|
||||
// NewFakeLoaderWithRestrictor returns a Loader that
|
||||
// uses a fake filesystem.
|
||||
// The initialDir argument should be an absolute file path.
|
||||
func NewFakeLoaderWithRestrictor(
|
||||
lr loader.LoadRestrictorFunc, initialDir string) FakeLoader {
|
||||
// Create fake filesystem and inject it into initial Loader.
|
||||
fSys := fs.MakeFakeFS()
|
||||
fSys.Mkdir(initialDir)
|
||||
ldr, err := loader.NewLoader(initialDir, fSys)
|
||||
ldr, err := loader.NewLoader(
|
||||
lr, validators.MakeFakeValidator(), initialDir, fSys)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to make loader: %v", err)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func (f FakeLoader) AddDirectory(fullDirPath string) error {
|
||||
return f.fs.Mkdir(fullDirPath)
|
||||
}
|
||||
|
||||
// Root returns root.
|
||||
// Root delegates.
|
||||
func (f FakeLoader) Root() string {
|
||||
return f.delegate.Root()
|
||||
}
|
||||
@@ -67,12 +67,22 @@ func (f FakeLoader) New(newRoot string) (ifc.Loader, error) {
|
||||
return FakeLoader{fs: f.fs, delegate: l}, nil
|
||||
}
|
||||
|
||||
// Load performs load from a given location.
|
||||
// Load delegates.
|
||||
func (f FakeLoader) Load(location string) ([]byte, error) {
|
||||
return f.delegate.Load(location)
|
||||
}
|
||||
|
||||
// Cleanup does nothing
|
||||
// Cleanup delegates.
|
||||
func (f FakeLoader) Cleanup() error {
|
||||
return nil
|
||||
return f.delegate.Cleanup()
|
||||
}
|
||||
|
||||
// Validator delegates.
|
||||
func (f FakeLoader) Validator() ifc.Validator {
|
||||
return f.delegate.Validator()
|
||||
}
|
||||
|
||||
// LoadKvPairs delegates.
|
||||
func (f FakeLoader) LoadKvPairs(args types.GeneratorArgs) ([]types.Pair, error) {
|
||||
return f.delegate.LoadKvPairs(args)
|
||||
}
|
||||
@@ -1,49 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package configmapandsecret generates configmaps and secrets per generator rules.
|
||||
package configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/api/core/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// ConfigMapFactory makes ConfigMaps.
|
||||
type ConfigMapFactory struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
// NewConfigMapFactory returns a new ConfigMapFactory.
|
||||
func NewConfigMapFactory(l ifc.Loader) *ConfigMapFactory {
|
||||
return &ConfigMapFactory{ldr: l}
|
||||
}
|
||||
|
||||
func (f *ConfigMapFactory) makeFreshConfigMap(
|
||||
args *types.ConfigMapArgs) *corev1.ConfigMap {
|
||||
cm := &corev1.ConfigMap{}
|
||||
func makeFreshConfigMap(
|
||||
args *types.ConfigMapArgs) *v1.ConfigMap {
|
||||
cm := &v1.ConfigMap{}
|
||||
cm.APIVersion = "v1"
|
||||
cm.Kind = "ConfigMap"
|
||||
cm.Name = args.Name
|
||||
@@ -53,74 +24,48 @@ func (f *ConfigMapFactory) makeFreshConfigMap(
|
||||
}
|
||||
|
||||
// MakeConfigMap returns a new ConfigMap, or nil and an error.
|
||||
func (f *ConfigMapFactory) MakeConfigMap(
|
||||
args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) {
|
||||
var all []kv.Pair
|
||||
var err error
|
||||
cm := f.makeFreshConfigMap(args)
|
||||
|
||||
pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource)
|
||||
func (f *Factory) MakeConfigMap(
|
||||
args *types.ConfigMapArgs) (*v1.ConfigMap, error) {
|
||||
all, err := f.ldr.LoadKvPairs(args.GeneratorArgs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"env source file: %s",
|
||||
args.EnvSource))
|
||||
return nil, err
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromLiteralSources(args.LiteralSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"literal sources %v", args.LiteralSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"file sources: %v", args.FileSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
cm := makeFreshConfigMap(args)
|
||||
for _, p := range all {
|
||||
err = addKvToConfigMap(cm, p.Key, p.Value)
|
||||
err = f.addKvToConfigMap(cm, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options != nil {
|
||||
cm.SetLabels(options.Labels)
|
||||
cm.SetAnnotations(options.Annotations)
|
||||
if f.options != nil {
|
||||
cm.SetLabels(f.options.Labels)
|
||||
cm.SetAnnotations(f.options.Annotations)
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
// addKvToConfigMap adds the given key and data to the given config map.
|
||||
// Error if key invalid, or already exists.
|
||||
func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error {
|
||||
// Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys.
|
||||
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||
return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";"))
|
||||
func (f *Factory) addKvToConfigMap(configMap *v1.ConfigMap, p types.Pair) error {
|
||||
if err := f.ldr.Validator().ErrIfInvalidKey(p.Key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keyExistsErrorMsg := "cannot add key %s, another key by that name already exists: %v"
|
||||
|
||||
// If the configmap data contains byte sequences that are all in the UTF-8
|
||||
// range, we will write it to .Data
|
||||
if utf8.Valid([]byte(data)) {
|
||||
if _, entryExists := configMap.Data[keyName]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.Data)
|
||||
if utf8.Valid([]byte(p.Value)) {
|
||||
if _, entryExists := configMap.Data[p.Key]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, p.Key, configMap.Data)
|
||||
}
|
||||
configMap.Data[keyName] = data
|
||||
configMap.Data[p.Key] = p.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
// otherwise, it's BinaryData
|
||||
if configMap.BinaryData == nil {
|
||||
configMap.BinaryData = map[string][]byte{}
|
||||
}
|
||||
if _, entryExists := configMap.BinaryData[keyName]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.BinaryData)
|
||||
if _, entryExists := configMap.BinaryData[p.Key]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, p.Key, configMap.BinaryData)
|
||||
}
|
||||
configMap.BinaryData[keyName] = []byte(data)
|
||||
configMap.BinaryData[p.Key] = []byte(p.Value)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package configmapandsecret
|
||||
|
||||
@@ -25,6 +12,7 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
"sigs.k8s.io/kustomize/pkg/validators"
|
||||
)
|
||||
|
||||
func makeEnvConfigMap(name string) *corev1.ConfigMap {
|
||||
@@ -98,7 +86,7 @@ func TestConstructConfigMap(t *testing.T) {
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Name: "envConfigMap",
|
||||
DataSources: types.DataSources{
|
||||
EnvSource: "configmap/app.env",
|
||||
EnvSources: []string{"configmap/app.env"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -141,9 +129,10 @@ func TestConstructConfigMap(t *testing.T) {
|
||||
fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n"))
|
||||
fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n"))
|
||||
fSys.WriteFile("/configmap/app.bin", []byte{0xff, 0xfd})
|
||||
f := NewConfigMapFactory(loader.NewFileLoaderAtRoot(fSys))
|
||||
ldr := loader.NewFileLoaderAtRoot(validators.MakeFakeValidator(), fSys)
|
||||
for _, tc := range testCases {
|
||||
cm, err := f.MakeConfigMap(&tc.input, tc.options)
|
||||
f := NewFactory(ldr, tc.options)
|
||||
cm, err := f.MakeConfigMap(&tc.input)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
23
k8sdeps/configmapandsecret/factory.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package configmapandsecret
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// Factory makes ConfigMaps and Secrets.
|
||||
type Factory struct {
|
||||
ldr ifc.Loader
|
||||
options *types.GeneratorOptions
|
||||
}
|
||||
|
||||
// NewFactory returns a new factory that makes ConfigMaps and Secrets.
|
||||
func NewFactory(
|
||||
ldr ifc.Loader, o *types.GeneratorOptions) *Factory {
|
||||
return &Factory{ldr: ldr, options: o}
|
||||
}
|
||||
|
||||
const keyExistsErrorMsg = "cannot add key %s, another key by that name already exists: %v"
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) {
|
||||
var kvs []kv.Pair
|
||||
for _, s := range sources {
|
||||
k, v, err := parseLiteralSource(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kvs = append(kvs, kv.Pair{Key: k, Value: v})
|
||||
}
|
||||
return kvs, nil
|
||||
}
|
||||
|
||||
func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.Pair, error) {
|
||||
var kvs []kv.Pair
|
||||
for _, s := range sources {
|
||||
k, fPath, err := parseFileSource(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := ldr.Load(fPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kvs = append(kvs, kv.Pair{Key: k, Value: string(content)})
|
||||
}
|
||||
return kvs, nil
|
||||
}
|
||||
|
||||
func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.Pair, error) {
|
||||
if path == "" {
|
||||
return nil, nil
|
||||
}
|
||||
content, err := l.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kv.KeyValuesFromLines(content)
|
||||
}
|
||||
|
||||
// parseFileSource parses the source given.
|
||||
//
|
||||
// Acceptable formats include:
|
||||
// 1. source-path: the basename will become the key name
|
||||
// 2. source-name=source-path: the source-name will become the key name and
|
||||
// source-path is the path to the key file.
|
||||
//
|
||||
// Key names cannot include '='.
|
||||
func parseFileSource(source string) (keyName, filePath string, err error) {
|
||||
numSeparators := strings.Count(source, "=")
|
||||
switch {
|
||||
case numSeparators == 0:
|
||||
return path.Base(source), source, nil
|
||||
case numSeparators == 1 && strings.HasPrefix(source, "="):
|
||||
return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "="))
|
||||
case numSeparators == 1 && strings.HasSuffix(source, "="):
|
||||
return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "="))
|
||||
case numSeparators > 1:
|
||||
return "", "", errors.New("key names or file paths cannot contain '='")
|
||||
default:
|
||||
components := strings.Split(source, "=")
|
||||
return components[0], components[1], nil
|
||||
}
|
||||
}
|
||||
|
||||
// parseLiteralSource parses the source key=val pair into its component pieces.
|
||||
// This functionality is distinguished from strings.SplitN(source, "=", 2) since
|
||||
// it returns an error in the case of empty keys, values, or a missing equals sign.
|
||||
func parseLiteralSource(source string) (keyName, value string, err error) {
|
||||
// leading equal is invalid
|
||||
if strings.Index(source, "=") == 0 {
|
||||
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||
}
|
||||
// split after the first equal (so values can have the = character)
|
||||
items := strings.SplitN(source, "=", 2)
|
||||
if len(items) != 2 {
|
||||
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||
}
|
||||
return items[0], strings.Trim(items[1], "\"'"), nil
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 configmapandsecret
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/loader"
|
||||
)
|
||||
|
||||
func TestKeyValuesFromFileSources(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
sources []string
|
||||
expected []kv.Pair
|
||||
}{
|
||||
{
|
||||
description: "create kvs from file sources",
|
||||
sources: []string{"files/app-init.ini"},
|
||||
expected: []kv.Pair{
|
||||
{
|
||||
Key: "app-init.ini",
|
||||
Value: "FOO=bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
fSys := fs.MakeFakeFS()
|
||||
fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar"))
|
||||
for _, tc := range tests {
|
||||
kvs, err := keyValuesFromFileSources(loader.NewFileLoaderAtRoot(fSys), tc.sources)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(kvs, tc.expected) {
|
||||
t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, kvs, tc.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,17 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// SecretFactory makes Secrets.
|
||||
type SecretFactory struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
// NewSecretFactory returns a new SecretFactory.
|
||||
func NewSecretFactory(ldr ifc.Loader) *SecretFactory {
|
||||
return &SecretFactory{ldr: ldr}
|
||||
}
|
||||
|
||||
func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret {
|
||||
func makeFreshSecret(
|
||||
args *types.SecretArgs) *corev1.Secret {
|
||||
s := &corev1.Secret{}
|
||||
s.APIVersion = "v1"
|
||||
s.Kind = "Secret"
|
||||
@@ -53,53 +26,32 @@ func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret {
|
||||
}
|
||||
|
||||
// MakeSecret returns a new secret.
|
||||
func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) {
|
||||
var all []kv.Pair
|
||||
var err error
|
||||
s := f.makeFreshSecret(args)
|
||||
|
||||
pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource)
|
||||
func (f *Factory) MakeSecret(
|
||||
args *types.SecretArgs) (*corev1.Secret, error) {
|
||||
all, err := f.ldr.LoadKvPairs(args.GeneratorArgs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"env source file: %s",
|
||||
args.EnvSource))
|
||||
return nil, err
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromLiteralSources(args.LiteralSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"literal sources %v", args.LiteralSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"file sources: %v", args.FileSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
s := makeFreshSecret(args)
|
||||
for _, p := range all {
|
||||
err = addKvToSecret(s, p.Key, p.Value)
|
||||
err = f.addKvToSecret(s, p.Key, p.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options != nil {
|
||||
s.SetLabels(options.Labels)
|
||||
s.SetAnnotations(options.Annotations)
|
||||
if f.options != nil {
|
||||
s.SetLabels(f.options.Labels)
|
||||
s.SetAnnotations(f.options.Annotations)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func addKvToSecret(secret *corev1.Secret, keyName, data string) error {
|
||||
// Note, the rules for SecretKeys keys are the exact same as the ones for ConfigMap.
|
||||
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||
return fmt.Errorf("%q is not a valid key name for a Secret: %s", keyName, strings.Join(errs, ";"))
|
||||
func (f *Factory) addKvToSecret(secret *corev1.Secret, keyName, data string) error {
|
||||
if err := f.ldr.Validator().ErrIfInvalidKey(keyName); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, entryExists := secret.Data[keyName]; entryExists {
|
||||
return fmt.Errorf("cannot add key %s, another key by that name already exists", keyName)
|
||||
return fmt.Errorf(keyExistsErrorMsg, keyName, secret.Data)
|
||||
}
|
||||
secret.Data[keyName] = []byte(data)
|
||||
return nil
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package configmapandsecret
|
||||
|
||||
@@ -25,6 +12,7 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
"sigs.k8s.io/kustomize/pkg/validators"
|
||||
)
|
||||
|
||||
func makeEnvSecret(name string) *corev1.Secret {
|
||||
@@ -96,7 +84,7 @@ func TestConstructSecret(t *testing.T) {
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Name: "envSecret",
|
||||
DataSources: types.DataSources{
|
||||
EnvSource: "secret/app.env",
|
||||
EnvSources: []string{"secret/app.env"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -138,9 +126,10 @@ func TestConstructSecret(t *testing.T) {
|
||||
fSys := fs.MakeFakeFS()
|
||||
fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n"))
|
||||
fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n"))
|
||||
f := NewSecretFactory(loader.NewFileLoaderAtRoot(fSys))
|
||||
ldr := loader.NewFileLoaderAtRoot(validators.MakeFakeValidator(), fSys)
|
||||
for _, tc := range testCases {
|
||||
cm, err := f.MakeSecret(&tc.input, tc.options)
|
||||
f := NewFactory(ldr, tc.options)
|
||||
cm, err := f.MakeSecret(&tc.input)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,34 +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 k8sdeps provides kustomize factory with k8s dependencies
|
||||
package k8sdeps
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
|
||||
"sigs.k8s.io/kustomize/k8sdeps/transformer"
|
||||
"sigs.k8s.io/kustomize/k8sdeps/validator"
|
||||
"sigs.k8s.io/kustomize/pkg/factory"
|
||||
)
|
||||
|
||||
// NewFactory creates an instance of KustFactory using k8sdeps factories
|
||||
func NewFactory() *factory.KustFactory {
|
||||
return factory.NewKustFactory(
|
||||
kunstruct.NewKunstructuredFactoryImpl(),
|
||||
validator.NewKustValidator(),
|
||||
transformer.NewFactoryImpl(),
|
||||
)
|
||||
}
|
||||
@@ -1,18 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package kunstruct
|
||||
|
||||
@@ -31,15 +18,20 @@ import (
|
||||
|
||||
// KunstructuredFactoryImpl hides construction using apimachinery types.
|
||||
type KunstructuredFactoryImpl struct {
|
||||
cmFactory *configmapandsecret.ConfigMapFactory
|
||||
secretFactory *configmapandsecret.SecretFactory
|
||||
hasher *kustHash
|
||||
}
|
||||
|
||||
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
|
||||
|
||||
// NewKunstructuredFactoryImpl returns a factory.
|
||||
func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory {
|
||||
return &KunstructuredFactoryImpl{}
|
||||
return &KunstructuredFactoryImpl{hasher: NewKustHash()}
|
||||
}
|
||||
|
||||
// Hasher returns a kunstructured hasher
|
||||
// input: kunstructured; output: string hash.
|
||||
func (kf *KunstructuredFactoryImpl) Hasher() ifc.KunstructuredHasher {
|
||||
return kf.hasher
|
||||
}
|
||||
|
||||
// SliceFromBytes returns a slice of Kunstructured.
|
||||
@@ -79,27 +71,29 @@ func (kf *KunstructuredFactoryImpl) FromMap(
|
||||
}
|
||||
|
||||
// MakeConfigMap returns an instance of Kunstructured for ConfigMap
|
||||
func (kf *KunstructuredFactoryImpl) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||
cm, err := kf.cmFactory.MakeConfigMap(args, options)
|
||||
func (kf *KunstructuredFactoryImpl) MakeConfigMap(
|
||||
ldr ifc.Loader,
|
||||
options *types.GeneratorOptions,
|
||||
args *types.ConfigMapArgs) (ifc.Kunstructured, error) {
|
||||
o, err := configmapandsecret.NewFactory(
|
||||
ldr, options).MakeConfigMap(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewKunstructuredFromObject(cm)
|
||||
return NewKunstructuredFromObject(o)
|
||||
}
|
||||
|
||||
// MakeSecret returns an instance of Kunstructured for Secret
|
||||
func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||
sec, err := kf.secretFactory.MakeSecret(args, options)
|
||||
func (kf *KunstructuredFactoryImpl) MakeSecret(
|
||||
ldr ifc.Loader,
|
||||
options *types.GeneratorOptions,
|
||||
args *types.SecretArgs) (ifc.Kunstructured, error) {
|
||||
o, err := configmapandsecret.NewFactory(
|
||||
ldr, options).MakeSecret(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewKunstructuredFromObject(sec)
|
||||
}
|
||||
|
||||
// Set sets loader
|
||||
func (kf *KunstructuredFactoryImpl) Set(ldr ifc.Loader) {
|
||||
kf.cmFactory = configmapandsecret.NewConfigMapFactory(ldr)
|
||||
kf.secretFactory = configmapandsecret.NewSecretFactory(ldr)
|
||||
return NewKunstructuredFromObject(o)
|
||||
}
|
||||
|
||||
// validate validates that u has kind and name
|
||||
|
||||
123
k8sdeps/kunstruct/hasher.go
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package kunstruct
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/kustomize/pkg/hasher"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
// kustHash computes a hash of an unstructured object.
|
||||
type kustHash struct{}
|
||||
|
||||
// NewKustHash returns a kustHash object
|
||||
func NewKustHash() *kustHash {
|
||||
return &kustHash{}
|
||||
}
|
||||
|
||||
// Hash returns a hash of either a ConfigMap or a Secret
|
||||
func (h *kustHash) Hash(m ifc.Kunstructured) (string, error) {
|
||||
u := unstructured.Unstructured{
|
||||
Object: m.Map(),
|
||||
}
|
||||
kind := u.GetKind()
|
||||
switch kind {
|
||||
case "ConfigMap":
|
||||
cm, err := unstructuredToConfigmap(u)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return configMapHash(cm)
|
||||
case "Secret":
|
||||
sec, err := unstructuredToSecret(u)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return secretHash(sec)
|
||||
default:
|
||||
return "", fmt.Errorf(
|
||||
"type %s is not supported for hashing in %v",
|
||||
kind, m.Map())
|
||||
}
|
||||
}
|
||||
|
||||
// configMapHash returns a hash of the ConfigMap.
|
||||
// The Data, Kind, and Name are taken into account.
|
||||
func configMapHash(cm *v1.ConfigMap) (string, error) {
|
||||
encoded, err := encodeConfigMap(cm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
h, err := hasher.Encode(hasher.Hash(encoded))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// SecretHash returns a hash of the Secret.
|
||||
// The Data, Kind, Name, and Type are taken into account.
|
||||
func secretHash(sec *v1.Secret) (string, error) {
|
||||
encoded, err := encodeSecret(sec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
h, err := hasher.Encode(hasher.Hash(encoded))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// encodeConfigMap encodes a ConfigMap.
|
||||
// Data, Kind, and Name are taken into account.
|
||||
func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data}
|
||||
if len(cm.BinaryData) > 0 {
|
||||
m["binaryData"] = cm.BinaryData
|
||||
}
|
||||
data, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// encodeSecret encodes a Secret.
|
||||
// Data, Kind, Name, and Type are taken into account.
|
||||
func encodeSecret(sec *v1.Secret) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
data, err := json.Marshal(map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func unstructuredToConfigmap(u unstructured.Unstructured) (*v1.ConfigMap, error) {
|
||||
marshaled, err := json.Marshal(u.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out v1.ConfigMap
|
||||
err = json.Unmarshal(marshaled, &out)
|
||||
return &out, err
|
||||
}
|
||||
|
||||
func unstructuredToSecret(u unstructured.Unstructured) (*v1.Secret, error) {
|
||||
marshaled, err := json.Marshal(u.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out v1.Secret
|
||||
err = json.Unmarshal(marshaled, &out)
|
||||
return &out, err
|
||||
}
|
||||
@@ -1,20 +1,7 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
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 hash
|
||||
package kunstruct
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@@ -22,14 +9,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
var service = gvk.Gvk{Version: "v1", Kind: "Service"}
|
||||
var secret = gvk.Gvk{Version: "v1", Kind: "Secret"}
|
||||
var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"}
|
||||
var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
|
||||
|
||||
func TestConfigMapHash(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -54,7 +35,7 @@ func TestConfigMapHash(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
h, err := ConfigMapHash(c.cm)
|
||||
h, err := configMapHash(c.cm)
|
||||
if SkipRest(t, c.desc, err, c.err) {
|
||||
continue
|
||||
}
|
||||
@@ -80,7 +61,7 @@ func TestSecretHash(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
h, err := SecretHash(c.secret)
|
||||
h, err := secretHash(c.secret)
|
||||
if SkipRest(t, c.desc, err, c.err) {
|
||||
continue
|
||||
}
|
||||
@@ -156,15 +137,6 @@ func TestEncodeSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHash(t *testing.T) {
|
||||
// hash the empty string to be sure that sha256 is being used
|
||||
expect := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
sum := hash("")
|
||||
if expect != sum {
|
||||
t.Errorf("expected hash %q but got %q", expect, sum)
|
||||
}
|
||||
}
|
||||
|
||||
// warn devs who change types that they might have to update a hash function
|
||||
// not perfect, as it only checks the number of top-level fields
|
||||
func TestTypeStability(t *testing.T) {
|
||||