예제 #1
0
 def delete(self, context, lb):
     service_client = self.core_plugin.nsxlib.load_balancer.service
     lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
         context.session, lb.id)
     if lb_binding:
         lb_service_id = lb_binding['lb_service_id']
         lb_service = service_client.get(lb_service_id)
         vs_list = lb_service.get('virtual_server_ids')
         if not vs_list:
             try:
                 service_client.delete(lb_service_id)
             except nsxlib_exc.ManagerError:
                 self.lbv2_driver.pool.failed_completion(context,
                                                         lb,
                                                         delete=True)
                 msg = (_('Failed to delete lb service %(lbs)s from nsx') %
                        {
                            'lbs': lb_service_id
                        })
                 raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
         nsx_db.delete_nsx_lbaas_loadbalancer_binding(
             context.session, lb.id)
     self.lbv2_driver.load_balancer.successful_completion(context,
                                                          lb,
                                                          delete=True)
예제 #2
0
 def delete(self, context, lb, completor):
     service_client = self.core_plugin.nsxlib.load_balancer.service
     lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
         context.session, lb['id'])
     if lb_binding:
         lb_service_id = lb_binding['lb_service_id']
         nsx_router_id = lb_binding['lb_router_id']
         try:
             lb_service = service_client.get(lb_service_id)
         except nsxlib_exc.ManagerError:
             LOG.warning("LB service %(lbs)s is not found",
                         {'lbs': lb_service_id})
         else:
             vs_list = lb_service.get('virtual_server_ids')
             if not vs_list:
                 try:
                     service_client.delete(lb_service_id)
                     # If there is no lb service attached to the router,
                     # update the router advertise_lb_vip flag to false.
                     router_client = self.core_plugin.nsxlib.logical_router
                     router_client.update_advertisement(
                         nsx_router_id, advertise_lb_vip=False)
                 except nsxlib_exc.ManagerError:
                     completor(success=False)
                     msg = (
                         _('Failed to delete lb service %(lbs)s from nsx') %
                         {
                             'lbs': lb_service_id
                         })
                     raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
         nsx_db.delete_nsx_lbaas_loadbalancer_binding(
             context.session, lb['id'])
     completor(success=True)
예제 #3
0
    def stats(self, context, lb):
        # Since multiple LBaaS loadbalancer can share the same LB service,
        # get the corresponding virtual servers' stats instead of LB service.
        stats = {'active_connections': 0,
                 'bytes_in': 0,
                 'bytes_out': 0,
                 'total_connections': 0}

        service_client = self.core_plugin.nsxlib.load_balancer.service
        lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, lb['id'])
        vs_list = self._get_lb_virtual_servers(context, lb)
        if lb_binding:
            lb_service_id = lb_binding.get('lb_service_id')
            try:
                rsp = service_client.get_stats(lb_service_id)
                if rsp:
                    for vs in rsp.get('virtual_servers', []):
                        # Skip the virtual server that doesn't belong
                        # to this loadbalancer
                        if vs['virtual_server_id'] not in vs_list:
                            continue
                        vs_stats = vs.get('statistics', {})
                        for stat in lb_const.LB_STATS_MAP:
                            lb_stat = lb_const.LB_STATS_MAP[stat]
                            stats[stat] += vs_stats.get(lb_stat, 0)

            except nsxlib_exc.ManagerError:
                msg = _('Failed to retrieve stats from LB service '
                        'for loadbalancer %(lb)s') % {'lb': lb['id']}
                raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
        return stats
예제 #4
0
    def stats(self, context, lb):
        # Since multiple LBaaS loadbalancer can share the same LB service,
        # get the corresponding virtual servers' stats instead of LB service.
        stats = {'active_connections': 0,
                 'bytes_in': 0,
                 'bytes_out': 0,
                 'total_connections': 0}

        service_client = self.core_plugin.nsxlib.load_balancer.service
        for listener in lb.listeners:
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb.id)
            vs_binding = nsx_db.get_nsx_lbaas_listener_binding(
                context.session, lb.id, listener.id)
            if lb_binding and vs_binding:
                lb_service_id = lb_binding.get('lb_service_id')
                vs_id = vs_binding.get('lb_vs_id')
                try:
                    rsp = service_client.get_stats(lb_service_id)
                    if rsp:

                        vs_stats = rsp['virtual_servers'][vs_id]['statistics']
                        for stat in lb_const.LB_STATS_MAP:
                            lb_stat = lb_const.LB_STATS_MAP[stat]
                            if lb_stat in vs_stats:
                                stats[stat] += stats[stat] + vs_stats[lb_stat]

                except nsxlib_exc.ManagerError:
                    msg = _('Failed to retrieve stats from LB service '
                            'for loadbalancer %(lb)s') % {'lb': lb.id}
                    raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
        return stats
예제 #5
0
    def create(self, context, listener, completor, certificate=None):
        lb_id = listener['loadbalancer_id']
        nsxlib_lb = self.core_plugin.nsxlib.load_balancer
        app_client = nsxlib_lb.application_profile
        vs_client = nsxlib_lb.virtual_server
        service_client = nsxlib_lb.service
        vs_name = utils.get_name_and_uuid(listener['name'] or 'listener',
                                          listener['id'])
        tags = self._get_listener_tags(context, listener)

        if (listener['protocol'] == lb_const.LB_PROTOCOL_HTTP or
                listener['protocol'] == lb_const.LB_PROTOCOL_TERMINATED_HTTPS):
            profile_type = lb_const.LB_HTTP_PROFILE
        elif (listener['protocol'] == lb_const.LB_PROTOCOL_TCP
              or listener['protocol'] == lb_const.LB_PROTOCOL_HTTPS):
            profile_type = lb_const.LB_TCP_PROFILE
        else:
            msg = (_('Cannot create listener %(listener)s with '
                     'protocol %(protocol)s') % {
                         'listener': listener['id'],
                         'protocol': listener['protocol']
                     })
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
        try:
            app_profile = app_client.create(display_name=vs_name,
                                            resource_type=profile_type,
                                            tags=tags)
            app_profile_id = app_profile['id']
            kwargs = self._get_virtual_server_kwargs(context, listener,
                                                     vs_name, tags,
                                                     app_profile_id,
                                                     certificate)
            virtual_server = vs_client.create(**kwargs)
        except nsxlib_exc.ManagerError:
            completor(success=False)
            msg = _('Failed to create virtual server at NSX backend')
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        # If there is already lb:lb_service binding, add the virtual
        # server to the lb service
        binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, lb_id)
        if binding:
            lb_service_id = binding['lb_service_id']
            try:
                service_client.add_virtual_server(lb_service_id,
                                                  virtual_server['id'])
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = _('Failed to add virtual server to lb service '
                        'at NSX backend')
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        nsx_db.add_nsx_lbaas_listener_binding(context.session, lb_id,
                                              listener['id'], app_profile_id,
                                              virtual_server['id'])
        completor(success=True)
예제 #6
0
    def delete(self, context, pool):
        lb_id = pool.loadbalancer_id
        pool_client = self.core_plugin.nsxlib.load_balancer.pool
        vs_client = self.core_plugin.nsxlib.load_balancer.virtual_server
        service_client = self.core_plugin.nsxlib.load_balancer.service

        binding = nsx_db.get_nsx_lbaas_pool_binding(
            context.session, lb_id, pool.id)
        if binding:
            vs_id = binding['lb_vs_id']
            lb_pool_id = binding['lb_pool_id']
            try:
                vs_client.update(vs_id, pool_id='')
            except nsxlib_exc.ManagerError:
                self.lbv2_driver.pool.failed_completion(context, pool)
                msg = _('Failed to remove lb pool %(pool)s from virtual '
                        'server %(vs)s') % {'pool': lb_pool_id,
                                            'vs': vs_id}
                raise n_exc.BadRequest(resource='lbaas-pool', msg=msg)
            try:
                pool_client.delete(lb_pool_id)
            except nsxlib_exc.ManagerError:
                self.lbv2_driver.pool.failed_completion(context, pool)
                msg = (_('Failed to delete lb pool from nsx: %(pool)s') %
                       {'pool': lb_pool_id})
                raise n_exc.BadRequest(resource='lbaas-pool', msg=msg)
            nsx_db.delete_nsx_lbaas_pool_binding(context.session,
                                                 lb_id, pool.id)
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if lb_binding:
                lb_service_id = lb_binding['lb_service_id']
                try:
                    lb_service = service_client.get(lb_service_id)
                    vs_list = lb_service.get('virtual_server_ids')
                    if vs_list and vs_id in vs_list:
                        vs_list.remove(vs_id)
                    else:
                        LOG.debug('virtual server id %s is not in the lb '
                                  'service virtual server list %s',
                                  vs_id, vs_list)
                    service_client.update(lb_service_id,
                                          virtual_server_ids=vs_list)
                    if not vs_list:
                        service_client.delete(lb_service_id)
                        nsx_db.delete_nsx_lbaas_loadbalancer_binding(
                            context.session, lb_id)
                except nsxlib_exc.ManagerError:
                    self.lbv2_driver.pool.failed_completion(context, pool)
                    msg = (_('Failed to delete lb pool from nsx: %(pool)s') %
                           {'pool': lb_pool_id})
                    raise n_exc.BadRequest(resource='lbaas-pool', msg=msg)

        self.lbv2_driver.pool.successful_completion(
            context, pool, delete=True)
예제 #7
0
 def _add_loadbalancer_binding(self, context, lb_id, lbs_id, nsx_router_id,
                               vip_address):
     # First check if there is already binding for the lb.
     # If there is no binding for the lb, add the db binding.
     binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
         context.session, lb_id)
     if not binding:
         nsx_db.add_nsx_lbaas_loadbalancer_binding(context.session, lb_id,
                                                   lbs_id, nsx_router_id,
                                                   vip_address)
     else:
         LOG.debug("LB binding has already been added, and no need "
                   "to add here.")
예제 #8
0
 def delete(self, context, lb, completor):
     service_client = self.core_plugin.nsxlib.load_balancer.service
     router_client = self.core_plugin.nsxlib.logical_router
     lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
         context.session, lb['id'])
     if lb_binding:
         lb_service_id = lb_binding['lb_service_id']
         nsx_router_id = lb_binding['lb_router_id']
         try:
             lb_service = service_client.get(lb_service_id)
         except nsxlib_exc.ManagerError:
             LOG.warning("LB service %(lbs)s is not found",
                         {'lbs': lb_service_id})
         else:
             vs_list = lb_service.get('virtual_server_ids')
             if not vs_list:
                 try:
                     service_client.delete(lb_service_id)
                     # If there is no lb service attached to the router,
                     # delete the router advertise_lb_vip rule.
                     if nsx_router_id != lb_utils.NO_ROUTER_ID:
                         router_client.update_advertisement_rules(
                             nsx_router_id, [],
                             name_prefix=lb_utils.ADV_RULE_NAME)
                 except nsxlib_exc.ManagerError:
                     completor(success=False)
                     msg = (
                         _('Failed to delete lb service %(lbs)s from nsx') %
                         {
                             'lbs': lb_service_id
                         })
                     raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
         nsx_db.delete_nsx_lbaas_loadbalancer_binding(
             context.session, lb['id'])
         if nsx_router_id != lb_utils.NO_ROUTER_ID:
             router_id = nsx_db.get_neutron_from_nsx_router_id(
                 context.session, nsx_router_id)
             # Service router is needed only when the LB exist, and
             # no other services are using it.
             if not self.core_plugin.service_router_has_services(
                     context, router_id):
                 self.core_plugin.delete_service_router(context, router_id)
     completor(success=True)
예제 #9
0
 def delete(self, context, lb, completor):
     service_client = self.core_plugin.nsxlib.load_balancer.service
     router_client = self.core_plugin.nsxlib.logical_router
     lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
         context.session, lb['id'])
     if lb_binding:
         lb_service_id = lb_binding['lb_service_id']
         nsx_router_id = lb_binding['lb_router_id']
         try:
             lb_service = service_client.get(lb_service_id)
         except nsxlib_exc.ManagerError:
             LOG.warning("LB service %(lbs)s is not found",
                         {'lbs': lb_service_id})
         else:
             vs_list = lb_service.get('virtual_server_ids')
             if not vs_list:
                 try:
                     service_client.delete(lb_service_id)
                     # If there is no lb service attached to the router,
                     # delete the router advertise_lb_vip rule.
                     if nsx_router_id != lb_utils.NO_ROUTER_ID:
                         router_client.update_advertisement_rules(
                             nsx_router_id, [],
                             name_prefix=lb_utils.ADV_RULE_NAME)
                 except nsxlib_exc.ManagerError:
                     completor(success=False)
                     msg = (_('Failed to delete lb service %(lbs)s from nsx'
                              ) % {'lbs': lb_service_id})
                     raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
         nsx_db.delete_nsx_lbaas_loadbalancer_binding(
             context.session, lb['id'])
         if nsx_router_id != lb_utils.NO_ROUTER_ID:
             router_id = nsx_db.get_neutron_from_nsx_router_id(
                 context.session, nsx_router_id)
             # Service router is needed only when the LB exist, and
             # no other services are using it.
             if not self.core_plugin.service_router_has_services(
                     context,
                     router_id):
                 self.core_plugin.delete_service_router(context,
                                                        router_id)
     completor(success=True)
예제 #10
0
    def stats(self, context, lb):
        # Since multiple LBaaS loadbalancer can share the same LB service,
        # get the corresponding virtual servers' stats instead of LB service.
        stats = {
            'active_connections': 0,
            'bytes_in': 0,
            'bytes_out': 0,
            'total_connections': 0
        }

        service_client = self.core_plugin.nsxlib.load_balancer.service
        lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, lb['id'])
        vs_list = self._get_lb_virtual_servers(context, lb)
        if lb_binding:
            lb_service_id = lb_binding.get('lb_service_id')
            try:
                rsp = service_client.get_stats(lb_service_id)
                if rsp:
                    for vs in rsp['virtual_servers']:
                        # Skip the virtual server that doesn't belong
                        # to this loadbalancer
                        if vs['virtual_server_id'] not in vs_list:
                            continue
                        vs_stats = vs['statistics']
                        for stat in lb_const.LB_STATS_MAP:
                            lb_stat = lb_const.LB_STATS_MAP[stat]
                            stats[stat] += vs_stats[lb_stat]

            except nsxlib_exc.ManagerError:
                msg = _('Failed to retrieve stats from LB service '
                        'for loadbalancer %(lb)s') % {
                            'lb': lb['id']
                        }
                raise n_exc.BadRequest(resource='lbaas-lb', msg=msg)
        return stats
예제 #11
0
    def create(self, context, listener, certificate=None):
        lb_id = listener.loadbalancer_id
        vip_address = listener.loadbalancer.vip_address
        load_balancer = self.core_plugin.nsxlib.load_balancer
        app_client = load_balancer.application_profile
        vs_client = load_balancer.virtual_server
        service_client = load_balancer.service
        vs_name = utils.get_name_and_uuid(listener.name, listener.id)
        tags = lb_utils.get_tags(self.core_plugin, listener.id,
                                 lb_const.LB_LISTENER_TYPE, listener.tenant_id,
                                 context.project_name)
        tags.append({
            'scope': 'os-lbaas-lb-name',
            'tag': listener.loadbalancer.name
        })
        tags.append({'scope': 'os-lbaas-lb-id', 'tag': lb_id})
        if listener.protocol == 'HTTP' or listener.protocol == 'HTTPS':
            profile_type = lb_const.LB_HTTP_PROFILE
        elif listener.protocol == 'TCP':
            profile_type = lb_const.LB_TCP_PROFILE
        else:
            msg = (_('Cannot create listener %(listener)s with '
                     'protocol %(protocol)s') % {
                         'listener': listener.id,
                         'protocol': listener.protocol
                     })
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
        try:
            app_profile = app_client.create(display_name=vs_name,
                                            resource_type=profile_type,
                                            tags=tags)
            app_profile_id = app_profile['id']
            virtual_server = vs_client.create(
                display_name=vs_name,
                tags=tags,
                enabled=listener.admin_state_up,
                ip_address=vip_address,
                port=listener.protocol_port,
                application_profile_id=app_profile_id)
        except nsxlib_exc.ManagerError:
            self.lbv2_driver.listener.failed_completion(context, listener)
            msg = _('Failed to create virtual server at NSX backend')
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        # If there is already lb:lb_service binding, add the virtual
        # server to the lb service
        binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, lb_id)
        if binding:
            lb_service_id = binding['lb_service_id']
            try:
                service_client.add_virtual_server(lb_service_id,
                                                  virtual_server['id'])
            except nsxlib_exc.ManagerError:
                self.lbv2_driver.listener.failed_completion(context, listener)
                msg = _('Failed to add virtual server to lb service '
                        'at NSX backend')
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        nsx_db.add_nsx_lbaas_listener_binding(context.session, lb_id,
                                              listener.id, app_profile_id,
                                              virtual_server['id'])
        self.lbv2_driver.listener.successful_completion(context, listener)
예제 #12
0
    def delete(self, context, listener):
        lb_id = listener.loadbalancer_id
        load_balancer = self.core_plugin.nsxlib.load_balancer
        service_client = load_balancer.service
        vs_client = load_balancer.virtual_server
        app_client = load_balancer.application_profile

        binding = nsx_db.get_nsx_lbaas_listener_binding(
            context.session, lb_id, listener.id)
        if binding:
            vs_id = binding['lb_vs_id']
            app_profile_id = binding['app_profile_id']
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if lb_binding:
                try:
                    lbs_id = lb_binding.get('lb_service_id')
                    lb_service = service_client.get(lbs_id)
                    vs_list = lb_service.get('virtual_server_ids')
                    if vs_list and vs_id in vs_list:
                        service_client.remove_virtual_server(lbs_id, vs_id)
                except nsxlib_exc.ManagerError:
                    self.lbv2_driver.listener.failed_completion(
                        context, listener)
                    msg = (_('Failed to remove virtual server: %(listener)s '
                             'from lb service %(lbs)s') % {
                                 'listener': listener.id,
                                 'lbs': lbs_id
                             })
                    raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                if listener.default_pool_id:
                    vs_client.update(vs_id, pool_id='')
                    # Update pool binding to disassociate virtual server
                    pool_binding = nsx_db.get_nsx_lbaas_pool_binding(
                        context.session, lb_id, listener.default_pool_id)
                    if pool_binding:
                        nsx_db.update_nsx_lbaas_pool_binding(
                            context.session, lb_id, listener.default_pool_id,
                            None)
                vs_client.delete(vs_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("virtual server not found on nsx: %(vs)s") % {
                    'vs': vs_id
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                self.lbv2_driver.listener.failed_completion(context, listener)
                msg = (_('Failed to delete virtual server: %(listener)s') % {
                    'listener': listener.id
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                app_client.delete(app_profile_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("application profile not found on nsx: %s") %
                       app_profile_id)
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                self.lbv2_driver.listener.failed_completion(context, listener)
                msg = (_('Failed to delete application profile: %(app)s') % {
                    'app': app_profile_id
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            nsx_db.delete_nsx_lbaas_listener_binding(context.session, lb_id,
                                                     listener.id)

        self.lbv2_driver.listener.successful_completion(context,
                                                        listener,
                                                        delete=True)
예제 #13
0
    def delete(self, context, listener, completor):
        lb_id = listener['loadbalancer_id']
        nsxlib_lb = self.core_plugin.nsxlib.load_balancer
        service_client = nsxlib_lb.service
        vs_client = nsxlib_lb.virtual_server
        app_client = nsxlib_lb.application_profile

        binding = nsx_db.get_nsx_lbaas_listener_binding(
            context.session, lb_id, listener['id'])
        if binding:
            vs_id = binding['lb_vs_id']
            app_profile_id = binding['app_profile_id']
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if not lb_binding:
                completor(success=False)
                msg = (_('Failed to delete virtual server: %(listener)s: '
                         'loadbalancer %(lb)s mapping was not found') %
                       {'listener': listener['id'], 'lb': lb_id})
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                lbs_id = lb_binding.get('lb_service_id')
                lb_service = service_client.get(lbs_id)
                vs_list = lb_service.get('virtual_server_ids')
                if vs_list and vs_id in vs_list:
                    service_client.remove_virtual_server(lbs_id, vs_id)
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = (_('Failed to remove virtual server: %(listener)s '
                         'from lb service %(lbs)s') %
                       {'listener': listener['id'], 'lbs': lbs_id})
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                persist_profile_id = None
                if listener.get('default_pool_id'):
                    vs_data = vs_client.update(vs_id, pool_id='')
                    persist_profile_id = vs_data.get('persistence_profile_id')
                    # Update pool binding to disassociate virtual server
                    self._remove_default_pool_binding(context, listener)
                vs_client.delete(vs_id)
                # Also delete the old session persistence profile
                if persist_profile_id:
                    lb_utils.delete_persistence_profile(
                        self.core_plugin.nsxlib, persist_profile_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("virtual server not found on nsx: %(vs)s") %
                       {'vs': vs_id})
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = (_('Failed to delete virtual server: %(listener)s') %
                       {'listener': listener['id']})
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                app_client.delete(app_profile_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("application profile not found on nsx: %s") %
                       app_profile_id)
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = (_('Failed to delete application profile: %(app)s') %
                       {'app': app_profile_id})
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

            # Delete imported NSX cert if there is any
            cert_tags = [{'scope': lb_const.LB_LISTENER_TYPE,
                          'tag': listener['id']}]
            results = self.core_plugin.nsxlib.search_by_tags(
                tags=cert_tags)
            # Only delete object related to certificate used by listener
            for res_obj in results['results']:
                res_type = res_obj.get('resource_type')
                if res_type in lb_const.LB_CERT_RESOURCE_TYPE:
                    tm_client = self.core_plugin.nsxlib.trust_management
                    try:
                        tm_client.delete_cert(res_obj['id'])
                    except nsxlib_exc.ManagerError:
                        LOG.error("Exception thrown when trying to delete "
                                  "certificate: %(cert)s",
                                  {'cert': res_obj['id']})

            nsx_db.delete_nsx_lbaas_listener_binding(
                context.session, lb_id, listener['id'])

        completor(success=True)
예제 #14
0
    def create(self, context, listener, completor,
               certificate=None):
        lb_id = listener['loadbalancer_id']
        nsxlib_lb = self.core_plugin.nsxlib.load_balancer
        app_client = nsxlib_lb.application_profile
        vs_client = nsxlib_lb.virtual_server
        service_client = nsxlib_lb.service
        vs_name = utils.get_name_and_uuid(listener['name'] or 'listener',
                                          listener['id'])
        tags = self._get_listener_tags(context, listener)

        if (listener['protocol'] == lb_const.LB_PROTOCOL_HTTP or
                listener['protocol'] == lb_const.LB_PROTOCOL_TERMINATED_HTTPS):
            profile_type = lb_const.LB_HTTP_PROFILE
        elif (listener['protocol'] == lb_const.LB_PROTOCOL_TCP or
              listener['protocol'] == lb_const.LB_PROTOCOL_HTTPS):
            profile_type = lb_const.LB_TCP_PROFILE
        else:
            completor(success=False)
            msg = (_('Cannot create listener %(listener)s with '
                     'protocol %(protocol)s') %
                   {'listener': listener['id'],
                    'protocol': listener['protocol']})
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
        # Validate default pool
        self._validate_default_pool(context, listener, None, completor)
        try:
            app_profile = app_client.create(
                display_name=vs_name, resource_type=profile_type, tags=tags)
            app_profile_id = app_profile['id']
            kwargs = self._get_virtual_server_kwargs(
                context, listener, vs_name, tags, app_profile_id, certificate)
            virtual_server = vs_client.create(**kwargs)
        except nsxlib_exc.ManagerError:
            completor(success=False)
            msg = _('Failed to create virtual server at NSX backend')
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        # If there is already lb:lb_service binding, add the virtual
        # server to the lb service
        binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, lb_id)
        if not binding:
            completor(success=False)
            msg = _('Failed to get loadbalancer %s binding') % lb_id
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        lb_service_id = binding['lb_service_id']
        try:
            service_client.add_virtual_server(lb_service_id,
                                              virtual_server['id'])
        except nsxlib_exc.ManagerError:
            completor(success=False)
            msg = _('Failed to add virtual server to lb service '
                    'at NSX backend')
            raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

        nsx_db.add_nsx_lbaas_listener_binding(
            context.session, lb_id, listener['id'], app_profile_id,
            virtual_server['id'])
        self._update_default_pool_and_binding(
            context, listener, virtual_server, completor)
        completor(success=True)
예제 #15
0
    def delete(self, context, listener, completor):
        lb_id = listener['loadbalancer_id']
        nsxlib_lb = self.core_plugin.nsxlib.load_balancer
        service_client = nsxlib_lb.service
        vs_client = nsxlib_lb.virtual_server
        app_client = nsxlib_lb.application_profile

        binding = nsx_db.get_nsx_lbaas_listener_binding(
            context.session, lb_id, listener['id'])
        if binding:
            vs_id = binding['lb_vs_id']
            app_profile_id = binding['app_profile_id']
            lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                context.session, lb_id)
            if lb_binding:
                try:
                    lbs_id = lb_binding.get('lb_service_id')
                    lb_service = service_client.get(lbs_id)
                    vs_list = lb_service.get('virtual_server_ids')
                    if vs_list and vs_id in vs_list:
                        service_client.remove_virtual_server(lbs_id, vs_id)
                except nsxlib_exc.ManagerError:
                    completor(success=False)
                    msg = (_('Failed to remove virtual server: %(listener)s '
                             'from lb service %(lbs)s') % {
                                 'listener': listener['id'],
                                 'lbs': lbs_id
                             })
                    raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                if listener.get('default_pool_id'):
                    vs_client.update(vs_id, pool_id='')
                    # Update pool binding to disassociate virtual server
                    pool_binding = nsx_db.get_nsx_lbaas_pool_binding(
                        context.session, lb_id, listener['default_pool_id'])
                    if pool_binding:
                        nsx_db.update_nsx_lbaas_pool_binding(
                            context.session, lb_id,
                            listener['default_pool_id'], None)
                vs_client.delete(vs_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("virtual server not found on nsx: %(vs)s") % {
                    'vs': vs_id
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = (_('Failed to delete virtual server: %(listener)s') % {
                    'listener': listener['id']
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            try:
                app_client.delete(app_profile_id)
            except nsx_exc.NsxResourceNotFound:
                msg = (_("application profile not found on nsx: %s") %
                       app_profile_id)
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)
            except nsxlib_exc.ManagerError:
                completor(success=False)
                msg = (_('Failed to delete application profile: %(app)s') % {
                    'app': app_profile_id
                })
                raise n_exc.BadRequest(resource='lbaas-listener', msg=msg)

            # Delete imported NSX cert if there is any
            cert_tags = [{
                'scope': lb_const.LB_LISTENER_TYPE,
                'tag': listener['id']
            }]
            results = self.core_plugin.nsxlib.search_by_tags(tags=cert_tags)
            # Only delete object related to certificate used by listener
            for res_obj in results['results']:
                res_type = res_obj.get('resource_type')
                if res_type in lb_const.LB_CERT_RESOURCE_TYPE:
                    tm_client = self.core_plugin.nsxlib.trust_management
                    try:
                        tm_client.delete_cert(res_obj['id'])
                    except nsxlib_exc.ManagerError:
                        LOG.error(
                            "Exception thrown when trying to delete "
                            "certificate: %(cert)s", {'cert': res_obj['id']})

            nsx_db.delete_nsx_lbaas_listener_binding(context.session, lb_id,
                                                     listener['id'])

        completor(success=True)
예제 #16
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)
예제 #17
0
    def get_operating_status(self, context, id, with_members=False):
        """Return a map of the operating status of all connected LB objects """
        service_client = self.core_plugin.nsxlib.load_balancer.service
        lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, id)
        if not lb_binding:
            LOG.warning("Failed to get loadbalancer %s operating status. "
                        "Mapping was not found", id)
            return {}

        lb_service_id = lb_binding['lb_service_id']
        try:
            service_status = service_client.get_status(lb_service_id)
            if not isinstance(service_status, dict):
                service_status = {}

            vs_statuses = service_client.get_virtual_servers_status(
                lb_service_id)
            if not isinstance(vs_statuses, dict):
                vs_statuses = {}
        except nsxlib_exc.ManagerError:
            LOG.warning("LB service %(lbs)s is not found",
                        {'lbs': lb_service_id})
            return {}

        # get the loadbalancer status from the LB service
        lb_status = self._nsx_status_to_lb_status(
            service_status.get('service_status'))
        statuses = {lb_const.LOADBALANCERS: [{'id': id, 'status': lb_status}],
                    lb_const.LISTENERS: [],
                    lb_const.POOLS: [],
                    lb_const.MEMBERS: []}

        # Add the listeners statuses from the virtual servers statuses
        for vs in vs_statuses.get('results', []):
            vs_status = self._nsx_status_to_lb_status(vs.get('status'))
            vs_id = vs.get('virtual_server_id')
            list_binding = nsx_db.get_nsx_lbaas_listener_binding_by_lb_and_vs(
                context.session, id, vs_id)
            if list_binding:
                listener_id = list_binding['listener_id']
                statuses[lb_const.LISTENERS].append(
                    {'id': listener_id, 'status': vs_status})

        # Add the pools statuses from the LB service status
        for pool in service_status.get('pools', []):
            nsx_pool_id = pool.get('pool_id')
            pool_status = self._nsx_status_to_lb_status(pool.get('status'))
            pool_binding = nsx_db.get_nsx_lbaas_pool_binding_by_lb_pool(
                context.session, id, nsx_pool_id)
            if pool_binding:
                pool_id = pool_binding['pool_id']
                statuses[lb_const.POOLS].append(
                    {'id': pool_id, 'status': pool_status})
                # Add the pools members
                if with_members and pool.get('members'):
                    statuses[lb_const.MEMBERS].extend(
                        self.get_lb_pool_members_statuses(
                            nsx_pool_id, pool['members']))

        return statuses
예제 #18
0
    def get_operating_status(self, context, id, with_members=False):
        """Return a map of the operating status of all connected LB objects """
        service_client = self.core_plugin.nsxlib.load_balancer.service
        lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
            context.session, id)
        if not lb_binding:
            LOG.warning(
                "Failed to get loadbalancer %s operating status. "
                "Mapping was not found", id)
            return {}

        lb_service_id = lb_binding['lb_service_id']
        try:
            service_status = service_client.get_status(lb_service_id)
            if not isinstance(service_status, dict):
                service_status = {}

            vs_statuses = service_client.get_virtual_servers_status(
                lb_service_id)
            if not isinstance(vs_statuses, dict):
                vs_statuses = {}
        except nsxlib_exc.ManagerError:
            LOG.warning("LB service %(lbs)s is not found",
                        {'lbs': lb_service_id})
            return {}

        # get the loadbalancer status from the LB service
        lb_status = self._nsx_status_to_lb_status(
            service_status.get('service_status'))
        statuses = {
            lb_const.LOADBALANCERS: [{
                'id': id,
                'status': lb_status
            }],
            lb_const.LISTENERS: [],
            lb_const.POOLS: [],
            lb_const.MEMBERS: []
        }

        # Add the listeners statuses from the virtual servers statuses
        for vs in vs_statuses.get('results', []):
            vs_status = self._nsx_status_to_lb_status(vs.get('status'))
            vs_id = vs.get('virtual_server_id')
            list_binding = nsx_db.get_nsx_lbaas_listener_binding_by_lb_and_vs(
                context.session, id, vs_id)
            if list_binding:
                listener_id = list_binding['listener_id']
                statuses[lb_const.LISTENERS].append({
                    'id': listener_id,
                    'status': vs_status
                })

        # Add the pools statuses from the LB service status
        for pool in service_status.get('pools', []):
            nsx_pool_id = pool.get('pool_id')
            pool_status = self._nsx_status_to_lb_status(pool.get('status'))
            pool_binding = nsx_db.get_nsx_lbaas_pool_binding_by_lb_pool(
                context.session, id, nsx_pool_id)
            if pool_binding:
                pool_id = pool_binding['pool_id']
                statuses[lb_const.POOLS].append({
                    'id': pool_id,
                    'status': pool_status
                })
                # Add the pools members
                if with_members and pool.get('members'):
                    statuses[lb_const.MEMBERS].extend(
                        self.get_lb_pool_members_statuses(
                            nsx_pool_id, pool['members']))

        return statuses
예제 #19
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)
예제 #20
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)
예제 #21
0
 def delete(self, context, member):
     lb_id = member.pool.loadbalancer_id
     pool_id = member.pool.id
     service_client = self.core_plugin.nsxlib.load_balancer.service
     pool_client = self.core_plugin.nsxlib.load_balancer.pool
     pool_members = self.lbv2_driver.plugin.get_pool_members(
         context, pool_id)
     pool_binding = nsx_db.get_nsx_lbaas_pool_binding(
         context.session, lb_id, pool_id)
     if pool_binding:
         lb_pool_id = pool_binding['lb_pool_id']
         lb_vs_id = pool_binding['lb_vs_id']
         # If this is the last member of pool, detach virtual server from
         # the lb service. If this is the last load balancer for this lb
         # service, delete the lb service as well.
         if len(pool_members) == 1:
             lb_binding = nsx_db.get_nsx_lbaas_loadbalancer_binding(
                 context.session, lb_id)
             if lb_binding:
                 lb_service_id = lb_binding['lb_service_id']
                 try:
                     lb_service = service_client.get(lb_service_id)
                     vs_list = lb_service.get('virtual_server_ids')
                     if vs_list and lb_vs_id in vs_list:
                         vs_list.remove(lb_vs_id)
                     else:
                         LOG.error(
                             'virtual server id %s is not in the lb '
                             'service virtual server list %s', lb_vs_id,
                             vs_list)
                     service_client.update(lb_service_id,
                                           virtual_server_ids=vs_list)
                     if not vs_list:
                         service_client.delete(lb_service_id)
                         nsx_db.delete_nsx_lbaas_loadbalancer_binding(
                             context.session, lb_id)
                 except nsxlib_exc.ManagerError:
                     self.lbv2_driver.member.failed_completion(
                         context, member)
                     msg = _('Failed to remove virtual server from lb '
                             'service on NSX backend')
                     raise n_exc.BadRequest(resource='lbaas-member',
                                            msg=msg)
         try:
             lb_pool = pool_client.get(lb_pool_id)
             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)
             else:
                 fixed_ip = member.address
             if 'members' in lb_pool:
                 m_list = lb_pool['members']
                 members = [
                     m for m in m_list if m['ip_address'] != fixed_ip
                 ]
                 pool_client.update_pool_with_members(lb_pool_id, members)
         except nsxlib_exc.ManagerError:
             self.lbv2_driver.member.failed_completion(context, member)
             msg = _('Failed to remove member from pool on NSX backend')
             raise n_exc.BadRequest(resource='lbaas-member', msg=msg)
     self.lbv2_driver.member.successful_completion(context,
                                                   member,
                                                   delete=True)