#! /usr/bin/python3 # coding=utf-8 import time import paramiko import MySQLdb import json q1c = "SELECT REPLACE(hw_addr, ':','') as hw_addr, " \ "serial, " \ "net_num " \ "FROM dhcp4.1c_import " \ "where imported = 0;" qleases4 = "SELECT INET_NTOA(address) as ip4, " \ "HEX(hwaddr)as hw_addr, hostname, " \ "expire, " \ "valid_lifetime " \ "FROM lease4 " \ "where INET_NTOA(address) like '10.5.0%';" qhosts_ip = "SELECT " \ "INET_NTOA(ipv4_address) AS ipv4_address " \ "FROM dhcp4.hosts;" qinsert_hosts = "START TRANSACTION; " \ "SET @ipv4_reservation='%s'; " \ "SET @hostname = '%s'; " \ "SET @identifier_type='hw-address'; " \ "SET @identifier_value='%s'; " \ "SET @dhcp4_subnet_id=1024; " \ "INSERT INTO hosts ( dhcp_identifier, " \ " dhcp_identifier_type, " \ " dhcp4_subnet_id, " \ " ipv4_address, " \ " hostname) " \ "VALUES ( " \ "UNHEX(@identifier_value)," \ " (SELECT type FROM host_identifier_type WHERE name=@identifier_type)," \ " @dhcp4_subnet_id," \ " INET_ATON(@ipv4_reservation)," \ " @hostname); " \ "COMMIT;" qupdate_1c = "update 1c_import set imported = 1 where serial = '%s';" def send_data(user, password, name, host): errorcode = '' # work = True commands = [] # commands.append("hostname %s" % name) # commands.append("echo '%s' > /etc/hostname" % name) # commands.append("echo 'hostname=%s' > /etc/network.conf.factory" % name) # commands.append("echo 'dhcp=true' >> /etc/network.conf.factory") # commands.append("echo 'hostname=%s' > /config/network.conf" % name) # commands.append("echo 'dhcp=true' >> /config/network.conf") # commands.append("sync") commands.append("/sbin/reboot \n") client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # если нет хоста - добавляем try: client.connect(hostname=host, username=user, password=password, look_for_keys=False, allow_agent=False) # пытаемся подключиться, look_for_keys=False, allow_agent=False - зачем-то # нужны циске. except Exception as exept: # в случае исключения - errorcode = exept # возвращаем код и описание исключения else: # усли все в порядке conn = client.invoke_shell() # врубаем интерактивный шелл - с цисками только так. time.sleep(1) # задержка conn.recv(1000) # хаваем все, что выплюнула, дабы не отсвечивало (ограничиваю 1000 строк) # conn.send("head -n 1 /config/network.conf\n") # time.sleep(1) # h = conn.recv(100) # if "hostname=" + name in h: # work = False work = True # ЗАГЛУШКА!!! В данном случае условия не проверяются. if work: print(name, host, "will reboot") for command in commands: # Читаем и исполняем команды conn.send(command + '\n') # засылаем команду time.sleep(0.1) # ждем указанный таймаут conn.recv(99999999999) # хаваем его в никуда else: print("nothing to do") finally: # по окончании всех процедур client.close() # закрываем коннектий return errorcode # Вертаем все, что наковыряли def read_table(sql, dbhost, dbuser, dbpass, dbbase): try: conn = MySQLdb.connect(host=dbhost, user=dbuser, passwd=dbpass, db=dbbase) except MySQLdb.Error as err: print("Connection error: {}".format(err)) conn.close() try: cur = conn.cursor(MySQLdb.cursors.DictCursor) cur.execute(sql) data = cur.fetchall() except MySQLdb.Error as err: print("Query error: {}".format(err)) conn.close() return data def first_free_ip(ips, ip_pool, octet1, octet2, octet3): locked_ip = [] octet4 = '' set_octets = False for ip in ips: octets = ip['ipv4_address'].split('.') if not set_octets: octet1 = octets[0] octet2 = octets[1] set_octets = True if octets[2] == str(octet3): locked_ip.append(octets[3]) i = int(ip_pool[0]) while i < int(ip_pool[1]): if not str(i) in locked_ip: octet4 = str(i) break i = i + 1 if octet4 == '': return '' else: return "%s.%s.%s.%s" % (octet1, octet2, octet3, octet4) def make_hosts(sql, ip, hostname, hw_addr, dbhost, dbuser, dbpass, dbbase): try: conn = MySQLdb.connect(host=dbhost, user=dbuser, passwd=dbpass, db=dbbase) except MySQLdb.Error as err: print("Connection error: {}".format(err)) conn.close() try: cur = conn.cursor(MySQLdb.cursors.DictCursor) cur.execute(sql % (ip, hostname, hw_addr)) data = cur.fetchall() cur.close() except MySQLdb.Error as err: print("Query error: {}".format(err)) try: cur = conn.cursor(MySQLdb.cursors.DictCursor) print(qupdate_1c % hostname) cur.execute(qupdate_1c % hostname) data = cur.fetchall() cur.close() except MySQLdb.Error as err: print("Query error: {}".format(err)) conn.commit() conn.close() return data def read_conf(): conf = json.load(open('config.json')) return conf def main(): conf = read_conf() data_1c = read_table(q1c, conf['dbhost'], conf['dbuser'], conf['dbpass'], conf['dbbase']) data_leases = read_table(qleases4, conf['dbhost'], conf['dbuser'], conf['dbpass'], conf['dbbase']) for line in data_1c: set_ip = first_free_ip(read_table(qhosts_ip, conf['dbhost'], conf['dbuser'], conf['dbpass'], conf['dbbase']), conf['ippool'], conf['ip_oct1'], conf['ip_oct2'], line['net_num']) set_hw_addr = line['hw_addr'] set_host = line['serial'] make_hosts(qinsert_hosts, set_ip, set_host, set_hw_addr, conf['dbhost'], conf['dbuser'], conf['dbpass'], conf['dbbase']) print('host built name %s, mac %s, ip %s' % (set_host, set_hw_addr, set_ip)) for line in data_1c: for lease in data_leases: if line['hw_addr'] == lease['hw_addr']: send_data(conf['sshuser'], conf['sshpass'], line['serial'], lease['ip4']) if __name__ == '__main__': main()