Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port support added for same Ip-address. #355

Merged
merged 2 commits into from
Feb 3, 2020
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
11 changes: 9 additions & 2 deletions lib/jnpr/jsnapy/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@

class Comparator:

def __init__(self):
def __init__(self, **kwargs):
"""
Comparator object constructor.
:param int port.

"""
self.logger_check = logging.getLogger(__name__)
self.log_detail = {'hostname': None}

self.port = kwargs.get('port', None)

def is_op(self, op):
"""
Expand Down Expand Up @@ -63,6 +68,8 @@ def generate_snap_file(self, device, prefix, name, reply_format):
"""
This function generates name of snapshot files
"""
if self.port is not None:
device = "{}_{}".format(device, self.port)
if os.path.isfile(prefix):
return prefix
else:
Expand Down
127 changes: 67 additions & 60 deletions lib/jnpr/jsnapy/jsnapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def get_hosts(self):
sys.exit(1)
self.login(output_file)

def generate_rpc_reply(self, dev, output_file, hostname, config_data):
def generate_rpc_reply(self, dev, output_file, hostname, config_data, **kwargs):
"""
Generates rpc-reply based on command/rpc given and stores them in snap_files
:param dev: device handler
Expand All @@ -394,22 +394,21 @@ def generate_rpc_reply(self, dev, output_file, hostname, config_data):
colorama.Fore.RED +
"ERROR!! File %s is not found for taking snapshots" %
tfile, extra=self.log_detail)

g = Parser()
g = Parser(**kwargs)
vnitinv marked this conversation as resolved.
Show resolved Hide resolved
for tests in test_files:
val = g.generate_reply(tests, dev, output_file, hostname, self.db)
return val

def compare_tests(
self, hostname, config_data, pre_snap=None, post_snap=None, action=None):
self, hostname, config_data, pre_snap=None, post_snap=None, action=None, **kwargs):
"""
called by check and snapcheck argument, to compare snap files
calls the function to compare snapshots based on arguments given
(--check, --snapcheck, --diff)
:param hostname: device name
:return: return object of Operator containing test details
"""
comp = Comparator()
comp = Comparator(**kwargs)
vnitinv marked this conversation as resolved.
Show resolved Hide resolved
chk = self.args.check
diff = self.args.diff
pre_snap_file = self.args.pre_snapfile if pre_snap is None else pre_snap
Expand Down Expand Up @@ -490,39 +489,26 @@ def login(self, output_file):
dgroup = [i.strip().lower() for i in gp.split(',')]
for dgp in dev_file:
vnitinv marked this conversation as resolved.
Show resolved Hide resolved
if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
for val in dev_file[dgp]:
for counter, val in enumerate(dev_file[dgp]):
# There can be multiple values of device/hostname
# The values can have same hostname but different port
# key for the dictionary modified from hostname to enumerate value to keep distinction
hostname = list(val)[0]
self.log_detail = {'hostname': hostname}
if val.get(hostname) is not None and hostname not in host_dict:
host_dict[hostname] = deepcopy(val.get(hostname))
if val.get(hostname) is not None and hostname not in self.host_list:
#host_dict[hostname] = deepcopy(val.get(hostname))
self.host_list.append(hostname)
host_dict[counter] = deepcopy(val.get(hostname))
host_dict[counter]["device"] = hostname

# login credentials are given in main config file, can connect to multiple devices
else:
#key_value = deepcopy(k)
for host in hosts_val:
try:
hostname = host['device']
self.log_detail = {'hostname': hostname}
except KeyError as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! KeyError 'device' key not found",
extra=self.log_detail)
#raise Exception(ex)
except Exception as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! %s" %
ex,
extra=self.log_detail)
#raise Exception(ex)
else:
if hostname not in host_dict:
self.host_list.append(hostname)
# host.pop('device')
host_dict[hostname] = deepcopy(host)

for (hostname, key_value) in iteritems(host_dict):
self.get_hosts_list(hosts_val,host_dict)

for (iter, key_value) in iteritems(host_dict):
hostname = key_value.get('device')
#it is under check that args.hostname is None
#The file config takes precedence over cmd line params -- no changes made
username = self.args.login or key_value.get('username')
password = self.args.passwd or key_value.get('passwd')
Expand Down Expand Up @@ -556,7 +542,7 @@ def login(self, output_file):
key_value = {'port': port} if port is not None else {}
self.connect(hostname, username, password, output_file, **key_value)

def get_test(self, config_data, hostname, snap_file, post_snap, action):
def get_test(self, config_data, hostname, snap_file, post_snap, action, **kwargs):
"""
Analyse testfile and return object of operator.Operator containing test details
called by connect() function and other functions of Jsnapy module functions
Expand All @@ -574,7 +560,8 @@ def get_test(self, config_data, hostname, snap_file, post_snap, action):
config_data,
snap_file,
post_snap,
action)
action,
**kwargs)

result_status = res.result

Expand Down Expand Up @@ -696,7 +683,8 @@ def connect(self, hostname, username, password, output_file,
dev,
output_file,
hostname,
config_data)
config_data,
**kwargs)
self.snap_q.put(res)
dev.close()
if self.args.check is True or self.args.snapcheck is True or self.args.diff is True or action in [
Expand All @@ -715,16 +703,18 @@ def connect(self, hostname, username, password, output_file,
hostname,
local_snap,
post_snap,
action)
action,
**kwargs)
res[local_snap] = ret_obj
else:
res = self.get_test(
config_data,
hostname,
output_file,
post_snap,
action)

action,
**kwargs)

return res

############################### functions to support module ##############
Expand Down Expand Up @@ -760,36 +750,23 @@ def multiple_device_details(
gp = first_entry.get('group', 'all')

dgroup = [i.strip().lower() for i in gp.split(',')]
iter = 0
for dgp in dev_file:
if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
for val in dev_file[dgp]:
hostname = list(val)[0]
self.log_detail = {'hostname': hostname}
if val.get(hostname) is not None and hostname not in host_dict:
host_dict[hostname] = deepcopy(val.get(hostname))
iter += 1
if val.get(hostname) is not None and hostname not in self.host_list:
self.host_list.append(hostname)
host_dict[iter] = deepcopy(val.get(hostname))
host_dict[iter]["device"] = hostname
else:
for host in hosts:
try:
hostname = host['device']
self.log_detail = {'hostname': hostname}
except KeyError as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! KeyError 'device' key not found",
extra=self.log_detail)
except Exception as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! %s" %
ex,
extra=self.log_detail)
else:
if hostname not in host_dict:
self.host_list.append(hostname)
host_dict[hostname] = deepcopy(host)
# changes to support port
self.get_hosts_list(hosts, host_dict)

for (hostname, key_value) in iteritems(host_dict):
for (iter, key_value) in iteritems(host_dict):
hostname = key_value.get('device')
username = key_value.get('username')
password = key_value.get('passwd')
key_value = self.get_values(key_value)
Expand Down Expand Up @@ -1033,6 +1010,36 @@ def check(self, data, pre_file=None, post_file=None, dev=None, folder=None):
res = self.extract_data(data, pre_file, "check", post_file)
return res

def get_hosts_list(self, hosts_val, host_dict):
"""
Function extracts list of hosts from the details given.
:param hosts_val: has the list of hosts to be parsed
:param host_dict: The dictionary to be created to store the parsed values
"""

for counter, host in enumerate(hosts_val):
try:
hostname = host['device']
self.log_detail = {'hostname': hostname}
except KeyError as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! KeyError 'device' key not found",
extra=self.log_detail)
except Exception as ex:
self.logger.error(
colorama.Fore.RED +
"ERROR!! %s" %
ex,
extra=self.log_detail)
else:
if hostname not in self.host_list:
self.host_list.append(hostname)
# There can be multiple values of device/hostname
# The values can have same hostname but different port
# key for the dictionary modified from hostname to enumerate value to keep distinction
host_dict[counter] = deepcopy(host)

####### generate init folder ######
'''
def generate_init(self):
Expand Down
10 changes: 9 additions & 1 deletion lib/jnpr/jsnapy/snap.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@

class Parser:

def __init__(self):
def __init__(self, **kwargs):
"""
Parser object constructor.
:param int port.

"""
self.logger_snap = logging.getLogger(__name__)
self.log_detail = {'hostname': None}
self.reply = {}
self.command_list = []
self.rpc_list = []
self.test_included = []
self.port = kwargs.get('port', None)

def _write_file(self, rpc_reply, format, output_file):
"""
Expand Down Expand Up @@ -89,6 +95,8 @@ def generate_snap_file(self, output_file, hostname, name, cmd_format):
:param cmd_format: xml/text
:return: return output file
"""
if self.port is not None:
hostname = "{}_{}".format(hostname, self.port)
name = name.split('|')[0].strip()
cmd_rpc = re.sub('/|\*|\.|-|\|', '_', name)
if os.path.isfile(output_file):
Expand Down