コード例 #1
0
    def _get_router_for_floatingip(self, context, internal_port,
                                   internal_subnet_id, external_network_id):
        subnet_db = self._get_subnet(context, internal_subnet_id)
        if not subnet_db['gateway_ip']:
            msg = (_('Cannot add floating IP to port on subnet %s '
                     'which has no gateway_ip') % internal_subnet_id)
            raise q_exc.BadRequest(resource='floatingip', msg=msg)

        # find router interface ports on this network
        router_intf_qry = context.session.query(models_v2.Port)
        router_intf_ports = router_intf_qry.filter_by(
            network_id=internal_port['network_id'],
            device_owner=DEVICE_OWNER_ROUTER_INTF)

        for intf_p in router_intf_ports:
            if intf_p['fixed_ips'][0]['subnet_id'] == internal_subnet_id:
                router_id = intf_p['device_id']
                router_gw_qry = context.session.query(models_v2.Port)
                has_gw_port = router_gw_qry.filter_by(
                    network_id=external_network_id,
                    device_id=router_id,
                    device_owner=DEVICE_OWNER_ROUTER_GW).count()
                if has_gw_port:
                    return router_id

        raise l3.ExternalGatewayForFloatingIPNotFound(
            subnet_id=internal_subnet_id,
            external_network_id=external_network_id,
            port_id=internal_port['id'])
コード例 #2
0
    def _get_router_for_internal_subnet(self, context, internal_port,
                                        internal_subnet_id):
        subnet_db = self._get_subnet(context, internal_subnet_id)
        if not subnet_db['gateway_ip']:
            msg = ('Cannot add floating IP to port on subnet %s '
                   'which has no gateway_ip' % internal_subnet_id)
            raise q_exc.BadRequest(resource='floatingip', msg=msg)

        #FIXME(danwent): can do join, but cannot use standard F-K syntax?
        # just do it inefficiently for now
        port_qry = context.session.query(models_v2.Port)
        ports = port_qry.filter_by(network_id=internal_port['network_id'])
        for p in ports:
            ips = [ip['ip_address'] for ip in p['fixed_ips']]
            if len(ips) != 1:
                continue
            fixed = p['fixed_ips'][0]
            if (fixed['ip_address'] == subnet_db['gateway_ip']
                    and fixed['subnet_id'] == internal_subnet_id):
                router_qry = context.session.query(Router)
                try:
                    router = router_qry.filter_by(id=p['device_id']).one()
                    return router['id']
                except exc.NoResultFound:
                    pass

        raise l3.ExternalGatewayForFloatingIPNotFound(
            subnet_id=internal_subnet_id, port_id=internal_port['id'])
コード例 #3
0
    def get_assoc_data(self, context, fip, floating_network_id):
        """When a floating IP is associated with an internal port,
        we need to extract/determine some data associated with the
        internal port, including the internal_ip_address, and router_id.
        We also need to confirm that this internal port is owned by the
        tenant who owns the floating IP.
        """
        internal_port = self._get_port(context, fip['port_id'])
        if not internal_port['tenant_id'] == fip['tenant_id']:
            port_id = fip['port_id']
            if 'id' in fip:
                floatingip_id = fip['id']
                msg = _('Port %(port_id)s is associated with a different '
                        'tenant than Floating IP %(floatingip_id)s and '
                        'therefore cannot be bound.')
            else:
                msg = _('Cannnot create floating IP and bind it to '
                        'Port %(port_id)s, since that port is owned by a '
                        'different tenant.')
            raise q_exc.BadRequest(resource='floatingip', msg=msg % locals())

        internal_subnet_id = None
        if 'fixed_ip_address' in fip and fip['fixed_ip_address']:
            internal_ip_address = fip['fixed_ip_address']
            for ip in internal_port['fixed_ips']:
                if ip['ip_address'] == internal_ip_address:
                    internal_subnet_id = ip['subnet_id']
            if not internal_subnet_id:
                msg = ('Port %s does not have fixed ip %s' %
                       (internal_port['id'], internal_ip_address))
                raise q_exc.BadRequest(resource='floatingip', msg=msg)
        else:
            ips = [ip['ip_address'] for ip in internal_port['fixed_ips']]
            if len(ips) == 0:
                msg = ('Cannot add floating IP to port %s that has'
                       'no fixed IP addresses' % internal_port['id'])
                raise q_exc.BadRequest(resource='floatingip', msg=msg)
            if len(ips) > 1:
                msg = ('Port %s has multiple fixed IPs.  Must provide'
                       ' a specific IP when assigning a floating IP' %
                       internal_port['id'])
                raise q_exc.BadRequest(resource='floatingip', msg=msg)
            internal_ip_address = internal_port['fixed_ips'][0]['ip_address']
            internal_subnet_id = internal_port['fixed_ips'][0]['subnet_id']

        router_id = self._get_router_for_internal_subnet(
            context, internal_port, internal_subnet_id)
        # confirm that this router has a floating
        # ip enabled gateway with support for this floating IP network
        try:
            port_qry = context.elevated().session.query(models_v2.Port)
            ports = port_qry.filter_by(
                network_id=floating_network_id,
                device_id=router_id,
                device_owner=DEVICE_OWNER_ROUTER_GW).one()
        except exc.NoResultFound:
            raise l3.ExternalGatewayForFloatingIPNotFound(
                subnet_id=internal_subnet_id, port_id=internal_port['id'])

        return (fip['port_id'], internal_ip_address, router_id)
コード例 #4
0
    def get_assoc_data(self, context, fip, floating_network_id):
        """Determine/extract data associated with the internal port.

        When a floating IP is associated with an internal port,
        we need to extract/determine some data associated with the
        internal port, including the internal_ip_address, and router_id.
        We also need to confirm that this internal port is owned by the
        tenant who owns the floating IP.
        """
        (internal_port, internal_subnet_id,
         internal_ip_address) = self._internal_fip_assoc_data(context, fip)
        router_id = self._get_router_for_floatingip(context, internal_port,
                                                    internal_subnet_id,
                                                    floating_network_id)
        # confirm that this router has a floating
        # ip enabled gateway with support for this floating IP network
        try:
            port_qry = context.elevated().session.query(models_v2.Port)
            port_qry.filter_by(network_id=floating_network_id,
                               device_id=router_id,
                               device_owner=DEVICE_OWNER_ROUTER_GW).one()
        except exc.NoResultFound:
            raise l3.ExternalGatewayForFloatingIPNotFound(
                subnet_id=internal_subnet_id, port_id=internal_port['id'])

        return (fip['port_id'], internal_ip_address, router_id)