def validate_metering_label_rule(metering_label_rule): MeteringPlugin.validate_metering_rule_ip_address( metering_label_rule, "remote_ip_prefix") MeteringPlugin.validate_metering_rule_ip_address( metering_label_rule, "source_ip_prefix") MeteringPlugin.validate_metering_rule_ip_address( metering_label_rule, "destination_ip_prefix") if metering_label_rule.get("remote_ip_prefix"): if metering_label_rule.get("source_ip_prefix") or \ metering_label_rule.get("destination_ip_prefix"): raise neutron_exc.Invalid( "Cannot use 'remote-ip-prefix' in conjunction " "with 'source-ip-prefix' or 'destination-ip-prefix'.") none_ip_prefix_informed = not metering_label_rule.get( 'remote_ip_prefix') and not metering_label_rule.get( 'source_ip_prefix') and not metering_label_rule.get( 'destination_ip_prefix') if none_ip_prefix_informed: raise neutron_exc.Invalid( "You must define at least one of the following parameters " "'remote_ip_prefix', or 'source_ip_prefix' or " "'destination_ip_prefix'.")
def _port_action(self, plugin, context, port, action): """Perform port operations taking care of concurrency issues.""" try: if action == 'create_port': return p_utils.create_port(plugin, context, port) elif action == 'update_port': return plugin.update_port(context, port['id'], port) else: msg = _('Unrecognized action') raise exceptions.Invalid(message=msg) except (db_exc.DBError, exceptions.NetworkNotFound, exceptions.SubnetNotFound, exceptions.IpAddressGenerationFailure) as e: with excutils.save_and_reraise_exception(reraise=False) as ctxt: if isinstance(e, exceptions.IpAddressGenerationFailure): # Check if the subnet still exists and if it does not, # this is the reason why the ip address generation failed. # In any other unlikely event re-raise try: subnet_id = port['port']['fixed_ips'][0]['subnet_id'] plugin.get_subnet(context, subnet_id) except exceptions.SubnetNotFound: pass else: ctxt.reraise = True net_id = port['port']['network_id'] LOG.warning( _LW("Action %(action)s for network %(net_id)s " "could not complete successfully: %(reason)s"), { "action": action, "net_id": net_id, 'reason': e })
def update_status(self, context, obj_type, obj_id, provisioning_status=None, operating_status=None): if not provisioning_status and not operating_status: LOG.warning('update_status for %(obj_type)s %(obj_id)s called ' 'without specifying provisioning_status or ' 'operating_status' % {'obj_type': obj_type, 'obj_id': obj_id}) return model_mapping = { 'loadbalancer': db_models.LoadBalancer, 'pool': db_models.PoolV2, 'listener': db_models.Listener, 'member': db_models.MemberV2, 'healthmonitor': db_models.HealthMonitorV2 } if obj_type not in model_mapping: raise n_exc.Invalid(_('Unknown object type: %s') % obj_type) try: self.plugin.db.update_status( context, model_mapping[obj_type], obj_id, provisioning_status=provisioning_status, operating_status=operating_status) except n_exc.NotFound: # update_status may come from agent on an object which was # already deleted from db with other request LOG.warning('Cannot update status: %(obj_type)s %(obj_id)s ' 'not found in the DB, it was probably deleted ' 'concurrently', {'obj_type': obj_type, 'obj_id': obj_id})
def __init__(self, collection, resource, plugin=None, resource_info=None, allow_pagination=None, allow_sorting=None, parent_resource=None, member_actions=None, collection_actions=None, item=None, action_status=None): # Ensure dashes are always replaced with underscores self.collection = collection and collection.replace('-', '_') self.resource = resource and resource.replace('-', '_') self._member_actions = member_actions or {} self._collection_actions = collection_actions or {} self._resource_info = resource_info self._plugin = plugin # Controllers for some resources that are not mapped to anything in # RESOURCE_ATTRIBUTE_MAP will not have anything in _resource_info if self.resource_info: self._mandatory_fields = set([ field for (field, data) in self.resource_info.items() if data.get('required_by_policy') ]) if 'tenant_id' in self._mandatory_fields: # ensure that project_id is queried in the database when # tenant_id is required self._mandatory_fields.add('project_id') else: self._mandatory_fields = set() self.allow_pagination = allow_pagination if self.allow_pagination is None: self.allow_pagination = True self.allow_sorting = allow_sorting if self.allow_sorting is None: self.allow_sorting = True self.native_pagination = api_common.is_native_pagination_supported( self.plugin) self.native_sorting = api_common.is_native_sorting_supported( self.plugin) if self.allow_pagination and self.native_pagination: if not self.native_sorting: raise exceptions.Invalid( _("Native pagination depends on native sorting")) self.primary_key = self._get_primary_key() self.parent = parent_resource parent_resource = '_%s' % parent_resource if parent_resource else '' self._parent_id_name = ('%s_id' % self.parent if self.parent else None) self._plugin_handlers = { self.LIST: 'get%s_%s' % (parent_resource, self.collection), self.SHOW: 'get%s_%s' % (parent_resource, self.resource) } for action in [self.CREATE, self.UPDATE, self.DELETE]: self._plugin_handlers[action] = '%s%s_%s' % ( action, parent_resource, self.resource) self.item = item self.action_status = action_status or {}
def _ensure_driver_unique(self, driver): for k, v in self.providers.items(): if v['driver'] == driver: msg = (_("Driver %s is not unique across providers") % driver) LOG.error(msg) raise n_exc.Invalid(msg)
def __init__(self, plugin, collection, resource, attr_info, allow_bulk=False, member_actions=None, parent=None, allow_pagination=False, allow_sorting=False): if member_actions is None: member_actions = [] self._plugin = plugin self._collection = collection.replace('-', '_') self._resource = resource.replace('-', '_') self._attr_info = attr_info self._allow_bulk = allow_bulk self._allow_pagination = allow_pagination self._allow_sorting = allow_sorting self._native_bulk = self._is_native_bulk_supported() self._native_pagination = self._is_native_pagination_supported() self._native_sorting = self._is_native_sorting_supported() self._policy_attrs = [ name for (name, info) in self._attr_info.items() if info.get('required_by_policy') ] self._notifier = n_rpc.get_notifier('network') # use plugin's dhcp notifier, if this is already instantiated agent_notifiers = getattr(plugin, 'agent_notifiers', {}) self._dhcp_agent_notifier = (agent_notifiers.get( const.AGENT_TYPE_DHCP) or dhcp_rpc_agent_api.DhcpAgentNotifyAPI()) if cfg.CONF.notify_nova_on_port_data_changes: from neutron.notifiers import nova self._nova_notifier = nova.Notifier() self._member_actions = member_actions self._primary_key = self._get_primary_key() if self._allow_pagination and self._native_pagination: # Native pagination need native sorting support if not self._native_sorting: raise exceptions.Invalid( _("Native pagination depend on native sorting")) if not self._allow_sorting: LOG.info( _LI("Allow sorting is enabled because native " "pagination requires native sorting")) self._allow_sorting = True if parent: self._parent_id_name = '%s_id' % parent['member_name'] parent_part = '_%s' % parent['member_name'] else: self._parent_id_name = None parent_part = '' self._plugin_handlers = { self.LIST: 'get%s_%s' % (parent_part, self._collection), self.SHOW: 'get%s_%s' % (parent_part, self._resource) } for action in [self.CREATE, self.UPDATE, self.DELETE]: self._plugin_handlers[action] = '%s%s_%s' % (action, parent_part, self._resource)
def validate_name(name): if len(name) > attr.NAME_MAX_LEN: raise n_exc.Invalid( _("Provider name %(name)s is limited by %(len)s characters") % { 'name': name, 'len': attr.NAME_MAX_LEN })
def parse_service_provider_opt(service_module='neutron', service_type=None): """Parse service definition opts and returns result.""" def validate_name(name): if len(name) > db_const.NAME_FIELD_SIZE: raise n_exc.Invalid( _("Provider name %(name)s is limited by %(len)s characters") % { 'name': name, 'len': db_const.NAME_FIELD_SIZE }) neutron_mod = NeutronModule(service_module) svc_providers_opt = neutron_mod.service_providers() LOG.debug("Service providers = %s", svc_providers_opt) res = [] for prov_def in svc_providers_opt: split = prov_def.split(':') try: svc_type, name, driver = split[:3] if service_type and service_type != svc_type: continue except ValueError: raise n_exc.Invalid(_("Invalid service provider format")) validate_name(name) name = normalize_provider_name(name) default = False if len(split) == 4 and split[3]: if split[3] == 'default': default = True else: msg = (_("Invalid provider format. " "Last part should be 'default' or empty: %s") % prov_def) LOG.error(msg) raise n_exc.Invalid(msg) driver = get_provider_driver_class(driver) res.append({ 'service_type': svc_type, 'name': name, 'driver': driver, 'default': default }) return res
def validate_name(name): if len(name) > db_const.NAME_FIELD_SIZE: raise n_exc.Invalid( _("Provider name %(name)s is limited by %(len)s characters") % { 'name': name, 'len': db_const.NAME_FIELD_SIZE })
def _ensure_default_unique(self, type, default): if not default: return for k, v in self.providers.items(): if k[0] == type and v['default']: msg = _("Multiple default providers " "for service %s") % type LOG.error(msg) raise n_exc.Invalid(msg)
def __init__(self): LOG.debug("ISOFLAT PLUGIN INITIALIZED") self.service_type_manager = st_db.ServiceTypeManager.get_instance() self.service_type_manager.add_provider_configuration(constants.ISOFLAT, pconf.ProviderConfiguration('neutron_isoflat')) drivers, default_provider = service_base.load_drivers(constants.ISOFLAT, self) if default_provider in drivers: self.driver = drivers[default_provider] else: raise n_exc.Invalid("Error retrieving driver for provider %s" % default_provider)
def __init__(self, plugin, collection, resource, attr_info, allow_bulk=False, member_actions=None, parent=None, allow_pagination=False, allow_sorting=False): if member_actions is None: member_actions = [] self._plugin = plugin self._collection = collection.replace('-', '_') # networks self._resource = resource.replace('-', '_') # network self._attr_info = attr_info # allow ... self._allow_bulk = allow_bulk self._allow_pagination = allow_pagination self._allow_sorting = allow_sorting self._native_bulk = self._is_native_bulk_supported() self._native_pagination = self._is_native_pagination_supported() self._native_sorting = self._is_native_sorting_supported() self._policy_attrs = self._init_policy_attrs() self._notifier = n_rpc.get_notifier('network') self._member_actions = member_actions self._primary_key = self._get_primary_key() if self._allow_pagination and self._native_pagination: # Native pagination need native sorting support if not self._native_sorting: raise exceptions.Invalid( _("Native pagination depend on native sorting")) if not self._allow_sorting: LOG.info( _LI("Allow sorting is enabled because native " "pagination requires native sorting")) self._allow_sorting = True self.parent = parent if parent: self._parent_id_name = '%s_id' % parent['member_name'] parent_part = '_%s' % parent['member_name'] else: self._parent_id_name = None parent_part = '' self._plugin_handlers = { self.LIST: 'get%s_%s' % (parent_part, self._collection), # get_networks list操作 self.SHOW: 'get%s_%s' % (parent_part, self._resource) # get_network show操作 } for action in [self.CREATE, self.UPDATE, self.DELETE]: # create: create_network # update: update_network # delete: delete_network self._plugin_handlers[action] = '%s%s_%s' % (action, parent_part, self._resource)
def test__update_router_provider_invalid(self): test_dc = driver_controller.DriverController(self.fake_l3) with mock.patch.object(test_dc, "_get_provider_for_router"): with mock.patch.object( driver_controller, "_ensure_driver_supports_request") as _ensure: _ensure.side_effect = lib_exc.Invalid(message='message') self.assertRaises(lib_exc.Invalid, test_dc._update_router_provider, None, None, None, None, None, {'name': 'testname'}, {'flavor_id': 'old_fid'}, None)
def validate_metering_rule_ip_address(metering_label_rule, ip_address_field): try: if metering_label_rule.get(ip_address_field): ipaddress.ip_interface( metering_label_rule.get(ip_address_field)) except ValueError as exception: raise neutron_exc.Invalid( "%s: %s is invalid [%s]." % (ip_address_field, metering_label_rule.get(ip_address_field), exception))
def _update_router_provider(self, resource, event, trigger, context, router_id, router, old_router, router_db, **kwargs): """Handle transition between providers. The provider can currently be changed only by the caller updating 'ha' and/or 'distributed' attributes. If we allow updates of flavor_id directly in the future those requests will also land here. """ drv = self._get_provider_for_router(context, router_id) new_drv = None if _flavor_specified(router): if router['flavor_id'] != old_router['flavor_id']: # TODO(kevinbenton): this is currently disallowed by the API # so we shouldn't hit it but this is a placeholder to add # support later. raise NotImplementedError() # the following is to support updating the 'ha' and 'distributed' # attributes via the API. try: _ensure_driver_supports_request(drv, router) except lib_exc.Invalid: # the current driver does not support this request, we need to # migrate to a new provider. populate the distributed and ha # flags from the previous state if not in the update so we can # determine the target provider appropriately. # NOTE(kevinbenton): if the router is associated with a flavor # we bail because changing the provider without changing # the flavor will make things inconsistent. We can probably # update the flavor automatically in the future. if old_router['flavor_id']: raise lib_exc.Invalid( _("Changing the 'ha' and 'distributed' attributes on a " "router associated with a flavor is not supported.")) if 'distributed' not in router: router['distributed'] = old_router['distributed'] if 'ha' not in router: router['ha'] = old_router['distributed'] new_drv = self._attrs_to_driver(router) if new_drv: LOG.debug( "Router %(id)s migrating from %(old)s provider to " "%(new)s provider.", { 'id': router_id, 'old': drv, 'new': new_drv }) _ensure_driver_supports_request(new_drv, router) # TODO(kevinbenton): notify old driver explicity of driver change with context.session.begin(subtransactions=True): self._stm.del_resource_associations(context, [router_id]) self._stm.add_resource_association(context, 'L3_ROUTER_NAT', new_drv.name, router_id)
def _ensure_driver_supports_request(drv, router_body): r = router_body for key, attr in (('distributed', 'distributed_support'), ('ha', 'ha_support')): flag = r.get(key) if flag not in [True, False]: continue # not specified in body if not getattr(drv, attr).is_compatible(flag): raise lib_exc.Invalid( _("Provider %(name)s does not support %(key)s=%(flag)s") % dict(name=drv.name, key=key, flag=flag))
def add_provider(self, provider): self._ensure_driver_unique(provider['driver']) self._ensure_default_unique(provider['service_type'], provider['default']) provider_type = (provider['service_type'], provider['name']) if provider_type in self.providers: msg = (_("Multiple providers specified for service " "%s") % provider['service_type']) LOG.error(msg) raise n_exc.Invalid(msg) self.providers[provider_type] = {'driver': provider['driver'], 'default': provider['default']}
def update_status(self, context, obj_type, obj_id, status): model_mapping = { 'pool': loadbalancer_db.Pool, 'vip': loadbalancer_db.Vip, 'member': loadbalancer_db.Member, 'health_monitor': loadbalancer_db.PoolMonitorAssociation } if obj_type not in model_mapping: raise n_exc.Invalid(_('Unknown object type: %s') % obj_type) try: if obj_type == 'health_monitor': self.plugin.update_pool_health_monitor( context, obj_id['monitor_id'], obj_id['pool_id'], status) else: self.plugin.update_status( context, model_mapping[obj_type], obj_id, status) except n_exc.NotFound: # update_status may come from agent on an object which was # already deleted from db with other request LOG.warning(_LW('Cannot update status: %(obj_type)s %(obj_id)s ' 'not found in the DB, it was probably deleted ' 'concurrently'), {'obj_type': obj_type, 'obj_id': obj_id})
def test__update_router_provider_invalid(self, mock_method): mock_method.side_effect = lib_exc.Invalid(message='message') driver_controller._LegacyPlusProviderConfiguration()
def test_invalid(self): try: raise ne.Invalid("hello world") except ne.Invalid as e: self.assertEqual(e.msg, "hello world")
def execute_sysfs_command(self, command, ts_port_params, src_port_params, common_vlans_ranges_str, vf_to_vf_all_vlans, direction): """Execute the SRIOV NIC Switch Driver's SysFs command. # Mirror traffic from VF0 to VF3 on interface p2p1, ex. echo add 3 > /sys/class/net/p2p1/device/sriov/0/ingress_mirror echo add 3 > /sys/class/net/p2p1/device/sriov/0/egress_mirror # Remove traffic mirroring from VF0 to VF3 on interface p2p1, ex. echo rem 3 > /sys/class/net/p2p1/device/sriov/0/ingress_mirror echo rem 3 > /sys/class/net/p2p1/device/sriov/0/egress_mirror # Add VLANs 2,6,18-22 to Mirror traffic to VF3 (port p2p1), ex. echo add 2,6,18-22 > /sys/class/net/p2p1/device/sriov/3/vlan_mirror # Remove VLANs 2,6,18-22 to Mirror traffic to VF3 (port p2p1), ex. echo rem 2,6,18-22 > /sys/class/net/p2p1/device/sriov/3/vlan_mirror # Remove all VLANs from mirroring at VF3, ex. echo rem 0-4095 > /sys/class/net/p1p1/device/sriov/3/vlan_mirror """ if vf_to_vf_all_vlans: if direction in ['OUT', 'BOTH']: sysfs_kobject_path = \ '/sys/class/net/' + ts_port_params['pf_device'] + \ '/device/sriov/' + src_port_params['vf_index'] + \ '/egress_mirror/' commit_cmd = ['echo', command, ts_port_params['vf_index'], '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) and/or " "Source VF (%s) combination" % (ts_port_params['pf_device'], src_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return if direction in ['IN', 'BOTH']: sysfs_kobject_path = \ '/sys/class/net/' + ts_port_params['pf_device'] + \ '/device/sriov/' + src_port_params['vf_index'] + \ '/ingress_mirror/' commit_cmd = ['echo', command, ts_port_params['vf_index'], '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) and/or " "Source VF (%s) combination" % (ts_port_params['pf_device'], src_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return else: if direction != 'BOTH': LOG.warning("SRIOV NIC Switch driver only supports" "direction=BOTH for specific VLANs' mirroring") sysfs_kobject_path = '/sys/class/net/' + \ ts_port_params['pf_device'] + \ '/device/sriov/' + \ ts_port_params['vf_index'] + '/' commit_cmd = ['echo', command, common_vlans_ranges_str, '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) or Tap-service VF (%s) " "combination" % (ts_port_params['pf_device'], ts_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return
def _get_driver_for_provider(self, provider): if provider in self.drivers: return self.drivers[provider] raise n_exc.Invalid("Error retrieving driver for provider %s" % provider)
def _get_driver_for_provider(self, provider): if provider in self.drivers: return self.drivers[provider] # raise if not associated (should never be reached) raise n_exc.Invalid("Error retrieving driver for provider %s" % provider)