Adding Netbox
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
# CLI Parser Directives
|
||||
|
||||
The `command_parser` module is a module that can be used to parse the results of
|
||||
text strings into Ansible facts. The primary motivation for developing the
|
||||
`command_parser` module is to convert structured ASCII text output (such as
|
||||
the stdout returned from network devices) into JSON data structures suitable to be
|
||||
used as host facts.
|
||||
|
||||
The parser template file format is loosely based on the Ansible playbook directives
|
||||
language. It uses the Ansible directive language to ease the transition from
|
||||
writing playbooks to writing parser templates. However, parser templates developed using this
|
||||
module are not written directly into the playbook, but are a separate file
|
||||
called from playbooks. This is done for a variety of reasons but most notably
|
||||
to keep separation between the parsing logic and playbook execution.
|
||||
|
||||
The `command_parser` works based on a set of directives that perform actions
|
||||
on structured data with the end result being a valid JSON structure that can be
|
||||
returned to the Ansible facts system.
|
||||
|
||||
## Parser language
|
||||
|
||||
The parser template format uses YAML formatting, providing an ordered list of directives
|
||||
to be performed on the content (provided by the module argument). The overall
|
||||
general structure of a directive is as follows:
|
||||
|
||||
```yaml
|
||||
- name: some description name of the task to be performed
|
||||
directive:
|
||||
argument: value
|
||||
argument_option: value
|
||||
argument: value
|
||||
directive_option: value
|
||||
directive_option: value
|
||||
```
|
||||
|
||||
The `command_parser` currently supports the following top-level directives:
|
||||
|
||||
* `pattern_match`
|
||||
* `pattern_group`
|
||||
* `json_template`
|
||||
* `export_facts`
|
||||
|
||||
In addition to the directives, the following common directive options are
|
||||
currently supported:
|
||||
|
||||
* `name`
|
||||
* `block`
|
||||
* `loop`
|
||||
* `loop_control`
|
||||
|
||||
* `loop_var`
|
||||
|
||||
* `when`
|
||||
* `register`
|
||||
* `export`
|
||||
* `export_as`
|
||||
* `extend`
|
||||
|
||||
Any of the directive options are accepted but in some cases, the option may
|
||||
provide no operation. For instance, when using the `export_facts`
|
||||
directive, the options `register`, `export` and `export_as` are all
|
||||
ignored. The module should provide warnings when an option is ignored.
|
||||
|
||||
The following sections provide more details about how to use the parser
|
||||
directives to parse text into JSON structure.
|
||||
|
||||
## Directive Options
|
||||
|
||||
This section provides details on the various options that are available to be
|
||||
configured on any directive.
|
||||
|
||||
### `name`
|
||||
|
||||
All entries in the parser template many contain a `name` directive. The
|
||||
`name` directive can be used to provide an arbitrary description as to the
|
||||
purpose of the parser items. The use of `name` is optional for all
|
||||
directives.
|
||||
|
||||
The default value for `name` is `null`.
|
||||
|
||||
### `register`
|
||||
|
||||
Use the `register` option to register the results of a directive operation
|
||||
temporarily into the variable name you specify
|
||||
so you can retrieve it later in your parser template. You use `register` in
|
||||
a parser template just as you would in an Ansible playbook.
|
||||
|
||||
Variables created with `register` alone are not available outside of the parser context.
|
||||
Any values registered are only available within the scope of the parser activities.
|
||||
If you want to provide values back to the playbook, you must also define the [export](#export) option.
|
||||
|
||||
Typically you will use `register` alone for parsing each individual part of the
|
||||
command output, then amalgamate them into a single variable at the end of the parser template,
|
||||
register that variable and set `export: yes` on it.
|
||||
|
||||
The default value for `register` is `null`.
|
||||
|
||||
<a id="export"></a>
|
||||
|
||||
### `export`
|
||||
|
||||
Use the `export` option to export any value back to the calling task as an
|
||||
Ansible fact. The `export` option accepts a boolean value that defines if
|
||||
the registered fact should be exported to the calling task in the playbook (or
|
||||
role) scope. To export the value, simply set `export` to True.
|
||||
|
||||
Note this option requires the `register` value to be set in some cases and will
|
||||
produce a warning message if the `register` option is not provided.
|
||||
|
||||
The default value for `export` is `False`.
|
||||
|
||||
### `export_as`
|
||||
|
||||
Use the `export_as` option to export a value back to the calling task as an
|
||||
Ansible fact in a specific format. The `export_as` option defines the structure of the exported data.
|
||||
Accepted values for `export_as`:
|
||||
|
||||
* `dict`
|
||||
* `hash`
|
||||
* `object`
|
||||
* `list`
|
||||
* `elements` that defines the structure
|
||||
|
||||
**Note** this option requires the `register` value to be set and `export: True`.
|
||||
Variables can also be used with `export_as`.
|
||||
How to use variable with `export_as` is as follows:
|
||||
|
||||
Variable should be defined in vars or defaults or in playbook.
|
||||
```yaml
|
||||
vars:
|
||||
export_type: "list"
|
||||
```
|
||||
|
||||
Parser file needs to have the variable set to `export_as`.
|
||||
```
|
||||
export_as: "{{ export_type }}"
|
||||
```
|
||||
|
||||
### `extend`
|
||||
|
||||
Use the `extend` option to extend a current fact hierarchy with the new
|
||||
registered fact. This will case the facts to be merged and returned as a
|
||||
single tree. If the fact doesn't previously exist, this will create the entire
|
||||
structure.
|
||||
|
||||
The default value for `extend` is `null`.
|
||||
|
||||
### loop
|
||||
|
||||
Use the `loop` option to loop over a directive in order to process values.
|
||||
With the `loop` option, the parser will iterate over the directive and
|
||||
provide each of the values provided by the loop content to the directive for
|
||||
processing.
|
||||
|
||||
Access to the individual items is the same as it would be for Ansible
|
||||
playbooks. When iterating over a list of items, you can access the individual
|
||||
item using the `{{ item }}` variable. When looping over a hash, you can
|
||||
access `{{ item.key }}` and `{{ item.value }}`.
|
||||
|
||||
### `loop_control`
|
||||
|
||||
Use the `loop_control` option to specify the name of the variable to be
|
||||
used for the loop instead of default loop variable `item`.
|
||||
When looping over a hash, you can access `{{ foo.key }}` and `{{ foo.value }}` where `foo`
|
||||
is `loop_var`.
|
||||
The general structure of `loop_control` is as follows:
|
||||
|
||||
```yaml
|
||||
- name: User defined variable
|
||||
pattern_match:
|
||||
regex: "^(\\S+)"
|
||||
content: "{{ foo }}"
|
||||
loop: "{{ context }}"
|
||||
loop_control:
|
||||
loop_var: foo
|
||||
|
||||
```
|
||||
|
||||
### `when`
|
||||
|
||||
Use the `when` option to place a condition on the directive to
|
||||
decided if it is executed or not. The `when` option operates the same as
|
||||
it would in an Ansible playbook.
|
||||
|
||||
For example, if you only want to perform the match statement
|
||||
when the value of `ansible_network_os` is set to `ios`, you can apply
|
||||
the `when` conditional like this:
|
||||
|
||||
```yaml
|
||||
- name: conditionally matched var
|
||||
pattern_match:
|
||||
regex: "hostname (.+)"
|
||||
when: ansible_network_os == 'ios'
|
||||
```
|
||||
|
||||
## Directives
|
||||
|
||||
The directives perform actions on the content using regular expressions to
|
||||
extract various values. Each directive provides some additional arguments that
|
||||
can be used to perform its operation.
|
||||
|
||||
### `pattern_match`
|
||||
|
||||
Use the `pattern_match` directive to extract one or more values from
|
||||
the structured ASCII text based on regular expressions.
|
||||
|
||||
The following arguments are supported for this directive:
|
||||
|
||||
* `regex`
|
||||
* `content`
|
||||
* `match_all`
|
||||
* `match_greedy`
|
||||
* `match_until` : Sets a ending boundary for `match_greedy`.
|
||||
|
||||
The `regex` argument templates the value given to it so variables and filters can be used.
|
||||
Example :
|
||||
```yaml
|
||||
- name: Use a variable and a filter
|
||||
pattern_match:
|
||||
regex: "{{ inventory_hostname | lower }} (.+)"
|
||||
```
|
||||
|
||||
### `pattern_group`
|
||||
|
||||
Use the `pattern_group` directive to group multiple
|
||||
`pattern_match` results together.
|
||||
|
||||
The following arguments are supported for this directive:
|
||||
|
||||
* `json_template`
|
||||
* `set_vars`
|
||||
* `export_facts`
|
||||
|
||||
### `json_template`
|
||||
|
||||
Use the `json_template` directive to create a JSON data structure based on a
|
||||
template. This directive will allow you to template out a multi-level JSON
|
||||
blob.
|
||||
|
||||
The following arguments are supported for this directive:
|
||||
|
||||
* `template`
|
||||
|
||||
|
||||
**Note**
|
||||
Native jinja2 datatype (eg. 'int', 'float' etc.) rendering is supported with Ansible version >= 2.7
|
||||
and jinja2 library version >= 2.10. To enable native jinja2 config add below configuration in active
|
||||
ansible configuration file.
|
||||
```
|
||||
[defaults]
|
||||
jinja2_native= True
|
||||
```
|
||||
|
||||
Usage example:
|
||||
```yaml
|
||||
- set_fact:
|
||||
count: "1"
|
||||
|
||||
- name: print count
|
||||
debug:
|
||||
msg: "{{ count|int }}"
|
||||
```
|
||||
|
||||
With jinja2_native configuration enabled the output of above example task will have
|
||||
```
|
||||
"msg": 1
|
||||
```
|
||||
|
||||
and with jinja2_native configuration disabled (default) output of above example task will have
|
||||
```
|
||||
"msg": "1"
|
||||
```
|
||||
|
||||
### `set_vars`
|
||||
|
||||
Use the `set_vars` directive to set variables to the values like key / value pairs
|
||||
and return a dictionary.
|
||||
|
||||
### `export_facts`
|
||||
|
||||
Use the `export_facts` directive to take an arbitrary set of key / value pairs
|
||||
and expose (return) them back to the playbook global namespace. Any key /
|
||||
value pairs that are provided in this directive become available on the host.
|
||||
@@ -0,0 +1,276 @@
|
||||
# CLI Template Directives
|
||||
|
||||
**Note** `network_template` lookup plugin is deprecated in v2.7.3 and will be removed
|
||||
in version v2.7.7 i.e, four releases from the deprecation version.
|
||||
|
||||
The `network_template` module supports a number of keyword based objectives that
|
||||
handle how to process the template. Templates are broken up into a series
|
||||
of blocks that process lines. Blocks are logical groups that have a common
|
||||
set of properties in common.
|
||||
|
||||
Blocks can also include other template files and are processed in the same
|
||||
manner as lines. See includes below for a description on how to use the
|
||||
include directive.
|
||||
|
||||
The template module works by processing the lines directives in sequential
|
||||
order. The module will attempt to template each line in the lines directive
|
||||
and, if successful, add the line to the final output. Values used for
|
||||
variable substitution come from the host facts. If the line could not
|
||||
be successfully templated, the line is skipped and a warning message is
|
||||
displayed that the line could not be templated.
|
||||
|
||||
There are additional directives that can be combined to support looping over
|
||||
lists and hashes as well as applying conditional statements to blocks, lines
|
||||
and includes.
|
||||
|
||||
## `name`
|
||||
|
||||
Entries in the template may contain a `name` field. The `name` field
|
||||
is used to provide a description of the entry. It is also used to provide
|
||||
feedback when processing the template to indicate when an entry is
|
||||
skipped or fails.
|
||||
|
||||
## `lines`
|
||||
|
||||
The `lines` directive provides an ordered list of statements to attempt
|
||||
to template. Each entry in the `lines` directive will be evaluated for
|
||||
variable substitution. If the entry can be successfully templated, then the
|
||||
output will be added to the final set of entries. If the entry cannot be
|
||||
successfully templated, then the entry is ignored (skipped) and a warning
|
||||
message is provided. If the entry in the `lines` directive contains
|
||||
only static text (no variables), then the line will always be processed.
|
||||
|
||||
The `lines` directive also supports standard Jinja2 filters as well as any
|
||||
Ansible specific Jinja2 filters. For example, lets assume we want to add a
|
||||
default value if a more specific value was not assigned by a fact.
|
||||
|
||||
```yaml
|
||||
- name: render the system hostname
|
||||
lines:
|
||||
- "hostname {{ hostname | default(inventory_hostname_short }}"
|
||||
```
|
||||
|
||||
## `block`
|
||||
|
||||
A group of `lines` directives can be combined into a `block`
|
||||
directive. These `block` directives are used to apply a common set of
|
||||
values to one or more `lines` or `includes` entries.
|
||||
|
||||
For instance, a `block` directive that contains one or more `lines`
|
||||
entries could be use the same set of `loop` values or have a
|
||||
common `when` conditional statement applied to them.
|
||||
|
||||
## `include`
|
||||
|
||||
Sometimes it is advantageous to break up templates into separate files and
|
||||
combine them. The `include` directive will instruct the current template
|
||||
to load another template file and process it.
|
||||
|
||||
The `include` directive also supports variable substitution for the
|
||||
provided file name and can be processed with the `loop` and `when`
|
||||
directives.
|
||||
|
||||
## `when`
|
||||
|
||||
The `when` directive allows for conditional statements to be applied to
|
||||
a set of `lines`, a `block` and/or the `include` directive. The
|
||||
`when` statement is evaluated prior to processing the statements and if
|
||||
the condition is true, the statements will attempt to be templated. If the
|
||||
statement is false, the statements are skipped and a message returned.
|
||||
|
||||
## `loop`
|
||||
|
||||
Depending on the input facts, sometimes it is necessary to iterate over a
|
||||
set of statements. The `loop` directive allows the same set of statements
|
||||
to be processed in such a manner. The `loop` directive takes, as input,
|
||||
the name of a fact that is either a list or a hash and iterates over the
|
||||
statements for each entry.
|
||||
|
||||
When the provided fact is a list of items, the value will be assigned to a
|
||||
variable called `item` and can be referenced by the statements.
|
||||
|
||||
When the provided fact is a hash of items, the hash key will be assigned to
|
||||
the `item.key` variable and the hash value will be assigned to the
|
||||
`item.value` variable. Both can then be referenced by the statements.
|
||||
|
||||
## `loop_control`
|
||||
|
||||
The `loop_control` directive allows the template to configure aspects
|
||||
related to how loops are process. This directive provides a set of suboptions
|
||||
to configure how loops are processed.
|
||||
|
||||
### `loop_var`
|
||||
|
||||
The `loop_var` directive allows the template to override the default
|
||||
variable name `item`. This is useful when handling nested loops such
|
||||
that both inner and outer loops values can be accessed.
|
||||
|
||||
When setting the `loop_var` to some string, the string will replace
|
||||
`item` as the variable name used to access the values.
|
||||
|
||||
For example, lets assume instead of using item, we want to use a different
|
||||
variable name such as entry:
|
||||
|
||||
```yaml
|
||||
- name: render entries
|
||||
lines:
|
||||
- "hostname {{ entry.hostname }}"
|
||||
- "domain-name {{ entry.domain_name }}"
|
||||
loop: "{{ system }}"
|
||||
loop_control:
|
||||
loop_var: entry
|
||||
```
|
||||
|
||||
## `join`
|
||||
|
||||
When building template statements that include optional values for
|
||||
configuration, the `join` directive can be useful. The `join`
|
||||
directive instructs the template to combine the templated lines together
|
||||
into a single string to insert into the configuration.
|
||||
|
||||
For example, lets assume there is a need to add the following statement to
|
||||
the configuration:
|
||||
|
||||
```
|
||||
ip domain-name ansible.com vrf management
|
||||
ip domain-name redhat.com
|
||||
```
|
||||
|
||||
To support templating the above lines, the facts might include the domain-name
|
||||
and the vrf name values. Here is the example facts:
|
||||
|
||||
```yaml
|
||||
---
|
||||
system:
|
||||
- domain_name: ansible.com
|
||||
vrf: management
|
||||
- domain_name redhat.com
|
||||
```
|
||||
|
||||
And the template statement would be the following:
|
||||
|
||||
```yaml
|
||||
- name: render domain-name
|
||||
lines:
|
||||
- "ip domain-name {{ item.domain_name }}"
|
||||
- "vrf {{ item.vrf }}"
|
||||
loop: "{{ system }}"
|
||||
join: yes
|
||||
```
|
||||
|
||||
When this entry is processed, the first iteration will successfully template
|
||||
both lines and add `ip domain-name ansible.com vrf management` to the
|
||||
output.
|
||||
|
||||
When the second entry is processed, the first line will be successfully
|
||||
templated but since there is no management key, the second line will return a
|
||||
null value. The final line added to the configuration will be ` ip
|
||||
domain-name redhat.com`.
|
||||
|
||||
If the `join` directive had been omitted, then the final set of
|
||||
configuration statements would be as follows:
|
||||
|
||||
```
|
||||
ip domain-name ansible.com
|
||||
vrf management
|
||||
ip domain-name redhat.com
|
||||
```
|
||||
|
||||
## `join_delimiter`
|
||||
|
||||
When the `join` delimiter is used, the templated values are combined into a
|
||||
single string that is added to the final output. The lines are joined using a
|
||||
space. The delimiting character used when processing the `join` can be
|
||||
modified using `join_delimiter` directive.
|
||||
|
||||
Here is an example of using the this directive. Take the following entry:
|
||||
|
||||
```yaml
|
||||
- name: render domain-name
|
||||
lines:
|
||||
- "ip domain-name {{ item.domain_name }}"
|
||||
- "vrf {{ item.vrf }}"
|
||||
loop: "{{ system }}"
|
||||
join: yes
|
||||
join_delimiter: ,
|
||||
```
|
||||
|
||||
When the preceding statements are processed, the final output would be
|
||||
(assuming all variables are provided):
|
||||
|
||||
```
|
||||
ip domain-name ansible.com,vrf management
|
||||
ip domain-name redhat.com
|
||||
```
|
||||
|
||||
## `indent`
|
||||
|
||||
The `indent` directive is used to add one or more leading spaces to the
|
||||
final templated statement. It can be used to recreated a structured
|
||||
configuration file.
|
||||
|
||||
Take the following template entry as an example:
|
||||
|
||||
```yaml
|
||||
- name: render the interface context
|
||||
lines: "interface Ethernet0/1"
|
||||
|
||||
- name: render the interface configuration
|
||||
lines:
|
||||
- "ip address 192.168.10.1/24"
|
||||
- "no shutdown"
|
||||
- "description this is an example"
|
||||
indent: 3
|
||||
|
||||
- name: render the interface context
|
||||
lines: "!"
|
||||
```
|
||||
|
||||
Then the statements above are processed, the output will look like the
|
||||
following:
|
||||
|
||||
```
|
||||
interface Ethernet0/1
|
||||
ip address 192.168.10.1/24
|
||||
no shutdown
|
||||
description this is an example
|
||||
!
|
||||
```
|
||||
|
||||
## `required`
|
||||
|
||||
The `required` directive specifies that all of the statements must be
|
||||
templated otherwise a failure is generated. Essentially it is a way to
|
||||
make certain that the variables are defined.
|
||||
|
||||
For example, take the following:
|
||||
|
||||
```yaml
|
||||
- name: render router ospf context
|
||||
lines:
|
||||
- "router ospf {{ process_id }}"
|
||||
required: yes
|
||||
```
|
||||
|
||||
When the above is processed, if the variable `process_id` is not present,
|
||||
then the statement cannot be templated. Since the `required` directive
|
||||
is set to true, the statement will cause the template to generate a failure
|
||||
message.
|
||||
|
||||
## `missing_key`
|
||||
|
||||
By default, when statements are processed and a variable is undefined, the
|
||||
module will simply display a warning message to the screen. In some cases, it
|
||||
is desired to either suppress warning messages on a missing key or to force the
|
||||
module to fail on a missing key.
|
||||
|
||||
To change the default behaviour, use the `missing_key` directive. This
|
||||
directive accepts one of three choices:
|
||||
|
||||
* `ignore`
|
||||
* `warn` (default)
|
||||
* `fail`
|
||||
|
||||
The value of this directive will instruct the template how to handle any
|
||||
condition where the desired variable is undefined.
|
||||
|
||||
Reference in New Issue
Block a user