def validate_provider_segment(self, segment): network_type = segment[api.NETWORK_TYPE] driver = self.drivers.get(network_type) if driver: driver.obj.validate_provider_segment(segment) else: msg = _("network_type value '%s' not supported") % network_type raise exc.InvalidInput(error_message=msg)
def _process_net_type(self, network_type, physical_network, physical_network_set): if network_type in [ svc_constants.TYPE_VLAN, constants.TYPE_IB, svc_constants.TYPE_FLAT ]: if physical_network_set: if physical_network not in self.network_vlan_ranges: msg = _("Unknown provider:physical_network " "%s") % physical_network raise q_exc.InvalidInput(error_message=msg) elif 'default' in self.network_vlan_ranges: physical_network = 'default' else: msg = _("provider:physical_network required") raise q_exc.InvalidInput(error_message=msg) return physical_network
def convert_to_uuid_list_or_none(value_list): if value_list is None: return for sg_id in value_list: if not uuidutils.is_uuid_like(sg_id): msg = _("'%s' is not an integer or uuid") % sg_id raise nexception.InvalidInput(error_message=msg) return value_list
def _validate_ip_version(self, ip_version, addr, name): """Check IP field of a subnet match specified ip version.""" ip = netaddr.IPNetwork(addr) if ip.version != ip_version: data = {'name': name, 'addr': addr, 'ip_version': ip_version} msg = _("%(name)s '%(addr)s' does not match " "the ip_version '%(ip_version)s'") % data raise n_exc.InvalidInput(error_message=msg)
def is_partial_segment(self, segment): network_type = segment[api.NETWORK_TYPE] driver = self.drivers.get(network_type) if driver: return driver.obj.is_partial_segment(segment) else: msg = _("network_type value '%s' not supported") % network_type raise exc.InvalidInput(error_message=msg)
def allocate_mock(request): if type(request) == ipam_req.SpecificAddressRequest: if request.address == netaddr.IPAddress(fail_ip): raise n_exc.InvalidInput(error_message=error_message) else: return str(request.address) else: return auto_ip
def _process_nat_update(self, context, attrs, id): forward_ports = attrs.get(nat.FORWARD_PORTS) forward_ports_set = attributes.is_attr_set(forward_ports) if not forward_ports_set: return None # LOG.info("forward ports %s" % forward_ports) valid_protocols = ["tcp", "udp"] for entry in forward_ports: if not isinstance(entry, dict): msg = _( "nat:forward_ports: must specify a list of dicts (ex: 'l4_protocol=tcp,l4_port=80')" ) raise q_exc.InvalidInput(error_message=msg) if not ("l4_protocol" in entry and "l4_port" in entry): msg = _( "nat:forward_ports: dict is missing l4_protocol and l4_port (ex: 'l4_protocol=tcp,l4_port=80')" ) raise q_exc.InvalidInput(error_message=msg) if entry['l4_protocol'] not in valid_protocols: msg = _( "nat:forward_ports: invalid protocol (only tcp and udp allowed)" ) raise q_exc.InvalidInput(error_message=msg) l4_port = entry['l4_port'] if ":" in l4_port: try: (first, last) = l4_port.split(":") first = int(first) last = int(last) except: msg = _( "nat:forward_ports: l4_port range must be integer:integer" ) raise q_exc.InvalidInput(error_message=msg) else: try: l4_port = int(l4_port) except: msg = _("nat:forward_ports: l4_port must be an integer") raise q_exc.InvalidInput(error_message=msg) return forward_ports
def _raise_if_updates_provider_attributes(attrs): """Raise exception if provider attributes are present. This method is used for plugins that do not support updating provider networks. """ if any(attributes.is_attr_set(attrs.get(a)) for a in ATTRIBUTES): msg = _("Plugin does not support updating provider attributes") raise n_exc.InvalidInput(error_message=msg)
def _validate_bandwidth_or_none(data, valid_values=None): if data is not None: try: if attr.convert_to_int(data) < 0: raise nexception.InvalidInput() except nexception.InvalidInput: msg = _("'%s' is not a valid positive integer value for bandwidth" ) % data return msg
def _validate_segment_range(self, network_profile): """ Validate segment range values. :param network_profile: network profile object """ if not re.match(r"(\d+)\-(\d+)", network_profile["segment_range"]): msg = _("invalid segment range. example range: 500-550") raise q_exc.InvalidInput(error_message=msg)
def validate_provider_segment(self, segment): physical_network = segment.get(api.PHYSICAL_NETWORK) if not physical_network: msg = _("physical_network required for flat provider network") raise exc.InvalidInput(error_message=msg) if self.flat_networks is not None and not self.flat_networks: msg = _("Flat provider networks are disabled") raise exc.InvalidInput(error_message=msg) if self.flat_networks and physical_network not in self.flat_networks: msg = ( _("physical_network '%s' unknown for flat provider network") % physical_network) raise exc.InvalidInput(error_message=msg) for key, value in six.iteritems(segment): if value and key not in [api.NETWORK_TYPE, api.PHYSICAL_NETWORK]: msg = _("%s prohibited for flat provider network") % key raise exc.InvalidInput(error_message=msg)
def _validate_ipv6_update_dhcp(self, subnet, cur_subnet): if ('enable_dhcp' in subnet and not subnet['enable_dhcp']): msg = _("Cannot disable enable_dhcp with " "ipv6 attributes set") ra_mode_set = attributes.is_attr_set(subnet.get('ipv6_ra_mode')) address_mode_set = attributes.is_attr_set( subnet.get('ipv6_address_mode')) if ra_mode_set or address_mode_set: raise n_exc.InvalidInput(error_message=msg) old_ra_mode_set = attributes.is_attr_set( cur_subnet.get('ipv6_ra_mode')) old_address_mode_set = attributes.is_attr_set( cur_subnet.get('ipv6_address_mode')) if old_ra_mode_set or old_address_mode_set: raise n_exc.InvalidInput(error_message=msg)
def validate_filters(cls, **kwargs): bad_filters = [ key for key in kwargs if key not in cls.fields or key in cls.synthetic_fields ] if bad_filters: bad_filters = ', '.join(bad_filters) msg = _("'%s' is not supported for filtering") % bad_filters raise exceptions.InvalidInput(error_message=msg)
def _validate_availability_zone_hints(data, valid_value=None): # syntax check only here. existence of az will be checked later. msg = attr.validate_list_of_unique_strings(data) if msg: return msg az_string = convert_az_list_to_string(data) if len(az_string) > AZ_HINTS_DB_LEN: msg = _("Too many availability_zone_hints specified") raise exceptions.InvalidInput(error_message=msg)
def _process_port_binding(self, mech_context, attrs): binding = mech_context._binding port = mech_context.current self._update_port_dict_binding(port, binding) host = attrs and attrs.get(portbindings.HOST_ID) host_set = attributes.is_attr_set(host) vnic_type = attrs and attrs.get(portbindings.VNIC_TYPE) vnic_type_set = attributes.is_attr_set(vnic_type) # CLI can't send {}, so treat None as {} profile = attrs and attrs.get(portbindings.PROFILE) profile_set = profile is not attributes.ATTR_NOT_SPECIFIED if profile_set and not profile: profile = {} if binding.vif_type != portbindings.VIF_TYPE_UNBOUND: if (not host_set and not vnic_type_set and not profile_set and binding.segment and self.mechanism_manager.validate_port_binding( mech_context)): return False self.mechanism_manager.unbind_port(mech_context) self._update_port_dict_binding(port, binding) # Return True only if an agent notification is needed. # This will happen if a new host, vnic_type, or profile was specified # that differs from the current one. Note that host_set is True # even if the host is an empty string ret_value = ((host_set and binding.get('host') != host) or (vnic_type_set and binding.get('vnic_type') != vnic_type) or (profile_set and self._get_profile(binding) != profile)) if host_set: binding.host = host port[portbindings.HOST_ID] = host if vnic_type_set: binding.vnic_type = vnic_type port[portbindings.VNIC_TYPE] = vnic_type if profile_set: binding.profile = jsonutils.dumps(profile) if len(binding.profile) > models.BINDING_PROFILE_LEN: msg = _("binding:profile value too large") raise exc.InvalidInput(error_message=msg) port[portbindings.PROFILE] = profile # To try to [re]bind if host is non-empty. if binding.host: self.mechanism_manager.bind_port(mech_context) self._update_port_dict_binding(port, binding) return ret_value
def validate_provider_segment(self, segment): physical_network = segment.get(api.PHYSICAL_NETWORK) if physical_network: msg = _("provider:physical_network specified for %s " "network") % segment.get(api.NETWORK_TYPE) raise exc.InvalidInput(error_message=msg) segmentation_id = segment.get(api.SEGMENTATION_ID) if not segmentation_id: msg = _("segmentation_id required for %s provider " "network") % segment.get(api.NETWORK_TYPE) raise exc.InvalidInput(error_message=msg) for key, value in segment.items(): if value and key not in [api.NETWORK_TYPE, api.SEGMENTATION_ID]: msg = (_("%(key)s prohibited for %(tunnel)s provider network"), {'key': key, 'tunnel': segment.get(api.NETWORK_TYPE)}) raise exc.InvalidInput(error_message=msg)
def validate_remote_ip_prefix(ethertype, prefix): if prefix: net = netaddr.IPNetwork(prefix) if ((ethertype == ETHERTYPES["IPv4"] and net.version == 6) or (ethertype == ETHERTYPES["IPv6"] and net.version == 4)): human_ether = human_readable_ethertype(ethertype) raise exceptions.InvalidInput( error_message="Etherytype %s does not match " "remote_ip_prefix, which is IP version %s" % (human_ether, net.version))
def _validate_ipv6_combination(self, ra_mode, address_mode): if ra_mode != address_mode: msg = _( "ipv6_ra_mode set to '%(ra_mode)s' with ipv6_address_mode " "set to '%(addr_mode)s' is not valid. " "If both attributes are set, they must be the same value") % { 'ra_mode': ra_mode, 'addr_mode': address_mode } raise n_exc.InvalidInput(error_message=msg)
def _raise_if_updates_provider_attributes(attrs): """Raise exception if provider attributes are present. This method is used for plugins that do not support updating provider networks. """ immutable = (NETWORK_TYPE, PHYSICAL_NETWORK, SEGMENTATION_ID) if any(attributes.is_attr_set(attrs.get(a)) for a in immutable): msg = _("plugin does not support updating provider attributes") raise q_exc.InvalidInput(error_message=msg)
def convert_to_int_dec_and_hex(data): try: return int(data, 0) except (ValueError, TypeError): pass try: return int(data) except (ValueError, TypeError): msg = _("'%s' is not a integer") % data raise exceptions.InvalidInput(error_message=msg)
def is_valid_vlan_id(seg_id): msg = None try: int_seg_id = int(seg_id) except ValueError: msg = _("segmentation_id must be a valid integer") if int_seg_id < 0 or int_seg_id >= 4095: msg = _("Segmentation id is out of range") if msg: raise exceptions.InvalidInput(error_message=msg)
def _set_tenant_network_type(self): tenant_network_type = cfg.CONF.HYPERV.tenant_network_type if tenant_network_type not in [ svc_constants.TYPE_LOCAL, svc_constants.TYPE_FLAT, svc_constants.TYPE_VLAN, svc_constants.TYPE_NONE ]: msg = _("Invalid tenant_network_type: %s. " "Agent terminated!") % tenant_network_type raise n_exc.InvalidInput(error_message=msg) self._tenant_network_type = tenant_network_type
def get_ports(context, limit=None, sorts=None, marker=None, page_reverse=False, filters=None, fields=None): """Retrieve a list of ports. The contents of the list depends on the identity of the user making the request (as indicated by the context) as well as any filters. : param context: neutron api request context : param filters: a dictionary with keys that are valid keys for a port as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. Values in this dictionary are an iterable containing values that will be used for an exact match comparison for that value. Each result returned by this function will have matched one of the values for each key in filters. : param fields: a list of strings that are valid keys in a port dictionary as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. Only these fields will be returned. """ LOG.info("get_ports for tenant %s filters %s fields %s" % (context.tenant_id, filters, fields)) if filters is None: filters = {} if "ip_address" in filters: if not context.is_admin: raise exceptions.NotAuthorized() ips = [] try: ips = [netaddr.IPAddress(ip) for ip in filters.pop("ip_address")] except netaddr.AddrFormatError: raise exceptions.InvalidInput( error_message="Invalid format provided for ip_address") query = db_api.port_find_by_ip_address(context, ip_address=ips, scope=db_api.ALL, **filters) ports = [] for ip in query: ports.extend(ip.ports) else: ports = db_api.port_find(context, limit, sorts, marker, fields=fields, join_security_groups=True, **filters) return v._make_ports_list(ports, fields)
def validate_protocol_with_port_ranges(ethertype, protocol, port_range_min, port_range_max): if protocol in ALLOWED_WITH_RANGE: if protocol == PROTOCOL_MAP[ethertype]["icmp"]: if port_range_min is None and port_range_max is not None: raise sg_ext.SecurityGroupMissingIcmpType(value=port_range_max) elif port_range_min is not None: attr = None field = None value = None if port_range_min < 0 or port_range_min > 255: field = "port_range_min" attr = "type" value = port_range_min elif (port_range_max is not None and port_range_max < 0 or port_range_max > 255): field = "port_range_max" attr = "code" value = port_range_max if attr and field and value: raise sg_ext.SecurityGroupInvalidIcmpValue(field=field, attr=attr, value=value) else: if (port_range_min is None) != (port_range_max is None): # TODO(anyone): what exactly is a TCP or UDP rule withouts # ports? raise exceptions.InvalidInput( error_message="For TCP/UDP rules, port_range_min and" "port_range_max must either both be supplied" ", or neither of them") if port_range_min is not None and port_range_max is not None: if port_range_min > port_range_max: raise sg_ext.SecurityGroupInvalidPortRange() if port_range_min < MIN_PORT or port_range_max > MAX_PORT: raise exceptions.InvalidInput( error_message="port_range_min and port_range_max must " "be >= %s and <= %s" % (MIN_PORT, MAX_PORT))
def _validate_subnet_cidr(self, context, network, new_subnet_cidr): """Validate the CIDR for a subnet. Verifies the specified CIDR does not overlap with the ones defined for the other subnets specified for this network, or with any other CIDR if overlapping IPs are disabled. Does not apply to subnets with temporary IPv6 Prefix Delegation CIDRs (::/64). """ new_subnet_ipset = netaddr.IPSet([new_subnet_cidr]) # Disallow subnets with prefix length 0 as they will lead to # dnsmasq failures (see bug 1362651). # This is not a discrimination against /0 subnets. # A /0 subnet is conceptually possible but hardly a practical # scenario for neutron's use cases. for cidr in new_subnet_ipset.iter_cidrs(): if cidr.prefixlen == 0: err_msg = _("0 is not allowed as CIDR prefix length") raise n_exc.InvalidInput(error_message=err_msg) if cfg.CONF.allow_overlapping_ips: subnet_list = network.subnets else: subnet_list = self._get_all_subnets(context) for subnet in subnet_list: if ((netaddr.IPSet([subnet.cidr]) & new_subnet_ipset) and subnet.cidr != constants.PROVISIONAL_IPV6_PD_PREFIX): # don't give out details of the overlapping subnet err_msg = (_("Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s overlaps with another " "subnet") % { 'cidr': new_subnet_cidr, 'network_id': network.id }) LOG.info( _LI("Validation for CIDR: %(new_cidr)s failed - " "overlaps with subnet %(subnet_id)s " "(CIDR: %(cidr)s)"), { 'new_cidr': new_subnet_cidr, 'subnet_id': subnet.id, 'cidr': subnet.cidr }) raise n_exc.InvalidInput(error_message=err_msg)
def _validate_uniquerules(rules): pairs = [] for r in rules: if 'source' not in r or 'destination' not in r: continue pairs.append((r['source'], r['destination'])) if len(set(pairs)) != len(pairs): error = _("Duplicate router rules (src,dst) found '%s'") % pairs LOG.debug(error) raise nexception.InvalidInput(error_message=error)
def convert_to_unsigned_int_or_none(val): if val is None: return try: val = int(val) if val < 0: raise ValueError() except (ValueError, TypeError): msg = _("'%s' must be a non negative integer.") % val raise nexception.InvalidInput(error_message=msg) return val
def _validate_eui64_applicable(self, subnet): # Per RFC 4862, section 5.5.3, prefix length and interface # id together should be equal to 128. Currently neutron supports # EUI64 interface id only, thus limiting the prefix # length to be 64 only. if ipv6_utils.is_auto_address_subnet(subnet): if netaddr.IPNetwork(subnet['cidr']).prefixlen != 64: msg = _('Invalid CIDR %s for IPv6 address mode. ' 'OpenStack uses the EUI-64 address format, ' 'which requires the prefix to be /64.') raise n_exc.InvalidInput(error_message=(msg % subnet['cidr']))
def convert_kvp_str_to_list(data): """Convert a value of the form 'key=value' to ['key', 'value']. :raises: n_exc.InvalidInput if any of the strings are malformed (e.g. do not contain a key). """ kvp = [x.strip() for x in data.split('=', 1)] if len(kvp) == 2 and kvp[0]: return kvp msg = _("'%s' is not of the form <key>=[value]") % data raise n_exc.InvalidInput(error_message=msg)
def _parse_networks(self, entries): self.flat_networks = entries if '*' in self.flat_networks: LOG.info(_("Arbitrary flat physical_network names allowed")) self.flat_networks = None elif not all(self.flat_networks): msg = _("physical network name is empty") raise exc.InvalidInput(error_message=msg) else: LOG.info(_("Allowable flat physical_network names: %s"), self.flat_networks)