blob: ebbc8a0db78c0a141df55bdd1d29434cbb8026b9 [file] [log] [blame]
Petr Michalecad441172017-09-18 17:18:10 +02001Escaping of References and Inventory Queries
2--------------------------------------------
3
4Reference and inventory queries can be escaped to produce literal strings, for example:
5
6.. code-block:: yaml
7
8 parameters:
9 colour: Blue
10 unescaped: The colour is ${colour}
11 escaped: The colour is \${colour}
12 double_escaped: The colour is \\${colour}
13
14
15This would produce:
16
17.. code-block:: yaml
18
19 parameters:
20 colour: Blue
21 unescaped: The colour is Blue
22 escaped: The colour is ${colour}
23 double_escaped: The colour is \Blue
24
25
26
27Ignore class not found
28----------------------
29
30At some cases (bootstrapping, development) it can be convenient to ignore some missing classes.
31To control the feature there are two options available:
32
33.. code-block:: yaml
34
35 ignore_class_notfound: False
Petr Michalec19324742017-09-18 17:32:24 +020036 ignore_class_regexp: ['.*']
Petr Michalecad441172017-09-18 17:18:10 +020037
38If you set regexp pattern to ``service.*`` all missing classes starting 'service.' will be logged with warning, but will not
39fail to return rendered reclass. Assuming all parameter interpolation passes.
40
41
42
43Merging Referenced Lists and Dictionaries
44-----------------------------------------
45
46Referenced lists or dicts can now be merged:
47
48.. code-block:: yaml
49
50 # nodes/test.yml
51 classes:
52 - test1
53 - test2
54 parameters:
55 one:
56 a: 1
57 b: 2
58 two:
59 c: 3
60 d: 4
61 three:
62 e: 5
63
64 # classes/test1.yml
65 parameters:
66 three: ${one}
67
68 # classes/test2.yml
69 parameters:
70 three: ${two}
71
72``running reclass.py --nodeinfo node1`` then gives:
73
74.. code-block:: yaml
75
76 parameters:
77 one:
78 a: 1
79 b: 2
80 three:
81 a: 1
82 b: 2
83 c: 3
84 d: 4
85 e: 5
86 two:
87 c: 3
88 d: 4
89
90This first sets the parameter three to the value of parameter one (class test1) then merges parameter two into
91parameter three (class test2) and finally merges the parameter three definition given in the node definition into
92the final value.
93
94
95
96Nested References
97-----------------
98
99References can now be nested, for example:
100
101.. code-block:: yaml
102
103 # nodes/node1.yml
104 parameters:
105 alpha:
106 one: ${beta:${alpha:two}}
107 two: a
108 beta:
109 a: 99
110
111``reclass.py --nodeinfo node1`` then gives:
112
113.. code-block:: yaml
114
115 parameters:
116 alpha:
117 one: 99
118 two: a
119 beta:
120 a: 99
121
122The ``${beta:${alpha:two}}`` construct first resolves the ``${alpha:two}`` reference to the value 'a', then resolves
123the reference ``${beta:a}`` to the value 99.
124
125
Andrew Pickforde0eb7b62018-03-16 08:45:42 +0100126Ignore overwritten missing references
127-------------------------
128
129Given the following classes:
130
131.. code-block:: yaml
132 # node1.yml
133 classes:
134 - class1
135 - class2
136 - class3
137
138 # class1.yml
139 parameters:
140 a: ${x}
141
142 # class2.yml
143 parameters:
144 a: ${y}
145
146 # class3.yml
147 parameters:
148 y: 1
149
150
151The parameter ``a`` only depends on the parameter ``y`` through the reference set in class2. The fact that the parameter ``x`` referenced
152in class1 is not defined does not affect the final value of the parameter ``a``. For such overwritten missing references by default a warning is
153printed but no error is raised, providing the final value of the parameter being evaluated is a scalar. If the final value is a dictionary or list
154an error will always be raised in the case of a missing reference.
155
156Default value is True to keep backward compatible behavior.
157
158.. code-block:: yaml
159
160 ignore_overwritten_missing_reference: True
161
Petr Michalecad441172017-09-18 17:18:10 +0200162
163Inventory Queries
164-----------------
165
166Inventory querying works using a new key type - exports to hold values which other node definitions can read using a $[] query, for example with:
167
168.. code-block:: yaml
169
170 # nodes/node1.yml
171 exports:
172 test_zero: 0
173 test_one:
174 name: ${name}
175 value: 6
176 test_two: ${dict}
177
178 parameters:
179 name: node1
180 dict:
181 a: 1
182 b: 2
183 exp_value_test: $[ exports:test_two ]
184 exp_if_test0: $[ if exports:test_zero == 0 ]
185 exp_if_test1: $[ exports:test_one if exports:test_one:value == 7 ]
186 exp_if_test2: $[ exports:test_one if exports:test_one:name == self:name ]
187
188 # nodes/node2.yml
189 exports:
190 test_zero: 0
191 test_one:
192 name: ${name}
193 value: 7
194 test_two: ${dict}
195
196 parameters:
197 name: node2
198 dict:
199 a: 11
200 b: 22
201
202
203``running reclass.py --nodeinfo node1`` gives (listing only the exports and parameters):
204
205.. code-block:: yaml
206
207 exports:
208 test_one:
209 name: node1
210 value: 6
211 test_two:
212 a: 1
213 b: 2
214 parameters:
215 dict:
216 a: 1
217 b: 2
218 exp_if_test0:
219 - node1
220 - node2
221 exp_if_test1:
222 node2:
223 name: node2
224 value: 7
225 exp_if_test2:
226 node1:
227 name: node1
228 value: 6
229 exp_value_test:
230 node1:
231 a: 1
232 b: 2
233 node2:
234 a: 11
235 b: 22
236 name: node1
237
238
239Exports defined for a node can be a simple value or a reference to a parameter in the node definition.
Petr Michalecab9cac32017-09-18 17:35:54 +0200240The ``$[]`` inventory queries are calculated for simple value expressions, ``$[ exports:key ]``, by returning
241a dictionary with an element (``{ node_name: key value }``) for each node which defines 'key' in the exports
242section. For tests with a preceeding value, ``$[ exports:key if exports:test_key == test_value ]``, the
243element (``{ node_name: key value }``) is only added to the returned dictionary if the test_key defined in
Petr Michalecad441172017-09-18 17:18:10 +0200244the node exports section equals the test value. For tests without a preceeding value,
Petr Michalecab9cac32017-09-18 17:35:54 +0200245``$[ if exports:test_key == test_value ]``, a list of nodes which pass the test is returned. For either test
Petr Michalecad441172017-09-18 17:18:10 +0200246form the test value can either be a simple value or a node parameter. And as well as an equality test
Petr Michalecab9cac32017-09-18 17:35:54 +0200247a not equals test (``!=``) can also be used.
Petr Michalecad441172017-09-18 17:18:10 +0200248
249
250**Inventory query options**
251
252By default inventory queries only look at nodes in the same environment as the querying node. This can be
253overriden using the +AllEnvs option:
254
Petr Michalecab9cac32017-09-18 17:35:54 +0200255.. code-block:: yaml
256
Petr Michalecad441172017-09-18 17:18:10 +0200257 $[ +AllEnvs exports:test ]
258
259Any errors in rendering the export parameters for a node will give an error for the inventory query as a whole.
Petr Michalecab9cac32017-09-18 17:35:54 +0200260This can be overriden using the ``+IgnoreErrors`` option:
261
262.. code-block:: yaml
Petr Michalecad441172017-09-18 17:18:10 +0200263
264 $[ +IgnoreErrors exports:test ]
265
Petr Michalecab9cac32017-09-18 17:35:54 +0200266With the ``+IgnoreErrors`` option nodes which generate an error evaluating ``exports:test`` will be ignored.
Petr Michalecad441172017-09-18 17:18:10 +0200267
268Inventory query options can be combined:
269
Petr Michalecab9cac32017-09-18 17:35:54 +0200270.. code-block:: yaml
271
Petr Michalecad441172017-09-18 17:18:10 +0200272 $[ +AllEnvs +IgnoreErrors exports:test ]
273
274**Logical operators and/or**
275
276The logical operators and/or can be used in inventory queries:
277
Petr Michalecab9cac32017-09-18 17:35:54 +0200278.. code-block:: yaml
279
Petr Michalecad441172017-09-18 17:18:10 +0200280 $[ exports:test_value if exports:test_zero == 0 and exports:test_one == self:value ]
281
282The individual elements of the if statement are evaluated and combined with the logical operators starting from the
283left and working to the right.
284
285
286**Inventory query example**
287
288Defining a cluster of machines using an inventory query, for example to open access to a database server to a
289group of nodes. Given exports/parameters for nodes of the form:
290
291.. code-block:: yaml
292
Petr Michalecab9cac32017-09-18 17:35:54 +0200293 # for all nodes requiring access to the database server
294 exports:
295 host:
296 ip_address: aaa.bbb.ccc.ddd
297 cluster: _some_cluster_name_
Petr Michalecad441172017-09-18 17:18:10 +0200298
299.. code-block:: yaml
300
Petr Michalecab9cac32017-09-18 17:35:54 +0200301 # for the database server
302 parameters:
303 cluster_name: production-cluster
304 postgresql:
305 server:
306 clients: $[ exports:host:ip_address if exports:cluster == self:cluster_name ]
Petr Michalecad441172017-09-18 17:18:10 +0200307
Petr Michalecab9cac32017-09-18 17:35:54 +0200308This will generate a dictionary with an entry for node where the ``export:cluster`` key for a node is equal to the
309``parameter:cluster_name`` key of the node on which the inventory query is run on. Each entry in the generated dictionary
310will contain the value of the ``exports:host:ip_address`` key. The output dictionary (depending on node definitions)
Petr Michalecad441172017-09-18 17:18:10 +0200311would look like:
312
313.. code-block:: yaml
314
Petr Michalecab9cac32017-09-18 17:35:54 +0200315 node1:
316 ip_address: aaa.bbb.ccc.ddd
317 node2:
318 ip_address: www.xxx.yyy.zzz
Petr Michalecad441172017-09-18 17:18:10 +0200319
320For nodes where exports:cluster key is not defined or where the key is not equal to self:cluster_name no entry is made
321in the output dictionary.
322
323In practise the exports:cluster key can be set using a parameter reference:
324
325.. code-block:: yaml
326
Petr Michalecab9cac32017-09-18 17:35:54 +0200327 exports:
328 cluster: ${cluster_name}
329 parameters:
330 cluster_name: production-cluster
Petr Michalecad441172017-09-18 17:18:10 +0200331
332The above exports and parameter definitions could be put into a separate class and then included by nodes which require
333access to the database and included by the database server as well.