#!/usr/bin/env python ''' CLI interface which configures and makes new nodes with the most commonly used commands. Rick van der Zwet ''' import getrange import gformat import os import readline import sys print "WARNING I AM NOT PRODUCTION CODE YET!" + __doc__ DEBUG = "-g" in sys.argv def rlprompt(prompt, prefill=''): ''' Get line with some boring default ''' prompt = "%s [%s]: " % (prompt, prefill) if DEBUG: print prompt return prefill return raw_input(prompt) or prefill def rlinput(prompt, prefill=''): ''' Get line with some editable boring default ''' if DEBUG: print "%s [%s]:" % (prompt, prefill) return prefill readline.set_startup_hook(lambda: readline.insert_text(prefill)) try: return raw_input(prompt + ": ") finally: readline.set_startup_hook() def rlinput_float(prompt, prefill=0): while True: try: prefill = rlinput(prompt, prefill) return float(prefill) except ValueError: print "Invalid Number!" pass def rlinput_choices(prompt, choices, prefill=''): if DEBUG: print '%s [%s]:' % (prompt, prefill) return prefill while True: filtered_choices = sorted(list(set([x for x in choices if (str(prefill).lower() in str(x).lower())]))) if len(filtered_choices) == 1: return filtered_choices[0] elif len(filtered_choices) == 0: filtered_choices = choices prefill = rlinput(prompt + ' ' + str(filtered_choices), prefill) if prefill in prompt: return prefill def newNode(): datadump = { 'nodename' : "New", 'location' : "1234 AB, Leiden", 'nodetype' : "Hybrid", 'latitude' : "52.", 'longitude' : "4.", } datadump['nodename'] = rlprompt("Nodename", datadump['nodename']) datadump['location'] = rlprompt("Location", datadump['location']) datadump['nodetype'] = rlprompt("Nodetype", datadump['nodetype']) datadump['latitude'] = rlinput_float("Latitude", datadump['latitude']) datadump['longitude'] = rlinput_float("Longitude", datadump['longitude']) datadump['autogen_item'] = datadump['nodetype'] + datadump['nodename'] print "Generating the Master IP range..." master_network = getrange.get_ranges(False, 24, 1)[0] master_ip = getrange.showaddr(master_network + 1) datadump['master_ip'] = master_ip def new_access_point(): ifname = rlinput("Interface name", "ath0") datadump['iface_' + ifname] = { 'ip' : rlinput(" - IP", master_ip + "/26"), 'dhcp' : rlinput(" - DHCP range", "10-60"), 'ssid' : rlinput(" - SSID", "ap-WirelessLeiden-" + datadump['nodename']), 'mode' : 'ap', 'type' : '11b', 'comment' : rlinput(" - Comment", "Omni voor de Buurt"), 'sdesc': rlinput(" - Short Description", "2buurt"), 'channel' : rlprompt(" - Channel", "10"), 'status' : 'up', } newNode.if_nr = 0 def new_interlink(link_type='wireless', link_mode='station'): ifname = rlinput("Interface name", "vr%i" % newNode.if_nr) newNode.if_nr = newNode.if_nr + 1 netmask = 28 if link_mode == 'station': remote = rlinput_choices("Create interlink with (remote host)", gformat.get_hostlist(),'Hybrid') remote_datadump = gformat.get_yaml(remote) print "Available remote interfaces:" if_choices = [] for ifkey in remote_datadump['autogen_iface_keys']: ifdump = remote_datadump[ifkey] # Could only do this if all meta information is correct #if link_type == 'wireless' and link_mode == 'station': # basedump = remote_datadump['iface_' + ifdump['autogen_ifbase']] # if not basedump.has_key('mode') or basedump['mode'] != 'ap-wds': # continue if_choices.append(ifdump['autogen_ifbase']) print " - %4s" % ifdump['autogen_ifbase'], '- %20s' % ifdump['ip'], '- %30s' % ifdump['comment'], if ifdump.has_key('ssid'): print '-', ifdump['ssid'] else: print '' iface = rlinput_choices("Remote interface", if_choices) ifdump = remote_datadump['iface_%s' % iface] #make_alias = rlprompt("Create Alias", "no") == "yes" link_network = gformat.network(ifdump['ip']) elif link_mode == 'master': remote = rlinput("Interlink is planned for (remote host)", 'Unused%s' % newNode.if_nr) print "Generating the Interlink IP range..." link_network = getrange.get_ranges(True, netmask, 1)[0] print "Using Network %s/%s" % (gformat.showaddr(link_network), netmask) # XXX: Create remote linking # XXX: This does not handle IP pools # Common part datadump['iface_%s' % ifname] = { 'comment': rlinput(" - Comment", "Link naar " + remote), 'sdesc': rlinput(" - Short Description", "2" + remote), 'type': "eth", 'status': 'up', 'dhcp': 'False', } if link_type == 'wireless': compass = rlprompt("Compass direction", 'n') datadump['iface_%s' % ifname].update({ 'ns_mac': rlinput(" - NS MAC", "00:27:22:"), 'bridge_type': rlinput(' - Bridge Type', 'NanoStation5M'), 'compass': compass, }) if link_mode == 'master': datadump['iface_%s' % ifname].update({ 'ssid': rlinput(" - SSID", 'il-%s.%s.wleiden.net' % (compass, datadump['nodename'])), 'ip': rlinput(" - IP", getrange.showaddr(link_network + 1) + "/" + str(netmask)), 'ns_ip': rlinput(" - NS IP", getrange.showaddr(link_network + 2) + "/" + str(netmask)), 'mode': "ap-wds", }) elif link_mode == 'station': datadump['iface_%s' % ifname].update({ 'ssid': rlinput(" - SSID", ifdump['ssid']), 'ip': rlinput(" - IP", getrange.showaddr(link_network + 3) + "/" + str(netmask)), 'ns_ip': rlinput(" - NS IP", getrange.showaddr(link_network + 4) + "/" + str(netmask)), 'mode': "station-wds", }) elif link_type == 'wired': if link_mode == 'master': datadump['iface_%s' % ifname].update({ 'ip': rlinput(" - IP", getrange.showaddr(link_network + 1) + "/" + str(netmask)), }) elif link_mode == 'station': datadump['iface_%s' % ifname].update({ 'ip': rlinput(" - IP", getrange.showaddr(link_network + 2) + "/" + str(netmask)), }) def printMenu(): print '''\ ========================================== Create Interfaces 1) New Accesspoint (ath0) 2) New Wired Interlink (station) 3) New Wired Interlink (master) 4) New Wireless Interlink (station) 5) New Wireless Interlink (master) 9) Finish and Save ========================================== ''' choice = 5 while choice != 9: printMenu() choice = int(rlprompt("Choice", choice)) if choice == 1: new_access_point() elif choice == 2: new_interlink('wired', 'station') elif choice == 3: new_interlink('wired', 'master') elif choice == 4: new_interlink('wireless', 'station') elif choice == 5: new_interlink('wireless', 'master') else: print "Invalid choice!" # Output final result print datadump #os.mkdir(datadump['autogen_item']) #gformat.store_yaml(datadump) if __name__ == '__main__': def printMenu(): print '''\ ========================================== Node File Editor by Rick van der Zwet 1) New Node 9) Quit ========================================== ''' printMenu() choice = 1 while choice != 9: choice = int(rlprompt("Choice", choice)) if choice == 9: break elif choice == 1: newNode() printMenu() sys.exit(1) else: print "Invalid choice!"