mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-10 08:20:59 +00:00
ValueAddTransformer
This commit is contained in:
370
examples/valueAdd.md
Normal file
370
examples/valueAdd.md
Normal file
@@ -0,0 +1,370 @@
|
||||
# Simple addition of one string value
|
||||
|
||||
[DRY]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
||||
|
||||
Suppose you have several distinct cloud _projects_
|
||||
(on GCP or AWS or whatever) named:
|
||||
|
||||
* cat-111
|
||||
* dog-222
|
||||
* fox-333
|
||||
|
||||
These might be project names within the company,
|
||||
cloud billing identifiers, or both.
|
||||
|
||||
Further suppose
|
||||
|
||||
* You want to deploy these projects to different
|
||||
k8s namespaces, named after the projects.
|
||||
|
||||
* You need to specify the project name
|
||||
in various resource subfields.
|
||||
|
||||
* You want to name the configuration
|
||||
directories using the project name.
|
||||
|
||||
Additionally you might want to deploy the
|
||||
projects one at a time, or all at once.
|
||||
|
||||
Ideally, you'll want to avoid specifying
|
||||
the project name in more than one place
|
||||
(i.e. you want to stay [DRY]).
|
||||
|
||||
Here's a possible layout:
|
||||
|
||||
|
||||
> ```
|
||||
> ├── all
|
||||
> │ └── kustomization.yaml
|
||||
> │
|
||||
> ├── bases
|
||||
> │ └── iam-iap-tunnel
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── policymembers.yaml
|
||||
> │
|
||||
> └── projects
|
||||
> ├── cat-111
|
||||
> │ └── kustomization.yaml
|
||||
> ├── dog-222
|
||||
> │ └── kustomization.yaml
|
||||
> └── fox-333
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
This layout allows each project to be
|
||||
individually buildable:
|
||||
|
||||
> ```
|
||||
> kustomize build projects/cat-111
|
||||
> kustomize build projects/dog-222
|
||||
> kustomize build projects/fox-333
|
||||
> ```
|
||||
|
||||
or collectively buildable:
|
||||
|
||||
> ```
|
||||
> kustomize build all
|
||||
> ```
|
||||
|
||||
-----
|
||||
Make a place to work:
|
||||
|
||||
<!-- @makePlaceToWork @testAgainstLatestRelease -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
<!-- @defineLayout @testAgainstLatestRelease -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/bases/iam-iap-tunnel
|
||||
mkdir -p $DEMO_HOME/projects/cat-111
|
||||
mkdir -p $DEMO_HOME/projects/dog-222
|
||||
mkdir -p $DEMO_HOME/projects/fox-333
|
||||
```
|
||||
|
||||
To ground this example with a common problem,
|
||||
assume a set of engineers:
|
||||
|
||||
* red@example.com
|
||||
* blue@example.com
|
||||
* yellow@example.com
|
||||
|
||||
who need particular access to one or more projects.
|
||||
|
||||
Define an instance of `IAMCustomRole`:
|
||||
|
||||
<!-- @customRole @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/customroles.yaml
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMCustomRole
|
||||
metadata:
|
||||
name: engineer
|
||||
spec:
|
||||
title: Colorful Engineer
|
||||
permissions:
|
||||
- iap.tunnelInstances.accessViaIAP
|
||||
stage: GA
|
||||
EOF
|
||||
```
|
||||
|
||||
Define corresponding instances of `IAMPolicyMember`.
|
||||
|
||||
The `resourceRef/external` fields in these instances
|
||||
are intentionally incomplete, and will be completed
|
||||
by kustomize below.
|
||||
|
||||
The boilerplate in these instances could be removed
|
||||
by making a custom generator, but that's for
|
||||
different tutorial.
|
||||
|
||||
<!-- @policyMembers @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/policymembers.yaml
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-red
|
||||
spec:
|
||||
member: user:red@example.com
|
||||
role: roles/engineer
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
kind: Project
|
||||
external: projects
|
||||
---
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-blue
|
||||
spec:
|
||||
member: user:blue@example.com
|
||||
role: roles/engineer
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
kind: Project
|
||||
external: projects
|
||||
---
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-yellow
|
||||
spec:
|
||||
member: user:yellow@example.com
|
||||
role: roles/engineer
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
kind: Project
|
||||
external: projects
|
||||
EOF
|
||||
```
|
||||
|
||||
Make a base that combines these:
|
||||
|
||||
<!-- @makeBase @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/kustomization.yaml
|
||||
resources:
|
||||
- customroles.yaml
|
||||
- policymembers.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Make a transformer, which at the moment has no
|
||||
equivalent directive in the kustomization file.
|
||||
|
||||
It's purpose will be more
|
||||
evident momentarily.
|
||||
|
||||
<!-- @makeTransformerDir @testAgainstLatestRelease -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/transformers/setProject
|
||||
cat <<'EOF' >$DEMO_HOME/transformers/setProject/kustomization.yaml
|
||||
resources:
|
||||
- setProject.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @defineSetProjectTransformer @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/transformers/setProject/setProject.yaml
|
||||
apiVersion: builtin
|
||||
kind: ValueAddTransformer
|
||||
metadata:
|
||||
name: dirNameAdd
|
||||
|
||||
# Omitting the 'value:' field means that the current
|
||||
# kustomization root directory name will be used as
|
||||
# the value.
|
||||
# value: not specified!
|
||||
|
||||
targets:
|
||||
- fieldPath: metadata/namespace
|
||||
- selector:
|
||||
kind: IAMPolicyMember
|
||||
fieldPath: spec/resourceRef/external
|
||||
filePathPosition: 2
|
||||
EOF
|
||||
```
|
||||
|
||||
Now make the _cat_, _dog_ and _fox_ _variants_.
|
||||
|
||||
These are the targets that one could
|
||||
independently apply to a cluster.
|
||||
|
||||
<!-- @defineCat @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/projects/cat-111/kustomization.yaml
|
||||
resources:
|
||||
- ../../bases/iam-iap-tunnel
|
||||
transformers:
|
||||
- ../../transformers/setProject
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @defineDog @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/projects/dog-222/kustomization.yaml
|
||||
resources:
|
||||
- ../../bases/iam-iap-tunnel
|
||||
transformers:
|
||||
- ../../transformers/setProject
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @defineFox @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/projects/fox-333/kustomization.yaml
|
||||
resources:
|
||||
- ../../bases/iam-iap-tunnel
|
||||
transformers:
|
||||
- ../../transformers/setProject
|
||||
EOF
|
||||
```
|
||||
|
||||
Then, optionally, a target to deploy all the
|
||||
projects at once:
|
||||
|
||||
<!-- @defineAllTarget @testAgainstLatestRelease -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/all
|
||||
cat <<'EOF' >$DEMO_HOME/all/kustomization.yaml
|
||||
resources:
|
||||
- ../projects/cat-111
|
||||
- ../projects/dog-222
|
||||
- ../projects/fox-333
|
||||
EOF
|
||||
```
|
||||
|
||||
The layout is now:
|
||||
|
||||
<!-- @showLayout @testAgainstLatestRelease -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
It should look like:
|
||||
|
||||
> ```
|
||||
> /tmp/someTmpDir
|
||||
> ├── all
|
||||
> │ └── kustomization.yaml
|
||||
> ├── bases
|
||||
> │ └── iam-iap-tunnel
|
||||
> │ ├── customroles.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── policymembers.yaml
|
||||
> ├── projects
|
||||
> │ ├── cat-111
|
||||
> │ │ └── kustomization.yaml
|
||||
> │ ├── dog-222
|
||||
> │ │ └── kustomization.yaml
|
||||
> │ └── fox-333
|
||||
> │ └── kustomization.yaml
|
||||
> └── transformers
|
||||
> └── setProject
|
||||
> ├── kustomization.yaml
|
||||
> └── setProject.yaml
|
||||
> ```
|
||||
|
||||
The expected output from building the dog project
|
||||
is as follows:
|
||||
|
||||
<!-- @definedExpectedOutput @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/out_expected.yaml
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMCustomRole
|
||||
metadata:
|
||||
name: engineer
|
||||
namespace: dog-222
|
||||
spec:
|
||||
permissions:
|
||||
- iap.tunnelInstances.accessViaIAP
|
||||
stage: GA
|
||||
title: Colorful Engineer
|
||||
---
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-blue
|
||||
namespace: dog-222
|
||||
spec:
|
||||
member: user:blue@example.com
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
external: projects/dog-222
|
||||
kind: Project
|
||||
role: roles/engineer
|
||||
---
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-red
|
||||
namespace: dog-222
|
||||
spec:
|
||||
member: user:red@example.com
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
external: projects/dog-222
|
||||
kind: Project
|
||||
role: roles/engineer
|
||||
---
|
||||
apiVersion: iam.cnrm.cloud.google.com/v1beta1
|
||||
kind: IAMPolicyMember
|
||||
metadata:
|
||||
name: iap-tunnel-yellow
|
||||
namespace: dog-222
|
||||
spec:
|
||||
member: user:yellow@example.com
|
||||
resourceRef:
|
||||
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
|
||||
external: projects/dog-222
|
||||
kind: Project
|
||||
role: roles/engineer
|
||||
EOF
|
||||
```
|
||||
|
||||
In this output, the namespace of all instances is the
|
||||
project name, and the project name also appears
|
||||
in the resourceRef field of the `IAMPolicyMember` instances.
|
||||
|
||||
Confirm this is happens:
|
||||
|
||||
<!-- @runIt @testAgainstLatestRelease -->
|
||||
```
|
||||
kustomize build $DEMO_HOME/projects/dog-222 >$DEMO_HOME/out_actual.yaml
|
||||
```
|
||||
|
||||
Confirm expectations:
|
||||
|
||||
<!-- @diffShouldExitZero @testAgainstLatestRelease -->
|
||||
```
|
||||
diff $DEMO_HOME/out_actual.yaml $DEMO_HOME/out_expected.yaml
|
||||
```
|
||||
|
||||
Build all the projects at once like this:
|
||||
|
||||
<!-- @buildAll @testAgainstLatestRelease -->
|
||||
```
|
||||
kustomize build $DEMO_HOME/all
|
||||
```
|
||||
Reference in New Issue
Block a user