blob: 31458b683b90decbd88a68db7550c5342c8da9f9 [file] [log] [blame]
Andrew Pickfordbb0a6192017-09-08 16:04:24 +02001Escaping of References and Inventory Queries
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +02002--------------------------------------------
Andrew Pickfordbb0a6192017-09-08 16:04:24 +02003
4Reference and inventory queries can be escaped to produce literal strings, for example:
5
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +02006.. 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}
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020013
14
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020015This would produce:
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020016
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020017.. 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
36 ignore_class_regexp: ['*']
37
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.
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020040
41
42
43Merging Referenced Lists and Dictionaries
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020044-----------------------------------------
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020045
46Referenced lists or dicts can now be merged:
47
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020048.. code-block:: yaml
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020049
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020050 # 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
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020063
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020064 # classes/test1.yml
65 parameters:
66 three: ${one}
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020067
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020068 # classes/test2.yml
69 parameters:
70 three: ${two}
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020071
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020072``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
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020089
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
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020092the final value.
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020093
94
95
96Nested References
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +020097-----------------
Andrew Pickfordbb0a6192017-09-08 16:04:24 +020098
99References can now be nested, for example:
100
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200101.. code-block:: yaml
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200102
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200103 # nodes/node1.yml
104 parameters:
105 alpha:
106 one: ${beta:${alpha:two}}
107 two: a
108 beta:
109 a: 99
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200110
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200111``reclass.py --nodeinfo node1`` then gives:
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200112
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200113.. 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.
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200124
125
126
127Inventory Queries
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200128-----------------
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200129
130Inventory querying works using a new key type - exports to hold values which other node definitions can read using a $[] query, for example with:
131
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200132.. code-block:: yaml
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200133
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200134 # nodes/node1.yml
135 exports:
136 test_zero: 0
137 test_one:
138 name: ${name}
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200139 value: 6
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200140 test_two: ${dict}
141
142 parameters:
143 name: node1
144 dict:
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200145 a: 1
146 b: 2
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200147 exp_value_test: $[ exports:test_two ]
148 exp_if_test0: $[ if exports:test_zero == 0 ]
149 exp_if_test1: $[ exports:test_one if exports:test_one:value == 7 ]
150 exp_if_test2: $[ exports:test_one if exports:test_one:name == self:name ]
151
152 # nodes/node2.yml
153 exports:
154 test_zero: 0
155 test_one:
156 name: ${name}
157 value: 7
158 test_two: ${dict}
159
160 parameters:
161 name: node2
162 dict:
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200163 a: 11
164 b: 22
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200165
166
167``running reclass.py --nodeinfo node1`` gives (listing only the exports and parameters):
168
169.. code-block:: yaml
170
171 exports:
172 test_one:
173 name: node1
174 value: 6
175 test_two:
176 a: 1
177 b: 2
178 parameters:
179 dict:
180 a: 1
181 b: 2
182 exp_if_test0:
183 - node1
184 - node2
185 exp_if_test1:
186 node2:
187 name: node2
188 value: 7
189 exp_if_test2:
190 node1:
191 name: node1
192 value: 6
193 exp_value_test:
194 node1:
195 a: 1
196 b: 2
197 node2:
198 a: 11
199 b: 22
200 name: node1
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200201
202
203Exports defined for a node can be a simple value or a reference to a parameter in the node definition.
204The $[] inventory queries are calculated for simple value expressions, $[ exports:key ], by returning
205a dictionary with an element ({ node_name: key value }) for each node which defines 'key' in the exports
206section. For tests with a preceeding value, $[ exports:key if exports:test_key == test_value ], the
207element ({ node_name: key value }) is only added to the returned dictionary if the test_key defined in
208the node exports section equals the test value. For tests without a preceeding value,
209$[ if exports:test_key == test_value ], a list of nodes which pass the test is returned. For either test
210form the test value can either be a simple value or a node parameter. And as well as an equality test
211a not equals test (!=) can also be used.
212
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200213
214**Inventory query options**
Andrew Pickfordbb0a6192017-09-08 16:04:24 +0200215
216By default inventory queries only look at nodes in the same environment as the querying node. This can be
217overriden using the +AllEnvs option:
218
219 $[ +AllEnvs exports:test ]
220
221Any errors in rendering the export parameters for a node will give an error for the inventory query as a whole.
222This can be overriden using the +IgnoreErrors option:
223
224 $[ +IgnoreErrors exports:test ]
225
226With the +IgnoreErrors option nodes which generate an error evaluating exports:test will be ignored.
227
228Inventory query options can be combined:
229
230 $[ +AllEnvs +IgnoreErrors exports:test ]
231
232**Logical operators and/or**
233
234The logical operators and/or can be used in inventory queries:
235
236 $[ exports:test_value if exports:test_zero == 0 and exports:test_one == self:value ]
237
238The individual elements of the if statement are evaluated and combined with the logical operators starting from the
239left and working to the right.
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200240
241
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200242**Inventory query example**
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200243
244Defining a cluster of machines using an inventory query, for example to open access to a database server to a
245group of nodes. Given exports/parameters for nodes of the form:
246
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200247.. code-block:: yaml
248
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200249# for all nodes requiring access to the database server
250exports:
251 host:
252 ip_address: aaa.bbb.ccc.ddd
253 cluster: _some_cluster_name_
254
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200255.. code-block:: yaml
256
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200257# for the database server
258parameters:
259 cluster_name: production-cluster
260 postgresql:
261 server:
262 clients: $[ exports:host:ip_address if exports:cluster == self:cluster_name ]
263
264This will generate a dictionary with an entry for node where the export:cluster key for a node is equal to the
265parameter:cluster_name key of the node on which the inventory query is run on. Each entry in the generated dictionary
266will contain the value of the exports:host:ip_address key. The output dictionary (depending on node definitions)
267would look like:
268
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200269.. code-block:: yaml
270
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200271node1:
272 ip_address: aaa.bbb.ccc.ddd
273node2:
274 ip_address: www.xxx.yyy.zzz
275
276For nodes where exports:cluster key is not defined or where the key is not equal to self:cluster_name no entry is made
277in the output dictionary.
278
279In practise the exports:cluster key can be set using a parameter reference:
280
Andrew Pickfordfd6a3a32017-09-13 16:24:21 +0200281.. code-block:: yaml
282
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200283exports:
284 cluster: ${cluster_name}
Andrew Pickfordf4b93c02017-09-13 15:34:10 +0200285parameters:
286 cluster_name: production-cluster
287
288The above exports and parameter definitions could be put into a separate class and then included by nodes which require
289access to the database and included by the database server as well.