def delete(self, context, member, completor): lb_id = member['pool']['loadbalancer_id'] pool_id = member['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') try: with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id): 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.ResourceNotFound: pass except nsxlib_exc.ManagerError: completor(success=False) msg = _('Failed to remove member from pool on NSX backend') raise n_exc.BadRequest(resource='lbaas-member', msg=msg) completor(success=True)
def update(self, context, old_member, new_member, completor): lb_id = old_member['pool']['loadbalancer_id'] pool_id = old_member['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') try: with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id): lb_pool = pool_client.get(lb_pool_id) updated_members = self._get_updated_pool_members( context, lb_pool, new_member) pool_client.update_pool_with_members( lb_pool_id, updated_members) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to update member %(member)s: ' '%(err)s', { 'member': old_member['id'], 'err': e }) completor(success=True)
def delete(self, context, member, completor): lb_id = member['pool']['loadbalancer_id'] pool_id = member['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') try: with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id): 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.ResourceNotFound: pass except nsxlib_exc.ManagerError: completor(success=False) msg = _('Failed to remove member from pool on NSX backend') raise n_exc.BadRequest(resource='lbaas-member', msg=msg) completor(success=True)
def update(self, context, old_pool, new_pool, completor): pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_name = None tags = None lb_algorithm = None if new_pool['name'] != old_pool['name']: pool_name = utils.get_name_and_uuid(new_pool['name'] or 'pool', new_pool['id']) tags = self._get_pool_tags(context, new_pool) if new_pool['lb_algorithm'] != old_pool['lb_algorithm']: lb_algorithm = lb_const.LB_POOL_ALGORITHM_MAP.get( new_pool['lb_algorithm']) binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, old_pool['loadbalancer_id'], old_pool['id']) if not binding: msg = (_('Cannot find pool %(pool)s binding on NSX db ' 'mapping') % {'pool': old_pool['id']}) raise n_exc.BadRequest(resource='lbaas-pool', msg=msg) try: lb_pool_id = binding['lb_pool_id'] kwargs = self._get_pool_kwargs(pool_name, tags, lb_algorithm) pool_client.update(lb_pool_id, **kwargs) completor(success=True) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to update pool %(pool)s with ' 'error %(error)s', {'pool': old_pool['id'], 'error': e})
def _convert_l7policy_to_rule(self, context, rule): lb_id = rule.policy.listener.loadbalancer_id body = {} l7policy = rule.policy if l7policy.action == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, l7policy.redirect_pool_id) if pool_binding: lb_pool_id = pool_binding['lb_pool_id'] body['actions'] = [{'type': lb_const.LB_SELECT_POOL_ACTION, 'pool_id': lb_pool_id}] else: msg = _('Failed to get LB pool binding from nsx db') raise n_exc.BadRequest(resource='lbaas-l7rule-create', msg=msg) elif l7policy.action == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL: body['actions'] = [{'type': lb_const.LB_HTTP_REDIRECT_ACTION, 'redirect_rul': l7policy.redirect_url}] elif l7policy.action == lb_const.L7_POLICY_ACTION_REJECT: body['actions'] = [{'type': lb_const.LB_REJECT_ACTION}] else: msg = (_('Invalid l7policy action: %(action)s') % {'action': l7policy.action}) raise n_exc.BadRequest(resource='lbaas-l7rule-create', msg=msg) return body
def delete(self, context, pool, completor): lb_id = pool['loadbalancer_id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool vs_client = self.core_plugin.nsxlib.load_balancer.virtual_server 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') if vs_id: try: vs_client.update(vs_id, pool_id='') except nsxlib_exc.ResourceNotFound: pass except nsxlib_exc.ManagerError: completor(success=False) 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.ResourceNotFound: pass except nsxlib_exc.ManagerError: completor(success=False) 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']) 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 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') if vs_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) self.lbv2_driver.pool.successful_completion(context, pool, delete=True)
def delete(self, context, pool, completor): lb_id = pool['loadbalancer_id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool 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') if vs_id: # NOTE(salv-orlando): Guard against accidental compat breakages try: listener = pool['listener'] or pool['listeners'][0] except IndexError: # If listeners is an empty list we hit this exception listener = None if listener: self._process_vs_update(context, pool, listener, None, vs_id, completor) try: pool_client.delete(lb_pool_id) except nsxlib_exc.ResourceNotFound: pass except nsxlib_exc.ManagerError: completor(success=False) 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']) completor(success=True)
def delete(self, context, member): lb_id = member.pool.loadbalancer_id pool_id = member.pool.id pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') 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)
def _validate_default_pool(self, context, listener, vs_id, completor, old_listener=None): if listener.get('default_pool_id'): pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, listener['loadbalancer']['id'], listener['default_pool_id']) if (pool_binding and pool_binding['lb_vs_id'] and (vs_id is None or pool_binding['lb_vs_id'] != vs_id)): completor(success=False) msg = (_('Default pool %s is already used by another ' 'listener') % listener['default_pool_id']) raise n_exc.BadRequest(resource='lbaas-pool', msg=msg) # Perform additional validation for session persistence before # creating resources in the backend old_pool = None if old_listener: old_pool = old_listener.get('default_pool') lb_utils.validate_session_persistence(listener.get('default_pool'), listener, completor, old_pool=old_pool)
def get_rule_actions(context, l7policy): lb_id = l7policy['listener']['loadbalancer_id'] if l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, l7policy['redirect_pool_id']) if pool_binding: lb_pool_id = pool_binding['lb_pool_id'] actions = [{'type': lb_const.LB_SELECT_POOL_ACTION, 'pool_id': lb_pool_id}] else: msg = _('Failed to get LB pool binding from nsx db') raise n_exc.BadRequest(resource='lbaas-l7rule-create', msg=msg) elif l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL: actions = [{'type': lb_const.LB_HTTP_REDIRECT_ACTION, 'redirect_status': lb_const.LB_HTTP_REDIRECT_STATUS, 'redirect_url': l7policy['redirect_url']}] elif l7policy['action'] == lb_const.L7_POLICY_ACTION_REJECT: actions = [{'type': lb_const.LB_REJECT_ACTION, 'reply_status': lb_const.LB_HTTP_REJECT_STATUS}] else: msg = (_('Invalid l7policy action: %(action)s') % {'action': l7policy['action']}) raise n_exc.BadRequest(resource='lbaas-l7rule-create', msg=msg) return actions
def update(self, context, old_pool, new_pool, completor): pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_name = None tags = None lb_algorithm = None description = None if new_pool['name'] != old_pool['name']: pool_name = utils.get_name_and_uuid(new_pool['name'] or 'pool', new_pool['id']) tags = self._get_pool_tags(context, new_pool) if new_pool['lb_algorithm'] != old_pool['lb_algorithm']: lb_algorithm = lb_const.LB_POOL_ALGORITHM_MAP.get( new_pool['lb_algorithm']) if new_pool.get('description') != old_pool.get('description'): description = new_pool['description'] binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, old_pool['loadbalancer_id'], old_pool['id']) if not binding: msg = (_('Cannot find pool %(pool)s binding on NSX db ' 'mapping') % { 'pool': old_pool['id'] }) raise n_exc.BadRequest(resource='lbaas-pool', msg=msg) # NOTE(salv-orlando): Guard against accidental compat breakages try: listener = new_pool['listener'] or new_pool['listeners'][0] except IndexError: # If listeners is an empty list we hit this exception listener = None # Perform additional validation for session persistence before # operating on resources in the backend self._validate_session_persistence(new_pool, listener, completor, old_pool=old_pool) try: lb_pool_id = binding['lb_pool_id'] kwargs = self._get_pool_kwargs(pool_name, tags, lb_algorithm, description) pool_client.update(lb_pool_id, **kwargs) if (listener and new_pool['session_persistence'] != old_pool['session_persistence']): self._process_vs_update(context, new_pool, listener, lb_pool_id, binding['lb_vs_id'], completor) completor(success=True) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error( 'Failed to update pool %(pool)s with ' 'error %(error)s', { 'pool': old_pool['id'], 'error': e })
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 _remove_default_pool_binding(self, context, listener): if not listener.get('default_pool_id'): return # Remove the current default pool from the DB bindings lb_id = listener['loadbalancer']['id'] pool_id = listener['default_pool_id'] pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: nsx_db.update_nsx_lbaas_pool_binding( context.session, lb_id, pool_id, None)
def _remove_default_pool_binding(self, context, listener): if not listener.get('default_pool_id'): return # Remove the current default pool from the DB bindings lb_id = listener['loadbalancer']['id'] pool_id = listener['default_pool_id'] pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: nsx_db.update_nsx_lbaas_pool_binding(context.session, lb_id, pool_id, None)
def create(self, context, hm, completor): lb_id = hm['pool']['loadbalancer_id'] pool_id = hm['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool monitor_client = self.core_plugin.nsxlib.load_balancer.monitor monitor_name = utils.get_name_and_uuid(hm['name'] or 'monitor', hm['id']) tags = lb_utils.get_tags(self.core_plugin, hm['id'], lb_const.LB_HM_TYPE, hm['tenant_id'], context.project_name) monitor_body = self._build_monitor_args(hm) try: lb_monitor = monitor_client.create(display_name=monitor_name, tags=tags, **monitor_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) binding = nsx_db.get_nsx_lbaas_pool_binding(context.session, lb_id, pool_id) if binding: lb_pool_id = binding['lb_pool_id'] try: pool_client.add_monitor_to_pool(lb_pool_id, lb_monitor['id']) except nsxlib_exc.ManagerError: completor(success=False) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s') % { 'monitor': lb_monitor['id'], 'pool': lb_pool_id } raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) nsx_db.add_nsx_lbaas_monitor_binding(context.session, lb_id, pool_id, hm['id'], lb_monitor['id'], lb_pool_id) else: completor(success=False) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s: NSX pool was not found on the DB') % { 'monitor': hm['id'], 'pool': pool_id } raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) completor(success=True)
def create(self, context, hm, completor): lb_id = hm['pool']['loadbalancer_id'] pool_id = hm['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool monitor_client = self.core_plugin.nsxlib.load_balancer.monitor monitor_name = utils.get_name_and_uuid(hm['name'] or 'monitor', hm['id']) tags = lb_utils.get_tags(self.core_plugin, hm['id'], lb_const.LB_HM_TYPE, hm['tenant_id'], context.project_name) monitor_body = self._build_monitor_args(hm) try: lb_monitor = monitor_client.create( display_name=monitor_name, tags=tags, **monitor_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if binding: lb_pool_id = binding['lb_pool_id'] try: pool_client.add_monitor_to_pool(lb_pool_id, lb_monitor['id']) except nsxlib_exc.ManagerError: completor(success=False) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s') % {'monitor': lb_monitor['id'], 'pool': lb_pool_id} raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) nsx_db.add_nsx_lbaas_monitor_binding( context.session, lb_id, pool_id, hm['id'], lb_monitor['id'], lb_pool_id) else: completor(success=False) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s: NSX pool was not found on the DB') % { 'monitor': hm['id'], 'pool': pool_id} raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) completor(success=True)
def _get_virtual_server_kwargs(self, context, listener, vs_name, tags, app_profile_id, certificate=None): # If loadbalancer vip_port already has floating ip, use floating # IP as the virtual server VIP address. Else, use the loadbalancer # vip_address directly on virtual server. filters = {'port_id': [listener['loadbalancer']['vip_port_id']]} floating_ips = self.core_plugin.get_floatingips(context, filters=filters) if floating_ips: lb_vip_address = floating_ips[0]['floating_ip_address'] else: lb_vip_address = listener['loadbalancer']['vip_address'] kwargs = { 'enabled': listener['admin_state_up'], 'ip_address': lb_vip_address, 'port': listener['protocol_port'], 'application_profile_id': app_profile_id, 'description': listener.get('description') } if vs_name: kwargs['display_name'] = vs_name if tags: kwargs['tags'] = tags if listener['connection_limit'] != -1: kwargs['max_concurrent_connections'] = \ listener['connection_limit'] if listener['default_pool_id']: pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, listener['loadbalancer']['id'], listener['default_pool_id']) if pool_binding: kwargs['pool_id'] = pool_binding.get('lb_pool_id') ssl_profile_binding = self._get_ssl_profile_binding( tags, certificate=certificate) if (listener['protocol'] == lb_const.LB_PROTOCOL_TERMINATED_HTTPS and ssl_profile_binding): kwargs.update(ssl_profile_binding) return kwargs
def _validate_default_pool(self, context, listener, vs_id, completor, old_listener=None): if listener.get('default_pool_id'): pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, listener['loadbalancer']['id'], listener['default_pool_id']) if (pool_binding and pool_binding['lb_vs_id'] and (vs_id is None or pool_binding['lb_vs_id'] != vs_id)): completor(success=False) msg = (_('Default pool %s is already used by another ' 'listener') % listener['default_pool_id']) raise n_exc.BadRequest(resource='lbaas-pool', msg=msg) # Perform additional validation for session persistence before # creating resources in the backend old_pool = None if old_listener: old_pool = old_listener.get('default_pool') lb_utils.validate_session_persistence( listener.get('default_pool'), listener, completor, old_pool=old_pool)
def update(self, context, old_member, new_member, completor): lb_id = old_member['pool']['loadbalancer_id'] pool_id = old_member['pool']['id'] pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') try: with locking.LockManager.get_lock('pool-member-%s' % lb_pool_id): lb_pool = pool_client.get(lb_pool_id) updated_members = self._get_updated_pool_members( context, lb_pool, new_member) pool_client.update_pool_with_members(lb_pool_id, updated_members) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to update member %(member)s: ' '%(err)s', {'member': old_member['id'], 'err': e}) completor(success=True)
def create(self, context, hm): lb_id = hm.pool.loadbalancer_id pool_id = hm.pool.id pool_client = self.core_plugin.nsxlib.load_balancer.pool monitor_client = self.core_plugin.nsxlib.load_balancer.monitor monitor_name = utils.get_name_and_uuid(hm.name or 'monitor', hm.id) tags = lb_utils.get_tags(self.core_plugin, hm.id, lb_const.LB_HM_TYPE, hm.tenant_id, context.project_name) monitor_body = self._build_monitor_args(hm) try: lb_monitor = monitor_client.create(display_name=monitor_name, tags=tags, **monitor_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): self.lbv2_driver.health_monitor.failed_completion(context, hm) binding = nsx_db.get_nsx_lbaas_pool_binding(context.session, lb_id, pool_id) if binding: lb_pool_id = binding['lb_pool_id'] try: pool_client.add_monitor_to_pool(lb_pool_id, lb_monitor['id']) except nsxlib_exc.ManagerError: self.lbv2_driver.health_monitor.failed_completion(context, hm) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s') % { 'monitor': lb_monitor['id'], 'pool': lb_pool_id } raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) nsx_db.add_nsx_lbaas_monitor_binding(context.session, lb_id, pool_id, hm.id, lb_monitor['id'], lb_pool_id) self.lbv2_driver.health_monitor.successful_completion(context, hm)
def _get_virtual_server_kwargs(self, context, listener, vs_name, tags, app_profile_id, certificate=None): # If loadbalancer vip_port already has floating ip, use floating # IP as the virtual server VIP address. Else, use the loadbalancer # vip_address directly on virtual server. filters = {'port_id': [listener['loadbalancer']['vip_port_id']]} floating_ips = self.core_plugin.get_floatingips(context, filters=filters) if floating_ips: lb_vip_address = floating_ips[0]['floating_ip_address'] else: lb_vip_address = listener['loadbalancer']['vip_address'] kwargs = {'enabled': listener['admin_state_up'], 'ip_address': lb_vip_address, 'port': listener['protocol_port'], 'application_profile_id': app_profile_id, 'description': listener.get('description')} if vs_name: kwargs['display_name'] = vs_name if tags: kwargs['tags'] = tags if listener['connection_limit'] != -1: kwargs['max_concurrent_connections'] = \ listener['connection_limit'] if listener['default_pool_id']: pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, listener['loadbalancer']['id'], listener['default_pool_id']) if pool_binding: kwargs['pool_id'] = pool_binding.get('lb_pool_id') ssl_profile_binding = self._get_ssl_profile_binding( tags, certificate=certificate) if (listener['protocol'] == lb_const.LB_PROTOCOL_TERMINATED_HTTPS and ssl_profile_binding): kwargs.update(ssl_profile_binding) return kwargs
def update(self, context, old_member, new_member): lb_id = old_member.pool.loadbalancer_id pool_id = old_member.pool.id pool_client = self.core_plugin.nsxlib.load_balancer.pool pool_binding = nsx_db.get_nsx_lbaas_pool_binding( context.session, lb_id, pool_id) if pool_binding: lb_pool_id = pool_binding.get('lb_pool_id') try: lb_pool = pool_client.get(lb_pool_id) updated_members = self._get_updated_pool_members( context, lb_pool, new_member) pool_client.update_pool_with_members(lb_pool_id, updated_members) except Exception as e: with excutils.save_and_reraise_exception(): self.lbv2_driver.member.failed_completion( context, new_member) LOG.error('Failed to update member %(member)s: ' '%(err)s', { 'member': old_member.id, 'err': e }) self.lbv2_driver.member.successful_completion(context, new_member)
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 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 _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)
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)