| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 1 | Escaping of References and Inventory Queries | 
 | 2 | -------------------------------------------- | 
 | 3 |  | 
 | 4 | Reference 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 |  | 
 | 15 | This 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 |  | 
 | 27 | Ignore class not found | 
 | 28 | ---------------------- | 
 | 29 |  | 
 | 30 | At some cases (bootstrapping, development) it can be convenient to ignore some missing classes. | 
 | 31 | To control the feature there are two options available: | 
 | 32 |  | 
 | 33 | .. code-block:: yaml | 
 | 34 |  | 
 | 35 |   ignore_class_notfound: False | 
| Petr Michalec | 1932474 | 2017-09-18 17:32:24 +0200 | [diff] [blame] | 36 |   ignore_class_regexp: ['.*'] | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 37 |  | 
 | 38 | If you set regexp pattern to ``service.*`` all missing classes starting 'service.' will be logged with warning, but will not | 
 | 39 | fail to return rendered reclass. Assuming all parameter interpolation passes. | 
 | 40 |  | 
 | 41 |  | 
 | 42 |  | 
 | 43 | Merging Referenced Lists and Dictionaries | 
 | 44 | ----------------------------------------- | 
 | 45 |  | 
 | 46 | Referenced 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 |  | 
 | 90 | This first sets the parameter three to the value of parameter one (class test1) then merges parameter two into | 
 | 91 | parameter three (class test2) and finally merges the parameter three definition given in the node definition into | 
 | 92 | the final value. | 
 | 93 |  | 
 | 94 |  | 
| Petr Michalec | 0a3a368 | 2018-03-28 15:30:15 +0200 | [diff] [blame] | 95 | Allow override list and dicts by empty entity,None instead of merge | 
 | 96 | ------------------------------------------------------------------- | 
 | 97 |  | 
 | 98 | With settings: | 
 | 99 |  | 
 | 100 | .. code-block:: yaml | 
 | 101 |  | 
 | 102 |   allow_none_override: True       # default True | 
 | 103 |  | 
 | 104 |   # note dict,list over None is allowed and not configurable | 
 | 105 |  | 
 | 106 | Referenced lists or dicts can now be overriden by None or empty type of dict, list: | 
 | 107 |  | 
 | 108 | .. code-block:: yaml | 
 | 109 |  | 
 | 110 |   # nodes/test.yml | 
 | 111 |   parameters: | 
 | 112 |     one: | 
 | 113 |       a: 1 | 
 | 114 |       b: 2 | 
 | 115 |     two: {} | 
 | 116 |     three: None | 
 | 117 |  | 
 | 118 |   # classes/test1.yml | 
 | 119 |   parameters: | 
 | 120 |     one: ${two} | 
 | 121 |  | 
 | 122 |   # classes/test2.yml | 
 | 123 |   parameters: | 
 | 124 |     three: ${one} | 
 | 125 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 126 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 127 | Constant Parameters | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 128 | -------------------------- | 
 | 129 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 130 | Parameters can be labeled as constant by using the prefix ``=`` | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 131 |  | 
 | 132 | .. code-block:: yaml | 
 | 133 |  | 
 | 134 |   parameters: | 
 | 135 |     =one: 1 | 
 | 136 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 137 | If in the normal parameter merging a constant parameter would be changed then depending | 
 | 138 | on the setting of ``strict_constant_parameters`` either an exception is raised (``strict_constant_parameters`` true) | 
 | 139 | or the parameter is left unchanged and no notification or error is given (``strict_constant_parameters`` false) | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 140 |  | 
 | 141 | For example with: | 
 | 142 |  | 
 | 143 | .. code-block:: yaml | 
 | 144 |  | 
 | 145 |   # nodes/node1.yml | 
 | 146 |   classes: | 
 | 147 |   - first | 
 | 148 |   - second | 
 | 149 |  | 
 | 150 |   # classes/first.yml | 
 | 151 |   parameters: | 
 | 152 |     =one: 1 | 
 | 153 |  | 
 | 154 |   # classes/second.yml | 
 | 155 |   parameters: | 
 | 156 |     one: 2 | 
 | 157 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 158 | ``reclass.py --nodeinfo node1`` then gives an ''Attempt to change constant value'' error if ``strict_constant_parameters`` | 
 | 159 | is true or gives: | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 160 |  | 
 | 161 | .. code-block:: yaml | 
 | 162 |  | 
 | 163 |   parameters: | 
 | 164 |     alpha: | 
 | 165 |       one: 1 | 
 | 166 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 167 | if ``strict_constant_parameters`` is false | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 168 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 169 | Default value for ``strict_constant_parameters`` is True | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 170 |  | 
 | 171 | .. code-block:: yaml | 
 | 172 |  | 
| Andrew Pickford | 34d1445 | 2018-07-18 15:46:11 +0200 | [diff] [blame] | 173 |   strict_constant_parameters: True | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 174 |  | 
 | 175 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 176 | Nested References | 
 | 177 | ----------------- | 
 | 178 |  | 
 | 179 | References can now be nested, for example: | 
 | 180 |  | 
 | 181 | .. code-block:: yaml | 
 | 182 |  | 
 | 183 |   # nodes/node1.yml | 
 | 184 |   parameters: | 
 | 185 |     alpha: | 
 | 186 |       one: ${beta:${alpha:two}} | 
 | 187 |       two: a | 
 | 188 |     beta: | 
 | 189 |       a: 99 | 
 | 190 |  | 
 | 191 | ``reclass.py --nodeinfo node1`` then gives: | 
 | 192 |  | 
 | 193 | .. code-block:: yaml | 
 | 194 |  | 
 | 195 |   parameters: | 
 | 196 |     alpha: | 
 | 197 |       one: 99 | 
 | 198 |       two: a | 
 | 199 |     beta: | 
 | 200 |       a: 99 | 
 | 201 |  | 
 | 202 | The ``${beta:${alpha:two}}`` construct first resolves the ``${alpha:two}`` reference to the value 'a', then resolves | 
 | 203 | the reference ``${beta:a}`` to the value 99. | 
 | 204 |  | 
 | 205 |  | 
| Andrew Pickford | e0eb7b6 | 2018-03-16 08:45:42 +0100 | [diff] [blame] | 206 | Ignore overwritten missing references | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 207 | ------------------------------------- | 
| Andrew Pickford | e0eb7b6 | 2018-03-16 08:45:42 +0100 | [diff] [blame] | 208 |  | 
 | 209 | Given the following classes: | 
 | 210 |  | 
 | 211 | .. code-block:: yaml | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 212 |  | 
| Andrew Pickford | e0eb7b6 | 2018-03-16 08:45:42 +0100 | [diff] [blame] | 213 |   # node1.yml | 
 | 214 |   classes: | 
 | 215 |   - class1 | 
 | 216 |   - class2 | 
 | 217 |   - class3 | 
 | 218 |  | 
 | 219 |   # class1.yml | 
 | 220 |   parameters: | 
 | 221 |     a: ${x} | 
 | 222 |  | 
 | 223 |   # class2.yml | 
 | 224 |   parameters: | 
 | 225 |     a: ${y} | 
 | 226 |  | 
 | 227 |   # class3.yml | 
 | 228 |   parameters: | 
 | 229 |     y: 1 | 
 | 230 |  | 
| Luis Buriola | c04e1b0 | 2018-07-17 16:57:35 +0100 | [diff] [blame] | 231 |  | 
| Andrew Pickford | e0eb7b6 | 2018-03-16 08:45:42 +0100 | [diff] [blame] | 232 | The parameter ``a`` only depends on the parameter ``y`` through the reference set in class2. The fact that the parameter ``x`` referenced | 
 | 233 | in class1 is not defined does not affect the final value of the parameter ``a``. For such overwritten missing references by default a warning is | 
 | 234 | printed 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 | 
 | 235 | an error will always be raised in the case of a missing reference. | 
 | 236 |  | 
 | 237 | Default value is True to keep backward compatible behavior. | 
 | 238 |  | 
 | 239 | .. code-block:: yaml | 
 | 240 |  | 
 | 241 |   ignore_overwritten_missing_reference: True | 
 | 242 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 243 |  | 
| Andrew Pickford | ffd77b4 | 2018-03-16 14:37:03 +0100 | [diff] [blame] | 244 | Print summary of missed references | 
 | 245 | ---------------------------------- | 
 | 246 |  | 
 | 247 | Instead of failing on the first undefinded reference error all missing reference errors are printed at once. | 
 | 248 |  | 
 | 249 | .. code-block:: yaml | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 250 |  | 
| Andrew Pickford | ffd77b4 | 2018-03-16 14:37:03 +0100 | [diff] [blame] | 251 |   reclass --nodeinfo mynode | 
 | 252 |   -> dontpanic | 
 | 253 |      Cannot resolve ${_param:kkk}, at mkkek3:tree:to:fail, in yaml_fs:///test/classes/third.yml | 
 | 254 |      Cannot resolve ${_param:kkk}, at mkkek3:tree:another:xxxx, in yaml_fs:///test/classes/third.yml | 
 | 255 |      Cannot resolve ${_param:kkk}, at mykey2:tree:to:fail, in yaml_fs:///test/classes/third.yml | 
 | 256 |  | 
 | 257 | .. code-block:: yaml | 
 | 258 |  | 
 | 259 |   group_errors: True | 
 | 260 |  | 
 | 261 |  | 
| Andrew Pickford | 04cb20a | 2018-04-24 14:27:50 +0200 | [diff] [blame] | 262 | Use references in class names | 
 | 263 | ----------------------------- | 
 | 264 |  | 
 | 265 | Allows to use references in the class names. | 
 | 266 |  | 
 | 267 | References pointed to in class names cannot themselves reference another key, they should be simple strings. | 
 | 268 |  | 
 | 269 | To avoid pitfalls do not over-engineer your class references. They should be used only for core conditions and only for them. | 
 | 270 | A short example: `- system.wrodpress.db.${_class:database_backend}`. | 
 | 271 |  | 
 | 272 | Best practices: | 
 | 273 | - use references in class names always load your global class specification prior the reference is used. | 
 | 274 | - structure your class references under parameters under one key (for example `_class`). | 
 | 275 | - use class references as a kind of "context" or "global" available options you always know what they are set. | 
 | 276 |  | 
 | 277 | Class referencing for existing reclass users. Frequently when constructing your models you had to load or not load some | 
 | 278 | classes based on your setup. In most cases this lead to fork of a model or introducing kind of template generator (like cookiecutter) to | 
 | 279 | create a model based on the base "context" or "global" variables. Class referencing is a simple way how to avoid | 
 | 280 | "pre-processors" like this and if/else conditions around class section. | 
 | 281 |  | 
 | 282 |  | 
 | 283 | Assuming following class setup: | 
 | 284 |  | 
 | 285 | * node is loading `third.yml` class only | 
 | 286 |  | 
 | 287 |  | 
 | 288 | Classes: | 
 | 289 |  | 
 | 290 | .. code-block:: yaml | 
| Andrew Pickford | e3b114e | 2018-06-27 16:30:38 +0200 | [diff] [blame] | 291 |  | 
| Andrew Pickford | 04cb20a | 2018-04-24 14:27:50 +0200 | [diff] [blame] | 292 |   #/etc/reclass/classes/global.yml | 
 | 293 |   parameters: | 
 | 294 |     _class: | 
 | 295 |       env: | 
 | 296 |         override: 'env.dev' | 
 | 297 |     lab: | 
 | 298 |       name: default | 
 | 299 |  | 
 | 300 |   #/etc/reclass/classes/lab/env/dev.yml | 
 | 301 |   parameters: | 
 | 302 |     lab: | 
 | 303 |       name: dev | 
 | 304 |  | 
 | 305 |   #/etc/reclass/classes/second.yml | 
 | 306 |   classes: | 
 | 307 |     - global | 
 | 308 |     - lab.${_class:env:override} | 
 | 309 |  | 
 | 310 |   #/etc/reclass/classes/third.yml | 
 | 311 |   classes: | 
 | 312 |     - global | 
 | 313 |     - second | 
 | 314 |  | 
 | 315 |  | 
 | 316 | Reclass --nodeinfo then returns: | 
 | 317 |  | 
 | 318 | .. code-block:: yaml | 
 | 319 |  | 
 | 320 |   ... | 
 | 321 |   ... | 
 | 322 |   applications: [] | 
 | 323 |   environment: base | 
 | 324 |   exports: {} | 
 | 325 |   classes: | 
| Petr Michalec | 67e737c | 2018-04-25 09:44:02 +0200 | [diff] [blame] | 326 |   - global | 
| Andrew Pickford | 04cb20a | 2018-04-24 14:27:50 +0200 | [diff] [blame] | 327 |   - lab.${_class:env:override} | 
 | 328 |   - second | 
 | 329 |   parameters: | 
 | 330 |     _class: | 
 | 331 |       env: | 
 | 332 |         override: env.dev | 
 | 333 |     lab: | 
 | 334 |       name: dev | 
 | 335 |     ... | 
 | 336 |     ... | 
 | 337 |  | 
 | 338 |  | 
| Petr Michalec | d2762b0 | 2018-09-05 14:01:52 +0200 | [diff] [blame] | 339 | Load classes with relative names | 
 | 340 | -------------------------------- | 
 | 341 |  | 
 | 342 | Load referenced class from a relative location to the current class. | 
 | 343 | To load class from relative location start the class uri with "." char. | 
 | 344 | The only supported reference is to nested tree structure below the current class. | 
 | 345 |  | 
 | 346 | You are allowed to use syntax for relative uri to required class on any place on your model (first class loaded, init.yml, regular class .yml). | 
 | 347 |  | 
 | 348 | The feature is expected to improve flexibility while sharing classes between your models. | 
 | 349 |  | 
 | 350 | It's a new feature use it with care and mind that using "relative syntax" lower traceability of | 
 | 351 | your pillar composition. | 
 | 352 |  | 
 | 353 | Example usage of relative class name: | 
 | 354 |  | 
 | 355 | .. code-block:: yaml | 
 | 356 |  | 
 | 357 |   #/etc/reclass/classes/component/defaults.yml | 
 | 358 |   classes: | 
 | 359 |     component: | 
 | 360 |       config: | 
 | 361 |         a: b | 
 | 362 |  | 
 | 363 | .. code-block:: yaml | 
 | 364 |  | 
 | 365 |   #/etc/reclass/classes/component/init.yml | 
 | 366 |   classes: | 
 | 367 |     - .defaults | 
 | 368 |  | 
 | 369 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 370 | Inventory Queries | 
 | 371 | ----------------- | 
 | 372 |  | 
 | 373 | Inventory querying works using a new key type - exports to hold values which other node definitions can read using a $[] query, for example with: | 
 | 374 |  | 
 | 375 | .. code-block:: yaml | 
 | 376 |  | 
 | 377 |   # nodes/node1.yml | 
 | 378 |   exports: | 
 | 379 |     test_zero: 0 | 
 | 380 |     test_one: | 
 | 381 |       name: ${name} | 
 | 382 |       value: 6 | 
 | 383 |     test_two: ${dict} | 
 | 384 |  | 
 | 385 |   parameters: | 
 | 386 |     name: node1 | 
 | 387 |     dict: | 
 | 388 |       a: 1 | 
 | 389 |       b: 2 | 
 | 390 |     exp_value_test: $[ exports:test_two ] | 
 | 391 |     exp_if_test0: $[ if exports:test_zero == 0 ] | 
 | 392 |     exp_if_test1: $[ exports:test_one if exports:test_one:value == 7 ] | 
 | 393 |     exp_if_test2: $[ exports:test_one if exports:test_one:name == self:name ] | 
 | 394 |  | 
 | 395 |   # nodes/node2.yml | 
 | 396 |   exports: | 
 | 397 |     test_zero: 0 | 
 | 398 |     test_one: | 
 | 399 |       name: ${name} | 
 | 400 |       value: 7 | 
 | 401 |     test_two: ${dict} | 
 | 402 |  | 
 | 403 |   parameters: | 
 | 404 |     name: node2 | 
 | 405 |     dict: | 
 | 406 |       a: 11 | 
 | 407 |       b: 22 | 
 | 408 |  | 
 | 409 |  | 
 | 410 | ``running reclass.py --nodeinfo node1``  gives (listing only the exports and parameters): | 
 | 411 |  | 
 | 412 | .. code-block:: yaml | 
 | 413 |  | 
 | 414 |   exports: | 
 | 415 |     test_one: | 
 | 416 |       name: node1 | 
 | 417 |       value: 6 | 
 | 418 |     test_two: | 
 | 419 |       a: 1 | 
 | 420 |       b: 2 | 
 | 421 |   parameters: | 
 | 422 |     dict: | 
 | 423 |       a: 1 | 
 | 424 |       b: 2 | 
 | 425 |     exp_if_test0: | 
 | 426 |       - node1 | 
 | 427 |       - node2 | 
 | 428 |     exp_if_test1: | 
 | 429 |       node2: | 
 | 430 |         name: node2 | 
 | 431 |         value: 7 | 
 | 432 |     exp_if_test2: | 
 | 433 |       node1: | 
 | 434 |         name: node1 | 
 | 435 |         value: 6 | 
 | 436 |     exp_value_test: | 
 | 437 |       node1: | 
 | 438 |         a: 1 | 
 | 439 |         b: 2 | 
 | 440 |       node2: | 
 | 441 |         a: 11 | 
 | 442 |         b: 22 | 
 | 443 |     name: node1 | 
 | 444 |  | 
 | 445 |  | 
 | 446 | Exports defined for a node can be a simple value or a reference to a parameter in the node definition. | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 447 | The ``$[]`` inventory queries are calculated for simple value expressions, ``$[ exports:key ]``, by returning | 
 | 448 | a dictionary with an element (``{ node_name: key value }``) for each node which defines 'key' in the exports | 
 | 449 | section. For tests with a preceeding value, ``$[ exports:key if exports:test_key == test_value ]``, the | 
 | 450 | element (``{ node_name: key value }``) is only added to the returned dictionary if the test_key defined in | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 451 | the node exports section equals the test value. For tests without a preceeding value, | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 452 | ``$[ if exports:test_key == test_value ]``, a list of nodes which pass the test is returned. For either test | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 453 | form the test value can either be a simple value or a node parameter. And as well as an equality test | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 454 | a not equals test (``!=``) can also be used. | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 455 |  | 
 | 456 |  | 
 | 457 | **Inventory query options** | 
 | 458 |  | 
 | 459 | By default inventory queries only look at nodes in the same environment as the querying node. This can be | 
 | 460 | overriden using the +AllEnvs option: | 
 | 461 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 462 | .. code-block:: yaml | 
 | 463 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 464 |   $[ +AllEnvs exports:test ] | 
 | 465 |  | 
 | 466 | Any errors in rendering the export parameters for a node will give an error for the inventory query as a whole. | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 467 | This can be overriden using the ``+IgnoreErrors`` option: | 
 | 468 |  | 
 | 469 | .. code-block:: yaml | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 470 |  | 
 | 471 |   $[ +IgnoreErrors exports:test ] | 
 | 472 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 473 | With the ``+IgnoreErrors`` option nodes which generate an error evaluating ``exports:test`` will be ignored. | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 474 |  | 
 | 475 | Inventory query options can be combined: | 
 | 476 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 477 | .. code-block:: yaml | 
 | 478 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 479 |   $[ +AllEnvs +IgnoreErrors exports:test ] | 
 | 480 |  | 
 | 481 | **Logical operators and/or** | 
 | 482 |  | 
 | 483 | The logical operators and/or can be used in inventory queries: | 
 | 484 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 485 | .. code-block:: yaml | 
 | 486 |  | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 487 |   $[ exports:test_value if exports:test_zero == 0 and exports:test_one == self:value ] | 
 | 488 |  | 
 | 489 | The individual elements of the if statement are evaluated and combined with the logical operators starting from the | 
 | 490 | left and working to the right. | 
 | 491 |  | 
 | 492 |  | 
 | 493 | **Inventory query example** | 
 | 494 |  | 
 | 495 | Defining a cluster of machines using an inventory query, for example to open access to a database server to a | 
 | 496 | group of nodes. Given exports/parameters for nodes of the form: | 
 | 497 |  | 
 | 498 | .. code-block:: yaml | 
 | 499 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 500 |   # for all nodes requiring access to the database server | 
 | 501 |     exports: | 
 | 502 |       host: | 
 | 503 |         ip_address: aaa.bbb.ccc.ddd | 
 | 504 |       cluster: _some_cluster_name_ | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 505 |  | 
 | 506 | .. code-block:: yaml | 
 | 507 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 508 |   # for the database server | 
 | 509 |   parameters: | 
 | 510 |     cluster_name: production-cluster | 
 | 511 |     postgresql: | 
 | 512 |       server: | 
 | 513 |         clients: $[ exports:host:ip_address if exports:cluster == self:cluster_name ] | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 514 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 515 | This will generate a dictionary with an entry for node where the ``export:cluster`` key for a node is equal to the | 
 | 516 | ``parameter:cluster_name`` key of the node on which the inventory query is run on. Each entry in the generated dictionary | 
 | 517 | will contain the value of the ``exports:host:ip_address`` key. The output dictionary (depending on node definitions) | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 518 | would look like: | 
 | 519 |  | 
 | 520 | .. code-block:: yaml | 
 | 521 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 522 |   node1: | 
 | 523 |     ip_address: aaa.bbb.ccc.ddd | 
 | 524 |   node2: | 
 | 525 |     ip_address: www.xxx.yyy.zzz | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 526 |  | 
 | 527 | For nodes where exports:cluster key is not defined or where the key is not equal to self:cluster_name no entry is made | 
 | 528 | in the output dictionary. | 
 | 529 |  | 
 | 530 | In practise the exports:cluster key can be set using a parameter reference: | 
 | 531 |  | 
 | 532 | .. code-block:: yaml | 
 | 533 |  | 
| Petr Michalec | ab9cac3 | 2017-09-18 17:35:54 +0200 | [diff] [blame] | 534 |   exports: | 
 | 535 |     cluster: ${cluster_name} | 
 | 536 |   parameters: | 
 | 537 |     cluster_name: production-cluster | 
| Petr Michalec | ad44117 | 2017-09-18 17:18:10 +0200 | [diff] [blame] | 538 |  | 
 | 539 | The above exports and parameter definitions could be put into a separate class and then included by nodes which require | 
 | 540 | access to the database and included by the database server as well. | 
| Luis Buriola | c04e1b0 | 2018-07-17 16:57:35 +0100 | [diff] [blame] | 541 |  | 
 | 542 |  | 
| Luis Buriola | 96d7ace | 2018-07-22 22:00:02 +0100 | [diff] [blame] | 543 | Compose node name | 
| Luis Buriola | c04e1b0 | 2018-07-17 16:57:35 +0100 | [diff] [blame] | 544 | --------------------------- | 
 | 545 |  | 
 | 546 | Nodes can be defined in subdirectories. However, node names (filename) must be unique across all subdirectories. | 
 | 547 |  | 
 | 548 | For example, the following file structure is invalid: | 
 | 549 |  | 
 | 550 | .. code-block:: yaml | 
 | 551 |  | 
 | 552 |   inventory/nodes/prod/mysql.yml | 
 | 553 |   inventory/nodes/staging/mysql.yml | 
 | 554 |  | 
 | 555 | With setting: | 
 | 556 |  | 
 | 557 | .. code-block:: yaml | 
 | 558 |  | 
| Luis Buriola | 96d7ace | 2018-07-22 22:00:02 +0100 | [diff] [blame] | 559 |   compose_node_name: True       # default False | 
| Luis Buriola | c04e1b0 | 2018-07-17 16:57:35 +0100 | [diff] [blame] | 560 |  | 
 | 561 | This adds the subfolder to the node name and the structure above can then be used. It generates the following reclass objects: | 
 | 562 |  | 
 | 563 | .. code-block:: yaml | 
 | 564 |  | 
 | 565 |   nodes: | 
 | 566 |     prod.mysql: | 
 | 567 |       ... | 
 | 568 |     staging.mysql: | 
 | 569 |       ... | 
| Luis Buriola | a7bfd74 | 2018-07-23 10:43:46 +0100 | [diff] [blame] | 570 |  | 
 | 571 | If the subfolder path starts with the underscore character ``_``, then the subfolder path is NOT added to the node name. |