1
0

external_pillars.rst 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. .. _external-pillars:
  2. ================
  3. External Pillars
  4. ================
  5. Salt provides a mechanism for generating pillar data by calling external
  6. pillar interfaces. This document will describe an outline of an ext_pillar
  7. module.
  8. Location
  9. --------
  10. Salt expects to find your ``ext_pillar`` module in the same location where it
  11. looks for other python modules. If the ``extension_modules`` option in your
  12. Salt master configuration is set, Salt will look for a ``pillar`` directory
  13. under there and load all the modules it finds. Otherwise, it will look in
  14. your Python site-packages ``salt/pillar`` directory.
  15. Configuration
  16. -------------
  17. The external pillars that are called when a minion refreshes its pillars is
  18. controlled by the ``ext_pillar`` option in the Salt master configuration. You
  19. can pass a single argument, a list of arguments or a dictionary of arguments
  20. to your pillar:
  21. .. code-block:: yaml
  22. ext_pillar:
  23. - example_a: some argument
  24. - example_b:
  25. - argumentA
  26. - argumentB
  27. - example_c:
  28. keyA: valueA
  29. keyB: valueB
  30. The Module
  31. ----------
  32. Imports and Logging
  33. -------------------
  34. Import modules your external pillar module needs. You should first include
  35. generic modules that come with stock Python:
  36. .. code-block:: python
  37. import logging
  38. And then start logging. This is an idiomatic way of setting up logging in Salt:
  39. .. code-block:: python
  40. log = logging.getLogger(__name__)
  41. Finally, load modules that are specific to what you are doing. You should catch
  42. import errors and set a flag that the ``__virtual__`` function can use later.
  43. .. code-block:: python
  44. try:
  45. import weird_thing
  46. EXAMPLE_A_LOADED = True
  47. except ImportError:
  48. EXAMPLE_A_LOADED = False
  49. Options
  50. -------
  51. If you define an ``__opts__`` dictionary, it will be merged into the
  52. ``__opts__`` dictionary handed to the ``ext_pillar`` function later. This is a
  53. good place to put default configuration items. The convention is to name
  54. things ``modulename.option``.
  55. .. code-block:: python
  56. __opts__ = { 'example_a.someconfig': 137 }
  57. Initialization
  58. --------------
  59. If you define an ``__init__`` function, it will be called with the following
  60. signature:
  61. .. code-block:: python
  62. def __init__( __opts__ ):
  63. # Do init work here
  64. **Note**: The ``__init__`` function is ran every time a particular minion causes
  65. the external pillar to be called, so don't put heavy initialization code here.
  66. The ``__init__`` functionality is a side-effect of the Salt loader, so it may
  67. not be as useful in pillars as it is in other Salt items.
  68. __virtual__
  69. -----------
  70. If you define a ``__virtual__`` function, you can control whether or not this
  71. module is visible. If it returns ``False`` then Salt ignores this module. If
  72. it returns a string, then that string will be how Salt identifies this external
  73. pillar in its ``ext_pillar`` configuration. If you're not renaming the module,
  74. simply return ``True`` in the ``__virtual__`` function, which is the same as if
  75. this function did not exist, then, the name Salt's ``ext_pillar`` will use to
  76. identify this module is its conventional name in Python.
  77. This is useful to write modules that can be installed on all Salt masters, but
  78. will only be visible if a particular piece of software your module requires is
  79. installed.
  80. .. code-block:: python
  81. # This external pillar will be known as `example_a`
  82. def __virtual__():
  83. if EXAMPLE_A_LOADED:
  84. return True
  85. return False
  86. .. code-block:: python
  87. # This external pillar will be known as `something_else`
  88. __virtualname__ = 'something_else'
  89. def __virtual__():
  90. if EXAMPLE_A_LOADED:
  91. return __virtualname__
  92. return False
  93. ext_pillar
  94. ----------
  95. This is where the real work of an external pillar is done. If this module is
  96. active and has a function called ``ext_pillar``, whenever a minion updates its
  97. pillar this function is called.
  98. How it is called depends on how it is configured in the Salt master
  99. configuration. The first argument is always the current pillar dictionary, this
  100. contains pillar items that have already been added, starting with the data from
  101. ``pillar_roots``, and then from any already-ran external pillars.
  102. Using our example above:
  103. .. code-block:: python
  104. ext_pillar( id, pillar, 'some argument' ) # example_a
  105. ext_pillar( id, pillar, 'argumentA', 'argumentB' ) # example_b
  106. ext_pillar( id, pillar, keyA='valueA', keyB='valueB' ) # example_c
  107. In the ``example_a`` case, ``pillar`` will contain the items from the
  108. ``pillar_roots``, in ``example_b`` ``pillar`` will contain that plus the items
  109. added by ``example_a``, and in ``example_c`` ``pillar`` will contain that plus
  110. the items added by ``example_b``. In all three cases, ``id`` will contain the
  111. ID of the minion making the pillar request.
  112. This function should return a dictionary, the contents of which are merged in
  113. with all of the other pillars and returned to the minion. **Note**: this function
  114. is called once for each minion that fetches its pillar data.
  115. .. code-block:: python
  116. def ext_pillar( minion_id, pillar, *args, **kwargs ):
  117. my_pillar = {'external_pillar': {}}
  118. my_pillar['external_pillar'] = get_external_pillar_dictionary()
  119. return my_pillar
  120. You can call pillar with the dictionary's top name to retrieve its data.
  121. From above example, 'external_pillar' is the top dictionary name. Therefore:
  122. .. code-block:: bash
  123. salt-call '*' pillar.get external_pillar
  124. You shouldn't just add items to ``pillar`` and return that, since that will
  125. cause Salt to merge data that already exists. Rather, just return the items
  126. you are adding or changing. You could, however, use ``pillar`` in your module
  127. to make some decision based on pillar data that already exists.
  128. This function has access to some useful globals:
  129. :__opts__:
  130. A dictionary of mostly Salt configuration options. If you had an
  131. ``__opts__`` dictionary defined in your module, those values will be
  132. included.
  133. :__salt__:
  134. A dictionary of Salt module functions, useful so you don't have to
  135. duplicate functions that already exist. E.g.
  136. ``__salt__['cmd.run']( 'ls -l' )`` **Note**, runs on the *master*
  137. :__grains__:
  138. A dictionary of the grains of the minion making this pillar call.
  139. Example configuration
  140. ---------------------
  141. As an example, if you wanted to add external pillar via the ``cmd_json``
  142. external pillar, add something like this to your master config:
  143. .. code-block:: yaml
  144. ext_pillar:
  145. - cmd_json: 'echo {\"arg\":\"value\"}'
  146. Reminder
  147. --------
  148. Just as with traditional pillars, external pillars must be refreshed in order for
  149. minions to see any fresh data:
  150. .. code-block:: bash
  151. salt '*' saltutil.refresh_pillar