mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Lenovo cli bugfixes (#45278)
* To change all CLIs present in the code to latest CNOS CLI. One bug of executing with Lenovo Jakku switch is also getting fixed. * To change the file names as the commands have changed from display to show * To change to new CLI in test_cnos_comand.py as well
This commit is contained in:
parent
cbf2c2a000
commit
ac58c36ad0
16 changed files with 51 additions and 43 deletions
|
@ -68,33 +68,37 @@ options:
|
||||||
required: true
|
required: true
|
||||||
port:
|
port:
|
||||||
description:
|
description:
|
||||||
- Specifies the port to use when building the connection to the remote device.
|
- Specifies the port to use when building the connection to the
|
||||||
|
remote device.
|
||||||
default: 22
|
default: 22
|
||||||
username:
|
username:
|
||||||
description:
|
description:
|
||||||
- Configures the username to use to authenticate the connection to
|
- Configures the username to use to authenticate the connection to
|
||||||
the remote device. This value is used to authenticate
|
the remote device. This value is used to authenticate
|
||||||
the SSH session. If the value is not specified in the task, the
|
the SSH session. If the value is not specified in the task, the
|
||||||
value of environment variable C(ANSIBLE_NET_USERNAME) will be used instead.
|
value of environment variable C(ANSIBLE_NET_USERNAME) will be used
|
||||||
|
instead.
|
||||||
password:
|
password:
|
||||||
description:
|
description:
|
||||||
- Specifies the password to use to authenticate the connection to
|
- Specifies the password to use to authenticate the connection to
|
||||||
the remote device. This value is used to authenticate
|
the remote device. This value is used to authenticate
|
||||||
the SSH session. If the value is not specified in the task, the
|
the SSH session. If the value is not specified in the task, the
|
||||||
value of environment variable C(ANSIBLE_NET_PASSWORD) will be used instead.
|
value of environment variable C(ANSIBLE_NET_PASSWORD) will be used
|
||||||
|
instead.
|
||||||
timeout:
|
timeout:
|
||||||
description:
|
description:
|
||||||
- Specifies the timeout in seconds for communicating with the network device
|
- Specifies the timeout in seconds for communicating with the network
|
||||||
for either connecting or sending commands. If the timeout is
|
device for either connecting or sending commands. If the timeout
|
||||||
exceeded before the operation is completed, the module will error.
|
is exceeded before the operation is completed, the module will
|
||||||
|
error.
|
||||||
default: 10
|
default: 10
|
||||||
ssh_keyfile:
|
ssh_keyfile:
|
||||||
description:
|
description:
|
||||||
- Specifies the SSH key to use to authenticate the connection to
|
- Specifies the SSH key to use to authenticate the connection to
|
||||||
the remote device. This value is the path to the
|
the remote device. This value is the path to the
|
||||||
key used to authenticate the SSH session. If the value is not specified
|
key used to authenticate the SSH session. If the value is not
|
||||||
in the task, the value of environment variable C(ANSIBLE_NET_SSH_KEYFILE)
|
specified in the task, the value of environment variable
|
||||||
will be used instead.
|
C(ANSIBLE_NET_SSH_KEYFILE) will be used instead.
|
||||||
gather_subset:
|
gather_subset:
|
||||||
version_added: "2.6"
|
version_added: "2.6"
|
||||||
description:
|
description:
|
||||||
|
@ -231,7 +235,7 @@ class FactsBase(object):
|
||||||
|
|
||||||
class Default(FactsBase):
|
class Default(FactsBase):
|
||||||
|
|
||||||
COMMANDS = ['display sys-info', 'display running-config']
|
COMMANDS = ['show sys-info', 'show running-config']
|
||||||
|
|
||||||
def populate(self):
|
def populate(self):
|
||||||
super(Default, self).populate()
|
super(Default, self).populate()
|
||||||
|
@ -297,12 +301,12 @@ class Default(FactsBase):
|
||||||
class Hardware(FactsBase):
|
class Hardware(FactsBase):
|
||||||
|
|
||||||
COMMANDS = [
|
COMMANDS = [
|
||||||
'display running-config'
|
'show running-config'
|
||||||
]
|
]
|
||||||
|
|
||||||
def populate(self):
|
def populate(self):
|
||||||
super(Hardware, self).populate()
|
super(Hardware, self).populate()
|
||||||
data = self.run(['display process memory'])
|
data = self.run(['show process memory'])
|
||||||
data = to_text(data, errors='surrogate_or_strict').strip()
|
data = to_text(data, errors='surrogate_or_strict').strip()
|
||||||
data = data.replace(r"\n", "\n")
|
data = data.replace(r"\n", "\n")
|
||||||
if data:
|
if data:
|
||||||
|
@ -331,7 +335,7 @@ class Hardware(FactsBase):
|
||||||
|
|
||||||
class Config(FactsBase):
|
class Config(FactsBase):
|
||||||
|
|
||||||
COMMANDS = ['display running-config']
|
COMMANDS = ['show running-config']
|
||||||
|
|
||||||
def populate(self):
|
def populate(self):
|
||||||
super(Config, self).populate()
|
super(Config, self).populate()
|
||||||
|
@ -342,7 +346,7 @@ class Config(FactsBase):
|
||||||
|
|
||||||
class Interfaces(FactsBase):
|
class Interfaces(FactsBase):
|
||||||
|
|
||||||
COMMANDS = ['display interface brief']
|
COMMANDS = ['show interface brief']
|
||||||
|
|
||||||
def populate(self):
|
def populate(self):
|
||||||
super(Interfaces, self).populate()
|
super(Interfaces, self).populate()
|
||||||
|
@ -350,10 +354,10 @@ class Interfaces(FactsBase):
|
||||||
self.facts['all_ipv4_addresses'] = list()
|
self.facts['all_ipv4_addresses'] = list()
|
||||||
self.facts['all_ipv6_addresses'] = list()
|
self.facts['all_ipv6_addresses'] = list()
|
||||||
|
|
||||||
data1 = self.run(['display interface status'])
|
data1 = self.run(['show interface status'])
|
||||||
data1 = to_text(data1, errors='surrogate_or_strict').strip()
|
data1 = to_text(data1, errors='surrogate_or_strict').strip()
|
||||||
data1 = data1.replace(r"\n", "\n")
|
data1 = data1.replace(r"\n", "\n")
|
||||||
data2 = self.run(['display interface mac-address'])
|
data2 = self.run(['show interface mac-address'])
|
||||||
data2 = to_text(data2, errors='surrogate_or_strict').strip()
|
data2 = to_text(data2, errors='surrogate_or_strict').strip()
|
||||||
data2 = data2.replace(r"\n", "\n")
|
data2 = data2.replace(r"\n", "\n")
|
||||||
lines1 = None
|
lines1 = None
|
||||||
|
@ -364,7 +368,7 @@ class Interfaces(FactsBase):
|
||||||
lines2 = self.parse_interfaces(data2)
|
lines2 = self.parse_interfaces(data2)
|
||||||
if lines1 is not None and lines2 is not None:
|
if lines1 is not None and lines2 is not None:
|
||||||
self.facts['interfaces'] = self.populate_interfaces(lines1, lines2)
|
self.facts['interfaces'] = self.populate_interfaces(lines1, lines2)
|
||||||
data3 = self.run(['display lldp neighbors'])
|
data3 = self.run(['show lldp neighbors'])
|
||||||
data3 = to_text(data3, errors='surrogate_or_strict').strip()
|
data3 = to_text(data3, errors='surrogate_or_strict').strip()
|
||||||
data3 = data3.replace(r"\n", "\n")
|
data3 = data3.replace(r"\n", "\n")
|
||||||
if data3:
|
if data3:
|
||||||
|
@ -372,9 +376,9 @@ class Interfaces(FactsBase):
|
||||||
if lines3 is not None:
|
if lines3 is not None:
|
||||||
self.facts['neighbors'] = self.populate_neighbors(lines3)
|
self.facts['neighbors'] = self.populate_neighbors(lines3)
|
||||||
|
|
||||||
data4 = self.run(['display ip interface brief vrf all'])
|
data4 = self.run(['show ip interface brief vrf all'])
|
||||||
data5 = self.run(['display ipv6 interface brief vrf all'])
|
data5 = self.run(['show ipv6 interface brief vrf all'])
|
||||||
data4 = to_text(data4, errors='surrogate_or_stdisplay').strip()
|
data4 = to_text(data4, errors='surrogate_or_strict').strip()
|
||||||
data4 = data4.replace(r"\n", "\n")
|
data4 = data4.replace(r"\n", "\n")
|
||||||
data5 = to_text(data5, errors='surrogate_or_strict').strip()
|
data5 = to_text(data5, errors='surrogate_or_strict').strip()
|
||||||
data5 = data5.replace(r"\n", "\n")
|
data5 = data5.replace(r"\n", "\n")
|
||||||
|
@ -484,14 +488,24 @@ class Interfaces(FactsBase):
|
||||||
|
|
||||||
def populate_neighbors(self, lines3):
|
def populate_neighbors(self, lines3):
|
||||||
neighbors = dict()
|
neighbors = dict()
|
||||||
|
device_name = ''
|
||||||
for line in lines3:
|
for line in lines3:
|
||||||
neighborSplit = line.split()
|
neighborSplit = line.split()
|
||||||
innerData = dict()
|
innerData = dict()
|
||||||
innerData['Local Interface'] = neighborSplit[1].strip()
|
count = len(neighborSplit)
|
||||||
innerData['Hold Time'] = neighborSplit[2].strip()
|
if count == 5:
|
||||||
innerData['Capability'] = neighborSplit[3].strip()
|
local_interface = neighborSplit[1].strip()
|
||||||
innerData['Remote Port'] = neighborSplit[4].strip()
|
innerData['Device Name'] = neighborSplit[0].strip()
|
||||||
neighbors[neighborSplit[0].strip()] = innerData
|
innerData['Hold Time'] = neighborSplit[2].strip()
|
||||||
|
innerData['Capability'] = neighborSplit[3].strip()
|
||||||
|
innerData['Remote Port'] = neighborSplit[4].strip()
|
||||||
|
neighbors[local_interface] = innerData
|
||||||
|
elif count == 4:
|
||||||
|
local_interface = neighborSplit[0].strip()
|
||||||
|
innerData['Hold Time'] = neighborSplit[1].strip()
|
||||||
|
innerData['Capability'] = neighborSplit[2].strip()
|
||||||
|
innerData['Remote Port'] = neighborSplit[3].strip()
|
||||||
|
neighbors[local_interface] = innerData
|
||||||
return neighbors
|
return neighbors
|
||||||
|
|
||||||
def parse_neighbors(self, neighbors):
|
def parse_neighbors(self, neighbors):
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
vlan {{item.vlanid1}}
|
vlan {{item.vlanid1}}
|
||||||
name anil
|
name anil
|
||||||
exit
|
exit
|
||||||
#config d
|
|
||||||
interface ethernet {{item.slot_chassis_number1}}
|
interface ethernet {{item.slot_chassis_number1}}
|
||||||
#aggregation-group {{item.portchannel_interface_number1}} mode {{item.portchannel_mode1}}
|
|
||||||
description anil
|
description anil
|
||||||
mtu 600
|
mtu 600
|
||||||
exit
|
exit
|
||||||
#config d
|
interface port-channel {{item.portchannel_interface_number1}}
|
||||||
interface port-aggregation {{item.portchannel_interface_number1}}
|
|
||||||
shut
|
shut
|
||||||
lacp suspend-individual
|
lacp suspend-individual
|
||||||
no shut
|
no shut
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
vlan 33
|
vlan 33
|
||||||
name panil
|
name sunil
|
||||||
flood ipv4
|
flood ipv4
|
||||||
state active
|
state active
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
vlan {{item.vlanid1}}
|
vlan {{item.vlanid1}}
|
||||||
name anil
|
name anil
|
||||||
exit
|
exit
|
||||||
#config d
|
|
||||||
interface ethernet {{item.slot_chassis_number1}}
|
interface ethernet {{item.slot_chassis_number1}}
|
||||||
#aggregation-group {{item.portchannel_interface_number1}} mode {{item.portchannel_mode1}}
|
|
||||||
description anil
|
description anil
|
||||||
mtu 600
|
mtu 600
|
||||||
exit
|
exit
|
||||||
#config d
|
interface port-channel {{item.portchannel_interface_number1}}
|
||||||
interface port-aggregation {{item.portchannel_interface_number1}}
|
|
||||||
shut
|
shut
|
||||||
lacp suspend-individual
|
lacp suspend-individual
|
||||||
no shut
|
no shut
|
||||||
|
|
|
@ -50,7 +50,7 @@ class TestCnosCommandModule(TestCnosModule):
|
||||||
try:
|
try:
|
||||||
command = item
|
command = item
|
||||||
except ValueError:
|
except ValueError:
|
||||||
command = 'display version'
|
command = 'show version'
|
||||||
filename = str(command).replace(' ', '_')
|
filename = str(command).replace(' ', '_')
|
||||||
output.append(load_fixture(filename))
|
output.append(load_fixture(filename))
|
||||||
return output
|
return output
|
||||||
|
@ -58,49 +58,49 @@ class TestCnosCommandModule(TestCnosModule):
|
||||||
self.run_commands.side_effect = load_from_file
|
self.run_commands.side_effect = load_from_file
|
||||||
|
|
||||||
def test_cnos_command_simple(self):
|
def test_cnos_command_simple(self):
|
||||||
set_module_args(dict(commands=['display version']))
|
set_module_args(dict(commands=['show version']))
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertEqual(len(result['stdout']), 1)
|
self.assertEqual(len(result['stdout']), 1)
|
||||||
self.assertTrue(result['stdout'][0].startswith('Lenovo Networking Operating System (NOS) Software'))
|
self.assertTrue(result['stdout'][0].startswith('Lenovo Networking Operating System (NOS) Software'))
|
||||||
|
|
||||||
def test_cnos_command_multiple(self):
|
def test_cnos_command_multiple(self):
|
||||||
set_module_args(dict(commands=['display version', 'display running-config']))
|
set_module_args(dict(commands=['show version', 'show running-config']))
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertEqual(len(result['stdout']), 2)
|
self.assertEqual(len(result['stdout']), 2)
|
||||||
self.assertTrue(result['stdout'][0].startswith('Lenovo Networking Operating System (NOS) Software'))
|
self.assertTrue(result['stdout'][0].startswith('Lenovo Networking Operating System (NOS) Software'))
|
||||||
|
|
||||||
def test_cnos_command_wait_for(self):
|
def test_cnos_command_wait_for(self):
|
||||||
wait_for = 'result[0] contains "Lenovo Networking Operating System (NOS) Software"'
|
wait_for = 'result[0] contains "Lenovo Networking Operating System (NOS) Software"'
|
||||||
set_module_args(dict(commands=['display version'], wait_for=wait_for))
|
set_module_args(dict(commands=['show version'], wait_for=wait_for))
|
||||||
self.execute_module()
|
self.execute_module()
|
||||||
|
|
||||||
def test_cnos_command_wait_for_fails(self):
|
def test_cnos_command_wait_for_fails(self):
|
||||||
wait_for = 'result[0] contains "test string"'
|
wait_for = 'result[0] contains "test string"'
|
||||||
set_module_args(dict(commands=['display version'], wait_for=wait_for))
|
set_module_args(dict(commands=['show version'], wait_for=wait_for))
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
self.assertEqual(self.run_commands.call_count, 10)
|
self.assertEqual(self.run_commands.call_count, 10)
|
||||||
|
|
||||||
def test_cnos_command_retries(self):
|
def test_cnos_command_retries(self):
|
||||||
wait_for = 'result[0] contains "test string"'
|
wait_for = 'result[0] contains "test string"'
|
||||||
set_module_args(dict(commands=['display version'], wait_for=wait_for, retries=2))
|
set_module_args(dict(commands=['show version'], wait_for=wait_for, retries=2))
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
self.assertEqual(self.run_commands.call_count, 2)
|
self.assertEqual(self.run_commands.call_count, 2)
|
||||||
|
|
||||||
def test_cnos_command_match_any(self):
|
def test_cnos_command_match_any(self):
|
||||||
wait_for = ['result[0] contains "Lenovo Networking Operating System (NOS) Software"',
|
wait_for = ['result[0] contains "Lenovo Networking Operating System (NOS) Software"',
|
||||||
'result[0] contains "test string"']
|
'result[0] contains "test string"']
|
||||||
set_module_args(dict(commands=['display version'], wait_for=wait_for, match='any'))
|
set_module_args(dict(commands=['show version'], wait_for=wait_for, match='any'))
|
||||||
self.execute_module()
|
self.execute_module()
|
||||||
|
|
||||||
def test_cnos_command_match_all(self):
|
def test_cnos_command_match_all(self):
|
||||||
wait_for = ['result[0] contains "Lenovo Networking Operating System (NOS) Software"',
|
wait_for = ['result[0] contains "Lenovo Networking Operating System (NOS) Software"',
|
||||||
'result[0] contains "Lenovo"']
|
'result[0] contains "Lenovo"']
|
||||||
set_module_args(dict(commands=['display version'], wait_for=wait_for, match='all'))
|
set_module_args(dict(commands=['show version'], wait_for=wait_for, match='all'))
|
||||||
self.execute_module()
|
self.execute_module()
|
||||||
|
|
||||||
def test_cnos_command_match_all_failure(self):
|
def test_cnos_command_match_all_failure(self):
|
||||||
wait_for = ['result[0] contains "Lenovo ENOS"',
|
wait_for = ['result[0] contains "Lenovo ENOS"',
|
||||||
'result[0] contains "test string"']
|
'result[0] contains "test string"']
|
||||||
commands = ['display version', 'display run']
|
commands = ['show version', 'show run']
|
||||||
set_module_args(dict(commands=commands, wait_for=wait_for, match='all'))
|
set_module_args(dict(commands=commands, wait_for=wait_for, match='all'))
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
|
|
Loading…
Reference in a new issue