Ejemplo n.º 1
0
    def __init__(
        self,
        interface,
        ip,
        prefix_or_mask,
        broadcast,
        router=None,
        connectivity_url_data: Dict[str, Any] = None,
        static_routes=None,
    ):
        """Setup context manager and validate call signature.

        @param interface: Name of the network interface to bring up.
        @param ip: IP address to assign to the interface.
        @param prefix_or_mask: Either netmask of the format X.X.X.X or an int
            prefix.
        @param broadcast: Broadcast address for the IPv4 network.
        @param router: Optionally the default gateway IP.
        @param connectivity_url_data: Optionally, a URL to verify if a usable
           connection already exists.
        @param static_routes: Optionally a list of static routes from DHCP
        """
        if not all([interface, ip, prefix_or_mask, broadcast]):
            raise ValueError(
                "Cannot init network on {0} with {1}/{2} and bcast {3}".format(
                    interface, ip, prefix_or_mask, broadcast))
        try:
            self.prefix = net.ipv4_mask_to_net_prefix(prefix_or_mask)
        except ValueError as e:
            raise ValueError("Cannot setup network, invalid prefix or "
                             "netmask: {0}".format(e)) from e

        self.connectivity_url_data = connectivity_url_data
        self.interface = interface
        self.ip = ip
        self.broadcast = broadcast
        self.router = router
        self.static_routes = static_routes
        # List of commands to run to cleanup state.
        self.cleanup_cmds: List[str] = []
Ejemplo n.º 2
0
def _normalize_net_keys(network, address_keys=()):
    """Normalize dictionary network keys returning prefix and address keys.

    @param network: A dict of network-related definition containing prefix,
        netmask and address_keys.
    @param address_keys: A tuple of keys to search for representing the address
        or cidr. The first address_key discovered will be used for
        normalization.

    @returns: A dict containing normalized prefix and matching addr_key.
    """
    net = dict((k, v) for k, v in network.items() if v)
    addr_key = None
    for key in address_keys:
        if net.get(key):
            addr_key = key
            break
    if not addr_key:
        message = "No config network address keys [%s] found in %s" % (
            ",".join(address_keys),
            network,
        )
        LOG.error(message)
        raise ValueError(message)

    addr = str(net.get(addr_key))
    if not is_ip_network(addr):
        LOG.error("Address %s is not a valid ip network", addr)
        raise ValueError(f"Address {addr} is not a valid ip address")

    ipv6 = is_ipv6_network(addr)
    ipv4 = is_ipv4_network(addr)

    netmask = net.get("netmask")
    if "/" in addr:
        addr_part, _, maybe_prefix = addr.partition("/")
        net[addr_key] = addr_part
        if ipv6:
            # this supports input of ffff:ffff:ffff::
            prefix = ipv6_mask_to_net_prefix(maybe_prefix)
        elif ipv4:
            # this supports input of 255.255.255.0
            prefix = ipv4_mask_to_net_prefix(maybe_prefix)
        else:
            # In theory this never happens, is_ip_network() should catch all
            # invalid networks
            LOG.error("Address %s is not a valid ip network", addr)
            raise ValueError(f"Address {addr} is not a valid ip address")
    elif "prefix" in net:
        prefix = int(net["prefix"])
    elif netmask and ipv4:
        prefix = ipv4_mask_to_net_prefix(netmask)
    elif netmask and ipv6:
        prefix = ipv6_mask_to_net_prefix(netmask)
    else:
        prefix = 64 if ipv6 else 24

    if "prefix" in net and str(net["prefix"]) != str(prefix):
        LOG.warning(
            "Overwriting existing 'prefix' with '%s' in network info: %s",
            prefix,
            net,
        )
    net["prefix"] = prefix

    if ipv6:
        # TODO: we could/maybe should add this back with the very uncommon
        # 'netmask' for ipv6.  We need a 'net_prefix_to_ipv6_mask' for that.
        if "netmask" in net:
            del net["netmask"]
    elif ipv4:
        net["netmask"] = net_prefix_to_ipv4_mask(net["prefix"])

    return net