#!/usr/bin/env python

#
# author: guangjun.lv
# V 1.0

#
# bonding interface, bridge interface management utility
# bonding create, destroy, port join bonding, leave bonding
# bridge create, destroy, port in bridge, leave bridge, bridge patch ports
# bonding, bridge interface, ip, gw configuration

import os
import commands
import logging

LINK_STATE_UP = 1
LINK_STATE_DOWN = 0

dns_file = '/etc/resolv.conf'
netdev_files = '/etc/sysconfig/network-scripts'

# logging for information, debug
logger = logging.getLogger("net_config")
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', '%a, %d %b %Y %H:%M:%S',)
file_handler = logging.FileHandler("/tmp/net_config.log")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.setLevel(logging.INFO)


# apply to restart network service
# after configure bonding,bridge,ip,gw,etc...
def restart_network_service():
    os.system('systemctl restart network')


# bridge interface
def join_port_to_br(br_name, port):
    if len(br_name) == 0 or not len(port):
        logger.info('join_port_to_br: invalid brname or port name')
        return False

    port_file = netdev_files + '/ifcfg-' + port
    if os.path.exists(port_file) == False:
        logger.info('join_port_to_br: invalid port entry')
        return False

    if port_in_bonds(port):
        logger.info('join_port_to_br: port is in bonding inf')
        return False

    if not br_exist(br_name):
        logger.info('join_port_to_br: br isnot exist')
        return False        

    if port_in_br(br_name, port):
        logger.info('join_port_to_br: %s has been in %s' % (port, br_name))
        return True

    commands = 'ovs-vsctl add-port %s %s 2>/dev/null' % (br_name, port)
    ret = not os.system(commands)
    if not ret:
        logger.info('join_port_to_br: add port %s to %s fail' % (port, br_name))
    return ret

def leave_port_from_br(br_name, port):
    if len(br_name) == 0 or not len(port):
        logger.info('leave_port_from_br: invalid brname or port name')
        return False

    if not port_in_br(br_name, port):
        logger.info('leave_port_from_br: %s not in %' % (port, br_name))
        return False

    commands = 'ovs-vsctl del-port %s %s 2>/dev/null' % (br_name, port)
    ret = not os.system(commands)
    if not ret:
        logger.info('delete_port_from_br: delete port %s from %s fail' % (port, br_name))
    return ret

def create_br(br_name):
    if len(br_name) == 0:
        logger.info('create_br: invalid brname')
        return False
    
    if br_exist(br_name):
        logger.info('create_br: br has been created')
        return True
   
    br_file = netdev_files + '/ifcfg-' + br_name
    commands = 'ovs-vsctl add-br %s 2>/dev/null' % (br_name)
    ret = not os.system(commands)
    if (False == ret):
        logger.info('create_br: fail, commands: %s' % commands)
    else:
        if not os.path.exists(br_file):
            fp = open(br_file, 'w')
            fp.writelines('IPADDR=\nNETMASK=\nGATEWAY=\nONBOOT=yes\n')
            fp.writelines('DEVICE=%s\nNAME=%s\nDEVICETYPE=ovs\n' % (br_name, br_name))
            fp.writelines('OVSBOOTPROTO=none\nTYPE=OVSBridge')
            fp.close() 

        logger.info('create_br: success, commands: %s' % commands)

    return ret


def destroy_br(br_name):
    if len(br_name) == 0:
        logger.info('destroy_br: invalid brname')
        return False
    
    if not br_exist(br_name):
        logger.info('destroy_br: br %s isnot exist' % br_name)
        return False

    commands = 'ovs-vsctl del-br %s 2>/dev/null' % (br_name)
    ret = not os.system(commands)
    if (False == ret):
        logger.info('destroy_br: fail, commands: %s' % commands)
    else:
        br_file = netdev_files + '/ifcfg-' + br_name
        commands = 'rm -f %s 2>/dev/null' % br_file
        os.system(commands)

        logger.info('destroy_br: success, commands: %s' % commands)

    return ret


def br_exist(br_name):
    commands = 'ovs-vsctl list-br | grep %s 2>/dev/null' % (br_name)
    ret = not not len(os.popen(commands).readline())
    return ret

def get_br_of_port(port):
    commands = 'ovs-vsctl port-to-br %s 2>/dev/null' % (port)
    br = os.popen(commands).readline()
    if len(br):
        return br.strip('\n') 
    else:
        return br

def port_in_brs(port):
    commands = 'ovs-vsctl port-to-br %s 2>/dev/null' % (port)
    ret = not not len(os.popen(commands).readline())
    return ret

def port_in_br(br_name, port):
    if len(br_name) == 0:
        logger.info('port_in_br: invalid brname')
        return False
   
    if not br_exist(br_name):
        logger.info('port_in_br: br isnot exist')
        return False        
 
    commands = 'ovs-vsctl list-ports %s | grep %s 2>/dev/null' % (br_name, port)
    ret = not not len(os.popen(commands).readline())
    return ret

def create_br_patch(br1_name, br2_name):
    if len(br1_name) == 0 or not len(br2_name):
        logger.info('create_br_patch: invalid brname')
        return False

    if not br_exist(br1_name) or not br_exist(br2_name):
        logger.info('create_br_patch: br isnot exist')
        return False
  
    patch_inf_name = 'patch-to-%s' % (br2_name)
    patch_peer_inf_name = 'patch-to-%s' % (br1_name)
    commands = 'ovs-vsctl add-port %s %s        \
                -- set interface %s type=patch  \
                -- set interface %s options:peer=%s' \
                % (br1_name, patch_inf_name, patch_inf_name, patch_inf_name, patch_peer_inf_name)
    ret1 = not os.system(commands)

    patch_inf_name = 'patch-to-%s' % (br1_name)
    patch_peer_inf_name = 'patch-to-%s' % (br2_name)
    commands = 'ovs-vsctl add-port %s %s        \
                -- set interface %s type=patch  \
                -- set interface %s options:peer=%s' \
                % (br2_name, patch_inf_name, patch_inf_name, patch_inf_name, patch_peer_inf_name)
    ret2 = not os.system(commands)
    return ret1 & ret2

def delete_br_patch(br1_name, br2_name):
    if len(br1_name) == 0 or not len(br2_name):
        logger.info('create_br_patch: invalid brname')
        return False

    if not br_exist(br1_name) or not br_exist(br2_name):
        logger.info('create_br_patch: br isnot exist')
        return False
  
    patch_inf_name = 'patch-to-%s' % (br2_name)
    commands = 'ovs-vsctl del-port %s %s 2>/dev/null' % (br1_name, patch_inf_name)
    ret1 = not os.system(commands)

    patch_inf_name = 'patch-to-%s' % (br1_name)
    commands = 'ovs-vsctl del-port %s %s 2>/dev/null' % (br2_name, patch_inf_name)
    ret2 = not os.system(commands)
    return ret1 & ret2

def get_bridge_info():
    commands = 'ovs-vsctl list-br 2>/dev/null' 
    br_lists = os.popen(commands).read()
    if not len(br_lists):
        return None 

    print 'get bridge and port lists:\n'
    brs = br_lists.split('\n')
    for br in brs:
       if len(br):
           commands = 'ovs-vsctl list-ports %s' % br
           print 'bridge: %s\nports: %s' % (br, os.popen(commands).read())

# bonding interface 
def get_bonding_inf_info_list():
    bond_info_list = {}
    bond_ifs = get_bonding_inf_list()
    for dev in bond_ifs:
        ip = get_bonding_inf_ip(dev)
        mask = get_bonding_inf_ipmask(dev)
        gw = get_bonding_inf_gw(dev)
        state = get_bonding_inf_state(dev)
        slave_nics = get_bonding_inf_nics(dev)
        bond_info_list[dev] = [ip,mask,gw,state,slave_nics]
    return bond_info_list

def create_bonding_inf(inf_name, nics):
    if len(inf_name) == 0 or len(nics) == 0:
        logger.info('create_bonding_inf: invalid inf_name or nics')
        return False

    if bond_exist(inf_name):
        logger.info('create_bonding_inf: %s has been exist' % inf_name)
        return False

    commands = 'nmcli connection add type bond con-name ' + inf_name + ' ifname ' + inf_name + \
               ' mode balance-rr 1>/dev/null 2>/dev/null' 
    ret = os.system(commands)
    if ret:
        logger.info('create_bonding_inf: %s fail' % commands)
        return False
   
    logger.info('create_bonding_inf:  create bonding: %s success' % inf_name)

    for nic in nics:
        if port_in_brs(nic):
            logger.info('create_bonding_inf: port %s is a ovs port' % nic)
            continue

        if port_in_bond(inf_name, nic):
            logger.info('create_bonding_inf: port %s is a %s member' % (nic, inf_name))
            continue

        if port_in_bonds(nic):
            logger.info('create_bonding_inf: port %s is a %s member' % (nic, inf_name))
            continue

        nic_dev_file = netdev_files + '/ifcfg-' + nic 

        fp = open(nic_dev_file, 'w')
        fp.writelines('TYPE=Ethernet\nONBOOT=yes\nBOOTPROTO=none\n')
        fp.writelines('DEVICE=%s\nMASTER=%s\nSLAVE=yes' % (nic, inf_name))
        fp.close()

        logger.info('create_bonding_inf:  add port %s to bonding: %s member success' % (nic, inf_name))

def destroy_bonding(bond_name):
    if len(bond_name) == 0:
        logger.info('destroy_bonding: invalid inf_name %s' % bond_name)
        return False

    if not bond_exist(bond_name):
        logger.info('destroy_bonding: %s is not exist' % bond_name)
        return False

    # bonding maybe join bridge, MUST leave bridge first
    if port_in_brs(bond_name): 
        logger.info('destroy_bonding: %s has join in bridge, couldnot destroy' % bond_name)
        return False

    slave_nics = get_bonding_inf_nics(bond_name)

    leave_devs_from_bonding(bond_name, slave_nics)
    commands = 'nmcli c delete %s 1>/dev/null 2>/dev/null' % (bond_name)
    os.system(commands)

    bond_file = netdev_files + '/ifcfg-' + bond_name
    commands = 'rm -f %s 2>/dev/null' % bond_name
    os.system(commands)

    logger.info('delete_bonding: delete bonding: %s success:' % bond_name)
    return True

def join_devs2_bonding(inf_name, nics):
    for nic in nics:
        if port_in_bond(inf_name, nic):
            logger.info('join_devs2_bonding: port %s is a %s member' % (nic, inf_name))
            continue

        nic_dev_file = netdev_files + '/ifcfg-' + nic

        fp = open(nic_dev_file, 'w')
        fp.writelines('TYPE=Ethernet\nONBOOT=yes\nBOOTPROTO=none\n')
        fp.writelines('DEVICE=%s\nMASTER=%s\nSLAVE=yes' % (nic, inf_name))
        fp.close()

        logger.info('join_devs2_bonding:  add port %s to bond: %s member success' % (nic, inf_name))

def leave_devs_from_bonding(inf_name, nics):
    if not len(nics):
        return

    for nic in nics:
        if not port_in_bond(inf_name, nic):
            logger.info('leave_devs_from_bonding: port %s is not bond:%s member' % (nic, inf_name))
            continue
  
        nic_dev_file = netdev_files + '/ifcfg-' + nic
        if os.path.exists(nic_dev_file):
            fp = open(nic_dev_file, 'r')
            txt = fp.read()
            fp.close()
            lines = txt.split('\n')

            fp = open(nic_dev_file, 'w')
            for line in lines:
                if 'MASTER' in line or 'SLAVE' in line:
                    continue 
                fp.write(line)
                fp.write('\n')

            fp.close()

            logger.info('leave_devs2_bonding:  delete port %s from bond: %s member success' % (nic, inf_name))

def get_bonding_inf_ip(inf_name):
    return get_ip_address(inf_name)


def set_bonding_inf_ip(ip, mask, inf_name):
    ip_con_file = netdev_files + '/ifcfg-' + inf_name 

    if not bond_exist(inf_name):
        logger.info('set_bonding_inf_ip: bonding inf %s is not exist' % bond_name)
        return False

    if valid_ip(ip) and valid_mask(mask):
        fp = open(ip_con_file, 'w')
        fp.writelines('TYPE=Bond\nONBOOT=yes\nBOOTPROTO=static\n')
        fp.writelines('DEVICE=%s\nBONDING_MASTER=yes\n' % (inf_name))
        fp.writelines('IPADDR=%s\nNETMASK=%s' % (ip, mask))

        logger.info('set_bonding_inf_ip: set ip %s, mask %s success ' % (ip, mask))
        
        fp.close()
        return True
    else:
        logger.info('set_bonding_inf_ip: invalid ip %s, mask %s, gw %s ' % (ip, mask))
        return False

def set_bonding_inf_ip_gw(ip, mask, gw, inf_name):

    ip_con_file = netdev_files + '/ifcfg-' + inf_name 

    if not bond_exist(inf_name):
        logger.info('set_bonding_inf_ip_gw: bonding inf %s is not exist' % bond_name)
        return False

    if valid_ip(ip) and valid_mask(mask) and valid_ip(gw):
        fp = open(ip_con_file, 'w')
        fp.writelines('TYPE=Bond\nONBOOT=yes\nBOOTPROTO=static\n')
        fp.writelines('DEVICE=%s\nBONDING_MASTER=yes\n' % (inf_name))
        fp.writelines('IPADDR=%s\nNETMASK=%sGATEWAY=%s' % (ip, mask, gw))

        logger.info('set_bonding_inf_ip_gw: set ip %s, mask %s, gw %ss success ' % (ip, mask, gw))
    
        fp.close()
        return True
    else:
        logger.info('set_bonding_inf_ip_gw: invalid ip %s, mask %s, gw %s ' % (ip, mask, gw))
        return False


def unset_bonding_inf_ip(ip, mask, inf_name):
    unset_ip_config(ip, mask, inf_name)

def unset_bonding_inf_gw(gw, inf_name):
    unset_gw_config(gw, inf_name)

def get_bonding_inf_ipmask(inf_name):
    return get_net_mask(inf_name)

def get_bonding_inf_state(inf_name):
    cmd = 'ethtool ' + inf_name 
    (status, output) = commands.getstatusoutput(cmd)
    if status == 0:
        return LINK_STATE_UP
    else:
        return LINK_STATE_DOWN

def get_bonding_inf_gw(inf_name):
    return get_gateway(inf_name)

def get_bonding_inf_nics(inf_name):
    slave_nics = []
    eth_dev = get_phy_eth_dev_list()
    for dev in eth_dev:
        bond = get_phy_eth_dev_bond(dev)
        if len(bond) and inf_name == bond:
            slave_nics.append(dev)
    return slave_nics


def port_in_bond(bond_name, port):
    if not bond_exist(bond_name):
        logger.info('port_in_bond: bond_name %s isnot exist' % bond_name)

    nic_dev_file = netdev_files + '/ifcfg-' + port
    if os.path.exists(nic_dev_file):
        master_set = False
        slave_set = False
        fp = open(nic_dev_file, 'r')
        txt = fp.read()
        fp.close()
        lines = txt.split('\n')
        for line in lines:
            if 'MASTER' in line and len(line) > len('MASTER=') and bond_name in line:
                master_set = True
            if 'SLAVE' in line and 'yes' in line:
                slave_set = True

        if master_set and slave_set:
            return True
    else:
        return False


def get_bond_of_port(port):
    bond_name = ''

    nic_dev_file = netdev_files + '/ifcfg-' + port
    if os.path.exists(nic_dev_file):
        master_set = False
        slave_set = False
        fp = open(nic_dev_file, 'r')
        txt = fp.read()
        fp.close()
        lines = txt.split('\n')
        for line in lines:
            if 'MASTER' in line and len(line) > len('MASTER=') and 'BONDING_MASTER' not in line:
                master_set = True
                bond_name = line.strip()
                bond_name = bond_name[7:len(bond_name)]
            if 'SLAVE' in line and 'yes' in line:
                slave_set = True

        if master_set and slave_set:
            return bond_name
    else:
        return bond_name


def port_in_bonds(port):
    nic_dev_file = netdev_files + '/ifcfg-' + port
    if os.path.exists(nic_dev_file):
        master_set = False
        slave_set = False
        fp = open(nic_dev_file, 'r')
        txt = fp.read()
        fp.close()
        lines = txt.split('\n')
        for line in lines:
            if 'MASTER' in line and len(line) > len('MASTER=') and 'BONDING_MASTER' not in line:
                master_set = True
            if 'SLAVE' in line and 'yes' in line:
                slave_set = True

        if master_set and slave_set:
            return True
    else:
        return False

def bond_exist(bond_name):
    bond_inf_file = netdev_files + '/ifcfg-' + bond_name
    if os.path.exists(bond_inf_file):
        return True
    else:
        return False


# physical eth device
def get_phy_eth_dev_info_list():
    dev_info_list = {}
    eth_dev = get_phy_eth_dev_list()
    for dev in eth_dev:
        ip = get_phy_eth_dev_ip(dev)
        mask = get_phy_eth_dev_ipmask(dev)
        state = get_phy_eth_dev_state(dev)
        bond = get_phy_eth_dev_bond(dev)
        net = get_phy_eth_dev_network(dev)
        dev_info_list[dev] = [ip,mask,state,bond,net]
    return dev_info_list

def get_phy_eth_dev_ip(dev_name):
    return get_ip_address(dev_name)

def get_phy_eth_dev_ipmask(dev_name):
    return get_net_mask(dev_name)

def get_phy_eth_dev_state(dev_name):
    cmd = 'ethtool ' + dev_name 
    (status, output) = commands.getstatusoutput(cmd)
    if status == 0:
        return LINK_STATE_UP
    else:
        return LINK_STATE_DOWN

def get_phy_eth_dev_bond(dev_name):
    slave = False
    bond_name = ''

    dev_if_file = netdev_files+'/ifcfg-' + dev_name
    if not os.path.exists(dev_if_file):
        logger.info('get_phy_eth_dev_bond, invalid dev_name %s' % dev_name)
        return bond_name

    txt = open(dev_if_file, 'r').read()
    lines = txt.split('\n')

    for line in lines:
        if 'SLAVE' in line:
            if 'yes' in line.split('=')[1].strip():
                slave = True

    if slave:
        for line in lines:
            if 'MASTER' in line:
                bond_name = line.split('=')[1].strip()

    return bond_name


def get_phy_eth_dev_network(dev_name):
    physnet = ''

    bond_name = get_phy_eth_dev_bond(dev_name)
    if not len(bond_name):
        logger.info('get_phy_eth_dev_network, %s is not bond member' % dev_name)
        return physnet

    logger.info('get_phy_eth_dev_network, %s is the bond: %s member' % (dev_name, bond_name))

    br_name = get_br_of_port(bond_name)
    if not len(br_name):
        logger.info('get_phy_eth_dev_network, %s is not bridge member' % br_name)
        return physnet

    logger.info('get_phy_eth_dev_network, %s is the bridge: %s member' % (bond_name, br_name))

    bridge_mapping_file = '/etc/neutron/plugins/ml2/openvswitch_agent.ini'
    if not os.path.exists(bridge_mapping_file):
        logger.info('get_phy_eth_dev_network, %s is not exist' % bridge_mapping_file)
        return physnet

    commands = 'cat %s | grep bridge_mappings' % bridge_mapping_file
    ret = os.popen(commands).readline()
    if not len(ret):
        logger.info('get_phy_eth_dev_network, no bridge_mapping information in %s ' % bridge_mapping_file)
        return physnet

    if not br_name in ret:
        logger.info('get_phy_eth_dev_network, no bridge_mapping information in %s ' % bridge_mapping_file)
        return physnet

    mappings = ret.strip() 
    mappings = mappings[mappings.find('=')+1:len(mappings)] 
    mappings = mappings.strip() 
    if ',' in mappings:
        mappings = mappings.split(',')
        for mapping in mappings:
            if br_name in mapping:
                mapping = mapping.strip()
                physnet = mapping[0:mapping.find(':')] 
    else:
        physnet = mappings[0:mappings.find(':')] 

    logger.info('get_phy_eth_dev_network, bridge_mapping information: %s ' % physnet)
    return physnet

def get_dns_address():
    dns_list = []
    with open(dns_file, 'r') as f0:
        for i in f0:
            if i.startswith('nameserver '):
                tmp = i.split()
                dns_list.append(tmp[1])
    return dns_list


def set_dns_address(address):
    os.remove(dns_file)
    fp = open(dns_file, 'w')
    for i in address:
        if i != '':
            fp.write('nameserver ')
            fp.write(i)
            fp.write('\n')
    return os.system('resolvconf -u &')


def get_bri_list():
    lt = []
    path_list = os.listdir(netdev_files)
    for filename in path_list:
        if filename.startswith('ifcfg-'):
            txt = open(netdev_files+'/'+filename, 'r').read()
            txt = txt.upper()
            if 'ONBOOT=NO' in txt or 'ONBOOT="NO"' in txt:
                continue
            if ('TYPE=BRIDGE' in txt or 'TYPE="BRIDGE"' in txt) \
                    and 'IPADDR=' in txt:
                lt.append(filename[6:])
    return lt

def get_bonding_inf_list():
    lt = []
    path_list = os.listdir(netdev_files)
    for filename in path_list:
        if filename.startswith('ifcfg-'):
            txt = open(netdev_files+'/'+filename, 'r').read()
            txt = txt.upper()
            if 'BRIDGE' in txt:
                continue
            if 'TYPE=BOND' in txt or 'TYPE="BOND"' in txt:
                lt.append(filename[6:])
    return lt

def get_phy_eth_dev_list():
    lt = []
    path_list = os.listdir(netdev_files)
    for filename in path_list:
        if filename.startswith('ifcfg-'):
            txt = open(netdev_files+'/'+filename, 'r').read()
            txt = txt.upper()
            if 'BRIDGE' in txt:
                continue
            if 'TYPE=ETHERNET' in txt or 'TYPE="ETHERNET"' in txt:
                lt.append(filename[6:])
    return lt

def get_net_list():
    lt = []
    path_list = os.listdir(netdev_files)
    for filename in path_list:
        if filename.startswith('ifcfg-'):
            txt = open(netdev_files+'/'+filename, 'r').read()
            txt = txt.upper()
            if 'BRIDGE' in txt:
                continue
            if 'ONBOOT=NO' in txt or 'ONBOOT="NO"' in txt:
                continue
            if 'TYPE=ETHERNET' in txt or 'TYPE="ETHERNET"' in txt:
                cmd = 'ethtool '+filename[6:]
                (status, output) = commands.getstatusoutput(cmd)
                if status == 0:
                    lt.append(filename[6:])
    return lt


def get_ip_address(ifname):
    ip = ''

    ip_con_file = netdev_files + '/ifcfg-' + ifname
    if not os.path.exists(ip_con_file):
        logger('get_ip_address, invalid devname %s' % dev_name)
        return ip

    txt = open(netdev_files + '/ifcfg-' + ifname, 'r').read()
    lines = txt.split('\n')
    for line in lines:
        if 'IPADDR' in line and '#' not in line:
            ip = line.split('=')[1].strip()
    return ip


# def get_ip_address(ifname, logger):
#    logger.info('get_ip '+ifname)
#    ip = ''
#    cmd = "ifconfig " + ifname
#    txt = os.popen(cmd).readlines()
#    for line in txt:
#        if 'inet' in line and 'inet6' not in line:
#            ip = line.split()[1].strip()
#    return ip


def valid_ip(address):
    q = address.split('.')
    return len(q) == 4 and len(filter(lambda x: x>=0 and x<=255,
        map(int, filter(lambda x: x.isdigit(), q)))) == 4


def valid_mask(mask):
    if mask == '0.0.0.0':
        return False
    mask_num = []
    mask_bin = ''
    if valid_ip(mask):
        mask = mask.split(".")
        mask_num = [int(num) for num in mask]
        mask_bin = ''

    for num in mask_num:
        item = bin(num).split('0b')[1]
        if len(item) != 8:
            zero_num = '0'*(8-len(item))
            item = zero_num + item
        mask_bin += item

    if '01' in mask_bin:
        return False
    else:
        return True

def unset_ip_config(ip, mask, dev):

    ip_con_file = netdev_files + '/ifcfg-' +  dev
    if not os.path.exists(ip_con_file):
        logger('unset_ip_config: invalid devname %s' % dev)
        return None
  
    fp = open(ip_con_file, 'r')
    txt = fp.read()
    fp.close()
    lines = txt.split('\n')

    fp = open(ip_con_file, 'w')
    for line in lines:
        if 'IPADDR' in line or 'NETMASK' in line:
            continue

        if 'BOOTPROTO' in line:
            line = 'BOOTPROTO=none' 

        fp.write(line)
        fp.write('\n')

    logger.info('unset_ip_config:  unset inf %s: ip %s, mask %s success ' % (dev, ip, mask))
    fp.close()


def unset_gw_config(gw, dev):
    ip_con_file = netdev_files + '/ifcfg-' +  dev
    if not os.path.exists(ip_con_file):
        logger('unset_gw_config: invalid devname %s' % dev)
        return None
  
    fp = open(ip_con_file, 'r')
    txt = fp.read()
    fp.close()
    lines = txt.split('\n')

    fp = open(ip_con_file, 'w')
    for line in lines:
        if 'GATEWAY' in line:
            continue

        fp.write(line)
        fp.write('\n')

    logger.info('unset_gw_config:  unset inf %s: gw %s success ' % (dev, gw))


def save_ip_config(ip, mask, gw, dev):
    ip_set = False
    mask_set = False
    gw_set = False
    boot_set = False

    ip_con_file = netdev_files + '/ifcfg-' +  dev
    if not os.path.exists(ip_con_file):
        logger('save_ip_config: invalid devname', dev)
        return None

    filename = netdev_files + '/ifcfg-' + dev
    fp = open(filename, 'r')
    txt = fp.read()
    fp.close()
    fp = open(filename, 'w+')
    lines = txt.split('\n')
    for line in lines:
        if 'IPADDR' in line:
            new_line = 'IPADDR' + '=' + ip
            txt = txt.replace(line, new_line)
            ip_set = True
        if 'GATEWAY' in line:
            new_line = 'GATEWAY' + '=' + gw 
            txt = txt.replace(line, new_line)
            gw_set = True
        if 'NETMASK' in line:
            new_line = 'NETMASK' + '=' + mask
            txt = txt.replace(line, new_line)
            mask_set = True
        if 'BOOTPROTO' in line:
            new_line = 'BOOTPROTO' + '=static' 
            txt = txt.replace(line, new_line)
            boot_set = True 

    if ip_set or mask_set or gw_set or boot_set:
        fp.write(txt)
        fp.close()

    fp = open(filename, 'a+')
    if not ip_set:
        fp.write('\nIPADDR=%s' % ip)

    if not mask_set:
        fp.write('\nNETMASK=%s' % mask)

    if not gw_set:
        fp.write('\nGATEWAY=%s' % gw)

    if not boot_set:
        fp.write('\nBOOTPROTO=static')

    logger.info('save_ip_config:  set inf %s: ip %s, mask %s, gw %s success ' % (dev, ip, mask, gw))

    fp.close()


def get_net_mask(dev):
    mask = ''

    ip_con_file = netdev_files + '/ifcfg-' +  dev
    if not os.path.exists(ip_con_file):
        logger('get_net_mask, invalid devname %s' % dev)
        return mask

    txt = open(netdev_files + '/ifcfg-' + dev, 'r').read()
    lines = txt.split('\n')
    for line in lines:
        if 'NETMASK' in line and '#' not in line:
            mask = line.split('=')[1].strip()
    return mask


# def get_net_mask(dev):
#    msk = ''
#    cmd = "ifconfig " + dev
#    txt = os.popen(cmd).readlines()
#    for line in txt:
#        if 'netmask' in line:
#            msk = line.split()[3].strip()
#    return msk


def get_gateway(dev):
    gw = ''

    gw_con_file = netdev_files + '/ifcfg-' +  dev
    if not os.path.exists(gw_con_file):
        logger('get_gateway, invalid devname %s' % dev)
        return gw 

    txt = open(netdev_files + '/ifcfg-' + dev, 'r').read()
    lines = txt.split('\n')
    for line in lines:
        if 'GATEWAY' in line and '#' not in line:
            gw = line.split('=')[1].strip()
    return gw

def bonding_test():
    bond_name = 'bond0'
    nics=['enp2s0f1']

    print 'list physical ethernet device:'
    print get_phy_eth_dev_info_list()

    print 'list bonding interface:'
    print get_bonding_inf_info_list()

    print 'create bonding interface:'
    create_bonding_inf(bond_name, nics)
    leave_devs_from_bonding(bond_name, nics)
    join_devs2_bonding(bond_name, nics)

    print 'set bonding interface ip mask, gw:'
    set_bonding_inf_ip_gw('192.168.1.1', '255.255.255.0', '192.168.1.254', bond_name)

    print 'list bonding interface:'
    print get_bonding_inf_info_list()

    print 'unset bonding interface ip mask, gw:'
    unset_bonding_inf_ip('192.168.1.1', '255.255.255.0', bond_name)
    unset_bonding_inf_gw('192.168.1.254', bond_name)

    print 'list bonding interface:'
    print get_bonding_inf_info_list()

    print 'delete bonding interface:'
    destroy_bonding(bond_name)

    print 'list bonding interface:'
    print get_bonding_inf_info_list()


def bridge_test():

    br_name = 'br-jun'
    port = 'enp2s0f1'

    print 'create bridge:'
    create_br('br-jun')
    get_bridge_info()

    join_port_to_br(br_name, port)
    get_bridge_info()

    leave_port_from_br(br_name, port)
    get_bridge_info()

    create_br_patch(br_name, 'br-int')
    get_bridge_info()

    delete_br_patch(br_name, 'br-int')
    get_bridge_info()

    destroy_br('br-jun')

def bonding_bridge_test():

    bond_name = 'bond0'
    nics=['enp2s0f1']

    br_name = 'br-jun'

    create_bonding_inf(bond_name, nics)

    create_br('br-jun')
    get_bridge_info()

    join_port_to_br(br_name, bond_name)
    get_bridge_info()


# main routinue
if __name__ == '__main__':

   #bonding_test() 

   #bridge_test()

   #bonding_bridge_test()
   print get_phy_eth_dev_network('enp2s0f1')
 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐