Пример #1
0
 def find_from_tuple(cls, link):
     """
     Find link by providing a tuple with two ip addresses or two mac addresses
     :param link: tuple with two string elements indicating source and destination (ip or mac addresses)
     :returns: Link object
     """
     try:
         a = link[0]
         b = link[1]
     except IndexError:
         raise ValueError('Expecting tuple with source and destination')
     # find interfaces
     if (valid_ipv4(a) and valid_ipv4(b)) or (valid_ipv6(a) and valid_ipv6(b)):
         try:
             a = Ip.objects.get(address=a).interface
             b = Ip.objects.get(address=b).interface
         except Ip.DoesNotExist as e:
             raise LinkDataNotFound(e)
     elif valid_mac(a) and valid_mac(b):
         try:
             a = Interface.objects.get(mac=a)
             b = Interface.objects.get(mac=b)
         except Interface.DoesNotExist as e:
             raise LinkDataNotFound(e)
     else:
         raise ValueError('Expecting valid ipv4, ipv6 or mac address')
     # find link with interfaces
     # inverse order is also ok
     q = Q(interface_a=a, interface_b=b) | Q(interface_a=b, interface_b=a)
     link = Link.objects.filter(q).first()
     if link is None:
         raise LinkNotFound('Link matching query does not exist',
                            interface_a=a,
                            interface_b=b)
     return link
Пример #2
0
 def validate(value):
     try:
         netaddr.valid_mac(value)
     except netaddr.AddrFormatError:
         error = 'value should be MAC format.'
         raise ValueError(error)
     else:
         return value
Пример #3
0
 def check_config(self):
     super(DP, self).check_config()
     test_config_condition(not isinstance(self.dp_id, int), (
         'dp_id must be %s not %s' % (int, type(self.dp_id))))
     test_config_condition(self.dp_id < 0 or self.dp_id > 2**64-1, (
         'DP ID %s not in valid range' % self.dp_id))
     test_config_condition(not netaddr.valid_mac(self.faucet_dp_mac), (
         'invalid MAC address %s' % self.faucet_dp_mac))
     test_config_condition(not (self.interfaces or self.interface_ranges), (
         'DP %s must have at least one interface' % self))
     # To prevent L2 learning from timing out before L3 can refresh
     test_config_condition(self.timeout < self.arp_neighbor_timeout, (
         'L2 timeout must be >= ARP timeout'))
     if self.cache_update_guard_time == 0:
         self.cache_update_guard_time = int(self.timeout / 2)
     if self.learn_jitter == 0:
         self.learn_jitter = int(max(math.sqrt(self.timeout) * 3, 1))
     if self.learn_ban_timeout == 0:
         self.learn_ban_timeout = self.learn_jitter
     if self.lldp_beacon:
         self._check_conf_types(self.lldp_beacon, self.lldp_beacon_defaults_types)
         test_config_condition('send_interval' not in self.lldp_beacon, (
             'lldp_beacon send_interval not set'))
         test_config_condition('max_per_interval' not in self.lldp_beacon, (
             'lldp_beacon max_per_interval not set'))
         self.lldp_beacon = self._set_unknown_conf(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         if self.lldp_beacon['system_name'] is None:
             self.lldp_beacon['system_name'] = self.name
     if self.stack:
         self._check_conf_types(self.stack, self.stack_defaults_types)
     if self.dot1x:
         self._check_conf_types(self.dot1x, self.dot1x_defaults_types)
     self._check_conf_types(self.table_sizes, self.default_table_sizes_types)
Пример #4
0
def mac_address(mac, for_item=True):
    """
    Validate as an Eternet mac address.

    :param mac: mac address
    :type mac: str
    :returns: str mac or CX
    """
    if not isinstance(mac, str):
        raise CX("Invalid input, mac must be a string")
    else:
        mac = mac.lower().strip()

    if for_item is True:
        # this value has special meaning for items
        if mac == "random":
            return mac

        # copying system collection will set mac to ""
        # netaddr will fail to validate this mac and throw an exception
        if mac == "":
            return mac

    if not netaddr.valid_mac(mac):
        raise CX("Invalid mac address format (%s)" % mac)

    return mac
Пример #5
0
 def test_regenerate_mac_address(self):
     body = self.create_port(self.network)
     current_mac = body['mac_address']
     body = self.admin_client.update_port(body['id'], mac_address=None)
     new_mac = body['port']['mac_address']
     self.assertNotEqual(current_mac, new_mac)
     self.assertTrue(netaddr.valid_mac(new_mac))
Пример #6
0
 def check_config(self):
     assert isinstance(
         self.dp_id,
         int), 'dp_id must be %s not %s' % (int, type(self.dp_id))
     assert self.dp_id > 0 and self.dp_id <= 2**64 - 1, 'DP ID %s not in valid range' % self.dp_id
     assert netaddr.valid_mac(
         self.faucet_dp_mac), 'invalid MAC address %s' % self.faucet_dp_mac
     assert not (self.group_table and self.group_table_routing), (
         'groups for routing and other functions simultaneously not supported'
     )
     assert (self.interfaces or self.interface_ranges), (
         'DP %s must have at least one interface' % self)
     # To prevent L2 learning from timing out before L3 can refresh
     assert self.timeout >= self.arp_neighbor_timeout, 'L2 timeout must be >= L3 timeout'
     if self.lldp_beacon:
         self._check_conf_types(self.lldp_beacon,
                                self.lldp_beacon_defaults_types)
         assert 'send_interval' in self.lldp_beacon, (
             'lldp_beacon send_interval not set')
         assert 'max_per_interval' in self.lldp_beacon, (
             'lldp_beacon max_per_interval not set')
         self.lldp_beacon = self._set_unknown_conf(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         if self.lldp_beacon['system_name'] is None:
             self.lldp_beacon['system_name'] = self.name
     if self.stack:
         self._check_conf_types(self.stack, self.stack_defaults_types)
Пример #7
0
def validate_config(options):
    config = ConfigParser.ConfigParser()
    config.readfp(options.config)
    if not config.has_section(options.env):
        error("Environment {} does not exist in file {}".format(options.env, options.config.name))
    env = dict(config.items(options.env))

    if not valid_mac(env["fuel_mac"]):
        error("Wrong MAC address for Fuel node: {}".format(env["fuel_mac"]))

    for key in ["fuel_ip", "fuel_netmask", "fuel_gw", "fuel_control_ip"]:
        if not valid_ipv4(env[key]):
            error("Wrong IP address ({}) for {} parameter".format(env[key], key))

    ip = IPNetwork(env["fuel_ip"] + "/" + env["fuel_netmask"])
    gw = IPAddress(env["fuel_gw"])
    if gw not in ip:
        error("Gateway address is not within network range")

    for path in [
        env["image_mount_dir"],
        env["ks_files_dir"],
        env["ks_patch"],
        env["pxe_config_dir"],
        env["esxi_private_key_file"],
    ]:
        if not os.path.exists(path):
            error("Path {} does not exist or is not accessible".format(path))

    env["pxe_config_file"] = os.path.join(env["pxe_config_dir"], "01-{}".format(env["fuel_mac"].replace(":", "-")))
    return env
Пример #8
0
def validate_config(options):
    config = ConfigParser.ConfigParser()
    config.readfp(options.config)
    if not config.has_section(options.env):
        error('Environment {} does not exist in file {}'.format(
            options.env, options.config.name))
    env = dict(config.items(options.env))

    if not valid_mac(env['fuel_mac']):
        error('Wrong MAC address for Fuel node: {}'.format(env['fuel_mac']))

    for key in ['fuel_ip', 'fuel_netmask', 'fuel_gw', 'fuel_control_ip']:
        if not valid_ipv4(env[key]):
            error('Wrong IP address ({}) for {} parameter'.format(
                env[key], key))

    ip = IPNetwork(env['fuel_ip'] + '/' + env['fuel_netmask'])
    gw = IPAddress(env['fuel_gw'])
    if gw not in ip:
        error('Gateway address is not within network range')

    for path in [
            env['image_mount_dir'], env['ks_files_dir'], env['ks_patch'],
            env['pxe_config_dir'], env['esxi_private_key_file']
    ]:
        if not os.path.exists(path):
            error('Path {} does not exist or is not accessible'.format(path))

    env['pxe_config_file'] = os.path.join(
        env['pxe_config_dir'],
        '01-{}'.format(env['fuel_mac'].replace(':', '-')))
    return env
Пример #9
0
 def check_config(self):
     test_config_condition(not isinstance(self.dp_id, int),
                           ('dp_id must be %s not %s' %
                            (int, type(self.dp_id))))
     test_config_condition(self.dp_id < 0 or self.dp_id > 2**64 - 1,
                           ('DP ID %s not in valid range' % self.dp_id))
     test_config_condition(not netaddr.valid_mac(self.faucet_dp_mac),
                           ('invalid MAC address %s' % self.faucet_dp_mac))
     test_config_condition(self.group_table and self.group_table_routing, (
         'groups for routing and other functions simultaneously not supported'
     ))
     test_config_condition(
         not (self.interfaces or self.interface_ranges),
         ('DP %s must have at least one interface' % self))
     # To prevent L2 learning from timing out before L3 can refresh
     test_config_condition(self.timeout < self.arp_neighbor_timeout,
                           ('L2 timeout must be >= L3 timeout'))
     if self.lldp_beacon:
         self._check_conf_types(self.lldp_beacon,
                                self.lldp_beacon_defaults_types)
         test_config_condition('send_interval' not in self.lldp_beacon,
                               ('lldp_beacon send_interval not set'))
         test_config_condition('max_per_interval' not in self.lldp_beacon,
                               ('lldp_beacon max_per_interval not set'))
         self.lldp_beacon = self._set_unknown_conf(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         if self.lldp_beacon['system_name'] is None:
             self.lldp_beacon['system_name'] = self.name
     if self.stack:
         self._check_conf_types(self.stack, self.stack_defaults_types)
     if self.dot1x:
         self._check_conf_types(self.dot1x, self.dot1x_defaults_types)
     if self.table_sizes:
         self._check_conf_types(self.table_sizes, self.table_sizes_types)
Пример #10
0
def mac_address(mac: str, for_item=True) -> str:
    """
    Validate as an Ethernet MAC address.

    :param mac: MAC address
    :param for_item: If the check should be performed for an item or not.
    :returns: MAC address
    :raises ValueError: Raised in case ``mac`` has an invalid format.
    :raises TypeError: Raised in case ``mac`` is not a string.
    """
    if not isinstance(mac, str):
        raise TypeError("Invalid input, mac must be a string")
    mac = mac.lower().strip()

    if for_item is True:
        # this value has special meaning for items
        if mac == "random":
            return mac

        # copying system collection will set mac to ""
        # netaddr will fail to validate this mac and throws an exception
        if mac == "":
            return mac

    if not netaddr.valid_mac(mac):
        raise ValueError("Invalid mac address format (%s)" % mac)

    return mac
    def eui_is_valid(addr):
        '''Returns if addr is a valid MAC address.

        *Arguments*
        | argument | Description |  Example  |  Default value
        | addr | the mac address |  00-01-02-AA-BB-CC   |  -   |
        '''
        return netaddr.valid_mac(addr)
Пример #12
0
    def check_config(self):
        super(VLAN, self).check_config()
        test_config_condition(not self.vid_valid(self.vid), 'invalid VID %s' % self.vid)
        test_config_condition(not netaddr.valid_mac(self.faucet_mac), (
            'invalid MAC address %s' % self.faucet_mac))

        test_config_condition(
            self.acl_in and self.acls_in, 'found both acl_in and acls_in, use only acls_in')
        test_config_condition(
            self.acl_out and self.acls_out, 'found both acl_out and acls_out, use only acls_out')
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [self.acl_in,]
            self.acl_in = None
        if self.acl_out and not isinstance(self.acl_out, list):
            self.acls_out = [self.acl_out,]
            self.acl_out = None
        all_acls = []
        if self.acls_in:
            all_acls.extend(self.acls_in)
        if self.acls_out:
            all_acls.extend(self.acls_out)
        for acl in all_acls:
            test_config_condition(
                not isinstance(acl, (int, str)), 'acl names must be int or str')

        if self.max_hosts:
            if not self.proactive_arp_limit:
                self.proactive_arp_limit = 2 * self.max_hosts
            if not self.proactive_nd_limit:
                self.proactive_nd_limit = 2 * self.max_hosts

        if self.faucet_vips:
            self.faucet_vips = frozenset([
                self._check_ip_str(ip_str, ip_method=ipaddress.ip_interface)
                for ip_str in self.faucet_vips])
            for faucet_vip in self.faucet_vips:
                test_config_condition(
                    faucet_vip.network.prefixlen == faucet_vip.max_prefixlen,
                    'VIP cannot be a host address')

        if self.routes:
            test_config_condition(not isinstance(self.routes, list), 'invalid VLAN routes format')
            try:
                self.routes = [route['route'] for route in self.routes]
            except TypeError:
                raise InvalidConfigError('%s is not a valid routes value' % self.routes)
            except KeyError:
                pass
            for route in self.routes:
                test_config_condition(not isinstance(route, dict), 'invalid VLAN route format')
                test_config_condition('ip_gw' not in route, 'missing ip_gw in VLAN route')
                test_config_condition('ip_dst' not in route, 'missing ip_dst in VLAN route')
                ip_gw = self._check_ip_str(route['ip_gw'])
                ip_dst = self._check_ip_str(route['ip_dst'], ip_method=ipaddress.ip_network)
                test_config_condition(
                    ip_gw.version != ip_dst.version,
                    'ip_gw version does not match the ip_dst version')
                self.add_route(ip_dst, ip_gw)
Пример #13
0
def is_mac(mac_str):
    '''
    validate 48bit mac address  00:1b:77:ff:fe:49:54:ff'
    todo: 64bit mac?
    '''
    if netaddr.valid_mac(mac_str):
        return True
    else:
        return False
Пример #14
0
 def click_save(self) -> None:
     mac = self.mac_var.get()
     if not netaddr.valid_mac(mac):
         messagebox.showerror("MAC Error", f"{mac} is an invalid mac")
     else:
         self.app.core.ifaces_manager.mac = netaddr.EUI(mac)
         self.app.guiconfig.mac = mac
         self.app.save_config()
         self.destroy()
Пример #15
0
 def __post_load_macs(self):
     """
     Called by post_load() to load internal representation of macs
     """
     self.macs = self.link_data('macs', dict)
     for k, v in self.macs.items():
         old_k = k
         k = k.lower()
         if netaddr.valid_mac(k) is False:
             self.app.log.error("data:mac: Invalid key format '{}: File {}".format(k, self.path))
             continue
         if v is not None:
             v = v.lower()
             if netaddr.valid_mac(k) is False:
                 self.app.log.error("data:mac: Invalid value format '{}: File {}".format(k, self.path))
                 continue
         del self.macs[old_k]
         self.macs[k] = v
Пример #16
0
def mkAddress(addr):
    if netaddr.valid_mac(addr):
        return mkMACAddr(addr)
    elif netaddr.valid_ipv4(addr):
        return "IPAddr4{32'h%x}" % netaddr.IPAddress(addr)
    elif netaddr.valid_ipv6(addr):
        return "IPAddr6{128'h%x}" % netaddr.IPAddress(addr)
    else:
        raise Exception("unknown address format " + addr)
Пример #17
0
def check_mac_address_field(json_obj, mac_addr_field, required):
    mac_field = check_field(json_obj, mac_addr_field, str, required)
    if not mac_field and not required:
        return
    if not netaddr.valid_mac(mac_field):
        raise InvalidUsage(
            400,
            message=
            f"Supplied MAC '{mac_field}' in '{mac_addr_field}' is not valid")
    return mac_field
Пример #18
0
 def get_link(cls, source, target, topology=None):
     """
     Find link between source and target, (or vice versa, order is irrelevant).
     :param source: ip or mac addresses
     :param target: ip or mac addresses
     :param topology: optional topology relation
     :returns: Link object
     :raises: LinkNotFound
     """
     a = source
     b = target
     # ensure parameters are coherent
     if not (valid_ipv4(a) and valid_ipv4(b)) and not (
             valid_ipv6(a) and valid_ipv6(b)) and not (valid_mac(a)
                                                       and valid_mac(b)):
         raise ValueError('Expecting valid ipv4, ipv6 or mac address')
     # get interfaces
     a = cls._get_link_interface(a)
     b = cls._get_link_interface(b)
     # raise LinkDataNotFound if an interface is not found
     not_found = []
     if a is None:
         not_found.append(source)
     if b is None:
         not_found.append(target)
     if not_found:
         msg = 'the following interfaces could not be found: {0}'.format(
             ', '.join(not_found))
         raise LinkDataNotFound(msg)
     # find link with interfaces
     # inverse order is also ok
     q = (Q(interface_a=a, interface_b=b) | Q(interface_a=b, interface_b=a))
     # add topology to lookup
     if topology:
         q = q & Q(topology=topology)
     link = Link.objects.filter(q).first()
     if link is None:
         raise LinkNotFound('Link matching query does not exist',
                            interface_a=a,
                            interface_b=b,
                            topology=topology)
     return link
Пример #19
0
def _validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(_validate_no_whitespace(data))
        if valid_mac is False:
            msg = _("'%s' is not a valid MAC address") % data
            LOG.debug(msg)
            return msg
    except AttributeError as ex:
        msg = _("MAC address must be string: %s") % ex
        LOG.exception(msg)
        return msg
Пример #20
0
def validate_mac_address_or_none(instance):
    """Validate instance is a MAC address"""

    if instance is None:
        return

    if not netaddr.valid_mac(instance):
        msg = _("'%s' is not a valid mac address")
        raise webob.exc.HTTPBadRequest(explanation=msg % instance)

    return True
Пример #21
0
def _validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(_validate_no_whitespace(data))
        if valid_mac is False:
            msg = _("'%s' is not a valid MAC address") % data
            LOG.debug(msg)
            return msg
    except AttributeError as ex:
        msg = _("MAC address must be string: %s") % ex
        LOG.exception(msg)
        return msg
Пример #22
0
 def test_list_virtual_interfaces(self):
     # Positive test:Should be able to GET the virtual interfaces list
     # for a given server_id
     resp, output = self.client.list_virtual_interfaces(self.server_id)
     self.assertEqual(200, resp.status)
     self.assertNotEqual(output, None)
     virt_ifaces = output
     self.assertNotEqual(0, len(virt_ifaces["virtual_interfaces"]), "Expected virtual interfaces, got 0 interfaces.")
     for virt_iface in virt_ifaces["virtual_interfaces"]:
         mac_address = virt_iface["mac_address"]
         self.assertTrue(netaddr.valid_mac(mac_address), "Invalid mac address detected.")
Пример #23
0
def _validate_mac_address(name, value):
    """Check if a given value is a valid MAC address."""
    try:
        if not netaddr.valid_mac(value):
            raise wsme.exc.ClientSideError(_(
                "Parameter '%s' must be a valid MAC address" % name))
        if not int(netaddr.EUI(value).oui):
            raise wsme.exc.ClientSideError(_(
                "Parameter '%s' must be a MAC address with a non-zero OUI" %
                name))
    except netaddr.core.NotRegisteredError:
        pass  # allow any OUI value regardless of registration
Пример #24
0
 def test_list_virtual_interfaces(self):
     # Positive test:Should be able to GET the virtual interfaces list
     # for a given server_id
     output = self.client.list_virtual_interfaces(self.server_id)
     self.assertIsNotNone(output)
     virt_ifaces = output
     self.assertNotEqual(0, len(virt_ifaces['virtual_interfaces']),
                         'Expected virtual interfaces, got 0 interfaces.')
     for virt_iface in virt_ifaces['virtual_interfaces']:
         mac_address = virt_iface['mac_address']
         self.assertTrue(netaddr.valid_mac(mac_address),
                         "Invalid mac address detected.")
Пример #25
0
 def test_list_virtual_interfaces(self):
     # Positive test:Should be able to GET the virtual interfaces list
     # for a given server_id
     output = self.client.list_virtual_interfaces(self.server_id)
     self.assertIsNotNone(output)
     virt_ifaces = output
     self.assertNotEqual(0, len(virt_ifaces['virtual_interfaces']),
                         'Expected virtual interfaces, got 0 interfaces.')
     for virt_iface in virt_ifaces['virtual_interfaces']:
         mac_address = virt_iface['mac_address']
         self.assertTrue(netaddr.valid_mac(mac_address),
                         "Invalid mac address detected.")
Пример #26
0
def _validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(_validate_no_whitespace(data))
    except Exception:
        valid_mac = False
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. _validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #27
0
def _validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(_validate_no_whitespace(data))
    except Exception:
        valid_mac = False
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. _validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #28
0
    def check_config(self):
        super(VLAN, self).check_config()
        assert self.vid_valid(self.vid), 'invalid VID %s' % self.vid
        assert netaddr.valid_mac(
            self.faucet_mac), 'invalid MAC address %s' % self.faucet_mac

        if self.faucet_vips:
            try:
                self.faucet_vips = [
                    ipaddress.ip_interface(btos(ip)) for ip in self.faucet_vips
                ]
            except (ValueError, AttributeError, TypeError) as err:
                assert False, 'Invalid IP address in faucet_vips: %s' % err
            for faucet_vip in self.faucet_vips:
                self.dyn_faucet_vips_by_ipv[faucet_vip.version].append(
                    faucet_vip)
            self.dyn_ipvs = list(self.dyn_faucet_vips_by_ipv.keys())

        if self.bgp_as:
            assert self.bgp_port
            assert ipaddress.IPv4Address(btos(self.bgp_routerid))
            for neighbor_ip in self.bgp_neighbor_addresses:
                assert ipaddress.ip_address(btos(neighbor_ip))
            assert self.bgp_neighbor_as

        if self.routes:
            try:
                self.routes = [route['route'] for route in self.routes]
                for route in self.routes:
                    try:
                        ip_gw = ipaddress.ip_address(btos(route['ip_gw']))
                        ip_dst = ipaddress.ip_network(btos(route['ip_dst']))
                    except (ValueError, AttributeError, TypeError) as err:
                        assert False, 'Invalid IP address in route: %s' % err
                    assert ip_gw.version == ip_dst.version
                    self.dyn_routes_by_ipv[ip_gw.version][ip_dst] = ip_gw
            except KeyError:
                assert False, 'missing route config'
            except TypeError:
                assert False, '%s is not a valid routes value' % self.routes
        if self.acl_in and self.acls_in:
            assert False, 'found both acl_in and acls_in, use only acls_in'
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [
                self.acl_in,
            ]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                assert isinstance(acl,
                                  (int, str)), 'acl names must be int or str'
Пример #29
0
 def _validate_mac(self, parent: tk.BaseWidget, iface: Interface) -> bool:
     mac = self.mac.get()
     auto_mac = self.is_auto.get()
     if auto_mac:
         iface.mac = None
     else:
         if not netaddr.valid_mac(mac):
             title = f"MAC Error for {iface.name}"
             messagebox.showerror(title,
                                  "Invalid MAC Address",
                                  parent=parent)
             return False
         else:
             mac = netaddr.EUI(mac, dialect=netaddr.mac_unix_expanded)
             iface.mac = str(mac)
     return True
Пример #30
0
def validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(validate_no_whitespace(data))
    except Exception:
        valid_mac = False

    if valid_mac:
        valid_mac = (not netaddr.EUI(data) in
                     map(netaddr.EUI, constants.INVALID_MAC_ADDRESSES))
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #31
0
def validate_mac_address(data, valid_values=None):
    try:
        valid_mac = netaddr.valid_mac(validate_no_whitespace(data))
    except Exception:
        valid_mac = False

    if valid_mac:
        valid_mac = (not netaddr.EUI(data) in map(
            netaddr.EUI, constants.INVALID_MAC_ADDRESSES))
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #32
0
def ovn_pre_check(topo_d, name, info):
    for ls, mac_cidrs in info.get('interfaces', {}).iteritems():
        mtu = topo_d.get(ls, {}).get('mtu')
        if mtu and not (str(mtu).isdigit() and 0 < mtu < 1500):
            raise ValueError('ovn_ls %s not found or has invalid mtu' % ls)
        ls_cidrs = topo_d.get(ls, {}).get('cidr')
        if not ls_cidrs:
            raise ValueError('ovn_ls %s not found or has no cidr' % ls)
        ls_cidrs = ls_cidrs.split()
        try:
            ls_ip_nets = [netaddr.IPNetwork(cidr) for cidr in ls_cidrs]
        except Exception as e:
            raise ValueError('ovn_ls %s has an invalid cidr: %s' %
                             (ls, e.message))
        mac, cidrs = mac_cidrs.split(' ', 1)
        if not (netaddr.valid_mac(mac) and mac[1] != '1'):
            raise ValueError("%(name)s interface has an invalid mac %(mac)s" %
                             {
                                 'name': name,
                                 'mac': mac
                             })
        cidrs = cidrs.split()
        try:
            intf_nets = [netaddr.IPNetwork(cidr) for cidr in cidrs]
        except Exception as e:
            raise ValueError(
                '%(name)s interface on %(ls)s has an invalid cidr: %(e)s' % {
                    'name': name,
                    'ls': ls,
                    'e': e.message
                })
        if set(intf_nets) - set(ls_ip_nets):
            raise ValueError("Not all %(name)s interface cidr in its %(ls)s" %
                             {
                                 'name': name,
                                 'ls': ls
                             })
        chassis = info.get('chassis')
        if not (chassis and os.path.exists('/var/run/netns/%s' % chassis)):
            raise ValueError(
                ("%s interface doesn't have an valid 'chassis' to indicate "
                 "which chassis it resides on") % name)
        chassis_sock = info.get('chassis_sock')
        if not (chassis_sock and os.path.exists(chassis_sock)):
            raise ValueError(
                "%s interface doesn't have an valid 'chassis_sock'" % name)
Пример #33
0
 def check_config(self):
     super(DP, self).check_config()
     test_config_condition(not isinstance(self.dp_id, int),
                           ('dp_id must be %s not %s' %
                            (int, type(self.dp_id))))
     test_config_condition(self.dp_id < 0 or self.dp_id > 2**64 - 1,
                           ('DP ID %s not in valid range' % self.dp_id))
     test_config_condition(not netaddr.valid_mac(self.faucet_dp_mac),
                           ('invalid MAC address %s' % self.faucet_dp_mac))
     test_config_condition(
         not (self.interfaces or self.interface_ranges),
         ('DP %s must have at least one interface' % self))
     test_config_condition(self.timeout < 15, ('timeout must be > 15'))
     # To prevent L2 learning from timing out before L3 can refresh
     test_config_condition(
         not (self.arp_neighbor_timeout < (self.timeout / 2)),
         ('L2 timeout must be > ARP timeout * 2'))
     test_config_condition(
         not (self.nd_neighbor_timeout < (self.timeout / 2)),
         ('L2 timeout must be > ND timeout * 2'))
     test_config_condition(
         self.combinatorial_port_flood and self.group_table,
         ('combinatorial_port_flood and group_table mutually exclusive'))
     if self.cache_update_guard_time == 0:
         self.cache_update_guard_time = int(self.timeout / 2)
     if self.learn_jitter == 0:
         self.learn_jitter = int(max(math.sqrt(self.timeout) * 3, 1))
     if self.learn_ban_timeout == 0:
         self.learn_ban_timeout = self.learn_jitter
     if self.lldp_beacon:
         self._check_conf_types(self.lldp_beacon,
                                self.lldp_beacon_defaults_types)
         test_config_condition('send_interval' not in self.lldp_beacon,
                               ('lldp_beacon send_interval not set'))
         test_config_condition('max_per_interval' not in self.lldp_beacon,
                               ('lldp_beacon max_per_interval not set'))
         self.lldp_beacon = self._set_unknown_conf(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         if self.lldp_beacon['system_name'] is None:
             self.lldp_beacon['system_name'] = self.name
     if self.stack:
         self._check_conf_types(self.stack, self.stack_defaults_types)
     if self.dot1x:
         self._check_conf_types(self.dot1x, self.dot1x_defaults_types)
     self._check_conf_types(self.table_sizes,
                            self.default_table_sizes_types)
Пример #34
0
 def serialize(self, _payload=None, _prev=None):
     opt_buf = bytearray()
     if self.options is not None:
         opt_buf = self.options.serialize()
     if netaddr.valid_mac(self.chaddr):
         chaddr = addrconv.mac.text_to_bin(self.chaddr)
     else:
         chaddr = self.chaddr
     self.hlen = len(chaddr)
     return struct.pack(self._DHCP_PACK_STR, self.op, self.htype, self.hlen,
                        self.hops, self.xid, self.secs, self.flags,
                        addrconv.ipv4.text_to_bin(self.ciaddr),
                        addrconv.ipv4.text_to_bin(self.yiaddr),
                        addrconv.ipv4.text_to_bin(self.siaddr),
                        addrconv.ipv4.text_to_bin(self.giaddr), chaddr,
                        self.sname.encode('ascii'),
                        self.boot_file.encode('ascii')) + opt_buf
Пример #35
0
 def test_list_virtual_interfaces(self):
     """Test listing virtual interfaces of a server"""
     if CONF.service_available.neutron:
         with testtools.ExpectedException(exceptions.BadRequest):
             self.client.list_virtual_interfaces(self.server['id'])
     else:
         output = self.client.list_virtual_interfaces(self.server['id'])
         virt_ifaces = output['virtual_interfaces']
         self.assertNotEmpty(
             virt_ifaces, 'Expected virtual interfaces, got 0 '
             'interfaces.')
         for virt_iface in virt_ifaces:
             mac_address = virt_iface['mac_address']
             self.assertTrue(
                 netaddr.valid_mac(mac_address),
                 "Invalid mac address detected. mac address: %s" %
                 mac_address)
Пример #36
0
    def check_config(self):
        super(VLAN, self).check_config()
        test_config_condition(not self.vid_valid(self.vid), 'invalid VID %s' % self.vid)
        test_config_condition(not netaddr.valid_mac(self.faucet_mac), (
            'invalid MAC address %s' % self.faucet_mac))

        test_config_condition(
            self.acl_in and self.acls_in, 'found both acl_in and acls_in, use only acls_in')
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [self.acl_in,]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                test_config_condition(
                    not isinstance(acl, (int, str)), 'acl names must be int or str')

        if self.max_hosts:
            if not self.proactive_arp_limit:
                self.proactive_arp_limit = 2 * self.max_hosts
            if not self.proactive_nd_limit:
                self.proactive_nd_limit = 2 * self.max_hosts

        if self.faucet_vips:
            self.faucet_vips = frozenset([
                self._check_ip_str(ip_str, ip_method=ipaddress.ip_interface)
                for ip_str in self.faucet_vips])

        if self.routes:
            test_config_condition(not isinstance(self.routes, list), 'invalid VLAN routes format')
            try:
                self.routes = [route['route'] for route in self.routes]
            except TypeError:
                raise InvalidConfigError('%s is not a valid routes value' % self.routes)
            except KeyError:
                pass
            for route in self.routes:
                test_config_condition(not isinstance(route, dict), 'invalid VLAN route format')
                test_config_condition('ip_gw' not in route, 'missing ip_gw in VLAN route')
                test_config_condition('ip_dst' not in route, 'missing ip_dst in VLAN route')
                ip_gw = self._check_ip_str(route['ip_gw'])
                ip_dst = self._check_ip_str(route['ip_dst'], ip_method=ipaddress.ip_network)
                test_config_condition(
                    ip_gw.version != ip_dst.version,
                    'ip_gw version does not match the ip_dst version')
                self.add_route(ip_dst, ip_gw)
Пример #37
0
 def serialize(self, _payload=None, _prev=None):
     opt_buf = bytearray()
     if self.options is not None:
         opt_buf = self.options.serialize()
     if netaddr.valid_mac(self.chaddr):
         chaddr = addrconv.mac.text_to_bin(self.chaddr)
     else:
         chaddr = self.chaddr
     self.hlen = len(chaddr)
     return struct.pack(self._DHCP_PACK_STR, self.op, self.htype, self.hlen,
                        self.hops, self.xid, self.secs, self.flags,
                        addrconv.ipv4.text_to_bin(self.ciaddr),
                        addrconv.ipv4.text_to_bin(self.yiaddr),
                        addrconv.ipv4.text_to_bin(self.siaddr),
                        addrconv.ipv4.text_to_bin(self.giaddr),
                        chaddr,
                        self.sname.encode('ascii'),
                        self.boot_file.encode('ascii')) + opt_buf
Пример #38
0
    def test_list_virtual_interfaces(self):
        # Positive test:Should be able to GET the virtual interfaces list
        # for a given server_id

        if CONF.service_available.neutron:
            with testtools.ExpectedException(exceptions.BadRequest):
                self.client.list_virtual_interfaces(self.server['id'])
        else:
            output = self.client.list_virtual_interfaces(self.server['id'])
            virt_ifaces = output['virtual_interfaces']
            self.assertNotEmpty(virt_ifaces,
                                'Expected virtual interfaces, got 0 '
                                'interfaces.')
            for virt_iface in virt_ifaces:
                mac_address = virt_iface['mac_address']
                self.assertTrue(netaddr.valid_mac(mac_address),
                                "Invalid mac address detected. mac address: %s"
                                % mac_address)
Пример #39
0
    def get(self, mac, full):
        """
        json response from www.macvendorlookup.com:

        {u'addressL1': u'1 Infinite Loop',
        u'addressL2': u'',
        u'addressL3': u'Cupertino CA 95014',
        u'company': u'Apple',
        u'country': u'UNITED STATES',
        u'endDec': u'202412195315711',
        u'endHex': u'B817C2FFFFFF',
        u'startDec': u'202412178538496',
        u'startHex': u'B817C2000000',
        u'type': u'MA-L'}
        """
        unknown = {'company': 'unknown'}
        if not valid_mac(mac):
            print('Error: the mac addr {} is not valid'.format(mac))
            return

        try:
            r = requests.get('http://www.macvendorlookup.com/api/v2/' + mac)
        except requests.exceptions.HTTPError as e:
            print("HTTPError:", e.message)
            return unknown

        if r.status_code == 204:  # no content found, bad MAC addr
            print('ERROR: Bad MAC addr:', mac)
            return unknown
        elif r.headers['content-type'] != 'application/json':
            print('ERROR: Wrong content type:', r.headers['content-type'])
            return unknown

        a = {}

        try:
            if full: a = r.json()[0]
            else: a['company'] = r.json()[0]['company']
            # print 'GOOD:',r.status_code,r.headers,r.ok,r.text,r.reason
        except:
            print('ERROR:', r.status_code, r.headers, r.ok, r.text, r.reason)
            a = unknown

        return a
Пример #40
0
	def get(self, mac, full):
		"""
		json response from www.macvendorlookup.com:

		{u'addressL1': u'1 Infinite Loop',
		u'addressL2': u'',
		u'addressL3': u'Cupertino CA 95014',
		u'company': u'Apple',
		u'country': u'UNITED STATES',
		u'endDec': u'202412195315711',
		u'endHex': u'B817C2FFFFFF',
		u'startDec': u'202412178538496',
		u'startHex': u'B817C2000000',
		u'type': u'MA-L'}
		"""
		unknown = {'company': 'unknown'}
		if not valid_mac(mac):
			print('Error: the mac addr {} is not valid'.format(mac))
			return

		try:
			r = requests.get('http://www.macvendorlookup.com/api/v2/' + mac)
		except requests.exceptions.HTTPError as e:
			print ("HTTPError:", e.message)
			return unknown

		if r.status_code == 204:  # no content found, bad MAC addr
			print ('ERROR: Bad MAC addr:', mac)
			return unknown
		elif r.headers['content-type'] != 'application/json':
			print ('ERROR: Wrong content type:', r.headers['content-type'])
			return unknown

		a = {}

		try:
			if full: a = r.json()[0]
			else: a['company'] = r.json()[0]['company']
			# print 'GOOD:',r.status_code,r.headers,r.ok,r.text,r.reason
		except:
			print ('ERROR:', r.status_code, r.headers, r.ok, r.text, r.reason)
			a = unknown

		return a
Пример #41
0
    def test_list_virtual_interfaces(self):
        # Positive test:Should be able to GET the virtual interfaces list
        # for a given server_id

        if CONF.service_available.neutron:
            with testtools.ExpectedException(exceptions.BadRequest):
                self.client.list_virtual_interfaces(self.server['id'])
        else:
            output = self.client.list_virtual_interfaces(self.server['id'])
            virt_ifaces = output['virtual_interfaces']
            self.assertNotEmpty(
                virt_ifaces, 'Expected virtual interfaces, got 0 '
                'interfaces.')
            for virt_iface in virt_ifaces:
                mac_address = virt_iface['mac_address']
                self.assertTrue(
                    netaddr.valid_mac(mac_address),
                    "Invalid mac address detected. mac address: %s" %
                    mac_address)
Пример #42
0
    def __init__(self, startMac, macCount):
        """
        Initialize the object.
        :param start: string notation for first mac address.
        :param count: Number of mac addresses to be maintained.
        """
        self.startMac = startMac
        self.macCount = macCount

        if self.macCount <= 0:
            raise Exception(
                "Not possible to issue mac addresses in this range")

        if netaddr.valid_mac(self.startMac):
            raise Exception("Not a valid mac address")

        self.EnsureMacsAvailable(self.startMac, self.macCount)

        self.macDB = MacDatabase(self, self.startMac, self.macCount)
Пример #43
0
    def test_list_virtual_interfaces(self):
        # Positive test:Should be able to GET the virtual interfaces list
        # for a given server_id

        if CONF.service_available.neutron:
            # TODO(mriedem): After a microversion implements the API for
            # neutron, a 400 should be a failure for nova-network and neutron.
            with testtools.ExpectedException(exceptions.BadRequest):
                self.client.list_virtual_interfaces(self.server['id'])
        else:
            output = self.client.list_virtual_interfaces(self.server['id'])
            virt_ifaces = output
            self.assertNotEmpty(virt_ifaces['virtual_interfaces'],
                                'Expected virtual interfaces, got 0 '
                                'interfaces.')
            for virt_iface in virt_ifaces['virtual_interfaces']:
                mac_address = virt_iface['mac_address']
                self.assertTrue(netaddr.valid_mac(mac_address),
                                "Invalid mac address detected. mac address: %s"
                                % mac_address)
Пример #44
0
    def get_policy_for_ep(self, endpoint):
        """Get all the policy for a given EP

        Start by finding the Endpoint in the L2 or L3
        EP subtrees:
        /EpdrL2Discovered/EpdrLocalL2Ep
        /EpdrL3Discovered/EpdrLocalL3Ep

        If an L3 EP is requested, there should also be an
        associated L2 EP. The search for policy continues from the
        L2 EP, as that object will have children URis.
        """
        def _find_matching_ep(endpoint, ep_type, eps):
            for ep in eps:
                prop = ep._get_property(ep_type)
                if prop and endpoint in prop.get('data'):
                    return ep
            return None

        # Devine the EP type, if possible
        l2_ep_obj = None
        l3_ep_obj = None
        if netaddr.valid_ipv4(endpoint) or netaddr.valid_ipv6(endpoint):
            #ep_obj = netaddr.IPAddress(endpoint)
            eps = self.objects_by_type.get('EpdrLocalL3Ep')
            l3_ep_obj = _find_matching_ep(endpoint, 'ip', eps)
            if l3_ep_obj:
                l3_ep_obj.do_print()
            if not l3_ep_obj or not l3_ep_obj._get_property('mac'):
                return
            endpoint = l3_ep_obj._get_property('mac')['data']

        if netaddr.valid_mac(endpoint):
            eps = self.objects_by_type.get('EpdrLocalL2Ep')
            l2_ep_obj = _find_matching_ep(endpoint, 'mac', eps)
            if l2_ep_obj:
                l2_ep_obj.do_print()
            if not l2_ep_obj or not l2_ep_obj.children:
                return
        # Now do depth-first search for each child
        self.find_related_objects(l2_ep_obj)
Пример #45
0
def mac_address(mac, for_item=True):
    """
    Validate as an Eternet mac address.

    @param: str mac (mac address)
    @returns: str mac or CX
    """
    if not isinstance(mac, basestring):
        raise CX("Invalid input, mac must be a string")
    else:
        mac = mac.lower().strip()

    if for_item is True:
        # this value has special meaning for items
        if mac == "random":
            return mac

    if not netaddr.valid_mac(mac):
        raise CX("Invalid mac address format (%s)" % mac)

    return mac
Пример #46
0
def mac_address(mac, for_item=True):
    """
    Validate as an Eternet mac address.

    @param: str mac (mac address)
    @returns: str mac or CX
    """
    if not isinstance(mac, basestring):
        raise CX("Invalid input, mac must be a string")
    else:
        mac = mac.lower().strip()

    if for_item is True:
        # this value has special meaning for items
        if mac == "random":
            return mac

    if not netaddr.valid_mac(mac):
        raise CX("Invalid mac address format (%s)" % mac)

    return mac
Пример #47
0
def validate_mac_address(data, valid_values=None):
    """Validate data is a MAC address.

    :param data: The data to validate.
    :param valid_values: Not used!
    :returns: None if the data is a valid MAC address, otherwise a human
    readable message as to why validation failed.
    """
    try:
        valid_mac = netaddr.valid_mac(validate_no_whitespace(data))
    except Exception:
        valid_mac = False

    if valid_mac:
        valid_mac = (not netaddr.EUI(data) in
                     map(netaddr.EUI, constants.INVALID_MAC_ADDRESSES))
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #48
0
    def check_config(self):
        super(VLAN, self).check_config()
        test_config_condition(not self.vid_valid(self.vid), 'invalid VID %s' % self.vid)
        test_config_condition(not netaddr.valid_mac(self.faucet_mac), (
            'invalid MAC address %s' % self.faucet_mac))

        test_config_condition(self.acl_in and self.acls_in, 'found both acl_in and acls_in, use only acls_in')
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [self.acl_in,]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                test_config_condition(not isinstance(acl, (int, str)), 'acl names must be int or str')

        if self.max_hosts:
            if not self.proactive_arp_limit:
                self.proactive_arp_limit = 2 * self.max_hosts
            if not self.proactive_nd_limit:
                self.proactive_nd_limit = 2 * self.max_hosts

        if self.faucet_vips:
            self.faucet_vips = frozenset([
                self._check_ip_str(ip_str, ip_method=ipaddress.ip_interface) for ip_str in self.faucet_vips])

        if self.bgp_neighbor_addresses or self.bgp_neighbour_addresses:
            neigh_addresses = frozenset(self.bgp_neighbor_addresses + self.bgp_neighbour_addresses)
            self.bgp_neighbor_addresses = frozenset([
                self._check_ip_str(ip_str) for ip_str in neigh_addresses])

        if self.bgp_server_addresses:
            self.bgp_server_addresses = frozenset([
                self._check_ip_str(ip_str) for ip_str in self.bgp_server_addresses])
            for ipv in self.bgp_ipvs():
                test_config_condition(
                    len(self.bgp_server_addresses_by_ipv(ipv)) != 1,
                    'Only one BGP server address per IP version supported')

        if self.bgp_as:
            test_config_condition(not isinstance(self.bgp_port, int), (
                'BGP port must be %s not %s' % (int, type(self.bgp_port))))
            test_config_condition(self.bgp_connect_mode not in ('passive'), (
                'BGP connect mode %s must be passive' % self.bgp_connect_mode))
            test_config_condition(not ipaddress.IPv4Address(self.bgp_routerid), (
                '%s is not a valid IPv4 address' % (self.bgp_routerid)))
            test_config_condition(not self.bgp_neighbor_as, 'No BGP neighbor AS')
            test_config_condition(not self.bgp_neighbor_addresses, 'No BGP neighbor addresses')
            test_config_condition(len(self.bgp_neighbor_addresses) != len(self.bgp_neighbor_addresses), (
                'Must be as many BGP neighbor addresses as BGP server addresses'))

        if self.routes:
            test_config_condition(not isinstance(self.routes, list), 'invalid VLAN routes format')
            try:
                self.routes = [route['route'] for route in self.routes]
            except TypeError:
                raise InvalidConfigError('%s is not a valid routes value' % self.routes)
            except KeyError:
                pass
            for route in self.routes:
                test_config_condition(not isinstance(route, dict), 'invalid VLAN route format')
                test_config_condition('ip_gw' not in route, 'missing ip_gw in VLAN route')
                test_config_condition('ip_dst' not in route, 'missing ip_dst in VLAN route')
                ip_gw = self._check_ip_str(route['ip_gw'])
                ip_dst = self._check_ip_str(route['ip_dst'], ip_method=ipaddress.ip_network)
                test_config_condition(
                    ip_gw.version != ip_dst.version,
                    'ip_gw version does not match the ip_dst version')
                self.add_route(ip_dst, ip_gw)
Пример #49
0
def validate_endpoint(config, combined_id, endpoint):
    """
    Ensures that the supplied endpoint is valid. Once this routine has returned
    successfully, we know that all required fields are present and have valid
    values.

    Has the side-effect of putting IP and MAC addresses in canonical form in
    the input dict.

    :param config: configuration structure
    :param combined_id: EndpointId object
    :param endpoint: endpoint dictionary as read from etcd
    :raises ValidationFailed
    """
    issues = []

    if not isinstance(endpoint, dict):
        raise ValidationFailed("Expected endpoint to be a dict.")

    if not VALID_ID_RE.match(combined_id.endpoint):
        issues.append("Invalid endpoint ID '%r'." % combined_id.endpoint)

    if "state" not in endpoint:
        issues.append("Missing 'state' field.")
    elif endpoint["state"] not in ("active", "inactive"):
        issues.append("Expected 'state' to be one of active/inactive.")

    for field in ["name", "mac"]:
        if field not in endpoint:
            issues.append("Missing '%s' field." % field)
        elif not isinstance(endpoint[field], StringTypes):
            issues.append("Expected '%s' to be a string; got %r." %
                          (field, endpoint[field]))
        elif field == "mac":
            if not netaddr.valid_mac(endpoint.get("mac")):
                issues.append("Invalid MAC address")
            else:
                endpoint["mac"] = canonicalise_mac(endpoint.get("mac"))

    if "profile_id" in endpoint:
        if "profile_ids" not in endpoint:
            endpoint["profile_ids"] = [endpoint["profile_id"]]
        del endpoint["profile_id"]

    if "profile_ids" not in endpoint:
        issues.append("Missing 'profile_id(s)' field.")
    else:
        for value in endpoint["profile_ids"]:
            if not isinstance(value, StringTypes):
                issues.append("Expected profile IDs to be strings.")
                break

            if not VALID_ID_RE.match(value):
                issues.append("Invalid profile ID '%r'." % value)

    if ("name" in endpoint and isinstance(endpoint['name'], StringTypes)
        and combined_id.host == config.HOSTNAME
        and not endpoint["name"].startswith(config.IFACE_PREFIX)):
        # Only test the interface for local endpoints - remote hosts may have
        # a different interface prefix.
        issues.append("Interface %r does not start with %r." %
                      (endpoint["name"], config.IFACE_PREFIX))

    for version in (4, 6):
        nets = "ipv%d_nets" % version
        if nets not in endpoint:
            endpoint[nets] = []
        else:
            canonical_nws = []
            nets_list = endpoint.get(nets, [])
            if not isinstance(nets_list, list):
                issues.append("%s should be a list" % nets)
            else:
                for ip in nets_list:
                    if not validate_cidr(ip, version):
                        issues.append("IP address %r is not a valid "
                                      "IPv%d CIDR." % (ip, version))
                        break
                    else:
                        canonical_nws.append(canonicalise_cidr(ip, version))
                endpoint[nets] = canonical_nws

        gw_key = "ipv%d_gateway" % version
        try:
            gw_str = endpoint[gw_key]
            if gw_str is not None and not validate_ip_addr(gw_str,
                                                           version):
                issues.append("%s is not a valid IPv%d gateway address." %
                              (gw_key, version))
            else:
                endpoint[gw_key] = canonicalise_ip(gw_str, version)
        except KeyError:
            pass

    if issues:
        raise ValidationFailed(" ".join(issues))
Пример #50
0
 def get_link(cls, source, target, topology=None):
     """
     Find link between source and target, (or vice versa, order is irrelevant).
     :param source: ip or mac addresses
     :param target: ip or mac addresses
     :param topology: optional topology relation
     :returns: Link object
     :raises: LinkNotFound
     """
     a = source
     b = target
     # ensure parameters are coherent
     if not (valid_ipv4(a) and valid_ipv4(b)) and not (valid_ipv6(a) and valid_ipv6(b)) and not (valid_mac(a) and valid_mac(b)):
         raise ValueError('Expecting valid ipv4, ipv6 or mac address')
     # get interfaces
     a = cls._get_link_interface(a)
     b = cls._get_link_interface(b)
     # raise LinkDataNotFound if an interface is not found
     not_found = []
     if a is None:
         not_found.append(source)
     if b is None:
         not_found.append(target)
     if not_found:
         msg = 'the following interfaces could not be found: {0}'.format(', '.join(not_found))
         raise LinkDataNotFound(msg)
     # find link with interfaces
     # inverse order is also ok
     q = (Q(interface_a=a, interface_b=b) | Q(interface_a=b, interface_b=a))
     # add topology to lookup
     if topology:
         q = q & Q(topology=topology)
     link = Link.objects.filter(q).first()
     if link is None:
         raise LinkNotFound('Link matching query does not exist',
                            interface_a=a,
                            interface_b=b,
                            topology=topology)
     return link
Пример #51
0
def validate_endpoint(config, combined_id, endpoint):
    """
    Ensures that the supplied endpoint is valid. Once this routine has returned
    successfully, we know that all required fields are present and have valid
    values.

    Has the side-effect of putting IP and MAC addresses in canonical form in
    the input dict.

    :param config: configuration structure
    :param combined_id: EndpointId object
    :param endpoint: endpoint dictionary as read from etcd
    :raises ValidationFailed
    """
    issues = []

    if not isinstance(endpoint, dict):
        raise ValidationFailed("Expected endpoint to be a dict.")

    if not VALID_ID_RE.match(combined_id.endpoint):
        issues.append("Invalid endpoint ID '%r'." % combined_id.endpoint)

    if "state" not in endpoint:
        issues.append("Missing 'state' field.")
    elif endpoint["state"] not in ("active", "inactive"):
        issues.append("Expected 'state' to be one of active/inactive.")

    for field in ["name", "mac"]:
        if field not in endpoint:
            issues.append("Missing '%s' field." % field)
        elif not isinstance(endpoint[field], StringTypes):
            issues.append("Expected '%s' to be a string; got %r." %
                          (field, endpoint[field]))
        elif field == "mac":
            if not netaddr.valid_mac(endpoint.get("mac")):
                issues.append("Invalid MAC address")
            else:
                endpoint["mac"] = canonicalise_mac(endpoint.get("mac"))

    if "profile_id" in endpoint:
        if "profile_ids" not in endpoint:
            endpoint["profile_ids"] = [endpoint["profile_id"]]
        del endpoint["profile_id"]

    if "profile_ids" not in endpoint:
        issues.append("Missing 'profile_id(s)' field.")
    else:
        for value in endpoint["profile_ids"]:
            if not isinstance(value, StringTypes):
                issues.append("Expected profile IDs to be strings.")
                break

            if not VALID_ID_RE.match(value):
                issues.append("Invalid profile ID '%r'." % value)

    if ("name" in endpoint and isinstance(endpoint['name'], StringTypes)
        and combined_id.host == config.HOSTNAME
        and not endpoint["name"].startswith(config.IFACE_PREFIX)):
        # Only test the interface for local endpoints - remote hosts may have
        # a different interface prefix.
        issues.append("Interface %r does not start with %r." %
                      (endpoint["name"], config.IFACE_PREFIX))

    if "labels" in endpoint:
        _validate_label_dict(issues, endpoint["labels"])

    for version in (4, 6):
        nets = "ipv%d_nets" % version
        if nets not in endpoint:
            endpoint[nets] = []
        else:
            canonical_nws = []
            nets_list = endpoint.get(nets, [])
            if not isinstance(nets_list, list):
                issues.append("%s should be a list." % nets)
            else:
                for ip in nets_list:
                    if not validate_cidr(ip, version):
                        issues.append("IP address %r is not a valid "
                                      "IPv%d CIDR." % (ip, version))
                        break
                    else:
                        canonical_nws.append(canonicalise_cidr(ip, version))
                endpoint[nets] = canonical_nws

        n_key = nat_key(version)
        nat_maps = endpoint.get(n_key, None)
        if nat_maps is not None:
            if isinstance(nat_maps, list):
                canonical_nm = []
                for nat_map in nat_maps:
                    canonical = {}
                    for t in "int", "ext":
                        canonical[t] = None
                        ip = nat_map.get("%s_ip" % t, None)
                        if ip:
                            if validate_ip_addr(ip, version):
                                canonical[t] = canonicalise_ip(ip, version)
                            else:
                                issues.append("%s_ip (%r) is not a valid IPv%d"
                                              " address." % (t, ip, version))
                        else:
                            issues.append("%s_ip was not specified a %s entry."
                                          % (t, n_key))
                    if canonical["int"] and canonical["ext"]:
                        canonical_nm.append({"int_ip": canonical["int"],
                                             "ext_ip": canonical["ext"]})
                endpoint[n_key] = canonical_nm

                for nat_map in canonical_nm:
                    if version == 4:
                        nm = "/32"
                    else:
                        nm = "/128"
                    int_ip_nm = nat_map["int_ip"] + nm
                    # At this point these have all been canonicalized, so we
                    # should be able to do a strict string comparison.
                    if int_ip_nm not in endpoint[nets]:
                        issues.append("int_ip %s is not listed in %s." %
                                      (int_ip_nm, nets))
            else:
                issues.append("%s should be a list." % n_key)

        gw_key = "ipv%d_gateway" % version
        try:
            gw_str = endpoint[gw_key]
            if gw_str is not None and not validate_ip_addr(gw_str,
                                                           version):
                issues.append("%s is not a valid IPv%d gateway address." %
                              (gw_key, version))
            else:
                endpoint[gw_key] = canonicalise_ip(gw_str, version)
        except KeyError:
            pass

    if issues:
        raise ValidationFailed(" ".join(issues))
Пример #52
0
def test_valid_mac():
    assert valid_mac('00-B0-D0-86-BB-F7')
    assert not valid_mac('00-1B-77-49-54-FD-12-34')
Пример #53
0
def _validate_endpoint_common(config, combined_id, endpoint):
    """
    Ensures that the supplied endpoint is valid. Once this routine has returned
    successfully, we know that all required fields are present and have valid
    values.

    Has the side-effect of putting IP and MAC addresses in canonical form in
    the input dict.

    :param config: configuration structure
    :param combined_id: EndpointId object
    :param endpoint: endpoint dictionary as read from etcd
    :raises ValidationFailed
    """
    issues = []

    if not isinstance(endpoint, dict):
        raise ValidationFailed("Expected endpoint to be a dict.")

    if not VALID_ID_RE.match(combined_id.endpoint):
        issues.append("Invalid endpoint ID '%r'." % combined_id.endpoint)

    if "name" in endpoint:
        if not isinstance(endpoint["name"], StringTypes):
            issues.append("Expected 'name' to be a string; got %r." %
                          endpoint["name"])
        elif not VALID_LINUX_IFACE_NAME_RE.match(endpoint["name"]):
            issues.append("'name' must be a valid interface name.")

    if "mac" in endpoint:
        if not netaddr.valid_mac(endpoint["mac"]):
            issues.append("Invalid MAC address.")
        else:
            endpoint["mac"] = canonicalise_mac(endpoint.get("mac"))

    if "profile_id" in endpoint:
        if "profile_ids" not in endpoint:
            endpoint["profile_ids"] = [endpoint["profile_id"]]
        del endpoint["profile_id"]

    if "profile_ids" not in endpoint:
        endpoint["profile_ids"] = []
    else:
        for value in endpoint["profile_ids"]:
            if not isinstance(value, StringTypes):
                issues.append("Expected profile IDs to be strings.")
                break

            if not VALID_ID_RE.match(value):
                issues.append("Invalid profile ID '%r'." % value)

    if "labels" in endpoint:
        _validate_label_dict(issues, endpoint["labels"])

    for version in (4, 6):
        nets = "ipv%d_nets" % version
        if nets in endpoint:
            canonical_nws = []
            nets_list = endpoint.get(nets, [])
            if not isinstance(nets_list, list):
                issues.append("%s should be a list." % nets)
            else:
                for ip in nets_list:
                    if not validate_cidr(ip, version):
                        issues.append("IP address %r is not a valid "
                                      "IPv%d CIDR." % (ip, version))
                        break
                    else:
                        canonical_nws.append(canonicalise_cidr(ip, version))
                endpoint[nets] = canonical_nws

        n_key = nat_key(version)
        nat_maps = endpoint.get(n_key, None)
        if nat_maps is not None:
            if isinstance(nat_maps, list):
                canonical_nm = []
                for nat_map in nat_maps:
                    canonical = {}
                    for t in "int", "ext":
                        canonical[t] = None
                        ip = nat_map.get("%s_ip" % t, None)
                        if ip:
                            if validate_ip_addr(ip, version):
                                canonical[t] = canonicalise_ip(ip, version)
                            else:
                                issues.append("%s_ip (%r) is not a valid IPv%d"
                                              " address." % (t, ip, version))
                        else:
                            issues.append("%s_ip was not specified a %s entry."
                                          % (t, n_key))
                    if canonical["int"] and canonical["ext"]:
                        canonical_nm.append({"int_ip": canonical["int"],
                                             "ext_ip": canonical["ext"]})
                endpoint[n_key] = canonical_nm

                for nat_map in canonical_nm:
                    if version == 4:
                        nm = "/32"
                    else:
                        nm = "/128"
                    int_ip_nm = nat_map["int_ip"] + nm
                    # At this point these have all been canonicalized, so we
                    # should be able to do a strict string comparison.
                    if int_ip_nm not in endpoint.get(nets, []):
                        issues.append("int_ip %s is not listed in %s." %
                                      (int_ip_nm, nets))
            else:
                issues.append("%s should be a list." % n_key)

        gw_key = "ipv%d_gateway" % version
        try:
            gw_str = endpoint[gw_key]
            if gw_str is not None and not validate_ip_addr(gw_str,
                                                           version):
                issues.append("%s is not a valid IPv%d gateway address." %
                              (gw_key, version))
            else:
                endpoint[gw_key] = canonicalise_ip(gw_str, version)
        except KeyError:
            pass
    return issues
Пример #54
0
 def validate(self, value, context):
     self._error_message = 'Invalid MAC address.'
     return netaddr.valid_mac(value)
Пример #55
0
 def validate(value):
     if isinstance(value, six.string_types) and netaddr.valid_mac(value):
         return value
     raise ValueError(_("Expected MAC String, got '%s'") % value)