mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Document that dict key syntax should be preferred
While `{{ salt.foo.bar() }}` often works, it can introduce some edge cases which are avoided by `{{ salt['foo.bar']() }}`.
This commit is contained in:
parent
096dca61ba
commit
c2e0b57ba9
13 changed files with 57 additions and 49 deletions
|
@ -563,7 +563,7 @@ The ``onfail`` requisite is applied in the same way as ``require`` and ``watch``
|
|||
notify-build_failure:
|
||||
hipchat.send_message:
|
||||
- room_id: 123456
|
||||
- message: "Building website fail on {{ salt.grains.get('id') }}"
|
||||
- message: "Building website fail on {{ salt['grains.get']('id') }}"
|
||||
|
||||
|
||||
The default behavior of the ``onfail`` when multiple requisites are listed is
|
||||
|
@ -723,7 +723,7 @@ be installed. Thus allowing for a requisite to be defined "after the fact".
|
|||
|
||||
.. code-block:: sls
|
||||
|
||||
{% for cfile in salt.pillar.get('nginx:config_files') %}
|
||||
{% for cfile in salt['pillar.get']('nginx:config_files') %}
|
||||
/etc/nginx/conf.d/{{ cfile }}:
|
||||
file.managed:
|
||||
- source: salt://nginx/configs/{{ cfile }}
|
||||
|
|
|
@ -21,6 +21,13 @@ General rules
|
|||
4. Store sensitive data in pillar.
|
||||
5. Don't use grains for matching in your pillar top file for any sensitive
|
||||
pillars.
|
||||
6. When accessing modules from within a template, use the mapping
|
||||
key syntax instead of the attribute one to avoid edge cases. Example:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{%- set do_this = salt['pillar.get']('foo:bar') %}
|
||||
{%- set avoid_this = salt.pillar.get('foo:bar') %}
|
||||
|
||||
.. include:: ../_incl/grains_passwords.rst
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ file. This section contains several suggestions and examples.
|
|||
deploy_myapp:
|
||||
git.latest:
|
||||
- name: git@github.com/myco/myapp.git
|
||||
- version: {{ salt.pillar.get('myapp:version', 'master') }}
|
||||
- version: {{ salt['pillar.get']('myapp:version', 'master') }}
|
||||
|
||||
Use a descriptive State ID
|
||||
``````````````````````````
|
||||
|
@ -363,11 +363,11 @@ for commenting YAML code.
|
|||
|
||||
# BAD EXAMPLE
|
||||
# The Jinja in this YAML comment is still executed!
|
||||
# {% set apache_is_installed = 'apache' in salt.pkg.list_pkgs() %}
|
||||
# {% set apache_is_installed = 'apache' in salt['pkg.list_pkgs']() %}
|
||||
|
||||
# GOOD EXAMPLE
|
||||
# The Jinja in this Jinja comment will not be executed.
|
||||
{# {% set apache_is_installed = 'apache' in salt.pkg.list_pkgs() %} #}
|
||||
{# {% set apache_is_installed = 'apache' in salt['pkg.list_pkgs']() %} #}
|
||||
|
||||
Easy on the Jinja!
|
||||
------------------
|
||||
|
@ -427,7 +427,7 @@ Less common values are often found by running commands. For example:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set is_selinux_enabled = salt.cmd.run('sestatus') == '1' %}
|
||||
{% set is_selinux_enabled = salt['cmd.run']('sestatus') == '1' %}
|
||||
|
||||
This is usually best done with a variable assignment in order to separate the
|
||||
data from the state that will make use of the data.
|
||||
|
@ -442,7 +442,7 @@ from the Salt Master. For example:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set some_data = salt.pillar.get('some_data', {'sane default': True}) %}
|
||||
{% set some_data = salt['pillar.get']('some_data', {'sane default': True}) %}
|
||||
|
||||
{# or #}
|
||||
|
||||
|
@ -478,7 +478,7 @@ Below is a simple example of a readable loop:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% for user in salt.pillar.get('list_of_users', []) %}
|
||||
{% for user in salt['pillar.get']('list_of_users', []) %}
|
||||
|
||||
{# Ensure unique state IDs when looping. #}
|
||||
{{ user.name }}-{{ loop.index }}:
|
||||
|
@ -690,7 +690,7 @@ Macros are useful for creating reusable, parameterized states. For example:
|
|||
- groups: {{ groups | json() }}
|
||||
{% endmacro %}
|
||||
|
||||
{% for user_info in salt.pillar.get('my_users', []) %}
|
||||
{% for user_info in salt['pillar.get']('my_users', []) %}
|
||||
{{ user_state('user_number_' ~ loop.index, **user_info) }}
|
||||
{% endfor %}
|
||||
|
||||
|
@ -708,7 +708,7 @@ example, the following macro could be used to write a php.ini config file:
|
|||
- source: salt://php.ini.tmpl
|
||||
- template: jinja
|
||||
- context:
|
||||
php_ini_settings: {{ salt.pillar.get('php_ini', {}) | json() }}
|
||||
php_ini_settings: {{ salt['pillar.get']('php_ini', {}) | json() }}
|
||||
|
||||
``/srv/pillar/php.sls``:
|
||||
|
||||
|
@ -920,7 +920,7 @@ Pillar can also be used.
|
|||
.. code-block:: jinja
|
||||
|
||||
{% set lookup_table = {...} %}
|
||||
{% do lookup_table.update(salt.pillar.get('my:custom:data')) %}
|
||||
{% do lookup_table.update(salt['pillar.get']('my:custom:data')) %}
|
||||
|
||||
When to use lookup tables
|
||||
`````````````````````````
|
||||
|
@ -994,7 +994,7 @@ XML.)
|
|||
.. code-block:: jinja
|
||||
|
||||
{% import_yaml 'tomcat/defaults.yaml' as server_xml_defaults %}
|
||||
{% set server_xml_final_values = salt.pillar.get(
|
||||
{% set server_xml_final_values = salt['pillar.get'](
|
||||
'appX:server_xml_overrides',
|
||||
default=server_xml_defaults,
|
||||
merge=True)
|
||||
|
@ -1033,11 +1033,11 @@ example:
|
|||
|
||||
{# Extract the relevant subset for the app configured on the current
|
||||
machine (configured via a grain in this example). #}
|
||||
{% app = app_defaults.get(salt.grains.get('role')) %}
|
||||
{% app = app_defaults.get(salt['grains.get']('role')) %}
|
||||
|
||||
{# Allow values from Pillar to (optionally) update values from the lookup
|
||||
table. #}
|
||||
{% do app_defaults.update(salt.pillar.get('myapp', {})) %}
|
||||
{% do app_defaults.update(salt['pillar.get']('myapp', {})) %}
|
||||
|
||||
deploy_application:
|
||||
git.latest:
|
||||
|
|
|
@ -161,7 +161,7 @@ starts at the root of the state tree or pillar.
|
|||
Errors
|
||||
======
|
||||
|
||||
Saltstack allows raising custom errors using the ``raise`` jinja function.
|
||||
Saltstack allows raising custom errors using the ``raise`` Jinja function.
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
|
@ -2506,7 +2506,8 @@ dictionary of :term:`execution function <Execution Function>`.
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
# The following two function calls are equivalent.
|
||||
# The following two function calls are mostly equivalent,
|
||||
# but the first style should be preferred to avoid edge cases.
|
||||
{{ salt['cmd.run']('whoami') }}
|
||||
{{ salt.cmd.run('whoami') }}
|
||||
|
||||
|
@ -2536,7 +2537,7 @@ For example, making the call:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{%- do salt.log.error('testing jinja logging') -%}
|
||||
{%- do salt['log.error']('testing jinja logging') -%}
|
||||
|
||||
Will insert the following message in the minion logs:
|
||||
|
||||
|
@ -2552,14 +2553,14 @@ Profiling
|
|||
.. versionadded:: 3002
|
||||
|
||||
When working with a very large codebase, it becomes increasingly imperative to
|
||||
trace inefficiencies with state and pillar render times. The `profile` jinja
|
||||
trace inefficiencies with state and pillar render times. The `profile` Jinja
|
||||
block enables the user to get finely detailed information on the most expensive
|
||||
areas in the codebase.
|
||||
|
||||
Profiling blocks
|
||||
----------------
|
||||
|
||||
Any block of jinja code can be wrapped in a ``profile`` block. The syntax for
|
||||
Any block of Jinja code can be wrapped in a ``profile`` block. The syntax for
|
||||
a profile block is ``{% profile as '<name>' %}<jinja code>{% endprofile %}``,
|
||||
where ``<name>`` can be any string. The ``<name>`` token will appear in the
|
||||
log at the ``profile`` level along with the render time of the block.
|
||||
|
@ -2626,15 +2627,15 @@ For ``import_*`` blocks, the ``profile`` log statement has the following form:
|
|||
[...]
|
||||
|
||||
Python Methods
|
||||
====================
|
||||
==============
|
||||
|
||||
A powerful feature of jinja that is only hinted at in the official jinja
|
||||
documentation is that you can use the native python methods of the
|
||||
variable type. Here is the python documentation for `string methods`_.
|
||||
A powerful feature of Jinja that is only hinted at in the official Jinja
|
||||
documentation is that you can use the native Python methods of the
|
||||
variable type. Here is the Python documentation for `string methods`_.
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set hostname,domain = grains.id.partition('.')[::2] %}{{ hostname }}
|
||||
{% set hostname, domain = grains.id.partition('.')[::2] %}{{ hostname }}
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
|
@ -2681,7 +2682,7 @@ module, say ``my_filters`` and use as:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ salt.my_filters.my_jinja_filter(my_variable) }}
|
||||
{{ salt['my_filters.my_jinja_filter'](my_variable) }}
|
||||
|
||||
The greatest benefit is that you are able to access thousands of existing functions, e.g.:
|
||||
|
||||
|
@ -2689,16 +2690,16 @@ The greatest benefit is that you are able to access thousands of existing functi
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ salt.dnsutil.AAAA('www.google.com') }}
|
||||
{{ salt['dnsutil.AAAA']('www.google.com') }}
|
||||
|
||||
- retrieve a specific field value from a :mod:`Redis <salt.modules.modredis>` hash:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ salt.redis.hget('foo_hash', 'bar_field') }}
|
||||
{{ salt['redis.hget']('foo_hash', 'bar_field') }}
|
||||
|
||||
- get the routes to ``0.0.0.0/0`` using the :mod:`NAPALM route <salt.modules.napalm_route>`:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ salt.route.show('0.0.0.0/0') }}
|
||||
{{ salt['route.show']('0.0.0.0/0') }}
|
||||
|
|
|
@ -394,8 +394,8 @@ For example:
|
|||
.. code-block:: jinja
|
||||
|
||||
# /srv/salt/orchestrate/do_complex_thing.sls
|
||||
{% set tag = salt.pillar.get('event_tag') %}
|
||||
{% set data = salt.pillar.get('event_data') %}
|
||||
{% set tag = salt['pillar.get']('event_tag') %}
|
||||
{% set data = salt['pillar.get']('event_data') %}
|
||||
|
||||
# Pass data from the event to a custom runner function.
|
||||
# The function expects a 'foo' argument.
|
||||
|
|
|
@ -52,7 +52,7 @@ Unfortunately, it can lead to code that looks like the following.
|
|||
{% do storage.update({'server_ip': servers_list[server_index]}) %}
|
||||
{% endif %}
|
||||
|
||||
{% for network, _ in salt.pillar.get('inventory:networks', {}) | dictsort %}
|
||||
{% for network, _ in salt['pillar.get']('inventory:networks', {}) | dictsort %}
|
||||
{% do storage.ipsets.hash_net.foo_networks.append(network) %}
|
||||
{% endfor %}
|
||||
|
||||
|
@ -88,7 +88,7 @@ Let's move that to an execution module.
|
|||
|
||||
{% do storage.update({'server_ip': salt['storage.ip']()}) %}
|
||||
|
||||
{% for network, _ in salt.pillar.get('inventory:networks', {}) | dictsort %}
|
||||
{% for network, _ in salt['pillar.get']('inventory:networks', {}) | dictsort %}
|
||||
{% do storage.ipsets.hash_net.af_networks.append(network) %}
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ def renderer(path=None, string=None, default_renderer="jinja|yaml", **kwargs):
|
|||
.. code-block:: jinja
|
||||
|
||||
#!jinja|yaml
|
||||
{% set apache = salt.grains.filter_by({
|
||||
{% set apache = salt['grains.filter_by']({
|
||||
...normal jinja map file here...
|
||||
}, merge=salt.pillar.get('apache:lookup')) %}
|
||||
{{ apache | yaml() }}
|
||||
|
@ -141,7 +141,7 @@ def renderer(path=None, string=None, default_renderer="jinja|yaml", **kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set apache = salt.slsutil.renderer('map.sls') %}
|
||||
{% set apache = salt['slsutil.renderer']('map.sls') %}
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -211,7 +211,7 @@ def serialize(serializer, obj, **mod_kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set json_string = salt.slsutil.serialize('json',
|
||||
{% set json_string = salt['slsutil.serialize']('json',
|
||||
{'foo': 'Foo!'}) %}
|
||||
"""
|
||||
kwargs = salt.utils.args.clean_kwargs(**mod_kwargs)
|
||||
|
@ -235,7 +235,7 @@ def deserialize(serializer, stream_or_string, **mod_kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set python_object = salt.slsutil.deserialize('json',
|
||||
{% set python_object = salt['slsutil.deserialize']('json',
|
||||
'{"foo": "Foo!"}') %}
|
||||
"""
|
||||
kwargs = salt.utils.args.clean_kwargs(**mod_kwargs)
|
||||
|
|
|
@ -135,7 +135,7 @@ def base64_encodefile(fname):
|
|||
path:
|
||||
to:
|
||||
data: |
|
||||
{{ salt.hashutil.base64_encodefile('/path/to/binary_file') | indent(6) }}
|
||||
{{ salt['hashutil.base64_encodefile']('/path/to/binary_file') | indent(6) }}
|
||||
|
||||
The :py:func:`file.decode <salt.states.file.decode>` state function can be
|
||||
used to decode this data and write it to disk.
|
||||
|
|
|
@ -405,7 +405,7 @@ def search_by(lookup, tgt_type="compound", minion_id=None):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set roles = salt.match.search_by({
|
||||
{% set roles = salt['match.search_by']({
|
||||
'web': ['G@os_family:Debian not nodeX'],
|
||||
'db': ['L@node2,node3 and G@datacenter:west'],
|
||||
'caching': ['node3', 'node4'],
|
||||
|
|
|
@ -301,7 +301,7 @@ def get(tgt, fun, tgt_type="glob", exclude_minion=False):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set minion_ips = salt.saltutil.runner('mine.get',
|
||||
{% set minion_ips = salt['saltutil.runner']('mine.get',
|
||||
tgt='*',
|
||||
fun='network.ip_addrs',
|
||||
tgt_type='glob') %}
|
||||
|
|
|
@ -321,8 +321,8 @@ def version_compare(ver1, oper, ver2, ignore_epoch=False):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{%- set postfix_version = salt.pkg.version('postfix') %}
|
||||
{%- if postfix_version and salt.pkg_resource.version_compare(postfix_version, '>=', '3.3', ignore_epoch=True) %}
|
||||
{%- set postfix_version = salt['pkg.version']('postfix') %}
|
||||
{%- if postfix_version and salt['pkg_resource.version_compare'](postfix_version, '>=', '3.3', ignore_epoch=True) %}
|
||||
{#- do stuff #}
|
||||
{%- endif %}
|
||||
|
||||
|
|
|
@ -126,18 +126,18 @@ def renderer(path=None, string=None, default_renderer="jinja|yaml", **kwargs):
|
|||
.. code-block:: jinja
|
||||
|
||||
#!jinja|yaml
|
||||
{% set apache = salt.grains.filter_by({
|
||||
{% set apache = salt['grains.filter_by']({
|
||||
...normal jinja map file here...
|
||||
}, merge=salt.pillar.get('apache:lookup')) %}
|
||||
}, merge=salt['pillar.get']('apache:lookup')) %}
|
||||
{{ apache | yaml() }}
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
#!py
|
||||
def run():
|
||||
apache = __salt__.grains.filter_by({
|
||||
apache = __salt__['grains.filter_by']({
|
||||
...normal map here but as a python dict...
|
||||
}, merge=__salt__.pillar.get('apache:lookup'))
|
||||
}, merge=__salt__['pillar.get']('apache:lookup'))
|
||||
return apache
|
||||
|
||||
Regardless of which of the above map files is used, it can be accessed from
|
||||
|
@ -146,7 +146,7 @@ def renderer(path=None, string=None, default_renderer="jinja|yaml", **kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set apache = salt.slsutil.renderer('map.sls') %}
|
||||
{% set apache = salt['slsutil.renderer']('map.sls') %}
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -219,7 +219,7 @@ def serialize(serializer, obj, **mod_kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set json_string = salt.slsutil.serialize('json',
|
||||
{% set json_string = salt['slsutil.serialize']('json',
|
||||
{'foo': 'Foo!'}) %}
|
||||
"""
|
||||
kwargs = salt.utils.args.clean_kwargs(**mod_kwargs)
|
||||
|
@ -243,7 +243,7 @@ def deserialize(serializer, stream_or_string, **mod_kwargs):
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set python_object = salt.slsutil.deserialize('json',
|
||||
{% set python_object = salt['slsutil.deserialize']('json',
|
||||
'{"foo": "Foo!"}') %}
|
||||
"""
|
||||
kwargs = salt.utils.args.clean_kwargs(**mod_kwargs)
|
||||
|
|
|
@ -8814,7 +8814,7 @@ def decode(
|
|||
- name: /tmp/new_file
|
||||
- encoding_type: base64
|
||||
- encoded_data: |
|
||||
{{ salt.pillar.get('path:to:data') | indent(8) }}
|
||||
{{ salt['pillar.get']('path:to:data') | indent(8) }}
|
||||
"""
|
||||
ret = {"name": name, "changes": {}, "result": False, "comment": ""}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue