def test_dvr_port_binding_deleted_by_port_deletion(self): with self.ctx.session.begin(subtransactions=True): self.ctx.session.add(models_v2.Network(id="network_id")) device_owner = constants.DEVICE_OWNER_DVR_INTERFACE port = models_v2.Port( id="port_id", network_id="network_id", mac_address="00:11:22:33:44:55", admin_state_up=True, status=constants.PORT_STATUS_ACTIVE, device_id="device_id", device_owner=device_owner, ) self.ctx.session.add(port) binding_kwarg = { "port_id": "port_id", "host": "host", "vif_type": portbindings.VIF_TYPE_UNBOUND, "vnic_type": portbindings.VNIC_NORMAL, "router_id": "router_id", "status": constants.PORT_STATUS_DOWN, } self.ctx.session.add(models.DVRPortBinding(**binding_kwarg)) binding_kwarg["host"] = "another-host" self.ctx.session.add(models.DVRPortBinding(**binding_kwarg)) with warnings.catch_warnings(record=True) as warning_list: with self.ctx.session.begin(subtransactions=True): self.ctx.session.delete(port) self.assertEqual([], warning_list) ports = ml2_db.get_dvr_port_bindings(self.ctx.session, "port_id") self.assertEqual(0, len(ports))
def test_dvr_port_binding_deleted_by_port_deletion(self): with self.ctx.session.begin(subtransactions=True): self.ctx.session.add(models_v2.Network(id='network_id')) device_owner = constants.DEVICE_OWNER_DVR_INTERFACE port = models_v2.Port( id='port_id', network_id='network_id', mac_address='00:11:22:33:44:55', admin_state_up=True, status=constants.PORT_STATUS_ACTIVE, device_id='device_id', device_owner=device_owner) self.ctx.session.add(port) binding_kwarg = { 'port_id': 'port_id', 'host': 'host', 'vif_type': portbindings.VIF_TYPE_UNBOUND, 'vnic_type': portbindings.VNIC_NORMAL, 'router_id': 'router_id', 'status': constants.PORT_STATUS_DOWN } self.ctx.session.add(models.DVRPortBinding(**binding_kwarg)) binding_kwarg['host'] = 'another-host' self.ctx.session.add(models.DVRPortBinding(**binding_kwarg)) with warnings.catch_warnings(record=True) as warning_list: with self.ctx.session.begin(subtransactions=True): self.ctx.session.delete(port) self.assertEqual([], warning_list) ports = ml2_db.get_dvr_port_bindings(self.ctx.session, 'port_id') self.assertEqual(0, len(ports))
def test_get_dvr_port_bindings(self): network_id = "foo_network_id" port_id_1 = "foo_port_id_1" port_id_2 = "foo_port_id_2" self._setup_neutron_network(network_id, [port_id_1, port_id_2]) router = self._setup_neutron_router() self._setup_dvr_binding(network_id, port_id_1, router.id, "foo_host_id_1") self._setup_dvr_binding(network_id, port_id_1, router.id, "foo_host_id_2") ports = ml2_db.get_dvr_port_bindings(self.ctx.session, "foo_port_id") self.assertEqual(2, len(ports))
def test_get_dvr_port_bindings(self): network_id = 'foo_network_id' port_id_1 = 'foo_port_id_1' port_id_2 = 'foo_port_id_2' self._setup_neutron_network(network_id, [port_id_1, port_id_2]) router = self._setup_neutron_router() self._setup_dvr_binding( network_id, port_id_1, router.id, 'foo_host_id_1') self._setup_dvr_binding( network_id, port_id_1, router.id, 'foo_host_id_2') ports = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id') self.assertEqual(2, len(ports))
def port_bound_to_host(self, context, port_id, host): try: port = self.get_port(context, port_id) if port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE: bindings = db.get_dvr_port_bindings(port_id) for b in bindings: if b.host == host: return True LOG.debug("No Binding exists for port %s", port_id) return False else: port_host = db.get_port_binding_host(port_id) return (port_host == host) except exc.PortNotFound: LOG.debug("Port not found %s", port_id) return False
def test_get_dvr_port_bindings_not_found(self): port = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id') self.assertFalse(len(port))
def delete_port(self, context, id, l3_port_check=True): LOG.debug(_("Deleting port %s"), id) l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) if l3plugin and l3_port_check: l3plugin.prevent_l3_port_deletion(context, id) session = context.session mech_context = None # REVISIT: Serialize this operation with a semaphore to prevent # undesired eventlet yields leading to 'lock wait timeout' errors with contextlib.nested(lockutils.lock('db-access'), session.begin(subtransactions=True)): try: port_db = (session.query(models_v2.Port). enable_eagerloads(False). filter_by(id=id).with_lockmode('update').one()) except sa_exc.NoResultFound: # the port existed when l3plugin.prevent_l3_port_deletion # was called but now is already gone LOG.debug(_("The port '%s' was deleted"), id) return port = self._make_port_dict(port_db) network = self.get_network(context, port['network_id']) if port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE: bindings = db.get_dvr_port_bindings(id) for bind in bindings: mech_context = driver_context.PortContext(self, context, port, network, binding=bind) self.mechanism_manager.delete_port_precommit(mech_context) LOG.debug("Calling base delete_port %s for DVR", id) super(Ml2Plugin, self).delete_port(context, id) else: mech_context = driver_context.PortContext(self, context, port, network) if "compute:" in port['device_owner']: self.dvr_deletens_ifnovm(context, id) self.mechanism_manager.delete_port_precommit(mech_context) self._delete_port_security_group_bindings(context, id) LOG.debug(_("Calling base delete_port")) if l3plugin: l3plugin.disassociate_floatingips(context, id) super(Ml2Plugin, self).delete_port(context, id) try: # for both normal and DVR Interface ports, only one invocation of # delete_port_postcommit if mech_context: self.mechanism_manager.delete_port_postcommit(mech_context) else: LOG.error(_("Unable to invoke delete_port_postcommit," " mech_context NULL for port %s"), id) except ml2_exc.MechanismDriverError: # TODO(apech) - One or more mechanism driver failed to # delete the port. Ideally we'd notify the caller of the # fact that an error occurred. LOG.error(_("mechanism_manager.delete_port_postcommit failed for" " port %s"), id) self.notify_security_groups_member_updated(context, port)