Beispiel #1
0
def _split_switch_type_entries(entries, running_entries):
    legacy_entries = {}
    ovs_entries = {}

    def store_broken_entry(name, attrs):
        """
        If a network/bond should be removed but its existing entry was not
        found in running config, we have to find out what switch type has to
        be used for removal on our own.

        All we do now is, that we pass orphan entry to legacy swich which is
        (unlike OVS switch) able to remove broken networks/bonds.

        TODO: Try to find out which switch type should be used for broken
        network/bonding removal.
        """
        legacy_entries[name] = attrs

    def store_entry(name, attrs, switch_type):
        if switch_type is None:
            store_broken_entry(name, attrs)
        elif switch_type == legacy_switch.SWITCH_TYPE:
            legacy_entries[name] = attrs
        elif switch_type == ovs_switch.SWITCH_TYPE:
            ovs_entries[name] = attrs
        else:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_PARAMS, 'Invalid switch type %s' % attrs['switch']
            )

    for name, attrs in six.iteritems(entries):
        if 'remove' in attrs:
            running_attrs = running_entries.get(name, {})
            switch_type = running_attrs.get('switch')

            # When removing a network/bond, we try to determine its switch
            # type from the netinfo report.
            # This is not always possible, specifically with bonds owned by ovs
            # but not successfully deployed (not saved in running config).
            if (
                switch_type == legacy_switch.SWITCH_TYPE
                and bond.Bond(name).exists()
                and not Ifcfg.owned_device(name)
            ):
                # If not owned by Legacy, assume OVS and let it be removed in
                # the OVS way.
                switch_type = ovs_switch.SWITCH_TYPE

        else:
            switch_type = attrs['switch']
        store_entry(name, attrs, switch_type)

    return legacy_entries, ovs_entries
Beispiel #2
0
def _filter_owned_bonds(kconfig_bonds):
    """
    Bonds retrieved from the kernel include both the ones owned by us and the
    ones that are not.
    The filter returns only the owned bonds by examining the ifcfg files
    in case ifcfg persistence is set.
    """
    if config.get('vars', 'net_persistence') == 'ifcfg':
        return {bond_name: bond_attrs
                for bond_name, bond_attrs in six.viewitems(kconfig_bonds)
                if Ifcfg.owned_device(bond_name)}
    return {}
Beispiel #3
0
def _filter_owned_bonds(kconfig_bonds):
    """
    Bonds retrieved from the kernel include both the ones owned by us and the
    ones that are not.
    The filter returns only the owned bonds by examining the ifcfg files
    in case ifcfg persistence is set.
    """
    if config.get('vars', 'net_persistence') == 'ifcfg':
        return {bond_name: bond_attrs
                for bond_name, bond_attrs in six.viewitems(kconfig_bonds)
                if Ifcfg.owned_device(bond_name)}
    return kconfig_bonds
Beispiel #4
0
def _split_switch_type_entries(entries, running_entries):
    legacy_entries = {}
    ovs_entries = {}

    def store_broken_entry(name, attrs):
        """
        If a network/bond should be removed but its existing entry was not
        found in running config, we have to find out what switch type has to
        be used for removal on our own.

        All we do now is, that we pass orphan entry to legacy swich which is
        (unlike OVS switch) able to remove broken networks/bonds.

        TODO: Try to find out which switch type should be used for broken
        network/bonding removal.
        """
        legacy_entries[name] = attrs

    def store_entry(name, attrs, switch_type):
        if switch_type is None:
            store_broken_entry(name, attrs)
        elif switch_type == legacy_switch.SWITCH_TYPE:
            legacy_entries[name] = attrs
        elif switch_type == ovs_switch.SWITCH_TYPE:
            ovs_entries[name] = attrs
        else:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_PARAMS, 'Invalid switch type %s' % attrs['switch'])

    for name, attrs in six.iteritems(entries):
        if 'remove' in attrs:
            running_attrs = running_entries.get(name, {})
            switch_type = running_attrs.get('switch')

            # When removing a network/bond, we try to determine its switch
            # type from the netinfo report.
            # This is not always possible, specifically with bonds owned by ovs
            # but not successfully deployed (not saved in running config).
            if (switch_type == legacy_switch.SWITCH_TYPE and
                    bond.Bond(name).exists() and
                    not Ifcfg.owned_device(name)):
                # If not owned by Legacy, assume OVS and let it be removed in
                # the OVS way.
                switch_type = ovs_switch.SWITCH_TYPE

        else:
            switch_type = attrs['switch']
        store_entry(name, attrs, switch_type)

    return legacy_entries, ovs_entries
Beispiel #5
0
def _setup_legacy(networks, bondings, options, net_info, in_rollback):
    _netinfo = CachingNetInfo(net_info)

    with Ifcfg(_netinfo, in_rollback) as configurator:
        # from this point forward, any exception thrown will be handled by
        # Configurator.__exit__.

        legacy_switch.remove_networks(networks, bondings, configurator,
                                      _netinfo)

        legacy_switch.bonds_setup(bondings, configurator, _netinfo,
                                  in_rollback)

        legacy_switch.add_missing_networks(configurator, networks, bondings,
                                           _netinfo)

        connectivity.check(options)
Beispiel #6
0
def _objectivize_network(
    bridge=None,
    vlan=None,
    vlan_id=None,
    bonding=None,
    bondattr=None,
    nic=None,
    mtu=None,
    ipaddr=None,
    netmask=None,
    gateway=None,
    bootproto=None,
    ipv6addr=None,
    ipv6gateway=None,
    ipv6autoconf=None,
    dhcpv6=None,
    defaultRoute=None,
    nameservers=None,
    _netinfo=None,
    configurator=None,
    blockingdhcp=None,
    opts=None,
):
    """
    Constructs an object hierarchy that describes the network configuration
    that is passed in the parameters.

    :param bridge: name of the bridge.
    :param vlan: vlan device name.
    :param vlan_id: vlan tag id.
    :param bonding: name of the bond.
    :param bondattr: bond attributes if defined.
    :param nic: name of the nic.
    :param mtu: the desired network maximum transmission unit.
    :param ipaddr: IPv4 address in dotted decimal format.
    :param netmask: IPv4 mask in dotted decimal format.
    :param gateway: IPv4 address in dotted decimal format.
    :param bootproto: protocol for getting IP config for the net, e.g., 'dhcp'
    :param ipv6addr: IPv6 address in format address[/prefixlen].
    :param ipv6gateway: IPv6 address in format address[/prefixlen].
    :param ipv6autoconf: whether to use IPv6's stateless autoconfiguration.
    :param dhcpv6: whether to use DHCPv6.
    :param nameservers: a list of DNS servers.
    :param _netinfo: network information snapshot.
    :param configurator: instance to use to apply the network configuration.
    :param blockingdhcp: whether to acquire dhcp IP config in a synced manner.
    :param defaultRoute: Should this network's gateway be set in the main
                         routing table?
    :param opts: misc options received by the callee, e.g., {'stp': True}. this
                 function can modify the dictionary.

    :returns: the top object of the hierarchy.
    """
    if _netinfo is None:
        _netinfo = CachingNetInfo()
    if configurator is None:
        configurator = Ifcfg(_netinfo)
    if opts is None:
        opts = {}
    if bootproto == 'none':
        bootproto = None

    top_net_dev = None
    if bonding:
        if bondattr is None:
            bondattr = {}
        top_net_dev = Bond.objectivize(
            bonding,
            configurator,
            options=bondattr.get('options'),
            nics=bondattr.get('nics'),
            hwaddr=bondattr.get('hwaddr'),
            mtu=mtu,
            _netinfo=_netinfo,
            on_removal_just_detach_from_network=True,
        )
    elif nic:
        top_net_dev = Nic(nic, configurator, mtu=mtu, _netinfo=_netinfo)
    if vlan is not None:
        tag = _netinfo.vlans[vlan]['vlanid'] if vlan_id is None else vlan_id
        top_net_dev = Vlan(top_net_dev, tag, configurator, mtu=mtu, name=vlan)
    elif vlan_id is not None:
        top_net_dev = Vlan(top_net_dev, vlan_id, configurator, mtu=mtu)
    if bridge is not None:
        top_net_dev = Bridge(
            bridge,
            configurator,
            port=top_net_dev,
            mtu=mtu,
            stp=opts.get('stp', None),
        )
        # Inherit DUID from the port's possibly still active DHCP lease so the
        # bridge gets the same IP address. (BZ#1219429)
        if top_net_dev.port and bootproto == 'dhcp':
            top_net_dev.duid_source = top_net_dev.port.name
    if top_net_dev is None:
        raise ConfigNetworkError(
            ne.ERR_BAD_PARAMS, 'Network defined without ' 'devices.'
        )
    top_net_dev.ipv4 = IPv4(ipaddr, netmask, gateway, defaultRoute, bootproto)
    top_net_dev.ipv6 = IPv6(
        ipv6addr, ipv6gateway, defaultRoute, ipv6autoconf, dhcpv6
    )
    top_net_dev.blockingdhcp = configurator._inRollback or tobool(blockingdhcp)
    top_net_dev.nameservers = nameservers
    return top_net_dev