Skip to content

Commit c8c3048

Browse files
authored
Merge pull request #73 from QualiSystems/dev
cloudshell-networking-cisco-5.2.2 release
2 parents 845a9ba + 5080119 commit c8c3048

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1201
-723
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ install:
1010
python setup.py install;
1111
fi'
1212
- pip install -r test_requirements.txt
13-
- pip install coveralls
13+
- pip install codecov
1414

1515
script:
1616
- nosetests --with-coverage --cover-package=cloudshell.networking.cisco tests
1717

1818
after_success:
19-
- coveralls
19+
- codecov

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
include *.txt
2-
recursive-include *.csv
2+
global-include *.csv
33
global-include *.ini

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# cloudshell-networking-cisco
22
[![Build status](https://travis-ci.org/QualiSystems/cloudshell-networking-cisco.svg?branch=dev)](https://travis-ci.org/QualiSystems/cloudshell-networking-cisco)
3-
[![Coverage Status](https://coveralls.io/repos/github/QualiSystems/cloudshell-networking-cisco/badge.svg)](https://coveralls.io/github/QualiSystems/cloudshell-networking-cisco)
3+
[![codecov](https://codecov.io/gh/QualiSystems/cloudshell-networking-cisco/branch/dev/graph/badge.svg)](https://codecov.io/gh/QualiSystems/cloudshell-networking-cisco)
44
[![PyPI version](https://badge.fury.io/py/cloudshell-networking-cisco.svg)](https://badge.fury.io/py/cloudshell-networking-cisco)
55
[![Dependency Status](https://dependencyci.com/github/QualiSystems/cloudshell-networking-cisco/badge)](https://dependencyci.com/github/QualiSystems/cloudshell-networking-cisco)
66
[![Stories in Ready](https://badge.waffle.io/QualiSystems/cloudshell-networking-cisco.svg?label=ready&title=Ready)](http://waffle.io/QualiSystems/cloudshell-networking-cisco)

cloudshell/networking/cisco/autoload/cisco_generic_snmp_autoload.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from cloudshell.devices.standards.networking.autoload_structure import *
1212

1313

14-
1514
class CiscoGenericSNMPAutoload(object):
1615
IF_ENTITY = "ifDescr"
1716
ENTITY_PHYSICAL = "entPhysicalDescr"
@@ -74,6 +73,11 @@ def discover(self, supported_os):
7473
self.logger.error("Entity table error, no chassis found")
7574

7675
autoload_details = AutoloadDetailsBuilder(self.resource).autoload_details()
76+
if not self.shell_name:
77+
root_model_name = [x for x in autoload_details.attributes if
78+
x.relative_address == "" and x.attribute_name == "Model Name"][0]
79+
if root_model_name:
80+
autoload_details.attributes.remove(root_model_name)
7781
self._log_autoload_details(autoload_details)
7882
return autoload_details
7983

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
3-
4-
import re
5-
import time
3+
from cloudshell.cli.cli_service_impl import CliServiceImpl
64

75
from cloudshell.cli.command_mode_helper import CommandModeHelper
86
from cloudshell.cli.session.ssh_session import SSHSession
@@ -17,7 +15,6 @@ class CiscoCliHandler(CliHandlerImpl):
1715
def __init__(self, cli, resource_config, logger, api):
1816
super(CiscoCliHandler, self).__init__(cli, resource_config, logger, api)
1917
self.modes = CommandModeHelper.create_command_mode(resource_config, api)
20-
self._enable_password = None
2118

2219
@property
2320
def default_mode(self):
@@ -31,13 +28,6 @@ def enable_mode(self):
3128
def config_mode(self):
3229
return self.modes[ConfigCommandMode]
3330

34-
@property
35-
def enable_password(self):
36-
if not self._enable_password:
37-
password = self.resource_config.enable_password
38-
self._enable_password = self._api.DecryptPassword(password).Value
39-
return self._enable_password
40-
4131
def _console_ssh_session(self):
4232
console_port = int(self.resource_config.console_port)
4333
session = ConsoleSSHSession(self.resource_config.console_server_ip_address,
@@ -82,53 +72,9 @@ def on_session_start(self, session, logger):
8272
:return:
8373
"""
8474

85-
self._enter_enable_mode(session=session, logger=logger)
86-
session.hardware_expect("terminal length 0", EnableCommandMode.PROMPT, logger)
87-
session.hardware_expect("terminal width 300", EnableCommandMode.PROMPT, logger)
88-
session.hardware_expect("terminal no exec prompt timestamp", EnableCommandMode.PROMPT, logger)
89-
self._enter_config_mode(session, logger)
90-
session.hardware_expect("no logging console", ConfigCommandMode.PROMPT, logger)
91-
session.hardware_expect("exit", EnableCommandMode.PROMPT, logger)
92-
93-
def _enter_config_mode(self, session, logger):
94-
max_retries = 5
95-
error_message = "Failed to enter config mode, please check logs, for details"
96-
output = session.hardware_expect(ConfigCommandMode.ENTER_COMMAND,
97-
'{0}|{1}'.format(ConfigCommandMode.PROMPT, EnableCommandMode.PROMPT), logger)
98-
99-
config_mode_match = re.search(ConfigCommandMode.PROMPT, output)
100-
retries = 0
101-
while (not config_mode_match) and retries <= max_retries:
102-
time.sleep(5)
103-
output = session.hardware_expect(ConfigCommandMode.ENTER_COMMAND,
104-
'{0}|{1}'.format(ConfigCommandMode.PROMPT, EnableCommandMode.PROMPT),
105-
logger)
106-
config_mode_match = re.search(ConfigCommandMode.PROMPT, output)
107-
retries += 1
108-
if not config_mode_match:
109-
raise Exception('_enter_config_mode', error_message)
110-
111-
def _enter_enable_mode(self, session, logger):
112-
"""
113-
Enter enable mode
114-
115-
:param session:
116-
:param logger:
117-
:raise Exception:
118-
"""
119-
result = session.hardware_expect("", "{default}|{enable}|{config}".format(default=DefaultCommandMode.PROMPT,
120-
enable=EnableCommandMode.PROMPT,
121-
config=ConfigCommandMode.PROMPT),
122-
logger)
123-
124-
if re.search(DefaultCommandMode.PROMPT, result):
125-
expect_map = {'[Pp]assword': lambda session, logger: session.send_line(self.enable_password, logger)}
126-
session.hardware_expect('enable', EnableCommandMode.PROMPT, action_map=expect_map, logger=logger)
127-
result = session.hardware_expect('', '{0}|{1}'.format(DefaultCommandMode.PROMPT, EnableCommandMode.PROMPT),
128-
logger)
129-
if not re.search(EnableCommandMode.PROMPT, result):
130-
raise Exception('enter_enable_mode', 'Enable password is incorrect')
131-
elif re.search(ConfigCommandMode.PROMPT, result):
132-
session.hardware_expect("end", EnableCommandMode.PROMPT, logger=logger)
133-
else:
134-
logger.debug("Session already in Enable Mode")
75+
cli_service = CliServiceImpl(session=session, command_mode=self.enable_mode, logger=logger)
76+
cli_service.send_command("terminal length 0", EnableCommandMode.PROMPT)
77+
cli_service.send_command("terminal width 300", EnableCommandMode.PROMPT)
78+
cli_service.send_command("terminal no exec prompt timestamp", EnableCommandMode.PROMPT)
79+
with cli_service.enter_mode(self.config_mode) as config_session:
80+
config_session.send_command("no logging console", ConfigCommandMode.PROMPT)

cloudshell/networking/cisco/cli/cisco_command_modes.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# -*- coding: utf-8 -*-
33

44
from collections import OrderedDict
5+
import re
6+
import time
57

68
from cloudshell.cli.command_mode import CommandMode
79

@@ -15,7 +17,7 @@ def __init__(self, resource_config, api):
1517
"""
1618
Initialize Default command mode, only for cases when session started not in enable mode
1719
18-
:param context:
20+
:param resource_config:
1921
"""
2022

2123
self.resource_config = resource_config
@@ -52,11 +54,12 @@ def __init__(self, resource_config, api):
5254
"""
5355
Initialize Enable command mode - default command mode for Cisco Shells
5456
55-
:param context:
57+
:param resource_config:
5658
"""
5759

5860
self.resource_config = resource_config
5961
self._api = api
62+
self._enable_password = None
6063

6164
CommandMode.__init__(self,
6265
EnableCommandMode.PROMPT,
@@ -67,8 +70,15 @@ def __init__(self, resource_config, api):
6770
enter_error_map=self.enter_error_map(),
6871
exit_error_map=self.exit_error_map())
6972

73+
@property
74+
def enable_password(self):
75+
if not self._enable_password:
76+
password = self.resource_config.enable_password
77+
self._enable_password = self._api.DecryptPassword(password).Value
78+
return self._enable_password
79+
7080
def enter_action_map(self):
71-
return OrderedDict()
81+
return {"[Pp]assword": lambda session, logger: session.send_line(self.enable_password, logger)}
7282

7383
def enter_error_map(self):
7484
return OrderedDict()
@@ -81,40 +91,64 @@ def exit_error_map(self):
8191

8292

8393
class ConfigCommandMode(CommandMode):
94+
MAX_ENTER_CONFIG_MODE_RETRIES = 5
95+
ENTER_CONFIG_RETRY_TIMEOUT = 5
8496
PROMPT = r'\(config.*\)#\s*$'
8597
ENTER_COMMAND = 'configure terminal'
86-
EXIT_COMMAND = 'exit'
98+
EXIT_COMMAND = "exit"
99+
ENTER_ACTION_COMMANDS = []
87100

88101
def __init__(self, resource_config, api):
89102
"""
90103
Initialize Config command mode
91104
92-
:param context:
105+
:param resource_config:
93106
"""
94107

95108
self.resource_config = resource_config
96109
self._api = api
97110

98-
exit_action_map = {
99-
self.PROMPT: lambda session, logger: session.send_line('exit', logger)}
100111
CommandMode.__init__(self,
101112
ConfigCommandMode.PROMPT,
102113
ConfigCommandMode.ENTER_COMMAND,
103114
ConfigCommandMode.EXIT_COMMAND,
104115
enter_action_map=self.enter_action_map(),
105-
exit_action_map=exit_action_map,
116+
exit_action_map=self.exit_action_map(),
106117
enter_error_map=self.enter_error_map(),
107118
exit_error_map=self.exit_error_map())
108119

109120
def enter_action_map(self):
110-
return OrderedDict()
121+
return {r"{}.*$".format(EnableCommandMode.PROMPT): self._check_config_mode}
111122

112123
def enter_error_map(self):
113124
return OrderedDict()
114125

115126
def exit_error_map(self):
116127
return OrderedDict()
117128

129+
def exit_action_map(self):
130+
return {self.PROMPT: lambda session, logger: session.send_line('exit', logger)}
131+
132+
def enter_actions(self, cli_service):
133+
for cmd in self.ENTER_ACTION_COMMANDS:
134+
cli_service.send_command(cmd)
135+
136+
def _check_config_mode(self, session, logger):
137+
error_message = "Failed to enter config mode, please check logs, for details"
138+
output = session.hardware_expect("", expected_string="{0}|{1}".format(EnableCommandMode.PROMPT,
139+
ConfigCommandMode.PROMPT),
140+
logger=logger)
141+
retry = 0
142+
while (not re.search(ConfigCommandMode.PROMPT, output)) and retry < self.MAX_ENTER_CONFIG_MODE_RETRIES:
143+
output = session.hardware_expect(ConfigCommandMode.ENTER_COMMAND,
144+
expected_string="{0}|{1}".format(EnableCommandMode.PROMPT,
145+
ConfigCommandMode.PROMPT),
146+
logger=logger)
147+
time.sleep(self.ENTER_CONFIG_RETRY_TIMEOUT)
148+
retry += 1
149+
if not re.search(ConfigCommandMode.PROMPT, output):
150+
raise Exception(error_message)
151+
118152

119153
CommandMode.RELATIONS_DICT = {
120154
DefaultCommandMode: {

cloudshell/networking/cisco/command_actions/add_remove_vlan_actions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def verify_interface_configured(vlan_range, current_config):
3232
:return: True or False
3333
"""
3434

35-
return re.search("switchport.*vlan.*{0}".format(str(vlan_range)), current_config,
35+
return re.search("switchport.*vlan\s+{0}$".format(str(vlan_range)), current_config,
3636
re.MULTILINE | re.IGNORECASE | re.DOTALL)
3737

3838
def create_vlan(self, vlan_range, action_map=None, error_map=None):
@@ -108,6 +108,6 @@ def set_vlan_to_interface(self, vlan_range, port_mode, port_name, qnq, c_tag,
108108

109109
def _get_l2_protocol_tunnel_cmd(self, action_map=None, error_map=None):
110110
return CommandTemplateExecutor(self._cli_service,
111-
vlan_command_template.L2_TUNNEL,
112-
action_map=action_map,
113-
error_map=error_map)
111+
vlan_command_template.L2_TUNNEL,
112+
action_map=action_map,
113+
error_map=error_map)

0 commit comments

Comments
 (0)