Skip to content

Commit

Permalink
Merge pull request #51 from QualiSystems/dev
Browse files Browse the repository at this point in the history
Release 2.7.0
  • Loading branch information
Costya-Y committed Dec 26, 2018
2 parents 6c81d1b + a977719 commit 3660ed4
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 45 deletions.
4 changes: 2 additions & 2 deletions cloudshell/devices/driver_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ def get_snmp_parameters_from_command_context(resource_config, api, force_decrypt
snmp_user=resource_config.snmp_v3_user or '',
snmp_password=api.DecryptPassword(resource_config.snmp_v3_password).Value or '',
snmp_private_key=resource_config.snmp_v3_private_key or '',
auth_protocol=resource_config.snmp_v3_auth_protocol or 'No Authentication Protocol',
private_key_protocol=resource_config.snmp_v3_priv_protocol or 'No Privacy Protocol')
auth_protocol=resource_config.snmp_v3_auth_protocol or SNMPV3Parameters.AUTH_NO_AUTH,
private_key_protocol=resource_config.snmp_v3_priv_protocol or SNMPV3Parameters.PRIV_NO_PRIV).get_valid()
else:
if resource_config.shell_name or force_decrypt:
write_community = api.DecryptPassword(resource_config.snmp_write_community).Value or ''
Expand Down
80 changes: 41 additions & 39 deletions cloudshell/devices/networking_utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from functools import wraps

import jsonpickle
import os
import re

from urlparse import urlsplit, SplitResult
from urlparse import urlsplit, urlunsplit


def validate_vlan_number(number):
Expand Down Expand Up @@ -66,46 +62,52 @@ def parse_url(url):
if hasattr(parsed, attr_value):
value = getattr(parsed, attr_value)
if attr_value == UrlParser.PATH:
path, filename = os.path.split(value)
result[UrlParser.PATH] = path
result[UrlParser.FILENAME] = filename
path = value
result[UrlParser.FILENAME] = ""
if not path.endswith("/"):
filename = path[path.rfind("/") + 1:]
result[UrlParser.FILENAME] = filename
path = path.replace(filename, "")
result[UrlParser.PATH] = path[:-1]
else:
result[attr_value] = value
return result

@staticmethod
def build_url(url):
url_result = {UrlParser.QUERY: '', UrlParser.FRAGMENT: ''}
if not url or UrlParser.SCHEME not in url or not url[UrlParser.SCHEME]:
raise Exception('UrlParser:build_url', 'Url dictionary is empty or missing key values')

url_result[UrlParser.SCHEME] = url[UrlParser.SCHEME]

if UrlParser.NETLOC in url and url[UrlParser.NETLOC]:
if UrlParser.USERNAME in url \
and url[UrlParser.USERNAME] \
and url[UrlParser.USERNAME] in url[UrlParser.NETLOC]:
url_result[UrlParser.NETLOC] = url[UrlParser.NETLOC]
if UrlParser.NETLOC not in url_result:
url_result[UrlParser.NETLOC] = url[UrlParser.HOSTNAME]
if UrlParser.PORT in url and url[UrlParser.PORT]:
url_result[UrlParser.NETLOC] += ':{}'.format(url[UrlParser.PORT])
if UrlParser.USERNAME in url and url[UrlParser.USERNAME]:
credentials = '{}@'.format(url[UrlParser.USERNAME])
if UrlParser.PASSWORD in url and url[UrlParser.PASSWORD]:
credentials = '{}:{}@'.format(url[UrlParser.USERNAME], url[UrlParser.PASSWORD])
url_result[UrlParser.NETLOC] = credentials + url_result[UrlParser.NETLOC]

url_result[UrlParser.PATH] = url[UrlParser.FILENAME]
if UrlParser.PATH in url and url[UrlParser.PATH]:
url_result[UrlParser.PATH] = url[UrlParser.PATH] + '/' + url_result[UrlParser.PATH]
url_result[UrlParser.PATH] = re.sub('//+', '/', url_result[UrlParser.PATH])

if UrlParser.QUERY in url and url[UrlParser.QUERY]:
url_result[UrlParser.QUERY] = url[UrlParser.QUERY]

result = SplitResult(**url_result)
return result.geturl()
if not url:
raise Exception('Url dictionary is empty.')
scheme = url.get(UrlParser.SCHEME, "")
query = url.get(UrlParser.QUERY, "")
fragment = url.get(UrlParser.FRAGMENT, "")
netloc = url.get(UrlParser.NETLOC)
host = url.get(UrlParser.HOSTNAME, "")
port = url.get(UrlParser.PORT)
username = url.get(UrlParser.USERNAME)
password = url.get(UrlParser.PASSWORD)
path = url.get(UrlParser.PATH, "")
filename = url.get(UrlParser.FILENAME, "")

if not scheme:
raise Exception('Url missing key value: scheme.')

if not netloc:
netloc = host
if port and str(port) not in netloc:
netloc += ':{}'.format(port)
if username and username not in netloc or password and password not in netloc:
credentials = '{}@'.format(username)
if password:
credentials = '{}:{}@'.format(username, password)
netloc = credentials + netloc

target_path = filename
if path:
if not path.endswith("/"):
path = "{}/".format(path)
target_path = path + target_path

return urlunsplit((scheme, netloc, target_path, query, fragment))


def command_logging(func):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ def snmp_v3_private_key(self):
"""
return self.attributes.get("{}SNMP V3 Private Key".format(self.namespace_prefix), None)

@property
def snmp_v3_auth_protocol(self):
"""
:rtype: str
"""
return self.attributes.get("{}SNMP V3 Authentication Protocol".format(self.namespace_prefix), None)

@property
def snmp_v3_priv_protocol(self):
"""
:rtype: str
"""
return self.attributes.get("{}SNMP V3 Privacy Protocol".format(self.namespace_prefix), None)

@property
def snmp_version(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ ipcalc==1.1.3
jsonpickle==0.9.3
cloudshell-shell-core>=4.0,<4.1
cloudshell-cli>=3.3,<3.4
cloudshell-snmp>=3.2,<3.3
cloudshell-snmp>=3.3,<3.4
cloudshell-automation-api>=8.3,<8.4
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,28 @@ def test_snmp_v3_private_key(self):
# verify
self.assertEqual(result, expected_val)

def test_snmp_v3_auth_protocol(self):
"""Check that property will return needed attribute value from the internal attributes dictionary"""
expected_val = "test value"
self.resource.attributes = {
"{}.{}".format(self.shell_name, "SNMP V3 Authentication Protocol"): expected_val
}
# act
result = self.resource.snmp_v3_auth_protocol
# verify
self.assertEqual(result, expected_val)

def test_snmp_v3_priv_protocol(self):
"""Check that property will return needed attribute value from the internal attributes dictionary"""
expected_val = "test value"
self.resource.attributes = {
"{}.{}".format(self.shell_name, "SNMP V3 Privacy Protocol"): expected_val
}
# act
result = self.resource.snmp_v3_priv_protocol
# verify
self.assertEqual(result, expected_val)

def test_snmp_version(self):
"""Check that property will return needed attribute value from the internal attributes dictionary"""
expected_val = "test value"
Expand Down
4 changes: 3 additions & 1 deletion tests/devices/test_driver_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ def test_get_snmp_parameters_from_command_context_for_snmp_v3(self, snmpv3parame
config = mock.MagicMock(snmp_version="v3")
api = mock.MagicMock()
snmp_v3 = mock.MagicMock()
snmpv3parameters_class.return_value = snmp_v3
snmp_v3_inst = mock.Mock()
snmp_v3_inst.get_valid.return_value = snmp_v3
snmpv3parameters_class.return_value = snmp_v3_inst
decrypted_snmp_string = mock.MagicMock()
api.DecryptPassword.return_value = decrypted_snmp_string
# act
Expand Down
33 changes: 32 additions & 1 deletion tests/devices/test_networking_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,17 @@ def test_build_url_without_scheme(self):

self.assertRaisesRegexp(
Exception,
'Url dictionary is empty or missing key values',
'Url missing key value: scheme.',
networking_utils.UrlParser.build_url,
url_data,
)

def test_build_url_fail_when_url_empty(self):
url_data = {}

self.assertRaisesRegexp(
Exception,
'Url dictionary is empty.',
networking_utils.UrlParser.build_url,
url_data,
)
Expand All @@ -93,6 +103,7 @@ def test_url_parse_and_builder_returns_the_same(self):

def test_build_url_without_netloc(self):
url_data = networking_utils.UrlParser.parse_url('http://test.com')
url_data["netloc"] = ""
backup_user = 'user' # we can add it in ConfigurationRunner
backup_password = 'password'
port = '22'
Expand All @@ -105,3 +116,23 @@ def test_build_url_without_netloc(self):
url = networking_utils.UrlParser.build_url(url_data)

self.assertEqual(url, 'http://user:password@test.com:22')

def test_scp_link_parsed_and_return_same_link(self):
url = ("scp://cisco:securePassword!1@test.host.com:"
"//d:/some_path/test_file_name.ext?arg=val")
url_data = networking_utils.UrlParser.parse_url(url)
new_url = networking_utils.UrlParser.build_url(url_data)
self.assertEqual(url, new_url)

def test_link_without_filename(self):
url = ("scp://cisco:securePassword!1@test.host.com"
"//some_path/")
url_data = networking_utils.UrlParser.parse_url(url)
new_url = networking_utils.UrlParser.build_url(url_data)
self.assertEqual(url, new_url)

def test_simple_ftp_path(self):
url = 'ftp://192.168.122.10/Test-running-100418-163658'
url_data = networking_utils.UrlParser.parse_url(url)
new_url = networking_utils.UrlParser.build_url(url_data)
self.assertEqual(url, new_url)
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.0
2.7.0

0 comments on commit 3660ed4

Please sign in to comment.