简体   繁体   中英

How can I compare two Json arrays at Python?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM