From: Michael Rasmussen Date: Wed, 12 Apr 2017 20:40:25 +0000 (+0200) Subject: test highlight X-Git-Url: http://git.datanom.net/netconf.git/commitdiff_plain/4b6fdffed694745b66e33ac058e9bdddfa7d3df3 test highlight --- diff --git a/netconf.py b/netconf.py new file mode 100644 index 0000000..3dd1d37 --- /dev/null +++ b/netconf.py @@ -0,0 +1,322 @@ +#!/usr/bin/env python +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 +# + +# +# The porpuse of this script is to help with basic and/or initial +# network configuration for Illumos based distribution. However, +# the script is developed specifically for OmniOS so there is no +# garaunty that it will work on other Illumos based distributions +# than Omnios. +# + +import sys, subprocess, getopt + +def runcmd(cmd): + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + output, error = process.communicate(); + + return (output.rstrip(), error.rstrip()) + +class ParserError(Exception): + pass + +class Parser: + """ Parse nic information """ + + def __init__(self): + self.__dladm1 = "dladm show-phys -p -o link,media | sed 's/:/ /g'" + self.__dladm2 = "dladm show-phys -p -m -o link,address,inuse | sed 's/:/ /g' | sed 's/\\\[[:space:]]/:/g' | sed 's/\\\//g'" + + def __parse_nics(self, text): + nics = {} + for line in text.splitlines(): + parts = line.split() + #if parts[1] in ('Ethernet', 'Infiniband'): + if parts[1] in ('Ethernet'): + nics[parts[0]] = [parts[0], parts[1]] + + return nics + + def __parse_macs(self, obj, text): + list = [] + if obj: + for line in text.splitlines(): + parts = line.split() + try: + if parts[2] == 'yes': + del obj[parts[0]] + else: + obj[parts[0]].append(parts[1]) + except KeyError: + pass + for k, v in obj.items(): + list.append(v) + + return list + + def parse(self): + (nics, error) = runcmd(self.__dladm1) + if error: + raise ParserError(error) + + (macs, error) = runcmd(self.__dladm2) + if error: + raise ParserError(error) + + return self.__parse_macs(self.__parse_nics(nics), macs) + +def get_terminal_width(): + try: + if sys.version_info >= (2,7): + width = int(subprocess.check_output(['tput', 'cols'])) + else: + (out, err) = runcmd('tput cols') + if err: + raise OSError(err); + width = int(out) + except OSError as e: + print("Invalid Command 'tput cols': exit status ({1})".format(e.errno)) + except subprocess.CalledProcessError as e: + print("Command 'tput cols' returned non-zero exit status: ({1})".format(e.returncode)) + else: + return width + +def make_menu(interfaces): + res = None + while not res: + sys.stderr.write("\x1b[2J\x1b[H") + cols = get_terminal_width() + intro = 'The following unconfigured interfaces was discovered' + fill = (cols / 2) - (len(intro) / 2) + print '{0:^{cols}}'.format('Simple network interface configuration tool', cols=cols) + print + print '{0:<{fill}}{1}'.format('', intro, fill=fill) + print '{0:<{fill}}{1:>2} {2:^15} {3:^10} {4:^17}'.format('','#','Interface','Media','MAC',fill=fill) + print '{0:<{fill}}{1:-^2} {2:-^15} {3:-^10} {4:-^17}'.format('','','','','',fill=fill) + + n = 0 + for i in interfaces: + print '{0:<{fill}}{1:>2} {2:<15} {3:<10} {4:>17}'.format('',n,i[0],i[1],i[2],fill=fill) + n += 1 + print + print '{0:<{fill}}{1:<}'.format('','select interface number to configure:',fill=fill), + nic = int(raw_input()) + if nic >= n or nic < 0: + print '{0:<{fill}}{1:<} {2:<}'.format('','Error: Interface: 0 <= # <',n,fill=fill), + raw_input(' << Hit any key >>') + else: + res = interfaces[nic] + + return res + +def get_config(): + ip = mask = gw = None + nettype = raw_input('dhcp or static [dhcp]: ').lower() + if nettype == 'static': + while not ip: + ip = raw_input('Enter IP: ') + mask = raw_input('Enter netmask [24]: ') + if not mask: + mask = 24 + gw = raw_input('Enter default route [0=no]: ') + if not gw: + gw = 0 + + return (ip,mask,gw) + +def usage(): + print 'Usage: %s [options]' % sys.argv[0] + print + print '%s' % """Options: + -h, --help This usage. + -a, --address IP for interface. 0 means use DHCP + -g, --gateway Default gateway. Optional. + -i, --interface Interface to configure. + -m, --netmask Netmask to use for interface. Default /24. + -n, --nameserver Nameserver to use. Optional. + -r, --record Output create commands to stdout.""" + +def parse_input(): + options = () + + try: + opts, args = getopt.gnu_getopt(sys.argv[1:], + 'ha:g:i:m:n:r', ['help', 'address=', 'gateway=', + 'interface=', 'netmask=', 'nameserver=', 'record']) + except getopt.GetoptError as err: + print str(err) + usage() + sys.exit(2) + + address = gateway = interface = netmask = nameserver = None + record = False + + if opts: + for o, a in opts: + if o in ('-h', '--help'): + usage() + sys.exit(0) + if o in ('-a', '--address'): + address = a + elif o in ('-g', '--gateway'): + gateway = a + elif o in ('-i', '--interface'): + interface = a + elif o in ('-m', '--netmask'): + netmask = a + elif o in ('-n', '--nameserver'): + nameserver = a + elif o in ('-r', '--record'): + record = True + else: + assert False, 'Unhandled option' + + if (record): + if (bool(address) ^ bool(interface)): + print 'Error: missing options' + usage() + sys.exit(2) + else: + if not address or not interface or error: + print 'Error: missing options' + usage() + sys.exit(2) + + if address == '0': + address = None + if not netmask: + netmask = '24' + + options = (interface, address, netmask, gateway, nameserver, record) + + return options + +def main(): + interactive = True + record = False + output = '' + + options = parse_input() + if options: + record = options[5] + if (options[0]): + interactive = False + + p = Parser() + try: + interfaces = p.parse() + if interfaces: + if interactive: + nic = make_menu(interfaces) + else: + nic = options + found = False + for i in interfaces: + if nic[0] == i[0]: + found = True + break + if not found: + err = '%s: No such interface' % nic[0] + raise RuntimeError(err) + if nic: + if interactive: + (ip,mask,gw) = get_config() + else: + ip = options[1] + mask = options[2] + gw = options[3] + cmd = 'ipadm delete-if %s' % nic[0] + if record: + output += cmd + else: + runcmd(cmd) + cmd = 'ipadm create-if %s' % nic[0] + if record: + output += "\n" + cmd + else: + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + if not ip: + # use DHCP + cmd = 'ipadm create-addr -T dhcp %s/v4' % nic[0] + if record: + output += "\n" + cmd + else: + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + else: + # use STATIC + cmd = 'ipadm create-addr -T static -a %s/%s %s/v4' % (ip, mask, nic[0]) + if record: + output += "\n" + cmd + else: + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + if gw: + cmd = 'route -p add default %s' % gw + if record: + output += "\n" + cmd + else: + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + if not record: + cmd = 'netstat -rn -finet' + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + print 'New route table' + print out + if interactive: + dns = raw_input('Configure DNS [n]? ').lower() + else: + dns = options[4] + if not dns or dns == 'n': + pass + else: + if interactive: + dns = None + print + while not dns: + dns = raw_input('Enter nameserver: ') + + cmd = "echo 'nameserver %s' >> /etc/resolv.conf " % dns + cmd += '&& cp /etc/nsswitch.conf{,.bak} ' + cmd += '&& cp /etc/nsswitch.{dns,conf}' + if record: + output += "\n" + cmd + else: + (out, err) = runcmd(cmd) + if err: + raise RuntimeError(err) + if record: + print output + else: + print "Found no unassigned interfaces" + except ParserError as e: + print 'Parse Errror: %s' % e + except RuntimeError as e: + print 'Runtime Error: %s' % e + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + sys.stderr.write("\x1b[2J\x1b[H") +