blob: 554a62dee13246b0fa9a07eb06718694e37005ba [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
Andrew Pickfordffd77b42018-03-16 14:37:03 +0100163Print summary of missed references
164----------------------------------
165
166Instead of failing on the first undefinded reference error all missing reference errors are printed at once.
167
168.. code-block:: yaml
169 reclass --nodeinfo mynode
170 -> dontpanic
171 Cannot resolve ${_param:kkk}, at mkkek3:tree:to:fail, in yaml_fs:///test/classes/third.yml
172 Cannot resolve ${_param:kkk}, at mkkek3:tree:another:xxxx, in yaml_fs:///test/classes/third.yml
173 Cannot resolve ${_param:kkk}, at mykey2:tree:to:fail, in yaml_fs:///test/classes/third.yml
174
175.. code-block:: yaml
176
177 group_errors: True
178
179
Petr Michalecad441172017-09-18 17:18:10 +0200180Inventory Queries
181-----------------
182
183Inventory querying works using a new key type - exports to hold values which other node definitions can read using a $[] query, for example with:
184
185.. code-block:: yaml
186
187 # nodes/node1.yml
188 exports:
189 test_zero: 0
190 test_one:
191 name: ${name}
192 value: 6
193 test_two: ${dict}
194
195 parameters:
196 name: node1
197 dict:
198 a: 1
199 b: 2
200 exp_value_test: $[ exports:test_two ]
201 exp_if_test0: $[ if exports:test_zero == 0 ]
202 exp_if_test1: $[ exports:test_one if exports:test_one:value == 7 ]
203 exp_if_test2: $[ exports:test_one if exports:test_one:name == self:name ]
204
205 # nodes/node2.yml
206 exports:
207 test_zero: 0
208 test_one:
209 name: ${name}
210 value: 7
211 test_two: ${dict}
212
213 parameters:
214 name: node2
215 dict:
216 a: 11
217 b: 22
218
219
220``running reclass.py --nodeinfo node1`` gives (listing only the exports and parameters):
221
222.. code-block:: yaml
223
224 exports:
225 test_one:
226 name: node1
227 value: 6
228 test_two:
229 a: 1
230 b: 2
231 parameters:
232 dict:
233 a: 1
234 b: 2
235 exp_if_test0:
236 - node1
237 - node2
238 exp_if_test1:
239 node2:
240 name: node2
241 value: 7
242 exp_if_test2:
243 node1:
244 name: node1
245 value: 6
246 exp_value_test:
247 node1:
248 a: 1
249 b: 2
250 node2:
251 a: 11
252 b: 22
253 name: node1
254
255
256Exports 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 +0200257The ``$[]`` inventory queries are calculated for simple value expressions, ``$[ exports:key ]``, by returning
258a dictionary with an element (``{ node_name: key value }``) for each node which defines 'key' in the exports
259section. For tests with a preceeding value, ``$[ exports:key if exports:test_key == test_value ]``, the
260element (``{ node_name: key value }``) is only added to the returned dictionary if the test_key defined in
Petr Michalecad441172017-09-18 17:18:10 +0200261the node exports section equals the test value. For tests without a preceeding value,
Petr Michalecab9cac32017-09-18 17:35:54 +0200262``$[ 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 +0200263form 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 +0200264a not equals test (``!=``) can also be used.
Petr Michalecad441172017-09-18 17:18:10 +0200265
266
267**Inventory query options**
268
269By default inventory queries only look at nodes in the same environment as the querying node. This can be
270overriden using the +AllEnvs option:
271
Petr Michalecab9cac32017-09-18 17:35:54 +0200272.. code-block:: yaml
273
Petr Michalecad441172017-09-18 17:18:10 +0200274 $[ +AllEnvs exports:test ]
275
276Any 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 +0200277This can be overriden using the ``+IgnoreErrors`` option:
278
279.. code-block:: yaml
Petr Michalecad441172017-09-18 17:18:10 +0200280
281 $[ +IgnoreErrors exports:test ]
282
Petr Michalecab9cac32017-09-18 17:35:54 +0200283With the ``+IgnoreErrors`` option nodes which generate an error evaluating ``exports:test`` will be ignored.
Petr Michalecad441172017-09-18 17:18:10 +0200284
285Inventory query options can be combined:
286
Petr Michalecab9cac32017-09-18 17:35:54 +0200287.. code-block:: yaml
288
Petr Michalecad441172017-09-18 17:18:10 +0200289 $[ +AllEnvs +IgnoreErrors exports:test ]
290
291**Logical operators and/or**
292
293The logical operators and/or can be used in inventory queries:
294
Petr Michalecab9cac32017-09-18 17:35:54 +0200295.. code-block:: yaml
296
Petr Michalecad441172017-09-18 17:18:10 +0200297 $[ exports:test_value if exports:test_zero == 0 and exports:test_one == self:value ]
298
299The individual elements of the if statement are evaluated and combined with the logical operators starting from the
300left and working to the right.
301
302
303**Inventory query example**
304
305Defining a cluster of machines using an inventory query, for example to open access to a database server to a
306group of nodes. Given exports/parameters for nodes of the form:
307
308.. code-block:: yaml
309
Petr Michalecab9cac32017-09-18 17:35:54 +0200310 # for all nodes requiring access to the database server
311 exports:
312 host:
313 ip_address: aaa.bbb.ccc.ddd
314 cluster: _some_cluster_name_
Petr Michalecad441172017-09-18 17:18:10 +0200315
316.. code-block:: yaml
317
Petr Michalecab9cac32017-09-18 17:35:54 +0200318 # for the database server
319 parameters:
320 cluster_name: production-cluster
321 postgresql:
322 server:
323 clients: $[ exports:host:ip_address if exports:cluster == self:cluster_name ]
Petr Michalecad441172017-09-18 17:18:10 +0200324
Petr Michalecab9cac32017-09-18 17:35:54 +0200325This will generate a dictionary with an entry for node where the ``export:cluster`` key for a node is equal to the
326``parameter:cluster_name`` key of the node on which the inventory query is run on. Each entry in the generated dictionary
327will contain the value of the ``exports:host:ip_address`` key. The output dictionary (depending on node definitions)
Petr Michalecad441172017-09-18 17:18:10 +0200328would look like:
329
330.. code-block:: yaml
331
Petr Michalecab9cac32017-09-18 17:35:54 +0200332 node1:
333 ip_address: aaa.bbb.ccc.ddd
334 node2:
335 ip_address: www.xxx.yyy.zzz
Petr Michalecad441172017-09-18 17:18:10 +0200336
337For nodes where exports:cluster key is not defined or where the key is not equal to self:cluster_name no entry is made
338in the output dictionary.
339
340In practise the exports:cluster key can be set using a parameter reference:
341
342.. code-block:: yaml
343
Petr Michalecab9cac32017-09-18 17:35:54 +0200344 exports:
345 cluster: ${cluster_name}
346 parameters:
347 cluster_name: production-cluster
Petr Michalecad441172017-09-18 17:18:10 +0200348
349The above exports and parameter definitions could be put into a separate class and then included by nodes which require
350access to the database and included by the database server as well.