def post(self, member): """Creates a pool member on a pool.""" context = pecan.request.context.get('octavia_context') member.project_id = self._get_lb_project_id(context.session, self.load_balancer_id) # Validate member subnet if member.subnet_id: validate.subnet_exists(member.subnet_id) lock_session = db_api.get_session(autocommit=False) if self.repositories.check_quota_met( context.session, lock_session, data_models.Member, member.project_id): lock_session.rollback() raise exceptions.QuotaException( resource=data_models.Member._name() ) try: member_dict = db_prepare.create_member(member.to_dict( render_unsets=True), self.pool_id) self._test_lb_and_listener_statuses(lock_session) db_member = self.repositories.member.create(lock_session, **member_dict) db_new_member = self._get_db_member(lock_session, db_member.id) lock_session.commit() except oslo_exc.DBDuplicateEntry as de: lock_session.rollback() if ['id'] == de.columns: raise exceptions.IDAlreadyExists() raise exceptions.DuplicateMemberEntry( ip_address=member_dict.get('ip_address'), port=member_dict.get('protocol_port')) except Exception: with excutils.save_and_reraise_exception(): lock_session.rollback() try: LOG.info("Sending Creation of Member %s to handler", db_member.id) self.handler.create(db_member) except Exception: for listener_id in self._get_affected_listener_ids( context.session): with excutils.save_and_reraise_exception(reraise=False): self.repositories.listener.update( context.session, listener_id, operating_status=constants.ERROR) return self._convert_db_to_type(db_new_member, member_types.MemberResponse)
def post(self, member): """Creates a pool member on a pool.""" session = db_api.get_session() member_dict = member.to_dict() member_dict['pool_id'] = self.pool_id member_dict['operating_status'] = constants.OFFLINE # Verify load balancer is in a mutable status. If so it can be assumed # that the listener is also in a mutable status because a load balancer # will only be ACTIVE when all its listeners as ACTIVE. if not self.repositories.test_and_set_lb_and_listener_prov_status( session, self.load_balancer_id, self.listener_id, constants.PENDING_UPDATE, constants.PENDING_UPDATE): LOG.info( _LI("Member cannot be created because its Load " "Balancer is in an immutable state.")) lb_repo = self.repositories.load_balancer db_lb = lb_repo.get(session, id=self.load_balancer_id) raise exceptions.ImmutableObject(resource=db_lb._name(), id=self.load_balancer_id) try: db_member = self.repositories.member.create(session, **member_dict) except oslo_exc.DBDuplicateEntry as de: # Setting LB and Listener back to active because this is just a # validation failure self.repositories.load_balancer.update( session, self.load_balancer_id, provisioning_status=constants.ACTIVE) self.repositories.listener.update( session, self.listener_id, provisioning_status=constants.ACTIVE) if ['id'] == de.columns: raise exceptions.IDAlreadyExists() elif (set(['pool_id', 'ip_address', 'protocol_port']) == set(de.columns)): raise exceptions.DuplicateMemberEntry( ip_address=member_dict.get('ip_address'), port=member_dict.get('protocol_port')) try: LOG.info(_LI("Sending Creation of Member %s to handler"), db_member.id) self.handler.create(db_member) except Exception: with excutils.save_and_reraise_exception(reraise=False): self.repositories.listener.update( session, self.listener_id, operating_status=constants.ERROR) db_member = self.repositories.member.get(session, id=db_member.id) return self._convert_db_to_type(db_member, member_types.MemberResponse)
def post(self, member): """Creates a pool member on a pool.""" context = pecan.request.context.get('octavia_context') member_dict = db_prepare.create_member( member.to_dict(render_unsets=True), self.pool_id) self._test_lb_and_listener_statuses(context.session) try: db_member = self.repositories.member.create( context.session, **member_dict) except oslo_exc.DBDuplicateEntry as de: # Setting LB and Listener back to active because this is just a # validation failure self.repositories.load_balancer.update( context.session, self.load_balancer_id, provisioning_status=constants.ACTIVE) for listener_id in self._get_affected_listener_ids( context.session): self.repositories.listener.update( context.session, listener_id, provisioning_status=constants.ACTIVE) if ['id'] == de.columns: raise exceptions.IDAlreadyExists() elif (set(['pool_id', 'ip_address', 'protocol_port']) == set(de.columns)): raise exceptions.DuplicateMemberEntry( ip_address=member_dict.get('ip_address'), port=member_dict.get('protocol_port')) try: LOG.info(_LI("Sending Creation of Member %s to handler"), db_member.id) self.handler.create(db_member) except Exception: for listener_id in self._get_affected_listener_ids( context.session): with excutils.save_and_reraise_exception(reraise=False): self.repositories.listener.update( context.session, listener_id, operating_status=constants.ERROR) db_member = self._get_db_member(context.session, db_member.id) return self._convert_db_to_type(db_member, member_types.MemberResponse)
def _validate_create_member(self, lock_session, member_dict): """Validate creating member on pool.""" try: return self.repositories.member.create(lock_session, **member_dict) except odb_exceptions.DBDuplicateEntry as de: column_list = ['pool_id', 'ip_address', 'protocol_port'] constraint_list = ['uq_member_pool_id_address_protocol_port'] if ['id'] == de.columns: raise exceptions.IDAlreadyExists() elif (set(column_list) == set(de.columns) or set(constraint_list) == set(de.columns)): raise exceptions.DuplicateMemberEntry( ip_address=member_dict.get('ip_address'), port=member_dict.get('protocol_port')) except odb_exceptions.DBError: # TODO(blogan): will have to do separate validation protocol # before creation or update since the exception messages # do not give any information as to what constraint failed raise exceptions.InvalidOption(value='', option='')