diff options
author | Anil Kumar Muraleedharan <amuraleedhar@lenovo.com> | 2018-08-30 01:32:06 +0530 |
---|---|---|
committer | Nathaniel Case <this.is@nathanielca.se> | 2018-08-29 16:02:06 -0400 |
commit | 4b2495a54ce699e17b6d5b5f4495c818247bc770 (patch) | |
tree | 42d6b1c5e8f5126a72741e2b287e5500b670ee74 | |
parent | 305ae5442a44dc0bebcfacfcb20d1ca1e40c74d2 (diff) | |
download | ansible-4b2495a54ce699e17b6d5b5f4495c818247bc770.tar.gz |
Lenovo integration test roles 1 (#44559)
* Integration test suit for cnos_facts, cnos_config, cnos_command, enos_facts, enos_config and enos_command.
* Update all_facts.yaml
* Update invalid_subset.yaml
* Update not_hardware.yaml
* Adding cnos_backup, cnos_bgp, cnos_conditional_command, cnos_condtional_template, cnos_ethernet, cnos_portchannel, cnos_rollback.
* Update README.md
* Adding the sample roles for cnos_save, cnos_show_run, cnos_template, cnos_vlag and cnos_vlan
131 files changed, 4048 insertions, 0 deletions
diff --git a/test/integration/targets/cnos_backup/README.md b/test/integration/targets/cnos_backup/README.md new file mode 100644 index 0000000000..d2f161f4ed --- /dev/null +++ b/test/integration/targets/cnos_backup/README.md @@ -0,0 +1,115 @@ +# Ansible Role: cnos_backup_sample - Saving the switch configuration to a remote server +--- +<add role description below> + +This role is an example of using the *cnos_backup.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with switch configurations. It provides a way to back up the running or startup configurations of a switch to a remote server. This is achieved by periodically saving a copy of the startup or running configuration of the network device to a remote server using FTP, SFTP, TFTP, or SCP. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_backup](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_backup.html&cp=0_3_1_0_4_4). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`configType` | Specifies the type of configuration to be backed up to the remote server (**running-config** - running configuration, **startup-config** - startup configuration) +`protocol` | Specifies the protocol used by the network device to interact with the remote server to where to upload the backup configuration (**ftp** - FTP, **sftp** - SFTP, **tftp** - TFTP, **scp** - SCP) +`serverip` | Specifies the IP Address of the remote server to where the configuration will be backed up +`rcpath` | Specifies the full file path where the configuration file will be copied on the remote server (when backing up the switch configuration through TFTP, an empty directory needs to be created, otherwise the operation will fail) +`serverusername` | Configures the username for the server relating to the protocol used +`serverpassword` | Configures the password for the server relating to the protocol used + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_backup.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_backup_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_backup_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_backup_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` +- name: Module to back up configuration + hosts: cnos_backup_sample + gather_facts: no + connection: local + roles: + - cnos_backup_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_backup/aliases b/test/integration/targets/cnos_backup/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_backup/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_backup/cnos_backup_sample_hosts b/test/integration/targets/cnos_backup/cnos_backup_sample_hosts new file mode 100644 index 0000000000..9c2692eace --- /dev/null +++ b/test/integration/targets/cnos_backup/cnos_backup_sample_hosts @@ -0,0 +1,17 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_backup_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_backup_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos rcpath=/root/cnos_config/G8272-running-config.txt + +#Use this in case its TFTP as tftpboot folder is the starting point for tftp +#10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos rcpath=/anil/G8272-running-config.txt diff --git a/test/integration/targets/cnos_backup/tasks/main.yml b/test/integration/targets/cnos_backup/tasks/main.yml new file mode 100644 index 0000000000..fe2b9a88e6 --- /dev/null +++ b/test/integration/targets/cnos_backup/tasks/main.yml @@ -0,0 +1,25 @@ +# This contain sample config back up tasks +--- + +- name: Test Startup Config Backup + cnos_backup: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_backup_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' serverusername='{{item.serverusername}}' serverpassword='{{item.serverpassword}}' + with_items: "{{test_config_data2}}" + +- name: Test Running Config Backup + cnos_backup: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_backup_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' serverusername='{{item.serverusername}}' serverpassword='{{item.serverpassword}}' + with_items: "{{test_config_data1}}" + +#Root folder will be different for SFTP/SCP and TFTP +#The following task is commented. +#Before trying this, please change in /etc/ansible/hosts file +#and backup the config file with reference to your tftp-root folder + +#- name: Test Running Config Backup -TFTP +# cnos_backup: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_backup_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' +# with_items: "{{test_config_data3}}" + +#- name: Test Startup Config Backup - TFTP +# cnos_backup: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_backup_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' +# with_items: "{{test_config_data4}}" + +# Completed file diff --git a/test/integration/targets/cnos_backup/vars/main.yml b/test/integration/targets/cnos_backup/vars/main.yml new file mode 100644 index 0000000000..478ec145c4 --- /dev/null +++ b/test/integration/targets/cnos_backup/vars/main.yml @@ -0,0 +1,12 @@ +--- +test_config_data1: + - {configType: "running-config", protocol: "sftp", serverip: "10.241.106.118", serverusername: "root", serverpassword: "root123", rcpath: "/root/cnos_config/"} + +test_config_data2: + - {configType: "startup-config", protocol: "sftp", serverip: "10.241.106.118", serverusername: "root", serverpassword: "root123", rcpath: "/root/cnos_config/"} + +test_config_data3: + - {configType: running-config, protocol: "tftp", serverip: "10.241.106.118", rcpath: "/root/cnos_config/"} + +test_config_data4: + - {configType: startup-config, protocol: "tftp", serverip: "10.241.106.118", rcpath: "/root/cnos_config/"} diff --git a/test/integration/targets/cnos_bgp/README.md b/test/integration/targets/cnos_bgp/README.md new file mode 100644 index 0000000000..678720bed6 --- /dev/null +++ b/test/integration/targets/cnos_bgp/README.md @@ -0,0 +1,119 @@ +# Ansible Role: cnos_bgp_sample - CNOS Switch BGP Configuration +--- +<add role description below> + +This role is an example of using the *cnos_bgp.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with Border Gateway Protocol (BGP) related configurations. The operators used are overloaded to ensure control over switch BGP configurations. This module is invoked using method with *asNumber* as one of its arguments. + +The first level of the BGP configuration allows to set up an AS number, with the following attributes going into various configuration operations under the context of BGP. After passing this level, there are eight BGP arguments that will perform further configurations. They are *bgpArg1*, *bgpArg2*, *bgpArg3*, *bgpArg4*, *bgpArg5*, *bgpArg6*, *bgpArg7*, and *bgpArg8*. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_bgp](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_bgp.html&cp=0_3_1_0_4_16). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`asNum` | Specifies the AS number +`bgpArg1` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **address-family**, **bestpath**, **bgp**, **cluster-id**, **confederation**, **enforce-first-as**, **fast-external-failover**, **graceful-restart**, **graceful-restart-helper**, **log-neighbor-changes**, **maxas-limit**, **neighbor**, **router-id**, **shutdown**, **synchronization**, **timers**, **vrf**. +`bgpArg2` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **ipv4**, **ipv6**, **always-compare-med**, **compare-confed-aspath**, **compare-routerid**, **dont-compare-originator-id**, **tie-break-on-age**, **as-path**, **med**, number of times to prepend the local AS, Route Reflector Cluster ID as a 32 bit quantity or in IP address format, **identifier**, **peers**, delay value, number of autonomous systems in the AS-path attribute, neighbor address, neighbor prefix, manually configured router identifier, keepalive interval. +`bgpArg3` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **aggregate-address**, **client-to-client**, **dampening**, **distance**, **maximum-paths**, **network**, **nexthop**, **redistribute**, **save**, **synchronization**, **ignore**, **multipath-relax**, **confed**, **missing-as-worst**, **non-deterministic**, **remove-recv-med**, **remove-send-med**, set routing domain confederation AS, AS number. +`bgpArg4` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: IP address/prefix length, **route-map**, time after which a penalty is decreased by half, administrative distance to routes outside the AS, **ebgp**, **ibgp**, **synchronization**, IP address, delay value, **direct**, **ospf**, **static**, **memory**. +`bgpArg5` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **as-set**, **summary-only**, name of the route map that controls where BGP route dampening is enabled, value to start reusing a route, administrative distance to routes inside the AS, value for maximum path numbers, **backdoor**, **mask**, **route-map**. +`bgpArg6` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **summary-only**, **as-set**, value to start suppressing a route, administrative distance for local routes, IP subnet address mask, name of the route map. +`bgpArg7` | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: maximum duration to suppress a stable route, **route-map**, **backdoor**. +'bgpArg8' | This is an overloaded BGP variable. Please refer to the [cnos_bgp module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_bgp.html?cp=0_3_1_0_2_13) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: time after which an unreachable route's penalty is decreased by half, **backdoor**. + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_bgp.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_bgp_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_bgp_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_bgp_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` +- name: Module to do BGP configuration + hosts: cnos_bgp_sample + gather_facts: no + connection: local + roles: + - cnos_bgp_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_bgp/aliases b/test/integration/targets/cnos_bgp/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_bgp/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_bgp/cnos_bgp_sample_hosts b/test/integration/targets/cnos_bgp/cnos_bgp_sample_hosts new file mode 100644 index 0000000000..4981b0101b --- /dev/null +++ b/test/integration/targets/cnos_bgp/cnos_bgp_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_bgp_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_bgp_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_bgp/tasks/main.yml b/test/integration/targets/cnos_bgp/tasks/main.yml new file mode 100644 index 0000000000..96af8dbb3e --- /dev/null +++ b/test/integration/targets/cnos_bgp/tasks/main.yml @@ -0,0 +1,78 @@ +## This contain sample BGP execution tasks +--- +- name: Test BGP - neighbor + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' bgpArg4='{{item.bgpArg4}}' bgpArg5='{{item.bgpArg5}}' bgpArg6='{{item.bgpArg6}}' + with_items: "{{test_bgp_data13}}" + +- name: Test BGP - BFD + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' bgpArg4='{{item.bgpArg4}}' + with_items: "{{test_bgp_data19}}" + +- name: Test BGP - address-family - dampening + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' bgpArg4='{{item.bgpArg4}}' bgpArg5='{{item.bgpArg5}}' bgpArg6='{{item.bgpArg6}}' bgpArg7='{{item.bgpArg7}}' bgpArg8='{{item.bgpArg8}}' + with_items: "{{test_bgp_data1}}" + +- name: Test BGP - address-family - network + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' bgpArg4='{{item.bgpArg4}}' bgpArg5='{{item.bgpArg5}}' + with_items: "{{test_bgp_data18}}" + +- name: Test BGP - bestpath - always-compare-med + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data2}}" + +- name: Test BGP - bestpath-compare-confed-aspat + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data3}}" + +- name: Test BGP - bgp + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data4}}" + +- name: Test BGP - cluster-id + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data5}}" + +- name: Test BGP - confederation-identifier + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' + with_items: "{{test_bgp_data6}}" + +- name: Test BGP - enforce-first-as + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' + with_items: "{{test_bgp_data7}}" + +- name: Test BGP - fast-external-failover + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' + with_items: "{{test_bgp_data8}}" + +- name: Test BGP - graceful-restart + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data9}}" + +- name: Test BGP - graceful-restart-helper + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' + with_items: "{{test_bgp_data10}}" + +- name: Test BGP - maxas-limit + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data11}}" + +#- name: Test BGP - neighbor +# cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' +# with_items: "{{test_bgp_data13}}" + +- name: Test BGP - router-id + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' + with_items: "{{test_bgp_data14}}" + +- name: Test BGP - synchronization + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' + with_items: "{{test_bgp_data15}}" + +- name: Test BGP - timers + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' bgpArg2='{{item.bgpArg2}}' bgpArg3='{{item.bgpArg3}}' + with_items: "{{test_bgp_data16}}" + +- name: Test BGP - vrf + cnos_bgp: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_bgp_{{ inventory_hostname }}_output.txt asNum='{{item.asNum}}' bgpArg1='{{item.bgpArg1}}' + with_items: "{{test_bgp_data17}}" +# Completed file diff --git a/test/integration/targets/cnos_bgp/vars/main.yml b/test/integration/targets/cnos_bgp/vars/main.yml new file mode 100644 index 0000000000..ba08d9c0ff --- /dev/null +++ b/test/integration/targets/cnos_bgp/vars/main.yml @@ -0,0 +1,37 @@ +--- +test_bgp_data1: + - {asNum: 33, bgpArg1: "address-family", bgpArg2: "ipv4", bgpArg3: "dampening", bgpArg4: 13, bgpArg5: 233, bgpArg6: 333, bgpArg7: 15, bgpArg8: 33 } +test_bgp_data2: + - {asNum: 33, bgpArg1: "bestpath", bgpArg2: "always-compare-med"} +test_bgp_data3: + - {asNum: 33, bgpArg1: "bestpath", bgpArg2: "compare-confed-aspath"} +test_bgp_data4: + - {asNum: 33, bgpArg1: "bgp", bgpArg2: 33} +test_bgp_data5: + - {asNum: 33, bgpArg1: "cluster-id", bgpArg2: "1.2.3.4"} +test_bgp_data6: + - {asNum: 33, bgpArg1: "confederation", bgpArg2: "identifier", bgpArg3: 333} +test_bgp_data7: + - {asNum: 33, bgpArg1: "enforce-first-as"} +test_bgp_data8: + - {asNum: 33, bgpArg1: "fast-external-failover"} +test_bgp_data9: + - {asNum: 33, bgpArg1: "graceful-restart", bgpArg2: 333} +test_bgp_data10: + - {asNum: 33, bgpArg1: "graceful-restart-helper"} +test_bgp_data11: + - {asNum: 33, bgpArg1: "maxas-limit", bgpArg2: 333} +test_bgp_data13: + - {asNum: 33, bgpArg1: "neighbor", bgpArg2: "10.241.107.40", bgpArg3: 13, bgpArg4: "address-family", bgpArg5: "ipv4", bgpArg6: "next-hop-self" } +test_bgp_data14: + - {asNum: 33, bgpArg1: "router-id", bgpArg2: "1.2.3.4"} +test_bgp_data15: + - {asNum: 33, bgpArg1: "synchronization"} +test_bgp_data16: + - {asNum: 33, bgpArg1: "timers", bgpArg2: 333, bgpArg3: 3333} +test_bgp_data17: + - {asNum: 33, bgpArg1: "vrf"} +test_bgp_data18: + - {asNum: 33, bgpArg1: "address-family", bgpArg2: "ipv4", bgpArg3: "network", bgpArg4: "1.2.3.4/5", bgpArg5: "backdoor"} +test_bgp_data19: + - {asNum: 33, bgpArg1: "neighbor", bgpArg2: "10.241.107.40", bgpArg3: 13, bgpArg4: "bfd"} diff --git a/test/integration/targets/cnos_command/README.md b/test/integration/targets/cnos_command/README.md new file mode 100644 index 0000000000..5195a59d13 --- /dev/null +++ b/test/integration/targets/cnos_command/README.md @@ -0,0 +1,115 @@ +# Ansible Role: cnos_command - Exceutes any CLI command on switch and results are displayed. +--- +<add role description below> + + Sends arbitrary commands to an CNOS node and returns the results + read from the device. The C(cnos_command) module includes an + argument that will cause the module to wait for a specific condition + before returning or timing out if the condition is not met. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.6 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +These are the various options the customer have in executing the cnos_command modules: + +Variable | Description +--- | --- +`commands` | List of commands to send to the remote device over the configured provider. The resulting output from the command is returned. If the I(wait_for) argument is provided, the module is not returned until the condition is satisfied or the number of retires as expired. +`wait_for` | List of conditions to evaluate against the output of the command. The task will wait for each condition to be true before moving forward. If the conditional is not true within the configured number of retries, the task fails. See examples. +`match` | The I(match) argument is used in conjunction with the I(wait_for) argument to specify the match policy. Valid values are C(all) or C(any). If the value is set to C(all) then all conditionals in the wait_for must be satisfied. If the value is set to C(any) then only one of the values must be satisfied. +`retries` | Specifies the number of retries a command should by tried before it is considered failed. The command is run on the target device every retry and evaluated against the I(wait_for) conditions. +`interval` | Configures the interval in seconds to wait between retries of the command. If the command does not pass the specified conditions, the interval indicates how long to wait before trying the command again. + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_command.py - This module file will be located at lib/ansible/modules/network/cnos/ of Ansible installation. +- cnos.py - This module util file will be located at lib/ansible/module_utils/network/cnos of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_command] +10.241.107.39 ansible_connection=network_cli ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_command_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: cnos_command + gather_facts: no + connection: network_cli + roles: + - cnos_command +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, eithe +r version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PU +RPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_command/aliases b/test/integration/targets/cnos_command/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_command/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_command/cnos_command_sample_hosts b/test/integration/targets/cnos_command/cnos_command_sample_hosts new file mode 100644 index 0000000000..2ff0169b7e --- /dev/null +++ b/test/integration/targets/cnos_command/cnos_command_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_command_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_command] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_command/defaults/main.yaml b/test/integration/targets/cnos_command/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/cnos_command/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/cnos_command/tasks/cli.yaml b/test/integration/targets/cnos_command/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/cnos_command/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/cnos_command/tasks/main.yaml b/test/integration/targets/cnos_command/tasks/main.yaml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/cnos_command/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/cnos_command/tests/cli/bad_operator.yaml b/test/integration/targets/cnos_command/tests/cli/bad_operator.yaml new file mode 100644 index 0000000000..79bba2b4f6 --- /dev/null +++ b/test/integration/targets/cnos_command/tests/cli/bad_operator.yaml @@ -0,0 +1,20 @@ +--- +- debug: msg="START cli/bad_operator.yaml" + +- name: test bad operator + cnos_command: + commands: + - display version + - display interface brief + wait_for: + - result[0] contains 'Description: Foo' + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == true" + - "result.msg is defined" + +- debug: msg="END cli/bad_operator.yaml" diff --git a/test/integration/targets/cnos_command/tests/cli/contains.yaml b/test/integration/targets/cnos_command/tests/cli/contains.yaml new file mode 100644 index 0000000000..78fbf0a9fb --- /dev/null +++ b/test/integration/targets/cnos_command/tests/cli/contains.yaml @@ -0,0 +1,20 @@ +--- +- debug: msg="START cli/contains.yaml" + +- name: test contains operator + cnos_command: + commands: + - display version + - display process memory + wait_for: + - "result[0] contains 'Lenovo'" + - "result[1] contains 'Mem:'" + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + +- debug: msg="END cli/contains.yaml" diff --git a/test/integration/targets/cnos_command/tests/cli/invalid.yaml b/test/integration/targets/cnos_command/tests/cli/invalid.yaml new file mode 100644 index 0000000000..017e6d6234 --- /dev/null +++ b/test/integration/targets/cnos_command/tests/cli/invalid.yaml @@ -0,0 +1,29 @@ +--- +- debug: msg="START cli/invalid.yaml" + +- name: run invalid command + cnos_command: + commands: ['display foo'] + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed" + +- name: run commands that include invalid command + cnos_command: + commands: + - display version + - display foo + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed" + ignore_errors: true + +- debug: msg="END cli/invalid.yaml" diff --git a/test/integration/targets/cnos_command/tests/cli/output.yaml b/test/integration/targets/cnos_command/tests/cli/output.yaml new file mode 100644 index 0000000000..4b262a98bc --- /dev/null +++ b/test/integration/targets/cnos_command/tests/cli/output.yaml @@ -0,0 +1,29 @@ +--- +- debug: msg="START cli/output.yaml" + +- name: get output for single command + cnos_command: + commands: ['display version'] + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + +- name: get output for multiple commands + cnos_command: + commands: + - display version + - display interface brief + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + - "result.stdout | length == 2" + +- debug: msg="END cli/output.yaml" diff --git a/test/integration/targets/cnos_command/tests/cli/timeout.yaml b/test/integration/targets/cnos_command/tests/cli/timeout.yaml new file mode 100644 index 0000000000..5502ee8f1c --- /dev/null +++ b/test/integration/targets/cnos_command/tests/cli/timeout.yaml @@ -0,0 +1,19 @@ +--- +- debug: msg="START cli/timeout.yaml" + +- name: test bad condition + cnos_command: + commands: + - display version + wait_for: + - "result[0] contains bad_value_string" + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == true" + - "result.msg is defined" + +- debug: msg="END cli/timeout.yaml" diff --git a/test/integration/targets/cnos_command/vars/main.yaml b/test/integration/targets/cnos_command/vars/main.yaml new file mode 100644 index 0000000000..a5cf22b798 --- /dev/null +++ b/test/integration/targets/cnos_command/vars/main.yaml @@ -0,0 +1,10 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin +# transport: cli + timeout: 30 + authorize: True + auth_pass: diff --git a/test/integration/targets/cnos_conditional_command/README.md b/test/integration/targets/cnos_conditional_command/README.md new file mode 100644 index 0000000000..4663322df6 --- /dev/null +++ b/test/integration/targets/cnos_conditional_command/README.md @@ -0,0 +1,120 @@ +# Ansible Role: cnos_conditional_command_sample - Executing a single CNOS command with respect to conditions specified in the inventory +--- +<add role description below> + +This role is an example of using the *cnos_conditional_command.py* Lenovo module in the context of CNOS switch configuration. This module allows you to modify the running configuration of a switch. It provides a way to execute a single CNOS command on a network device by evaluating the current running configuration and executing the command only if the specific settings have not been already configured. + +The CNOS command is passed as an argument of the method. + +This module functions the same as the *cnos_command.py* module. The only exception is that the following inventory variable can be specified: condition = <flag string> + +When this inventory variable is specified as the variable of a task, the command is executed for the network element that matches the flag string. +Usually, commands are executed across a group of network devices. When there is a requirement to skip the execution of the command on one or more devices, it is recommended to use this module. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_conditional_command](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_conditional_command.html&cp=0_3_1_0_4_9). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) +`condition` | If `condition=false` is specified in the inventory file against any device, the command execution is skipped for that device (**true**, **false**) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`flag` | If a task needs to be executed, the flag needs to be set the same as it is specified in the inventory for that device +`clicommand` | Specifies the CLI command as an attribute to this method + + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_conditional_command.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_conditional_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_conditional_command_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos condition=pass +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_conditional_command_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some configurations + hosts: cnos_conditional_command_sample + gather_facts: no + connection: local + roles: + - cnos_conditional_command_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_conditional_command/aliases b/test/integration/targets/cnos_conditional_command/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_conditional_command/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_conditional_command/cnos_conditional_command_sample_hosts b/test/integration/targets/cnos_conditional_command/cnos_conditional_command_sample_hosts new file mode 100644 index 0000000000..4b80cb031b --- /dev/null +++ b/test/integration/targets/cnos_conditional_command/cnos_conditional_command_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_conditional_command_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_conditional_command_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_conditional_command/tasks/main.yml b/test/integration/targets/cnos_conditional_command/tasks/main.yml new file mode 100644 index 0000000000..18feb5d262 --- /dev/null +++ b/test/integration/targets/cnos_conditional_command/tasks/main.yml @@ -0,0 +1,7 @@ +# This contain sample command execution tasks +--- + +- name: Run a command + cnos_conditional_command: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} condition={{ hostvars[inventory_hostname]['condition'] }} flag='{{item.flag}}' clicommand='{{item.clicommand}}' outputfile=./results/cnos_conditional_command_{{ inventory_hostname }}_output.txt + with_items: "{{conditional_command_data1}}" +# Completed file diff --git a/test/integration/targets/cnos_conditional_command/vars/main.yml b/test/integration/targets/cnos_conditional_command/vars/main.yml new file mode 100644 index 0000000000..588ae01178 --- /dev/null +++ b/test/integration/targets/cnos_conditional_command/vars/main.yml @@ -0,0 +1,3 @@ +--- +conditional_command_data1: + - {flag: "pass", clicommand: "display users"} diff --git a/test/integration/targets/cnos_conditional_template/README.md b/test/integration/targets/cnos_conditional_template/README.md new file mode 100644 index 0000000000..c3f40dd898 --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/README.md @@ -0,0 +1,120 @@ +# Ansible Role: cnos_conditional_template_sample - Manages switch configuration using templates with respect to conditions specified in the inventory +--- +<add role description below> + +This role is an example of using the *cnos_conditional_template.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with the running configuration of a switch. It provides a way to execute a set of CNOS commands on a switch by evaluating the current running configuration and executing the commands only if the specific settings have not been already configured. + +The configuration source can be a set of commands or a template written in the Jinja2 templating language. + +This module functions the same as the *cnos_template.py* module. The only exception is that the following inventory variable can be specified: condition = <flag string> + +When this inventory variable is specified as the variable of a task, the template is executed for the network element that matches the flag string. + +Usually, templates are used when commands are the same across a group of network devices. When there is a requirement to skip the execution of the template on one or more devices, it is recommended to use this module. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_conditional_template](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_conditional_template.html&cp=0_3_1_0_4_11). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) +`condition` | If `condition=<flag string>` is specified in the inventory file against any device, the template execution is done for that device in case it matches the flag setting for that task + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`flag` | If a task needs to be executed, you have to set the flag the same as it is specified in the inventory for that device +`commandfile` | Specifies the path to the CNOS command file which needs to be applied + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_conditional_template.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_conditional_template_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_conditional_template_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos condition=pass +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_conditional_template_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some template configurations + hosts: cnos_conditional_template_sample + gather_facts: no + connection: local + roles: + - cnos_conditional_template_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_conditional_template/aliases b/test/integration/targets/cnos_conditional_template/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_conditional_template/cnos_conditional_template_sample_hosts b/test/integration/targets/cnos_conditional_template/cnos_conditional_template_sample_hosts new file mode 100644 index 0000000000..ee98b5f483 --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/cnos_conditional_template_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_conditional_template_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_conditional_template_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_conditional_template/tasks/main.yml b/test/integration/targets/cnos_conditional_template/tasks/main.yml new file mode 100644 index 0000000000..2567f12ad7 --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/tasks/main.yml @@ -0,0 +1,11 @@ +# This contain sample conditional template execution tasks +--- +- name: Replace Config CLI command template with values + template: src=demo_template.j2 dest=./commands/cnos_conditional_template_{{ inventory_hostname }}_command.txt + with_items: "{{conditional_template_data1}}" + +- name: Applying CLI commands on Switches + cnos_conditional_template: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} + condition={{ hostvars[inventory_hostname]['condition'] }} flag='{{item.flag}}' commandfile=./commands/cnos_conditional_template_{{ inventory_hostname }}_command.txt outputfile=./results/cnos_conditional_template_{{ inventory_hostname }}_output.txt + with_items: "{{conditional_template_data1}}" +# Completed file diff --git a/test/integration/targets/cnos_conditional_template/templates/demo_template.j2 b/test/integration/targets/cnos_conditional_template/templates/demo_template.j2 new file mode 100644 index 0000000000..c9b8ca8386 --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/templates/demo_template.j2 @@ -0,0 +1,16 @@ +#Demo Template +vlan {{item.vlanid1}} +name anil +exit +#config d +interface ethernet {{item.slot_chassis_number1}} +#aggregation-group {{item.portchannel_interface_number1}} mode {{item.portchannel_mode1}} +description anil +mtu 600 +exit +#config d +interface port-aggregation {{item.portchannel_interface_number1}} +shut +lacp suspend-individual +no shut +exit diff --git a/test/integration/targets/cnos_conditional_template/vars/main.yml b/test/integration/targets/cnos_conditional_template/vars/main.yml new file mode 100644 index 0000000000..b2795dc79a --- /dev/null +++ b/test/integration/targets/cnos_conditional_template/vars/main.yml @@ -0,0 +1,3 @@ +--- +conditional_template_data1: + - {flag: "pass", vlanid1: 13, slot_chassis_number1: "1/2", portchannel_interface_number1: 100, portchannel_mode1: "active"} diff --git a/test/integration/targets/cnos_config/README.md b/test/integration/targets/cnos_config/README.md new file mode 100644 index 0000000000..da5ab5d4b6 --- /dev/null +++ b/test/integration/targets/cnos_config/README.md @@ -0,0 +1,123 @@ +# Ansible Role: cnos_config - Exceutes any Configuration command on switch and results are displayed. +--- +<add role description below> + + Lenovo CNOS configurations use a simple block indent file syntax + for segmenting configuration into sections. This module provides + an implementation for working with CNOS configuration sections in + a deterministic way. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.6 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +These are the various options the customer have in executing the cnos_config modules: + +Variable | Description +--- | --- +`lines` | The ordered set of commands that should be configured in the section. The commands must be the exact same commands as found in the device running-config. Be sure to note the configuration command syntax as some commands are automatically modified by the device config parser. +`parents` | The ordered set of parents that uniquely identify the section the commands should be checked against. If the parents argument is omitted, the commands are checked against the set of top level or global commands. +`src` | Specifies the source path to the file that contains the configuration or configuration template to load. The path to the source file can either be the full path on the Ansible control host or a relative path from the playbook or role root directory. This argument is mutually exclusive with I(lines), I(parents). +`before` | The ordered set of commands to push on to the command stack if a change needs to be made. This allows the playbook designer the opportunity to perform configuration commands prior to pushing any changes without affecting how the set of commands are matched against the system. +`after` | The ordered set of commands to append to the end of the command stack if a change needs to be made. Just like with I(before) this allows the playbook designer to append a set of commands to be executed after the command set. +`replace` | Instructs the module on the way to perform the configuration on the device. If the replace argument is set to I(line) then the modified lines are pushed to the device in configuration mode. If the replace argument is set to I(block) then the entire command block is pushed to the device in configuration mode if any line is not correct. +`config` | The module, by default, will connect to the remote device and retrieve the current running-config to use as a base for comparing against the contents of source. There are times when it is not desirable to have the task get the current running-config for every task in a playbook. The I(config) argument allows the implementer to pass in the configuration to use as the base config for comparison. +`backup` | This argument will cause the module to create a full backup of the current C(running-config) from the remote device before any changes are made. The backup file is written to the C(backup) folder in the playbook root directory. If the directory does not exist, it is created. +`match` |Instructs the module on the way to perform the matching of the set of commands against the current device config. If match is set to I(line), commands are matched line by line. If match is set to I(strict), command lines are matched with respect to position. If match is set to I(exact), command lines must be an equal match. Finally, if match is set to I(none), the module will not attempt to compare the source configuration with the running configuration on the remote device. +`comment` | Allows a commit description to be specified to be included when the configuration is committed. If the configuration is not changed or committed, this argument is ignored. +`admin` | Enters into administration configuration mode for making config changes to the device. + + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_config.py - This module file will be located at lib/ansible/modules/network/cnos/ of Ansible installation. +- cnos.py - This module util file will be located at lib/ansible/module_utils/network/cnos of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- cnos_config.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_config] +10.241.105.24 ansible_connection=network_cli ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_config_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: cnos_config + gather_facts: no + connection: network_cli + roles: + - cnos_config +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, eithe +r version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PU +RPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_config/aliases b/test/integration/targets/cnos_config/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_config/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_config/cnos_config_sample_hosts b/test/integration/targets/cnos_config/cnos_config_sample_hosts new file mode 100644 index 0000000000..4a87c18c54 --- /dev/null +++ b/test/integration/targets/cnos_config/cnos_config_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_command_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_config] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_config/defaults/main.yaml b/test/integration/targets/cnos_config/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/cnos_config/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/cnos_config/tasks/cli.yaml b/test/integration/targets/cnos_config/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/cnos_config/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/cnos_config/tasks/main.yaml b/test/integration/targets/cnos_config/tasks/main.yaml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/cnos_config/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/cnos_config/templates/basic/config.j2 b/test/integration/targets/cnos_config/templates/basic/config.j2 new file mode 100644 index 0000000000..13ae810013 --- /dev/null +++ b/test/integration/targets/cnos_config/templates/basic/config.j2 @@ -0,0 +1,4 @@ +vlan 13 + name anil + flood ipv4 + state active diff --git a/test/integration/targets/cnos_config/templates/basic/config1.j2 b/test/integration/targets/cnos_config/templates/basic/config1.j2 new file mode 100644 index 0000000000..05305af622 --- /dev/null +++ b/test/integration/targets/cnos_config/templates/basic/config1.j2 @@ -0,0 +1,4 @@ +vlan 33 + name panil + flood ipv4 + state active diff --git a/test/integration/targets/cnos_config/templates/defaults/config.j2 b/test/integration/targets/cnos_config/templates/defaults/config.j2 new file mode 100644 index 0000000000..d4c04bb3ee --- /dev/null +++ b/test/integration/targets/cnos_config/templates/defaults/config.j2 @@ -0,0 +1,2 @@ +vlan 13 + name anil diff --git a/test/integration/targets/cnos_config/tests/cli/backup.yaml b/test/integration/targets/cnos_config/tests/cli/backup.yaml new file mode 100644 index 0000000000..3f385311fd --- /dev/null +++ b/test/integration/targets/cnos_config/tests/cli/backup.yaml @@ -0,0 +1,52 @@ +--- +- debug: msg="START cli/backup.yaml" + +- name: setup + cnos_config: + commands: + - no vlan 13 + provider: "{{ cli }}" + ignore_errors: yes + +- name: collect any backup files + find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + delegate_to: localhost + +- name: delete backup files + file: + path: "{{ item.path }}" + state: absent + with_items: "{{backup_files.files|default([])}}" + +- name: configure device with config + cnos_config: + src: roles/cnos_config/templates/basic/config.j2 + backup: yes + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + +- name: collect any backup files + find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + delegate_to: localhost + +- assert: + that: + - "backup_files.files is defined" + +- name: teardown + cnos_config: + commands: + - no vlan 13 + provider: "{{ cli }}" + +- debug: msg="END cli/backup.yaml" diff --git a/test/integration/targets/cnos_config/tests/cli/basic.yaml b/test/integration/targets/cnos_config/tests/cli/basic.yaml new file mode 100644 index 0000000000..61773d2dcb --- /dev/null +++ b/test/integration/targets/cnos_config/tests/cli/basic.yaml @@ -0,0 +1,39 @@ +--- +- debug: msg="START cli/basic.yaml" + +- name: setup + cnos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + ignore_errors: yes + +- name: configure device with config + cnos_config: + src: roles/cnos_config/templates/basic/config.j2 + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: check device with config + cnos_config: + src: roles/cnos_config/templates/basic/config.j2 + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: teardown + cnos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + +- debug: msg="END cli/basic.yaml" diff --git a/test/integration/targets/cnos_config/tests/cli/defaults.yaml b/test/integration/targets/cnos_config/tests/cli/defaults.yaml new file mode 100644 index 0000000000..3bea4e0c77 --- /dev/null +++ b/test/integration/targets/cnos_config/tests/cli/defaults.yaml @@ -0,0 +1,50 @@ +--- +- debug: msg="START cli/defaults.yaml" + +- name: setup + cnos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + ignore_errors: yes + become: True + become_method: enable + +- name: configure device with defaults included + cnos_config: + src: roles/cnos_config/templates/defaults/config.j2 + provider: "{{ cli }}" + register: result + become: True + become_method: enable + +- debug: var=result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: check device with defaults included Hell + cnos_config: + src: roles/cnos_config/templates/defaults/config.j2 + provider: "{{ cli }}" + register: result + +- debug: var=result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: teardown + cnos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + become: true + become_method: enable + ignore_errors: yes + +- debug: msg="END cli/defaults.yaml" diff --git a/test/integration/targets/cnos_config/vars/main.yml b/test/integration/targets/cnos_config/vars/main.yml new file mode 100644 index 0000000000..d0fcdabf53 --- /dev/null +++ b/test/integration/targets/cnos_config/vars/main.yml @@ -0,0 +1,9 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin + timeout: 60 + context: ansible + auth_pass: diff --git a/test/integration/targets/cnos_ethernet/README.md b/test/integration/targets/cnos_ethernet/README.md new file mode 100644 index 0000000000..e3c606ef0a --- /dev/null +++ b/test/integration/targets/cnos_ethernet/README.md @@ -0,0 +1,120 @@ +# Ansible Role: cnos_ethernet_sample - Performs switch ethernet port configuration and state management +--- +<add role description below> + +This role is an example of using the *cnos_interface.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with interface related configurations. The operators used are overloaded to ensure control over switch interface configurations, such as ethernet ports, loopback interfaces, VLANs, and the management interface. + +Apart from the regular device connection related attributes, there are seven interface arguments that will perform further configurations. They are *interfaceArg1*, *interfaceArg2*, *interfaceArg3*, *interfaceArg4*, *interfaceArg5*, *interfaceArg6*, and *interfaceArg7*. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_interface](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_interface.html&cp=0_3_1_0_4_12). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`interfaceOption` | Specifies the type of the interface that will be configured (**ethernet** - ethernet port, **loopback** - loopback interface, **vlan** - VLAN, **mgmt** - management interface, **port-aggregation** - Link Aggregation Group) +`interfaceRange` | Specifies the interface range that will be configured +`interfaceArg1` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **aggregation-group**, **bfd**, **bridge-port**, **description**, **duplex**, **flowcontrol**, **ip**, **ipv6**, **lacp**, **lldp**, **load-interval**, **mac**, **mac-address**, **mac-learn**, **microburst-detection**, **mtu**, **service**, **service-policy**, **shutdown**, **snmp**, **spanning-tree**, **speed**, **storm-control**, **vlan**, **vrrp**, **port-aggregation**. +`interfaceArg2` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: specify a LAG number, **authentication**, **echo**, **ipv4**, **ipv6**, **interval**, **neighbor**, **access**, **mode**, **trunk**, interface description, **auto**, **full**, **half**, **receive**, **send**, **access-group**, **arp**, **dhcp**, **port**, **port-unreachable**, **redirects**, **router**, **unreachables**, **address**, **link-local**, **port-priority**, **suspend-individual**, **timeout**, **transmit**, **trap-notification**, **tlv-select**, load interval delay, **counter**, name for the MAC access group, MAC address in XXXX.XXXX.XXXX format, threshold value, MTU in bytes, instance ID to map to the EVC, **input**, **output**, **copp-system-policy**, **type**, **bpdufilter**, **bpduguard**, **cost**, **enable**, **disable**, **guard**, **link-type**, **mst**, **port**, **port-priority**, **vlan**, **auto**, 1000, 10000, 40000, **broadcast**, **unicast**, **multicast**, **egress-only**, **destination-ip**, **destination-mac**, **destination-port**, **source-dest-ip**, **source-dest-mac**, **source-dest-port**, **source-interface**, **source-ip**, **source-mac**, **source-port**. +`interfaceArg3` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **active**, **passive**, **on**, **keyed-md5**, **keyed-sha1**, **meticulous-keyed-md5**, **meticulous-keyed-sha1**, **simple**, **authentication**, **echo**, **interval**, interval value, source IP address, **off**, ACL name, IP address of the ARP entry, **timeout**, **client**, **relay**, **area**, **multi-area**, **dhcp**, IPv6 address, IPv6 address of the DHCP Relay, Neighbor IPv6 address, LACP port priority, **long**, **short**, **link-aggregation**, **mac-phy-status**, **management-address**, **max-frame-size**, **port-description**, **port-protocol-vlan**, **port-vlan**, **power-mdi**, **protocol-identity**, **system-capabilities**, **system-description**, **system-name**, **vid-management**, **vlan-name**, counter for the load interval, name of the policy to attach, **all**, COPP class name to attach, **qos**, **queuing**, **enable**, **disable**, **auto**, port path cost, **loop**, **root**, **auto**, **point-to-point**, **shared**, MSTP instance range, port priority value, specify VLAN, allowed traffic level, **ipv6**, **source-interface**. +`interfaceArg4` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **key-chain**, **key-id**, **keyed-md5**, **keyed-sha1**, **meticulous-keyed-md5**, **meticulous-keyed-sha1**, **simple**, interval value, BFD minimum receive interval, destination IP address, **in**, **out**, MAC address in XXXX.XXXX.XXXX format, timeout value, **class-id**, **request**, IPv4 address of the DHCP Relay, OSPF area ID, **anycast**, **secondary**, **ethernet**, **vlan**, load interval delay, name of the QoS policy to attach, **input**, **output**, **cost**, **port-priority**. +`interfaceArg5` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: name of the key chain, key ID, **key-chain**, **key-id**, BFD minimum receive interval, Hello multiplier value, **admin-down**, **multihop**, **non-persistent**, vendor class ID name, **bootfile-name**, **host-name**, **log-server**, **ntp-server**, **tftp-server-name**, specifiy ethernet port, specify VLAN, name of the QoS policy to attach, **auto**, port path cost, port priority value. +`interfaceArg6` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: authentication key string, name of the key chain, key ID, Hello multiplier value, **admin-down**, **non-persistent**. +`interfaceArg7` | This is an overloaded BGP variable. Please refer to the [cnos_interface module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_interface.html?cp=0_3_1_0_2_12) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: authentication key string, **admin-down**. + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_interface.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_interface_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_ethernet_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_interface_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do Interface Ethernet configurations + hosts: cnos_ethernet_sample + gather_facts: no + connection: local + roles: + - cnos_ethernet_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_ethernet/aliases b/test/integration/targets/cnos_ethernet/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_ethernet/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_ethernet/cnos_ethernet_sample_hosts b/test/integration/targets/cnos_ethernet/cnos_ethernet_sample_hosts new file mode 100644 index 0000000000..1c49fc0cdd --- /dev/null +++ b/test/integration/targets/cnos_ethernet/cnos_ethernet_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_ethernet_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_ethernet_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_ethernet/tasks/main.yml b/test/integration/targets/cnos_ethernet/tasks/main.yml new file mode 100644 index 0000000000..237fd6fdcf --- /dev/null +++ b/test/integration/targets/cnos_ethernet/tasks/main.yml @@ -0,0 +1,98 @@ +### This contain sample execution tasks +--- +- name: Test Interface Ethernet - aggregation-group + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data1}}" + +#- name: Test Interface Ethernet - aggregation-group - Interface Range +# cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' +# with_items: "{{test_ethernet_data24}}" + +- name: Test Interface Ethernet - bridge-port + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data2}}" + +- name: Test Interface Ethernet - bridgeport mode + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data3}}" + +- name: Test Interface Ethernet - Description + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data4}}" + +- name: Test Interface Ethernet - Duplex + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data5}}" + +- name: Test Interface Ethernet - flowcontrol + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data6}}" + +- name: Test Interface Ethernet - lacp + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data7}}" + +- name: Test Interface Ethernet - lldp + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data8}}" + +- name: Test Interface Ethernet - load-interval + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' + with_items: "{{test_ethernet_data9}}" + +#- name: Test Interface Ethernet - mac +# cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' +# with_items: "{{test_ethernet_data10}}" + +- name: Test Interface Ethernet - microburst-detection + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data11}}" + +- name: Test Interface Ethernet - mtu + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data12}}" + +- name: Test Interface Ethernet - service-policy + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data13}}" + +- name: Test Interface Ethernet - speed + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data14}}" + +- name: Test Interface Ethernet - storm + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data15}}" + +#- name: Test Interface Ethernet - vlan +# cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' +# with_items: "{{test_ethernet_data16}}" + +- name: Test Interface Ethernet - vrrp + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_ethernet_data17}}" + +- name: Test Interface Ethernet - spanning tree1 + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data18}}" + +- name: Test Interface Ethernet - spanning tree 2 + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' + with_items: "{{test_ethernet_data19}}" + +- name: Test Interface Ethernet - ip1 + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' + with_items: "{{test_ethernet_data20}}" + +- name: Test Interface Ethernet - ip2 + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_ethernet_data21}}" + +- name: Test Interface Ethernet - bfd + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' + with_items: "{{test_ethernet_data22}}" + +- name: Test Interface Ethernet - bfd + cnos_interface: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_ethernet_{{ inventory_hostname }}_output.txt interfaceOption='{{item.interfaceOption}}' interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' interfaceArg6='{{item.interfaceArg6}}' + with_items: "{{test_ethernet_data23}}" +# Completed file diff --git a/test/integration/targets/cnos_ethernet/vars/main.yml b/test/integration/targets/cnos_ethernet/vars/main.yml new file mode 100644 index 0000000000..b1565cb65c --- /dev/null +++ b/test/integration/targets/cnos_ethernet/vars/main.yml @@ -0,0 +1,49 @@ +--- +test_ethernet_data1: + - {interfaceOption: 'ethernet', interfaceRange: 1, interfaceArg1: "channel-group", interfaceArg2: 33, interfaceArg3: "on"} +test_ethernet_data2: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "switchport", interfaceArg2: "access", interfaceArg3: 33} +test_ethernet_data3: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "switchport", interfaceArg2: "mode", interfaceArg3: "access"} +test_ethernet_data4: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "description", interfaceArg2: "Hentammoo "} +test_ethernet_data5: + - {interfaceOption: 'ethernet', interfaceRange: 1, interfaceArg1: "duplex", interfaceArg2: "auto"} +test_ethernet_data6: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "flowcontrol", interfaceArg2: "send", interfaceArg3: "off"} +test_ethernet_data7: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "lacp", interfaceArg2: "port-priority", interfaceArg3: 33} +test_ethernet_data8: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "lldp", interfaceArg2: "tlv-select", interfaceArg3: "max-frame-size"} +test_ethernet_data9: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "load-interval", interfaceArg2: "counter", interfaceArg3: 2, interfaceArg4: 33} +test_ethernet_data10: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "mac", interfaceArg2: "copp-system-acl-vlag-hc"} +test_ethernet_data11: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "microburst-detection", interfaceArg2: 25} +test_ethernet_data12: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "mtu", interfaceArg2: 660} +test_ethernet_data13: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "service-policy", interfaceArg2: "input", interfaceArg3: "Anil"} +test_ethernet_data14: + - {interfaceOption: 'ethernet', interfaceRange: 1, interfaceArg1: "speed", interfaceArg2: "40000"} +test_ethernet_data15: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "storm-control", interfaceArg2: "broadcast", interfaceArg3: 12.5 } +test_ethernet_data16: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "vlan", interfaceArg2: "disable"} +test_ethernet_data17: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "vrrp", interfaceArg2: 33} +test_ethernet_data18: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "spanning-tree", interfaceArg2: "bpduguard", interfaceArg3: "enable"} +test_ethernet_data19: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "spanning-tree", interfaceArg2: "mst", interfaceArg3: "33-35", interfaceArg4: "cost", interfaceArg5: 33} +test_ethernet_data20: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "ip", interfaceArg2: "access-group", interfaceArg3: "anil", interfaceArg4: "in"} +test_ethernet_data21: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "ip", interfaceArg2: "port", interfaceArg3: "anil" } +test_ethernet_data22: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "bfd", interfaceArg2: "interval", interfaceArg3: 55, interfaceArg4: 55, interfaceArg5: 33} +test_ethernet_data23: + - {interfaceOption: 'ethernet', interfaceRange: 33, interfaceArg1: "bfd", interfaceArg2: "ipv4", interfaceArg3: "authentication", interfaceArg4: "meticulous-keyed-md5", interfaceArg5: "key-chain", interfaceArg6: "mychain"} +test_ethernet_data24: + - {interfaceOption: 'ethernet', interfaceRange: "1/1-2", interfaceArg1: "channel-group", interfaceArg2: 33, interfaceArg3: "on"} diff --git a/test/integration/targets/cnos_facts/README.md b/test/integration/targets/cnos_facts/README.md new file mode 100644 index 0000000000..4ead5ed73a --- /dev/null +++ b/test/integration/targets/cnos_facts/README.md @@ -0,0 +1,112 @@ +# Ansible Role: cnos_facts - Displays switch inforamtion +--- +<add role description below> + + Collects a base set of device facts from a remote Lenovo device + running on CNOS. This module prepends all of the + base network fact keys with C(ansible_net_<fact>). The facts + module will always collect a base set of facts from the device + and can enable or disable collection of additional facts. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.6 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +To gather subsets you will specify the following variables to get appropriate +data retrived from the devices + +Variable | Description +--- | --- +`gather_subset` | When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument include all, hardware, config, and interfaces. Can specify a list of values to include a larger subset. Values can also be used with an initial C(M(!)) to specify that a specific subset should not be collected. + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_facts.py - This module file will be located at lib/ansible/modules/network/cnos/ of Ansible installation. +- cnos.py - This module util file will be located at lib/ansible/module_utils/network/cnos of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- cnos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_facts] +10.241.105.24 ansible_connection=network_cli ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_facts_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: cnos_facts + gather_facts: no + connection: network_cli + roles: + - cnos_facts +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_facts/aliases b/test/integration/targets/cnos_facts/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_facts/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_facts/cnos_facts_sample_hosts b/test/integration/targets/cnos_facts/cnos_facts_sample_hosts new file mode 100644 index 0000000000..99cc3c263a --- /dev/null +++ b/test/integration/targets/cnos_facts/cnos_facts_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_facts_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_facts] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_facts/defaults/main.yaml b/test/integration/targets/cnos_facts/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/cnos_facts/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/cnos_facts/tasks/cli.yaml b/test/integration/targets/cnos_facts/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/cnos_facts/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/cnos_facts/tasks/main.yml b/test/integration/targets/cnos_facts/tasks/main.yml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/cnos_facts/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/cnos_facts/tests/cli/all_facts.yaml b/test/integration/targets/cnos_facts/tests/cli/all_facts.yaml new file mode 100644 index 0000000000..4deed11fe7 --- /dev/null +++ b/test/integration/targets/cnos_facts/tests/cli/all_facts.yaml @@ -0,0 +1,27 @@ +--- +- debug: msg="START cli/all_facts.yaml" + +- name: test getting all facts + cnos_facts: + gather_subset: + - all + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + #- "result.ansible_facts.ansible_net_filesystems is defined" + # Check that these facts not only are present, but are valid (positive integers) + - "result.ansible_facts.ansible_net_memfree_mb > 1" + - "result.ansible_facts.ansible_net_memtotal_mb > 1" + +- debug: msg="END cli/all_facts.yaml" diff --git a/test/integration/targets/cnos_facts/tests/cli/default_facts.yaml b/test/integration/targets/cnos_facts/tests/cli/default_facts.yaml new file mode 100644 index 0000000000..e0fd6e3d8f --- /dev/null +++ b/test/integration/targets/cnos_facts/tests/cli/default_facts.yaml @@ -0,0 +1,30 @@ +--- +- debug: msg="START cli/default_facts.yaml" + + +- name: test getting default facts + cnos_facts: + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + #- "result.ansible_facts.ansible_net_filesystems is defined" + # ... and not present + - "'config' not in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + #- "result.ansible_facts.ansible_net_filesystems is defined" #hw + - "result.ansible_facts.ansible_net_memtotal_mb > 10" #hw + - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned + + # ... and not present + - "result.ansible_facts.ansible_net_config is not defined" # config + +- debug: msg="END cli/default.yaml" diff --git a/test/integration/targets/cnos_facts/tests/cli/invalid_subset.yaml b/test/integration/targets/cnos_facts/tests/cli/invalid_subset.yaml new file mode 100644 index 0000000000..c583f84b53 --- /dev/null +++ b/test/integration/targets/cnos_facts/tests/cli/invalid_subset.yaml @@ -0,0 +1,39 @@ +--- +- debug: msg="START cli/invalid_subset.yaml" + +- name: test invalid subset (foobar) + cnos_facts: + gather_subset: + - "foobar" + register: result + ignore_errors: true + +- assert: + that: + # Failures shouldn't return changes + - "result.changed == false" + # It's a failure + - "result.failed == true" + # Sensible Failure message + - "result.msg == 'Bad subset'" + +- name: test subset specified multiple times + cnos_facts: + gather_subset: + - "!hardware" + - "hardware" + authorize: yes + register: result + ignore_errors: true + +- assert: + that: + # Failures shouldn't return changes + - "result.changed == false" + # It's a failure + - "result.failed == true" + # Sensible Failure message + - "result.msg == 'Bad subset'" + ignore_errors: true + +- debug: msg="END cli/invalid_subset.yaml" diff --git a/test/integration/targets/cnos_facts/tests/cli/not_hardware.yaml b/test/integration/targets/cnos_facts/tests/cli/not_hardware.yaml new file mode 100644 index 0000000000..4f019e40d3 --- /dev/null +++ b/test/integration/targets/cnos_facts/tests/cli/not_hardware.yaml @@ -0,0 +1,28 @@ +--- +- debug: msg="START cli/not_hardware_facts.yaml" + +- name: test not hardware + cnos_facts: + gather_subset: + - "!hardware" + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'config' in result.ansible_facts.ansible_net_gather_subset" + + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + # ... and not present + - "'hardware' not in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned + # ... and not present + - "result.ansible_facts.ansible_net_filesystems is not defined" + +- debug: msg="END cli/not_hardware_facts.yaml" diff --git a/test/integration/targets/cnos_facts/vars/main.yml b/test/integration/targets/cnos_facts/vars/main.yml new file mode 100644 index 0000000000..aa25153ec8 --- /dev/null +++ b/test/integration/targets/cnos_facts/vars/main.yml @@ -0,0 +1,9 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin + timeout: 30 + authorize: True + auth_pass: diff --git a/test/integration/targets/cnos_portchannel/README.md b/test/integration/targets/cnos_portchannel/README.md new file mode 100644 index 0000000000..65dcf52e2a --- /dev/null +++ b/test/integration/targets/cnos_portchannel/README.md @@ -0,0 +1,117 @@ +# Ansible Role: cnos_portchannel_sample - Switch Link Aggregation Group (LAG) configuration +--- +<add role description below> + +This role is an example of using the *cnos_portchannel.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with port aggregation related configurations. The operators used are overloaded to ensure control over switch port aggregation configurations. + +Apart from the regular device connection related attributes, there are five vLAG arguments which are overloaded variables that will perform further configurations. They are portChArg1, portChArg2, portChArg3, portChArg4, and portChArg5. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_portchannel](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_portchannel.html&cp=0_3_1_0_4_13). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`interfaceRange` | Specifies the interface range that will be part of the LAG +`portChArg1` | This is an overloaded variable. Please refer to the [cnos_portchannel module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_portchannel.html?cp=0_3_1_0_2_14) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **aggregation-group**, **bridge-port**, **description**, **duplex**, **flowcontrol**, **lacp**, **lldp**, **load-interval**, **mac**, **mac-address**, **mac-learn**, **microburst-detection**, **mtu**, **service**, **service-policy**, **shutdown**, **snmp**, **speed**, **storm-control**, **vlan**, **vrrp**, **port-aggregation**. +`portChArg2` | This is an overloaded PortChannel variable. Please refer to the [cnos_portchannel module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_portchannel.html?cp=0_3_1_0_2_14) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: specify a LAG number, **access**, **mode**, **trunk**, LAG description, **auto**, **full**, **half**, **receive**, **send**, **port-priority**, **suspend-individual**, **timeout**, **transmit**, **trap-notification**, **tlv-select**, load interval delay, **counter**, name for the MAC access group, MAC address in XXXX.XXXX.XXXX format, threshold value, MTU in bytes, instance ID to map to the EVC, **input**, **output**, **copp-system-policy**, **type**, **auto**, 1000, 10000, 40000, **broadcast**, **unicast**, **multicast**, **disable**, **enable**, **egress-only**, virtual router ID, **destination-ip**, **destination-mac**, **destination-port**, **source-dest-ip**, **source-dest-mac**, **source-dest-port**, **source-interface**, **source-ip**, **source-mac**, **source-port**. +`portChArg3` | This is an overloaded PortChannel variable. Please refer to the [cnos_portchannel module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_portchannel.html?cp=0_3_1_0_2_14) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **active**, **passive**, **on**, **off**, LACP port priority, **long**, **short**, **link-aggregation**, **mac-phy-status**, **management-address**, **max-frame-size**, **port-description**, **port-protocol-vlan**, **port-vlan**, **power-mdi**, **protocol-identity**, **system-capabilities**, **system-description**, **system-name**, **vid-management**, **vlan-name**, counter for the load interval, the name of the policy to attach, **all**, COPP class name to attach, **qos**, **queuing**, allowed traffic level, **ipv6**, **source-interface**. +`portChArg4` | This is an overloaded PortChannel variable. Please refer to the [cnos_portchannel module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_portchannel.html?cp=0_3_1_0_2_14) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: load interval delay, name of the QoS policy to attach, **input**, **output** +`portChArg5` | This is an overloaded PortChannel variable. Please refer to the [cnos_portchannel module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_portchannel.html?cp=0_3_1_0_2_14) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: name of the QoS policy to attach + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_portchannel.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_portchannel_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_portchannel_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_portchannel_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do Port Channel configurations + hosts: cnos_portchannel_sample + gather_facts: no + connection: local + roles: + - cnos_portchannel_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/cnos_portchannel/aliases b/test/integration/targets/cnos_portchannel/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_portchannel/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_portchannel/cnos_portchannel_sample_hosts b/test/integration/targets/cnos_portchannel/cnos_portchannel_sample_hosts new file mode 100644 index 0000000000..81d1a27bfc --- /dev/null +++ b/test/integration/targets/cnos_portchannel/cnos_portchannel_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_portchannel_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_portchannel_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_portchannel/tasks/main.yml b/test/integration/targets/cnos_portchannel/tasks/main.yml new file mode 100644 index 0000000000..a7e82cbf49 --- /dev/null +++ b/test/integration/targets/cnos_portchannel/tasks/main.yml @@ -0,0 +1,98 @@ +# This contain sample template execution tasks +--- +- name: Test Port Channel - aggregation-group + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data1}}" + +- name: Test Port Channel - aggregation-group - Interface Range + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data24}}" + +- name: Test Port Channel - bridge-port + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data2}}" + +- name: Test Port Channel - bridgeport mode + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data3}}" + +- name: Test Port Channel - Description + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data4}}" + +- name: Test Port Channel - Duplex + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data5}}" + +- name: Test Port Channel - flowcontrol + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data6}}" + +- name: Test Port Channel - lacp + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data7}}" + +- name: Test Port Channel - lldp + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data8}}" + +- name: Test Port Channel - load-interval + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' + with_items: "{{test_portchannel_data9}}" + +#- name: Test Port Channel - mac +# cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' +# with_items: "{{test_portchannel_data10}}" + +- name: Test Port Channel - microburst-detection + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data11}}" + +- name: Test Port Channel - mtu + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data12}}" + +- name: Test Port Channel - service-policy + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data13}}" + +- name: Test Port Channel - speed + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data14}}" + +- name: Test Port Channel - storm + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data15}}" + +#- name: Test Port Channel - vlan +# cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' +# with_items: "{{test_portchannel_data16}}" + +- name: Test Port Channel - vrrp + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' + with_items: "{{test_portchannel_data17}}" + +- name: Test Port Channel - spanning tree1 + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data18}}" + +- name: Test Port Channel - spanning tree 2 + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' + with_items: "{{test_portchannel_data19}}" + +- name: Test Port Channel - ip1 + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' + with_items: "{{test_portchannel_data20}}" + +- name: Test Port Channel - ip2 + cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' + with_items: "{{test_portchannel_data21}}" + +#- name: Test Port Channel - bfd +# cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' +# with_items: "{{test_portchannel_data22}}" + +#- name: Test Port Channel - bfd +# cnos_portchannel: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_portchannel_{{ inventory_hostname }}_output.txt interfaceRange='{{item.interfaceRange}}' interfaceArg1='{{item.interfaceArg1}}' interfaceArg2='{{item.interfaceArg2}}' interfaceArg3='{{item.interfaceArg3}}' interfaceArg4='{{item.interfaceArg4}}' interfaceArg5='{{item.interfaceArg5}}' interfaceArg6='{{item.interfaceArg6}}' +# with_items: "{{test_portchannel_data23}}" +## Completed file diff --git a/test/integration/targets/cnos_portchannel/vars/main.yml b/test/integration/targets/cnos_portchannel/vars/main.yml new file mode 100644 index 0000000000..bb7a1bf034 --- /dev/null +++ b/test/integration/targets/cnos_portchannel/vars/main.yml @@ -0,0 +1,49 @@ +--- +test_portchannel_data1: + - {interfaceRange: 33, interfaceArg1: "channel-group", interfaceArg2: 33, interfaceArg3: "on"} +test_portchannel_data2: + - {interfaceRange: 33, interfaceArg1: "switchport", interfaceArg2: "access", interfaceArg3: 33} +test_portchannel_data3: + - {interfaceRange: 33, interfaceArg1: "switchport", interfaceArg2: "mode", interfaceArg3: "access"} +test_portchannel_data4: + - {interfaceRange: 33, interfaceArg1: "description", interfaceArg2: "Hentammoo "} +test_portchannel_data5: + - {interfaceRange: 2, interfaceArg1: "duplex", interfaceArg2: "auto"} +test_portchannel_data6: + - {interfaceRange: 33, interfaceArg1: "flowcontrol", interfaceArg2: "send", interfaceArg3: "off"} +test_portchannel_data7: + - {interfaceRange: 33, interfaceArg1: "lacp", interfaceArg2: "port-priority", interfaceArg3: 33} +test_portchannel_data8: + - {interfaceRange: 33, interfaceArg1: "lldp", interfaceArg2: "tlv-select", interfaceArg3: "max-frame-size"} +test_portchannel_data9: + - {interfaceRange: 33, interfaceArg1: "load-interval", interfaceArg2: "counter", interfaceArg3: 2, interfaceArg4: 33 } +test_portchannel_data10: + - {interfaceRange: 33, interfaceArg1: "mac", interfaceArg2: "copp-system-acl-vlag-hc"} +test_portchannel_data11: + - {interfaceRange: 33, interfaceArg1: "microburst-detection", interfaceArg2: 25} +test_portchannel_data12: + - {interfaceRange: 33, interfaceArg1: "mtu", interfaceArg2: 66} +test_portchannel_data13: + - {interfaceRange: 33, interfaceArg1: "service-policy", interfaceArg2: "input", interfaceArg3: "Anil"} +test_portchannel_data14: + - {interfaceRange: 13, interfaceArg1: "speed", interfaceArg2: "40000"} +test_portchannel_data15: + - {interfaceRange: 33, interfaceArg1: "storm-control", interfaceArg2: "broadcast", interfaceArg3: 12.5 } +test_portchannel_data16: + - {interfaceRange: 33, interfaceArg1: "vlan", interfaceArg2: "disable"} +test_portchannel_data17: + - {interfaceRange: 33, interfaceArg1: "vrrp", interfaceArg2: 33} +test_portchannel_data18: + - {interfaceRange: 33, interfaceArg1: "spanning-tree", interfaceArg2: "bpduguard", interfaceArg3: "enable"} +test_portchannel_data19: + - {interfaceRange: 33, interfaceArg1: "spanning-tree", interfaceArg2: "mst", interfaceArg3: "33-35", interfaceArg4: "cost", interfaceArg5: 33} +test_portchannel_data20: + - {interfaceRange: 33, interfaceArg1: "ip", interfaceArg2: "access-group", interfaceArg3: "anil", interfaceArg4: "in"} +test_portchannel_data21: + - {interfaceRange: 33, interfaceArg1: "ip", interfaceArg2: "port", interfaceArg3: "anil" } +test_portchannel_data22: + - {interfaceRange: 2, interfaceArg1: "bfd", interfaceArg2: "interval", interfaceArg3: 55, interfaceArg4: 55, interfaceArg5: 33} +test_portchannel_data23: + - {interfaceRange: 2, interfaceArg1: "bfd", interfaceArg2: "ipv4", interfaceArg3: "authentication", interfaceArg4: "meticulous-keyed-md5", interfaceArg5: "key-chain", interfaceArg6: "mychain"} +test_portchannel_data24: +- {interfaceRange: "13", interfaceArg1: "channel-group", interfaceArg2: 33, interfaceArg3: "on"} diff --git a/test/integration/targets/cnos_rollback/README.md b/test/integration/targets/cnos_rollback/README.md new file mode 100644 index 0000000000..9c877d4c8a --- /dev/null +++ b/test/integration/targets/cnos_rollback/README.md @@ -0,0 +1,119 @@ +# Ansible Role: cnos_rollback_sample - Rolls back the configuration of a switch from a remote server +--- +<add role description below> + +This role is an example of using the *cnos_rollback.py* Lenovo module in the context of CNOS switch configuration.This module allows you to work with switch configurations. It provides a way to roll back configurations of a switch from a remote server. This is achieved by using startup or running configurations of the target device that were previously backed up to a remote server using FTP, SFTP, TFTP, or SCP. + +The first step is to create a directory from where the remote server can be reached. The next step is to provide the full file path of the backup configurations location. Authentication details required by the remote server must be provided as well. + +By default, this method overwrites the switch's configuration file with the newly downloaded file. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_rollback](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_rollback.html&cp=0_3_1_0_4_5). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`configType` | Specifies the type of configuration which will be used for the rolling back process (**running-config** - running configuration, **startup-config** - startup configuration) +`protocol` | Specifies the protocol used by the network device to interact with the remote server from where to download the backup configuration (**ftp** - FTP, **sftp** - SFTP, **tftp** - TFTP, **scp** - SCP) +`serverip` | Specifies the IP Address of the remote server from where the backup configuration will be downloaded +`rcpath` | Specifies the full file path where the configuration file located on the remote server (in case the relative path is used as the variable value, the root folder for the user of the server needs to be specified) +`serverusername` | Configures the username for the server relating to the protocol used +`serverpassword` | Configures the password for the server relating to the protocol used + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_rollback.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_rollback_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_rollback_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_rollback_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do rollback of configurations + hosts: cnos_rollback_sample + gather_facts: no + connection: local + roles: + - cnos_rollback_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_rollback/aliases b/test/integration/targets/cnos_rollback/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_rollback/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_rollback/cnos_rollback_sample_hosts b/test/integration/targets/cnos_rollback/cnos_rollback_sample_hosts new file mode 100644 index 0000000000..cdbc1051b4 --- /dev/null +++ b/test/integration/targets/cnos_rollback/cnos_rollback_sample_hosts @@ -0,0 +1,17 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_rollback_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_rollback_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos rcpath=/root/cnos_config/G8272-running-config.txt + +#Use this in case its TFTP as tftpboot folder is the starting point for tftp +#10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos rcpath=/anil/G8272-running-config.txt diff --git a/test/integration/targets/cnos_rollback/tasks/main.yml b/test/integration/targets/cnos_rollback/tasks/main.yml new file mode 100644 index 0000000000..d41b10ae87 --- /dev/null +++ b/test/integration/targets/cnos_rollback/tasks/main.yml @@ -0,0 +1,25 @@ +# This contain sample config Roll Back execution tasks +--- + +- name: Test Rollback of config - Running config + cnos_rollback: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_rollback_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' serverusername='{{item.serverusername}}' serverpassword='{{item.serverpassword}}' + with_items: "{{test_rollback_data1}}" + +- name: Test Rollback of config - Startup config + cnos_rollback: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_rollback_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath='{{item.rcpath}}' serverusername='{{item.serverusername}}' serverpassword='{{item.serverpassword}}' + with_items: "{{test_rollback_data2}}" + +#Root folder will be different for SFTP/SCP and TFTP +#The following task is commented. +#Before trying this, please change in /etc/ansible/hosts file +#and place an config file with reference to your tftp-root folder + +#- name: Test Rollback of config - Running config - TFTP +# cnos_rollback: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_rollback_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath={{ hostvars[inventory_hostname]['rcpath']}} +# with_items: "{{test_rollback_data3}}" + +#- name: Test Rollback of config - Startup config - TFTP +# cnos_rollback: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_rollback_{{ inventory_hostname }}_output.txt configType='{{item.configType}}' protocol='{{item.protocol}}' serverip='{{item.serverip}}' rcpath={{ hostvars[inventory_hostname]['rcpath']}} +# with_items: "{{test_rollback_data4}}" + +# Completed file diff --git a/test/integration/targets/cnos_rollback/vars/main.yml b/test/integration/targets/cnos_rollback/vars/main.yml new file mode 100644 index 0000000000..55ac70c14c --- /dev/null +++ b/test/integration/targets/cnos_rollback/vars/main.yml @@ -0,0 +1,12 @@ +--- +test_rollback_data1: + - {configType: running-config, protocol: "sftp", serverip: "10.241.106.118", rcpath: "/root/cnos_config/10.241.107.39_running-config.txt", serverusername: "root", serverpassword: "root123"} + +test_rollback_data2: + - {configType: startup-config, protocol: "sftp", serverip: "10.241.106.118", rcpath: "/root/cnos_config/10.241.107.39_startup-config.txt", serverusername: "root", serverpassword: "root123"} + +test_rollback_data3: + - {configType: running-config, protocol: "tftp", serverip: "10.241.106.118"} + +test_rollback_data4: + - {configType: startup-config, protocol: "tftp", serverip: "10.241.106.118"} diff --git a/test/integration/targets/cnos_save/README.md b/test/integration/targets/cnos_save/README.md new file mode 100644 index 0000000000..f5ded939a4 --- /dev/null +++ b/test/integration/targets/cnos_save/README.md @@ -0,0 +1,96 @@ +# Ansible Role: cnos_save_sample - Saving the switch running configuration +--- +<add role description below> + +This role is an example of using the *cnos_save.py* Lenovo module in the context of CNOS switch configuration. This module allows you to copy the running configuration of a switch over its startup configuration. It is recommended to use this module shortly after any major configuration changes so they persist after a switch restart. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_save](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_save.html&cp=0_3_1_0_4_3). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_save.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_save_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_save_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_save_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do save configurations + hosts: cnos_save_sample + gather_facts: no + connection: local + roles: + - cnos_save_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_save/aliases b/test/integration/targets/cnos_save/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_save/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_save/cnos_save_sample_hosts b/test/integration/targets/cnos_save/cnos_save_sample_hosts new file mode 100644 index 0000000000..3883f8c052 --- /dev/null +++ b/test/integration/targets/cnos_save/cnos_save_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_save_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_save_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_save/tasks/main.yml b/test/integration/targets/cnos_save/tasks/main.yml new file mode 100644 index 0000000000..6251d9eb6e --- /dev/null +++ b/test/integration/targets/cnos_save/tasks/main.yml @@ -0,0 +1,18 @@ +# This contain sample template execution tasks +--- +- name: Test Save + cnos_save: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_save_{{ inventory_hostname }}_output.txt + with_items: "{{cnos_save_data1}}" + +- name: Test Reset to factory + cnos_factory: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_save_{{ inventory_hostname }}_output.txt + with_items: "{{cnos_save_data2}}" + +- name: Test Again save + cnos_save: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_save_{{ inventory_hostname }}_output.txt + with_items: "{{cnos_save_data3}}" + +- name: Test Reload + cnos_reload: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_save_{{ inventory_hostname }}_output.txt + with_items: "{{cnos_save_data4}}" +# Completed file diff --git a/test/integration/targets/cnos_save/vars/main.yml b/test/integration/targets/cnos_save/vars/main.yml new file mode 100644 index 0000000000..e577a44753 --- /dev/null +++ b/test/integration/targets/cnos_save/vars/main.yml @@ -0,0 +1,9 @@ +--- +cnos_save_data1: + - {} +cnos_save_data2: + - {} +cnos_save_data3: + - {} +cnos_save_data4: + - {} diff --git a/test/integration/targets/cnos_showrun/README.md b/test/integration/targets/cnos_showrun/README.md new file mode 100644 index 0000000000..c035161e26 --- /dev/null +++ b/test/integration/targets/cnos_showrun/README.md @@ -0,0 +1,96 @@ +# Ansible Role: cnos_showrun_sample - Displays Running Configuration inforamtion +--- +<add role description below> + +This role is an example of using the *cnos_showrun.py* Lenovo module in the context of CNOS switch configuration. This module allows you to view the switch information. It executes the **display running-config** CLI command on a switch and returns a file containing all the system information of the target network device. + +The results of the operation can be viewed in results directory. + +For more details, see [Lenovo modules for Ansible: cnos_showrun](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_showrun.html&cp=0_3_1_0_4_0). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_showrun.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_showrun_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The hosts file for the role is located in the main directory of the role. + +``` +[cnos_showrun_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_showrun_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do Show Sys Info + hosts: cnos_showrun_sample + gather_facts: no + connection: local + roles: + - cnos_showrun_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_showrun/aliases b/test/integration/targets/cnos_showrun/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_showrun/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_showrun/cnos_showrun_sample_hosts b/test/integration/targets/cnos_showrun/cnos_showrun_sample_hosts new file mode 100644 index 0000000000..b06c4c9567 --- /dev/null +++ b/test/integration/targets/cnos_showrun/cnos_showrun_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_facts_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_showrun_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_showrun/tasks/main.yml b/test/integration/targets/cnos_showrun/tasks/main.yml new file mode 100644 index 0000000000..b4d94d9ee6 --- /dev/null +++ b/test/integration/targets/cnos_showrun/tasks/main.yml @@ -0,0 +1,6 @@ +# This contain sample show rnunning config tasks +--- +- name: Test Running Configurations + cnos_showrun: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} enablePassword='{{item.enablePassword}}' outputfile=./results/cnos_showrun_{{ inventory_hostname }}_output.txt + with_items: "{{test_showrun_data}}" +# Completed file diff --git a/test/integration/targets/cnos_showrun/vars/main.yml b/test/integration/targets/cnos_showrun/vars/main.yml new file mode 100644 index 0000000000..892e75c5fb --- /dev/null +++ b/test/integration/targets/cnos_showrun/vars/main.yml @@ -0,0 +1,3 @@ +--- +test_showrun_data: + - {enablePassword: "anil"} diff --git a/test/integration/targets/cnos_template/README.md b/test/integration/targets/cnos_template/README.md new file mode 100644 index 0000000000..4e02756531 --- /dev/null +++ b/test/integration/targets/cnos_template/README.md @@ -0,0 +1,112 @@ +# Ansible Role: cnos_template_sample - Manages switch configuration using templates +--- +<add role description below> + +This role is an example of using the *cnos_template.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with the running configuration of a switch. It provides a way to execute a set of CNOS commands on a switch by evaluating the current running configuration and executing the commands only if the specific settings have not been already configured. + +The configuration source can be a set of commands or a template written in the Jinja2 templating language.# + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_template](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_template.html&cp=0_3_1_0_4_10). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up(**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`commandfile` | Specifies the path to the CNOS command file which needs to be applied + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_template.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_template_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_template_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_template_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some template configurations + hosts: cnos_template_sample + gather_facts: no + connection: local + roles: + - cnos_template_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_template/aliases b/test/integration/targets/cnos_template/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_template/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_template/cnos_template_sample_hosts b/test/integration/targets/cnos_template/cnos_template_sample_hosts new file mode 100644 index 0000000000..73001984c2 --- /dev/null +++ b/test/integration/targets/cnos_template/cnos_template_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_template_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_template_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_template/tasks/main.yml b/test/integration/targets/cnos_template/tasks/main.yml new file mode 100644 index 0000000000..cad5818914 --- /dev/null +++ b/test/integration/targets/cnos_template/tasks/main.yml @@ -0,0 +1,13 @@ +# This contain sample template execution tasks +--- +- name: Creates directory + file: path=./commands state=directory + +- name: Replace Config CLI command template with values + template: src=demo_template.j2 dest=./commands/cnos_template_{{ inventory_hostname }}_commands.txt + with_items: "{{cnos_template_data}}" + +- name: Applying CLI commands on Switches + cnos_template: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} commandfile=./commands/cnos_template_{{ inventory_hostname }}_commands.txt outputfile=./results/cnos_template_{{ inventory_hostname }}_output.txt + with_items: "{{cnos_template_data}}" +# Completed file diff --git a/test/integration/targets/cnos_template/templates/demo_template.j2 b/test/integration/targets/cnos_template/templates/demo_template.j2 new file mode 100644 index 0000000000..c9b8ca8386 --- /dev/null +++ b/test/integration/targets/cnos_template/templates/demo_template.j2 @@ -0,0 +1,16 @@ +#Demo Template +vlan {{item.vlanid1}} +name anil +exit +#config d +interface ethernet {{item.slot_chassis_number1}} +#aggregation-group {{item.portchannel_interface_number1}} mode {{item.portchannel_mode1}} +description anil +mtu 600 +exit +#config d +interface port-aggregation {{item.portchannel_interface_number1}} +shut +lacp suspend-individual +no shut +exit diff --git a/test/integration/targets/cnos_template/vars/main.yml b/test/integration/targets/cnos_template/vars/main.yml new file mode 100644 index 0000000000..51223679f9 --- /dev/null +++ b/test/integration/targets/cnos_template/vars/main.yml @@ -0,0 +1,3 @@ +--- +cnos_template_data: + - {vlanid1: 13, slot_chassis_number1: "1/2", portchannel_interface_number1: 100, portchannel_mode1: "active"} diff --git a/test/integration/targets/cnos_vlag/README.md b/test/integration/targets/cnos_vlag/README.md new file mode 100644 index 0000000000..0ad57abc85 --- /dev/null +++ b/test/integration/targets/cnos_vlag/README.md @@ -0,0 +1,115 @@ +# Ansible Role: cnos_vlag_sample - Switch vLAG configuration +--- +<add role description below> + +This role is an example of using the *cnos_vlag.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with virtual Link Aggregation Groups (vLAG) related configurations. The operators used are overloaded to ensure control over switch vLAG configurations. + +Apart from the regular device connection related attributes, there are four vLAG arguments which are overloaded variables that will perform further configurations. They are *vlagArg1*, *vlagArg2*, *vlagArg3*, and *vlagArg4*. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_vlag](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_vlag.html&cp=0_3_1_0_4_15). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`vlagArg1` | This is an overloaded BGP variable. Please refer to the [cnos_vlag module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_template.html?cp=0_3_1_0_2_10) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **enable**, **auto-recovery**, **config-consistency**, **isl**, **mac-address-table**, **peer-gateway**, **priority**, **startup-delay**, **tier-id**, **vrrp**, **instance**, **hlthchk**. +`vlagArg2` | This is an overloaded BGP variable. Please refer to the [cnos_vlag module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_template.html?cp=0_3_1_0_2_10) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: auto-recovery interval, **disabled**, **strict**, port aggregation number, vLAG priority, delay time, vLAG tier ID value, vLAG instance number, **keepalive-attempts**, **keepalive-interval**, **retry-interval**, **peer-ip**. +`vlagArg3` | This is an overloaded BGP variable. Please refer to the [cnos_vlag module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_template.html?cp=0_3_1_0_2_10) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **enable**, **port-aggregation**, number of Keep Alive attempts, Keep Alive interval, retry interval, vLAG Health Check peer IP address. +`vlagArg4` | This is an overloaded BGP variable. Please refer to the [cnos_vlag module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_template.html?cp=0_3_1_0_2_10) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: LAG Number, **default**, **management**. + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_vlag.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_vlag_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_vlag_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_vlag_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do VLAG configurations + hosts: cnos_vlag_sample + gather_facts: no + connection: local + roles: + - cnos_vlag_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_vlag/aliases b/test/integration/targets/cnos_vlag/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_vlag/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_vlag/cnos_vlag_sample_hosts b/test/integration/targets/cnos_vlag/cnos_vlag_sample_hosts new file mode 100644 index 0000000000..b24afe6ac6 --- /dev/null +++ b/test/integration/targets/cnos_vlag/cnos_vlag_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_vlag_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_vlag_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_vlag/tasks/main.yml b/test/integration/targets/cnos_vlag/tasks/main.yml new file mode 100644 index 0000000000..75a59ec3dd --- /dev/null +++ b/test/integration/targets/cnos_vlag/tasks/main.yml @@ -0,0 +1,51 @@ +# This contain sample template execution tasks +--- +- name: Test Vlag - enable + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' + with_items: "{{test_vlag_data1}}" +- name: Test Vlag - autorecovery + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data2}}" +- name: Test Vlag - config-consistency + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data3}}" +- name: Test Vlag - isl + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data4}}" +- name: Test Vlag - mac-address-table + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' + with_items: "{{test_vlag_data5}}" +- name: Test Vlag - peer-gateway + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' + with_items: "{{test_vlag_data6}}" +- name: Test Vlag - priority + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data7}}" +- name: Test Vlag - startup-delay + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data8}}" +- name: Test Vlag - tier-id + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data9}}" +- name: Test Vlag - vrrp + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' + with_items: "{{test_vlag_data10}}" +- name: Test Vlag - instance + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' vlagArg3='{{item.vlagArg3}}' + with_items: "{{test_vlag_data11}}" +- name: Test Vlag - instance2 + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' + with_items: "{{test_vlag_data12}}" +- name: Test Vlag - keepalive-attempts + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' vlagArg3='{{item.vlagArg3}}' + with_items: "{{test_vlag_data13}}" +- name: Test Vlag - keepalive-interval + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' vlagArg3='{{item.vlagArg3}}' + with_items: "{{test_vlag_data14}}" +- name: Test Vlag - retry-interval + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' vlagArg3='{{item.vlagArg3}}' + with_items: "{{test_vlag_data15}}" +- name: Test Vlag - peer ip + cnos_vlag: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlag_{{ inventory_hostname }}_output.txt vlagArg1='{{item.vlagArg1}}' vlagArg2='{{item.vlagArg2}}' vlagArg3='{{item.vlagArg3}}' + with_items: "{{test_vlag_data16}}" +# Completed file
\ No newline at end of file diff --git a/test/integration/targets/cnos_vlag/vars/main.yml b/test/integration/targets/cnos_vlag/vars/main.yml new file mode 100644 index 0000000000..e44a6758b8 --- /dev/null +++ b/test/integration/targets/cnos_vlag/vars/main.yml @@ -0,0 +1,33 @@ +--- +test_vlag_data1: + - {vlagArg1: "enable"} +test_vlag_data2: + - {vlagArg1: "auto-recovery", vlagArg2: 266} +test_vlag_data3: + - {vlagArg1: "config-consistency", vlagArg2: "strict"} +test_vlag_data4: + - {vlagArg1: "isl", vlagArg2: 33} +test_vlag_data5: + - {vlagArg1: "mac-address-table"} +test_vlag_data6: + - {vlagArg1: "peer-gateway"} +test_vlag_data7: + - {vlagArg1: "priority", vlagArg2: 1313} +test_vlag_data8: + - {vlagArg1: "startup-delay", vlagArg2: 323} +test_vlag_data9: + - {vlagArg1: "tier-id", vlagArg2: 313} +test_vlag_data10: + - {vlagArg1: "vrrp"} +test_vlag_data11: + - {vlagArg1: "instance", vlagArg2: 33, vlagArg3: 333} +test_vlag_data12: + - {vlagArg1: "instance", vlagArg2: "33"} +test_vlag_data13: + - {vlagArg1: "hlthchk", vlagArg2: "keepalive-attempts", vlagArg3: 13} +test_vlag_data14: + - {vlagArg1: "hlthchk", vlagArg2: "keepalive-interval", vlagArg3: 131} +test_vlag_data15: + - {vlagArg1: "hlthchk", vlagArg2: "retry-interval", vlagArg3: 133} +test_vlag_data16: + - {vlagArg1: "hlthchk", vlagArg2: "peer-ip", vlagArg3: "1.2.3.4"} diff --git a/test/integration/targets/cnos_vlan/README.md b/test/integration/targets/cnos_vlan/README.md new file mode 100644 index 0000000000..640b6992a2 --- /dev/null +++ b/test/integration/targets/cnos_vlan/README.md @@ -0,0 +1,116 @@ +# Ansible Role: cnos_vlan_sample - Switch VLAN configuration +--- +<add role description below> + +This role is an example of using the *cnos_vlan.py* Lenovo module in the context of CNOS switch configuration. This module allows you to work with VLAN related configurations. The operators used are overloaded to ensure control over switch VLAN configurations. + +The first level of VLAN configuration allows to set up the VLAN range, the VLAN tag persistence, a VLAN access map and access map filter. After passing this level, there are five VLAN arguments that will perform further configurations. They are *vlanArg1*, *vlanArg2*, *vlanArg3*, *vlanArg4*, and *vlanArg5*. The value of *vlanArg1* will determine the way following arguments will be evaluated. + +The results of the operation can be viewed in *results* directory. + +For more details, see [Lenovo modules for Ansible: cnos_vlan](http://systemx.lenovofiles.com/help/index.jsp?topic=%2Fcom.lenovo.switchmgt.ansible.doc%2Fcnos_vlan.html&cp=0_3_1_0_4_14). + + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.2 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running CNOS version 10.2.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> + +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `cnos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch +`enablePassword` | Configures the password used to enter Global Configuration command mode on the switch (this is an optional parameter) +`hostname` | Searches the hosts file at */etc/ansible/hosts* and identifies the IP address of the switch on which the role is going to be applied +`deviceType` | Specifies the type of device from where the configuration will be backed up (**g8272_cnos** - G8272, **g8296_cnos** - G8296, **g8332_cnos** - G8332, **NE10032** - NE10032, **NE1072T** - NE1072T, **NE1032** - NE1032, **NE1032T** - NE1032T, **NE2572** - NE2572) + +The values of the variables used need to be modified to fit the specific scenario in which you are deploying the solution. To change the values of the variables, you need to visits the *vars* directory of each role and edit the *main.yml* file located there. The values stored in this file will be used by Ansible when the template is executed. + +The syntax of *main.yml* file for variables is the following: + +``` +<template variable>:<value> +``` + +You will need to replace the `<value>` field with the value that suits your topology. The `<template variable>` fields are taken from the template and it is recommended that you leave them unchanged. + +Variable | Description +--- | --- +`vlanArg1` | This is an overloaded BGP variable. Please refer to the [cnos_vlan module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_vlan.html?cp=0_3_1_0_2_16) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **access-map**, **dot1q**, **filter**, specify VLAN. +`vlanArg2` | This is an overloaded BGP variable. Please refer to the [cnos_vlan module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_vlan.html?cp=0_3_1_0_2_16) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: VLAN access map name, **egress-only**, **name**, **flood**, **state**, **ip**. +`vlanArg3` | This is an overloaded BGP variable. Please refer to the [cnos_vlan module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_vlan.html?cp=0_3_1_0_2_16) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **action**, **match**, **statistics**, specify VLAN, name of the VLAN, **ipv4**, **ipv6**, **active**, **suspend**, **fast-leave**, **last-member-query-interval**, **mrouter**, **querier**, **querier-timeout**, **query-interval**, **query-max-response-time**, **report-suppression**, **robustness-variable**, **startup-query-count**, **startup-query-interval**. +`vlanArg4` | This is an overloaded BGP variable. Please refer to the [cnos_vlan module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_vlan.html?cp=0_3_1_0_2_16) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: **drop**, **forward**, **redirect**, **ip**, **mac**, last member query interval, **ethernet**, **port-aggregation**, querier IP address, querier timeout interval, query interval, query maximum response interval, robustness variable value, numbers of queries sent at startup, startup query interval. +`vlanArg5` | This is an overloaded BGP variable. Please refer to the [cnos_vlan module documentation](http://ralfss28.labs.lenovo.com:5555/help/topic/com.lenovo.switchmgt.ansible.doc/cnos_vlan.html?cp=0_3_1_0_2_16) for detailed information on usage. The values of these variables depend on the configuration context and the choices are the following: ACL name, specify ethernet port, LAG number. + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- cnos_vlan.py - This modules needs to be present in the *library* directory of the role. +- cnos.py - This module needs to be present in the PYTHONPATH environment variable set in the Ansible system. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_vlan_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[cnos_vlan_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +10.241.107.40 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook cnos_vlan_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do VLAN configurations + hosts: cnos_vlan_sample + gather_facts: no + connection: local + roles: + - cnos_vlan_sample +``` + + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file diff --git a/test/integration/targets/cnos_vlan/aliases b/test/integration/targets/cnos_vlan/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/cnos_vlan/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/cnos_vlan/cnos_vlan_sample_hosts b/test/integration/targets/cnos_vlan/cnos_vlan_sample_hosts new file mode 100644 index 0000000000..18f9d301dd --- /dev/null +++ b/test/integration/targets/cnos_vlan/cnos_vlan_sample_hosts @@ -0,0 +1,14 @@ +# You have to paste this dummy information in /etc/ansible/hosts +# Notes: +# - Comments begin with the '#' character +# - Blank lines are ignored +# - Groups of hosts are delimited by [header] elements +# - You can enter hostnames or ip addresses +# - A hostname/ip can be a member of multiple groups +# +# In the /etc/ansible/hosts file u have to enter [cnos_vlan_sample] tag +# Following you should specify IP Adresses details +# Please change <username> and <password> with appropriate value for your switch. + +[cnos_vlan_sample] +10.241.107.39 ansible_network_os=cnos ansible_ssh_user=<username> ansible_ssh_pass=<password> deviceType=g8272_cnos diff --git a/test/integration/targets/cnos_vlan/tasks/main.yml b/test/integration/targets/cnos_vlan/tasks/main.yml new file mode 100644 index 0000000000..f4a4138b5b --- /dev/null +++ b/test/integration/targets/cnos_vlan/tasks/main.yml @@ -0,0 +1,35 @@ +# This contain sample template execution task +--- +- name: Test Vlan - Create a vlan, name it + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' + with_items: "{{cnos_vlan_data1}}" + +- name: Test Vlan - Create a vlan, Flood configuration + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' + with_items: "{{cnos_vlan_data2}}" + +- name: Test Vlan - Create a vlan, State configuration + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' + with_items: "{{cnos_vlan_data3}}" + +- name: Test Vlan - VLAN Access map1 + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' + with_items: "{{cnos_vlan_data4}}" + +- name: Test Vlan - VLAN Accep Map2 + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' vlanArg4='{{item.vlanArg4}}' + with_items: "{{cnos_vlan_data5}}" + +- name: Test Vlan - ip igmp snooping query interval + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' vlanArg4='{{item.vlanArg4}}' + with_items: "{{cnos_vlan_data6}}" + +- name: Test Vlan - ip igmp snooping last member query interval + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' vlanArg4='{{item.vlanArg4}}' + with_items: "{{cnos_vlan_data7}}" + +- name: Test Vlan - ip igmp snooping mrouter interface port-aggregation + cnos_vlan: host={{ inventory_hostname }} username={{ hostvars[inventory_hostname]['ansible_ssh_user']}} password={{ hostvars[inventory_hostname]['ansible_ssh_pass']}} deviceType={{ hostvars[inventory_hostname]['deviceType']}} outputfile=./results/cnos_vlan_{{ inventory_hostname }}_output.txt vlanArg1='{{item.vlanArg1}}' vlanArg2='{{item.vlanArg2}}' vlanArg3='{{item.vlanArg3}}' vlanArg4='{{item.vlanArg4}}' vlanArg5='{{item.vlanArg5}}' + with_items: "{{cnos_vlan_data8}}" + +# Completed file diff --git a/test/integration/targets/cnos_vlan/vars/main.yml b/test/integration/targets/cnos_vlan/vars/main.yml new file mode 100644 index 0000000000..3ac98a7cb7 --- /dev/null +++ b/test/integration/targets/cnos_vlan/vars/main.yml @@ -0,0 +1,19 @@ +--- +cnos_vlan_data1: + - {vlanArg1: 13, vlanArg2: "name", vlanArg3: "anil"} +cnos_vlan_data2: + - {vlanArg1: 13, vlanArg2: "flood", vlanArg3: "ipv4"} +cnos_vlan_data3: + - {vlanArg1: 13, vlanArg2: "state", vlanArg3: "active"} +cnos_vlan_data4: + - {vlanArg1: "access-map", vlanArg2: "anil", vlanArg3: "statistics"} +cnos_vlan_data5: + - {vlanArg1: "access-map", vlanArg2: "anil", vlanArg3: "action", vlanArg4: "forward"} +cnos_vlan_data6: + - {vlanArg1: 13, vlanArg2: "ip", vlanArg3: "query-interval", vlanArg4: 1313} +cnos_vlan_data7: + - {vlanArg1: 13, vlanArg2: "ip", vlanArg3: "last-member-query-interval", vlanArg4: 23} +cnos_vlan_data8: + - {vlanArg1: 13, vlanArg2: "ip", vlanArg3: "mrouter", vlanArg4: "port-aggregation", vlanArg5: 23} +cnos_vlan_data9: + - {clicommand: "no vlan 13"} diff --git a/test/integration/targets/enos_command/README.md b/test/integration/targets/enos_command/README.md new file mode 100644 index 0000000000..bd23d22d40 --- /dev/null +++ b/test/integration/targets/enos_command/README.md @@ -0,0 +1,115 @@ +# Ansible Role: enos_command - Exceutes any CLI command on switch and results are displayed. +--- +<add role description below> + + Sends arbitrary commands to an ENOS node and returns the results + read from the device. The C(enos_command) module includes an + argument that will cause the module to wait for a specific condition + before returning or timing out if the condition is not met. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.4 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running ENOS version 8.4.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `enos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +These are the various options the customer have in executing the enos_command modules: + +Variable | Description +--- | --- +`commands` | List of commands to send to the remote device over the configured provider. The resulting output from the command is returned. If the I(wait_for) argument is provided, the module is not returned until the condition is satisfied or the number of retires as expired. +`wait_for` | List of conditions to evaluate against the output of the command. The task will wait for each condition to be true before moving forward. If the conditional is not true within the configured number of retries, the task fails. See examples. +`match` | The I(match) argument is used in conjunction with the I(wait_for) argument to specify the match policy. Valid values are C(all) or C(any). If the value is set to C(all) then all conditionals in the wait_for must be satisfied. If the value is set to C(any) then only one of the values must be satisfied. +`retries` | Specifies the number of retries a command should by tried before it is considered failed. The command is run on the target device every retry and evaluated against the I(wait_for) conditions. +`interval` | Configures the interval in seconds to wait between retries of the command. If the command does not pass the specified conditions, the interval indicates how long to wait before trying the command again. + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- enos_command.py - This module file will be located at lib/ansible/modules/network/enos/ of Ansible installation. +- enos.py - This module util file will be located at lib/ansible/module_utils/network/enos of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[enos_command] +10.241.105.24 ansible_connection=network_cli ansible_network_os=enos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook enos_command_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: enos_command + gather_facts: no + connection: network_cli + roles: + - enos_command +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, eithe +r version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PU +RPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/enos_command/aliases b/test/integration/targets/enos_command/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/enos_command/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/enos_command/defaults/main.yaml b/test/integration/targets/enos_command/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/enos_command/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/enos_command/tasks/cli.yaml b/test/integration/targets/enos_command/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/enos_command/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/enos_command/tasks/main.yaml b/test/integration/targets/enos_command/tasks/main.yaml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/enos_command/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/enos_command/tests/cli/bad_operator.yaml b/test/integration/targets/enos_command/tests/cli/bad_operator.yaml new file mode 100644 index 0000000000..e554b847d6 --- /dev/null +++ b/test/integration/targets/enos_command/tests/cli/bad_operator.yaml @@ -0,0 +1,20 @@ +--- +- debug: msg="START cli/bad_operator.yaml" + +- name: test bad operator + enos_command: + commands: + - show version + - show interface information + wait_for: + - result[0] contains 'Description: Foo' + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == true" + - "result.msg is defined" + +- debug: msg="END cli/bad_operator.yaml" diff --git a/test/integration/targets/enos_command/tests/cli/contains.yaml b/test/integration/targets/enos_command/tests/cli/contains.yaml new file mode 100644 index 0000000000..c9615d3cbf --- /dev/null +++ b/test/integration/targets/enos_command/tests/cli/contains.yaml @@ -0,0 +1,20 @@ +--- +- debug: msg="START cli/contains.yaml" + +- name: test contains operator + enos_command: + commands: + - show version + - show system memory + wait_for: + - "result[0] contains 'Lenovo'" + - "result[1] contains 'MemFree'" + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + +- debug: msg="END cli/contains.yaml" diff --git a/test/integration/targets/enos_command/tests/cli/invalid.yaml b/test/integration/targets/enos_command/tests/cli/invalid.yaml new file mode 100644 index 0000000000..1276c7c369 --- /dev/null +++ b/test/integration/targets/enos_command/tests/cli/invalid.yaml @@ -0,0 +1,29 @@ +--- +- debug: msg="START cli/invalid.yaml" + +- name: run invalid command + enos_command: + commands: ['show foo'] + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed" + +- name: run commands that include invalid command + enos_command: + commands: + - show version + - show foo + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed" + ignore_errors: true + +- debug: msg="END cli/invalid.yaml" diff --git a/test/integration/targets/enos_command/tests/cli/output.yaml b/test/integration/targets/enos_command/tests/cli/output.yaml new file mode 100644 index 0000000000..e3e3565cb0 --- /dev/null +++ b/test/integration/targets/enos_command/tests/cli/output.yaml @@ -0,0 +1,29 @@ +--- +- debug: msg="START cli/output.yaml" + +- name: get output for single command + enos_command: + commands: ['show version'] + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + +- name: get output for multiple commands + enos_command: + commands: + - show version + - show interface information + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.stdout is defined" + - "result.stdout | length == 2" + +- debug: msg="END cli/output.yaml" diff --git a/test/integration/targets/enos_command/tests/cli/timeout.yaml b/test/integration/targets/enos_command/tests/cli/timeout.yaml new file mode 100644 index 0000000000..e60bd18d92 --- /dev/null +++ b/test/integration/targets/enos_command/tests/cli/timeout.yaml @@ -0,0 +1,19 @@ +--- +- debug: msg="START cli/timeout.yaml" + +- name: test bad condition + enos_command: + commands: + - show version + wait_for: + - "result[0] contains bad_value_string" + provider: "{{ cli }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == true" + - "result.msg is defined" + +- debug: msg="END cli/timeout.yaml" diff --git a/test/integration/targets/enos_command/vars/main.yaml b/test/integration/targets/enos_command/vars/main.yaml new file mode 100644 index 0000000000..bdcdfd88e7 --- /dev/null +++ b/test/integration/targets/enos_command/vars/main.yaml @@ -0,0 +1,13 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin +# transport: cli + timeout: 30 + authorize: True + auth_pass: + +enos_command_data: + - {} diff --git a/test/integration/targets/enos_config/README.md b/test/integration/targets/enos_config/README.md new file mode 100644 index 0000000000..3746157a78 --- /dev/null +++ b/test/integration/targets/enos_config/README.md @@ -0,0 +1,123 @@ +# Ansible Role: enos_config - Exceutes any Configuration command on switch and results are displayed. +--- +<add role description below> + + Lenovo ENOS configurations use a simple block indent file syntax + for segmenting configuration into sections. This module provides + an implementation for working with ENOS configuration sections in + a deterministic way. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.4 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running ENOS version 8.4.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `enos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +These are the various options the customer have in executing the enos_config modules: + +Variable | Description +--- | --- +`lines` | The ordered set of commands that should be configured in the section. The commands must be the exact same commands as found in the device running-config. Be sure to note the configuration command syntax as some commands are automatically modified by the device config parser. +`parents` | The ordered set of parents that uniquely identify the section the commands should be checked against. If the parents argument is omitted, the commands are checked against the set of top level or global commands. +`src` | Specifies the source path to the file that contains the configuration or configuration template to load. The path to the source file can either be the full path on the Ansible control host or a relative path from the playbook or role root directory. This argument is mutually exclusive with I(lines), I(parents). +`before` | The ordered set of commands to push on to the command stack if a change needs to be made. This allows the playbook designer the opportunity to perform configuration commands prior to pushing any changes without affecting how the set of commands are matched against the system. +`after` | The ordered set of commands to append to the end of the command stack if a change needs to be made. Just like with I(before) this allows the playbook designer to append a set of commands to be executed after the command set. +`replace` | Instructs the module on the way to perform the configuration on the device. If the replace argument is set to I(line) then the modified lines are pushed to the device in configuration mode. If the replace argument is set to I(block) then the entire command block is pushed to the device in configuration mode if any line is not correct. +`config` | The module, by default, will connect to the remote device and retrieve the current running-config to use as a base for comparing against the contents of source. There are times when it is not desirable to have the task get the current running-config for every task in a playbook. The I(config) argument allows the implementer to pass in the configuration to use as the base config for comparison. +`backup` | This argument will cause the module to create a full backup of the current C(running-config) from the remote device before any changes are made. The backup file is written to the C(backup) folder in the playbook root directory. If the directory does not exist, it is created. +`match` |Instructs the module on the way to perform the matching of the set of commands against the current device config. If match is set to I(line), commands are matched line by line. If match is set to I(strict), command lines are matched with respect to position. If match is set to I(exact), command lines must be an equal match. Finally, if match is set to I(none), the module will not attempt to compare the source configuration with the running configuration on the remote device. +`comment` | Allows a commit description to be specified to be included when the configuration is committed. If the configuration is not changed or committed, this argument is ignored. +`admin` | Enters into administration configuration mode for making config changes to the device. + + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- enos_config.py - This module file will be located at lib/ansible/modules/network/enos/ of Ansible installation. +- enos.py - This module util file will be located at lib/ansible/module_utils/network/enos of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- enos_config.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *cnos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[enos_config] +10.241.105.24 ansible_connection=network_cli ansible_network_os=enos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook enos_config_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: enos_config + gather_facts: no + connection: network_cli + roles: + - enos_config +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, eithe +r version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PU +RPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/enos_config/aliases b/test/integration/targets/enos_config/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/enos_config/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/enos_config/defaults/main.yaml b/test/integration/targets/enos_config/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/enos_config/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/enos_config/tasks/cli.yaml b/test/integration/targets/enos_config/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/enos_config/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/enos_config/tasks/main.yaml b/test/integration/targets/enos_config/tasks/main.yaml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/enos_config/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/enos_config/templates/basic/config.j2 b/test/integration/targets/enos_config/templates/basic/config.j2 new file mode 100644 index 0000000000..c837f60fae --- /dev/null +++ b/test/integration/targets/enos_config/templates/basic/config.j2 @@ -0,0 +1,4 @@ +vlan 13 + name anil + optflood + stg 13 diff --git a/test/integration/targets/enos_config/templates/defaults/config.j2 b/test/integration/targets/enos_config/templates/defaults/config.j2 new file mode 100644 index 0000000000..d4c04bb3ee --- /dev/null +++ b/test/integration/targets/enos_config/templates/defaults/config.j2 @@ -0,0 +1,2 @@ +vlan 13 + name anil diff --git a/test/integration/targets/enos_config/tests/cli/backup.yaml b/test/integration/targets/enos_config/tests/cli/backup.yaml new file mode 100644 index 0000000000..09f7e7b11a --- /dev/null +++ b/test/integration/targets/enos_config/tests/cli/backup.yaml @@ -0,0 +1,52 @@ +--- +- debug: msg="START cli/backup.yaml" + +- name: setup + enos_config: + commands: + - no vlan 13 + provider: "{{ cli }}" + ignore_errors: yes + +- name: collect any backup files + find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + delegate_to: localhost + +- name: delete backup files + file: + path: "{{ item.path }}" + state: absent + with_items: "{{backup_files.files|default([])}}" + +- name: configure device with config + enos_config: + src: roles/enos_config/templates/basic/config.j2 + backup: yes + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + +- name: collect any backup files + find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + delegate_to: localhost + +- assert: + that: + - "backup_files.files is defined" + +- name: teardown + enos_config: + commands: + - no vlan 13 + provider: "{{ cli }}" + +- debug: msg="END cli/backup.yaml" diff --git a/test/integration/targets/enos_config/tests/cli/basic.yaml b/test/integration/targets/enos_config/tests/cli/basic.yaml new file mode 100644 index 0000000000..c0d5e1cc22 --- /dev/null +++ b/test/integration/targets/enos_config/tests/cli/basic.yaml @@ -0,0 +1,39 @@ +--- +- debug: msg="START cli/basic.yaml" + +- name: setup + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + ignore_errors: yes + +- name: configure device with config + enos_config: + src: roles/enos_config/templates/basic/config.j2 + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: check device with config + enos_config: + src: roles/enos_config/templates/basic/config.j2 + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: teardown + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + +- debug: msg="END cli/basic.yaml" diff --git a/test/integration/targets/enos_config/tests/cli/defaults.yaml b/test/integration/targets/enos_config/tests/cli/defaults.yaml new file mode 100644 index 0000000000..ef2cbcd981 --- /dev/null +++ b/test/integration/targets/enos_config/tests/cli/defaults.yaml @@ -0,0 +1,50 @@ +--- +- debug: msg="START cli/defaults.yaml" + +- name: setup + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + ignore_errors: yes + become: True + become_method: enable + +- name: configure device with defaults included + enos_config: + src: roles/enos_config/templates/defaults/config.j2 + provider: "{{ cli }}" + register: result + become: True + become_method: enable + +- debug: var=result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: check device with defaults included Hell + enos_config: + src: roles/enos_config/templates/defaults/config.j2 + provider: "{{ cli }}" + register: result + +- debug: var=result + +- assert: + that: + - "result.changed == false" + - "result.updates is not defined" + +- name: teardown + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + become: true + become_method: enable + ignore_errors: yes + +- debug: msg="END cli/defaults.yaml" diff --git a/test/integration/targets/enos_config/tests/cli/force.yaml b/test/integration/targets/enos_config/tests/cli/force.yaml new file mode 100644 index 0000000000..db48a23809 --- /dev/null +++ b/test/integration/targets/enos_config/tests/cli/force.yaml @@ -0,0 +1,41 @@ +--- +- debug: msg="START cli/force.yaml" + +- name: setup + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + ignore_errors: yes + +- name: configure device with config + enos_config: + src: roles/enos_config/templates/basic/config.j2 + provider: "{{ cli }}" + match: none + register: result + +- assert: + that: + - "result.changed == true" + - "result.updates is defined" + +- name: check device with config + enos_config: + src: roles/enos_config/templates/basic/config.j2 + provider: "{{ cli }}" + match: none + register: result + +- assert: + that: + - "result.changed == true" + - "result.updates is defined" + +- name: teardown + enos_config: + commands: + - no vlan 13\n + provider: "{{ cli }}" + +- debug: msg="END cli/force.yaml" diff --git a/test/integration/targets/enos_config/vars/main.yml b/test/integration/targets/enos_config/vars/main.yml new file mode 100644 index 0000000000..d0fcdabf53 --- /dev/null +++ b/test/integration/targets/enos_config/vars/main.yml @@ -0,0 +1,9 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin + timeout: 60 + context: ansible + auth_pass: diff --git a/test/integration/targets/enos_facts/README.md b/test/integration/targets/enos_facts/README.md new file mode 100644 index 0000000000..24b2e1067f --- /dev/null +++ b/test/integration/targets/enos_facts/README.md @@ -0,0 +1,111 @@ +# Ansible Role: enos_facts - Displays switch inforamtion +--- +<add role description below> + + Collects a base set of device facts from a remote Lenovo device + running on ENOS. This module prepends all of the + base network fact keys with C(ansible_net_<fact>). The facts + module will always collect a base set of facts from the device + and can enable or disable collection of additional facts. + +## Requirements +--- +<add role requirements information below> + +- Ansible version 2.4 or later ([Ansible installation documentation](http://docs.ansible.com/ansible/intro_installation.html)) +- Lenovo switches running ENOS version 8.4.1.0 or later +- an SSH connection to the Lenovo switch (SSH must be enabled on the network device) + + +## Role Variables +--- +<add role variables information below> +Available variables are listed below, along with description. + +The following are mandatory inventory variables: + +Variable | Description +--- | --- +`ansible_connection` | Has to be `network_cli` +`ansible_network_os` | Has to be `enos` +`ansible_ssh_user` | Specifies the username used to log into the switch +`ansible_ssh_pass` | Specifies the password used to log into the switch + +To gather subsets you will specify the following variables to get appropriate +data retrived from the devices + +Variable | Description +--- | --- +`gather_subset` | When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument include all, hardware, config, and interfaces. Can specify a list of values to include a larger subset. Values can also be used with an initial C(M(!)) to specify that a specific subset should not be collected. + +Need to specify these variables in vars/main.yml under variable `cli` + +Variable | Description +--- | --- +`host` | Has to be "{{ inventory_hostname }}" +`port` | Has to be`22` +`username` | User Name of switch +`password` | Password of switch +`timeout` | time out value for CLI +`authorixe` | Whether u have to enter enable mode for data collection. +`auth_pass`| Enable Password if required + + +## Dependencies +--- +<add dependencies information below> + +- username.iptables - Configures the firewall and blocks all ports except those needed for web server and SSH access. +- username.common - Performs common server configuration. +- enos_facts.py - This module file will be located at lib/ansible/modules/network/enos/ of Ansible installation. +- enos.py - This module util file will be located at lib/ansible/module_utils/network/enos of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/action of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- enos.py - This module plugin file will be located at lib/ansible/plugins/cliconf of Ansible installation. +- /etc/ansible/hosts - You must edit the */etc/ansible/hosts* file with the device information of the switches designated as leaf switches. You may refer to *enos_command_sample_hosts* for a sample configuration. + +Ansible keeps track of all network elements that it manages through a hosts file. Before the execution of a playbook, the hosts file must be set up. + +Open the */etc/ansible/hosts* file with root privileges. Most of the file is commented out by using **#**. You can also comment out the entries you will be adding by using **#**. You need to copy the content of the hosts file for the role into the */etc/ansible/hosts* file. The sample hosts file for the role is located in the main directory. + +``` +[enos_facts] +10.241.105.24 ansible_connection=network_cli ansible_network_os=enos ansible_ssh_user=<username> ansible_ssh_pass=<password> +``` + +**Note:** You need to change the IP addresses to fit your specific topology. You also need to change the `<username>` and `<password>` to the appropriate values used to log into the specific Lenovo network devices. + + +## Example Playbook +--- +<add playbook samples below> + +To execute an Ansible playbook, use the following command: + +``` +ansible-playbook enos_facts_sample.yml -vvv +``` + +`-vvv` is an optional verbos command that helps identify what is happening during playbook execution. The playbook for each role is located in the main directory of the solution. + +``` + - name: Module to do some CLI Command configurations + hosts: enos_facts + gather_facts: no + connection: network_cli + roles: + - enos_facts +``` + +## License +--- +<add license information below> +Copyright (C) 2017 Lenovo, Inc. + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +Ansible is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Ansible. If not, see <http://www.gnu.org/licenses/>. diff --git a/test/integration/targets/enos_facts/aliases b/test/integration/targets/enos_facts/aliases new file mode 100644 index 0000000000..be010d923f --- /dev/null +++ b/test/integration/targets/enos_facts/aliases @@ -0,0 +1,2 @@ +# No Lenovo Switch simulator yet, so not enabled +unsupported diff --git a/test/integration/targets/enos_facts/defaults/main.yaml b/test/integration/targets/enos_facts/defaults/main.yaml new file mode 100644 index 0000000000..9ef5ba5165 --- /dev/null +++ b/test/integration/targets/enos_facts/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/test/integration/targets/enos_facts/tasks/cli.yaml b/test/integration/targets/enos_facts/tasks/cli.yaml new file mode 100644 index 0000000000..d675462dd0 --- /dev/null +++ b/test/integration/targets/enos_facts/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/enos_facts/tasks/main.yml b/test/integration/targets/enos_facts/tasks/main.yml new file mode 100644 index 0000000000..415c99d8b1 --- /dev/null +++ b/test/integration/targets/enos_facts/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/enos_facts/tests/cli/all_facts.yaml b/test/integration/targets/enos_facts/tests/cli/all_facts.yaml new file mode 100644 index 0000000000..836dad8bcd --- /dev/null +++ b/test/integration/targets/enos_facts/tests/cli/all_facts.yaml @@ -0,0 +1,27 @@ +--- +- debug: msg="START cli/all_facts.yaml" + +- name: test getting all facts + enos_facts: + gather_subset: + - all + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + #- "result.ansible_facts.ansible_net_filesystems is defined" + # Check that these facts not only are present, but are valid (positive integers) + - "result.ansible_facts.ansible_net_memfree_mb > 1" + - "result.ansible_facts.ansible_net_memtotal_mb > 1" + +- debug: msg="END cli/all_facts.yaml" diff --git a/test/integration/targets/enos_facts/tests/cli/default_facts.yaml b/test/integration/targets/enos_facts/tests/cli/default_facts.yaml new file mode 100644 index 0000000000..61549dc951 --- /dev/null +++ b/test/integration/targets/enos_facts/tests/cli/default_facts.yaml @@ -0,0 +1,29 @@ +--- +- debug: msg="START cli/default_facts.yaml" + +- name: test getting default facts + enos_facts: + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + #- "result.ansible_facts.ansible_net_filesystems is defined" + # ... and not present + - "'config' not in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + #- "result.ansible_facts.ansible_net_filesystems is defined" #hw + - "result.ansible_facts.ansible_net_memtotal_mb > 10" #hw + - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned + + # ... and not present + - "result.ansible_facts.ansible_net_config is not defined" # config + +- debug: msg="END cli/default.yaml" diff --git a/test/integration/targets/enos_facts/tests/cli/invalid_subset.yaml b/test/integration/targets/enos_facts/tests/cli/invalid_subset.yaml new file mode 100644 index 0000000000..0b12c6c85e --- /dev/null +++ b/test/integration/targets/enos_facts/tests/cli/invalid_subset.yaml @@ -0,0 +1,43 @@ +--- +- debug: msg="START cli/invalid_subset.yaml" + +- name: test invalid subset (foobar) + enos_facts: + gather_subset: + - "foobar" + register: result + ignore_errors: true + +- assert: + that: + # Failures shouldn't return changes + - "result.changed == false" + # It's a failure + - "result.failed == true" + # Sensible Failure message + - "result.msg == 'Bad subset'" + +############### +# FIXME Future +# We may in the future want to add a test for + +- name: test subset specified multiple times + enos_facts: + gather_subset: + - "!hardware" + - "hardware" + authorize: yes + register: result + ignore_errors: true + +- assert: + that: + # Failures shouldn't return changes + - "result.changed == false" + # It's a failure + - "result.failed == true" + # Sensible Failure message + - "result.msg == 'Bad subset'" + ignore_errors: true + +- debug: msg="END cli/invalid_subset.yaml" diff --git a/test/integration/targets/enos_facts/tests/cli/not_hardware.yaml b/test/integration/targets/enos_facts/tests/cli/not_hardware.yaml new file mode 100644 index 0000000000..a885c59b12 --- /dev/null +++ b/test/integration/targets/enos_facts/tests/cli/not_hardware.yaml @@ -0,0 +1,28 @@ +--- +- debug: msg="START cli/not_hardware_facts.yaml" + +- name: test not hardware + enos_facts: + gather_subset: + - "!hardware" + register: result + +- assert: + that: + # _facts modules should never report a change + - "result.changed == false" + + # Correct subsets are present + - "'config' in result.ansible_facts.ansible_net_gather_subset" + + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + # ... and not present + - "'hardware' not in result.ansible_facts.ansible_net_gather_subset" + + # Items from those subsets are present + - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned + # ... and not present + - "result.ansible_facts.ansible_net_filesystems is not defined" + +- debug: msg="END cli/not_hardware_facts.yaml" diff --git a/test/integration/targets/enos_facts/vars/main.yml b/test/integration/targets/enos_facts/vars/main.yml new file mode 100644 index 0000000000..aa25153ec8 --- /dev/null +++ b/test/integration/targets/enos_facts/vars/main.yml @@ -0,0 +1,9 @@ +--- +cli: + host: "{{ inventory_hostname }}" + port: 22 + username: admin + password: admin + timeout: 30 + authorize: True + auth_pass: |