Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions ansible/library/show_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/python

from ansible.module_utils.basic import *
import time
import re

DOCUMENTATION = '''
module: show_interface.py
version_added: 2.0.0.2
Short_description: Retrieve the show interface status and show interface counter output values
Description:
- Retrieve the show interface status and show interface counter output values
and inserted into ansible_facts

options:
- command:
Description: Show interface command( counter/status)
Required: True
- interfaces:
Description: Interfaces for which the facts to be gathered. By default It will gather facts for all interfaces
Required: False
'''

EXAMPLES = '''
# Get show interface status
- show_interface: comamnd='status'

# Get show interface status of interface Ethernet0
- show_interface: comamnd='status' interfaces='Ethernet0'

# Get show interface counter
- show_interface: comamnd='counter' interface='Ethernet4'

'''

RETURN = '''
ansible_facts:
int_status:{
"Ethernet0":{
"name": "Ethernet0"
"speed": "40G"
"alias": "fortyGigE1/1/1"
"oper_state": "down"
"admin_state": "up"
}
}
ansible_facts:
int_counter:{
"Ethernet0":{
'IFACE' : "Ethernet0"
'STATE' : "U"
'RX_OK' : "25000"
'RX_DRP' : "3456"
'RX_OVR' : "0"
'TX_OK' : "5843"
'TX_ERR' : "0"
'TX_DRP' : "0"
'TX_OVR' : "0"

'''


class ShowInterfaceModule(object):
def __init__(self):
self.module = AnsibleModule(
argument_spec=dict(
command=dict(required=True, type='str'),
interfaces=dict(required=False, type='list', default=None),
),
supports_check_mode=False)
self.m_args = self.module.params
self.out = None
self.facts = {}
return

def run(self):
"""
Main method of the class
"""
if self.m_args['command'] == 'status': self.collect_interface_status()
if self.m_args['command'] == 'counter': self.collect_interface_counter()
self.module.exit_json(ansible_facts=self.facts)

def collect_interface_status(self):
regex_int = re.compile(r'(\S+)\s+[\d,]+\s+(\w+)\s+(\d+)\s+([\w\/]+)\s+(\w+)\s+(\w+)')
self.int_status = {}
if self.m_args['interfaces'] is not None:
for interface in self.m_args['interfaces']:
self.int_status[interface] = {}
command = 'sudo show interface status ' + interface
try:
rc, self.out, err = self.module.run_command(command, executable='/bin/bash', use_unsafe_shell=True)
for line in self.out.split("\n"):
line = line.strip()
if regex_int.match(line):
self.int_status[interface]['name'] = regex_int.match(line).group(1)
self.int_status[interface]['speed'] = regex_int.match(line).group(2)
self.int_status[interface]['alias'] = regex_int.match(line).group(4)
self.int_status[interface]['oper_state'] = regex_int.match(line).group(5)
self.int_status[interface]['admin_state'] = regex_int.match(line).group(6)
self.facts['int_status'] = self.int_status
except Exception as e:
self.module.fail_json(msg=str(e))
if rc != 0:
self.module.fail_json(msg="Command failed rc=%d, out=%s, err=%s" % (rc, self.out, err))
else:
try:
rc, self.out, err = self.module.run_command('show interface status', executable='/bin/bash', use_unsafe_shell=True)
for line in self.out.split("\n"):
line = line.strip()
if regex_int.match(line):
interface = regex_int.match(line).group(1)
self.int_status[interface] = {}
self.int_status[interface]['name'] = interface
self.int_status[interface]['speed'] = regex_int.match(line).group(2)
self.int_status[interface]['alias'] = regex_int.match(line).group(4)
self.int_status[interface]['oper_state'] = regex_int.match(line).group(5)
self.int_status[interface]['admin_state'] = regex_int.match(line).group(6)
self.facts['int_status'] = self.int_status
except Exception as e:
self.module.fail_json(msg=str(e))
if rc != 0:
self.module.fail_json(msg="Command failed rc = %d, out = %s, err = %s" % (rc, self.out, err))

return

def collect_interface_counter(self):
regex_int = re.compile(r'(\S+)\s+(\w)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)')
self.int_counter = {}
try:
rc, self.out, err = self.module.run_command('show interface counter', executable='/bin/bash', use_unsafe_shell=True)
for line in self.out.split("\n"):
line = line.strip()
if regex_int.match(line):
interface = regex_int.match(line).group(1)
self.int_counter[interface] = {}
self.int_counter[interface]['IFACE'] = interface
self.int_counter[interface]['STATE'] = regex_int.match(line).group(2)
self.int_counter[interface]['RX_OK'] = regex_int.match(line).group(3)
self.int_counter[interface]['RX_BPS'] = regex_int.match(line).group(4)
self.int_counter[interface]['RX_UTIL'] = regex_int.match(line).group(5)
self.int_counter[interface]['RX_ERR'] = regex_int.match(line).group(6)
self.int_counter[interface]['RX_DRP'] = regex_int.match(line).group(7)
self.int_counter[interface]['RX_OVR'] = regex_int.match(line).group(8)
self.int_counter[interface]['TX_OK'] = regex_int.match(line).group(9)
self.int_counter[interface]['TX_BPS'] = regex_int.match(line).group(10)
self.int_counter[interface]['TX_UTIL'] = regex_int.match(line).group(11)
self.int_counter[interface]['TX_ERR'] = regex_int.match(line).group(12)
self.int_counter[interface]['TX_DRP'] = regex_int.match(line).group(13)
self.int_counter[interface]['TX_OVR'] = regex_int.match(line).group(14)
except Exception as e:
self.module.fail_json(msg=str(e))
if rc != 0:
self.module.fail_json(msg="Command failed rc=%d, out=%s, err=%s" % (rc, self.out, err))
self.facts['int_counter'] = self.int_counter
return


def main():
ShowInt = ShowInterfaceModule()
ShowInt.run()
return

if __name__ == "__main__":
main()

41 changes: 41 additions & 0 deletions ansible/roles/test/tasks/iface_naming_mode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Tests for interface_naming_mode feature
- include_vars: roles/test/tasks/iface_naming_mode/vars/iface_naming_vars.yml

- name: Gathering minigraph facts about the device
minigraph_facts: host={{inventory_hostname}}

- name: find interface name mapping
port_alias: hwsku="{{hwsku}}"

# Get the default interface names list
- set_fact:
default_interfaces: "{{port_name_map | list}}"

#Get the configured ports which are up from minigraph facts and get its alias name
- set_fact:
up_ports: "{{minigraph_ports | list}}"

- set_fact:
upport_alias_list: "{{minigraph_ports.values()| map(attribute='alias') | list }}"

#Sample Test interface name and its alias
- set_fact:
interface: "{{minigraph_ports | sort | first}}"
- set_fact:
interface_alias: "{{port_name_map[interface]}}"

#############################################################
######################## START OF TESTS #####################
#############################################################

# All tests run for user guest in alias mode as well as in default mode

- name: Test Interface naming mode feature in alias mode
include: "roles/test/tasks/iface_naming_mode/iface_naming_mode_tests.yml"
vars:
mode: alias

- name: Test Interface naming mode feature in default mode
include: "roles/test/tasks/iface_naming_mode/iface_naming_mode_tests.yml"
vars:
mode: default
9 changes: 9 additions & 0 deletions ansible/roles/test/tasks/iface_naming_mode/add_user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: create user
user:
name: "{{uname1}}"
groups: sudo
state: present
shell: /bin/bash

- name: Set password for user
shell: "echo {{uname1}}:{{upasswd1}} | sudo chpasswd"
25 changes: 25 additions & 0 deletions ansible/roles/test/tasks/iface_naming_mode/check_userifmode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#When the interface naming mode is set,it is written as environment variable in bashrc file.
#The device need to be logout and login for the actual environment variable to take effect.
# As the ansible work in non interactive mode, it doesnt read the environmental varaiable set in bashrc file. Hence as a workaround the variable is extracted through check_userifmode.yml and manually set the variable 'SONIC_CLI_IFACE_MODE' to take effect.


- name: Extract the "SONIC_CLI_IFACE_MODE" value from bashrc file
shell: "cat /home/{{uname1}}/.bashrc | grep SONIC_CLI_IFACE_MODE"
args:
executable: /bin/bash
register: envout

#extract the environmental variable and save it in the variable 'ifmode_env'
- set_fact:
ifmode_env: "{{envout.stdout}}"
- set_fact: ifmode="{{ifmode_env.split('=')[1]}}"

- debug: msg="Interface mode is set to '{{ifmode}}'"

- command: show interfaces naming_mode
register: naming_mode
environment:
SONIC_CLI_IFACE_MODE: "{{ifmode}}"

- name: check the interface mode is properly set to {{mode}}
assert: {that: "'{{ifmode}}'=='{{mode}}' and '{{naming_mode.stdout}}' == '{{mode}}'"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
- name: Create normal guest user
include: "roles/test/tasks/iface_naming_mode/add_user.yml"

- name: set interface naming mode to {{mode}} mode
shell : sudo config interface_naming_mode {{mode}}
register: out
failed_when: out.rc != 0
become_user: '{{uname1}}'
become: yes

# Check whether the interface mode is set properly in bashrc file
- include: roles/test/tasks/iface_naming_mode/check_userifmode.yml

- set_fact:
intf: "{{interface_alias if (mode=='alias') else interface}}"

#############################################################
######################## START OF TESTS #####################
#############################################################

# All tests run for user guest in alias mode as well as in default mode
#Below set of testcases will run for all topologies
- block:
- name: Test show pfc counters output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_pfc_counters.yml"

- name: Test show queue counters output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_queue_counters.yml"

- name: Test show interface status, counter,description,summary output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_interface.yml"

- name: Test config interface <Interface> in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/interface_config.yml"

become_user: '{{uname1}}'
become: yes

#Test to be run in T1 topology
- block:
- name: Test show arp output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_arp.yml"

- name: Test show acl output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_acl.yml"

- name: Test show ip/ipv6 route in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_ip_route.yml"

when: testbed_type in ['t1']
become_user: '{{uname1}}'
become: yes

# Test to be run in t0 topology
- block:

- name: verify show portchannel interface output in {{mode}} mode
include: "roles/test/tasks/iface_naming_mode/show_portchannel.yml"

become_user: '{{uname1}}'
become: yes
when: testbed_type in ['t0', 't0-64', 't0-64-32', 't0-116', ]

- always:

- name: Remove the user
user:
name: "{{uname1}}"
groups: sudo
state: absent
shell: /bin/bash
remove: yes
79 changes: 79 additions & 0 deletions ansible/roles/test/tasks/iface_naming_mode/interface_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

#set the test interface according to default or alias mode
- set_fact:
intf: "{{interface_alias if (mode=='alias') else interface}}"

- set_fact:
native_speed: "{{port_speed[interface_alias] if (port_speed | length != 0) else iface_speed}}"

- block:

- name: shutdown the interface {{intf}} in {{mode}} mode
shell: sudo config interface {{intf}} shutdown
register: out
failed_when: out.rc != 0

- pause: seconds=3

- name: Get interface status
show_interface: command="status" interfaces={{intf}}

- pause: seconds=3

- name: Check whether the status is down
assert: {that: "'{{int_status[intf]['admin_state']}}' == 'down'"}

- name: Bringup the interface {{intf}} in {{mode}} mode
shell: sudo config interface {{intf}} startup
register: out
failed_when: out.rc != 0

- pause: seconds=3

- name: Get interface status
show_interface: command="status" interfaces="{{intf}}"

- name: Check whether the status is up
assert: {that: "'{{int_status[intf]['admin_state']}}' == 'up'"}

# check the config interface speed

- name: configure interface speed to 10G in {{mode}} mode
shell: sudo config interface {{intf}} speed 10000
register: out
failed_when: out.rc != 0

- name: get the interface speed
shell: sudo redis-cli -n 4 HGET "PORT|{{interface}}" 'speed'
register: speed

- debug: var=speed

- name: Check whether the speed is set to 10G
assert: {that: "'{{speed.stdout}}' == '10000'"}

- name: chamge interface speed to native speed and check
shell: sudo config interface {{intf}} speed {{native_speed}}
register: out
failed_when: out.rc != 0

- name: get the interface speed
shell: sudo redis-cli -n 4 HGET "PORT|{{interface}}" 'speed'
register: speed

- name: Check whether the speed is set to native speed
assert: {that: "'{{speed.stdout}}' == '{{native_speed}}'"}

# As the ansible work in non interactive mode, it doesnt read the environmental varaiable set in bashrc file. Hence as a workaround , the variable is extracted through check_userifmode.yml and manually set the variable 'SONIC_CLI_IFACE_MODE' to take effect.

environment:
SONIC_CLI_IFACE_MODE: "{{ifmode}}"

always:

- name: set the interface up
shell: sudo config interface {{intf}} startup

- name: change interface speed to native speed and check
shell: sudo config interface {{intf}} speed {{native_speed}}

Loading