#! /usr/bin/env python import subprocess import sys import os import time ld_file = "/tmp/megacli-logical.out" pd_file = "/tmp/megacli-physical.out" ld_cmd = "cat /opt/py/megacli-logical.out" pd_cmd = "cat /opt/py/megacli-physical.out" pd_dict = dict(slot='Slot Number', port_stat='Port status', size='Raw Size', data='Inquiry Data', temp='Drive Temperature ', smart_err='Drive has flagged a S.M.A.R.T alert', manufacter='Inquiry Data', model='Inquiry Data', serial='Inquiry Data') ld_dict = dict(num='Virtual Drive:', raid_lvl='RAID Level ', size='Size', state='State', pd_count='Number Of Drives') def f_ld_discover(cli_out): drives = [] linesplit = '' for line in cli_out: if 'Virtual Drive:' in line: linesplit = line.split(' ') drives.append(str(linesplit[2])) return drives def f_pd_discover(cli_out): drives = [] linesplit = '' for line in cli_out: if 'Slot Number:' in line: linesplit = line.split(' ') drives.append(str(linesplit[2])) return drives def f_json_print(inp, name): first = True print("{") print("\t\"data\":[") for key in inp: if not first: sys.stdout.write(",") else: first = False sys.stdout.write("\n\t\t{\"{#" + name + "}\":\"" + key + "\"}") print("\n\t]") print("}") def f_read_file(path): cli_out = [] try: f = open(path, 'r') except Exception: print(Exception) return [] else: for line in f.readlines(): cli_out.append(line.strip()) f.close() return cli_out def f_read_cli(cmd, outfile): outdata, stderr = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate() try: f = open(outfile, 'w') except Exception: return 1 else: f.write(outdata) f.close() return 0 def f_get_pd_val(slot, val, source): data = f_read_file(source) k = 0 out = "" for line in data: if pd_dict['slot'] in line: # print(line.strip().split(':')[1].strip()) if line.strip().split(':')[1].strip() == slot: k = 1 if k == 0: continue if k == 1: if pd_dict[val] in line: out = line.strip().split(':')[1].strip().split() if out != "": break if len(out) == 1 and out[0].isdigit(): return out[0] elif val == 'smart_err': if out[0] == 'No': return '0' else: return '1' elif val == "manufacter": return out[0].strip() elif val == "model": return out[1].strip() elif val == "serial": return out[2].strip() elif val == 'size': return out[0] elif val == 'port_stat': if out[0] == 'Active': return '1' else: return '0' elif val == 'temp': return out[0][:-1] def f_get_ld_val(num, val, source): data = f_read_file(source) k = 0 out = "" for line in data: if ld_dict['num'] in line: if line.split(':')[1].strip().split()[0].strip() == num: k = 1 if k == 0: continue if k == 1: if ld_dict[val] in line: out = line.split(':')[1].strip() if out != "": break if val == 'raid_lvl': return out elif val == 'size': return out.split()[0] elif val == 'state': if out.strip() == 'Optimal': return '0' else: return '1' elif val == 'pd_count': return out.strip() return out if __name__ == '__main__': if len(sys.argv) == 1 or len(sys.argv) == 3 or len(sys.argv) > 4: print("Wrong args. Cache will be updated if necessary") stat_pd = os.stat(pd_file) stat_ld = os.stat(ld_file) if (float(time.time()) - float(stat_pd.st_ctime)) > 50: f_read_cli(pd_cmd, pd_file) if (float(time.time()) - float(stat_ld.st_ctime)) > 50: f_read_cli(ld_cmd, ld_file) if len(sys.argv) == 2: if sys.argv[1] == "ld": f_json_print(f_ld_discover(f_read_file(ld_file)), "LD") if sys.argv[1] == "pd": f_json_print(f_pd_discover(f_read_file(pd_file)), "PD") elif len(sys.argv) == 4: if sys.argv[1] == 'pd': if sys.argv[3] in pd_dict.keys(): print(f_get_pd_val(sys.argv[2], sys.argv[3], pd_file)) if sys.argv[1] == 'ld': if sys.argv[3] in ld_dict.keys(): print(f_get_ld_val(sys.argv[2], sys.argv[3], ld_file))