Beispiel #1
0
    def add_router_interface(self, context, router_id, interface_info):
        # NOTE(arosen): I think there is a bug here since I believe we
        # can also get a port or ip here....
        subnet = self.get_subnet(context, interface_info['subnet_id'])
        port = {'port': {'network_id': subnet['network_id'], 'name': '',
                         'admin_state_up': True, 'device_id': '',
                         'device_owner': l3_db.DEVICE_OWNER_ROUTER_INTF,
                         'mac_address': attributes.ATTR_NOT_SPECIFIED,
                         'fixed_ips': [{'subnet_id': subnet['id'],
                                        'ip_address': subnet['gateway_ip']}]}}
        port = self.create_port(context, port)
        _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
            context.session, port['id'])

        nsx_router_id = nsx_db.get_nsx_router_id(context.session,
                                                 router_id)
        result = nsxlib.create_logical_router_port(
            logical_router_id=nsx_router_id,
            logical_switch_port_id=nsx_port_id,
            resource_type="LogicalRouterDownLinkPort",
            cidr_length=24, ip_address=subnet['gateway_ip'])
        interface_info['port_id'] = port['id']
        del interface_info['subnet_id']
        result = super(NsxV3Plugin, self).add_router_interface(
            context, router_id, interface_info)
        return result
Beispiel #2
0
    def delete_port(self, context, port_id, l3_port_check=True):
        _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
            context.session, port_id)
        nsxlib.delete_logical_port(nsx_port_id)
        ret_val = super(NsxV3Plugin, self).delete_port(context, port_id)

        return ret_val
Beispiel #3
0
    def add_router_interface(self, context, router_id, interface_info):
        # NOTE(arosen): I think there is a bug here since I believe we
        # can also get a port or ip here....
        subnet = self.get_subnet(context, interface_info["subnet_id"])
        port = {
            "port": {
                "network_id": subnet["network_id"],
                "name": "",
                "admin_state_up": True,
                "device_id": "",
                "device_owner": l3_db.DEVICE_OWNER_ROUTER_INTF,
                "mac_address": attributes.ATTR_NOT_SPECIFIED,
                "fixed_ips": [{"subnet_id": subnet["id"], "ip_address": subnet["gateway_ip"]}],
            }
        }
        port = self.create_port(context, port)
        _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(context.session, port["id"])

        nsx_router_id = nsx_db.get_nsx_router_id(context.session, router_id)
        result = nsxlib.create_logical_router_port(
            logical_router_id=nsx_router_id,
            logical_switch_port_id=nsx_port_id,
            resource_type="LogicalRouterDownLinkPort",
            cidr_length=24,
            ip_address=subnet["gateway_ip"],
        )
        interface_info["port_id"] = port["id"]
        del interface_info["subnet_id"]
        result = super(NsxV3Plugin, self).add_router_interface(context, router_id, interface_info)
        return result
Beispiel #4
0
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.warn(_LW("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
Beispiel #5
0
 def remove_router_interface(self, context, router_id, interface_info):
     if "subnet_id" in interface_info:
         subnet_id = interface_info["subnet_id"]
         subnet = self._get_subnet(context, subnet_id)
         rport_qry = context.session.query(models_v2.Port)
         ports = rport_qry.filter_by(
             device_id=router_id, device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF, network_id=subnet["network_id"]
         )
         for p in ports:
             if p["fixed_ips"][0]["subnet_id"] == subnet_id:
                 port_id = p["id"]
                 break
         else:
             raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id, subnet_id=subnet_id)
         _net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(context.session, port_id)
         nsxlib.delete_logical_router_port(nsx_port_id)
     return super(NsxV3Plugin, self).remove_router_interface(context, router_id, interface_info)
Beispiel #6
0
    def update_port(self, context, id, port):
        original_port = super(NsxV3Plugin, self).get_port(context, id)
        _, nsx_lport_id = nsx_db.get_nsx_switch_and_port_id(context.session, id)
        with context.session.begin(subtransactions=True):
            updated_port = super(NsxV3Plugin, self).update_port(context, id, port)
            sec_grp_updated = self.update_security_group_on_port(context, id, port, original_port, updated_port)
        try:
            nsxlib.update_logical_port(
                nsx_lport_id, name=port["port"].get("name"), admin_state=port["port"].get("admin_state_up")
            )
        except nsx_exc.ManagerError:
            # In case if there is a failure on NSX-v3 backend, rollback the
            # previous update operation on neutron side.
            LOG.exception(_LE("Unable to update NSX backend, rolling back " "changes on neutron"))
            with excutils.save_and_reraise_exception():
                with context.session.begin(subtransactions=True):
                    super(NsxV3Plugin, self).update_port(context, id, original_port)
                    if sec_grp_updated:
                        self.update_security_group_on_port(
                            context, id, {"port": original_port}, updated_port, original_port
                        )

        return updated_port