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)
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)
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
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
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)
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)
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.")
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)
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)
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
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)
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)
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)
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)
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)
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)
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
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
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)
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)
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)