salt.modules.napalm_formula#
NAPALM Formula helpers#
New in version 2019.2.0.
This is an Execution Module providing helpers for various NAPALM formulas, e.g., napalm-interfaces-formula, napalm-bgp-formula, napalm-ntp-formula etc., meant to provide various helper functions to make the templates more readable.
- salt.modules.napalm_formula.container_path(model, key=None, container=None, delim=':')#
Return the list of all the possible paths in a container, down to the
configcontainer. This function can be used to verify that themodelis a Python object correctly structured and respecting the OpenConfig hierarchy.- model
The OpenConfig-structured object to inspect.
- delim:
: The key delimiter. In particular cases, it is indicated to use
//as:might be already used in various cases, e.g., IPv6 addresses, interface name (e.g., Juniper QFX series), etc.
CLI Example:
salt '*' napalm_formula.container_path "{'interfaces': {'interface': {'Ethernet1': {'config': {'name': 'Ethernet1'}}}}}"
The example above would return a list with the following element:
interfaces:interface:Ethernet1:configwhich is the only possible path in that hierarchy.Other output examples:
- interfaces:interface:Ethernet1:config - interfaces:interface:Ethernet1:subinterfaces:subinterface:0:config - interfaces:interface:Ethernet2:config
- salt.modules.napalm_formula.defaults(model, defaults_, delim='//', flipped_merge=False)#
Apply the defaults to a Python dictionary having the structure as described in the OpenConfig standards.
- model
The OpenConfig model to apply the defaults to.
- defaults
The dictionary of defaults. This argument must equally be structured with respect to the OpenConfig standards.
For ease of use, the keys of these support glob matching, therefore we don't have to provide the defaults for each entity but only for the entity type. See an example below.
- delim:
// The key delimiter to use. Generally,
//should cover all the possible cases, and you don't need to override this value.- flipped_merge:
False Whether should merge the model into the defaults, or the defaults into the model. Default:
False(merge the model into the defaults, i.e., any defaults would be overridden by the values from themodel).
CLI Example:
salt '*' napalm_formula.defaults "{'interfaces': {'interface': {'Ethernet1': {'config': {'name': 'Ethernet1'}}}}}" "{'interfaces': {'interface': {'*': {'config': {'enabled': True}}}}}"
As one can notice in the example above, the
*corresponds to the interface name, therefore, the defaults will be applied on all the interfaces.
- salt.modules.napalm_formula.dictupdate(dest, upd, recursive_update=True, merge_lists=False)#
Recursive version of the default dict.update
Merges upd recursively into dest
If recursive_update=False, will use the classic dict.update, or fall back on a manual merge (helpful for non-dict types like
FunctionWrapper).If
merge_lists=True, will aggregate list object types instead of replace. The list inupdis added to the list indest, so the resulting list isdest[key] + upd[key]. This behaviour is only activated whenrecursive_update=True. By defaultmerge_lists=False.
- salt.modules.napalm_formula.render_field(dictionary, field, prepend=None, append=None, quotes=False, **opts)#
Render a field found under the
fieldlevel of the hierarchy in thedictionaryobject. This is useful to render a field in a Jinja template without worrying that the hierarchy might not exist. For example if we do the following in Jinja:{{ interfaces.interface.Ethernet5.config.description }}for the following object:{'interfaces': {'interface': {'Ethernet1': {'config': {'enabled': True}}}}}it would error, as theEthernet5key does not exist. With this helper, we can skip this and avoid existence checks. This must be however used with care.- dictionary
The dictionary to traverse.
- field
The key name or part to traverse in the
dictionary.- prepend:
None The text to prepend in front of the text. Usually, we need to have the name of the field too when generating the configuration.
- append:
None Text to append at the end.
- quotes:
False Whether should wrap the text around quotes.
CLI Example:
salt '*' napalm_formula.render_field "{'enabled': True}" enabled # This would return the value of the ``enabled`` leaf key salt '*' napalm_formula.render_field "{'enabled': True}" description # This would not error
Jinja usage example:
{%- set config = {'enabled': True, 'description': 'Interface description'} %} {{ salt.napalm_formula.render_field(config, 'description', quotes=True) }}
The example above would be rendered on Arista / Cisco as:
description "Interface description"
While on Junos (the semicolon is important to be added, otherwise the configuration won't be accepted by Junos):
description "Interface description";
- salt.modules.napalm_formula.render_fields(dictionary, *fields, **opts)#
This function works similarly to
render_fieldbut for a list of fields from the same dictionary, rendering, indenting and distributing them on separate lines.- dictionary
The dictionary to traverse.
- fields
A list of field names or paths in the dictionary.
- indent:
0 The indentation to use, prepended to the rendered field.
- separator:
\n The separator to use between fields.
CLI Example:
salt '*' napalm_formula.render_fields "{'mtu': 68, 'description': 'Interface description'}" mtu description
Jinja usage example:
{%- set config={'mtu': 68, 'description': 'Interface description'} %} {{ salt.napalm_formula.render_fields(config, 'mtu', 'description', quotes=True) }}
The Jinja example above would generate the following configuration:
mtu "68" description "Interface description"
- salt.modules.napalm_formula.setval(key, val, dict_=None, delim=':')#
Set a value under the dictionary hierarchy identified under the key. The target 'foo/bar/baz' returns the dictionary hierarchy {'foo': {'bar': {'baz': {}}}}.
Note
Currently this doesn't work with integers, i.e. cannot build lists dynamically.
CLI Example:
salt '*' formula.setval foo:baz:bar True
- salt.modules.napalm_formula.traverse(data, key, default=None, delimiter=':')#
Traverse a dict or list using a colon-delimited (or otherwise delimited, using the
delimiterparam) target string. The targetfoo:bar:0will returndata['foo']['bar'][0]if this value exists, and will otherwise return the dict in the default argument. Function will automatically determine the target type. The targetfoo:bar:0will return data['foo']['bar'][0] if data like{'foo':{'bar':['baz']}}, if data like{'foo':{'bar':{'0':'baz'}}}thenreturn data['foo']['bar']['0']CLI Example:
salt '*' napalm_formula.traverse "{'foo': {'bar': {'baz': True}}}" foo:baz:bar