def _get_fake_port_obj(self, port_id): with mock.patch('uuid.UUID') as mock_uuid: mock_uuid.return_value = port_id port = Port() port.id = port_id port.bindings = [PortBinding(profile={}, host='foo.com')] return port
def ensure_subports(self, port_id, db): # set the correct state on port in the case where it has subports. port = Port.get_object(db, id=port_id) # If the parent port has been deleted then that delete will handle # removing the trunked vlans on the switch using the mac if not port: LOG.debug('Discarding attempt to ensure subports on a port' 'that has been deleted') return # get switch from port bindings switch_name, switch_port, segmentation_id = \ self._link_info_from_port(port, None) # lock switch lock = self.coordinator.get_lock(switch_name) with lock: # get updated port from db updated_port = Port.get_object(db, id=port_id) if updated_port: self._set_port_state(updated_port, db) return else: # port delete operation will take care of deletion LOG.debug('Discarding attempt to ensure subports on a port {} ' 'that was deleted after lock ' 'acquisition'.format(port_id)) return
def _load_connected_networks(self, db_obj=None): # NOTE(tmorin): can be improved by directly looking up # Ports with device_id=self.router_id router_ports = RouterPort.get_objects(self.obj_context, router_id=self.router_id) # pylint: disable=no-member connected_networks = [] for router_port in router_ports: port = Port.get_object(self.obj_context, id=router_port.port_id) if port: # router gateway networks are not considered as requiring # to be bound to BGPVPNs if port.device_owner == constants.DEVICE_OWNER_ROUTER_GW: LOG.debug("skipping port %s, because router gateway", port.id) continue connected_networks.append({ 'network_id': port.network_id, 'subnets': _get_subnets_info(self.obj_context, port.network_id) }) else: LOG.warning( "Couldn't find Port for RouterPort (router:%s," "port:%s)", router_port.router_id, router_port.port_id) setattr(self, 'connected_networks', connected_networks) self.obj_reset_changes(['connected_networks'])
def get_objects(cls, context, _pager=None, validate_filters=True, **kwargs): if 'network_id' in kwargs and 'router_id' not in kwargs: ports = Port.get_objects( context, network_id=kwargs.pop('network_id'), device_owner=constants.DEVICE_OWNER_ROUTER_INTF) router_assocs = [] for port in ports: router_assocs.extend( super(BGPVPNRouterAssociation, cls).get_objects(context, _pager=_pager, validate_filters=validate_filters, router_id=RouterPort.get_object( context, port_id=port.id).router_id, **kwargs)) return router_assocs return super(BGPVPNRouterAssociation, cls).get_objects(context, _pager=_pager, validate_filters=validate_filters, **kwargs)
def ensure_port(self, port_id, db, mac, switch_name, switch_port, physnet, port_context): LOG.debug('Ensuring state of port {port_id} ' 'with mac addr {mac} ' 'on switch {switch_name} ' 'on port {switch_port} ' 'on physnet {physnet} ' 'using db context {db}'.format(port_id=port_id, mac=mac, switch_name=switch_name, switch_port=switch_port, physnet=physnet, db=db)) if not self.net_runr.has_host(switch_name): raise ml2_exc.MechanismDriverError('NetAnsible: couldnt find ' 'switch_name {} in network ' 'runner inventory while ' 'configuring port id ' '{}'.format( switch_name, port_id)) # get dlock for the switch we're working with lock = self.coordinator.get_lock(switch_name) with lock: # port = get the port from the db updated_port = Port.get_object(db, id=port_id) # if it exists and is bound to a port if self._get_port_lli(updated_port): if self._set_port_state(updated_port, db): if port_context and port_context.segments_to_bind: segments = port_context.segments_to_bind port_context.set_binding(segments[0][ml2api.ID], portbindings.VIF_TYPE_OTHER, {}) return else: # if the port doesn't exist, we have a mac+switch, we can look # up whether the port needs to be deleted on the switch if self._is_deleted_port_in_use(physnet, mac, db): LOG.debug('Port {port_id} was deleted, but its switch port' ' {sp} is now in use by another port, discarding' ' request to delete'.format(port_id=port_id, sp=switch_port)) return else: self._delete_switch_port(switch_name, switch_port)
def _get_gateway_mac_by_subnet(obj_context, subnet): if not subnet.gateway_ip: LOG.error("no gateway IP defined for subnet %s", subnet) return None ip_allocation = IPAllocation.get_object(obj_context, network_id=subnet.network_id, subnet_id=subnet.id, ip_address=subnet.gateway_ip) if ip_allocation: port = Port.get_object(obj_context, id=ip_allocation.port_id) return str(port.mac_address) else: LOG.debug("no port allocated to gateway IP for subnet %s", subnet.id) return None
def _is_deleted_port_in_use(self, physnet, mac, db): # Go through all ports with this mac addr and find which # network segment they are on, which will contain physnet # and net type # # if a port with this mac on the same physical provider # is attached to this port then don't delete the interface. # Don't need to check the segment since delete will remove all # segments, and bind also deletes before adding # # These checks are required because a second tenant could # set their mac address to the ironic port one and attempt # meddle with the port delete. This wouldn't do anything # bad today because bind deletes the interface and recreates # it on the physical switch, but that's an implementation # detail we shouldn't rely on. # get port by mac mports = Port.get_objects(db, mac_address=mac) if len(mports) > 1: # This isn't technically a problem, but it may indicate something # fishy is going on LOG.warn('multiple ports matching ironic ' 'port mac: {mac}'.format(mac=mac)) for port in mports: if port.bindings: lli = self._get_port_lli(port) if lli: net = Network.get_object(db, id=port.network_id) if net: for seg in net.segments: if (seg.physical_network == physnet and seg.network_type == 'vlan'): return True return False
def _load_ports_by_side(self, side): ports = [] if getattr(self, side + '_ppg'): # pylint: disable=no-member reverse_side = (side if self.reverse_hop else constants.REVERSE_PORT_SIDE[side]) ports = ([ getattr(pp, reverse_side) for pp in model_query.get_collection_query( self.obj_context, sfc_db.PortPair, filters={ 'portpairgroup_id': [getattr(self, side + '_ppg')] }) ]) elif getattr(self, side + '_network'): port_objs = (Port.get_objects(self.obj_context, network_id=getattr( self, side + '_network'))) ports = [port_obj.id for port_obj in port_objs] setattr(self, side + '_ports', ports) self.obj_reset_changes([side + '_ports'])
def _load_subnets(self, db_obj=None): # pylint: disable=no-member port = Port.get_object(self.obj_context, id=self.port_id) subnets_info = _get_subnets_info(self.obj_context, port.network_id) setattr(self, 'subnets', subnets_info) self.obj_reset_changes(['subnets'])