def delete(self, request, id, **kwargs): """Deletes the specified entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.start', notifier_api.CONF.default_notification_level, {self._resource + '_id': id}) action = self._plugin_handlers[self.DELETE] # Check authz parent_id = kwargs.get(self._parent_id_name) obj = self._item(request, id, parent_id=parent_id) try: policy.enforce(request.context, action, obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_deleter = getattr(self._plugin, action) obj_deleter(request.context, id, **kwargs) notifier_method = self._resource + '.delete.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, {self._resource + '_id': id}) result = {self._resource: self._view(obj)} self._send_dhcp_notification(request.context, result, notifier_method)
def delete(self, request, id, **kwargs): """Deletes the specified entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.start', notifier_api.INFO, {self._resource + '_id': id}) action = self._plugin_handlers[self.DELETE] # Check authz parent_id = kwargs.get(self._parent_id_name) obj = self._item(request, id, parent_id=parent_id) try: policy.enforce(request.context, action, obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_deleter = getattr(self._plugin, action) obj_deleter(request.context, id, **kwargs) notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.end', notifier_api.INFO, {self._resource + '_id': id})
def remove_router_interface(self, context, router_id, interface_info): # make sure router exists router = self._get_router(context, router_id) try: policy.enforce(context, "extension:router:remove_router_interface", self._make_router_dict(router)) except q_exc.PolicyNotAuthorized: raise l3.RouterNotFound(router_id=router_id) 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._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"] self._confirm_router_interface_not_in_use(context, router_id, subnet_id) _network_id = port_db["network_id"] self.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._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"] ).all() for p in ports: if p["fixed_ips"][0]["subnet_id"] == subnet_id: port_id = p["id"] _network_id = p["network_id"] self.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) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, "remove_router_interface", {"network_id": _network_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": {"port_id": port_id, "subnet_id": subnet_id}}, )
def delete(self, request, id, **kwargs): """Deletes the specified entity.""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.start', notifier_api.CONF.default_notification_level, {self._resource + '_id': id}) action = self._plugin_handlers[self.DELETE] # Check authz parent_id = kwargs.get(self._parent_id_name) obj = self._item(request, id, parent_id=parent_id) try: policy.enforce(request.context, action, obj) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_deleter = getattr(self._plugin, action) obj_deleter(request.context, id, **kwargs) notifier_method = self._resource + '.delete.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, {self._resource + '_id': id}) result = {self._resource: self._view(request.context, obj)} self._send_dhcp_notification(request.context, result, notifier_method)
def notify(create_result): notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.INFO, create_result) return create_result
def delete(self, request, id): """Deletes the specified entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.start', notifier_api.INFO, {self._resource + '_id': id}) action = "delete_%s" % self._resource # Check authz obj = self._item(request, id) try: policy.enforce(request.context, action, obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_deleter = getattr(self._plugin, action) obj_deleter(request.context, id) notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.end', notifier_api.INFO, {self._resource + '_id': id})
def update(self, request, id, body=None): """Updates the specified entity's attributes""" payload = body.copy() payload['id'] = id notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.start', notifier_api.INFO, payload) body = self._prepare_request_body(request.context, body, False) action = "update_%s" % self._resource # Check authz orig_obj = self._item(request, id)[self._resource] try: policy.enforce(request.context, action, orig_obj) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_updater = getattr(self._plugin, action) kwargs = {self._resource: body} obj = obj_updater(request.context, id, **kwargs) result = {self._resource: self._view(obj)} notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.end', notifier_api.INFO, result) return result
def delete(self, request, id): """Deletes the specified entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.start', notifier_api.INFO, {self._resource + '_id': id}) action = "delete_%s" % self._resource # Check authz obj = self._item(request, id)[self._resource] try: policy.enforce(request.context, action, obj) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_deleter = getattr(self._plugin, action) obj_deleter(request.context, id) notifier_api.notify(request.context, self._publisher_id, self._resource + '.delete.end', notifier_api.INFO, {self._resource + '_id': id})
def notify(create_result): notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.CONF.default_notification_level, create_result) return create_result
def notify(create_result): notifier_method = self._resource + '.create.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, create_result) self._send_dhcp_notification(request.context, create_result, notifier_method) return create_result
def update(self, request, id, body=None, **kwargs): """Updates the specified entity's attributes""" parent_id = kwargs.get(self._parent_id_name) try: payload = body.copy() except AttributeError: msg = _("Invalid format: %s") % request.body raise exceptions.BadRequest(resource='body', msg=msg) payload['id'] = id notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.start', notifier_api.CONF.default_notification_level, payload) body = Controller.prepare_request_body(request.context, body, False, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = self._plugin_handlers[self.UPDATE] # Load object to check authz # but pass only attributes in the original body and required # by the policy engine to the policy 'brain' field_list = [ name for (name, value) in self._attr_info.iteritems() if ('required_by_policy' in value and value['required_by_policy'] or 'default' not in value) ] orig_obj = self._item(request, id, field_list=field_list, parent_id=parent_id) orig_obj.update(body[self._resource]) try: policy.enforce(request.context, action, orig_obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_updater = getattr(self._plugin, action) kwargs = {self._resource: body} if parent_id: kwargs[self._parent_id_name] = parent_id obj = obj_updater(request.context, id, **kwargs) result = {self._resource: self._view(obj)} notifier_method = self._resource + '.update.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, result) self._send_dhcp_notification(request.context, result, notifier_method) return result
def update(self, request, id, body=None, **kwargs): """Updates the specified entity's attributes.""" parent_id = kwargs.get(self._parent_id_name) try: payload = body.copy() except AttributeError: msg = _("Invalid format: %s") % request.body raise exceptions.BadRequest(resource='body', msg=msg) payload['id'] = id notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.start', notifier_api.CONF.default_notification_level, payload) body = Controller.prepare_request_body(request.context, body, False, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = self._plugin_handlers[self.UPDATE] # Load object to check authz # but pass only attributes in the original body and required # by the policy engine to the policy 'brain' field_list = [name for (name, value) in self._attr_info.iteritems() if ('required_by_policy' in value and value['required_by_policy'] or 'default' not in value)] orig_obj = self._item(request, id, field_list=field_list, parent_id=parent_id) orig_obj.update(body[self._resource]) try: policy.enforce(request.context, action, orig_obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_updater = getattr(self._plugin, action) kwargs = {self._resource: body} if parent_id: kwargs[self._parent_id_name] = parent_id obj = obj_updater(request.context, id, **kwargs) result = {self._resource: self._view(request.context, obj)} notifier_method = self._resource + '.update.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, result) self._send_dhcp_notification(request.context, result, notifier_method) return result
def create(self, request, body=None): """Creates a new instance of the requested entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.start', notifier_api.INFO, body) body = self._prepare_request_body(request.context, body, True, allow_bulk=True) action = "create_%s" % self._resource # Check authz try: if self._collection in body: # Have to account for bulk create for item in body[self._collection]: self._validate_network_tenant_ownership( request, item[self._resource], ) policy.enforce( request.context, action, item[self._resource], ) count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, item[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} QUOTAS.limit_check(request.context, **kwargs) else: self._validate_network_tenant_ownership( request, body[self._resource] ) policy.enforce(request.context, action, body[self._resource]) count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, body[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} QUOTAS.limit_check(request.context, **kwargs) except exceptions.PolicyNotAuthorized: raise webob.exc.HTTPForbidden() obj_creator = getattr(self._plugin, action) kwargs = {self._resource: body} obj = obj_creator(request.context, **kwargs) result = {self._resource: self._view(obj)} notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.INFO, result) return result
def update(self, request, id, body=None): """Updates the specified entity's attributes""" payload = body.copy() payload['id'] = id notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.start', notifier_api.INFO, payload) body = Controller.prepare_request_body(request.context, body, False, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = "update_%s" % self._resource # Load object to check authz # but pass only attributes in the original body and required # by the policy engine to the policy 'brain' field_list = [ name for (name, value) in self._attr_info.iteritems() if ('required_by_policy' in value and value['required_by_policy'] or not 'default' in value) ] orig_obj = self._item(request, id, field_list=field_list) orig_obj.update(body) try: policy.enforce(request.context, action, orig_obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_updater = getattr(self._plugin, action) kwargs = {self._resource: body} obj = obj_updater(request.context, id, **kwargs) result = {self._resource: self._view(obj)} notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.end', notifier_api.INFO, result) return result
def update(self, request, id, body=None): """Updates the specified entity's attributes""" payload = body.copy() payload['id'] = id notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.start', notifier_api.INFO, payload) body = Controller.prepare_request_body(request.context, body, False, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = "update_%s" % self._resource # Load object to check authz # but pass only attributes in the original body and required # by the policy engine to the policy 'brain' field_list = [name for (name, value) in self._attr_info.iteritems() if ('required_by_policy' in value and value['required_by_policy'] or not 'default' in value)] orig_obj = self._item(request, id, field_list=field_list) orig_obj.update(body) try: policy.enforce(request.context, action, orig_obj, plugin=self._plugin) except exceptions.PolicyNotAuthorized: # To avoid giving away information, pretend that it # doesn't exist raise webob.exc.HTTPNotFound() obj_updater = getattr(self._plugin, action) kwargs = {self._resource: body} obj = obj_updater(request.context, id, **kwargs) result = {self._resource: self._view(obj)} notifier_api.notify(request.context, self._publisher_id, self._resource + '.update.end', notifier_api.INFO, result) return result
def _create_metadata_access_network(self, context, router_id): # This will still ensure atomicity on Quantum DB # context.elevated() creates a deep-copy context ctx_elevated = context.elevated() with ctx_elevated.session.begin(subtransactions=True): # Add network # Network name is likely to be truncated on NVP net_data = {'name': ('meta-%s' % router_id)[:40], 'tenant_id': '', # intentionally not set 'admin_state_up': True, 'port_security_enabled': False, 'shared': False, 'status': constants.NET_STATUS_ACTIVE} meta_net = self.create_network(ctx_elevated, {'network': net_data}) # Add subnet subnet_data = {'network_id': meta_net['id'], 'tenant_id': '', # intentionally not set 'name': 'meta-%s' % router_id, 'ip_version': 4, 'shared': False, 'cidr': METADATA_SUBNET_CIDR, 'enable_dhcp': True, # Ensure default allocation pool is generated 'allocation_pools': attributes.ATTR_NOT_SPECIFIED, 'gateway_ip': METADATA_GATEWAY_IP, 'dns_nameservers': [], 'host_routes': []} meta_sub = self.create_subnet(ctx_elevated, {'subnet': subnet_data}) self.add_router_interface(ctx_elevated, router_id, {'subnet_id': meta_sub['id']}) # We need to send a notification to the dhcp agent in order # to start the metadata agent proxy # Note: the publisher id is the same used in the api module notifier_api.notify(context, notifier_api.publisher_id('network'), 'network.create.end', notifier_api.CONF.default_notification_level, {'network': meta_net})
def _destroy_metadata_access_network(self, context, router_id, ports): # context.elevated() creates a deep-copy context ctx_elevated = context.elevated() # This will still ensure atomicity on Quantum DB with ctx_elevated.session.begin(subtransactions=True): if ports: meta_port = self._find_metadata_port(ctx_elevated, ports) if not meta_port: return meta_net_id = meta_port['network_id'] self.remove_router_interface( ctx_elevated, router_id, {'port_id': meta_port['id']}) # Remove network (this will remove the subnet too) self.delete_network(ctx_elevated, meta_net_id) # We need to send a notification to the dhcp agent in order # to stop the metadata agent proxy # Note: the publisher id is the same used in the api module notifier_api.notify( context, notifier_api.publisher_id('network'), 'network.delete.end', notifier_api.CONF.default_notification_level, {'network_id': meta_net_id})
def add_router_interface(self, context, router_id, interface_info): # make sure router exists router = self._get_router(context, router_id) if not interface_info: msg = _("Either subnet_id or port_id must be specified") raise q_exc.BadRequest(resource="router", msg=msg) try: policy.enforce(context, "extension:router:add_router_interface", self._make_router_dict(router)) except q_exc.PolicyNotAuthorized: raise l3.RouterNotFound(router_id=router_id) if "port_id" in interface_info: 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": "", } }, ) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, "add_router_interface", {"network_id": port["network_id"], "subnet_id": subnet_id} ) info = {"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(self, request, body=None): """Creates a new instance of the requested entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.start', notifier_api.INFO, body) body = Controller.prepare_request_body(request.context, body, True, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = "create_%s" % self._resource # Check authz try: if self._collection in body: # Have to account for bulk create for item in body[self._collection]: self._validate_network_tenant_ownership( request, item[self._resource], ) policy.enforce(request.context, action, item[self._resource], plugin=self._plugin) try: count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, item[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) except Exception: raise else: QUOTAS.limit_check(request.context, item[self._resource]['tenant_id'], **kwargs) else: self._validate_network_tenant_ownership( request, body[self._resource] ) policy.enforce(request.context, action, body[self._resource], plugin=self._plugin) try: count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, body[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) except Exception: raise else: QUOTAS.limit_check(request.context, body[self._resource]['tenant_id'], **kwargs) except exceptions.PolicyNotAuthorized: LOG.exception("Create operation not authorized") raise webob.exc.HTTPForbidden() def notify(create_result): notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.INFO, create_result) return create_result if self._collection in body and self._native_bulk: # plugin does atomic bulk create operations obj_creator = getattr(self._plugin, "%s_bulk" % action) objs = obj_creator(request.context, body) return notify({self._collection: [self._view(obj) for obj in objs]}) else: obj_creator = getattr(self._plugin, action) if self._collection in body: # Emulate atomic bulk behavior objs = self._emulate_bulk_create(obj_creator, request, body) return notify({self._collection: objs}) else: kwargs = {self._resource: body} obj = obj_creator(request.context, **kwargs) return notify({self._resource: self._view(obj)})
def create(self, request, body=None, **kwargs): """Creates a new instance of the requested entity""" parent_id = kwargs.get(self._parent_id_name) notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.start', notifier_api.INFO, body) body = Controller.prepare_request_body(request.context, body, True, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = self._plugin_handlers[self.CREATE] # Check authz if self._collection in body: # Have to account for bulk create items = body[self._collection] deltas = {} bulk = True else: items = [body] bulk = False for item in items: self._validate_network_tenant_ownership(request, item[self._resource]) policy.enforce(request.context, action, item[self._resource], plugin=self._plugin) try: tenant_id = item[self._resource]['tenant_id'] count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, tenant_id) if bulk: delta = deltas.get(tenant_id, 0) + 1 deltas[tenant_id] = delta else: delta = 1 kwargs = {self._resource: count + delta} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) else: QUOTAS.limit_check(request.context, item[self._resource]['tenant_id'], **kwargs) def notify(create_result): notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.INFO, create_result) return create_result kwargs = {self._parent_id_name: parent_id} if parent_id else {} if self._collection in body and self._native_bulk: # plugin does atomic bulk create operations obj_creator = getattr(self._plugin, "%s_bulk" % action) objs = obj_creator(request.context, body, **kwargs) return notify({self._collection: [self._view(obj) for obj in objs]}) else: obj_creator = getattr(self._plugin, action) if self._collection in body: # Emulate atomic bulk behavior objs = self._emulate_bulk_create(obj_creator, request, body, parent_id) return notify({self._collection: objs}) else: kwargs.update({self._resource: body}) obj = obj_creator(request.context, **kwargs) return notify({self._resource: self._view(obj)})
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._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._get_subnet(context, subnet_id) self._confirm_router_interface_not_in_use(context, router_id, subnet_id) _network_id = port_db['network_id'] self.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._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'] _network_id = p['network_id'] self.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) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, 'remove_router_interface', { 'network_id': _network_id, 'subnet_id': subnet_id }) 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: 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': '' } }) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, 'add_router_interface', { 'network_id': port['network_id'], 'subnet_id': subnet_id }) 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(self, request, body=None, **kwargs): """Creates a new instance of the requested entity""" parent_id = kwargs.get(self._parent_id_name) notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.start', notifier_api.CONF.default_notification_level, body) body = Controller.prepare_request_body(request.context, body, True, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = self._plugin_handlers[self.CREATE] # Check authz if self._collection in body: # Have to account for bulk create items = body[self._collection] deltas = {} bulk = True else: items = [body] bulk = False for item in items: self._validate_network_tenant_ownership(request, item[self._resource]) policy.enforce(request.context, action, item[self._resource], plugin=self._plugin) try: tenant_id = item[self._resource]['tenant_id'] count = quota.QUOTAS.count(request.context, self._resource, self._plugin, self._collection, tenant_id) if bulk: delta = deltas.get(tenant_id, 0) + 1 deltas[tenant_id] = delta else: delta = 1 kwargs = {self._resource: count + delta} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) else: quota.QUOTAS.limit_check(request.context, item[self._resource]['tenant_id'], **kwargs) def notify(create_result): notifier_method = self._resource + '.create.end' notifier_api.notify(request.context, self._publisher_id, notifier_method, notifier_api.CONF.default_notification_level, create_result) self._send_dhcp_notification(request.context, create_result, notifier_method) return create_result kwargs = {self._parent_id_name: parent_id} if parent_id else {} if self._collection in body and self._native_bulk: # plugin does atomic bulk create operations obj_creator = getattr(self._plugin, "%s_bulk" % action) objs = obj_creator(request.context, body, **kwargs) return notify( {self._collection: [self._view(obj) for obj in objs]}) else: obj_creator = getattr(self._plugin, action) if self._collection in body: # Emulate atomic bulk behavior objs = self._emulate_bulk_create(obj_creator, request, body, parent_id) return notify({self._collection: objs}) else: kwargs.update({self._resource: body}) obj = obj_creator(request.context, **kwargs) return notify({self._resource: self._view(obj)})
def create(self, request, body=None): """Creates a new instance of the requested entity""" notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.start', notifier_api.INFO, body) body = Controller.prepare_request_body(request.context, body, True, self._resource, self._attr_info, allow_bulk=self._allow_bulk) action = "create_%s" % self._resource # Check authz try: if self._collection in body: # Have to account for bulk create for item in body[self._collection]: self._validate_network_tenant_ownership( request, item[self._resource], ) policy.enforce(request.context, action, item[self._resource], plugin=self._plugin) try: count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, item[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) except Exception: raise else: QUOTAS.limit_check(request.context, item[self._resource]['tenant_id'], **kwargs) else: self._validate_network_tenant_ownership( request, body[self._resource] ) policy.enforce(request.context, action, body[self._resource], plugin=self._plugin) try: count = QUOTAS.count(request.context, self._resource, self._plugin, self._collection, body[self._resource]['tenant_id']) kwargs = {self._resource: count + 1} except exceptions.QuotaResourceUnknown as e: # We don't want to quota this resource LOG.debug(e) except Exception: raise else: QUOTAS.limit_check(request.context, body[self._resource]['tenant_id'], **kwargs) except exceptions.PolicyNotAuthorized: LOG.exception(_("Create operation not authorized")) raise webob.exc.HTTPForbidden() def notify(create_result): notifier_api.notify(request.context, self._publisher_id, self._resource + '.create.end', notifier_api.INFO, create_result) return create_result if self._collection in body and self._native_bulk: # plugin does atomic bulk create operations obj_creator = getattr(self._plugin, "%s_bulk" % action) objs = obj_creator(request.context, body) return notify({self._collection: [self._view(obj) for obj in objs]}) else: obj_creator = getattr(self._plugin, action) if self._collection in body: # Emulate atomic bulk behavior objs = self._emulate_bulk_create(obj_creator, request, body) return notify({self._collection: objs}) else: kwargs = {self._resource: body} obj = obj_creator(request.context, **kwargs) return notify({self._resource: self._view(obj)})
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._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._get_subnet(context, subnet_id) self._confirm_router_interface_not_in_use( context, router_id, subnet_id) _network_id = port_db['network_id'] self.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._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']).all() for p in ports: if p['fixed_ips'][0]['subnet_id'] == subnet_id: port_id = p['id'] _network_id = p['network_id'] self.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) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, 'remove_router_interface', {'network_id': _network_id, 'subnet_id': subnet_id}) 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})
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: 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': ''}}) routers = self.get_sync_data(context.elevated(), [router_id]) l3_rpc_agent_api.L3AgentNotify.routers_updated( context, routers, 'add_router_interface', {'network_id': port['network_id'], 'subnet_id': subnet_id}) 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