#!/usr/bin/env python3 # -*- coding: utf-8 -*- #************************************************************************** # Copyright (C) 2017, Paul Lutus * # * # This program is free software; you can redistribute it and/or modify * # it under the terms of the GNU General Public License as published by * # the Free Software Foundation; either version 2 of the License, or * # (at your option) any later version. * # * # This program is distributed in the hope that it will be useful, * # but WITHOUT ANY WARRANTY; without even the implied warranty of * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # GNU General Public License for more details. * # * # You should have received a copy of the GNU General Public License * # along with this program; if not, write to the * # Free Software Foundation, Inc., * # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #************************************************************************** import os import re import base64 import getpass import requests import ezodf def read_file(path): with open(path) as f: return f.read() def write_file(path, data): with open(path, 'w') as f: f.write(data) # quits the program if no entry def user_input(prompt): result = input(prompt).strip() if result: return result print("No entry, quitting.") quit() # returns true on success def ping_device(device, wait=300): return os.system('ping -c 1 -w %d %s > /dev/null 2>&1' % (wait, device)) == 0 # change these values as required router_name_prefix = 'pl-wireless' router_name_suffix = user_input('Which router (a-d):') ping_url = '%s-%s' % (router_name_prefix, router_name_suffix) # verify router is online if not ping_device(ping_url, 3): print("router %s not online, quitting." % ping_url) quit() password = getpass.getpass('Enter router password:') # change username as required user_pw_str = 'root:%s' % password # this is the source for the encoded user:password datum authorization = base64.b64encode(user_pw_str.encode()).decode('ascii') # construct HTTP URL for target router base_url = 'http://%s' % ping_url # get a session instance to avoid having to copy state # from one router acccess to another rs = requests.session() # the following two items -- 'Cookie' and 'Referer' -- # are all that are required to access the router # any number of times rs.headers['Cookie'] = 'Authorization=Basic%20' + authorization # the Referer item tells the router that the network # accesses are emanating from the router itself rs.headers['Referer'] = base_url # Router access 1: test login validity response = rs.get(base_url) # quit if login test fails if re.search('(?i)username or password is incorrect', response.text): print('Wrong username and/or password, quitting.') quit() print('Username and password validated with %s, continuing.' % ping_url) # change the spreadsheet document name/path as required ss_doc_name = 'name_MAC_IP_master_list.ods' print("Reading spreadsheet %s ..." % ss_doc_name) doc = ezodf.opendoc(ss_doc_name) sheet = doc.sheets[0] first_record = True for record in sheet.rows(): # first spreadsheet record contains field names if first_record: ss_names = [field.value for field in record] # use field names as keys to fields ss_data = {name:[] for name in ss_names} first_record = False else: # move record data name_iter = iter(ss_names) for field in record: ss_data[next(name_iter)].append(field.value) print('Creating name/ip data arrays ...') data_dict = {} mac_iter = iter(ss_data['MAC']) ip_iter = iter(ss_data['IP']) for name in ss_data['Name']: mac = next(mac_iter) ip = next(ip_iter) # verify that the record contains non-empty fields if name and mac and ip: # create reliably sortable IP string long_ip = '.'.join([ns.zfill(3) for ns in re.findall(r'\d+', ip)]) # t-link routers require a nonstandard mac syntax: : -> - router_mac = re.sub(':', '-', mac) # data_dict uses sortable long form ip address data_dict[long_ip] = [ip, name, mac, router_mac] # Router access 2: wipe any existing reserved address list print('Deleting all prior reserved addresses in %s ...' % ping_url) url = "%s/userRpm/FixMapCfgRpm.htm?doAll=DelAll&Page=1" % base_url rs.get(url) # create hosts_insert data hosts_insert = "# this data insert created by %s\n" % os.path.realpath(__file__) table_content = '' # Router access 3: create new reserved address list print('Creating new reserved addresses in %s ...' % ping_url) total = 0 for long_ip in sorted(data_dict): ip, name, mac, router_mac = data_dict[long_ip] hosts_insert += "%-16s %12s %12s.com\n" % (ip, name, name) s = "Name: %-18s MAC: %s IP: %s" % (name, mac, long_ip) print(s) table_content += "%s\n" % s # exclude router from reserved address list if not re.search(router_name_prefix, name): url = '%s/userRpm/FixMapCfgRpm.htm' % base_url + \ '?Mac=%s&Ip=%s&State=1&Changed=0' % (router_mac, ip) + \ '&SelIndex=0&Page=1&Save=Save' rs.get(url) total += 1 print('Created %d reserved addresses in %s.' % (total, ping_url)) write_file('name_mac_ip_table.txt', table_content) # insert generated IP/name list into the system "hosts" file # which contains insertion comment marks: # # BEGIN_INSERT and # END_INSERT # change this path as required hosts_path = '/netbackup/data/python_projects/hosts_file/hosts_base_do_not_delete' hosts = read_file(hosts_path) hosts = re.sub('(?s)(?<=# BEGIN_INSERT\n)(.*?)(?=# END_INSERT)', hosts_insert, hosts) write_file(hosts_path, hosts) # Router access 4: reboot router response = user_input('Okay to reboot router %s (y/n): ' % ping_url) if response.lower() == 'y': reboot_url = "%s/userRpm/SysRebootRpm.htm?Reboot=Reboot" % base_url rs.get(reboot_url) print('Router %s rebooted, done.' % ping_url)