Beispiel #1
0
 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
Beispiel #2
0
    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
Beispiel #3
0
 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'])
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
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
Beispiel #7
0
    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
Beispiel #8
0
    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'])
Beispiel #9
0
 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'])