I am creating a script that allows comparing two ssh command outputs to a remote Netapp, and that allows comparing between a current value and the maximum value of space that the Netapp cabin has.
I have collected these values in two dictionaries (rv and rv 2), which in turn, I convert to JSON format to be able to compare them based on the warning argument passed to it (if it exceeds this limit, it would have to notify).
import subprocess
import argparse
import sys
import json
import re
from subprocess import check_output
def parse_args(argv):
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--user", action="store",
help="User for login",
dest="user")
parser.add_argument("-p", "--pwd", action="store",
help="Password",
dest="pwd")
parser.add_argument("-i", "--ip", action="store",
help="Machine ip",
dest="ip")
parser.add_argument("-w", "--warning", action="store",
help="Warning threshold",
type = int,
dest="warning")
parser.add_argument("-m", "--machine_command", action="store",
help="Command",
type = int,
dest="ssh_command")
parser.add_argument("-M", "--machine_command_max", action="store",
help="Max value for command",
type = int,
dest="ssh_command_max")
args = parser.parse_args()
return args
args = parse_args(sys.argv[1:])
command = 'sshpass -p ' +args.pwd+ ' ssh ' + args.user + '@' +args.ip+ args.ssh_command
output = check_output(command, shell=True)
#Command to retrieve the max_values
command_max = 'sshpass -p ' +args.pwd+ ' ssh ' + args.user + '@' +args.ip+ args.ssh_command_max
output_max = check_output(command_max, shell=True)
rv = {}
current_node = None
for match in re.findall(r'Machine_name (name.*\d+)|(Metric_name_.*)', output):
node, metric = match
if node and current_node != node:
current_node = node
if current_node and metric:
name, value = metric.strip().split()
rv[current_node.strip() + "." + name.replace("Alloc", "")] = [value]
#print(';'.join(rv))
rv2 = {}
current_node = None
for match in re.findall(r'Machine_name (name.*\d+)|(Max_metric.*)', output_max):
node, metric = match
if node and current_node != node:
current_node = node
if current_node and metric:
name, value = metric.strip().split()
rv2[current_node.strip() + "." + name.replace("Max", "")] = [(value/100) * args.warning]
json1=json.dumps(rv, sort_keys=True)
json2=json.dumps(rv2, sort_keys=True)
def get_values(json, lst):
if isinstance(json, list):
for item in json: get_values(item, lst)
elif isinstance(json, dict):
for item in json.values(): get_values(item, lst)
else: lst.append(json)
list1 = []; get_values(json1, list1)
list2 = []; get_values(json2, list2)
diff = [(n, x, y) for n,(x,y) in enumerate(zip(list1, list2)) if x <= y]
print(diff)
An example of the values that I would like to compare: RV1:
{'node1.storePool_Owner': ['160'], 'node1.storePool_Deleg': ['0'], 'node2.storePool_LockState': ['0']}
RV2:
{'node1.storePool_Owner': ['1024000'], 'node1.storePool_Deleg': ['1024000'], 'node2.storePool_LockState': ['1024000']}
The idea is to compare each of these values, with their maximum equivalent.
Thanks a lot for your help.
An example of how should the comparison be: If this node, with that value:
node1.storePool_Owner': ['160']
Reaches the X% (warning arg) of:
node1.storePool_Owner': ['1024000']
Then it should return:
WARNING: node1.storePool_Owner has exceeded the threshold (x%)
This will compare the two json files/dictionaries. I noticed the values are lists of string... is that intentional?
import json
def open_json(path):
with open(path, 'r') as file:
return json.load(file)
def check_thresholds(data, thresholds):
for k, v in thresholds.items():
# your logic/output here
# k[0] and v[0] because your values are lists of strings... should they be just int of float?
difference = int(data.get(k)[0]) - int(v[0])
if difference >= 0:
print(f'WARNING: {k} has exceeded the threshold by {difference}')
else:
print(f'OK: {k}')
def main():
# load the data into dictionaries
data = open_json('./rv.json')
thresholds = open_json('./rv2.json')
# if your data is a dictionary and not json files then use these
# data = {'node1.storePool_Owner': ['160'], 'node1.storePool_Deleg': ['0'], 'node2.storePool_LockState': ['0']}
# thresholds = {'node1.storePool_Owner': ['1024000'], 'node1.storePool_Deleg': ['1024000'], 'node2.storePool_LockState': ['1024000']}
# run the checks
check_thresholds(data, thresholds)
main()
Output (I modified some values to show the warning):
WARNING: node1.storePool_Owner has exceeded the threshold by 1000
OK: node1.storePool_Deleg
OK: node2.storePool_LockState