def delete_trunk(self, context, trunk_id): """Delete the trunk port.""" LOG.debug("Deleting trunk_id %s", trunk_id) deleted_from_db = False with neutron_db_api.context_manager.writer.using(context): trunk = self._get_trunk(context, trunk_id) rules.trunk_can_be_managed(context, trunk) trunk_port_validator = rules.TrunkPortValidator(trunk.port_id) if not trunk_port_validator.is_bound(context): trunk.delete() deleted_from_db = True payload = callbacks.TrunkPayload(context, trunk_id, original_trunk=trunk) registry.notify(trunk_const.TRUNK, events.PRECOMMIT_DELETE, self, payload=payload) else: raise trunk_exc.TrunkInUse(trunk_id=trunk_id) if deleted_from_db: registry.notify(trunk_const.TRUNK, events.AFTER_DELETE, self, payload=payload)
def create_trunk(self, context, trunk): """Create a trunk object.""" LOG.debug("Creating trunk %s", trunk) trunk = self.validate_trunk(context, trunk['trunk']) sub_ports = [trunk_objects.SubPort( context=context, port_id=p['port_id'], segmentation_id=p['segmentation_id'], segmentation_type=p['segmentation_type']) for p in trunk['sub_ports']] trunk_obj = trunk_objects.Trunk( context=context, admin_state_up=trunk.get('admin_state_up', True), id=uuidutils.generate_uuid(), name=trunk.get('name', ""), description=trunk.get('description', ""), project_id=trunk['tenant_id'], port_id=trunk['port_id'], # Trunk will turn active only after it has been bound on a host status=trunk_const.DOWN_STATUS, sub_ports=sub_ports) with neutron_db_api.context_manager.writer.using(context): trunk_obj.create() payload = callbacks.TrunkPayload(context, trunk_obj.id, current_trunk=trunk_obj) registry.notify(trunk_const.TRUNK, events.PRECOMMIT_CREATE, self, payload=payload) registry.notify(trunk_const.TRUNK, events.AFTER_CREATE, self, payload=payload) return trunk_obj
def __init__(self): super(VppTrunkPlugin, self).__init__() self.communicator = EtcdAgentCommunicator( notify_bound=lambda *args: None) # Supported segmentation type is VLAN self._segmentation_types = { trunk_const.VLAN: plugin_utils.is_valid_vlan_tag } # Subscribe to trunk parent-port binding events # We use this event to trigger the etcd trunk key update. registry.subscribe(self._trigger_etcd_trunk_update, resources.PORT, events.AFTER_UPDATE) registry.notify(trunk_const.TRUNK_PLUGIN, events.AFTER_INIT, self) LOG.debug('vpp-trunk: vpp trunk service plugin has initialized')
def remove_subports(self, context, trunk_id, subports): """Remove one or more subports from the trunk.""" LOG.debug("Removing subports %s from trunk %s", subports, trunk_id) trunk = self._get_trunk(context, trunk_id) original_trunk = copy.deepcopy(trunk) subports = subports['sub_ports'] subports = self.validate_subports(context, subports, trunk, basic_validation=True, trunk_validation=False) removed_subports = [] rules.trunk_can_be_managed(context, trunk) # The trunk should not be in the ERROR_STATUS if trunk.status == trunk_const.ERROR_STATUS: raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id) else: # The trunk will transition to DOWN and subsequently to ACTIVE # when a subport is removed. trunk.update(status=trunk_const.DOWN_STATUS) current_subports = {p.port_id: p for p in trunk.sub_ports} # Ensure that all sub-ports to be removed are actually present for subport in subports: if subport['port_id'] not in current_subports: raise trunk_exc.SubPortNotFound(trunk_id=trunk_id, port_id=subport['port_id']) with neutron_db_api.context_manager.writer.using(context): for subport in subports: subport_obj = current_subports.pop(subport['port_id']) subport_obj.delete() removed_subports.append(subport_obj) if removed_subports: del trunk.sub_ports[:] trunk.sub_ports.extend(current_subports.values()) payload = callbacks.TrunkPayload(context, trunk_id, current_trunk=trunk, original_trunk=original_trunk, subports=removed_subports) registry.notify(trunk_const.SUBPORTS, events.PRECOMMIT_DELETE, self, payload=payload) self.send_subport_update_to_etcd(context, trunk) if removed_subports: registry.notify(trunk_const.SUBPORTS, events.AFTER_DELETE, self, payload=payload) return trunk
def remove_subports(self, context, trunk_id, subports): """Remove one or more subports from the trunk.""" LOG.debug("Removing subports %s from trunk %s", subports, trunk_id) trunk = self._get_trunk(context, trunk_id) original_trunk = copy.deepcopy(trunk) subports = subports['sub_ports'] subports = self.validate_subports(context, subports, trunk, basic_validation=True, trunk_validation=False) removed_subports = [] rules.trunk_can_be_managed(context, trunk) # The trunk should not be in the ERROR_STATUS if trunk.status == trunk_const.ERROR_STATUS: raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id) else: # The trunk will transition to DOWN and subsequently to ACTIVE # when a subport is removed. trunk.update(status=trunk_const.DOWN_STATUS) current_subports = {p.port_id: p for p in trunk.sub_ports} # Ensure that all sub-ports to be removed are actually present for subport in subports: if subport['port_id'] not in current_subports: raise trunk_exc.SubPortNotFound(trunk_id=trunk_id, port_id=subport['port_id']) with neutron_db_api.context_manager.writer.using(context): for subport in subports: subport_obj = current_subports.pop(subport['port_id']) subport_obj.delete() removed_subports.append(subport_obj) if removed_subports: del trunk.sub_ports[:] trunk.sub_ports.extend(current_subports.values()) payload = callbacks.TrunkPayload( context, trunk_id, current_trunk=trunk, original_trunk=original_trunk, subports=removed_subports ) registry.notify(trunk_const.SUBPORTS, events.PRECOMMIT_DELETE, self, payload=payload) self.send_subport_update_to_etcd(context, trunk) if removed_subports: registry.notify(trunk_const.SUBPORTS, events.AFTER_DELETE, self, payload=payload) return trunk
def add_subports(self, context, trunk_id, subports): """Add one or more subports to a trunk.""" LOG.debug("Adding subports %s to trunk %s", subports, trunk_id) trunk = self._get_trunk(context, trunk_id) subports = subports['sub_ports'] subports = self.validate_subports(context, subports, trunk, basic_validation=True) added_subports = [] rules.trunk_can_be_managed(context, trunk) original_trunk = copy.deepcopy(trunk) # The trunk should not be in the ERROR_STATUS if trunk.status == trunk_const.ERROR_STATUS: raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id) else: # The trunk will transition to DOWN and subsequently to ACTIVE # when a subport is added. trunk.update(status=trunk_const.DOWN_STATUS) with neutron_db_api.context_manager.writer.using(context): for subport in subports: subport_obj = trunk_objects.SubPort( context=context, trunk_id=trunk_id, port_id=subport['port_id'], segmentation_type=subport['segmentation_type'], segmentation_id=subport['segmentation_id']) subport_obj.create() trunk['sub_ports'].append(subport_obj) added_subports.append(subport_obj) payload = callbacks.TrunkPayload(context, trunk_id, current_trunk=trunk, original_trunk=original_trunk, subports=added_subports) if added_subports: registry.notify(trunk_const.SUBPORTS, events.PRECOMMIT_CREATE, self, payload=payload) self.send_subport_update_to_etcd(context, trunk) if added_subports: registry.notify(trunk_const.SUBPORTS, events.AFTER_CREATE, self, payload=payload) return trunk
def update_trunk(self, context, trunk_id, trunk): """Update the trunk object.""" LOG.debug("Updating trunk %s trunk_id %s", trunk, trunk_id) trunk_data = trunk['trunk'] with neutron_db_api.context_manager.writer.using(context): trunk_obj = self._get_trunk(context, trunk_id) original_trunk = copy.deepcopy(trunk_obj) trunk_obj.update_fields(trunk_data, reset_changes=True) trunk_obj.update() payload = callbacks.TrunkPayload(context, trunk_id, original_trunk=original_trunk, current_trunk=trunk_obj) registry.notify(trunk_const.TRUNK, events.PRECOMMIT_UPDATE, self, payload=payload) registry.notify(trunk_const.TRUNK, events.AFTER_UPDATE, self, payload=payload) return trunk_obj
def create_trunk(self, context, trunk): """Create a trunk object.""" LOG.debug("Creating trunk %s", trunk) trunk = self.validate_trunk(context, trunk['trunk']) sub_ports = [ trunk_objects.SubPort(context=context, port_id=p['port_id'], segmentation_id=p['segmentation_id'], segmentation_type=p['segmentation_type']) for p in trunk['sub_ports'] ] trunk_obj = trunk_objects.Trunk( context=context, admin_state_up=trunk.get('admin_state_up', True), id=uuidutils.generate_uuid(), name=trunk.get('name', ""), description=trunk.get('description', ""), project_id=trunk['tenant_id'], port_id=trunk['port_id'], # Trunk will turn active only after it has been bound on a host status=trunk_const.DOWN_STATUS, sub_ports=sub_ports) with neutron_db_api.context_manager.writer.using(context): trunk_obj.create() payload = callbacks.TrunkPayload(context, trunk_obj.id, current_trunk=trunk_obj) registry.notify(trunk_const.TRUNK, events.PRECOMMIT_CREATE, self, payload=payload) registry.notify(trunk_const.TRUNK, events.AFTER_CREATE, self, payload=payload) return trunk_obj