def _validate_net_configuration(net, attrs, running_config, netinfo):
    nic = attrs.get('nic')
    bonding = attrs.get('bonding')
    vlan = attrs.get('vlan')
    bridged = attrs.get('bridged', True)
    stp = attrs.get('stp', False)

    if not bridged:
        raise Exception('OVS does not support bridgeless networks')
    if bonding in running_config.bonds:
        if not is_ovs_bond(running_config.bonds[bonding]):
            raise Exception('%s is not OVS bonding' % bonding)
    if nic is not None and nic not in netinfo.nics:
        raise Exception('Nic %s does not exist' % nic)
    if vlan is not None and bonding is None and nic is None:
        raise Exception('You can not create a nicless/bondless vlan')

    for existing_net, existing_attrs in six.iteritems(running_config.networks):
        if (existing_net != net and
                existing_attrs.get('nic') == nic and
                existing_attrs.get('bond') == bonding and
                existing_attrs.get('vlan') == vlan):
            raise Exception('%s is already used by network %s' %
                            ((nic or bonding), existing_net))
    if vlan is None:
        untagged_net = _get_untagged_net(running_config)
        if untagged_net not in (None, net):
            raise Exception('Untagged network already defined with name %s' %
                            untagged_net)
        if rget(attrs, ('custom', 'ovs_aa_sid')) is not None:
            raise Exception('Cannot define aa-mapping on untagged network')
    if stp and vlan is not None:
        raise Exception('STP could be set only on untagged networks')
def _setup_ovs_bond(bond, attrs, running_config):
    """ Add OVS bonding and set it requested mode and lacp options.
    As we use custom entry, these values are not validated in network api,
    so we check correct values here.
    """
    commands = []
    commands.extend(['--', '--fake-iface', '--may-exist', 'add-bond',
                     BRIDGE_NAME, bond] + attrs.get('nics'))

    bond_options = get_bond_options(attrs.get('options'))
    mode = rget(bond_options, ('custom', 'ovs_mode')) or 'active-backup'
    lacp = rget(bond_options, ('custom', 'ovs_lacp')) or 'off'
    commands.extend(['--', 'set', 'port', bond, 'bond_mode=%s' % mode])
    commands.extend(['--', 'set', 'port', bond, 'lacp=%s' % lacp])

    running_config.setBonding(bond, {'nics': attrs.get('nics'),
                                     'options': attrs.get('options')})
    return commands
def _setup_ovs_bond(bond, attrs, running_config):
    """ Add OVS bonding and set it requested mode and lacp options.
    As we use custom entry, these values are not validated in network api,
    so we check correct values here.
    """
    commands = []
    commands.extend(['--', '--fake-iface', '--may-exist', 'add-bond',
                     BRIDGE_NAME, bond] + attrs.get('nics'))

    bond_options = get_bond_options(attrs.get('options'))
    mode = rget(bond_options, ('custom', 'ovs_mode')) or 'active-backup'
    lacp = rget(bond_options, ('custom', 'ovs_lacp')) or 'off'
    commands.extend(['--', 'set', 'port', bond, 'bond_mode=%s' % mode])
    commands.extend(['--', 'set', 'port', bond, 'lacp=%s' % lacp])

    running_config.setBonding(bond, {'nics': attrs.get('nics'),
                                     'options': attrs.get('options')})
    return commands
def _validate_bond_configuration(attrs, netinfo):
    nics = attrs.get('nics')
    bond_options = get_bond_options(attrs.get('options'))

    if nics is None or len(attrs.get('nics')) < 2:
        raise Exception('You have to define at least 2 slaves for '
                        'OVS bonding')
    for nic in nics:
        if nic not in netinfo.nics:
            raise Exception('Nic %s does not exist' % nic)

    mode = rget(bond_options, ('custom', 'ovs_mode')) or 'active-backup'
    lacp = rget(bond_options, ('custom', 'ovs_lacp')) or 'off'
    if mode:
        if mode not in VALID_MODES:
            raise Exception('%s is not valid ovs bond mode' % mode)
    if lacp:
        if lacp not in VALID_LACP:
            raise Exception('%s is not valid ovs lacp value' % lacp)
def _validate_bond_configuration(attrs, netinfo):
    nics = attrs.get('nics')
    bond_options = get_bond_options(attrs.get('options'))

    if nics is None or len(attrs.get('nics')) < 2:
        raise Exception('You have to define at least 2 slaves for '
                        'OVS bonding')
    for nic in nics:
        if nic not in netinfo.nics:
            raise Exception('Nic %s does not exist' % nic)

    mode = rget(bond_options, ('custom', 'ovs_mode')) or 'active-backup'
    lacp = rget(bond_options, ('custom', 'ovs_lacp')) or 'off'
    if mode:
        if mode not in VALID_MODES:
            raise Exception('%s is not valid ovs bond mode' % mode)
    if lacp:
        if lacp not in VALID_LACP:
            raise Exception('%s is not valid ovs lacp value' % lacp)
def _set_aa_mapping(network, attrs, running_config):
    """Handle OVS Auto-Attach mapping. This requires openvswitch >= 2.4"""
    command = []
    init_sid = rget(running_config.networks, (network, 'custom', 'ovs_aa_sid'))
    init_vlan = rget(running_config.networks, (network, 'vlan'))
    sid = rget(attrs, ('custom', 'ovs_aa_sid'))
    vlan = attrs.get('vlan')
    if init_sid != sid or init_vlan != vlan:  # if configuration differs
        if init_sid is not None:
            command.extend(['--', 'del-aa-mapping', network, str(init_sid),
                            str(init_vlan)])
        if sid is not None:
            interfaces = (
                running_config.bonds.get(attrs['bonding'])['nics']
                if 'bonding' in attrs else [attrs['nic']])
            for interface in interfaces:
                # lldp is disabled by default, see ovs-vswitchd.conf.db(5)
                command.extend(['--', 'set', 'Interface', interface,
                                'lldp:enable=true'])
            command.extend(['--', 'add-aa-mapping', network, str(sid),
                            str(vlan)])

    return command
def _edit_ovs_bond(bond, attrs, running_config):
    """ We have to use database commands to change slaves of running
    bonding, then we continue with standard bond setup.
    """
    commands = []
    current = set(rget(running_config.bonds, (bond, 'nics')))
    new = set(attrs.get('nics'))
    add = new - current
    remove = current - new
    for nic in add:
        commands.extend(['--', '--id=@' + nic, 'create', 'Interface', 'name=' +
                         nic, '--', 'add', 'Port', bond, 'interfaces', '@' +
                         nic])
    for nic in remove:
        commands.extend(['--', '--id=@' + nic, 'get', 'Interface', nic, '--',
                         'remove', 'Port', bond, 'interfaces', '@' + nic])

    commands.extend(_setup_ovs_bond(bond, attrs, running_config))
    return commands
def _edit_ovs_bond(bond, attrs, running_config):
    """ We have to use database commands to change slaves of running
    bonding, then we continue with standard bond setup.
    """
    commands = []
    current = set(rget(running_config.bonds, (bond, 'nics')))
    new = set(attrs.get('nics'))
    add = new - current
    remove = current - new
    for nic in add:
        commands.extend(['--', '--id=@' + nic, 'create', 'Interface', 'name=' +
                         nic, '--', 'add', 'Port', bond, 'interfaces', '@' +
                         nic])
    for nic in remove:
        commands.extend(['--', '--id=@' + nic, 'get', 'Interface', nic, '--',
                         'remove', 'Port', bond, 'interfaces', '@' + nic])

    commands.extend(_setup_ovs_bond(bond, attrs, running_config))
    return commands