Skip to content

Commit

Permalink
Add annotation reference docs
Browse files Browse the repository at this point in the history
  • Loading branch information
karlkfi committed Jan 5, 2022
1 parent d61fd35 commit 712ec48
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 0 deletions.
5 changes: 5 additions & 0 deletions site/book/06-deploying-packages/03-handling-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,8 @@ statefulset.apps/wordpress-mysql deleted
service/wordpress-mysql deleted
2 resource(s) deleted, 0 skipped
```

See [depends-on] for more information.

[depends-on]:
/reference/annotations/depends-on
29 changes: 29 additions & 0 deletions site/reference/annotations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Annotations Reference

<!--mdtogo:Short
Overview of kpt annotations
-->

<!--mdtogo:Long-->

The following annotations are used to configure kpt features:

| Annotation | Description |
| ---------- | ----------- |
| [config.kubernetes.io/depends-on] | specifies one or more resource dependencies |
| [config.kubernetes.io/apply-time-mutation] | specifies one or more substitutions to make at apply time using dependencies as input |
| [config.kubernetes.io/local-config] | specifies a resource to be skipped when applying |

The following annotations are used by kpt internally:

| Annotation | Description |
| ---------- | ----------- |
| `internal.config.kubernetes.io/path` | specifies the resource's file path when formatted as a ResourceList |
| `internal.config.kubernetes.io/index` | specifies the index of the resource in a file when formatted as a ResourceList |
| `config.kubernetes.io/merge-source` | specifies the source of the resource during a three way merge |

<!--mdtogo-->

[config.kubernetes.io/depends-on]: /reference/annotations/depends-on/
[config.kubernetes.io/apply-time-mutation]: /reference/annotations/apply-time-mutation/
[config.kubernetes.io/local-config]: /reference/annotations/local-config/
190 changes: 190 additions & 0 deletions site/reference/annotations/apply-time-mutation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
title: "`apply-time-mutation`"
linkTitle: "apply-time-mutation"
type: docs
description: >
Specify one or more substitutions to make at apply time using dependencies as input.
---

<!--mdtogo:Short
Specify one or more substitutions to make at apply time using dependencies as input.
-->

<!--mdtogo:Long-->

The `config.kubernetes.io/apply-time-mutation` annotation specifies one or more
substitutions to make at apply time using dependencies as input.

### Schema

The annotation value accepts one or more substitutions, formatted as a YAML
string.

#### Substitution

A substitution is a modification to a specific target field.

Each substitutions is configured with the following:

| Field | Description |
| ----- | ----------- |
| source resource | the resource to read from |
| source path | the source resource field to read from, specified by JSONPath |
| target resource | (implicit) the resource to write to |
| target path | the target resource field to write to, specified by JSONPath |
| token | (optional) the substring to replace in the target field. |

If the token is unspecified, the whole target field value will be replaced,
allowing for replacement of non-string values using the source field type.

<!--mdtogo-->

### Behavior

Like the `depends-on` feature, `apply-time-mutation` waits for dependencies
(source resources) to be applied and reconciled before applying the resource
with the annotation.

Unlike the `depends-on` feature, `apply-time-mutation` modifies the annotated
resource before applying it.

#### Special cases

If the source resource is not part of the package being applied, the apply of
the target resource will fail with an error.

The `apply-time-mutation` annotation is only enforced by `kpt live apply` and
`kpt live destroy`. Modifying or deleting these resources with other mechanisms
will not follow the rules specified by these annotations.

### JSONPath syntax

Since there is no formal specification for JSONPath, the supported syntax
depends on the chosen implimentation. In this case, kpt uses the
[ajson](https://github.com/spyzhov/ajson) library. For details about what
language features are supported, see the
[json-path-comparison table](https://cburgmer.github.io/json-path-comparison/).

### Example

<!--mdtogo:Examples-->

In this example, pod-b depends on pod-a with two substitutions that replace
tokens in the same target field. The value of the SERVICE_HOST environment
variable of a container in pod-b will be updated to represent the host and port
from pod-a.

Create a new kpt package:

```shell
mkdir my-pkg
cd my-pkg
kpt pkg init
```

Configure two pods, with one that depends on the other:

```shell
cat > pods.yaml << EOF
kind: Pod
apiVersion: v1
metadata:
name: pod-a
namespace: test
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- name: tcp
containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: pod-b
namespace: test
annotations:
config.kubernetes.io/apply-time-mutation: |
- sourceRef:
kind: Pod
name: pod-a
sourcePath: $.status.podIP
targetPath: $.spec.containers[?(@.name=="nginx")].env[?(@.name=="SERVICE_HOST")].value
token: ${pod-a-ip}
- sourceRef:
kind: Pod
name: pod-a
sourcePath: $.spec.containers[?(@.name=="nginx")].ports[?(@.name=="tcp")].containerPort
targetPath: $.spec.containers[?(@.name=="nginx")].env[?(@.name=="SERVICE_HOST")].value
token: ${pod-a-port}
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- name: tcp
containerPort: 80
env:
- name: SERVICE_HOST
value: "${pod-a-ip}:${pod-a-port}"
EOF
```

Create a namespace for your package:

```shell
kubectl create namespace test
```

Initialize the package inventory:

```shell
kpt live init
```

Apply the package to your Kubernetes cluster:

```shell
kpt live apply
```

If all goes well, the output should look like this:

```
pod/pod-a created
1 resource(s) applied. 1 created, 0 unchanged, 0 configured, 0 failed
pod/pod-b created
1 resource(s) applied. 1 created, 0 unchanged, 0 configured, 0 failed
```

To verify that the SERVICE_HOST was mutated correctly:

```shell
# Read the IP of pod-a
kubectl get pod pod-a -n test \
-o jsonpath='{.status.podIP}'
```

```shell
# Read the SERVICE_HOST of pod-b
kubectl get pod pod-b -n test \
-o jsonpath='{.spec.containers[?(@.name=="nginx")].env[?(@.name=="SERVICE_HOST")].value}'
```

Delete the package from your Kubernetes cluster:

```shell
kpt live destroy
```

If all goes well, the output should look like this:

```
pod/pod-b deleted
1 resource(s) deleted, 0 skipped
pod/pod-a deleted
1 resource(s) deleted, 0 skipped
```

<!--mdtogo-->
128 changes: 128 additions & 0 deletions site/reference/annotations/depends-on/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
title: "`depends-on`"
linkTitle: "depends-on"
type: docs
description: >
Specify one or more resource dependencies.
---

<!--mdtogo:Short
Specify one or more resource dependencies.
-->

<!--mdtogo:Long-->

The `config.kubernetes.io/depends-on` annotation specifies one or more resource
dependencies.

### Schema

The annotation value accepts one or more comma delimited resource references.

#### Resource reference

A resource reference is a string that uniquely identifies a resource.

It consists of the group, kind, name, and optionally the namespace, delimited by
forward slashes.

| Resource Scope | Format |
| -------------- | ------ |
| namespace-scoped | `<group>/namespaces/<namespace>/<kind>/<name>` |
| cluster-scoped | `<group>/<kind>/<name>` |

For resources in the "core" group, the empty string is used instead
(for example: `/namespaces/test/Pod/pod-a`).

<!--mdtogo-->

### Example

<!--mdtogo:Examples-->

In this example, pod-b depends on pod-a.

Create a new kpt package:

```shell
mkdir my-pkg
cd my-pkg
kpt pkg init
```

Configure two pods, with one that depends on the other:

```shell
cat > pods.yaml << EOF
kind: Pod
apiVersion: v1
metadata:
name: pod-a
namespace: test
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
---
kind: Pod
apiVersion: v1
metadata:
name: pod-b
namespace: test
annotations:
config.kubernetes.io/depends-on: /namespaces/test/Pod/pod-a
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
EOF
```

Create a namespace for your package:

```shell
kubectl create namespace test
```

Initialize the package inventory:

```shell
kpt live init
```

Apply the package to your Kubernetes cluster:

```shell
kpt live apply
```

If all goes well, the output should look like this:

```
pod/pod-a created
1 resource(s) applied. 1 created, 0 unchanged, 0 configured, 0 failed
pod/pod-b created
1 resource(s) applied. 1 created, 0 unchanged, 0 configured, 0 failed
```

Delete the package from your Kubernetes cluster:

```shell
kpt live destroy
```

If all goes well, the output should look like this:

```
pod/pod-b deleted
1 resource(s) deleted, 0 skipped
pod/pod-a deleted
1 resource(s) deleted, 0 skipped
```


<!--mdtogo-->
Loading

0 comments on commit 712ec48

Please sign in to comment.