#!/usr/bin/python
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#


'''
    This reads a configuration file and checks for functioning
    network links in /sys/class/net/*, then emits a ks.cfg network line.
    '''

import os
import re

from __future__ import print_function

global TO_LOG
# This "logs" to stdout which is captured during kickstart
TO_LOG = True

# This is the standard interface we install to. It is set to a speed value of
# 5 (vice 100,1000 or 10000) later on and any other interface will override it
# if you've got something faster installed.
standard_interface=['p4p1']

## These are configuration settings:
# Name of Configuration file:
cfg_file = "network.cfg"

# Where linux is putting the interface stuff:
iface_dir = '/sys/class/net/'

ignore_interfaces = ['lo','bond']

# Where we kickstart mounts the ISO, and our config directory:
base_cfg_dir = '/mnt/stage2/ks_scripts/'

# Remember the ? makes the match non-greedy. This is important.
cfg_line = re.compile("\s*(?P<key>.*?)=(?P<value>.*)\s*$")

# Pick the interface speed for bonding, or "Auto".
# Auto assumes you want the fastest connections with more than 1 interface,
# Or if there's not 2 interfaces at the same speed you want the fastest.
# auto is expected to be a string, otherwise use integers:
# Speed is in megs. 1000 is 1 gig, 10000 is 10G.

iface_speed = 'auto'

restring = iface_dir + "(?P<iface>.*)/speed"
iface_search = re.compile(restring)


def read_config(config_file):
    ''' Reads our network config file and hands back a dict of key:value
    pairs '''

    net_cfg = {}
    with open(config_file,'r') as cfg:
        network_lines = cfg.readlines()
        for line in network_lines:
            if cfg_line.match(line):
                key = cfg_line.match(line).group('key')
                value = cfg_line.match(line).group('value')
                net_cfg[key] = value
    return net_cfg


def find_usable_net_devs(location):
    ''' Search through iface_dir looking for /speed files.
    Build a dict keyed on speed (in otherwords the speed is the key with a list of
    interfaces as teh value). '''
    # We "pre-seed" the dictionary with the standard interface names at a
    # speed of 5 so that if there's nothing else we set that up. This
    # makes it easier  to reconfigure later.
    ifaces = {5:standard_interface}
    bad_ifaces={}
    devs = os.listdir(location)
    for dev in devs:
        dev_path = os.path.join(location,dev,'speed')
        add=True
        if os.path.isfile(dev_path):
            with open(dev_path,'r') as iface:
                try:
                    speed = iface.readlines()
                    # speed should only have one line:
                    speed = int(speed[0])
                # if there is no link some drivers/cards/whatever will
                # throw an IOError when you try to read the speed file.
                except IOError:
                    speed = 0
        # Other cards will return a -1, which is fine, but *some* of them
        # return a 65535. Those we set to 0 as well.
        if speed == 65535:
            speed = 0
        for i_face in ignore_interfaces:
            if i_face in dev:
                add = False
        if speed  <= 0:
            add = False
        if TO_LOG:
            print(add, dev)
        if add:
            if speed in ifaces:
                this_speed = ifaces[speed]
                this_speed.append(dev)
                ifaces[speed]=this_speed
            else:
                ifaces[speed]=[dev]
        else:
            bad_ifaces[dev] = speed
    print("We find these interfaces have link and might be useful:", ifaces)
    if TO_LOG:
        print("And these aren't useful:", bad_ifaces)
    return ifaces


def useable_interfaces(net_devs, nc, iface_speed):
    ''' This takes a go at figuring out which interfaces to use.'''
    iface_list = False
    notes = False
    if TO_LOG:
        print("in usable interfaces")

    if "bond" not in nc['BOND_DEVICE'].lower():
        if TO_LOG:
            print("useable interfaces if not", nc['BOND_DEVICE'])
        #  Not doing a bond, so  we check to make sure the requested device,
        #  nc['BOND_DEVICE'], is in the list of devices with carrier:
        if nc['BOND_DEVICE'] == '""':
            # In this case we have no network interface in the configuration but we
            # network settings.
            # First we check how many net_devs we have:
            if TO_LOG:
                print("nc['BOND_DEVICE']=''", len(net_devs), net_devs)
            if len(net_devs) == 1: # This is a dict of speed: devices
                speeds = net_devs.keys()
                speeds.sort(reverse=True)
                speed = speeds[0]
                possibles = net_devs[speed]
                if TO_LOG:
                    print(possibles)
                # At this point we have options, but no information, so:
                notes = "No device in the configuration file and multiple devices found. Picking the first"
                iface_list = [possibles[0]]
        else:
            if TO_LOG:
                print("inner else")
            for speed in net_devs:
                if nc['BOND_DEVICE'] in net_devs[speed]:
                    iface_list = [nc['BOND_DEVICE']]
                else:
                    iface_list = [nc['BOND_DEVICE']]
                    notes = "{0} did not have carrier at install time, and may not work".format(nc['BOND_DEVICE'])
    elif iface_speed != 'auto':
        if len(net_devs[iface_speed]) > 0:
            iface_list = net_devs[iface_speed]
        else:
            notes = "no devices set to {0}".format(iface_speed)
    else: # This SHOULD be iface_speed == auto, and nc['BOND_DEVCE'] containing bond.
        #  if not it is anyway.
        # Thus we are doing a bond of some sort.
        # This gives us the fastest interfaces first:
        speeds = net_devs.keys()
        speeds.sort(reverse=True)
        fastest = speeds[0]
        # Walk through "speeds" and take the first one that has more than one
        # interface. This will only set iface_list if there are 2 or more interfaces:
        # previous_speed = 0
        for i in speeds:
            if len(net_devs[i]) > 1:
                iface_list = net_devs[i]
                break
        if TO_LOG:
            print("iface list:", iface_list)
        # if iface_list is still false, and we are requesting a bond, we will
        # want the fastest interface with link:
        if (iface_list == False) and ("bond" in nc['BOND_DEVICE'].lower()):
                if TO_LOG:
                    print(len(net_devs), net_devs, i)
                if len(net_devs) == 0:
                    iface_list = net_devs
                    notes = "no devices found for the bond. Will not have network after reboot"
                else:
                    iface_list = net_devs[fastest] # This is assuming that we'll want to bond the fastest interaface.
                    if TO_LOG:
                        print("dev:", net_devs[fastest])
    if TO_LOG:
        print(iface_list, notes)
    return iface_list, notes


# Find our network configuration file:
if os.path.isfile(os.path.join(base_cfg_dir,cfg_file)):
    cfg_path = os.path.join(base_cfg_dir,cfg_file)
elif os.path.isfile(cfg_file):
    cfg_path = cfg_file
else:
    cfg_path = ''

if cfg_path:
    nc = read_config(cfg_path)
else:
    # if we don't have a working config file we use this
    # The IPs and hostnames are bad.
    nc = { IPADDR:"10.0.0.2",
        NETMASK:"255.255.255.252",
        GATEWAY:"10.0.0.1",
        BOND_DEVICE:"bond0",
        MTU:"9000",
        NAMESERVER:"192.168.0.1",
        HOSTNAME:"bad.example.com",
        NETWORKING_IPV6:"yes",
        IPV6ADDR:" 2001:0db8:0a0b:12f0:0000:0000:0000:0002/64",
        IPV6_DEFAULTGW:" 2001:0db8:0a0b:12f0:0000:0000:0000:0001",
        BONDING_OPTS:"miimon=100 mode=4 lacp_rate=fast xmit_hash_policy=layer3+4",
        DHCP:"no" }
# This should be set to no in the config file, but that could change:
if "DHCP" not in nc:
    nc['DHCP']='no'

net_devs = find_usable_net_devs(iface_dir)
bondable_iface, iface_problems = useable_interfaces(net_devs, nc, iface_speed)

# turn bondable_iface into a string for the network line:
if bondable_iface and len(bondable_iface) > 1:
    dev_list = bondable_iface
    dev_str = dev_list.pop()
    for d in dev_list:
        dev_str = dev_str + "," + d
else:
    dev_str = bondable_iface[0]


if ('y' in nc['NETWORKING_IPV6'].lower()) and re.search(":",nc['IPV6ADDR']):
    IPV6 = "--ipv6=" + nc["IPV6ADDR"]
else:
    if 'y' in nc['NETWORKING_IPV6'].lower():
        if iface_problems is False:
            iface_problems = "IPv6 enabled but no address provided"
        else:
            iface_problems = "{0} and IPv6 enabled but no address provided".format(iface_problems)
    if re.search(":",nc['IPV6ADDR']):
        if iface_problems is False:
            iface_problems = "IPv6 is disabled, but IPV6ADDR was set to {0}".format(nc['IPV6ADDR'])
        else:
            iface_problems = "{0} and IPv6 is disabled, but IPV6ADDR was set to {1}".format(iface_problems, nc['IPV6ADDR'])
    IPV6 = "--noipv6"

if "bond" in nc['BOND_DEVICE'].lower():
    bond_stuff = "--device={BOND_DEVICE} --bondslaves={0} --bondopts={BONDING_OPTS}".format(dev_str, **nc)
elif nc['BOND_DEVICE'] in dev_str:
    bond_stuff = "--device={0}".format(nc["BOND_DEVICE"])
elif bondable_iface and nc['BOND_DEVICE'] == '""' :
    print("**")
    print("No device (BOND_DEVICE) specified it he config, found", bondable_iface, "with link, using it.")
    print("**")
    bond_stuff = "--device={0}".format(bondable_iface[0])
else:
    print("**")
    print(nc["BOND_DEVICE"], "not found within $usable_devices, setting anyway, this probably won't work")
    print("**")
    bond_stuff = "--device={0}".format(nc["BOND_DEVICE"])

if 'yes' in nc['DHCP'].lower() or not bondable_iface:
    network_line = "network --bootproto=dhcp --device={BOND_DEVICE} --hostname={HOSTNAME}".format(**nc)
else:
    network_line = "network --bootproto=static {0} --activate {1} --ip={IPADDR} --netmask={NETMASK} --gateway={GATEWAY} --nameserver={NAMESERVER} --mtu={MTU} --hostname={HOSTNAME} \n".format(
            bond_stuff, IPV6, **nc)

if iface_problems:
    network_line = "# Problems found: {0}\n{1}".format(iface_problems,network_line)

with open('/tmp/network_line','w') as OUT:
    OUT.write(network_line)
