Exemple #1
0
def list_missing_routers(resource, event, trigger, **kwargs):
    """List neutron routers that are missing the NSX backend router
    """
    plugin = RoutersPlugin()
    admin_cxt = neutron_context.get_admin_context()
    neutron_routers = plugin.get_routers(admin_cxt)
    routers = []
    for router in neutron_routers:
        neutron_id = router['id']
        # get the router nsx id from the mapping table
        nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id)
        if not nsx_id:
            routers.append({
                'name': router['name'],
                'neutron_id': neutron_id,
                'nsx_id': None
            })
        else:
            try:
                nsxlib.logical_router.get(nsx_id)
            except nsx_exc.ResourceNotFound:
                routers.append({
                    'name': router['name'],
                    'neutron_id': neutron_id,
                    'nsx_id': nsx_id
                })
    if len(routers) > 0:
        title = ("Found %d routers missing from the NSX "
                 "manager:") % len(routers)
        LOG.info(
            formatters.output_formatter(title, routers,
                                        ['name', 'neutron_id', 'nsx_id']))
    else:
        LOG.info("All routers exist on the NSX manager")
Exemple #2
0
    def _check_lb_service_on_router(self, resource, event, trigger,
                                    payload=None):
        """Prevent removing a router GW or deleting a router used by LB"""
        router_id = payload.resource_id
        context = payload.context
        nsx_router_id = nsx_db.get_nsx_router_id(context.session,
                                                 router_id)
        if not nsx_router_id:
            # Skip non-v3 routers (could be a V router in case of TVD plugin)
            return
        nsxlib = self.loadbalancer.core_plugin.nsxlib
        service_client = nsxlib.load_balancer.service
        # Check if there is any lb service on nsx router
        lb_service = service_client.get_router_lb_service(nsx_router_id)
        if lb_service:
            msg = _('Cannot delete a %s as it still has lb service '
                    'attachment') % resource
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)

        # Also check if there are any loadbalancers attached to this router
        # subnets
        router_subnets = self.loadbalancer.core_plugin._find_router_subnets(
            context.elevated(), router_id)
        subnet_ids = [subnet['id'] for subnet in router_subnets]
        if subnet_ids and self._get_lb_ports(context.elevated(), subnet_ids):
            msg = (_('Cannot delete a %s as it used by a loadbalancer') %
                   resource)
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
Exemple #3
0
def get_nsx_router_id(session, cluster, neutron_router_id):
    """Return the NSX router uuid for a given neutron router.

    First, look up the Neutron database. If not found, execute
    a query on NSX platform as the mapping might be missing.
    """
    if not neutron_router_id:
        return
    nsx_router_id = nsx_db.get_nsx_router_id(
        session, neutron_router_id)
    if not nsx_router_id:
        # Find logical router from backend.
        # This is a rather expensive query, but it won't be executed
        # more than once for each router in Neutron's lifetime
        nsx_routers = routerlib.query_lrouters(
            cluster, '*',
            filters={'tag': neutron_router_id,
                     'tag_scope': 'q_router_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_routers:
            LOG.warning("Unable to find NSX router for Neutron router %s",
                        neutron_router_id)
            return
        nsx_router = nsx_routers[0]
        nsx_router_id = nsx_router['uuid']
        with session.begin(subtransactions=True):
            # Create DB mapping
            nsx_db.add_neutron_nsx_router_mapping(
                session,
                neutron_router_id,
                nsx_router_id)
    return nsx_router_id
Exemple #4
0
def update_enable_standby_relocation(resource, event, trigger, **kwargs):
    """Enable standby relocation on all routers """
    # This feature is supported only since nsx version 2.4
    nsxlib = utils.get_connected_nsxlib()
    version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_2_4_0(version):
        LOG.info("Standby relocation update is only supported from 2.4 "
                 "onwards")
        LOG.info("Version is %s", version)
        return

    # Go over all neutron routers
    plugin = RoutersPlugin()
    admin_cxt = neutron_context.get_admin_context()
    filters = utils.get_plugin_filters(admin_cxt)
    neutron_routers = plugin.get_routers(admin_cxt, filters=filters)
    for router in neutron_routers:
        neutron_id = router['id']
        # get the router nsx id from the mapping table
        nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id)
        try:
            nsxlib.logical_router.update(lrouter_id=nsx_id,
                                         enable_standby_relocation=True)
        except Exception as e:
            # This may fail if the service router is not created
            LOG.warning("Router %s cannot enable standby relocation: %s",
                        neutron_id, e)
        else:
            LOG.info("Router %s was enabled with standby relocation",
                     neutron_id)
    LOG.info("Done")
Exemple #5
0
def get_nsx_router_id(session, cluster, neutron_router_id):
    """Return the NSX router uuid for a given neutron router.

    First, look up the Neutron database. If not found, execute
    a query on NSX platform as the mapping might be missing.
    """
    if not neutron_router_id:
        return
    nsx_router_id = nsx_db.get_nsx_router_id(session, neutron_router_id)
    if not nsx_router_id:
        # Find logical router from backend.
        # This is a rather expensive query, but it won't be executed
        # more than once for each router in Neutron's lifetime
        nsx_routers = routerlib.query_lrouters(cluster,
                                               '*',
                                               filters={
                                                   'tag': neutron_router_id,
                                                   'tag_scope': 'q_router_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_routers:
            LOG.warning("Unable to find NSX router for Neutron router %s",
                        neutron_router_id)
            return
        nsx_router = nsx_routers[0]
        nsx_router_id = nsx_router['uuid']
        with session.begin(subtransactions=True):
            # Create DB mapping
            nsx_db.add_neutron_nsx_router_mapping(session, neutron_router_id,
                                                  nsx_router_id)
    return nsx_router_id
Exemple #6
0
    def _get_backend_router_and_fw_section(self, context, router_id):
        # find the backend router id in the DB
        nsx_router_id = nsx_db.get_nsx_router_id(context.session, router_id)
        if nsx_router_id is None:
            LOG.error("Didn't find nsx router for router %s", router_id)
            raise exceptions.FirewallInternalDriverError(
                driver=FWAAS_DRIVER_NAME)

        # get the FW section id of the backend router
        try:
            section_id = self.nsx_router.get_firewall_section_id(nsx_router_id)
        except Exception as e:
            LOG.error(
                "Failed to find router firewall section for router "
                "%(id)s: %(e)s", {
                    'id': router_id,
                    'e': e
                })
            raise exceptions.FirewallInternalDriverError(
                driver=FWAAS_DRIVER_NAME)
        if section_id is None:
            LOG.error(
                "Failed to find router firewall section for router "
                "%(id)s.", {'id': router_id})
            raise exceptions.FirewallInternalDriverError(
                driver=FWAAS_DRIVER_NAME)

        return nsx_router_id, section_id
Exemple #7
0
def update_nat_rules(resource, event, trigger, **kwargs):
    """Update all routers NAT rules to not bypass the firewall"""
    # This feature is supported only since nsx version 2
    nsxlib = utils.get_connected_nsxlib()
    version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_2_0_0(version):
        LOG.info("NAT rules update only supported from 2.0 onwards")
        LOG.info("Version is %s", version)
        return

    # Go over all neutron routers
    plugin = RoutersPlugin()
    admin_cxt = neutron_context.get_admin_context()
    neutron_routers = plugin.get_routers(admin_cxt)
    num_of_updates = 0
    for router in neutron_routers:
        neutron_id = router['id']
        # get the router nsx id from the mapping table
        nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id)
        if nsx_id:
            # get all NAT rules:
            rules = nsxlib.logical_router.list_nat_rules(nsx_id)['results']
            for rule in rules:
                if 'nat_pass' not in rule or rule['nat_pass']:
                    nsxlib.logical_router.update_nat_rule(nsx_id,
                                                          rule['id'],
                                                          nat_pass=False)
                    num_of_updates = num_of_updates + 1
    if num_of_updates:
        LOG.info("Done updating %s NAT rules", num_of_updates)
    else:
        LOG.info("Did not find any NAT rule to update")
Exemple #8
0
    def _check_lb_service_on_router(self, resource, event, trigger, **kwargs):
        """Prevent removing a router GW or deleting a router used by LB"""
        router_id = kwargs.get('router_id')
        context = kwargs['context']
        nsx_router_id = nsx_db.get_nsx_router_id(kwargs['context'].session,
                                                 router_id)
        if not nsx_router_id:
            # Skip non-v3 routers (could be a V router in case of TVD plugin)
            return
        nsxlib = self.loadbalancer.core_plugin.nsxlib
        service_client = nsxlib.load_balancer.service
        # Check if there is any lb service on nsx router
        lb_service = service_client.get_router_lb_service(nsx_router_id)
        if lb_service:
            msg = _('Cannot delete a %s as it still has lb service '
                    'attachment') % resource
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)

        # Also check if there are any loadbalancers attached to this router
        # subnets
        router_subnets = self.loadbalancer.core_plugin._find_router_subnets(
            context.elevated(), router_id)
        subnet_ids = [subnet['id'] for subnet in router_subnets]
        if subnet_ids and self._get_lb_ports(context.elevated(), subnet_ids):
            msg = (_('Cannot delete a %s as it used by a loadbalancer') %
                   resource)
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
    def _check_lb_service_on_router(self, resource, event, trigger, **kwargs):
        """Check if there is any lb service on nsx router"""

        nsx_router_id = nsx_db.get_nsx_router_id(kwargs['context'].session,
                                                 kwargs['router_id'])
        nsxlib = self.loadbalancer.core_plugin.nsxlib
        service_client = nsxlib.load_balancer.service
        lb_service = service_client.get_router_lb_service(nsx_router_id)
        if lb_service:
            msg = _('Cannot delete router as it still has lb service '
                    'attachment')
            raise nc_exc.CallbackFailure(msg)
Exemple #10
0
    def create(self, context, lb, completor):
        if not lb_utils.validate_lb_subnet(context, self.core_plugin,
                                           lb['vip_subnet_id']):
            completor(success=False)
            msg = (_('Cannot create lb on subnet %(sub)s for '
                     'loadbalancer %(lb)s. The subnet needs to connect a '
                     'router which is already set gateway.') % {
                         'sub': lb['vip_subnet_id'],
                         'lb': lb['id']
                     })
            raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg)

        service_client = self.core_plugin.nsxlib.load_balancer.service
        nsx_router_id = None
        lb_service = None
        nsx_router_id = lb_utils.NO_ROUTER_ID
        router_id = lb_utils.get_router_from_network(context, self.core_plugin,
                                                     lb['vip_subnet_id'])
        if router_id:
            nsx_router_id = nsx_db.get_nsx_router_id(context.session,
                                                     router_id)
            lb_service = service_client.get_router_lb_service(nsx_router_id)
        if not lb_service:
            lb_size = lb_utils.get_lb_flavor_size(self.flavor_plugin, context,
                                                  lb.get('flavor_id'))
            if router_id:
                # Make sure the NSX service router exists
                if not self.core_plugin.service_router_has_services(
                        context, router_id):
                    self.core_plugin.create_service_router(context, router_id)
                lb_service = self._create_lb_service(context, service_client,
                                                     lb['tenant_id'],
                                                     router_id, nsx_router_id,
                                                     lb['id'], lb_size)
            else:
                lb_service = self._create_lb_service_without_router(
                    context, service_client, lb['tenant_id'], lb, lb_size)
            if not lb_service:
                completor(success=False)
                msg = (_('Failed to create lb service for loadbalancer '
                         '%s') % lb['id'])
                raise nsx_exc.NsxPluginException(err_msg=msg)

        nsx_db.add_nsx_lbaas_loadbalancer_binding(context.session, lb['id'],
                                                  lb_service['id'],
                                                  nsx_router_id,
                                                  lb['vip_address'])

        completor(success=True)
Exemple #11
0
def nsx_update_router_lb_advertisement(resource, event, trigger, **kwargs):
    """The implementation of the VIP advertisement changed.

    This utility will update existing LB/routers
    """
    nsxlib = utils.get_connected_nsxlib()
    if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER):
        LOG.error("This utility is not available for NSX version %s",
                  nsxlib.get_version())
        return

    # Get the list of neutron routers used by LB
    lb_services = nsxlib.load_balancer.service.list()['results']
    lb_routers = []
    for lb_srv in lb_services:
        for tag in lb_srv.get('tags', []):
            if tag['scope'] == 'os-neutron-router-id':
                lb_routers.append(tag['tag'])
    lb_routers = set(lb_routers)
    LOG.info(
        "Going to update LB advertisement on %(num)s router(s): "
        "%(routers)s", {
            'num': len(lb_routers),
            'routers': lb_routers
        })

    context = neutron_context.get_admin_context()
    with utils.NsxV3PluginWrapper() as plugin:
        for rtr_id in lb_routers:
            nsx_router_id = nsx_db.get_nsx_router_id(context.session, rtr_id)
            if not nsx_router_id:
                LOG.error("Router %s NSX Id was not found.", rtr_id)
                continue
            try:
                # disable the global vip advertisement flag
                plugin.nsxlib.logical_router.update_advertisement(
                    nsx_router_id, advertise_lb_vip=False)
                # Add an advertisement rule for the external network
                router = plugin.get_router(context, rtr_id)
                lb_utils.update_router_lb_vip_advertisement(
                    context, plugin, router, nsx_router_id)
            except Exception as e:
                LOG.error("Failed updating router %(id)s: %(e)s", {
                    'id': rtr_id,
                    'e': e
                })

    LOG.info("Done.")
    def create(self, context, lb, completor):
        if not lb_utils.validate_lb_subnet(context, self.core_plugin,
                                           lb['vip_subnet_id']):
            completor(success=False)
            msg = (_('Cannot create lb on subnet %(sub)s for '
                     'loadbalancer %(lb)s. The subnet needs to connect a '
                     'router which is already set gateway.') %
                   {'sub': lb['vip_subnet_id'], 'lb': lb['id']})
            raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg)

        service_client = self.core_plugin.nsxlib.load_balancer.service
        nsx_router_id = None
        lb_service = None
        nsx_router_id = lb_utils.NO_ROUTER_ID
        router_id = lb_utils.get_router_from_network(
            context, self.core_plugin, lb['vip_subnet_id'])
        if router_id:
            nsx_router_id = nsx_db.get_nsx_router_id(context.session,
                                                     router_id)
            lb_service = service_client.get_router_lb_service(nsx_router_id)
        if not lb_service:
            lb_size = lb_utils.get_lb_flavor_size(
                self.flavor_plugin, context, lb.get('flavor_id'))
            if router_id:
                # Make sure the NSX service router exists
                if not self.core_plugin.service_router_has_services(
                        context, router_id):
                    self.core_plugin.create_service_router(context, router_id)
                lb_service = self._create_lb_service(
                    context, service_client, lb['tenant_id'],
                    router_id, nsx_router_id, lb['id'], lb_size)
            else:
                lb_service = self._create_lb_service_without_router(
                    context, service_client, lb['tenant_id'],
                    lb, lb_size)
            if not lb_service:
                completor(success=False)
                msg = (_('Failed to create lb service for loadbalancer '
                         '%s') % lb['id'])
                raise nsx_exc.NsxPluginException(err_msg=msg)

        nsx_db.add_nsx_lbaas_loadbalancer_binding(
            context.session, lb['id'], lb_service['id'],
            nsx_router_id, lb['vip_address'])

        completor(success=True)
Exemple #13
0
    def _check_lb_service_on_router_interface(self, *args, **kwargs):
        # Prevent removing the interface of an LB subnet from a router
        router_id = kwargs.get('router_id')
        subnet_id = kwargs.get('subnet_id')
        if not router_id or not subnet_id:
            return

        nsx_router_id = nsx_db.get_nsx_router_id(kwargs['context'].session,
                                                 kwargs['router_id'])
        if not nsx_router_id:
            # Skip non-v3 routers (could be a V router in case of TVD plugin)
            return

        # get LB ports and check if any loadbalancer is using this subnet
        if self._get_lb_ports(kwargs['context'].elevated(), [subnet_id]):
            msg = _('Cannot delete a router interface as it used by a '
                    'loadbalancer')
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
Exemple #14
0
    def _check_lb_service_on_router_interface(
            self, resource, event, trigger, payload=None):
        # Prevent removing the interface of an LB subnet from a router
        router_id = payload.resource_id
        subnet_id = payload.metadata.get('subnet_id')
        if not router_id or not subnet_id:
            return

        nsx_router_id = nsx_db.get_nsx_router_id(payload.context.session,
                                                 router_id)
        if not nsx_router_id:
            # Skip non-v3 routers (could be a V router in case of TVD plugin)
            return

        # get LB ports and check if any loadbalancer is using this subnet
        if self._get_lb_ports(payload.context.elevated(), [subnet_id]):
            msg = _('Cannot delete a router interface as it used by a '
                    'loadbalancer')
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
Exemple #15
0
    def _update_router_advertisement(self, context, vpnservice):
        LOG.debug("Updating router advertisement rules for router %s",
                  vpnservice['router_id'])

        router_id = vpnservice['router_id']
        # skip no-snat router as it is already advertised,
        # and router with no gw
        rtr = self.l3_plugin.get_router(context, router_id)
        if (not rtr.get('external_gateway_info')
                or not rtr['external_gateway_info'].get('enable_snat', True)):
            return

        rules = []

        # get all the active services of this router
        filters = {'router_id': [router_id], 'status': [constants.ACTIVE]}
        services = self.vpn_plugin.get_vpnservices(context.elevated(),
                                                   filters=filters)
        for srv in services:
            # use only services with active connections
            filters = {
                'vpnservice_id': [srv['id']],
                'status': [constants.ACTIVE]
            }
            connections = self.vpn_plugin.get_ipsec_site_connections(
                context.elevated(), filters=filters)
            if not connections:
                continue
            subnet = self.l3_plugin.get_subnet(context.elevated(),
                                               srv['subnet_id'])
            rules.append({
                'display_name':
                'VPN advertisement service ' + srv['id'],
                'action':
                consts.FW_ACTION_ALLOW,
                'networks': [subnet['cidr']]
            })

        logical_router_id = db.get_nsx_router_id(context.session, router_id)
        self._nsxlib.logical_router.update_advertisement_rules(
            logical_router_id, rules)
Exemple #16
0
    def _check_lb_service_on_router_interface(self,
                                              resource,
                                              event,
                                              trigger,
                                              payload=None):
        # Prevent removing the interface of an LB subnet from a router
        router_id = payload.resource_id
        subnet_id = payload.metadata.get('subnet_id')
        if not router_id or not subnet_id:
            return

        nsx_router_id = nsx_db.get_nsx_router_id(payload.context.session,
                                                 router_id)
        if not nsx_router_id:
            # Skip non-v3 routers (could be a V router in case of TVD plugin)
            return

        # get LB ports and check if any loadbalancer is using this subnet
        if self._get_lb_ports(payload.context.elevated(), [subnet_id]):
            msg = _('Cannot delete a router interface as it used by a '
                    'loadbalancer')
            raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
Exemple #17
0
    def _update_router_advertisement(self, context, vpnservice):
        LOG.debug("Updating router advertisement rules for router %s",
                  vpnservice['router_id'])

        router_id = vpnservice['router_id']
        # skip no-snat router as it is already advertised,
        # and router with no gw
        rtr = self.l3_plugin.get_router(context, router_id)
        if (not rtr.get('external_gateway_info') or
            not rtr['external_gateway_info'].get('enable_snat', True)):
            return

        rules = []

        # get all the active services of this router
        filters = {'router_id': [router_id], 'status': [constants.ACTIVE]}
        services = self.vpn_plugin.get_vpnservices(
            context.elevated(), filters=filters)
        rule_name_pref = 'VPN advertisement service'
        for srv in services:
            # use only services with active connections
            filters = {'vpnservice_id': [srv['id']],
                       'status': [constants.ACTIVE]}
            connections = self.vpn_plugin.get_ipsec_site_connections(
                context.elevated(), filters=filters)
            if not connections:
                continue
            subnet = self.l3_plugin.get_subnet(
                context.elevated(), srv['subnet_id'])
            rules.append({
                'display_name': "%s %s" % (rule_name_pref, srv['id']),
                'action': consts.FW_ACTION_ALLOW,
                'networks': [subnet['cidr']]})

        if rules:
            logical_router_id = db.get_nsx_router_id(context.session,
                                                     router_id)
            self._nsxlib.logical_router.update_advertisement_rules(
                logical_router_id, rules, name_prefix=rule_name_pref)
Exemple #18
0
    def _member_create(self, context, member, completor):
        lb_id = member['pool']['loadbalancer_id']
        pool_id = member['pool']['id']
        loadbalancer = member['pool']['loadbalancer']
        if not lb_utils.validate_lb_member_subnet(context, self.core_plugin,
                                                  member['subnet_id'],
                                                  loadbalancer):
            completor(success=False)
            msg = (_('Cannot add member %(member)s to pool as member subnet '
                     '%(subnet)s is neither public nor connected to the LB '
                     'router') %
                   {'member': member['id'], 'subnet': member['subnet_id']})
            raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg)

        pool_client = self.core_plugin.nsxlib.load_balancer.pool
        service_client = self.core_plugin.nsxlib.load_balancer.service

        network = lb_utils.get_network_from_subnet(
            context, self.core_plugin, member['subnet_id'])
        if network.get('router:external'):
            fixed_ip, router_id = self._get_info_from_fip(
                context, member['address'])
            if not router_id:
                completor(success=False)
                msg = (_('Floating ip %(fip)s has no router') % {
                    'fip': member['address']})
                raise n_exc.BadRequest(resource='lbaas-vip', msg=msg)
        else:
            router_id = lb_utils.get_router_from_network(
                context, self.core_plugin, member['subnet_id'])
            fixed_ip = member['address']

        binding = nsx_db.get_nsx_lbaas_pool_binding(context.session,
                                                    lb_id, pool_id)
        if binding:
            lb_pool_id = binding.get('lb_pool_id')
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if not lb_binding:
                completor(success=False)
                msg = (_('Failed to get LB binding for member %s') %
                       member['id'])
                raise nsx_exc.NsxPluginException(err_msg=msg)
            if lb_binding.lb_router_id == lb_utils.NO_ROUTER_ID:
                # Need to attach the LB service to the router now
                # This will happen here in case of external vip
                nsx_router_id = nsx_db.get_nsx_router_id(context.session,
                                                         router_id)
                try:
                    tags = lb_utils.get_tags(self.core_plugin, router_id,
                                             lb_const.LR_ROUTER_TYPE,
                                             member['tenant_id'],
                                             context.project_name)
                    service_client.update_service_with_attachment(
                        lb_binding.lb_service_id, nsx_router_id, tags=tags)
                    # TODO(asarfaty): Also update the tags
                except nsxlib_exc.ManagerError as e:
                    # This will happen if there is another service already
                    # attached to this router.
                    # This is currently a limitation.
                    completor(success=False)
                    msg = (_('Failed to attach router %(rtr)s to LB service '
                             '%(srv)s: %(e)s') %
                           {'rtr': router_id, 'srv': lb_binding.lb_service_id,
                            'e': e})
                    raise nsx_exc.NsxPluginException(err_msg=msg)
                # Update the nsx router in the DB binding
                nsx_db.update_nsx_lbaas_loadbalancer_binding(
                    context.session, lb_id, nsx_router_id)
                # Add rule to advertise external vips
                router = self.core_plugin.get_router(context, router_id)
                lb_utils.update_router_lb_vip_advertisement(
                    context, self.core_plugin, router, nsx_router_id)

            with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id):
                lb_pool = pool_client.get(lb_pool_id)
                old_m = lb_pool.get('members', None)
                new_m = [{
                    'display_name': member['name'][:219] + '_' + member['id'],
                    'ip_address': fixed_ip,
                    'port': member['protocol_port'],
                    'weight': member['weight']}]
                members = (old_m + new_m) if old_m else new_m
                pool_client.update_pool_with_members(lb_pool_id, members)

        else:
            completor(success=False)
            msg = (_('Failed to get pool binding to add member %s') %
                   member['id'])
            raise nsx_exc.NsxPluginException(err_msg=msg)

        completor(success=True)
Exemple #19
0
    def create(self, context, member):
        lb_id = member.pool.loadbalancer_id
        pool_id = member.pool.id
        loadbalancer = member.pool.loadbalancer
        if not lb_utils.validate_lb_subnet(context, self.core_plugin,
                                           member.subnet_id):
            msg = (_('Cannot add member %(member)s to pool as member subnet '
                     '%(subnet)s is neither public nor connected to router') %
                   {
                       'member': member.id,
                       'subnet': member.subnet_id
                   })
            raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg)

        pool_client = self.core_plugin.nsxlib.load_balancer.pool
        service_client = self.core_plugin.nsxlib.load_balancer.service
        pool_members = self.lbv2_driver.plugin.get_pool_members(
            context, pool_id)

        network = lb_utils.get_network_from_subnet(context, self.core_plugin,
                                                   member.subnet_id)
        if network.get('router:external'):
            router_id, fixed_ip = self._get_info_from_fip(
                context, member.address)
        else:
            router_id = lb_utils.get_router_from_network(
                context, self.core_plugin, member.subnet_id)
            fixed_ip = member.address

        binding = nsx_db.get_nsx_lbaas_pool_binding(context.session, lb_id,
                                                    pool_id)
        if binding:
            vs_id = binding.get('lb_vs_id')
            lb_pool_id = binding.get('lb_pool_id')
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if not lb_binding and len(pool_members) == 1:
                nsx_router_id = nsx_db.get_nsx_router_id(
                    context.session, router_id)
                lb_service = service_client.get_router_lb_service(
                    nsx_router_id)
                if not lb_service:
                    lb_size = lb_utils.get_lb_flavor_size(
                        self.flavor_plugin, context, loadbalancer.flavor_id)
                    lb_service = self._create_lb_service(
                        context, service_client, member.tenant_id, router_id,
                        nsx_router_id, loadbalancer.id, lb_size)
                if lb_service:
                    lb_service_id = lb_service['id']
                    self._add_loadbalancer_binding(context, loadbalancer.id,
                                                   lb_service_id,
                                                   nsx_router_id,
                                                   loadbalancer.vip_address)
                    if vs_id:
                        try:
                            service_client.add_virtual_server(
                                lb_service_id, vs_id)
                        except nsxlib_exc.ManagerError:
                            self.lbv2_driver.member.failed_completion(
                                context, member)
                            msg = (_('Failed to attach virtual server %(vs)s '
                                     'to lb service %(service)s') % {
                                         'vs': vs_id,
                                         'service': lb_service_id
                                     })
                            raise n_exc.BadRequest(resource='lbaas-member',
                                                   msg=msg)
                else:
                    msg = (_('Failed to get lb service to attach virtual '
                             'server %(vs)s for member %(member)s') % {
                                 'vs': vs_id,
                                 'member': member['id']
                             })
                    raise nsx_exc.NsxPluginException(err_msg=msg)

            lb_pool = pool_client.get(lb_pool_id)
            old_m = lb_pool.get('members', None)
            new_m = [{
                'display_name': member.name[:219] + '_' + member.id,
                'ip_address': fixed_ip,
                'port': member.protocol_port,
                'weight': member.weight
            }]
            members = (old_m + new_m) if old_m else new_m
            pool_client.update_pool_with_members(lb_pool_id, members)
        else:
            msg = (_('Failed to get pool binding to add member %s') %
                   member['id'])
            raise nsx_exc.NsxPluginException(err_msg=msg)

        self.lbv2_driver.member.successful_completion(context, member)
Exemple #20
0
    def _member_create(self, context, member, completor):
        lb_id = member['pool']['loadbalancer_id']
        pool_id = member['pool']['id']
        loadbalancer = member['pool']['loadbalancer']
        if not lb_utils.validate_lb_member_subnet(
                context, self.core_plugin, member['subnet_id'], loadbalancer):
            completor(success=False)
            msg = (_('Cannot add member %(member)s to pool as member subnet '
                     '%(subnet)s is neither public nor connected to the LB '
                     'router') % {
                         'member': member['id'],
                         'subnet': member['subnet_id']
                     })
            raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg)

        pool_client = self.core_plugin.nsxlib.load_balancer.pool
        service_client = self.core_plugin.nsxlib.load_balancer.service

        network = lb_utils.get_network_from_subnet(context, self.core_plugin,
                                                   member['subnet_id'])
        if network.get('router:external'):
            fixed_ip, router_id = self._get_info_from_fip(
                context, member['address'])
            if not router_id:
                completor(success=False)
                msg = (_('Floating ip %(fip)s has no router') % {
                    'fip': member['address']
                })
                raise n_exc.BadRequest(resource='lbaas-vip', msg=msg)
        else:
            router_id = lb_utils.get_router_from_network(
                context, self.core_plugin, member['subnet_id'])
            fixed_ip = member['address']

        binding = nsx_db.get_nsx_lbaas_pool_binding(context.session, lb_id,
                                                    pool_id)
        if binding:
            vs_id = binding.get('lb_vs_id')
            lb_pool_id = binding.get('lb_pool_id')
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            lb_service = None
            if not lb_binding:
                nsx_router_id = nsx_db.get_nsx_router_id(
                    context.session, router_id)
                lb_service = service_client.get_router_lb_service(
                    nsx_router_id)
                virtual_server_ids = (
                    lb_service and lb_service.get('virtual_server_ids', [])
                    or [])
                if not lb_service:
                    lb_size = lb_utils.get_lb_flavor_size(
                        self.flavor_plugin, context,
                        loadbalancer.get('flavor_id'))
                    if not self.core_plugin.service_router_has_services(
                            context, router_id):
                        self.core_plugin.create_service_router(
                            context, router_id)
                    lb_service = self._create_lb_service(
                        context, service_client, member['tenant_id'],
                        router_id, nsx_router_id, loadbalancer['id'], lb_size)
                if lb_service:
                    lb_service_id = lb_service['id']
                    self._add_loadbalancer_binding(context, loadbalancer['id'],
                                                   lb_service_id,
                                                   nsx_router_id,
                                                   loadbalancer['vip_address'])
                else:
                    completor(success=False)
                    msg = (_('Failed to get lb service to attach virtual '
                             'server %(vs)s for member %(member)s') % {
                                 'vs': vs_id,
                                 'member': member['id']
                             })
                    raise nsx_exc.NsxPluginException(err_msg=msg)

            with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id):
                lb_pool = pool_client.get(lb_pool_id)
                old_m = lb_pool.get('members', None)
                new_m = [{
                    'display_name':
                    member['name'][:219] + '_' + member['id'],
                    'ip_address':
                    fixed_ip,
                    'port':
                    member['protocol_port'],
                    'weight':
                    member['weight']
                }]
                members = (old_m + new_m) if old_m else new_m
                pool_client.update_pool_with_members(lb_pool_id, members)

            # Check whether the virtual server should be added to the load
            # balancing server. It is safe to perform this operation after the
            # member has been added to the pool. This allows us to skip this
            # check if there is already a member in the pool
            if vs_id and not old_m:
                # load the LB service if not already loaded
                if not lb_service:
                    nsx_router_id = nsx_db.get_nsx_router_id(
                        context.session, router_id)
                    lb_service = service_client.get_router_lb_service(
                        nsx_router_id)
                    lb_service_id = lb_service['id']
                    virtual_server_ids = lb_service.get(
                        'virtual_server_ids', [])
                if vs_id not in virtual_server_ids:
                    try:
                        service_client.add_virtual_server(lb_service_id, vs_id)
                    except nsxlib_exc.ManagerError:
                        completor(success=False)
                        msg = (_('Failed to attach virtual server %(vs)s '
                                 'to lb service %(service)s') % {
                                     'vs': vs_id,
                                     'service': lb_service_id
                                 })
                        raise n_exc.BadRequest(resource='lbaas-member',
                                               msg=msg)
        else:
            completor(success=False)
            msg = (_('Failed to get pool binding to add member %s') %
                   member['id'])
            raise nsx_exc.NsxPluginException(err_msg=msg)

        completor(success=True)