def create(self, context, healthmonitor): """ Create a loadbalancer_healtmonitor object. """ m = healthmonitor['healthmonitor'] tenant_id = self._get_tenant_id_for_create(context, m) project = self._project_read(project_id=tenant_id) uuid = uuidutils.generate_uuid() props = self.make_properties(m) id_perms = IdPermsType(enable=True) monitor_db = LoadbalancerHealthmonitor( uuid, project, loadbalancer_healthmonitor_properties=props, id_perms=id_perms, display_name=m['name']) monitor_db.uuid = uuid try: pool = self._api.loadbalancer_pool_read(id=m['pool_id']) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Pool', id=m['pool_id']) exist_hm_refs = pool.get_loadbalancer_healthmonitor_refs() if exist_hm_refs is not None: raise loadbalancerv2.OneHealthMonitorPerPool( pool_id=m['pool_id'], hm_id=exist_hm_refs[0]['uuid']) self._api.loadbalancer_healthmonitor_create(monitor_db) self._api.ref_update('loadbalancer-pool', m['pool_id'], 'loadbalancer-healthmonitor', uuid, None, 'ADD') return self.make_dict(monitor_db)
def create(self, context, pool_id, member): """ Create a loadbalancer_member object. """ m = member['member'] try: pool = self._api.loadbalancer_pool_read(id=pool_id) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Pool', id=pool_id) tenant_id = self._get_tenant_id_for_create(context, m) if str(uuid.UUID(tenant_id)) != pool.parent_uuid: raise NotAuthorized() obj_uuid = uuidutils.generate_uuid() props = self.make_properties(m) id_perms = IdPermsType(enable=True) member_db = LoadbalancerMember(obj_uuid, pool, loadbalancer_member_properties=props, id_perms=id_perms) member_db.uuid = obj_uuid self._api.loadbalancer_member_create(member_db) return self.make_dict(member_db)
def delete(self, context, id, pool_id): try: member = self._api.loadbalancer_member_read(id=id) except NoIdError: raise loadbalancerv2.EntityNotFound(name=self.neutron_name, id=id) try: pool = self._api.loadbalancer_pool_read(id=pool_id) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Pool', id=pool_id) if id not in [member['uuid'] for member in pool.get_loadbalancer_members() or []]: raise loadbalancerv2.MemberNotFoundForPool(member_id=id, pool_id=pool_id) super(LoadbalancerMemberManager, self).delete(context, id)
def create(self, context, listener): _l = listener['listener'] tenant_id = self._get_tenant_id_for_create(context, _l) project = self._project_read(project_id=tenant_id) if _l['loadbalancer_id']: try: lb = self._api.loadbalancer_read(id=_l['loadbalancer_id']) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Loadbalancer', id=_l['loadbalancer_id']) project_id = lb.parent_uuid if str(uuid.UUID(tenant_id)) != project_id: raise NotAuthorized() else: lb = None obj_uuid = uuidutils.generate_uuid() name = self._get_resource_name('loadbalancer-listener', project, _l['name'], obj_uuid) id_perms = IdPermsType(enable=True, description=_l['description']) ll = LoadbalancerListener(name, project, id_perms=id_perms, display_name=_l['name']) ll.uuid = obj_uuid if lb: ll.set_loadbalancer(lb) props = self.make_properties(_l) ll.set_loadbalancer_listener_properties(props) self._api.loadbalancer_listener_create(ll) return self.make_dict(ll)
def delete_listener(self, context, id): try: _ = self._api.loadbalancer_listener_read(id=id) except NoIdError: loadbalancerv2.EntityNotFound(name=self.neutron_name, id=id) super(ListenerManager, self).delete(context, id)
def update_pool(self, context, id, pool): with context.session.begin(subtransactions=True): pool_db = self._get_resource(context, models.PoolV2, id) hm_id = pool.get('healthmonitor_id') if hm_id: if not self._resource_exists(context, models.HealthMonitorV2, hm_id): raise loadbalancerv2.EntityNotFound( name=models.HealthMonitorV2.NAME, id=hm_id) filters = {'healthmonitor_id': [hm_id]} hmpools = self._get_resources(context, models.PoolV2, filters=filters) if hmpools: raise loadbalancerv2.EntityInUse( entity_using=models.PoolV2.NAME, id=hmpools[0].id, entity_in_use=models.HealthMonitorV2.NAME) # Only update or delete session persistence if it was part # of the API request. if 'session_persistence' in pool.keys(): sp = pool.pop('session_persistence') if sp is None or sp == {}: self._delete_session_persistence(context, id) else: self._update_pool_session_persistence(context, id, sp) # sqlalchemy cries if listeners is defined. listeners = pool.get('listeners') if listeners: del pool['listeners'] pool_db.update(pool) context.session.refresh(pool_db) return data_models.Pool.from_sqlalchemy_model(pool_db)
def update_status(self, context, model, id, provisioning_status=None, operating_status=None): with context.session.begin(subtransactions=True): if issubclass(model, models.LoadBalancer): try: model_db = (model_query.query_with_hooks( context, model).filter(model.id == id).options( orm.noload('vip_port')).one()) except exc.NoResultFound: raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=id) else: model_db = self._get_resource(context, model, id) if provisioning_status and (model_db.provisioning_status != provisioning_status): model_db.provisioning_status = provisioning_status LOG.debug("Provisioning status of %s (id=%s) updated to: %s", model_db.NAME, model_db.id, provisioning_status) if (operating_status and hasattr(model_db, 'operating_status') and model_db.operating_status != operating_status): model_db.operating_status = operating_status LOG.debug("Operating status of %s (id=%s) updated to: %s", model_db.NAME, model_db.id, operating_status)
def create_l7policy(self, context, l7policy): if (l7policy.get('redirect_pool_id') and l7policy['redirect_pool_id'] == n_const.ATTR_NOT_SPECIFIED): l7policy['redirect_pool_id'] = None if not l7policy.get('position'): l7policy['position'] = 2147483647 self._validate_l7policy_data(context, l7policy) with context.session.begin(subtransactions=True): listener_id = l7policy.get('listener_id') listener_db = self._get_resource(context, models.Listener, listener_id) if not listener_db: raise loadbalancerv2.EntityNotFound(name=models.Listener.NAME, id=listener_id) self._load_id(context, l7policy) l7policy['provisioning_status'] = constants.PENDING_CREATE l7policy_db = models.L7Policy(**l7policy) # MySQL int fields are by default 32-bit whereas handy system # constants like sys.maxsize are 64-bit on most platforms today. # Hence the reason this is 2147483647 (2^31 - 1) instead of an # elsewhere-defined constant. if l7policy['position'] == 2147483647: listener_db.l7_policies.append(l7policy_db) else: listener_db.l7_policies.insert(l7policy['position'] - 1, l7policy_db) listener_db.l7_policies.reorder() return data_models.L7Policy.from_sqlalchemy_model(l7policy_db)
def update_pool(self, context, id, pool): with context.session.begin(subtransactions=True): pool_db = self._get_resource(context, models.PoolV2, id) hm_id = pool.get('healthmonitor_id') if hm_id: if not self._resource_exists(context, models.HealthMonitorV2, hm_id): raise loadbalancerv2.EntityNotFound( name=models.HealthMonitorV2.NAME, id=hm_id) filters = {'healthmonitor_id': [hm_id]} hmpools = self._get_resources(context, models.PoolV2, filters=filters) if hmpools: raise loadbalancerv2.EntityInUse( entity_using=models.PoolV2.NAME, id=hmpools[0].id, entity_in_use=models.HealthMonitorV2.NAME) sp = pool.pop('session_persistence', None) if sp: self._update_pool_session_persistence(context, id, sp) else: self._delete_session_persistence(context, id) pool_db.update(pool) context.session.refresh(pool_db) return data_models.Pool.from_sqlalchemy_model(pool_db)
def _get_resource(self, context, model, id, for_update=False): resource = None try: if for_update: # To lock the instance for update, return a single # instance, instead of an instance with LEFT OUTER # JOINs that do not work in PostgreSQL query = self._model_query(context, model).options( lazyload('*') ).filter( model.id == id).with_lockmode('update') resource = query.one() else: resource = self._get_by_id(context, model, id) except exc.NoResultFound: with excutils.save_and_reraise_exception(reraise=False) as ctx: if issubclass(model, (models.LoadBalancer, models.Listener, models.L7Policy, models.L7Rule, models.PoolV2, models.MemberV2, models.HealthMonitorV2, models.LoadBalancerStatistics, models.SessionPersistenceV2)): raise loadbalancerv2.EntityNotFound(name=model.NAME, id=id) ctx.reraise = True return resource
def delete(self, context, id): try: lb = self._api.loadbalancer_read(id=id) except NoIdError: loadbalancerv2.EntityNotFound(name=self.neutron_name, id=id) super(LoadbalancerManager, self).delete(context, id) self._delete_virtual_interface(lb.get_virtual_machine_interface_refs())
def create(self, context, pool): """ Create a loadbalancer_pool object. """ p = pool['pool'] try: sas_fq_name = ["default-global-system-config"] sas_fq_name.append(p['provider']) sas_obj = self._api.service_appliance_set_read(fq_name=sas_fq_name) except NoIdError: raise pconf.ServiceProviderNotFound( provider=p['provider'], service_type=constants.LOADBALANCER) tenant_id = self._get_tenant_id_for_create(context, p) project = self._project_read(project_id=tenant_id) if p['listener_id']: try: ll = self._api.loadbalancer_listener_read(id=p['listener_id']) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Listener', id=p['listener_id']) project_id = ll.parent_uuid if str(uuid.UUID(tenant_id)) != project_id: raise n_exc.NotAuthorized() else: ll = None pool_uuid = uuidutils.generate_uuid() name = self._get_resource_name('loadbalancer-pool', project, p['name'], pool_uuid) props = self.make_properties(p) id_perms = IdPermsType(enable=True, description=p['description']) pool = LoadbalancerPool(name, project, loadbalancer_pool_properties=props, loadbalancer_pool_provider=p['provider'], id_perms=id_perms, display_name=p['name']) pool.uuid = pool_uuid pool.set_service_appliance_set(sas_obj) if ll: pool_exists = ll.get_loadbalancer_pool_back_refs() if pool_exists is not None: raise loadbalancerv2.OnePoolPerListener( listener_id=p['listener_id'], pool_id=pool_exists[0]['uuid']) pool.set_loadbalancer_listener(ll) self._api.loadbalancer_pool_create(pool) return self.make_dict(pool)
def _validate_listener_data(self, context, listener): pool_id = listener.get('default_pool_id') lb_id = listener.get('loadbalancer_id') if lb_id: if not self._resource_exists(context, models.LoadBalancer, lb_id): raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=lb_id) if pool_id: if not self._resource_exists(context, models.PoolV2, pool_id): raise loadbalancerv2.EntityNotFound(name=models.PoolV2.NAME, id=pool_id) pool = self._get_resource(context, models.PoolV2, pool_id) if ((pool.protocol, listener.get('protocol')) not in lb_const.LISTENER_POOL_COMPATIBLE_PROTOCOLS): raise loadbalancerv2.ListenerPoolProtocolMismatch( listener_proto=listener['protocol'], pool_proto=pool.protocol) if lb_id and pool_id: pool = self._get_resource(context, models.PoolV2, pool_id) if pool.loadbalancer_id != lb_id: raise sharedpools.ListenerPoolLoadbalancerMismatch( pool_id=pool_id, lb_id=pool.loadbalancer_id)
def _delete_loadbalancer_stats(self, context, loadbalancer_id): # This is internal method to delete pool statistics. It won't # be exposed to API with context.session.begin(subtransactions=True): stats_qry = context.session.query(models.LoadBalancerStatistics) try: stats = stats_qry.filter_by( loadbalancer_id=loadbalancer_id).one() except exc.NoResultFound: raise loadbalancerv2.EntityNotFound( name=models.LoadBalancerStatistics.NAME, id=loadbalancer_id) context.session.delete(stats)
def create_l7policy_rule(self, context, rule, l7policy_id): with context.session.begin(subtransactions=True): if not self._resource_exists(context, models.L7Policy, l7policy_id): raise loadbalancerv2.EntityNotFound(name=models.L7Policy.NAME, id=l7policy_id) self._validate_l7rule_data(context, rule) self._load_id(context, rule) rule['l7policy_id'] = l7policy_id rule['provisioning_status'] = constants.PENDING_CREATE rule_db = models.L7Rule(**rule) context.session.add(rule_db) return data_models.L7Rule.from_sqlalchemy_model(rule_db)
def create(self, context, pool): """ Create a loadbalancer_pool object. """ p = pool['pool'] tenant_id = self._get_tenant_id_for_create(context, p) project = self._project_read(project_id=tenant_id) if p['listener_id']: try: ll = self._api.loadbalancer_listener_read(id=p['listener_id']) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Listener', id=p['listener_id']) project_id = ll.parent_uuid if str(uuid.UUID(tenant_id)) != project_id: raise exc.NotAuthorized() else: ll = None pool_uuid = uuidutils.generate_uuid() name = self._get_resource_name('loadbalancer-pool', project, p['name'], pool_uuid) props = self.make_properties(p) id_perms = IdPermsType(enable=True, description=p['description']) pool = LoadbalancerPool(name, project, uuid=pool_uuid, loadbalancer_pool_properties=props, id_perms=id_perms, display_name=p['name']) if ll: pool_exists = ll.get_loadbalancer_pool_back_refs() if pool_exists is not None: raise loadbalancerv2.OnePoolPerListener( listener_id=p['listener_id'], pool_id=pool_exists[0]['uuid']) pool.set_loadbalancer_listener(ll) # Custom attributes if p['custom_attributes'] != ATTR_NOT_SPECIFIED: custom_attributes = KeyValuePairs() self.create_update_custom_attributes(p['custom_attributes'], custom_attributes) pool.set_loadbalancer_pool_custom_attributes(custom_attributes) self._api.loadbalancer_pool_create(pool) return self.make_dict(pool)
def _get_resource(self, context, model, id, for_update=False): resource = None try: if for_update: query = self._model_query(context, model).filter( model.id == id).with_lockmode('update') resource = query.one() else: resource = self._get_by_id(context, model, id) except exc.NoResultFound: with excutils.save_and_reraise_exception(reraise=False) as ctx: if issubclass(model, (models.LoadBalancer, models.Listener, models.PoolV2, models.MemberV2, models.HealthMonitorV2, models.LoadBalancerStatistics, models.SessionPersistenceV2)): raise loadbalancerv2.EntityNotFound(name=model.NAME, id=id) ctx.reraise = True return resource
def update_object(self, member_db, id, m): pool_id = member_db.parent_uuid try: pool = self._api.loadbalancer_pool_read(id=pool_id) except NoIdError: raise loadbalancerv2.EntityNotFound(name='Pool', id=pool_id) db_props = member_db.get_loadbalancer_member_properties() members = pool.get_loadbalancer_members() for member in members or []: if id == member['uuid']: continue member_obj = self._api.loadbalancer_member_read(id=member['uuid']) props = member_obj.get_loadbalancer_member_properties() if ((props.get_address() == db_props.get_address()) and (props.get_protocol_port() == db_props.get_protocol_port())): raise loadbalancerv2.MemberExists( address=props.get_address(), port=props.get_protocol_port(), pool=pool_id) return True
def _validate_l7policy_data(self, context, l7policy): if l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: if not l7policy['redirect_pool_id']: raise l7.L7PolicyRedirectPoolIdMissing() if not self._resource_exists(context, models.PoolV2, l7policy['redirect_pool_id']): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=l7policy['redirect_pool_id']) pool = self._get_resource(context, models.PoolV2, l7policy['redirect_pool_id']) listener = self._get_resource(context, models.Listener, l7policy['listener_id']) if pool.loadbalancer_id != listener.loadbalancer_id: raise sharedpools.ListenerAndPoolMustBeOnSameLoadbalancer() if (l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL and 'redirect_url' not in l7policy): raise l7.L7PolicyRedirectUrlMissing()
def _validate_listener_data(self, context, listener): pool_id = listener.get('default_pool_id') lb_id = listener.get('loadbalancer_id') if lb_id: if not self._resource_exists(context, models.LoadBalancer, lb_id): raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=lb_id) if pool_id: pool = self._get_resource(context, models.PoolV2, pool_id) if ((pool.protocol, listener.get('protocol')) not in lb_const.LISTENER_POOL_COMPATIBLE_PROTOCOLS): raise loadbalancerv2.ListenerPoolProtocolMismatch( listener_proto=listener['protocol'], pool_proto=pool.protocol) filters = {'default_pool_id': [pool_id]} listenerpools = self._get_resources(context, models.Listener, filters=filters) if listenerpools: raise loadbalancerv2.EntityInUse( entity_using=models.Listener.NAME, id=listenerpools[0].id, entity_in_use=models.PoolV2.NAME)
def get_exception_notfound(self, id=None): return loadbalancerv2.EntityNotFound(name=self.neutron_name, id=id)
def _check_pool_exists(self, context, pool_id): if not self.db._resource_exists(context, models.PoolV2, pool_id): raise loadbalancerv2.EntityNotFound(name=models.PoolV2.NAME, id=pool_id)
def check_subnet_exists(self, context, subnet_id): try: self._core_plugin.get_subnet(context, subnet_id) except n_exc.SubnetNotFound: raise loadbalancerv2.EntityNotFound(name="Subnet", id=subnet_id)