#!/usr/bin/env python
# -*- coding: UTF-8 -*-

### LICENSE BSD ###
# Copyright (c) 2011, Salvador Girones, Abiquo
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Abiquo nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
###
#
# This script creates needed scripts in order to configure dhcp server for Abiquo purpouses:
# http://community.abiquo.com/display/ABI17/Configuring+one+DHCP+Relay+server
#
##

import getopt, sys, os

def create_vlans_script(service_interface, vlan_range, service_network):
   
    minvlan = 0
    maxvlan = 0
    numvlans = 0
    loops = 0
    residual = 0

    try:
        minvlan = int(vlan_range.split('-')[0])
        maxvlan = int(vlan_range.split('-')[1])
        numvlans = maxvlan-minvlan+1
        loops = numvlans / 254
        residual = numvlans % 254
    except:
        print "\nError parsing vlans range.\n"
        sys.exit(2)

    #Generate script for creating vlans and config dhcpd
    try:
        f = open("vlans-config", "w")

        data = "#!/bin/bash\n\n"
        
        data += '# Abiquo Dhcp server config. Vlans generation.\n'
        data += '#\n'
        data += '# chkconfig: 2345 64 34\n'
        data += '# description: Create vlan interfaces and assign ip.\n'
        data += '#               Script generated by Abiquo DHCPD config script (http://community.abiquo.com/display/ABI17/Configuring+one+DHCP+Relay+server)\n'
        f.write(data)
        
        data = '\nstart() {\n'
        data += '    echo -n $"Starting $prog: "\n'
        #Vlans creation
        if loops:
            data += '    echo  "Starting subifaces: "\n'
            data += '    for i in `seq 0 %d`; do\n' % (int(loops-1))
            data += '        for j in `seq 1 254`; do\n'
            data += '            vlan=$[$i*254 + $j - 1 + %d]\n' % (int(minvlan))
            data += '            vconfig add %s $vlan\n' % (str(service_interface))
            data += '            ifconfig %s.$vlan up\n' % (str(service_interface))
            data += '            ifconfig %s.$vlan %d.%d.$[$i + %d].$j netmask 255.255.255.255\n' % (str(service_interface), int(service_network.split(".")[0]), int(service_network.split(".")[1]), int(service_network.split(".")[2]))
            data += '        done\n'
            data += '    done\n'

        if residual:
            data += '    for i in `seq 1 %s`; do\n' % (int(residual))
            data += '        vlan=$[%s + $i - 1 + %s]\n' % (int(loops*254), int(minvlan))
            data += '        vconfig add %s $vlan\n' % (str(service_interface))
            data += '        ifconfig %s.$vlan up\n' % (str(service_interface))
            data += '        ifconfig %s.$vlan %d.%d.%d.$i netmask 255.255.255.255\n' % (str(service_interface), int(service_network.split(".")[0]), int(service_network.split(".")[1]), int(service_network.split(".")[2]) + loops)
            data += '    done\n'

        #Close start
        data += '}\n'
        f.write(data)

        #Stop
        data = '\nstop() { \n'
        data += '    echo -n $"Stopping $prog: "\n'
        data += '    \n'
        data += '    killproc vlans-config\n'
        data += '    \n'
        data += '    for i in `seq %d %d`; do\n' % (minvlan, maxvlan)
        data += '        vconfig rem %s.$i\n' % (service_interface)
        data += '    done\n'
        data += '    \n'
        data += '    RETVAL=$?\n'
        data += '    echo\n'
        data += '    return $RETVAL\n'
        data += '}\n'
        f.write(data)
        
        #Restart
        data = '\nrestart() {\n'
        data += '      stop\n'
        data += '    start\n'
        data += '}\n'
        f.write(data)
        
        # Script logic
        data = '\ncase "$1" in\n'
        data += '  start)\n'
        data += '      start\n'
        data += '    ;;\n'
        data += '  stop)\n'
        data += '      stop\n'
        data += '    ;;\n'
        data += '  restart)\n'
        data += '      restart\n'
        data += '    ;;\n'
        data += '  *)\n'
        data += '    echo $"Usage: $0 {start|stop|restart}"\n'
        data += '    exit 1\n'
        data += 'esac\n'
        f.write(data)
        
        f.close()    
        os.system("chmod +x vlans-config")
        

    except Exception, e:
        print "\nError creating vlans-config.\n"
        print e
        f.close()
        sys.exit(2)

def create_dhcpd_config(vlan_range, service_interface):

    minvlan = int(vlan_range.split('-')[0])
    maxvlan = int(vlan_range.split('-')[1])

    #DHCPD config
    f = open("dhcpd", "w")
    data = '# Generated by Abiquo DHCPD config script'
    data +=	'\nDHCPDARGS="'
    
    for i in range(minvlan, maxvlan+1):
        data += ' %s.%d' % (service_interface,i)
    
    data += '"'
    f.write(data)


def usage():
    print "Usage: abiquo-dhcpd-config.py [OPTIONS]..."
    print "Creates configuration files and start scripts for the dhcp server and vlans.\n"
    print "-h\t--help\t\t\t\tThis help screen."
    print "-s\t--service-interface=INTERFACE\tInterface of the service network interface, where VLANs will be created."
    print "-v\t--vlan-range=VLANRANGE\t\tVLAN range (e.g. 2-200)."
    print "-n\t--service-network=IP\t\tNetwork available for service network interfaces (has to finish in 0)."
    print ""

def main():
    
    service_interface=None
    vlan_range=None
    service_network=None

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hs:v:n:", ["help", "service-interface=", "vlan-range=", "service-network="])
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(2)

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-s", "--service-interface"):
            service_interface=a
        elif o in ("-v", "--vlan-range"):
            vlan_range=a
        elif o in ("-n", "--service-network"):
            service_network=a
    
    if not (service_interface and vlan_range and service_network) or service_network.split(".")[3] != "0":
        usage()
        return
        
    print "-- Generating file --\n"

    #Vlans script
    print " * vlans-config\t\tScript to generate VLANs and assign IPs"
    create_vlans_script(service_interface, vlan_range, service_network)
    
    #DHCPD config
    print " * dhcpd\t\tScript to configure dhcpd listen interfaces"
    create_dhcpd_config(vlan_range, service_interface)
    
    print "\n-- End --\n"


if __name__ == "__main__":
    main()