<commit_before>Networking Support
==================

.. contents:: Topics

.. _working_with_networking_devices:

Working with Networking Devices
````````````````````````

Starting with Ansible version 2.1, you can now use the familiar Ansible models of playbook authoring and module development to manage heterogenous networking devices. 

Ansible currently supports the following networking devices:

* Arista EOS 
* Cisco NXOS 
* Cisco IOS 
* Cisco IOSXR 
* Cumulus Linux 
* Juniper JUNOS 
* OpenSwitch

.. _networking_prerequisites:

Network Automation Prerequisites
````````````````````````

TBD


.. _networking_installation:

Network Automation Installation
````````````````````````

TBD

.. _understanding_provider_arguments:

Connecting to Networking Devices
````````````````````````

All core networking modules implement a *provider* argument, which is a collection of arguments used to define the characteristics of how to connect to the device.  This section will assist in understanding how the provider argument is used.


Each core network module supports an underlying operating system and transport.  The operating system is a one-to-one match with the module, and the transport maintains a one-to-many relationship to the operating system as appropriate. Some network operating systems only have a single transport option.


Each core network module supports some basic arguments for configuring the transport:

* host - defines the hostname or IP address of the remote host
* port - defines the port to connect to
* username - defines the username to use to authenticate the connection
* password - defines the password to use to authenticate the connection
* transport - defines the type of connection transport to build
* authorize - enables privilege escalation for devices that require it
* auth_pass  - defines the password, if needed, for privilege escalation

Individual modules can set defaults for these arguments to common values that match device default configuration settings.  For instance, the default value for transport is universally 'cli'.  Some modules support other values such as EOS (eapi) and NXOS (nxapi), while some only support 'cli'.  All arguments are fully documented for each module.

By allowing individual tasks to set the transport arguments independently, modules that use different transport mechanisms and authentication credentials can be combined as necessary.

One downside to this approach is that every task needs to include the required arguments.  This is where the provider argument comes into play. The provider argument accepts keyword arguments and passes them through to the task to assign connection and authentication parameters.

The following two config modules are essentially identical (using nxos_config) as an example but it applies to all core networking modules::


    ---
    nxos_config:
       src: config.j2
       host: "{{ inventory_hostname }}"
       username: "{{ ansible_ssh_user }}"
       password: "{{ <PASSWORD> }}"
       transport: cli

    ---
    vars:
       cli:
       host: "{{ inventory_hostname }}"
       username: "{{ ansible_ssh_user }}" 
       password: "{{ <PASSWORD> }} "
       transport: cli
   

    nxos_config:
       src: config.j2
       provider: "{{ cli }}"
   
Given the above two examples that are equivalent, the arguments can also be used to establish precedence and defaults.  Consider the following example::

    ---
    vars:
        cli:
        host: "{{ inventory_hostname }}"
        username: operator
        password: <PASSWORD>
        transport: cli
   
    tasks:
    - nxos_config:
       src: config.j2
       provider: "{{ cli }}"
       username: admin
       password: <PASSWORD>


In this example, the values of admin for username and admin for password will override the values of operator in cli['username'] and secret in cli['password'])

This is true for all values in the provider including transport.  So you could have a singular task that is now supported over CLI or NXAPI (assuming the configuration is value). ::


    ---
    vars:
        cli:
        host: "{{ inventory_hostname }}"
        username: operator
        password: <PASSWORD>
        transport: cli
   
    tasks:
      - nxos_config:
          src: config.j2
          provider: "{{ cli }}"
          transport: nxapi

If all values are provided via the provider argument, the rules for requirements are still honored for the module.   For instance, take the following scenario::

    ---
    vars:
      conn:
      password: <PASSWORD>
      transport: cli
   
    tasks:
    - nxos_config:
      src: config.j2
      provider: "{{ conn }}"

Running the above task will cause an error to be generated with a message that required parameters are missing.  ::

    "msg": "missing required arguments: username,host"

Overall, this provides a very granular level of control over how credentials are used with modules.  It provides the playbook designer maximum control for changing context during a playbook run as needed.  

.. _networking_module_types:

Understanding Networking Module Types
````````````````````````

TBD

.. _networking_environment_variables:

Networking Environment Variables
````````````````````````

The following environment variables are available to Ansible networking modules:

username ANSIBLE_NET_USERNAME
password <PASSWORD>
ssh_keyfile ANSIBLE_NET_SSH_KEYFILE
authorize ANSIBLE_NET_AUTHORIZE
auth_pass ANSIBLE_NET_AUTH_PASS

Variables are evaulated in the following order, list from lowest to highest priority:

* Default
* Environment
* Provider
* Task arguments


.. _networking_module_index:

Available Networking Modules
````````````````````````

Most standard Ansible modules are designed to work with Linux/Unix or Windows machines and will not work with networking devices. Some modules (including "slurp", "raw", and "setup") are platform-agnostic and will work with networking devices.

To see what modules are available for networking devices, please browse the `"networking" section of the Ansible module index <http://docs.ansible.com/ansible/list_of_network_modules.html#>`_.

.. _networking_module_conditionals:

Conditionals in Networking Modules
````````````````````````

Ansible allows you to use conditionals to control the flow of your playbooks. Ansible networking command modules use unique conditional statements.

* eq - Equal
* neq - Not equal
* gt - Greater than
* ge - Greater than or equal
* lt - Less than
* le - Less than or equal
* contains - Object contains specified item




<commit_msg>Rearranged structure; added install instructions; added info to the conditionals section.<commit_after>Networking Support
==================

.. contents:: Topics

.. _working_with_networking_devices:

Working with Networking Devices
````````````````````````

Starting with Ansible version 2.1, you can now use the familiar Ansible models of playbook authoring and module development to manage heterogenous networking devices. 

Ansible currently supports the following networking devices:

* Arista EOS 
* Cisco NXOS 
* Cisco IOS 
* Cisco IOSXR 
* Cumulus Linux 
* Juniper JUNOS 
* OpenSwitch

.. _networking_installation:

Network Automation Installation
````````````````````````

Download the latest Ansible network release `here <http://releases.ansible.com/ansible-network/latest/>`_.

Playbooks for testing Ansible core network modules can be found `here <https://github.com/ansible/test-network-modules>`_.


.. _networking_module_index:

Available Networking Modules
````````````````````````

Most standard Ansible modules are designed to work with Linux/Unix or Windows machines and will not work with networking devices. Some modules (including "slurp", "raw", and "setup") are platform-agnostic and will work with networking devices.

To see what modules are available for networking devices, please browse the `"networking" section of the Ansible module index <http://docs.ansible.com/ansible/list_of_network_modules.html#>`_.

.. _understanding_provider_arguments:

Connecting to Networking Devices
````````````````````````

All core networking modules implement a *provider* argument, which is a collection of arguments used to define the characteristics of how to connect to the device.  This section will assist in understanding how the provider argument is used.


Each core network module supports an underlying operating system and transport.  The operating system is a one-to-one match with the module, and the transport maintains a one-to-many relationship to the operating system as appropriate. Some network operating systems only have a single transport option.


Each core network module supports some basic arguments for configuring the transport:

* host - defines the hostname or IP address of the remote host
* port - defines the port to connect to
* username - defines the username to use to authenticate the connection
* password - defines the password to use to authenticate the connection
* transport - defines the type of connection transport to build
* authorize - enables privilege escalation for devices that require it
* auth_pass  - defines the password, if needed, for privilege escalation

Individual modules can set defaults for these arguments to common values that match device default configuration settings.  For instance, the default value for transport is universally 'cli'.  Some modules support other values such as EOS (eapi) and NXOS (nxapi), while some only support 'cli'.  All arguments are fully documented for each module.

By allowing individual tasks to set the transport arguments independently, modules that use different transport mechanisms and authentication credentials can be combined as necessary.

One downside to this approach is that every task needs to include the required arguments.  This is where the provider argument comes into play. The provider argument accepts keyword arguments and passes them through to the task to assign connection and authentication parameters.

The following two config modules are essentially identical (using nxos_config) as an example but it applies to all core networking modules::


    ---
    nxos_config:
       src: config.j2
       host: "{{ inventory_hostname }}"
       username: "{{ ansible_ssh_user }}"
       password: "{{ <PASSWORD> }}"
       transport: cli

    ---
    vars:
       cli:
       host: "{{ inventory_hostname }}"
       username: "{{ ansible_ssh_user }}" 
       password: "{{ <PASSWORD> }} "
       transport: cli
   

    nxos_config:
       src: config.j2
       provider: "{{ cli }}"
   
Given the above two examples that are equivalent, the arguments can also be used to establish precedence and defaults.  Consider the following example::

    ---
    vars:
        cli:
        host: "{{ inventory_hostname }}"
        username: operator
        password: <PASSWORD>
        transport: cli
   
    tasks:
    - nxos_config:
       src: config.j2
       provider: "{{ cli }}"
       username: admin
       password: <PASSWORD>


In this example, the values of admin for username and admin for password will override the values of operator in cli['username'] and secret in cli['password'])

This is true for all values in the provider including transport.  So you could have a singular task that is now supported over CLI or NXAPI (assuming the configuration is value). ::


    ---
    vars:
        cli:
        host: "{{ inventory_hostname }}"
        username: operator
        password: <PASSWORD>
        transport: cli
   
    tasks:
      - nxos_config:
          src: config.j2
          provider: "{{ cli }}"
          transport: nxapi

If all values are provided via the provider argument, the rules for requirements are still honored for the module.   For instance, take the following scenario::

    ---
    vars:
      conn:
      password: <PASSWORD>_pass
      transport: cli
   
    tasks:
    - nxos_config:
      src: config.j2
      provider: "{{ conn }}"

Running the above task will cause an error to be generated with a message that required parameters are missing.  ::

    "msg": "missing required arguments: username,host"

Overall, this provides a very granular level of control over how credentials are used with modules.  It provides the playbook designer maximum control for changing context during a playbook run as needed.  

.. _networking_module_types:

Understanding Networking Module Types
````````````````````````

TBD

.. _networking_environment_variables:

Networking Environment Variables
````````````````````````

The following environment variables are available to Ansible networking modules:

username ANSIBLE_NET_USERNAME
password <PASSWORD>
ssh_keyfile ANSIBLE_NET_SSH_KEYFILE
authorize ANSIBLE_NET_AUTHORIZE
auth_pass <PASSWORD>NET_AUTH_PASS

Variables are evaulated in the following order, listed from lowest to highest priority:

* Default
* Environment
* Provider
* Task arguments

.. _networking_module_conditionals:

Conditionals in Networking Modules
````````````````````````

Ansible allows you to use conditionals to control the flow of your playbooks. Ansible networking command modules use the following unique conditional statements.

* eq - Equal
* neq - Not equal
* gt - Greater than
* ge - Greater than or equal
* lt - Less than
* le - Less than or equal
* contains - Object contains specified item


Conditionals used with networking command modules only evaluate results, not stdout. For example, the following example won't work::

    ---
    waitfor: "stdout_lines[0][6] contains '100.00'"

To evaluate this properly, you'll need to compare against results. For example::

    ---
    result[0] contains '100.00'



{'fraction_non_alphanumeric': 0.08332724749872197, 'fraction_numerical': 0.001971810414080187, 'mean_word_length': 3.7780879274249823, 'pattern_counts': {'":': 2, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '499826', 'n_tokens_mistral': 3595, 'n_tokens_neox': 3344, 'n_words': 1587}