You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# observedGeneration is used to check that the current version of the ClusterClass is the same as that when the Status was previously written.
83
+
# if metadata.generation isn't the same as observedGeneration Cluster using the ClusterClass should not reconcile.
84
+
observedGeneration: xx
85
+
# variables contains a list of all variable definitions, both inline and from external patches, that belong to the ClusterClass.
86
+
variables:
87
+
- name: no-proxy
88
+
definitions:
89
+
- namespace: inline
90
+
required: true
91
+
schema:
92
+
openAPIV3Schema:
93
+
type: string
94
+
default: "internal.com"
95
+
example: "internal.com"
96
+
description: "comma-separated list of machine or domain names excluded from using the proxy."
97
+
- name: http-proxy
98
+
definitions:
99
+
- namespace: inline
100
+
schema:
101
+
openAPIV3Schema:
102
+
type: string
103
+
default: "proxy.example.com"
104
+
example: "proxy.example.com"
105
+
description: "proxy for http calls."
106
+
- namespace: lbImageRepository
107
+
schema:
108
+
openAPIV3Schema:
109
+
type: string
110
+
default: "different.example.com"
111
+
example: "different.example.com"
112
+
description: "proxy for http calls."
113
+
```
114
+
115
+
### Variable namespacing
116
+
Variable definitions can be inline in the ClusterClass or from any number of external DiscoverVariables hooks. The source
117
+
of a variable definition is recorded in the `namespace` field in ClusterClass `.status.variables`.
118
+
Variables that are defined by an external DiscoverVariables hook will have the name of the patch they are associated with as their namespace.
119
+
Variables that are defined in the ClusterClass `.spec.variables` will have the namespace `inline`.
120
+
Note: `inline`is a reserved namespace. It can not be used as the name of an external patch to avoid conflicts.
121
+
122
+
If all variables that share a name have equivalent schemas the variables are considered `global` . `global` variables can
123
+
be set without providing a namespace - [see below](#setting-values-for-variables-in-the-cluster). The CAPI components will
124
+
consider variable definitions to be equivalent when they share a name and their schema is exactly equal.
125
+
126
+
### Setting values for variables in the Cluster
127
+
Setting variables that are defined with external variable definitions requires attention to be paid to variable namespacing, as exposed in the ClusterClass status.
128
+
Variable values are set in Cluster `.spec.topology.variables`.
129
+
130
+
```yaml
131
+
apiVersion: cluster.x-k8s.io/v1beta1
132
+
kind: Cluster
133
+
#metadata
134
+
spec:
135
+
topology:
136
+
variables:
137
+
# namespace is not needed as this variable is global.
138
+
- name: no-proxy
139
+
value: "internal.domain.com"
140
+
# namespaced variables require values for each individual schema.
141
+
- name: http-proxy
142
+
namespace: inline
143
+
value: http://proxy.example2.com:1234
144
+
- name: http-proxy
145
+
namespace: lbImageRepository
146
+
value:
147
+
host: proxy.example2.com
148
+
port: 1234
149
+
```
150
+
38
151
## Using one or multiple external patch extensions
39
152
40
153
Some considerations:
41
154
* In general a single external patch extension is simpler than many, as only one extension
42
-
then has to be built, deployed and managed.
155
+
then has to be built, deployed and managed.
43
156
* A single extension also requires less HTTP round-trips between the CAPI controller and the extension(s).
44
157
* With a single extension it is still possible to implement multiple logical features using different variables.
45
158
* When implementing multiple logical features in one extension it's recommended that they can be conditionally
@@ -50,8 +163,9 @@ Some considerations:
50
163
## Guidelines
51
164
52
165
For general Runtime Extension developer guidelines please refer to the guidelines in [Implementing Runtime Extensions](implement-extensions.md#guidelines).
53
-
This section outlines considerations specific to Topology Mutation hooks:
166
+
This section outlines considerations specific to Topology Mutation hooks.
54
167
168
+
### Patch extension guidelines
55
169
* **Input validation**: An External Patch Extension must always validate its input, i.e. it must validate that
56
170
all variables exist, have the right type and it must validate the kind and apiVersion of the templates which
57
171
should be patched.
@@ -68,9 +182,19 @@ This section outlines considerations specific to Topology Mutation hooks:
68
182
* **Avoid Dependencies**: An External Patch Extension must be independent of other External Patch Extensions. However
69
183
if dependencies cannot be avoided, it is possible to control the order in which patches are executed via the ClusterClass.
70
184
* **Error messages**: For a given request (a set of templates and variables) an External Patch Extension must
71
-
always return the same error message. Otherwise the system might became unstable due to controllers being overloaded
185
+
always return the same error message. Otherwise the system might become unstable due to controllers being overloaded
72
186
by continuous changes to Kubernetes resources as these messages are reported as conditions. See [error messages](implement-extensions.md#error-messages).
73
187
188
+
### Variable discovery guidelines
189
+
* **Distinctive variable names**: Names should be carefully chosen, and if possible generic names should be avoided.
190
+
Using a generic name could lead to conflicts if the variables defined for this patch are used in combination with other
191
+
patches providing variables with the same name.
192
+
* **Avoid breaking changes to variable definitions**: Changing a variable definition can lead to problems on existing
193
+
clusters because reconciliation will stop if variable values do not match the updated definition. When more than one variable
194
+
with the same name is defined, changes to variable definitions can require explicit values for each patch.
195
+
Updates to the variable definition should be carefully evaluated, and very well documented in extension release notes,
196
+
so ClusterClass authors can evaluate impacts of changes before performing an upgrade.
197
+
74
198
## Definitions
75
199
76
200
### GeneratePatches
@@ -192,6 +316,81 @@ function openSwaggerUI() {
192
316
}
193
317
</script>
194
318
319
+
### DiscoverVariables
320
+
321
+
A DiscoverVariables call returns definitions for one or more variables.
322
+
323
+
#### Example Request:
324
+
325
+
* The request is a simple call to the Runtime hook.
Copy file name to clipboardExpand all lines: docs/proposals/20220330-topology-mutation-hook.md
+22-6Lines changed: 22 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,11 +3,11 @@ title: Topology Mutation Hook
3
3
authors:
4
4
- "@sbueringer"
5
5
- "@fabriziopandini"
6
+
- "@killianmuldoon"
6
7
reviewers:
7
8
- "@CecileRobertMichon"
8
9
- "@enxebre"
9
10
- "@vincepri"
10
-
- "@killianmuldoon"
11
11
- "@ykakarap"
12
12
creation-date: 2022-03-30
13
13
last-updated: 2022-03-30
@@ -58,8 +58,11 @@ Refer to the [Cluster API Book Glossary](https://cluster-api.sigs.k8s.io/referen
58
58
59
59
-**Inline patches**: are defined inline in a ClusterClass and implemented by the core CAPI controller.
60
60
-**External patches**: are patches generated by an external component.
61
-
-**Topology Mutation Hook**: is the hook defined in this proposal that allows users to plug in an external component that generates patches.
61
+
-**Topology Mutation Hook**: is a hook defined in this proposal that allows users to plug in an external component that generates patches.
62
62
-**External patch extension**: is an external component that generates patches.
63
+
-**Inline variables**: are variables defined inline in a ClusterClass.
64
+
-**External variables**: are variables defined by an external component.
65
+
-**Variable Discovery Hook**: is a hook defined in this proposal that allows an external component to supply variable definitions.
63
66
64
67
## Summary
65
68
@@ -96,7 +99,6 @@ The main idea behind Topology Mutation Hook is to move the complexity that is cu
96
99
97
100
### Future work
98
101
99
-
* Explore a solution how External Patch Extensions can bring their own variable definitions to shift the responsibility of variable definition and management from ClusterClass authors to External Patch Extension authors. For now it’s the responsibility of the ClusterClass author.
100
102
* Explore a solution to detect and prevent an External Patch Extension to trigger infinite reconciles
101
103
102
104
@@ -115,11 +117,12 @@ As an External Patch Extension developer:
115
117
* I want to unit test the code/logic which generates external patches.
116
118
* I want to be able to generate external patches in either JSON Patch or JSON Merge Patch format.
117
119
* I want to generate external patches based on external data, for example by querying a cloud API.
120
+
* I want to supply the variable definitions, including schema and defaulting rules, for variables used in external patches.
118
121
* I want to validate the templates after all patches have been applied, so I can be sure that other External Patch Extensions didn't overwrite my changes.
119
122
120
123
### Cluster Operator guide
121
124
122
-
As a Cluster operator, to use ClusterClasses with an External Patch Extensions you have to deploy and register it. You can find the full documentation on how to deploy a Runtime Extension in the [Runtime SDK proposal](https://github.com/kubernetes-sigs/cluster-api/blob/75b39db545ae439f4f6203b5e07496d3b0a6aa75/docs/proposals/20220221-runtime-SDK.md#deploy-runtime-extensions).
125
+
As a Cluster operator, to use ClusterClasses with an External Patch Extension you have to deploy and register it. You can find the full documentation on how to deploy a Runtime Extension in the [Runtime SDK proposal](https://github.com/kubernetes-sigs/cluster-api/blob/75b39db545ae439f4f6203b5e07496d3b0a6aa75/docs/proposals/20220221-runtime-SDK.md#deploy-runtime-extensions).
123
126
124
127
An External Patch Extension can be registered by applying:
125
128
```yaml
@@ -138,7 +141,7 @@ Once the extension is registered the discovery hook is called and the Extension
138
141
139
142
### ClusterClass author guide
140
143
141
-
A ClusterClass author can use an External Patch Extension by referencing it in a ClusterClass and adding the corresponding variable definitions.
144
+
A ClusterClass author can use an External Patch Extension by referencing it in a ClusterClass.
142
145
143
146
A ClusterClass can have external patches, inline patches or both. The patches will then be applied in the order in which they are defined. The extension fields of the external patch must match the unique name of RuntimeExtensions assigned during discovery.
If the External Patch Extension requires variable definitions, they have to be added to ClusterClass.spec.variables. It is up to the External Patch Extension developer to document them including their OpenAPI schema. As future work we will explore a solution to discover variable definitions from External Patch Extensions automatically.
167
+
If the External Patch Extension requires variable definitions they must be defined and supplied using a Variable Discovery Hook. It is up to the External Patch Extension developer to define the variables, including their OpenAPI schema.
168
+
169
+
Note: In a previous version of this proposal variables defined inline in the ClusterClass `.spec` could be used in external patches.
170
+
With the introduction of Variable Discovery variables used in an external patch must come from an associated DiscoverVariables hook.
164
171
165
172
### Developer guide
166
173
@@ -219,6 +226,15 @@ Mitigations:
219
226
* External Patch Extension developers should ensure fast responses under all circumstances.
220
227
* Cluster operators can set a timeout on the RuntimeExtensionConfiguration to ensure Cluster topology reconciliation for all Clusters is not slowed down by one slow External Patch Extension. This only helps if the slow External Patch Extension is not used for all Clusters.
221
228
229
+
#### Clashing external variable definitions
230
+
Variable definitions supplied externally by an External Patch Extension through a Variable Discovery Hook can change when the definition in the External Patch Extension changes. This can lead to a clash where variables that previously had the same name and definition no longer have the same definition.
231
+
232
+
Mitigations:
233
+
* Variable Discovery Hooks allow addressing variables using namespacing, where the variable value setting in the Cluster
234
+
includes the name of the Patch as a namespace.
235
+
* ClusterClass authors should pro-actively test any changes to ClusterClasses and associated Runtime Extensions to avoid clashing variable definitions.
236
+
* External Patch extension authors should extensively document their patches, variables and their usage.
237
+
222
238
## Alternatives
223
239
224
240
### Extending inline patches vs. introducing external patches
0 commit comments