def remove_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise n_exc.BadRequest(resource='router', msg=msg) port_id = interface_info.get('port_id') subnet_id = interface_info.get('subnet_id') device_owner = self._get_device_owner(context, router_id) if port_id: port, subnet = self._remove_interface_by_port( context, router_id, port_id, subnet_id, device_owner) elif subnet_id: port, subnet = self._remove_interface_by_subnet( context, router_id, subnet_id, device_owner) self.l3_rpc_notifier.routers_updated(context, [router_id], 'remove_router_interface') info = { 'id': router_id, 'tenant_id': port['tenant_id'], 'port_id': port['id'], 'subnet_id': subnet['id'] } notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.delete', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) device_owner = self._get_device_owner(context, router_id) if add_by_port: port = self._add_interface_by_port(context, router_id, interface_info['port_id'], device_owner) elif add_by_sub: port = self._add_interface_by_subnet(context, router_id, interface_info['subnet_id'], device_owner) self.l3_rpc_notifier.routers_updated(context, [router_id], 'add_router_interface') info = { 'id': router_id, 'tenant_id': port['tenant_id'], 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id'] } notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.create', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def remove_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise n_exc.BadRequest(resource='router', msg=msg) port_id = interface_info.get('port_id') subnet_id = interface_info.get('subnet_id') device_owner = self._get_device_owner(context, router_id) if port_id: port, subnet = self._remove_interface_by_port(context, router_id, port_id, subnet_id, device_owner) elif subnet_id: port, subnet = self._remove_interface_by_subnet( context, router_id, subnet_id, device_owner) self.l3_rpc_notifier.routers_updated( context, [router_id], 'remove_router_interface') info = {'id': router_id, 'tenant_id': port['tenant_id'], 'port_id': port['id'], 'subnet_id': subnet['id']} notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.delete', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def test_allocation_notification(self): subnet = dict( id=1, first_ip=0, last_ip=255, cidr="0.0.0.0/24", ip_version=4, next_auto_assign_ip=0, network=dict(ip_policy=None), ip_policy=None, ) address = dict(address=0, created_at="123", subnet_id=1, address_readable="0.0.0.0", used_by_tenant_id=1) with self._stubs(address, subnets=[(subnet, 1)], addresses=[None, None]) as notify: self.ipam.allocate_ip_address(self.context, 0, 0, 0, version=4) notify.assert_called_once_with( self.context, notifier_api.publisher_id("network"), "ip_block.address.create", notifier_api.CONF.default_notification_level, dict( ip_block_id=address["subnet_id"], ip_address="0.0.0.0", device_ids=[], created_at=address["created_at"], used_by_tenant_id=1, ), )
def test_deallocation_notification(self): address = dict( address=0, created_at="123", subnet_id=1, address_readable="0.0.0.0", used_by_tenant_id=1, ports=[dict(device_id="foo")], ) port = dict(ip_addresses=[address]) with self._stubs(dict(), deleted_at="456") as notify: self.ipam.deallocate_ip_address(self.context, port) notify.assert_called_once_with( self.context, notifier_api.publisher_id("network"), "ip_block.address.delete", notifier_api.CONF.default_notification_level, dict( ip_block_id=address["subnet_id"], ip_address="0.0.0.0", device_ids=["foo"], created_at=address["created_at"], deleted_at="456", used_by_tenant_id=1, ), )
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._publisher_id = notifier_api.publisher_id('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( _("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 process_request(self, request): request.environ['HTTP_X_SERVICE_NAME'] = \ self.service_name or request.host payload = { 'request': self.environ_to_dict(request.environ), } api.notify(context.get_admin_context(), api.publisher_id(os.path.basename(sys.argv[0])), 'http.request', api.INFO, payload)
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._publisher_id = notifier_api.publisher_id("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() ) 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(_("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 allocate_ip_address(self, context, net_id, port_id, reuse_after, version=None, ip_address=None): elevated = context.elevated() if ip_address: ip_address = netaddr.IPAddress(ip_address) new_addresses = [] realloc_ips = self.attempt_to_reallocate_ip(context, net_id, port_id, reuse_after, version=None, ip_address=None) if self.is_strategy_satisfied(realloc_ips): return realloc_ips new_addresses.extend(realloc_ips) with context.session.begin(subtransactions=True): subnets = self._choose_available_subnet( elevated, net_id, version, ip_address=ip_address, reallocated_ips=realloc_ips) for subnet in subnets: ip_policy_rules = models.IPPolicy.get_ip_policy_rule_set( subnet) # Creating this IP for the first time next_ip = None if ip_address: next_ip = ip_address address = db_api.ip_address_find( elevated, network_id=net_id, ip_address=next_ip, used_by_tenant_id=elevated.tenant_id, scope=db_api.ONE) if address: raise exceptions.IpAddressGenerationFailure( net_id=net_id) else: next_ip = self._iterate_until_available_ip( elevated, subnet, net_id, ip_policy_rules) context.session.add(subnet) address = db_api.ip_address_create( elevated, address=next_ip, subnet_id=subnet["id"], version=subnet["ip_version"], network_id=net_id) address["deallocated"] = 0 new_addresses.append(address) for addr in new_addresses: payload = dict(used_by_tenant_id=addr["used_by_tenant_id"], ip_block_id=addr["subnet_id"], ip_address=addr["address_readable"], device_ids=[p["device_id"] for p in addr["ports"]], created_at=addr["created_at"]) notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.address.create", notifier_api.CONF.default_notification_level, payload) return new_addresses
def process_request(self, request): request.environ['HTTP_X_SERVICE_NAME'] = \ self.service_name or request.host payload = { 'request': self.environ_to_dict(request.environ), } api.notify(context.get_admin_context(), api.publisher_id(os.path.basename(sys.argv[0])), 'http.request', api.INFO, payload)
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._publisher_id = notifier_api.publisher_id('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(_("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 _notify_new_addresses(self, context, new_addresses): for addr in new_addresses: payload = dict(used_by_tenant_id=addr["used_by_tenant_id"], ip_block_id=addr["subnet_id"], ip_address=addr["address_readable"], device_ids=[p["device_id"] for p in addr["ports"]], created_at=addr["created_at"]) notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.address.create", notifier_api.CONF.default_notification_level, payload)
def _deallocate_ip_address(self, context, address): address["deallocated"] = 1 payload = dict(used_by_tenant_id=address["used_by_tenant_id"], ip_block_id=address["subnet_id"], ip_address=address["address_readable"], device_ids=[p["device_id"] for p in address["ports"]], created_at=address["created_at"], deleted_at=timeutils.utcnow()) notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.address.delete", notifier_api.CONF.default_notification_level, payload)
def test_create_subnet_notification(self): s = dict(network_id=1, cidr="192.168.10.0/24", tenant_id=1, id=1, created_at="123") with self._stubs(s) as notify: self.plugin.create_subnet(self.context, dict(subnet=s)) notify.assert_called_once_with( self.context, notifier_api.publisher_id("network"), "ip_block.create", notifier_api.CONF.default_notification_level, dict(tenant_id=s["tenant_id"], ip_block_id=s["id"], created_at=s["created_at"]))
def remove_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource="router", msg=msg) if "port_id" in interface_info: port_id = interface_info["port_id"] port_db = self._core_plugin._get_port(context, port_id) if not (port_db["device_owner"] == DEVICE_OWNER_ROUTER_INTF and port_db["device_id"] == router_id): raise l3.RouterInterfaceNotFound(router_id=router_id, port_id=port_id) if "subnet_id" in interface_info: port_subnet_id = port_db["fixed_ips"][0]["subnet_id"] if port_subnet_id != interface_info["subnet_id"]: raise q_exc.SubnetMismatchForPort(port_id=port_id, subnet_id=interface_info["subnet_id"]) subnet_id = port_db["fixed_ips"][0]["subnet_id"] subnet = self._core_plugin._get_subnet(context, subnet_id) self._confirm_router_interface_not_in_use(context, router_id, subnet_id) self._core_plugin.delete_port(context, port_db["id"], l3_port_check=False) elif "subnet_id" in interface_info: subnet_id = interface_info["subnet_id"] self._confirm_router_interface_not_in_use(context, router_id, subnet_id) subnet = self._core_plugin._get_subnet(context, subnet_id) found = False try: rport_qry = context.session.query(models_v2.Port) ports = rport_qry.filter_by( device_id=router_id, device_owner=DEVICE_OWNER_ROUTER_INTF, network_id=subnet["network_id"] ) for p in ports: if p["fixed_ips"][0]["subnet_id"] == subnet_id: port_id = p["id"] self._core_plugin.delete_port(context, p["id"], l3_port_check=False) found = True break except exc.NoResultFound: pass if not found: raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id, subnet_id=subnet_id) self.l3_rpc_notifier.routers_updated(context, [router_id], "remove_router_interface") info = {"id": router_id, "tenant_id": subnet["tenant_id"], "port_id": port_id, "subnet_id": subnet_id} notifier_api.notify( context, notifier_api.publisher_id("network"), "router.interface.delete", notifier_api.CONF.default_notification_level, {"router.interface": info}, ) return info
def test_delete_subnet_notification(self): now = time.strftime('%Y-%m-%d %H:%M:%S') later = time.strftime('%Y-%m-%d %H:%M:%S') s = dict(tenant_id=1, id=1, created_at=now) with self._stubs(s, deleted_at=later) as notify: self.plugin.delete_subnet(self.context, 1) notify.assert_called_once_with( self.context, notifier_api.publisher_id("network"), "ip_block.delete", notifier_api.CONF.default_notification_level, dict(tenant_id=s["tenant_id"], created_at=s["created_at"], ip_block_id=s["id"], deleted_at=later))
def main(): cfg.CONF(project='neutron') config.setup_logging(cfg.CONF) cxt = context.get_admin_context() plugin = manager.NeutronManager.get_plugin() for network in plugin.get_networks(cxt): notifier_api.notify(cxt, notifier_api.publisher_id('network'), 'network.exists', notifier_api.INFO, {'network': network}) for subnet in plugin.get_subnets(cxt): notifier_api.notify(cxt, notifier_api.publisher_id('network'), 'subnet.exists', notifier_api.INFO, {'subnet': subnet}) for port in plugin.get_ports(cxt): notifier_api.notify(cxt, notifier_api.publisher_id('network'), 'port.exists', notifier_api.INFO, {'port': port}) for router in plugin.get_routers(cxt): notifier_api.notify(cxt, notifier_api.publisher_id('network'), 'router.exists', notifier_api.INFO, {'router': router}) for floatingip in plugin.get_floatingips(cxt): notifier_api.notify(cxt, notifier_api.publisher_id('network'), 'floatingip.exists', notifier_api.INFO, {'floatingip': floatingip})
def _metering_notification(self): for label_id, info in self.metering_infos.items(): data = {'label_id': label_id, 'tenant_id': self.label_tenant_id.get(label_id), 'pkts': info['pkts'], 'bytes': info['bytes'], 'time': info['time'], 'first_update': info['first_update'], 'last_update': info['last_update'], 'host': self.host} LOG.debug("Send metering report: %s" % data) notifier_api.notify(self.context, notifier_api.publisher_id('metering'), 'l3.meter', notifier_api.CONF.default_notification_level, data) info['pkts'] = 0 info['bytes'] = 0 info['time'] = 0
def _metering_notification(self): for label_id, info in self.metering_infos.items(): data = {'label_id': label_id, 'tenant_id': self.label_tenant_id.get(label_id), 'pkts': info['pkts'], 'bytes': info['bytes'], 'time': info['time'], 'first_update': info['first_update'], 'last_update': info['last_update'], 'host': self.host} LOG.debug(_("Send metering report: %s"), data) notifier_api.notify(self.context, notifier_api.publisher_id('metering'), 'l3.meter', notifier_api.CONF.default_notification_level, data) info['pkts'] = 0 info['bytes'] = 0 info['time'] = 0
def process_response(self, request, response, exception=None, traceback=None): payload = { 'request': self.environ_to_dict(request.environ), } if response: payload['response'] = { 'status': response.status, 'headers': response.headers, } if exception: payload['exception'] = { 'value': repr(exception), 'traceback': tb.format_tb(traceback) } api.notify(context.get_admin_context(), api.publisher_id(os.path.basename(sys.argv[0])), 'http.response', api.INFO, payload)
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) device_owner = self._get_device_owner(context, router_id) if add_by_port: port = self._add_interface_by_port( context, router_id, interface_info['port_id'], device_owner) elif add_by_sub: port = self._add_interface_by_subnet( context, router_id, interface_info['subnet_id'], device_owner) self.l3_rpc_notifier.routers_updated( context, [router_id], 'add_router_interface') info = {'id': router_id, 'tenant_id': port['tenant_id'], 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id']} notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.create', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def delete_subnet(context, id): """Delete a subnet. : param context: neutron api request context : param id: UUID representing the subnet to delete. """ LOG.info("delete_subnet %s for tenant %s" % (id, context.tenant_id)) with context.session.begin(): subnet = db_api.subnet_find(context, id=id, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=id) payload = dict(tenant_id=subnet["tenant_id"], ip_block_id=subnet["id"], created_at=subnet["created_at"], deleted_at=timeutils.utcnow()) _delete_subnet(context, subnet) notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.delete", notifier_api.CONF.default_notification_level, payload)
def process_response(self, request, response, exception=None, traceback=None): payload = { 'request': self.environ_to_dict(request.environ), } if response: payload['response'] = { 'status': response.status, 'headers': response.headers, } if exception: payload['exception'] = { 'value': repr(exception), 'traceback': tb.format_tb(traceback) } api.notify(context.get_admin_context(), api.publisher_id(os.path.basename(sys.argv[0])), 'http.response', api.INFO, payload)
def _metering_notification(self): for label_id, info in self.metering_infos.items(): data = { "label_id": label_id, "tenant_id": self.label_tenant_id.get(label_id), "pkts": info["pkts"], "bytes": info["bytes"], "time": info["time"], "first_update": info["first_update"], "last_update": info["last_update"], "host": self.host, } LOG.debug(_("Send metering report: %s"), data) notifier_api.notify( self.context, notifier_api.publisher_id("metering"), "l3.meter", notifier_api.CONF.default_notification_level, data, ) info["pkts"] = 0 info["bytes"] = 0 info["time"] = 0
def remove_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource='router', msg=msg) if 'port_id' in interface_info: port_id = interface_info['port_id'] port_db = self._core_plugin._get_port(context, port_id) if not (port_db['device_owner'] == DEVICE_OWNER_ROUTER_INTF and port_db['device_id'] == router_id): raise l3.RouterInterfaceNotFound(router_id=router_id, port_id=port_id) if 'subnet_id' in interface_info: port_subnet_id = port_db['fixed_ips'][0]['subnet_id'] if port_subnet_id != interface_info['subnet_id']: raise q_exc.SubnetMismatchForPort( port_id=port_id, subnet_id=interface_info['subnet_id']) subnet_id = port_db['fixed_ips'][0]['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) self._confirm_router_interface_not_in_use(context, router_id, subnet_id) self._core_plugin.delete_port(context, port_db['id'], l3_port_check=False) elif 'subnet_id' in interface_info: subnet_id = interface_info['subnet_id'] self._confirm_router_interface_not_in_use(context, router_id, subnet_id) subnet = self._core_plugin._get_subnet(context, subnet_id) found = False try: rport_qry = context.session.query(models_v2.Port) ports = rport_qry.filter_by( device_id=router_id, device_owner=DEVICE_OWNER_ROUTER_INTF, network_id=subnet['network_id']) for p in ports: if p['fixed_ips'][0]['subnet_id'] == subnet_id: port_id = p['id'] self._core_plugin.delete_port(context, p['id'], l3_port_check=False) found = True break except exc.NoResultFound: pass if not found: raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id, subnet_id=subnet_id) self.l3_rpc_notifier.routers_updated(context, [router_id], 'remove_router_interface') info = { 'id': router_id, 'tenant_id': subnet['tenant_id'], 'port_id': port_id, 'subnet_id': subnet_id } notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.delete', notifier_api.CONF.default_notification_level, {'router.interface': info}) return info
def add_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource='router', msg=msg) if 'port_id' in interface_info: # make sure port update is committed with context.session.begin(subtransactions=True): if 'subnet_id' in interface_info: msg = _("Cannot specify both subnet-id and port-id") raise q_exc.BadRequest(resource='router', msg=msg) port = self._core_plugin._get_port(context, interface_info['port_id']) if port['device_id']: raise q_exc.PortInUse(net_id=port['network_id'], port_id=port['id'], device_id=port['device_id']) fixed_ips = [ip for ip in port['fixed_ips']] if len(fixed_ips) != 1: msg = _('Router port must have exactly one fixed IP') raise q_exc.BadRequest(resource='router', msg=msg) subnet_id = fixed_ips[0]['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) self._check_for_dup_router_subnet(context, router_id, port['network_id'], subnet['id'], subnet['cidr']) port.update({ 'device_id': router_id, 'device_owner': DEVICE_OWNER_ROUTER_INTF }) elif 'subnet_id' in interface_info: subnet_id = interface_info['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) # Ensure the subnet has a gateway if not subnet['gateway_ip']: msg = _('Subnet for router interface must have a gateway IP') raise q_exc.BadRequest(resource='router', msg=msg) self._check_for_dup_router_subnet(context, router_id, subnet['network_id'], subnet_id, subnet['cidr']) fixed_ip = { 'ip_address': subnet['gateway_ip'], 'subnet_id': subnet['id'] } port = self._core_plugin.create_port( context, { 'port': { 'tenant_id': subnet['tenant_id'], 'network_id': subnet['network_id'], 'fixed_ips': [fixed_ip], 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'device_id': router_id, 'device_owner': DEVICE_OWNER_ROUTER_INTF, 'name': '' } }) self.l3_rpc_notifier.routers_updated(context, [router_id], 'add_router_interface') info = { 'id': router_id, 'tenant_id': subnet['tenant_id'], 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id'] } notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.create', notifier_api.CONF.default_notification_level, {'router.interface': info}) return info
def add_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource="router", msg=msg) if "port_id" in interface_info: # make sure port update is committed with context.session.begin(subtransactions=True): if "subnet_id" in interface_info: msg = _("Cannot specify both subnet-id and port-id") raise q_exc.BadRequest(resource="router", msg=msg) port = self._get_port(context, interface_info["port_id"]) if port["device_id"]: raise q_exc.PortInUse(net_id=port["network_id"], port_id=port["id"], device_id=port["device_id"]) fixed_ips = [ip for ip in port["fixed_ips"]] if len(fixed_ips) != 1: msg = _("Router port must have exactly one fixed IP") raise q_exc.BadRequest(resource="router", msg=msg) subnet_id = fixed_ips[0]["subnet_id"] subnet = self._get_subnet(context, subnet_id) self._check_for_dup_router_subnet(context, router_id, port["network_id"], subnet["id"], subnet["cidr"]) port.update({"device_id": router_id, "device_owner": DEVICE_OWNER_ROUTER_INTF}) elif "subnet_id" in interface_info: subnet_id = interface_info["subnet_id"] subnet = self._get_subnet(context, subnet_id) # Ensure the subnet has a gateway if not subnet["gateway_ip"]: msg = _("Subnet for router interface must have a gateway IP") raise q_exc.BadRequest(resource="router", msg=msg) self._check_for_dup_router_subnet(context, router_id, subnet["network_id"], subnet_id, subnet["cidr"]) fixed_ip = {"ip_address": subnet["gateway_ip"], "subnet_id": subnet["id"]} port = self.create_port( context, { "port": { "tenant_id": subnet["tenant_id"], "network_id": subnet["network_id"], "fixed_ips": [fixed_ip], "mac_address": attributes.ATTR_NOT_SPECIFIED, "admin_state_up": True, "device_id": router_id, "device_owner": DEVICE_OWNER_ROUTER_INTF, "name": "", } }, ) l3_rpc_agent_api.L3AgentNotify.routers_updated(context, [router_id], "add_router_interface") info = { "id": router_id, "tenant_id": subnet["tenant_id"], "port_id": port["id"], "subnet_id": port["fixed_ips"][0]["subnet_id"], } notifier_api.notify( context, notifier_api.publisher_id("network"), "router.interface.create", notifier_api.CONF.default_notification_level, {"router.interface": info}, ) return info
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: default_route = route gateway_ip = default_route["nexthop"] new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) if default_route is None: new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) if isinstance(allocation_pools, list): ranges = [] cidrset = netaddr.IPSet([netaddr.IPNetwork(new_subnet["cidr"])]) for p in allocation_pools: cidrset -= netaddr.IPSet(netaddr.IPRange(p["start"], p["end"])) non_allocation_pools = v._pools_from_cidr(cidrset) for p in non_allocation_pools: r = netaddr.IPRange(p["start"], p["end"]) ranges.append(dict( length=len(r), offset=int(r[0]) - int(cidr[0]))) new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=ranges) subnet_dict = v._make_subnet_dict(new_subnet, default_route=routes.DEFAULT_ROUTE) subnet_dict["gateway_ip"] = gateway_ip notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.create", notifier_api.CONF.default_notification_level, dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def add_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise n_exc.BadRequest(resource='router', msg=msg) if 'port_id' in interface_info: # make sure port update is committed with context.session.begin(subtransactions=True): if 'subnet_id' in interface_info: msg = _("Cannot specify both subnet-id and port-id") raise n_exc.BadRequest(resource='router', msg=msg) port = self._core_plugin._get_port(context, interface_info['port_id']) if port['device_id']: raise n_exc.PortInUse(net_id=port['network_id'], port_id=port['id'], device_id=port['device_id']) fixed_ips = [ip for ip in port['fixed_ips']] if len(fixed_ips) != 1: msg = _('Router port must have exactly one fixed IP') raise n_exc.BadRequest(resource='router', msg=msg) subnet_id = fixed_ips[0]['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) self._check_for_dup_router_subnet(context, router_id, port['network_id'], subnet['id'], subnet['cidr']) port.update({'device_id': router_id, 'device_owner': DEVICE_OWNER_ROUTER_INTF}) elif 'subnet_id' in interface_info: subnet_id = interface_info['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) # Ensure the subnet has a gateway if not subnet['gateway_ip']: msg = _('Subnet for router interface must have a gateway IP') raise n_exc.BadRequest(resource='router', msg=msg) self._check_for_dup_router_subnet(context, router_id, subnet['network_id'], subnet_id, subnet['cidr']) fixed_ip = {'ip_address': subnet['gateway_ip'], 'subnet_id': subnet['id']} port = self._core_plugin.create_port(context, { 'port': {'tenant_id': subnet['tenant_id'], 'network_id': subnet['network_id'], 'fixed_ips': [fixed_ip], 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'device_id': router_id, 'device_owner': DEVICE_OWNER_ROUTER_INTF, 'name': ''}}) self.l3_rpc_notifier.routers_updated( context, [router_id], 'add_router_interface') info = {'id': router_id, 'tenant_id': subnet['tenant_id'], 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id']} notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.create', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def remove_router_interface(self, context, router_id, interface_info): if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise n_exc.BadRequest(resource='router', msg=msg) if 'port_id' in interface_info: port_id = interface_info['port_id'] port_db = self._core_plugin._get_port(context, port_id) if not (port_db['device_owner'] == DEVICE_OWNER_ROUTER_INTF and port_db['device_id'] == router_id): raise l3.RouterInterfaceNotFound(router_id=router_id, port_id=port_id) if 'subnet_id' in interface_info: port_subnet_id = port_db['fixed_ips'][0]['subnet_id'] if port_subnet_id != interface_info['subnet_id']: raise n_exc.SubnetMismatchForPort( port_id=port_id, subnet_id=interface_info['subnet_id']) subnet_id = port_db['fixed_ips'][0]['subnet_id'] subnet = self._core_plugin._get_subnet(context, subnet_id) self._confirm_router_interface_not_in_use( context, router_id, subnet_id) self._core_plugin.delete_port(context, port_db['id'], l3_port_check=False) elif 'subnet_id' in interface_info: subnet_id = interface_info['subnet_id'] self._confirm_router_interface_not_in_use(context, router_id, subnet_id) subnet = self._core_plugin._get_subnet(context, subnet_id) found = False try: rport_qry = context.session.query(models_v2.Port) ports = rport_qry.filter_by( device_id=router_id, device_owner=DEVICE_OWNER_ROUTER_INTF, network_id=subnet['network_id']) for p in ports: if p['fixed_ips'][0]['subnet_id'] == subnet_id: port_id = p['id'] self._core_plugin.delete_port(context, p['id'], l3_port_check=False) found = True break except exc.NoResultFound: pass if not found: raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id, subnet_id=subnet_id) self.l3_rpc_notifier.routers_updated( context, [router_id], 'remove_router_interface') info = {'id': router_id, 'tenant_id': subnet['tenant_id'], 'port_id': port_id, 'subnet_id': subnet_id} notifier_api.notify(context, notifier_api.publisher_id('network'), 'router.interface.delete', notifier_api.CONF.default_notification_level, {'router_interface': info}) return info
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) err_vals = {'cidr': sub_attrs["cidr"], 'network_id': net_id} err = _("Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s. Prefix is too small, must be a " "larger subnet. A prefix less than /%(prefix)s is required.") if cidr.version == 6 and cidr.prefixlen > 64: err_vals["prefix"] = 65 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) elif cidr.version == 4 and cidr.prefixlen > 30: err_vals["prefix"] = 31 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) if not context.is_admin and "segment_id" in sub_attrs: sub_attrs.pop("segment_id") sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: if default_route: raise q_exc.DuplicateRouteConflict( subnet_id=new_subnet["id"]) default_route = route gateway_ip = default_route["nexthop"] new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) if gateway_ip and default_route is None: new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) if isinstance(allocation_pools, list) and allocation_pools: subnet_net = netaddr.IPNetwork(new_subnet["cidr"]) cidrset = netaddr.IPSet( netaddr.IPRange( netaddr.IPAddress(subnet_net.first), netaddr.IPAddress(subnet_net.last)).cidrs()) for p in allocation_pools: start = netaddr.IPAddress(p["start"]) end = netaddr.IPAddress(p["end"]) cidrset -= netaddr.IPSet(netaddr.IPRange( netaddr.IPAddress(start), netaddr.IPAddress(end)).cidrs()) default_cidrset = models.IPPolicy.get_ip_policy_cidrs(new_subnet) cidrset.update(default_cidrset) cidrs = [str(x.cidr) for x in cidrset.iter_cidrs()] new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=cidrs) subnet_dict = v._make_subnet_dict(new_subnet) subnet_dict["gateway_ip"] = gateway_ip notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.create", notifier_api.CONF.default_notification_level, dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def add_router_interface(self, context, router_id, interface_info): LOG.debug(_("add_router_interface called in l3_db.py context: %s"), context) LOG.debug(_("add_router_interface called in l3_db.py router: %s"), router_id) LOG.debug(_("add_router_interface called in l3_db.py interface: %s"), interface_info) if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource="router", msg=msg) if "port_id" in interface_info: # make sure port update is committed LOG.debug(_("add_router_interface called in l3_db.py portid given")) with context.session.begin(subtransactions=True): if "subnet_id" in interface_info: msg = _("Cannot specify both subnet-id and port-id") raise q_exc.BadRequest(resource="router", msg=msg) port = self._core_plugin._get_port(context, interface_info["port_id"]) LOG.debug(_("add_router_interface called in l3_db.py port returned by plugin: %s"), port) if port["device_id"]: raise q_exc.PortInUse(net_id=port["network_id"], port_id=port["id"], device_id=port["device_id"]) fixed_ips = [ip for ip in port["fixed_ips"]] if len(fixed_ips) != 1: msg = _("Router port must have exactly one fixed IP") raise q_exc.BadRequest(resource="router", msg=msg) subnet_id = fixed_ips[0]["subnet_id"] subnet = self._core_plugin._get_subnet(context, subnet_id) LOG.debug(_("add_router_interface called in l3_db.py subnet returned by plugin: %s"), subnet) self._check_for_dup_router_subnet(context, router_id, port["network_id"], subnet["id"], subnet["cidr"]) LOG.debug(_("add_router_interface called in l3_db.py port.update going to be called")) port.update({"device_id": router_id, "device_owner": DEVICE_OWNER_ROUTER_INTF}) LOG.debug(_("add_router_interface called in l3_db.py port.update going to be called over")) elif "subnet_id" in interface_info: LOG.debug(_("add_router_interface called in l3_db.py subnetid given")) subnet_id = interface_info["subnet_id"] subnet = self._core_plugin._get_subnet(context, subnet_id) LOG.debug(_("add_router_interface called in l3_db.py subnet returned by plugin: %s"), subnet) # Ensure the subnet has a gateway if not subnet["gateway_ip"]: msg = _("Subnet for router interface must have a gateway IP") raise q_exc.BadRequest(resource="router", msg=msg) self._check_for_dup_router_subnet(context, router_id, subnet["network_id"], subnet_id, subnet["cidr"]) fixed_ip = {"ip_address": subnet["gateway_ip"], "subnet_id": subnet["id"]} port = self._core_plugin.create_port( context, { "port": { "tenant_id": subnet["tenant_id"], "network_id": subnet["network_id"], "fixed_ips": [fixed_ip], "mac_address": attributes.ATTR_NOT_SPECIFIED, "admin_state_up": True, "device_id": router_id, "device_owner": DEVICE_OWNER_ROUTER_INTF, "name": "", } }, ) LOG.debug(_("add_router_interface called in l3_db.py port returned by plugin: %s"), port) LOG.debug(_("add_router_interface called in l3_db.py router_updated being called context: %s"), context) LOG.debug(_("add_router_interface called in l3_db.py l3_rpc_notifier.update_routers being called")) """ self.l3_rpc_notifier.routers_updated( context, [router_id], 'add_router_interface') """ # inform ML2 plugin on creation of router ports self._core_plugin.update_router_interface(context, router_id) info = { "id": router_id, "tenant_id": subnet["tenant_id"], "port_id": port["id"], "subnet_id": port["fixed_ips"][0]["subnet_id"], } LOG.debug(_("add_router_interface called in l3_db.py info: %s"), info) LOG.debug(_("add_router_interface called in l3_db.py notify_api called")) notifier_api.notify( context, notifier_api.publisher_id("network"), "router.interface.create", notifier_api.CONF.default_notification_level, {"router.interface": info}, ) LOG.debug(_("add_router_interface called in l3_db.py notify_api called over")) return info