def test_type_prefixing(self): validators.add_validator('type:prefixed_type', dummy_validator) validators.add_validator('unprefixed_type', dummy_validator) self.assertEqual(dummy_validator, validators.get_validator('type:prefixed_type')) self.assertEqual(dummy_validator, validators.get_validator('prefixed_type')) self.assertEqual(dummy_validator, validators.get_validator('type:unprefixed_type')) self.assertEqual(dummy_validator, validators.get_validator('unprefixed_type'))
def __init__(self): # Dynamically change the validators so that they are applicable to # the MidoNet implementation of L2GW. # REVISIT(yamamoto): These validator modifications should not # have been here in the first place. We should either put them # in upstream or remove them. l2gw_validators.validate_gwdevice_list = ( l2gw_midonet_validators.validate_gwdevice_list) val_type = validators._to_validation_type('l2gwdevice_list') validators.validators.pop(val_type, None) validators.add_validator( val_type, l2gw_midonet_validators.validate_gwdevice_list) l2gw_validators.validate_network_mapping_list = ( l2gw_midonet_validators. validate_network_mapping_list_without_seg_id_validation) neutron_extensions.append_api_extensions_path(l2gateway_ext.__path__) super(MidonetL2GatewayPlugin, self).__init__()
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutron_lib.api import converters from neutron_lib.api.definitions import port from neutron_lib.api import validators from neutron_lib.api.validators import allowedaddresspairs as addr_validation from neutron_lib import constants validators.add_validator('allowed_address_pairs', addr_validation._validate_allowed_address_pairs) ADDRESS_PAIRS = 'allowed_address_pairs' ALIAS = 'allowed-address-pairs' IS_SHIM_EXTENSION = False IS_STANDARD_ATTR_EXTENSION = False NAME = 'Allowed Address Pairs' API_PREFIX = '' DESCRIPTION = 'Provides allowed address pairs' UPDATED_TIMESTAMP = '2013-07-23T10:00:00-00:00' RESOURCE_NAME = port.RESOURCE_NAME COLLECTION_NAME = port.COLLECTION_NAME RESOURCE_ATTRIBUTE_MAP = { COLLECTION_NAME: { ADDRESS_PAIRS: { 'allow_post': True,
class ServiceProfileDisabled(nexception.ServiceUnavailable): message = _("Service Profile is not enabled.") class InvalidFlavorServiceType(nexception.InvalidInput): message = _("Invalid service type %(service_type)s.") def _validate_flavor_service_type(validate_type, valid_values=None): """Ensure requested flavor service type plugin is loaded.""" if not directory.get_plugin(validate_type): raise InvalidFlavorServiceType(service_type=validate_type) validators.add_validator('validate_flavor_service_type', _validate_flavor_service_type) FLAVORS = 'flavors' SERVICE_PROFILES = 'service_profiles' FLAVORS_PREFIX = "" RESOURCE_ATTRIBUTE_MAP = { FLAVORS: { 'id': {'allow_post': False, 'allow_put': False, 'validate': {'type:uuid': None}, 'is_visible': True, 'primary_key': True}, 'name': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': attr.NAME_MAX_LEN}, 'is_visible': True, 'default': ''}, 'description': {'allow_post': True, 'allow_put': True,
def _get_request_dns_name(data): dns_domain = _get_dns_domain() if ((dns_domain and dns_domain != DNS_DOMAIN_DEFAULT)): return data return '' def convert_to_lowercase(data): if isinstance(data, six.string_types): return data.lower() msg = _("'%s' cannot be converted to lowercase string") % data raise n_exc.InvalidInput(error_message=msg) validators.add_validator('dns_name', _validate_dns_name) validators.add_validator('fip_dns_name', _validate_fip_dns_name) validators.add_validator('dns_domain', _validate_dns_domain) DNSNAME = 'dns_name' DNSDOMAIN = 'dns_domain' DNSASSIGNMENT = 'dns_assignment' EXTENDED_ATTRIBUTES_2_0 = { 'ports': { DNSNAME: {'allow_post': True, 'allow_put': True, 'default': '', 'convert_to': convert_to_lowercase, 'validate': {'type:dns_name': FQDN_MAX_LEN}, 'is_visible': True}, DNSASSIGNMENT: {'allow_post': False, 'allow_put': False, 'is_visible': True},
class ServiceProfileDisabled(nexception.ServiceUnavailable): message = _("Service Profile is not enabled.") class InvalidFlavorServiceType(nexception.InvalidInput): message = _("Invalid service type %(service_type)s.") def _validate_flavor_service_type(validate_type, valid_values=None): """Ensure requested flavor service type plugin is loaded.""" plugins = manager.NeutronManager.get_service_plugins() if validate_type not in plugins: raise InvalidFlavorServiceType(service_type=validate_type) validators.add_validator('validate_flavor_service_type', _validate_flavor_service_type) FLAVORS = 'flavors' SERVICE_PROFILES = 'service_profiles' FLAVORS_PREFIX = "" RESOURCE_ATTRIBUTE_MAP = { FLAVORS: { 'id': {'allow_post': False, 'allow_put': False, 'validate': {'type:uuid': None}, 'is_visible': True, 'primary_key': True}, 'name': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': attr.NAME_MAX_LEN}, 'is_visible': True, 'default': ''}, 'description': {'allow_post': True, 'allow_put': True,
def convert_az_string_to_list(az_string): return jsonutils.loads(az_string) if az_string else [] def _validate_availability_zone_hints(data, valid_value=None): # syntax check only here. existence of az will be checked later. msg = validators.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) validators.add_validator('availability_zone_hints', _validate_availability_zone_hints) # Attribute Map RESOURCE_NAME = 'availability_zone' AVAILABILITY_ZONES = 'availability_zones' AZ_HINTS = 'availability_zone_hints' # name: name of availability zone (string) # resource: type of resource: 'network' or 'router' # state: state of availability zone: 'available' or 'unavailable' # It means whether users can use the availability zone. RESOURCE_ATTRIBUTE_MAP = { AVAILABILITY_ZONES: { 'name': { 'is_visible': True }, 'resource': {
message = _("Unable to complete operation for Gateway Device. " "The tunnel ips are required for %(gw_type)s type.") class OperationRemoteMacEntryNotSupported(nexception.Conflict): message = _("Unable to operate remote_mac_entry for gateway device " "%(type)s type.") def _validate_port_or_none(data, valid_values=None): if data is None: return None return validators.validate_range(data, [0, 65535]) validators.add_validator('_midonet_port_or_none', _validate_port_or_none) GATEWAY_DEVICE = 'gateway_device' GATEWAY_DEVICES = '%ss' % GATEWAY_DEVICE HW_VTEP_TYPE = 'hw_vtep' ROUTER_DEVICE_TYPE = 'router_vtep' NETWORK_VLAN_TYPE = 'network_vlan' gateway_device_valid_types = [ HW_VTEP_TYPE, ROUTER_DEVICE_TYPE, NETWORK_VLAN_TYPE ] OVSDB = 'ovsdb' gateway_device_valid_protocols = [OVSDB] GATEWAY_DEVICE_PREFIX = '/gw'
from neutron import wsgi LOG = logging.getLogger(__name__) def _validate_ip_mcast_address(data, valid_values=None): """ Validates that an IP address is a multicast address. """ if not netaddr.IPAddress(data).is_multicast(): msg = _("'%s' is not a valid multicast IP address") % data LOG.debug(msg) return msg validators.add_validator('type:ip_mcast_address', _validate_ip_mcast_address) # wrs-provider:network_type # wrs-provider:physical_network # wrs-provider:segmentation_id NETWORK_TYPE = '%sprovider:network_type' % n_const.WRS_FIELD_PREFIX PHYSICAL_NETWORK = '%sprovider:physical_network' % n_const.WRS_FIELD_PREFIX SEGMENTATION_ID = '%sprovider:segmentation_id' % n_const.WRS_FIELD_PREFIX ATTRIBUTES = [NETWORK_TYPE, PHYSICAL_NETWORK, SEGMENTATION_ID] # wrs-provider:mtu MTU = '%sprovider:mtu' % n_const.WRS_FIELD_PREFIX EXTENDED_ATTRIBUTES_2_0 = { 'subnets': { NETWORK_TYPE: { 'allow_post': False,
def convert_az_string_to_list(az_string): return jsonutils.loads(az_string) if az_string else [] def _validate_availability_zone_hints(data, valid_value=None): # syntax check only here. existence of az will be checked later. msg = validators.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) validators.add_validator('availability_zone_hints', _validate_availability_zone_hints) # Attribute Map RESOURCE_NAME = 'availability_zone' AVAILABILITY_ZONES = 'availability_zones' AZ_HINTS = 'availability_zone_hints' # name: name of availability zone (string) # resource: type of resource: 'network' or 'router' # state: state of availability zone: 'available' or 'unavailable' # It means whether users can use the availability zone. RESOURCE_ATTRIBUTE_MAP = { AVAILABILITY_ZONES: { 'name': {'is_visible': True}, 'resource': {'is_visible': True}, 'state': {'is_visible': True} }
"%(reason)s") % {'data': data, 'reason': str(e)} return msg def _validate_dns_search_domain(data, max_len=db_const.NAME_FIELD_SIZE): msg = validators.validate_string(data, max_len) if msg: return msg if not data: return msg = _validate_dns_format(data) if msg: return msg validators.add_validator('dns_search_domain', _validate_dns_search_domain) ALIAS = 'dns-search-domain' DNS_SEARCH_DOMAIN = 'dns_search_domain' EXTENDED_ATTRIBUTES_2_0 = { 'subnets': { DNS_SEARCH_DOMAIN: { 'allow_post': True, 'allow_put': True, 'default': constants.ATTR_NOT_SPECIFIED, 'validate': {'type:dns_search_domain': db_const.NAME_FIELD_SIZE}, 'is_visible': True}, } }
]) if data not in connector_types: msg = _("Unknown connector type: %s") % data return msg nw_gw_quota_opts = [ cfg.IntOpt('quota_network_gateway', default=5, help=_('Number of network gateways allowed per tenant, ' '-1 for unlimited')) ] cfg.CONF.register_opts(nw_gw_quota_opts, 'QUOTAS') validators.add_validator('device_list', _validate_device_list) validators.add_validator('connector_type', _validate_connector_type) class Networkgw(extensions.ExtensionDescriptor): """API extension for Layer-2 Gateway support. The Layer-2 gateway feature allows for connecting neutron networks with external networks at the layer-2 level. No assumption is made on the location of the external network, which might not even be directly reachable from the hosts where the VMs are deployed. This is achieved by instantiating 'network gateways', and then connecting Neutron network to them. """ @classmethod
LOG.debug(msg) return msg def validate_ipv4_address_or_none(data, valid_values=None): if data is None: return None msg_ip = validators.validate_ip_address(data, valid_values) if not msg_ip: if netaddr.valid_ipv4(data): return None msg_ip = _("'%s' is not an IPv4 address") % data return msg_ip validators.add_validator('ipv4_address_or_none', validate_ipv4_address_or_none) # Attribute Map RESOURCE_ATTRIBUTE_MAP = { 'portforwardings': { 'id': { 'allow_post': False, 'allow_put': False, 'validate': { 'type:uuid': None }, 'is_visible': True, 'primary_key': True }, 'tenant_id': { 'allow_post': True,
def _convert_and_validate_addresses(addresses, valid_values=None): for address in addresses: ip_address = address.get('ip_address') msg = validate_ip_or_subnet_or_ip_pools_or_none(ip_address) if msg is not None: raise webob.exc.HTTPBadRequest(msg) if '-' in ip_address: ip_address = split('-', ip_address, maxsplit=1)[0] ip = IPAddress(ip_address) if ip.version != address.get('ip_version'): raise webob.exc.HTTPBadRequest('Bad IP version') validators.add_validator('convert_ip_addresses', _convert_and_validate_addresses) class Firewall_v2(extensions.APIExtensionDescriptor): api_definition = firewall_v2 @classmethod def get_resources(cls): special_mappings = {'firewall_policies': 'firewall_policy'} plural_mappings = resource_helper.build_plural_mappings( special_mappings, firewall_v2.RESOURCE_ATTRIBUTE_MAP) return resource_helper.build_resource_info( plural_mappings, firewall_v2.RESOURCE_ATTRIBUTE_MAP, fwaas_constants.FIREWALL_V2, action_map=firewall_v2.ACTION_MAP,
try: cidr = netaddr.IPNetwork(ip_prefix) return str(cidr) except (ValueError, TypeError, netaddr.AddrFormatError): raise exceptions.InvalidCIDR(input=ip_prefix) def _validate_name_not_default(data, max_len=db_const.NAME_FIELD_SIZE): msg = validators.validate_string(data, max_len) if msg: return msg if data.lower() == "default": raise SecurityGroupDefaultAlreadyExists() validators.add_validator('name_not_default', _validate_name_not_default) sg_supported_protocols = ([None] + list(const.IP_PROTOCOL_MAP.keys())) sg_supported_ethertypes = ['IPv4', 'IPv6'] SECURITYGROUPS = 'security_groups' SECURITYGROUPRULES = 'security_group_rules' # Attribute Map RESOURCE_ATTRIBUTE_MAP = { SECURITYGROUPS: { 'id': {'allow_post': False, 'allow_put': False, 'validate': {'type:uuid': None}, 'is_visible': True, 'is_filter': True, 'primary_key': True}, 'name': {'allow_post': True, 'allow_put': True,
class MissingRequiredEndpointGroup(nexception.BadRequest): message = _("Missing endpoint group%(suffix)s %(which)s for IPSec " "site-to-site connection") class EndpointGroupInUse(nexception.BadRequest): message = _("Endpoint group %(group_id)s is in use and cannot be deleted") def _validate_subnet_list_or_none(data, key_specs=None): if data is not None: return validators.validate_subnet_list(data, key_specs) validators.add_validator('type:subnet_list_or_none', _validate_subnet_list_or_none) vpn_supported_initiators = ['bi-directional', 'response-only'] vpn_supported_encryption_algorithms = ['3des', 'aes-128', 'aes-192', 'aes-256'] vpn_dpd_supported_actions = [ 'hold', 'clear', 'restart', 'restart-by-peer', 'disabled' ] vpn_supported_transform_protocols = ['esp', 'ah', 'ah-esp'] vpn_supported_encapsulation_mode = ['tunnel', 'transport'] #TODO(nati) add kilobytes when we support it vpn_supported_lifetime_units = ['seconds'] vpn_supported_pfs = ['group2', 'group5', 'group14'] vpn_supported_ike_versions = ['v1', 'v2'] vpn_supported_auth_mode = ['psk'] vpn_supported_auth_algorithms = ['sha1', 'sha256', 'sha384', 'sha512']
class MissingRequiredEndpointGroup(nexception.BadRequest): message = _("Missing endpoint group%(suffix)s %(which)s for IPSec " "site-to-site connection") class EndpointGroupInUse(nexception.BadRequest): message = _("Endpoint group %(group_id)s is in use and cannot be deleted") def _validate_subnet_list_or_none(data, key_specs=None): if data is not None: return validators.validate_subnet_list(data, key_specs) validators.add_validator('type:subnet_list_or_none', _validate_subnet_list_or_none) vpn_supported_initiators = ['bi-directional', 'response-only'] vpn_supported_encryption_algorithms = ['3des', 'aes-128', 'aes-192', 'aes-256'] vpn_dpd_supported_actions = [ 'hold', 'clear', 'restart', 'restart-by-peer', 'disabled' ] vpn_supported_transform_protocols = ['esp', 'ah', 'ah-esp'] vpn_supported_encapsulation_mode = ['tunnel', 'transport'] #TODO(nati) add kilobytes when we support it vpn_supported_lifetime_units = ['seconds'] vpn_supported_pfs = ['group2', 'group5', 'group14'] vpn_supported_ike_versions = ['v1', 'v2'] vpn_supported_auth_mode = ['psk'] vpn_supported_auth_algorithms = ['sha1', 'sha256', 'sha384', 'sha512'] vpn_supported_phase1_negotiation_mode = ['main']
"%(reason)s") % {'data': data, 'reason': str(e)} return msg def _validate_dns_search_domain(data, max_len=attributes.NAME_MAX_LEN): msg = validators.validate_string(data, max_len) if msg: return msg if not data: return msg = _validate_dns_format(data) if msg: return msg validators.add_validator('dns_search_domain', _validate_dns_search_domain) DNS_SEARCH_DOMAIN = 'dns_search_domain' EXTENDED_ATTRIBUTES_2_0 = { 'subnets': { DNS_SEARCH_DOMAIN: { 'allow_post': True, 'allow_put': True, 'default': constants.ATTR_NOT_SPECIFIED, 'validate': {'type:dns_search_domain': attributes.NAME_MAX_LEN}, 'is_visible': True}, } } class Dns_search_domain(extensions.ExtensionDescriptor):
if service_types: if not isinstance(service_types, list): raise webob.exc.HTTPBadRequest( _("Subnet service types must be a list.")) prefixes = valid_prefixes # Include standard prefixes prefixes += list(constants.DEVICE_OWNER_PREFIXES) prefixes += constants.DEVICE_OWNER_COMPUTE_PREFIX for service_type in service_types: if not service_type.startswith(tuple(prefixes)): raise InvalidSubnetServiceType(service_type=service_type) validators.add_validator('type:validate_subnet_service_types', _validate_subnet_service_types) EXTENDED_ATTRIBUTES_2_0 = { attributes.SUBNETS: { 'service_types': {'allow_post': True, 'allow_put': True, 'default': constants.ATTR_NOT_SPECIFIED, 'validate': {'type:validate_subnet_service_types': None}, 'is_visible': True, }, }, } class Subnet_service_types(extensions.ExtensionDescriptor):
def is_valid_rate_limit(rate_limit): if (not rate_limit.is_integer() or rate_limit < -1 or rate_limit > constants.MAX_VSD_INTEGER): return False return True def egress_limit_validation_kbps(data, valid_values=None): fip_rate_limit_validator(data, "nuage_egress_fip_rate_kbps") def ingress_limit_validation_kbps(data, valid_values=None): fip_rate_limit_validator(data, "nuage_ingress_fip_rate_kbps") lib_validators.add_validator('type:egress_rate_valid_kbps', egress_limit_validation_kbps) lib_validators.add_validator('type:ingress_rate_valid_kbps', ingress_limit_validation_kbps) EXTENDED_ATTRIBUTES_2_0 = { 'floatingips': { 'nuage_ingress_fip_rate_kbps': { 'allow_post': True, 'allow_put': True, 'is_visible': True, 'default': None, 'validate': { 'type:ingress_rate_valid_kbps': None }, 'convert_to': convert_ingress_default_to_default_value, 'enforce_policy': True
try: net = netaddr.IPNetwork(lib_validators.validate_no_whitespace(data)) if '/' not in data or (net.network != net.ip): msg = _("'%(data)s' isn't a recognized IP subnet cidr," " '%(cidr)s' is recommended") % { "data": data, "cidr": net.cidr } else: return except Exception: msg = _("'%s' is not a valid IP subnet") % data return msg # TODO(alegacy): Supersede the neutron-lib version because it does not # properly validate subnets that have non-zero values in the host portion of # the address. Move to neutron_lib when we eventually can no longer avoid # patching that package. def validate_hostroutes2(data, valid_values=None): msg = lib_validators.validate_hostroutes(data, valid_values=valid_values) if not msg: for hostroute in data: msg = _validate_subnet2(hostroute['destination']) if msg: break return msg lib_validators.add_validator('type:hostroutes2', validate_hostroutes2)
'validate': {'type:string': None}, 'is_visible': True, 'default': ''}, 'management_procotol': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': None}, 'is_visible': True}, 'credentials': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': None}, 'is_visible': True}, 'vendor': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': None}, 'is_visible': True} }, } validator_func = validators.access_parameter_validator nl_validators.add_validator('type:access_dict', validator_func) class BNPSwitchController(wsgi.Controller): """WSGI Controller for the extension bnp-switch.""" def __init__(self): self.protocol_manager = managers.ProvisioningManager() def _check_admin(self, context): reason = _("Only admin can configure Bnp-switch") if not context.is_admin: raise webob.exc.HTTPForbidden(reason) def index(self, request, **kwargs):
from neutron_lib import constants as lib_constants from neutron_lib.plugins import directory from nuage_neutron.plugins.common import constants as nuage_constants LOG = logging.getLogger(__name__) def validate_port_policy_groups(nuage_policy_groups, valid_values=None): if not isinstance(nuage_policy_groups, list): msg = _("'%s' is not a list") % nuage_policy_groups LOG.debug(msg) return msg lib_validators.add_validator('type:validate_port_policy_groups', validate_port_policy_groups) NUAGE_POLICY_GROUPS = 'nuage_policy_groups' RESOURCE_ATTRIBUTE_MAP = { NUAGE_POLICY_GROUPS: { 'id': { 'allow_post': False, 'allow_put': False, 'validate': { 'type:uuid': None }, 'is_visible': True, 'primary_key': True }, 'name': { 'allow_post': False,
invalid_attrs = set(address_pair.keys()) - set(['mac_address', 'ip_address']) if invalid_attrs: msg = (_("Unrecognized attribute(s) '%s'") % ', '.join(set(address_pair.keys()) - set(['mac_address', 'ip_address']))) raise webob.exc.HTTPBadRequest(msg) if '/' in ip_address: msg = validators.validate_subnet(ip_address) else: msg = validators.validate_ip_address(ip_address) if msg: raise webob.exc.HTTPBadRequest(msg) validators.add_validator('validate_allowed_address_pairs', _validate_allowed_address_pairs) ADDRESS_PAIRS = 'allowed_address_pairs' EXTENDED_ATTRIBUTES_2_0 = { 'ports': { ADDRESS_PAIRS: {'allow_post': True, 'allow_put': True, 'convert_to': converters.convert_none_to_empty_list, 'convert_list_to': converters.convert_kvp_list_to_dict, 'validate': {'type:validate_allowed_address_pairs': None}, 'enforce_policy': True, 'default': constants.ATTR_NOT_SPECIFIED, 'is_visible': True}, } }
invalid_attrs = set(address_pair.keys()) - set( ['mac_address', 'ip_address']) if invalid_attrs: msg = (_("Unrecognized attribute(s) '%s'") % ', '.join( set(address_pair.keys()) - set(['mac_address', 'ip_address']))) raise webob.exc.HTTPBadRequest(msg) if '/' in ip_address: msg = validators.validate_subnet(ip_address) else: msg = validators.validate_ip_address(ip_address) if msg: raise webob.exc.HTTPBadRequest(msg) validators.add_validator('validate_allowed_address_pairs', _validate_allowed_address_pairs) ADDRESS_PAIRS = 'allowed_address_pairs' EXTENDED_ATTRIBUTES_2_0 = { 'ports': { ADDRESS_PAIRS: { 'allow_post': True, 'allow_put': True, 'convert_to': converters.convert_none_to_empty_list, 'convert_list_to': converters.convert_kvp_list_to_dict, 'validate': { 'type:validate_allowed_address_pairs': None }, 'enforce_policy': True, 'default': constants.ATTR_NOT_SPECIFIED, 'is_visible': True
def test_adding_validator(self): validators.add_validator('new_type', dummy_validator) self.assertIn('type:new_type', validators.validators) self.assertEqual(dummy_validator, validators.validators['type:new_type'])
"""Helper function checking duplicate segments. If is_partial_funcs is specified and not None, then SegmentsContainDuplicateEntry is raised if two segments are identical and non partially defined (is_partial_func(segment) == False). Otherwise SegmentsContainDuplicateEntry is raised if two segment are identical. """ if is_partial_func is not None: segments = [s for s in segments if not is_partial_func(s)] fully_specifieds = [tuple(sorted(s.items())) for s in segments] if len(set(fully_specifieds)) != len(fully_specifieds): raise SegmentsContainDuplicateEntry() validators.add_validator('convert_segments', _convert_and_validate_segments) EXTENDED_ATTRIBUTES_2_0 = { 'networks': { SEGMENTS: { 'allow_post': True, 'allow_put': True, 'validate': { 'type:convert_segments': None }, 'convert_list_to': converters.convert_kvp_list_to_dict, 'default': constants.ATTR_NOT_SPECIFIED, 'enforce_policy': True, 'is_visible': True }, }
return msg def convert_none_to_empty_list(value): return [] if value is None else value try: from neutron.api.v2.attributes import ATTR_NOT_SPECIFIED except: from neutron_lib.constants import ATTR_NOT_SPECIFIED from neutron.api.v2 import attributes as attrs if hasattr(attrs, 'validators'): attrs.validators['type:customattributes'] = _validate_custom_attributes else: from neutron_lib.api import validators validators.add_validator('type:customattributes', _validate_custom_attributes) # Extended_Attribute MAP EXTENDED_ATTRIBUTES_2_0 = { 'pools': { 'custom_attributes': {'allow_post': True, 'allow_put': True, 'convert_to': convert_none_to_empty_list, 'default': ATTR_NOT_SPECIFIED, 'validate': {'type:customattributes': None}, 'is_visible': True}, } } class Loadbalancercustomattributes(ExtensionDescriptor):
try: data = int(data) except (ValueError, TypeError): return _ecmp_count_info() if data < 1 or data > 8: return _ecmp_count_info() def convert_to_uppercase(data): if data: return str(data).upper() validators.add_validator('type:ecmp_count', ecmp_count_validation) EXTENDED_ATTRIBUTES_2_0 = { 'routers': { 'net_partition': { 'allow_post': True, 'allow_put': True, 'is_visible': True, 'default': None, 'validate': { 'type:string_or_none': None } }, 'rd': { 'allow_post': True, 'allow_put': True,
'ipsec%s' % NetworkTypes.STT]) if data not in connector_types: msg = _("Unknown connector type: %s") % data return msg nw_gw_quota_opts = [ cfg.IntOpt('quota_network_gateway', default=5, help=_('Number of network gateways allowed per tenant, ' '-1 for unlimited')) ] cfg.CONF.register_opts(nw_gw_quota_opts, 'QUOTAS') validators.add_validator('device_list', _validate_device_list) validators.add_validator('connector_type', _validate_connector_type) class Networkgw(extensions.ExtensionDescriptor): """API extension for Layer-2 Gateway support. The Layer-2 gateway feature allows for connecting neutron networks with external networks at the layer-2 level. No assumption is made on the location of the external network, which might not even be directly reachable from the hosts where the VMs are deployed. This is achieved by instantiating 'network gateways', and then connecting Neutron network to them. """
def test_success_adding_duplicate_validator(self): validators.add_validator('dummy', dummy_validator) validators.add_validator('dummy', dummy_validator) self.assertEqual(dummy_validator, validators.get_validator('dummy'))
return None try: value = value.lower() assert value in [ constants.NUAGE_UNDERLAY_OFF, constants.NUAGE_UNDERLAY_ROUTE, constants.NUAGE_UNDERLAY_SNAT ] except Exception: msg = "Possible values for {} are: {}, {}, {}.".format( constants.NUAGE_UNDERLAY, constants.NUAGE_UNDERLAY_OFF, constants.NUAGE_UNDERLAY_ROUTE, constants.NUAGE_UNDERLAY_SNAT) raise nuage_exc.NuageBadRequest(msg=msg) return value validators.add_validator('type:ecmp_count', ecmp_count_validation) validators.add_validator('type:boolean_or_none', boolean_or_none_validation) EXTENDED_ATTRIBUTES_2_0 = { 'routers': { 'net_partition': { 'allow_post': True, 'allow_put': True, 'is_visible': True, 'default': None, 'validate': { 'type:string_or_none': None }, 'enforce_policy': True }, 'rd': {
def _validate_extra_dhcp_opt(data, key_specs=None): if data is not None: if not isinstance(data, list): raise ExtraDhcpOptBadData(data=data) for d in data: if d['opt_name'] in VALID_BLANK_EXTRA_DHCP_OPTS: msg = validators.validate_string_or_none( d['opt_value'], DHCP_OPT_VALUE_MAX_LEN) else: msg = validators.validate_dict(d, key_specs) if msg: raise ExtraDhcpOptBadData(data=msg) validators.add_validator('list_of_extra_dhcp_opts', _validate_extra_dhcp_opt) # Attribute Map EXTRADHCPOPTS = 'extra_dhcp_opts' CLIENT_ID = "client-id" EXTENDED_ATTRIBUTES_2_0 = { 'ports': { EXTRADHCPOPTS: { 'allow_post': True, 'allow_put': True, 'is_visible': True, 'default': None, 'validate': { 'type:list_of_extra_dhcp_opts': EXTRA_DHCP_OPT_KEY_SPECS
# A prefix for API resources. An empty prefix means that the API is going # to be exposed at the v2/ level as any other core resource (mandatory). API_PREFIX = '' # The description of the extension (mandatory). DESCRIPTION = "Provides integration with DNS." # A timestamp of when the extension was introduced (mandatory). UPDATED_TIMESTAMP = "2015-08-15T18:00:00-00:00" DNSNAME = 'dns_name' DNSDOMAIN = 'dns_domain' DNSASSIGNMENT = 'dns_assignment' validators.add_validator('dns_host_name', dns_validator.validate_dns_name) validators.add_validator('fip_dns_host_name', dns_validator.validate_fip_dns_name) validators.add_validator('dns_domain_name', dns_validator.validate_dns_domain) # The resource attribute map for the extension. It is effectively the # bulk of the API contract alongside ACTION_MAP (mandatory). RESOURCE_ATTRIBUTE_MAP = { port.COLLECTION_NAME: { DNSNAME: { 'allow_post': True, 'allow_put': True, 'default': '', 'convert_to': convert.convert_string_to_case_insensitive, 'validate': { 'type:dns_host_name': constants.FQDN_FIELD_SIZE
'id': {'allow_post': False, 'allow_put': False, 'is_visible': True}, 'name': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': None}, 'is_visible': True, 'default': ''}, 'devices': {'allow_post': True, 'allow_put': True, 'validate': {'type:l2gwdevice_list': None}, 'is_visible': True}, 'tenant_id': {'allow_post': True, 'allow_put': False, 'validate': {'type:string': None}, 'required_by_policy': True, 'is_visible': True} }, } validators.add_validator('l2gwdevice_list', l2gw_validators.validate_gwdevice_list) class L2gateway(api_extensions.ExtensionDescriptor): """API extension for Layer-2 Gateway support.""" @classmethod def get_name(cls): return "L2 Gateway" @classmethod def get_alias(cls): return "l2-gateway" @classmethod
def check_duplicate_segments(segments, is_partial_func=None): """Helper function checking duplicate segments. If is_partial_funcs is specified and not None, then SegmentsContainDuplicateEntry is raised if two segments are identical and non partially defined (is_partial_func(segment) == False). Otherwise SegmentsContainDuplicateEntry is raised if two segment are identical. """ if is_partial_func is not None: segments = [s for s in segments if not is_partial_func(s)] fully_specifieds = [tuple(sorted(s.items())) for s in segments] if len(set(fully_specifieds)) != len(fully_specifieds): raise SegmentsContainDuplicateEntry() validators.add_validator('convert_segments', _convert_and_validate_segments) EXTENDED_ATTRIBUTES_2_0 = { 'networks': { SEGMENTS: {'allow_post': True, 'allow_put': True, 'validate': {'type:convert_segments': None}, 'convert_list_to': converters.convert_kvp_list_to_dict, 'default': constants.ATTR_NOT_SPECIFIED, 'enforce_policy': True, 'is_visible': True}, } } class Multiprovidernet(extensions.ExtensionDescriptor): """Extension class supporting multiple provider networks.
RESOURCE_ATTRIBUTE_MAP = { 'ovsvapp_clusters': { 'tenant_id': {'allow_post': True, 'allow_put': False, 'validate': {'type:string': None}, 'required_by_policy': True, 'is_visible': False}, 'vcenter_id': {'allow_post': True, 'allow_put': True, 'is_visible': True, 'default': ''}, 'clusters': {'allow_post': True, 'allow_put': True, 'convert_to': convert_none_to_empty_list, 'validate': {'type:clusters_list': None}, 'default': None, 'is_visible': True}, } } validators.add_validator('type:clusters_list', validate_clusters_list) class Ovsvapp_cluster(api_extensions.ExtensionDescriptor): """Extension class supporting OVSvApp-Cluster-Mappings.""" @classmethod def get_name(cls): return "ovsvapp-cluster" @classmethod def get_alias(cls): return "ovsvapp-cluster" @classmethod def get_description(cls):
try: cidr = netaddr.IPNetwork(ip_prefix) return str(cidr) except (ValueError, TypeError, netaddr.AddrFormatError): raise exceptions.InvalidCIDR(input=ip_prefix) def _validate_name_not_default(data, max_len=db_const.NAME_FIELD_SIZE): msg = validators.validate_string(data, max_len) if msg: return msg if data.lower() == "default": raise SecurityGroupDefaultAlreadyExists() validators.add_validator('name_not_default', _validate_name_not_default) sg_supported_protocols = ([None] + list(const.IP_PROTOCOL_MAP.keys())) sg_supported_ethertypes = ['IPv4', 'IPv6'] SECURITYGROUPS = 'security_groups' SECURITYGROUPRULES = 'security_group_rules' # Attribute Map RESOURCE_ATTRIBUTE_MAP = { SECURITYGROUPS: { 'id': { 'allow_post': False, 'allow_put': False, 'validate': { 'type:uuid': None },
def convert_none_to_empty_list(value): return [] if value is None else value try: from neutron.api.v2.attributes import ATTR_NOT_SPECIFIED except Exception: from neutron_lib.constants import ATTR_NOT_SPECIFIED try: from neutron.api.v2 import attributes as attrs if hasattr(attrs, 'validators'): attrs.validators['type:customattributes'] = _validate_custom_attributes else: from neutron_lib.api import validators validators.add_validator('type:customattributes', _validate_custom_attributes) except ImportError: from neutron_lib.api import validators validators.add_validator('type:customattributes', _validate_custom_attributes) # Extended_Attribute MAP EXTENDED_ATTRIBUTES_2_0 = { 'pools': { 'custom_attributes': { 'allow_post': True, 'allow_put': True, 'convert_to': convert_none_to_empty_list, 'default': ATTR_NOT_SPECIFIED, 'validate': { 'type:customattributes': None
EDGE_SERVICE_GW = 'esg_id' EDGE_ID_MAX_LEN = 15 ESG_BGP_PEER_EXT_ALIAS = 'edge-service-gateway-bgp-peer' def _validate_edge_service_gw_id(esg_id, valid_values=None): msg = validators.validate_string(esg_id, max_len=EDGE_ID_MAX_LEN) if msg: return msg if esg_id and re.match(r'^edge-[1-9]+[0-9]*$', esg_id) is None: msg = _("'%s' is not a valid edge service gateway id.") % esg_id return msg validators.add_validator('validate_edge_service_gw_id', _validate_edge_service_gw_id) RESOURCE_ATTRIBUTE_MAP = { 'bgp-peers': { EDGE_SERVICE_GW: { 'allow_post': True, 'allow_put': False, 'default': None, 'validate': { 'type:validate_edge_service_gw_id': None }, 'enforce_policy': True, 'is_visible': True, 'required_by_policy': False } }
EDGE_ID_MAX_LEN = 15 ALIAS = 'edge-service-gateway-bgp-peer' def _validate_edge_service_gw_id(esg_id, valid_values=None): if esg_id is None: return msg = validators.validate_string(esg_id, max_len=EDGE_ID_MAX_LEN) if msg: return msg if re.match(r'^edge-[1-9]+[0-9]*$', esg_id) is None: msg = _("'%s' is not a valid edge service gateway id.") % esg_id return msg validators.add_validator('validate_edge_service_gw_id', _validate_edge_service_gw_id) RESOURCE_ATTRIBUTE_MAP = { 'bgp-peers': { EDGE_SERVICE_GW: { 'allow_post': True, 'allow_put': False, 'default': None, 'validate': {'type:validate_edge_service_gw_id': None}, 'enforce_policy': True, 'is_visible': True, 'required_by_policy': False } } }