#!/usr/local/nsc/bin/python2.7
# vim: tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80 smarttab expandtab

import sys
import os
import glob
import re
import fileinput
import netifaces as ni

class NetDevice(object):
    def __init__(self):
        self.name = None
        self.hostname = None
        self.ip = None
        self.netmask = None
        self.gateway = None
        self.bootproto = None
        self.onboot = "no"
        self.hwaddr = None
        self.gateway = None


# Network devices detected on system
gSysNetDevices = dict() 
gDevice = NetDevice()
gDspOnly = False
gFirewallMode = None

def set_firewall_mode(mode):
    fname = '/etc/firewall'
    print "Setting firewall mode to %s" % (mode)
    try:
        """
        Note fileinput module redirects stdout to the file, so do not
        do any print statements or any stdout operations until fileinput.close() is called

        Also be aware of the ending , in the print statements, it is intentional and used
        to avoid printing an extra line terminator in the existing file
        """
        for line in fileinput.input(fname, inplace=1, backup='.sngbkp'):
            if line.startswith('MODE'):
                print 'MODE=%s' % (mode),
            else:
                print line,
        fileinput.close()
        print "Changed firewall mode to %s" % (mode)
    except:
        print 'Error setting firewall mode'

def set_gen_network(hostname, gateway):
    fname = "/etc/sysconfig/network"
    print "Genetating file %s" % fname

    f = open(fname, "w")

    f.write("# Generated by %s script\n\n" % sys.argv[0])
    f.write("NETWORKING=yes\n")
    f.write("NETWORKING_IPV6=no\n")
    f.write("NOZEROCONF=yes\n")
    f.write("HOSTNAME=%s\n" % hostname)
    if gateway is not None:
        f.write("GATEWAY=\"%s\"\n" % gateway)

def parse_args(argv):
    global gDspOnly
    global gFirewallMode
    gDevice.onboot = "yes"

    for i in range(len(argv)):
        if i == 0:
            continue

        if argv[i] == "--dsp-only":
            gDspOnly = True

        if argv[i] == "--device":
            gDevice.name = argv[i+1]

        elif argv[i] == "--hostname":
            gDevice.hostname = argv[i+1]

        elif argv[i] == "--ip":
            gDevice.ip = argv[i+1]

        elif argv[i] == "--netmask":
            gDevice.netmask = argv[i+1]

        elif argv[i] == "--gateway":
            gDevice.gateway = argv[i+1]

        elif argv[i] == "--bootproto":
            gDevice.bootproto = argv[i+1]
        
        elif argv[i] == "--onboot":
            gDevice.onboot = argv[i+1]

        elif argv[i] == "--gateway":
            gDevice.gateway = argv[i+1]

        elif argv[i] == "--fwmode":
            gFirewallMode = argv[i+1]


def parse_dspifaces():
    sngdspIndex = 0
    for netif in ni.interfaces():
        if ni.ifaddresses(netif)[ni.AF_LINK] is None:
            continue

        hwaddr = ni.ifaddresses(netif)[ni.AF_LINK][0]['addr']

        if hwaddr[0:8] in "02:19:23":
            """
            We could use netif as deviceName, however
            in some situations netif will be eth0, eth1, ethX etc
            even though this is meant to be a DSP interface, because
            in virtual environments our version of the tg3 driver is
            not used, instead a virtual network device driver is used
            and therefore the name of the device is not sngdsp%d
            when assigned by the kernel driver. We want to override that
            in the configuration file so the device is renamed when brought up
            """
            deviceName = "sngdsp%d" % sngdspIndex
            sngdspIndex+=1
            gSysNetDevices[deviceName] = NetDevice()
            gSysNetDevices[deviceName].name = deviceName
            gSysNetDevices[deviceName].hwaddr = hwaddr


def parse_allifaces():
    ethIndex = 0
    sngdspIndex = 0

    for netif in ni.interfaces():
        deviceName = None;
        if netif == "lo":
            continue

        if ni.ifaddresses(netif)[ni.AF_LINK] is None:
            continue
            
        hwaddr = ni.ifaddresses(netif)[ni.AF_LINK][0]['addr']
        if hwaddr[0:11] in "00:00:00:00":
            print "Ignoring device with hwaddr:%s" % hwaddr
            continue

        if hwaddr[0:8] in "02:19:23":
            deviceName = "sngdsp%d" % sngdspIndex
            sngdspIndex+=1
        else:
            deviceName = "eth%d" % ethIndex
            ethIndex+=1

        gSysNetDevices[deviceName] = NetDevice()
        gSysNetDevices[deviceName].name = deviceName
        gSysNetDevices[deviceName].hwaddr = hwaddr



def cleanup_cfg_files():
    for f in glob.glob('/etc/sysconfig/network-scripts/ifcfg-*'):
        os.remove(f);


def gen_dsp_files():
    for key, myNetDevice in gSysNetDevices.iteritems():
        print "Verifying DSP interface %s" % key

        fname = "/etc/sysconfig/network-scripts/ifcfg-%s" % key
        if os.path.exists(fname):
            print "%s already exists" % fname
            continue
        else:
            print "Generating %s" %fname

        f = open(fname, 'w')

        f.write("# Generated by %s script\n\n" % sys.argv[0])
        f.write("DEVICE=%s\n" % myNetDevice.name)
        f.write("HWADDR=%s\n" % myNetDevice.hwaddr)
        f.write("ONBOOT=no\n")

def gen_all_interface_files():
    for key, myNetDevice in gSysNetDevices.iteritems():
        fname = "/etc/sysconfig/network-scripts/ifcfg-%s" % key
        print "Generating file:%s" % fname
        f = open(fname, 'w')

        f.write("# Generated by %s script\n\n" % sys.argv[0])
        f.write("DEVICE=%s\n" % myNetDevice.name)
        f.write("HWADDR=%s\n" % myNetDevice.hwaddr)
        f.write("ONBOOT=\"%s\"\n" % myNetDevice.onboot)

        if myNetDevice.bootproto == "dhcp":
            f.write("BOOTPROTO=\"%s\"\n" % myNetDevice.bootproto)
            if myNetDevice.hostname is not None:
                f.write("DHCP_HOSTNAME=\"%s\"\n" %myNetDevice.hostname)
        elif myNetDevice.bootproto == "static":
            f.write("IPADDR=\"%s\"\n" % myNetDevice.ip);
            f.write("NETMASK=\"%s\"\n" % myNetDevice.netmask);

def gen_lo_file():
    fname = "/etc/sysconfig/network-scripts/ifcfg-lo"

    print "Generating file %s" % fname

    f = open(fname, 'w')
    
    f.write("# Generated by %s script\n\n" % sys.argv[0])
    f.write("DEVICE=lo\n")
    f.write("IPADDR=127.0.0.1\n")
    f.write("NETMASK=255.0.0.0\n")
    f.write("NETWORK=127.0.0.0\n")
    f.write("# If you're having problems with gated making 127.0.0.0/8 a martian,\n")
    f.write("# you can change this to something else (255.255.255, for example)\n") 
    f.write("BROADCAST=127.255.255.255\n")
    f.write("ONBOOT=yes\n")
    f.write("NAME=loopback\n")

def set_device():
    if gDevice.name is None:
        print "Default device not generated"
        return

    if gDevice.name not in gSysNetDevices:
        print "Could not find default device in global devices"
        return

    # Keep the mac address of the system interface
    gDevice.hwaddr = gSysNetDevices[gDevice.name].hwaddr 

    # Overwrite device with the one specified by parameters
    gSysNetDevices[gDevice.name] = gDevice

## main() ##
parse_args(sys.argv)

if gDspOnly is True:

    parse_dspifaces()

    gen_dsp_files()

else:
    parse_allifaces()

    set_device()

    cleanup_cfg_files()

    gen_lo_file()

    gen_all_interface_files()

    if gDevice.hostname is not None:
        set_gen_network(gDevice.hostname, gDevice.gateway)

    if gFirewallMode is not None:
        set_firewall_mode(gFirewallMode)

