def create(self, context, lb, completor): lb_id = lb['id'] network = lb_utils.get_network_from_subnet(context, self.core_plugin, lb['vip_subnet_id']) router_id = self._validate_lb_network(context, lb) if not router_id and not network.get('router:external'): completor(success=False) msg = (_('Cannot create a loadbalancer %(lb_id)s on subnet. ' '%(subnet)s is neither public nor connected to the LB ' 'router') % { 'lb_id': lb_id, 'subnet': lb['vip_subnet_id'] }) raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg) if router_id and not self.core_plugin.service_router_has_services( context, router_id): self.core_plugin.create_service_router(context, router_id) lb_name = utils.get_name_and_uuid(lb['name'] or 'lb', lb_id) tags = lb_utils.get_tags(self.core_plugin, router_id if router_id else '', lb_const.LR_ROUTER_TYPE, lb['tenant_id'], context.project_name) lb_size = lb_utils.get_lb_flavor_size(self.flavor_plugin, context, lb.get('flavor_id')) service_client = self.core_plugin.nsxpolicy.load_balancer.lb_service try: if network.get('router:external'): connectivity_path = None else: connectivity_path = self.core_plugin.nsxpolicy.tier1.get_path( router_id) service_client.create_or_overwrite( lb_name, lb_service_id=lb['id'], description=lb['description'], tags=tags, size=lb_size, connectivity_path=connectivity_path) # Add rule to advertise external vips if router_id: p_utils.update_router_lb_vip_advertisement( context, self.core_plugin, router_id) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error( 'Failed to create loadbalancer %(lb)s for lb with ' 'exception %(e)s', { 'lb': lb['id'], 'e': e }) completor(success=True)
def _create_lb_service(self, context, service_client, tenant_id, router_id, nsx_router_id, lb_id, lb_size): router = self.core_plugin.get_router(context, router_id) if not router.get('external_gateway_info'): msg = (_('Tenant router %(router)s does not connect to ' 'external gateway') % { 'router': router['id'] }) raise n_exc.BadRequest(resource='lbaas-lbservice-create', msg=msg) lb_name = utils.get_name_and_uuid(router['name'] or 'router', router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, lb_const.LR_ROUTER_TYPE, tenant_id, context.project_name) attachment = { 'target_id': nsx_router_id, 'target_type': 'LogicalRouter' } try: lb_service = service_client.create(display_name=lb_name, tags=tags, attachment=attachment, size=lb_size) except nsxlib_exc.ManagerError as e: LOG.error("Failed to create LB service: %s", e) return # Add rule to advertise external vips lb_utils.update_router_lb_vip_advertisement(context, self.core_plugin, router, nsx_router_id) return lb_service
def _create_lb_service(self, context, service_client, tenant_id, router_id, nsx_router_id, lb_id, lb_size): """Create NSX LB service for a specific neutron router""" router = self.core_plugin.get_router(context, router_id) if not router.get('external_gateway_info'): msg = (_('Tenant router %(router)s does not connect to ' 'external gateway') % {'router': router['id']}) raise n_exc.BadRequest(resource='lbaas-lbservice-create', msg=msg) lb_name = utils.get_name_and_uuid(router['name'] or 'router', router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, lb_const.LR_ROUTER_TYPE, tenant_id, context.project_name) attachment = {'target_id': nsx_router_id, 'target_type': 'LogicalRouter'} try: lb_service = service_client.create(display_name=lb_name, tags=tags, attachment=attachment, size=lb_size) except nsxlib_exc.ManagerError as e: LOG.error("Failed to create LB service: %s", e) return # Add rule to advertise external vips lb_utils.update_router_lb_vip_advertisement( context, self.core_plugin, router, nsx_router_id) return lb_service
def _create_lb_service(self, context, service_client, tenant_id, router_id, nsx_router_id, lb_id, lb_size): router = self.core_plugin.get_router(context, router_id) if not router.get('external_gateway_info'): msg = (_('Tenant router %(router)s does not connect to ' 'external gateway') % { 'router': router['id'] }) raise n_exc.BadRequest(resource='lbaas-lbservice-create', msg=msg) lb_name = utils.get_name_and_uuid(router['name'] or 'router', router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, lb_const.LR_ROUTER_TYPE, tenant_id, context.project_name) attachment = { 'target_id': nsx_router_id, 'target_type': 'LogicalRouter' } lb_service = service_client.create(display_name=lb_name, tags=tags, attachment=attachment, size=lb_size) # Update router to enable advertise_lb_vip flag self.core_plugin.nsxlib.logical_router.update_advertisement( nsx_router_id, advertise_lb_vip=True) return lb_service
def _get_listener_tags(self, context, listener): 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'][:utils.MAX_TAG_LEN]}) tags.append({ 'scope': 'os-lbaas-lb-id', 'tag': listener['loadbalancer_id']}) return tags
def _get_listener_tags(self, context, listener): 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'][:utils.MAX_TAG_LEN] }) tags.append({ 'scope': 'os-lbaas-lb-id', 'tag': listener['loadbalancer_id'] }) return tags
def create(self, context, lb, completor): lb_id = lb['id'] network = lb_utils.get_network_from_subnet( context, self.core_plugin, lb['vip_subnet_id']) router_id = self._validate_lb_network(context, lb) if not router_id and not network.get('router:external'): completor(success=False) msg = (_('Cannot create a loadbalancer %(lb_id)s on subnet. ' '%(subnet)s is neither public nor connected to the LB ' 'router') % {'lb_id': lb_id, 'subnet': lb['vip_subnet_id']}) raise n_exc.BadRequest(resource='lbaas-subnet', msg=msg) if router_id and not self.core_plugin.service_router_has_services( context, router_id): self.core_plugin.create_service_router(context, router_id) lb_name = utils.get_name_and_uuid(lb['name'] or 'lb', lb_id) tags = lb_utils.get_tags(self.core_plugin, router_id if router_id else '', lb_const.LR_ROUTER_TYPE, lb['tenant_id'], context.project_name) lb_size = lb_utils.get_lb_flavor_size(self.flavor_plugin, context, lb.get('flavor_id')) service_client = self.core_plugin.nsxpolicy.load_balancer.lb_service try: if network.get('router:external'): connectivity_path = None else: connectivity_path = self.core_plugin.nsxpolicy.tier1.get_path( router_id) service_client.create_or_overwrite( lb_name, lb_service_id=lb['id'], description=lb['description'], tags=tags, size=lb_size, connectivity_path=connectivity_path) # Add rule to advertise external vips if router_id: p_utils.update_router_lb_vip_advertisement( context, self.core_plugin, router_id) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to create loadbalancer %(lb)s for lb with ' 'exception %(e)s', {'lb': lb['id'], 'e': e}) completor(success=True)
def _validate_member_lb_connectivity(self, context, member, completor): lb = member['pool'].get('loadbalancer') if not lb: msg = (_('Member %s loadbalancer object is missing') % member['id']) raise n_exc.BadRequest(resource='lbaas-vip', msg=msg) subnet_id = lb.get('vip_subnet_id') network = lb_utils.get_network_from_subnet(context, self.core_plugin, subnet_id) if not network.get('router:external'): return # If VIP is attached to an external network, loadbalancer_mgr might not # attach it to a router. If not, set the LB service connectivity path # to the member subnet's router. service_client = self.core_plugin.nsxpolicy.load_balancer.lb_service service = service_client.get(lb['id']) if not service.get('connectivity_path'): router_id = lb_utils.get_router_from_network( context, self.core_plugin, member['subnet_id']) if not self.core_plugin.service_router_has_services( context, router_id): self.core_plugin.create_service_router(context, router_id) connectivity_path = self.core_plugin.nsxpolicy.tier1.get_path( router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, lb_const.LR_ROUTER_TYPE, lb['tenant_id'], context.project_name) try: service_client.update(lb['id'], tags=tags, connectivity_path=connectivity_path) p_utils.update_router_lb_vip_advertisement( context, self.core_plugin, router_id) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error( 'Failed to set connectivity for loadbalancer ' '%(lb)s on subnet %(sub)s with error %(err)s', { 'lb': lb['id'], 'sub': member['subnet_id'], 'err': e })
def _validate_member_lb_connectivity(self, context, member, completor): lb = member['pool'].get('loadbalancer') if not lb: msg = (_('Member %s loadbalancer object is missing') % member['id']) raise n_exc.BadRequest(resource='lbaas-vip', msg=msg) subnet_id = lb.get('vip_subnet_id') network = lb_utils.get_network_from_subnet( context, self.core_plugin, subnet_id) if not network.get('router:external'): return # If VIP is attached to an external network, loadbalancer_mgr might not # attach it to a router. If not, set the LB service connectivity path # to the member subnet's router. service_client = self.core_plugin.nsxpolicy.load_balancer.lb_service service = service_client.get(lb['id']) if not service.get('connectivity_path'): router_id = lb_utils.get_router_from_network( context, self.core_plugin, member['subnet_id']) if not self.core_plugin.service_router_has_services(context, router_id): self.core_plugin.create_service_router(context, router_id) connectivity_path = self.core_plugin.nsxpolicy.tier1.get_path( router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, lb_const.LR_ROUTER_TYPE, lb['tenant_id'], context.project_name) try: service_client.update(lb['id'], tags=tags, connectivity_path=connectivity_path) p_utils.update_router_lb_vip_advertisement( context, self.core_plugin, router_id) except Exception as e: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to set connectivity for loadbalancer ' '%(lb)s on subnet %(sub)s with error %(err)s', {'lb': lb['id'], 'sub': member['subnet_id'], 'err': e})
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 _create_lb_service_without_router(self, context, service_client, tenant_id, lb, lb_size): """Create NSX LB service for an external VIP This service will not be attached to a router yet, and it will be updated once the first member is created. """ lb_id = lb['id'] lb_name = utils.get_name_and_uuid(lb['name'] or 'loadbalancer', lb_id) tags = lb_utils.get_tags(self.core_plugin, '', lb_const.LR_ROUTER_TYPE, tenant_id, context.project_name) try: lb_service = service_client.create(display_name=lb_name, tags=tags, size=lb_size) except nsxlib_exc.ManagerError as e: LOG.error("Failed to create LB service: %s", e) return return lb_service
def create(self, context, policy, completor): lb_id = policy['listener']['loadbalancer_id'] listener_id = policy['listener_id'] rule_client = self.core_plugin.nsxlib.load_balancer.rule tags = lb_utils.get_tags(self.core_plugin, policy['id'], lb_const.LB_L7POLICY_TYPE, policy['tenant_id'], context.project_name) binding = nsx_db.get_nsx_lbaas_listener_binding( context.session, lb_id, listener_id) if not binding: completor(success=False) msg = _('Cannot find nsx lbaas binding for listener ' '%(listener_id)s') % { 'listener_id': listener_id } raise n_exc.BadRequest(resource='lbaas-l7policy-create', msg=msg) vs_id = binding['lb_vs_id'] rule_body = lb_utils.convert_l7policy_to_lb_rule(context, policy) try: lb_rule = rule_client.create(tags=tags, **rule_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to create lb rule at NSX backend') try: self._update_policy_position(vs_id, lb_rule['id'], policy['position']) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error( 'Failed to add rule %(rule)% to virtual server ' '%(vs)s at NSX backend', { 'rule': lb_rule['id'], 'vs': vs_id }) nsx_db.add_nsx_lbaas_l7policy_binding(context.session, policy['id'], lb_rule['id'], vs_id) completor(success=True)
def _create_lb_service_without_router(self, context, service_client, tenant_id, lb, lb_size): """Create NSX LB service for an external VIP This service will not be attached to a router yet, and it will be updated once the first member is created. """ lb_id = lb['id'] lb_name = utils.get_name_and_uuid(lb['name'] or 'loadbalancer', lb_id) tags = lb_utils.get_tags(self.core_plugin, '', lb_const.LR_ROUTER_TYPE, tenant_id, context.project_name) try: lb_service = service_client.create(display_name=lb_name, tags=tags, size=lb_size) except nsxlib_exc.ManagerError as e: LOG.error("Failed to create LB service: %s", e) return return lb_service
def create(self, context, hm, completor): pool_id = hm['pool']['id'] pool_client = self.core_plugin.nsxpolicy.load_balancer.lb_pool monitor_client = self._get_monitor_policy_client(hm) 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) lb_monitor = None try: lb_monitor = monitor_client.create_or_overwrite( lb_monitor_profile_id=hm['id'], tags=tags, **monitor_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) if pool_id and lb_monitor: try: hm_path = monitor_client.get_path(hm['id']) pool_client.add_monitor_to_pool(pool_id, [hm_path]) except nsxlib_exc.ManagerError: completor(success=False) msg = _('Failed to attach monitor %(monitor)s to pool ' '%(pool)s') % { 'monitor': hm['id'], 'pool': pool_id } raise n_exc.BadRequest(resource='lbaas-hm', msg=msg) 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, policy, completor): lb_id = policy['listener']['loadbalancer_id'] listener_id = policy['listener_id'] rule_client = self.core_plugin.nsxlib.load_balancer.rule tags = lb_utils.get_tags(self.core_plugin, policy['id'], lb_const.LB_L7POLICY_TYPE, policy['tenant_id'], context.project_name) binding = nsx_db.get_nsx_lbaas_listener_binding( context.session, lb_id, listener_id) if not binding: completor(success=False) msg = _('Cannot find nsx lbaas binding for listener ' '%(listener_id)s') % {'listener_id': listener_id} raise n_exc.BadRequest(resource='lbaas-l7policy-create', msg=msg) vs_id = binding['lb_vs_id'] rule_body = lb_utils.convert_l7policy_to_lb_rule(context, policy) try: lb_rule = rule_client.create(tags=tags, **rule_body) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to create lb rule at NSX backend') try: self._update_policy_position(vs_id, lb_rule['id'], policy['position']) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): completor(success=False) LOG.error('Failed to add rule %(rule)% to virtual server ' '%(vs)s at NSX backend', {'rule': lb_rule['id'], 'vs': vs_id}) nsx_db.add_nsx_lbaas_l7policy_binding( context.session, policy['id'], lb_rule['id'], vs_id) completor(success=True)
def _get_pool_tags(self, context, pool): return lb_utils.get_tags(self.core_plugin, pool['id'], lb_const.LB_POOL_TYPE, pool['tenant_id'], context.project_name)
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)