From 776ecd99a1223bd63fe97acca0867332b11862f9 Mon Sep 17 00:00:00 2001 From: Mikhail Grebenkin Date: Thu, 1 Feb 2018 21:18:14 +0300 Subject: [PATCH] initial commit --- SetupMinersClass.py | 130 ++++++++++++++++++++ __pycache__/SetupMinersClass.cpython-35.pyc | Bin 0 -> 4673 bytes __pycache__/aw_sender.cpython-35.pyc | Bin 0 -> 3647 bytes aw_sender.py | 103 ++++++++++++++++ config.json | 11 ++ miner_reboot.py | 42 +++++++ 6 files changed, 286 insertions(+) create mode 100644 SetupMinersClass.py create mode 100644 __pycache__/SetupMinersClass.cpython-35.pyc create mode 100644 __pycache__/aw_sender.cpython-35.pyc create mode 100755 aw_sender.py create mode 100644 config.json create mode 100755 miner_reboot.py diff --git a/SetupMinersClass.py b/SetupMinersClass.py new file mode 100644 index 0000000..a434ee5 --- /dev/null +++ b/SetupMinersClass.py @@ -0,0 +1,130 @@ +#! /usr/bin/python3 +# coding=utf-8 + +import telnetlib +import json +import paramiko +import time + + +class SSHSetup: + def __init__(self, host, port, user, passwd, comlist=[]): + self.host = host + self.user = user + self.passwd = passwd + self.port = port + try: + self.client = paramiko.SSHClient() + self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.client.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, + look_for_keys=False, allow_agent=False) + self.ssh = self.client.invoke_shell() + time.sleep(1) + self.ssh.recv(10000) + except Exception as exc: + raise Exception('ssh error: {}'.format(exc)) + if len(comlist) > 0: + if 'exit' not in comlist: + comlist.append('exit') + self.sendall(comlist) + self.close() + + def send(self, command): + self.ssh.send(command + '\n') + time.sleep(1) + self.ssh.recv(10000).decode() + + def sendall(self, commlist=[]): + for command in commlist: + self.send(command) + + def close(self): + self.ssh.close() + + +class TelnetSetup: + def __init__(self, host, port, user, passwd, comlist=[]): + self.host = host + self.port = port + self.user = user + self.passwd = passwd + try: + self.tn = telnetlib.Telnet(host, port) + except Exception as exc: + raise Exception('telnet error: {}'.format(exc)) + + if len(comlist) > 0: + if 'exit' not in comlist: + comlist.append('exit') + self.login() + self.sendall(comlist) + self.close() + + def login(self): + self.tn.read_until(b'login:') + self.tn.write(self.user.encode('utf8') + b'\n') + self.tn.read_until(b'Password:') + self.tn.write(self.passwd.encode('utf8') + b'\n') + self.tn.read_until(self.user.encode('utf8')) + + def send(self, command): + self.tn.write(command.encode('utf8') + b'\n') + self.tn.read_until(self.user.encode('utf8')) + + def sendall(self, comlist=[]): + for command in comlist: + self.send(command) + + def close(self): + self.tn.close() + + +class SetupMiner: + def __init__(self, host, conf={}, telnets=[], sshs=[]): + self.host = host + self.conf = conf + if len(telnets) == 0: + self.telnets = ["exit"] + else: + self.telnets = telnets + if len(sshs) == 0: + self.sshs = ["exit"] + else: + self.sshs = sshs + try: + TelnetSetup(self.host, self.conf['telnetport'], self.conf['telnetuser'], self.conf['telnetpass'], + self.telnets) + self.result = "telnet OK; " + except Exception as exc: + self.result = "{}; ".format(exc) + try: + SSHSetup(self.host, self.conf['sshport'], self.conf['sshuser'], conf['sshpass'], self.sshs) + self.result += '\n ssh OK' + except Exception as exc: + self.result += '\n {}; '.format(exc) + + def ret_result(self): + return self.result + + +def read_conf(): + with open('config.json') as f: + conf = json.load(f) + return conf + + +def main(): + conf = read_conf() + minerconf = {"sshuser": conf["sshuser"], + "sshpass": conf["sshpass"], + "sshport": conf["sshport"], + "telnetuser": conf["telnetuser"], + "telnetpass": conf["telnetpass"], + "telnetport": conf["telnetport"]} + comlist = ["uname -a", "ps -A", "exit"] + s = SetupMiner('10.100.4.10', minerconf) + print(s.result) + + +if __name__ == '__main__': + main() diff --git a/__pycache__/SetupMinersClass.cpython-35.pyc b/__pycache__/SetupMinersClass.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47bc336959488ed4c61929d9ecd17bc30130cd95 GIT binary patch literal 4673 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 Vha|yo38er(``l_dTV5!u{{jxU>E-|c literal 0 HcmV?d00001 diff --git a/aw_sender.py b/aw_sender.py new file mode 100755 index 0000000..e726795 --- /dev/null +++ b/aw_sender.py @@ -0,0 +1,103 @@ +#! /usr/bin/python3 +# coding=utf-8 + +import requests +import json +import sys +from pyzabbix import ZabbixMetric, ZabbixSender + +hostname = 'hostname1' +zabbix_server = '10.3.2.5' +aw_url = 'http://10.5.0.1:17790/api/miners' + + +class AwZabbix: + def __init__(self, server, url, host): + self.url = url + self.server = server + self.host = host + self.data = '' + self.mult_dict = {'G': 1000000000, 'M': 1000000, 'T': 1000000000000, 'K': 1000, 'N': 0, } + self.packet = [] + self.lld_data = [] + + def get_data(self): + if len(self.data) == 0: + self.data = requests.get(self.url).json() + + def make_packet(self): + self.get_data() + if len(self.packet) != 0: + return self.packet + total_hashrate_raw = self.data['totalHashrate5s'] + if total_hashrate_raw: + hashrate_mult = self.mult_dict[total_hashrate_raw[-4:-3]] + total_hashrate = float(total_hashrate_raw[:-5].replace(',', '.')) * hashrate_mult + total_hashrate = int(total_hashrate) + self.packet.append(ZabbixMetric(self.host, 'total[hashrate]', total_hashrate)) + for group in self.data['groupList']: + for miner in group['minerList']: + hashrate_raw = miner['speedInfo']['hashrate'] + if hashrate_raw: + hashrate_mult = self.mult_dict[hashrate_raw[-4:-3]] + hashrate = float(hashrate_raw[:-5].replace(',', '.')) * hashrate_mult + hashrate = int(hashrate) + else: + hashrate = 0 + minername = str(miner['name']) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('hashrate', minername), hashrate)) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('ip', minername), miner['hostname'])) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('group', minername), miner['groupId'])) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('name', minername), miner['name'])) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('temp', minername), + miner['temperature'][:-3])) + self.packet.append(ZabbixMetric(self.host, "{}[{}]".format('status', minername), + miner['statusInfo']['statusDisplay'])) + return self.packet + + def send_packet(self): + if len(self.packet) == 0: + self.make_packet() + return ZabbixSender(self.server).send(self.packet) + + def lld(self): + self.get_data() + if len(self.lld_data) != 0: + return self.lld_data + self.lld_data = {} + jdat = [] + for group in self.data['groupList']: + for miner in group['minerList']: + jdat.append({"{#MINERID}": str(miner['id']), + "{#IP}": str(miner['hostname']), + "{#MINERNAME}": str(miner['name'])}) + self.lld_data = {'data': jdat} + return self.lld_data + + +def read_conf(): + with open('config.json') as f: + conf = json.load(f) + return conf + + +def main(): + conf = read_conf() + + z = AwZabbix(zabbix_server, aw_url, hostname) + + if len(sys.argv) == 1: + print(json.dumps(z.lld(), indent=4, sort_keys=True)) + elif len(sys.argv) == 2 and sys.argv[1] == 'send': + z.send_packet() + print(1) + elif len(sys.argv) == 2 and sys.argv[1] == 'send_debug': + print(z.send_packet()) + for i in z.packet: + print(i) + else: + print('Wrong args.') + + +if __name__ == '__main__': + main() diff --git a/config.json b/config.json new file mode 100644 index 0000000..8713788 --- /dev/null +++ b/config.json @@ -0,0 +1,11 @@ +{ + "sshuser":"root", + "sshpass":"admin", + "sshport":"22", + "telnetuser":"telnetd", + "telnetpass":"admin", + "telnetport":"23", + "hostname": "hostname1", + "zabbix_server": "", + "aw_url": "http://10.5.0.1:17790/api/miners" +} diff --git a/miner_reboot.py b/miner_reboot.py new file mode 100755 index 0000000..9c65764 --- /dev/null +++ b/miner_reboot.py @@ -0,0 +1,42 @@ +#! /usr/bin/python3 +# coding=utf-8 + +from aw_sender import AwZabbix +from SetupMinersClass import SetupMiner, read_conf +import sys +import json + + +def reboot_miner(miner, z, conf): + for miner_dat in z.lld()['data']: + if miner_dat["{#MINERNAME}"] == miner: + miner_ip = miner_dat['{#IP}'] + print(miner_ip) + s = SetupMiner(miner_ip, conf=conf, telnets=['shutdown -r now'], sshs=['shutdown -r now']) + print(s.result) + break + + +def main(): + conf = read_conf() + print(conf) + zabbix_server = conf["zabbix_server"] + aw_url = conf["aw_url"] + hostname = conf["hostname"] + minerconf = {"sshuser": conf["sshuser"], + "sshpass": conf["sshpass"], + "sshport": conf["sshport"], + "telnetuser": conf["telnetuser"], + "telnetpass": conf["telnetpass"], + "telnetport": conf["telnetport"]} + z = AwZabbix(zabbix_server, aw_url, hostname) + if len(sys.argv) == 1: + print('Need miner name to reboot as arg') + elif len(sys.argv) == 2 and sys.argv[1] == 'test': + print(z.lld()) + elif len(sys.argv) == 2: + print(reboot_miner(sys.argv[1], z, minerconf)) + + +if __name__ == '__main__': + main()