observium_api_client/client.py

223 lines
10 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2017-11-13 10:20:29 +00:00
import requests
import yaml
import argparse
2018-12-10 14:12:07 +00:00
import os
import shutil
2022-01-10 09:29:28 +00:00
import subprocess
2017-11-13 10:20:29 +00:00
2018-12-10 14:12:07 +00:00
config = os.path.join(os.path.dirname(os.path.realpath(__file__)),"config.yml")
with open(config, "r") as ymlfile:
2019-09-02 06:35:05 +00:00
cfg = yaml.load(ymlfile, Loader=yaml.FullLoader)
2017-11-13 10:20:29 +00:00
term_cols = getattr(shutil.get_terminal_size((80, 20)), 'columns')
2017-11-13 20:17:35 +00:00
def call_api(params, path):
url = '/'.join((params['base_url'],params['api_path'],path))
try:
2022-01-10 09:29:28 +00:00
if 'password_cmd' in params:
result = subprocess.run(params['password_cmd'].split(), stdout=subprocess.PIPE)
password = result.stdout.decode('utf-8')
else:
password = params['password']
response = requests.get(url, auth=(params['username'],password))
2017-11-13 20:17:35 +00:00
except:
return
if response.status_code != 200:
2017-11-14 09:51:58 +00:00
return
2017-11-13 10:20:29 +00:00
return response.json()
2019-07-23 18:52:42 +00:00
def print_data(term_cols, key, value, suffix = None):
2017-11-13 10:20:29 +00:00
if suffix is not None:
2019-01-17 16:39:24 +00:00
value_cols = term_cols - 26 - len(value)
print("(0x(B %-18s (0x(B %s %-*.*s (0x(B" %
(key, value, value_cols, value_cols, suffix))
2017-11-13 10:20:29 +00:00
else:
2019-01-17 16:39:24 +00:00
value_cols = term_cols - 25
print("(0x(B %-18s (0x(B %-*.*s (0x(B" %
(key, value_cols, value_cols, value))
2017-11-13 10:20:29 +00:00
2019-09-02 06:35:05 +00:00
def sizeof_fmt(num, suffix='B', binary=True):
if binary:
units = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
base = 1024.0
else:
units = ['','K','M','G','T','P','E','Z']
base = 1000.0
for unit in units:
if abs(num) < base:
return "%3.1f %s%s" % (num, unit, suffix)
num /= base
return "%.1f %s%s" % (num, 'Y', suffix)
2017-11-13 10:20:29 +00:00
def search_ports(args):
for instance, params in cfg['instances'].items():
2021-03-03 16:46:29 +00:00
if args.instance is not None and instance not in args.instance.split(','):
continue
2017-11-13 20:17:35 +00:00
data = call_api(params, 'ports/?ifAlias=%s' % args.string)
2019-07-24 09:07:02 +00:00
data_devices = call_api(params, 'devices/')
devices = data_devices['devices']
2017-11-13 10:20:29 +00:00
2017-11-13 20:17:35 +00:00
if data['count'] < 1:
print("No port found for description %s on instance %s" %
(args.string, instance))
2017-11-13 20:17:35 +00:00
return
2017-11-13 10:20:29 +00:00
2019-07-24 09:07:02 +00:00
if args.short:
2019-07-23 18:52:42 +00:00
term_cols = getattr(shutil.get_terminal_size((80, 20)), 'columns')
2020-02-13 07:55:23 +00:00
value_cols = term_cols - 59
2019-07-24 09:07:02 +00:00
2020-02-13 07:55:23 +00:00
print("(0l" + "q" * 27 + "w" + "q" * 18 + "w" + "q" * 7 + "w" + "q" * (term_cols - 57) + "k(B")
print("(0x(B %-25.25s (0x(B %-16.16s (0x(B %-5.5s (0x(B %-*.*s (0x(B" %
("Hostname", "Interface", "State", value_cols, value_cols, "Description"))
print("(0t" + "q" * 27 + "n" + "q" * 18 + "n" + "q" * 7 + "n" + "q" * (term_cols - 57) + "u(B")
2019-07-23 18:52:42 +00:00
2019-07-24 09:07:02 +00:00
for port in data['ports'].values():
if port['disabled'] == "1": continue
2019-01-16 10:43:54 +00:00
if port['deleted'] == "1": continue
if port['device_id'] in devices:
device = devices[port['device_id']]
else:
continue
2019-07-24 09:07:02 +00:00
if device['disabled'] == "1": continue
2019-07-24 09:07:02 +00:00
if args.short:
#short_hostname = device['hostname'].split(".",1)[0]
short_hostname = ".".join(device['hostname'].split(".")[0:-1])
2020-02-13 07:55:23 +00:00
print("(0x(B %-25.25s (0x(B %-16.16s (0x(B %-5.5s (0x(B %-*.*s (0x(B" %
(short_hostname, port['port_label_short'], port['ifOperStatus'], value_cols,
value_cols, port['ifAlias']))
#value_cols, port['port_descr_descr'] or port['ifAlias']))
2019-07-24 09:07:02 +00:00
else:
address = call_api(params, 'address/?device_id=%s&interface=%s' % (port['device_id'], port['port_label_short']))
address6 = call_api(params, 'address/?af=ipv6&device_id=%s&interface=%s' % (port['device_id'], port['port_label_short']))
term_cols = getattr(shutil.get_terminal_size((80, 20)), 'columns')
print("(0l" + "q" * 20 + "w" + "q" * (term_cols - 23) + "k(B")
print_data(term_cols, "Device", device['hostname'])
print_data(term_cols, "", "%s/device/device=%s" %
(params['base_url'], port['device_id']))
print_data(term_cols, "Hardware", device['hardware'])
print_data(term_cols, "Port", port['port_label_short'])
print_data(term_cols, "", "%s/device/device=%s/tab=port/port=%s/" %
(params['base_url'], port['device_id'], port['port_id']))
print_data(term_cols, "Description", port['ifAlias'])
print_data(term_cols, "Port status", "%s (Admin) / %s (Oper)" %
(port['ifAdminStatus'], port['ifOperStatus']))
print_data(term_cols, "Last change", port['ifLastChange'])
print_data(term_cols, "Speed", port['ifHighSpeed'], "Mbps")
print_data(term_cols, "Duplex", port['ifDuplex'])
print_data(term_cols, "MTU", port['ifMtu'])
for ip in address['addresses']:
print_data(term_cols, "IP address", "%s/%s" % (ip['ipv4_address'],ip['ipv4_prefixlen']))
for ip6 in address6['addresses']:
print_data(term_cols, "IPv6 address", "%s/%s" % (ip6['ipv6_compressed'],ip6['ipv6_prefixlen']))
2019-09-02 06:35:05 +00:00
print_data(term_cols, "Input rate", "%s (%s)" % (
sizeof_fmt(int(port['ifInOctets_rate']),suffix='Bps'),
sizeof_fmt(int(port['ifInOctets_rate'])*8,suffix='bps',binary=False),
)
)
print_data(term_cols, "Output rate", "%s (%s)" % (
sizeof_fmt(int(port['ifOutOctets_rate']),suffix='Bps'),
sizeof_fmt(int(port['ifOutOctets_rate'])*8,suffix='bps',binary=False),
)
)
2019-07-24 09:07:02 +00:00
print_data(term_cols, "Input errors rate", port['ifInErrors_rate'])
print_data(term_cols, "Output errors rate", port['ifOutErrors_rate'])
print("(0m" + "q" * 20 + "v" + "q" * (term_cols - 23) + "j(B")
if args.short:
2020-02-13 07:55:23 +00:00
print("(0m" + "q" * 27 + "v" + "q" * 18 + "v" + "q" * 7 + "v" + "q" * (term_cols - 57) + "j(B")
2019-07-23 18:52:42 +00:00
def search_devices(args):
if args.field == "location":
args.field = "location_text"
for instance, params in cfg['instances'].items():
2021-03-03 16:46:29 +00:00
if args.instance is not None and instance not in args.instance.split(','):
continue
2019-07-23 18:52:42 +00:00
data = call_api(params, 'devices/?%s=%s' % (args.field, args.string))
if data['count'] < 1:
2020-04-16 07:52:20 +00:00
print("No device found for %s %s on instance %s" %
(args.field, args.string, instance))
2021-03-03 16:46:29 +00:00
continue
2017-11-13 10:20:29 +00:00
2019-07-24 09:07:02 +00:00
if args.short:
term_cols = getattr(shutil.get_terminal_size((80, 20)), 'columns')
2021-03-03 16:46:29 +00:00
value_cols = term_cols - 90
2019-07-24 09:07:02 +00:00
2021-03-03 16:46:29 +00:00
print("(0l" + "q" * 27 + "w" + "q" * 28 + "w" + "q" * 28 + "w" + "q" * (term_cols - 88) + "k(B")
print("(0x(B %-25.25s (0x(B %-26.26s (0x(B %-26.26s (0x(B %-*.*s (0x(B" %
("Hostname", "Hardware", "Software", value_cols, value_cols, "Serial"))
print("(0t" + "q" * 27 + "n" + "q" * 28 + "n" + "q" * 28 + "n" + "q" * (term_cols - 88) + "u(B")
2019-07-24 09:07:02 +00:00
2019-07-23 18:52:42 +00:00
for device in data['devices'].values():
if device['disabled'] == "1": continue
2019-07-24 09:07:02 +00:00
if args.short:
short_hostname = ".".join(device['hostname'].split(".")[0:-1])
2021-03-03 16:46:29 +00:00
print("(0x(B %-25.25s (0x(B %-26.26s (0x(B %-26.26s (0x(B %-*.*s (0x(B" %
2019-07-24 09:07:02 +00:00
(short_hostname,
" ".join([device['vendor'] or "", device['hardware'] or ""]),
2021-03-03 16:46:29 +00:00
" ".join([device['os_text'], device['version'] or ""]),
2019-07-24 09:07:02 +00:00
value_cols, value_cols, device['serial']))
else:
term_cols = getattr(shutil.get_terminal_size((80, 20)), 'columns')
print("(0l" + "q" * 20 + "w" + "q" * (term_cols - 23) + "k(B")
print_data(term_cols, "Device", device['hostname'])
print_data(term_cols, "", "%s/device/device=%s" %
(params['base_url'], device['device_id']))
print_data(term_cols, "System name", device['sysName'])
print_data(term_cols, "Hardware", " ".join([device['vendor'] or "", device['hardware'] or ""]))
print_data(term_cols, "Software version",
" ".join([device['os_text'],
device['version'] or ""]))
if device['features']:
print_data(term_cols, "Features", device['features'])
print_data(term_cols, "Serial number", device['serial'])
print_data(term_cols, "Location", device['location'])
print("(0m" + "q" * 20 + "v" + "q" * (term_cols - 23) + "j(B")
if args.short:
2021-03-03 16:46:29 +00:00
print("(0m" + "q" * 27 + "v" + "q" * 28 + "v" + "q" * 28 + "v" + "q" * (term_cols - 88) + "j(B")
2019-07-24 09:07:02 +00:00
2022-01-10 09:29:28 +00:00
# Test instances
for instance in list(cfg['instances']):
test = call_api(cfg['instances'][instance], 'devices')
if test is None:
if cfg['debug']: print("Instance %s is not working, disabling" % instance)
cfg['instances'].pop(instance)
else:
if cfg['debug']: print("Instance %s is working" % instance)
2017-11-13 10:20:29 +00:00
# Argument parsing
parser = argparse.ArgumentParser()
2021-03-03 16:46:29 +00:00
parser.add_argument('-i','--instance', type=str, help="Comma-separated list of Observium instances to use",nargs='?', default=None)
subparsers = parser.add_subparsers(help='Action to perform',dest='action',required=True)
2019-07-23 18:52:42 +00:00
2017-11-13 10:20:29 +00:00
parser_search_port_by_descr = subparsers.add_parser('search_ports', help="Search ports by description")
parser_search_port_by_descr.add_argument('string', type=str, help="String to search")
2019-07-24 09:07:02 +00:00
parser_search_port_by_descr.add_argument('-s', '--short', action='store_true')
2017-11-13 10:20:29 +00:00
2019-07-23 18:52:42 +00:00
parser_search_device = subparsers.add_parser('search_devices', help="Search devices")
2019-07-24 09:07:02 +00:00
parser_search_device.add_argument('field', choices=['hostname', 'location', 'hardware', 'serial'], help="Field to use for search")
2019-07-23 18:52:42 +00:00
parser_search_device.add_argument('string', type=str, help="String to search")
2019-07-24 09:07:02 +00:00
parser_search_device.add_argument('-s', '--short', action='store_true')
2019-07-23 18:52:42 +00:00
2017-11-13 10:20:29 +00:00
args = parser.parse_args()
globals()[args.action](args)