|
| 1 | +# Templating |
| 2 | + |
| 3 | +`PublishedResources` allow to use [Go templates](https://pkg.go.dev/text/template) in a number of |
| 4 | +places. A simple template could look like `{{ .Object.spec.secretName | sha3sum }}`. |
| 5 | + |
| 6 | +## General Usage |
| 7 | + |
| 8 | +Users are encouraged to get familiar with the [Go documentation](https://pkg.go.dev/text/template) |
| 9 | +on templates. |
| 10 | + |
| 11 | +Specifically within the agent, the following rules apply when a template is evaluated: |
| 12 | + |
| 13 | +* All templates must evaluate successfully. Any error will cancel the synchronization process for |
| 14 | + that object, potentially leaving it in a half-finished overall state. |
| 15 | +* Templates should not output random values, as those can lead to reconcile loops and higher load |
| 16 | + on the service cluster. |
| 17 | +* Any leading and trailing whitespace will be automatically trimmed from the template's output. |
| 18 | +* All "objects" mentioned in this documentation refer technically to an `unstructured.Unstructured` |
| 19 | + value's `.Object` field, i.e. the JSON-decoded representation of a Kubernetes object. |
| 20 | + |
| 21 | +## Functions |
| 22 | + |
| 23 | +Templates can make use of all functions provided by [sprig/v3](https://masterminds.github.io/sprig/), |
| 24 | +for example `join` or `b64enc`. The agent then adds the following functions: |
| 25 | + |
| 26 | +* `sha3sum STRING`<br>Returns the hex-encoded SHA3-256 hash (32 characters long). |
| 27 | +* `sha3short STRING [LENGTH=20]`<br>Returns the first `LENGTH` characters of the hex-encoded SHA3-256 hash. |
| 28 | +* <del>`shortHash STRING`</del><br>Returns the first 20 characters of the hex-encoded SHA-1 hash. |
| 29 | + This function is only available for backwards compatibility when migrating `$variable`-based |
| 30 | + naming rules to use Go templates. New setups should not use this function, but one of the explicitly |
| 31 | + named ones, like `sha256sum` or `sha3sum`. |
| 32 | + |
| 33 | +## Context |
| 34 | + |
| 35 | +Depending on where a template is used, different data is available inside the template. The following |
| 36 | +is a summary of those different values: |
| 37 | + |
| 38 | +### Primary Object Naming Rules |
| 39 | + |
| 40 | +This is for templates used in `.spec.naming`: |
| 41 | + |
| 42 | +| Name | Type | Description | |
| 43 | +| ------------- | --------------------- | ----------- | |
| 44 | +| `Object` | `map[string]any` | the full remote object found in a kcp workspace | |
| 45 | +| `ClusterName` | `logicalcluster.Name` | the internal cluster identifier (e.g. "34hg2j4gh24jdfgf") | |
| 46 | +| `ClusterPath` | `logicalcluster.Path` | the workspace path (e.g. "root:customer:projectx") | |
| 47 | + |
| 48 | +### Related Object Template Source |
| 49 | + |
| 50 | +This is for templates used in `.spec.related[*].object.template` and |
| 51 | +`.spec.related[*].object.namespace.template`: |
| 52 | + |
| 53 | +| Name | Type | Description | |
| 54 | +| ------------- | --------------------- | ----------- | |
| 55 | +| `Side` | `string` | set to either one of the possible origin values (`kcp` or `origin`) to indicate for which cluster the template is currently being evaluated for | |
| 56 | +| `Object` | `map[string]any` | the primary object belonging to the related object. Since related object templates are evaluated twice (once for the origin side and once for the destination side), object is the primary object on the side the template is evaluated for | |
| 57 | +| `ClusterName` | `logicalcluster.Name` | the internal cluster identifier (e.g. "34hg2j4gh24jdfgf") of the kcp workspace that the synchronization is currently processing; this value is set for both evaluations, regardless of side | |
| 58 | +| `ClusterPath` | `logicalcluster.Path` | the workspace path (e.g. "root:customer:projectx"); this value is set for both evaluations, regardless of side | |
| 59 | + |
| 60 | +These templates are evaluated once on each side of the synchronization. |
| 61 | + |
| 62 | +### Related Object Label Selectors |
| 63 | + |
| 64 | +This is for templates used in `.spec.related[*].object.selector.matchLabels` and |
| 65 | +`.spec.related[*].object.namespace.selector.matchLabels`, both keys and values: |
| 66 | + |
| 67 | +| Name | Type | Description | |
| 68 | +| -------------- | --------------------- | ----------- | |
| 69 | +| `LocalObject` | `map[string]any` | the primary object copy on the local side of the sync (i.e. on the service cluster) | |
| 70 | +| `RemoteObject` | `map[string]any` | the primary object original, in kcp | |
| 71 | +| `ClusterName` | `logicalcluster.Name` | the internal cluster identifier (e.g. "34hg2j4gh24jdfgf") of the kcp workspace that the synchronization is currently processing (where the remote object exists) | |
| 72 | +| `ClusterPath` | `logicalcluster.Path` | the workspace path (e.g. "root:customer:projectx") | |
| 73 | + |
| 74 | +If a template for a key evaluates to an empty string, the key-value combination will be omitted from |
| 75 | +the final selector. Empty values however are allowed. |
| 76 | + |
| 77 | +### Related Object Label Selector Rewrites |
| 78 | + |
| 79 | +This is for templates used in `.spec.related[*].object.selector.rewrite.template` and |
| 80 | +`.spec.related[*].object.namespace.selector.rewrite.template`: |
| 81 | + |
| 82 | +| Name | Type | Description | |
| 83 | +| --------------- | --------------------- | ----------- | |
| 84 | +| `Value` | `string` | Either the a found namespace name (when a label selector was used to select the source namespaces for related objects) or the name of a found object (when a label selector was used to find objects). In the former case, the template should return the new namespace to use on the destination side, in the latter case it should return the new object name to use on the destination side. | |
| 85 | +| `RelatedObject` | `map[string]any` | When a rewrite is used to rewrite object names, RelatedObject is the original related object (found on the origin side). This enables you to ignore the given Value entirely and just select anything from the object itself. RelatedObject is `nil` when the rewrite is performed for a namespace. | |
| 86 | +| `LocalObject` | `map[string]any` | the primary object copy on the local side of the sync (i.e. on the service cluster) | |
| 87 | +| `RemoteObject` | `map[string]any` | the primary object original, in kcp | |
| 88 | +| `ClusterName` | `logicalcluster.Name` | the internal cluster identifier (e.g. "34hg2j4gh24jdfgf") of the kcp workspace that the synchronization is currently processing (where the remote object exists) | |
| 89 | +| `ClusterPath` | `logicalcluster.Path` | the workspace path (e.g. "root:customer:projectx") | |
0 commit comments