def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): """ Provides connectivity to a remote interface to the specified Virtual Network. """ LOG.debug("plug_interface() called\n") network = db.network_get(net_id) port = db.port_get(net_id, port_id) attachment_id = port[const.INTERFACEID] if attachment_id is None: raise cexc.InvalidAttach(port_id=port_id, net_id=net_id, att_id=remote_interface_id) attachment_id = attachment_id[:const.UUID_LENGTH] remote_interface_id = remote_interface_id[:const.UUID_LENGTH] if remote_interface_id != attachment_id: LOG.debug("Existing attachment_id:%s, remote_interface_id:%s" % \ (attachment_id, remote_interface_id)) raise exc.PortInUse(port_id=port_id, net_id=net_id, att_id=attachment_id) self._invoke_device_plugins(self._func_name(), [tenant_id, net_id, port_id, attachment_id]) db.port_unset_attachment(net_id, port_id) db.port_set_attachment(net_id, port_id, attachment_id)
def port_set_attachment(port_id, net_id, new_interface_id): # confirm network exists network_get(net_id) session = get_session() port = port_get(port_id, net_id) if new_interface_id != "": # We are setting, not clearing, the attachment-id if port['interface_id']: raise q_exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) try: port = session.query(models.Port).\ filter_by(interface_id=new_interface_id).\ one() raise q_exc.AlreadyAttached(net_id=net_id, port_id=port_id, att_id=new_interface_id, att_port_id=port['uuid']) except exc.NoResultFound: # this is what should happen pass port.interface_id = new_interface_id session.merge(port) session.flush() return port
def delete_port(self, tenant_id, net_id, port_id): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, the remote interface is first un-plugged and then the port is deleted. :returns: a mapping sequence with the following signature: {'port-id': uuid representing the deleted port on specified quantum network } :raises: exception.PortInUse :raises: exception.PortNotFound :raises: exception.NetworkNotFound """ LOG.debug("QuantumRestProxy: delete_port() called") net = self.get_network(tenant_id, net_id) port = self.get_port(tenant_id, net_id, port_id) if port['interface_id']: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) # Delete from DB try: port = db.port_destroy(port_id, net_id) except Exception, e: raise Exception("Failed to delete port: %s" % str(e))
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): """ Attaches a remote interface to the specified port on the specified Virtual Network. :returns: None :raises: exception.NetworkNotFound :raises: exception.PortNotFound :raises: exception.AlreadyAttached (? should the network automatically unplug/replug) """ LOG.debug("QuantumRestProxy: plug_interface() called") port = self.get_port(tenant_id, net_id, port_id) self.validate_attachment(tenant_id, net_id, port_id, remote_interface_id) if port['interface_id']: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) # Update DB db.port_set_attachment(port_id, net_id, remote_interface_id) # update attachment on network controller try: net_name = self.get_network(tenant_id, net_id).name gateway = self.nova.get_gateway(net_id) mac = self.nova.get_mac(remote_interface_id) if gateway is not None: resource = '/tenants/%s/networks/%s' % ( tenant_id, net_id) data = { "network": { "id": net_id, "gateway": gateway, "name": net_name, } } ret = self.servers.put(resource, data) if not self.servers.action_success(ret): raise RemoteRestError(ret[2]) if mac is not None: resource = '/tenants/%s/networks/%s/ports/%s/attachment' % ( tenant_id, net_id, port_id) data = {"attachment": { "id": remote_interface_id, "mac": mac, }} ret = self.servers.put(resource, data) if not self.servers.action_success(ret): raise RemoteRestError(ret[2]) except RemoteRestError as e: LOG.error( 'QuantumRestProxy: Unable to update remote network: %s' % e.message) # undo the connect db.port_unset_attachment(port_id, net_id) raise
def add_router_interface(self, context, router_id, interface_info): # make sure router exists - will raise if not 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) 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) self._check_for_dup_router_subnet(context, router_id, port['network_id'], fixed_ips[0]['subnet_id']) with context.session.begin(subtransactions=True): 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) fixed_ip = { 'ip_address': subnet['gateway_ip'], 'subnet_id': subnet['id'] } port = self.create_port( context, { 'port': { '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': '' } }) return { 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id'] }
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): """ Attaches a remote interface to the specified port on the specified Virtual Network. """ LOG.debug("FakePlugin.plug_interface() called") port = self._get_port(tenant_id, net_id, port_id) # Validate attachment self._validate_attachment(tenant_id, net_id, port_id, remote_interface_id) if port['interface_id']: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) db.port_set_attachment(port_id, net_id, remote_interface_id)
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): """ Attaches a remote interface to the specified port on the specified Virtual Network. """ LOG.debug("LinuxBridgePlugin.plug_interface() called") db.validate_port_ownership(tenant_id, net_id, port_id) port = db.port_get(port_id, net_id) attachment_id = port[const.INTERFACEID] if attachment_id: raise exc.PortInUse(port_id=port_id, net_id=net_id, att_id=attachment_id) db.port_set_attachment(port_id, net_id, remote_interface_id)
def delete_port(self, tenant_id, net_id, port_id): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, the remote interface is first un-plugged and then the port is deleted. """ LOG.debug("FakePlugin.delete_port() called") net = self._get_network(tenant_id, net_id) port = self._get_port(tenant_id, net_id, port_id) if port['interface_id']: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) try: port = db.port_destroy(port_id, net_id) except Exception, e: raise Exception("Failed to delete port: %s" % str(e))
def port_destroy(net_id, port_id): # confirm network exists network_get(net_id) session = get_session() try: port = (session.query(models.Port).filter_by(uuid=port_id).filter_by( network_id=net_id).one()) if port['interface_id']: raise q_exc.PortInUse(net_id=net_id, port_id=port_id, device_id=port['interface_id']) session.delete(port) session.flush() return port except exc.NoResultFound: raise q_exc.PortNotFound(port_id=port_id)
def delete_port(self, tenant_id, net_id, port_id): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, the remote interface is first un-plugged and then the port is deleted. """ LOG.debug("LinuxBridgePlugin.delete_port() called") db.validate_port_ownership(tenant_id, net_id, port_id) port = db.port_get(port_id, net_id) attachment_id = port[const.INTERFACEID] if not attachment_id: db.port_destroy(port_id, net_id) new_port_dict = cutil.make_port_dict(port) return new_port_dict else: raise exc.PortInUse(port_id=port_id, net_id=net_id, att_id=attachment_id)
def port_set_attachment_by_id(port_id, new_interface_id): session = get_session() port = port_get_by_id(port_id) if new_interface_id != "": if port['interface_id']: raise q_exc.PortInUse(port_id=port_id, att_id=port['interface_id']) try: port = session.query( models.Port).filter_by(interface_id=new_interface_id).one() raise q_exc.AlreadyAttached(port_id=port_id, att_id=new_interface_id, att_port_id=port['uuid']) except exc.NoResultFound: pass port.interface_id = new_interface_id session.merge(port) session.flush() return port
def delete_port(self, tenant_id, net_id, port_id): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, the remote interface should first be un-plugged and then the port can be deleted. """ LOG.debug("delete_port() called\n") network = db.network_get(net_id) port = db.port_get(net_id, port_id) attachment_id = port[const.INTERFACEID] if not attachment_id: self._invoke_device_plugins(self._func_name(), [tenant_id, net_id, port_id]) db.port_destroy(net_id, port_id) new_port_dict = cutil.make_port_dict(port_id, None, None, None) return new_port_dict else: raise exc.PortInUse(port_id=port_id, net_id=net_id, att_id=attachment_id)
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 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) self._check_for_dup_router_subnet(context, router_id, port['network_id'], fixed_ips[0]['subnet_id']) 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) 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.L3AgentNofity.routers_updated(context, routers) return { 'port_id': port['id'], 'subnet_id': port['fixed_ips'][0]['subnet_id'] }