index.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. .. _renderers:
  2. =========
  3. Renderers
  4. =========
  5. The Salt state system operates by gathering information from common data types
  6. such as lists, dictionaries, and strings that would be familiar to any
  7. developer.
  8. Salt Renderers translate input from the format in which it is written into
  9. Python data structures.
  10. The default renderer is set in the master/minion configuration file using the
  11. :conf_master:`renderer` config option, which defaults to ``jinja|yaml``.
  12. Two Kinds of Renderers
  13. ----------------------
  14. Renderers fall into one of two categories, based on what they output: text or
  15. data. The one exception to this would be the :mod:`pure python
  16. <salt.renderers.py>` renderer, which can be used in either capacity.
  17. Text Renderers
  18. **************
  19. A text renderer returns text. These include templating engines such as
  20. :mod:`jinja <salt.renderers.jinja>`, :mod:`mako <salt.renderers.mako>`, and
  21. :mod:`genshi <salt.renderers.genshi>`, as well as the :mod:`gpg
  22. <salt.renderers.gpg>` renderer. The following are all text renderers:
  23. - :mod:`aws_kms <salt.renderers.aws_kms>`
  24. - :mod:`cheetah <salt.renderers.cheetah>`
  25. - :mod:`genshi <salt.renderers.genshi>`
  26. - :mod:`gpg <salt.renderers.gpg>`
  27. - :mod:`jinja <salt.renderers.jinja>`
  28. - :mod:`mako <salt.renderers.mako>`
  29. - :mod:`nacl <salt.renderers.nacl>`
  30. - :mod:`pass <salt.renderers.pass>`
  31. - :mod:`py <salt.renderers.py>`
  32. - :mod:`wempy <salt.renderers.wempy>`
  33. Data Renderers
  34. **************
  35. A data renderer returns a Python data structure (typically a dictionary). The
  36. following are all data renderers:
  37. - :mod:`dson <salt.renderers.dson>`
  38. - :mod:`hjson <salt.renderers.hjson>`
  39. - :mod:`json5 <salt.renderers.json5>`
  40. - :mod:`json <salt.renderers.json>`
  41. - :mod:`pydsl <salt.renderers.pydsl>`
  42. - :mod:`pyobjects <salt.renderers.pyobjects>`
  43. - :mod:`py <salt.renderers.py>`
  44. - :mod:`stateconf <salt.renderers.stateconf>`
  45. - :mod:`yamlex <salt.renderers.yamlex>`
  46. - :mod:`yaml <salt.renderers.yaml>`
  47. Overriding the Default Renderer
  48. -------------------------------
  49. It can sometimes be beneficial to write an SLS file using a renderer other than
  50. the default one. This can be done by using a "shebang"-like syntax on the first
  51. line of the SLS file:
  52. Here is an example of using the :mod:`pure python <salt.renderers.py>` renderer
  53. to install a package:
  54. .. code-block:: python
  55. #!py
  56. def run():
  57. '''
  58. Install version 1.5-1.el7 of package "python-foo"
  59. '''
  60. return {
  61. 'include': ['python'],
  62. 'python-foo': {
  63. 'pkg.installed': [
  64. {'version': '1.5-1.el7'},
  65. ]
  66. }
  67. }
  68. This would be equivalent to the following:
  69. .. code-block:: yaml
  70. include:
  71. - python
  72. python-foo:
  73. pkg.installed:
  74. - version: '1.5-1.el7'
  75. .. _renderers-composing:
  76. Composing Renderers (a.k.a. The "Render Pipeline")
  77. --------------------------------------------------
  78. A render pipeline can be composed from other renderers by connecting them in a
  79. series of "pipes" (i.e. ``|``). The renderers will be evaluated from left to
  80. right, with each renderer receiving the result of the previous renderer's
  81. execution.
  82. Take for example the default renderer (``jinja|yaml``). The file is evaluated
  83. first a jinja template, and the result of that template is evaluated as a YAML
  84. document.
  85. Other render pipeline combinations include:
  86. ``yaml``
  87. Just YAML, no templating.
  88. ``mako|yaml``
  89. This passes the input to the ``mako`` renderer, with its output fed into
  90. the ``yaml`` renderer.
  91. ``jinja|mako|yaml``
  92. This one allows you to use both jinja and mako templating syntax in the
  93. input and then parse the final rendered output as YAML.
  94. The following is a contrived example SLS file using the ``jinja|mako|yaml``
  95. render pipeline:
  96. .. code-block:: text
  97. #!jinja|mako|yaml
  98. An_Example:
  99. cmd.run:
  100. - name: |
  101. echo "Using Salt ${grains['saltversion']}" \
  102. "from path {{grains['saltpath']}}."
  103. - cwd: /
  104. <%doc> ${...} is Mako's notation, and so is this comment. </%doc>
  105. {# Similarly, {{...}} is Jinja's notation, and so is this comment. #}
  106. .. important::
  107. Keep in mind that not all renderers can be used alone or with any other
  108. renderers. For example, text renderers shouldn't be used alone as their
  109. outputs are just strings, which still need to be parsed by another renderer
  110. to turn them into Python data structures.
  111. For example, it would not make sense to use ``yaml|jinja`` because the
  112. output of the :mod:`yaml <salt.renderers.yaml>` renderer is a Python data
  113. structure, and the :mod:`jinja <salt.renderers.jinja>` renderer only
  114. accepts text as input.
  115. Therefore, when combining renderers, you should know what each renderer
  116. accepts as input and what it returns as output. One way of thinking about
  117. it is that you can chain together multiple text renderers, but the pipeline
  118. *must* end in a data renderer. Similarly, since the text renderers in Salt
  119. don't accept data structures as input, a text renderer should usually not
  120. come after a data renderer. It's technically *possible* to write a renderer
  121. that takes a data structure as input and returns a string, but no such
  122. renderer is distributed with Salt.
  123. Writing Renderers
  124. -----------------
  125. A custom renderer must be a Python module which implements a ``render``
  126. function. This function must implement three positional arguments:
  127. 1. ``data`` - Can be called whatever you like. This is the input to be
  128. rendered.
  129. 2. ``saltenv``
  130. 3. ``sls``
  131. The first is the important one, and the 2nd and 3rd must be included since Salt
  132. needs to pass this info to each render, even though it is only used by template
  133. renderers.
  134. Renderers should be written so that the ``data`` argument can accept either
  135. strings or file-like objects as input. For example:
  136. .. code-block:: python
  137. import mycoolmodule
  138. from salt.ext import six
  139. def render(data, saltenv='base', sls='', **kwargs):
  140. if not isinstance(data, six.string_types):
  141. # Read from file-like object
  142. data = data.read()
  143. return mycoolmodule.do_something(data)
  144. Custom renderers should be placed within ``salt://_renderers/``, so that they
  145. can be synced to minions. They are synced when any of the following are run:
  146. - :py:func:`state.apply <salt.modules.state.apply_>`
  147. - :py:func:`saltutil.sync_renderers <salt.modules.saltutil.sync_renderers>`
  148. - :py:func:`saltutil.sync_all <salt.modules.saltutil.sync_all>`
  149. Any custom renderers which have been synced to a minion, that are named the
  150. same as one of Salt's default set of renderers, will take the place of the
  151. default renderer with the same name.
  152. .. note::
  153. Renderers can also be synced from ``salt://_renderers/`` to the Master
  154. using either the :py:func:`saltutil.sync_renderers
  155. <salt.runners.saltutil.sync_renderers>` or :py:func:`saltutil.sync_all
  156. <salt.runners.saltutil.sync_all>` runner function.
  157. Examples
  158. --------
  159. The best place to find examples of renderers is in the Salt source code.
  160. Documentation for renderers included with Salt can be found here:
  161. :blob:`salt/renderers`
  162. Here is a simple YAML renderer example:
  163. .. code-block:: python
  164. import salt.utils.yaml
  165. from salt.utils.yamlloader import SaltYamlSafeLoader
  166. from salt.ext import six
  167. def render(yaml_data, saltenv='', sls='', **kws):
  168. if not isinstance(yaml_data, six.string_types):
  169. yaml_data = yaml_data.read()
  170. data = salt.utils.yaml.safe_load(yaml_data)
  171. return data if data else {}
  172. Full List of Renderers
  173. ----------------------
  174. .. toctree::
  175. all/index