def _update_port_at_backend(self, context, port_id, switching_profile, delete_profile): """Update a logical port on the backend.""" port = self._get_port_details(context._plugin_context, port_id) # Retrieve logical port ID based on neutron port ID. nsx_port_id = nsx_db.get_nsx_switch_and_port_id( session=context._plugin_context.session, neutron_id=port_id)[1] # Retrieve source logical port from the backend. nsx_port = self._nsx_plugin._port_client.get(nsx_port_id) if delete_profile: # Prepare switching profile resources retrieved from backend # and pop the port mirror switching profile. switching_profile_ids = self._prepare_switch_profiles( nsx_port.get('switching_profile_ids', []), switching_profile) else: # Prepare switching profile resources retrieved from backend. switching_profile_ids = self._prepare_switch_profiles( nsx_port.get('switching_profile_ids', [])) # Update body with PortMirroring switching profile. switching_profile_ids.append( self._get_switching_profile_resource( switching_profile['id'], nsx_resources.SwitchingProfileTypes.PORT_MIRRORING)) address_bindings = self._nsx_plugin._build_address_bindings(port) #NOTE(abhiraut): Consider passing attachment_type self._nsx_plugin._port_client.update( lport_id=nsx_port.get('id'), vif_uuid=port_id, name=nsx_port.get('display_name'), admin_state=nsx_port.get('admin_state'), address_bindings=address_bindings, switch_profile_ids=switching_profile_ids, )
def update_router_firewall(self, context, nsxlib, router_id, router_interfaces, nsx_router_id, section_id): """Rewrite all the FWaaS v2 rules in the router edge firewall This method should be called on FWaaS updates, and on router interfaces changes. """ fw_rules = [] # Add firewall rules per port attached to a firewall group for port in router_interfaces: nsx_ls_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id( context.session, port['id']) # Check if this port has a firewall fwg = self.get_port_fwg(context, port['id']) if fwg: # Add plugin additional allow rules plugin_rules = self.core_plugin.get_extra_fw_rules( context, router_id, port['id']) # add the FWaaS rules for this port # ingress/egress firewall rules + default ingress/egress drop # rule for this port fw_rules.extend(self.get_port_rules(nsx_ls_id, fwg, plugin_rules)) # add a default allow-all rule to all other traffic & ports fw_rules.append(self.internal_driver.get_default_backend_rule( section_id, allow_all=True)) # update the backend router firewall nsxlib.firewall_section.update(section_id, rules=fw_rules)
def _tag_port(self, context, port_id, tag): # Translate neutron port id to nsx port id _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id( context._plugin_context.session, port_id) self.nsx_port.update(nsx_port_id, None, tags_update=[{'scope': 'gbp', 'tag': tag}])
def _update_port_at_backend(self, context, parent_port_id, subport): # Retrieve the child port details child_port = self.plugin_driver.get_port(context, subport.port_id) # Retrieve the logical port ID based on the child port's neutron ID nsx_child_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=subport.port_id)[1] # Retrieve child logical port from the backend try: nsx_child_port = self._nsxlib.logical_port.get(nsx_child_port_id) except nsxlib_exc.ResourceNotFound: with excutils.save_and_reraise_exception(): LOG.error( "Child port %s not found on the backend. " "Setting trunk status to ERROR.", nsx_child_port_id) # Build address bindings and switch profiles otherwise backend will # clear that information during port update address_bindings = self.plugin_driver._build_address_bindings( child_port) switching_profile_ids = self._build_switching_profile_ids( nsx_child_port.get('switching_profile_ids', [])) seg_id = None tags_update = [] attachment_type = nsx_constants.ATTACHMENT_VIF if parent_port_id: # Set properties for VLAN trunking if subport.segmentation_type == nsx_utils.NsxV3NetworkTypes.VLAN: seg_id = subport.segmentation_id tags_update.append({ 'scope': 'os-neutron-trunk-id', 'tag': subport.trunk_id }) vif_type = nsx_constants.VIF_TYPE_CHILD else: # Unset the parent port properties from child port seg_id = None vif_type = None tags_update.append({'scope': 'os-neutron-trunk-id', 'tag': None}) # Update logical port in the backend to set/unset parent port try: self._nsxlib.logical_port.update( lport_id=nsx_child_port.get('id'), vif_uuid=subport.port_id, name=nsx_child_port.get('display_name'), admin_state=nsx_child_port.get('admin_state'), address_bindings=address_bindings, switch_profile_ids=switching_profile_ids, attachment_type=attachment_type, parent_vif_id=parent_port_id, vif_type=vif_type, traffic_tag=seg_id, tags_update=tags_update) except nsxlib_exc.ManagerError as e: with excutils.save_and_reraise_exception(): LOG.error( "Unable to update subport for attachment " "type. Setting trunk status to ERROR. " "Exception is %s", e)
def _update_port_at_backend(self, context, parent_port_id, subport): # Retrieve the child port details child_port = self.plugin_driver.get_port(context, subport.port_id) # Retrieve the logical port ID based on the child port's neutron ID nsx_child_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=subport.port_id)[1] # Retrieve child logical port from the backend try: nsx_child_port = self._nsxlib.logical_port.get( nsx_child_port_id) except nsxlib_exc.ResourceNotFound: with excutils.save_and_reraise_exception(): LOG.error("Child port %s not found on the backend. " "Setting trunk status to ERROR.", nsx_child_port_id) # Build address bindings and switch profiles otherwise backend will # clear that information during port update address_bindings = self.plugin_driver._build_address_bindings( child_port) switching_profile_ids = self._build_switching_profile_ids( nsx_child_port.get('switching_profile_ids', [])) seg_id = None tags_update = [] attachment_type = nsx_constants.ATTACHMENT_VIF if parent_port_id: # Set properties for VLAN trunking if subport.segmentation_type == nsx_utils.NsxV3NetworkTypes.VLAN: seg_id = subport.segmentation_id tags_update.append({'scope': 'os-neutron-trunk-id', 'tag': subport.trunk_id}) vif_type = nsx_constants.VIF_TYPE_CHILD else: # Unset the parent port properties from child port seg_id = None vif_type = None tags_update.append({'scope': 'os-neutron-trunk-id', 'tag': None}) # Update logical port in the backend to set/unset parent port try: self._nsxlib.logical_port.update( lport_id=nsx_child_port.get('id'), vif_uuid=subport.port_id, name=nsx_child_port.get('display_name'), admin_state=nsx_child_port.get('admin_state'), address_bindings=address_bindings, switch_profile_ids=switching_profile_ids, attachment_type=attachment_type, parent_vif_id=parent_port_id, vif_type=vif_type, traffic_tag=seg_id, tags_update=tags_update) except nsxlib_exc.ManagerError as e: with excutils.save_and_reraise_exception(): LOG.error("Unable to update subport for attachment " "type. Setting trunk status to ERROR. " "Exception is %s", e)
def _tag_port(self, context, port_id, tag): # Translate neutron port id to nsx port id _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id( context._plugin_context.session, port_id) self.nsx_port.update(nsx_port_id, None, tags_update=[{ 'scope': 'gbp', 'tag': tag }])
def trunk_deleted(self, context, trunk): # Retrieve the logical port ID based on the parent port's neutron ID nsx_parent_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=trunk.port_id)[1] tags_update = [{'scope': 'os-neutron-trunk-id', 'tag': None}] self.plugin_driver.nsxlib.logical_port.update(nsx_parent_port_id, vif_uuid=trunk.port_id, vif_type=None, tags_update=tags_update) self._unset_subports(context, trunk.sub_ports)
def update_router_firewall(self, context, nsxlib, router_id, router_interfaces, nsx_router_id, section_id, from_fw=False): """Rewrite all the FWaaS v2 rules in the router edge firewall This method should be called on FWaaS updates, and on router interfaces changes. The purpose of from_fw is to differ between fw calls and other router calls, and if it is True - add the service router accordingly. """ fw_rules = [] with_fw = False # Add firewall rules per port attached to a firewall group for port in router_interfaces: nsx_ls_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id( context.session, port['id']) # Check if this port has a firewall fwg = self.get_port_fwg(context, port['id']) if fwg: with_fw = True # Add plugin additional allow rules plugin_rules = self.core_plugin.get_extra_fw_rules( context, router_id, port['id']) # add the FWaaS rules for this port # ingress/egress firewall rules + default ingress/egress drop # rule for this port fw_rules.extend(self.get_port_rules(nsx_ls_id, fwg, plugin_rules)) # add a default allow-all rule to all other traffic & ports fw_rules.append(self.internal_driver.get_default_backend_rule( section_id, allow_all=True)) # update the backend router firewall exists_on_backend = self.core_plugin.verify_sr_at_backend(context, router_id) if from_fw: # fw action required if with_fw: # firewall exists in Neutron and not on backend - create if not exists_on_backend: self.core_plugin.create_service_router( context, router_id, update_firewall=False) else: # First, check if other services exist and use the sr sr_exists = self.core_plugin.service_router_has_services( context, router_id) if not sr_exists and exists_on_backend: # No other services that require service router - delete self.core_plugin.delete_service_router(context, router_id) exists_on_backend = False if exists_on_backend: nsxlib.firewall_section.update(section_id, rules=fw_rules)
def update_router_firewall(self, context, nsxlib, router_id, router_interfaces, nsx_router_id, section_id, from_fw=False): """Rewrite all the FWaaS v2 rules in the router edge firewall This method should be called on FWaaS updates, and on router interfaces changes. The purpose of from_fw is to differ between fw calls and other router calls, and if it is True - add the service router accordingly. """ fw_rules = [] with_fw = False # Add firewall rules per port attached to a firewall group for port in router_interfaces: nsx_ls_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id( context.session, port['id']) # Check if this port has a firewall fwg = self.get_port_fwg(context, port['id']) if fwg: with_fw = True # Add plugin additional allow rules plugin_rules = self.core_plugin.get_extra_fw_rules( context, router_id, port['id']) # add the FWaaS rules for this port # ingress/egress firewall rules + default ingress/egress drop # rule for this port fw_rules.extend(self.get_port_rules(nsx_ls_id, fwg, plugin_rules)) # add a default allow-all rule to all other traffic & ports fw_rules.append(self.internal_driver.get_default_backend_rule( section_id, allow_all=True)) # update the backend router firewall exists_on_backend = self.core_plugin.verify_sr_at_backend(context, router_id) if from_fw: # fw action required if with_fw: # firewall exists in Neutron and not on backend - create if not exists_on_backend: self.core_plugin.create_service_router(context, router_id) exists_on_backend = True else: # First, check if other services exist and use the sr sr_exists = self.core_plugin.service_router_has_services( context, router_id) if not sr_exists and exists_on_backend: # No other services that require service router - delete self.core_plugin.delete_service_router(context, router_id) exists_on_backend = False if exists_on_backend: nsxlib.firewall_section.update(section_id, rules=fw_rules)
def trunk_deleted(self, context, trunk): # Retrieve the logical port ID based on the parent port's neutron ID nsx_parent_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=trunk.port_id)[1] tags_update = [{'scope': 'os-neutron-trunk-id', 'tag': None}] self.plugin_driver.nsxlib.logical_port.update( nsx_parent_port_id, vif_uuid=trunk.port_id, vif_type=None, tags_update=tags_update) self._unset_subports(context, trunk.sub_ports)
def get_nsx_switch_and_port_id(session, cluster, neutron_port_id): """Return the NSX switch and port uuids for a given neutron port. First, look up the Neutron database. If not found, execute a query on NSX platform as the mapping might be missing because the port was created before upgrading to grizzly. This routine also retrieves the identifier of the logical switch in the backend where the port is plugged. Prior to Icehouse this information was not available in the Neutron Database. For dealing with pre-existing records, this routine will query the backend for retrieving the correct switch identifier. As of Icehouse release it is not indeed anymore possible to assume the backend logical switch identifier is equal to the neutron network identifier. """ nsx_switch_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id( session, neutron_port_id) if not nsx_switch_id: # Find logical switch for port from backend # This is a rather expensive query, but it won't be executed # more than once for each port in Neutron's lifetime nsx_ports = switchlib.query_lswitch_lports( cluster, '*', relations='LogicalSwitchConfig', filters={ 'tag': neutron_port_id, 'tag_scope': 'q_port_id' }) # Only one result expected # NOTE(salv-orlando): Not handling the case where more than one # port is found with the same neutron port tag if not nsx_ports: LOG.warning("Unable to find NSX port for Neutron port %s", neutron_port_id) # This method is supposed to return a tuple return None, None nsx_port = nsx_ports[0] nsx_switch_id = (nsx_port['_relations']['LogicalSwitchConfig']['uuid']) if nsx_port_id: # Mapping already exists. Delete before recreating nsx_db.delete_neutron_nsx_port_mapping(session, neutron_port_id) else: nsx_port_id = nsx_port['uuid'] # (re)Create DB mapping nsx_db.add_neutron_nsx_port_mapping(session, neutron_port_id, nsx_switch_id, nsx_port_id) return nsx_switch_id, nsx_port_id
def get_nsx_switch_and_port_id(session, cluster, neutron_port_id): """Return the NSX switch and port uuids for a given neutron port. First, look up the Neutron database. If not found, execute a query on NSX platform as the mapping might be missing because the port was created before upgrading to grizzly. This routine also retrieves the identifier of the logical switch in the backend where the port is plugged. Prior to Icehouse this information was not available in the Neutron Database. For dealing with pre-existing records, this routine will query the backend for retrieving the correct switch identifier. As of Icehouse release it is not indeed anymore possible to assume the backend logical switch identifier is equal to the neutron network identifier. """ nsx_switch_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id( session, neutron_port_id) if not nsx_switch_id: # Find logical switch for port from backend # This is a rather expensive query, but it won't be executed # more than once for each port in Neutron's lifetime nsx_ports = switchlib.query_lswitch_lports( cluster, '*', relations='LogicalSwitchConfig', filters={'tag': neutron_port_id, 'tag_scope': 'q_port_id'}) # Only one result expected # NOTE(salv-orlando): Not handling the case where more than one # port is found with the same neutron port tag if not nsx_ports: LOG.warning("Unable to find NSX port for Neutron port %s", neutron_port_id) # This method is supposed to return a tuple return None, None nsx_port = nsx_ports[0] nsx_switch_id = (nsx_port['_relations'] ['LogicalSwitchConfig']['uuid']) if nsx_port_id: # Mapping already exists. Delete before recreating nsx_db.delete_neutron_nsx_port_mapping( session, neutron_port_id) else: nsx_port_id = nsx_port['uuid'] # (re)Create DB mapping nsx_db.add_neutron_nsx_port_mapping( session, neutron_port_id, nsx_switch_id, nsx_port_id) return nsx_switch_id, nsx_port_id
def trunk_created(self, context, trunk): # Retrieve the logical port ID based on the parent port's neutron ID nsx_parent_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=trunk.port_id)[1] tags_update = [{'scope': 'os-neutron-trunk-id', 'tag': trunk.id}] self.plugin_driver.nsxlib.logical_port.update( nsx_parent_port_id, vif_uuid=trunk.port_id, vif_type=nsx_constants.VIF_TYPE_PARENT, tags_update=tags_update) try: if trunk.sub_ports: self._set_subports(context, trunk.port_id, trunk.sub_ports) trunk.update(status=trunk_consts.ACTIVE_STATUS) except (nsxlib_exc.ManagerError, nsxlib_exc.ResourceNotFound): trunk.update(status=trunk_consts.ERROR_STATUS)
def trunk_created(self, context, trunk): # Retrieve the logical port ID based on the parent port's neutron ID nsx_parent_port_id = nsx_db.get_nsx_switch_and_port_id( session=context.session, neutron_id=trunk.port_id)[1] tags_update = [{'scope': 'os-neutron-trunk-id', 'tag': trunk.id}] self.plugin_driver.nsxlib.logical_port.update( nsx_parent_port_id, vif_uuid=trunk.port_id, vif_type=nsx_constants.VIF_TYPE_PARENT, tags_update=tags_update) try: if trunk.sub_ports: self._set_subports(context, trunk.port_id, trunk.sub_ports) trunk.update(status=trunk_consts.TRUNK_ACTIVE_STATUS) except (nsxlib_exc.ManagerError, nsxlib_exc.ResourceNotFound): trunk.update(status=trunk_consts.TRUNK_ERROR_STATUS)
def get_lswitch_and_lport_id(self, port_id): return nsx_db.get_nsx_switch_and_port_id(self.context.session, port_id)
def get_lswitch_and_lport_id(self, port_id): return nsx_db.get_nsx_switch_and_port_id(self.context.session, port_id)
def _convert_to_backend_source_port(self, session, port_id): nsx_port_id = nsx_db.get_nsx_switch_and_port_id(session, port_id)[1] return [{ "resource_type": "LogicalPortMirrorSource", "port_ids": [nsx_port_id] }]