def modify_and_trigger(dispatcher, group, logargs, modifier, *args, **kwargs): """ Modify group state and trigger convergence after that if the group is not suspended. Otherwise fail with :obj:`TenantSuspendedError`. :param IScalingGroup group: Scaling group whose state is getting modified :param log: Bound logger :param modifier: Callable as described in IScalingGroup.modify_state :return: Deferred with None if modification and convergence succeeded. Fails with :obj:`TenantSuspendedError` if group is suspended. """ def modifier_wrapper(_group, state, *_args, **_kwargs): # Ideally this will not be allowed by repose middleware but # adding check for mimic based integration tests if state.suspended: raise TenantSuspendedError(_group.tenant_id) return modifier(_group, state, *_args, **_kwargs) cannot_exec_pol_err = None try: yield group.modify_state(modifier_wrapper, *args, **kwargs) except CannotExecutePolicyError as ce: cannot_exec_pol_err = ce if tenant_is_enabled(group.tenant_id, config_value): eff = Effect( BoundFields( trigger_convergence(group.tenant_id, group.uuid), logargs)) yield perform(dispatcher, eff) if cannot_exec_pol_err is not None: raise cannot_exec_pol_err
def modify_and_trigger(dispatcher, group, logargs, modifier, *args, **kwargs): """ Modify group state and trigger convergence after that if the group is not suspended. Otherwise fail with :obj:`TenantSuspendedError`. :param IScalingGroup group: Scaling group whose state is getting modified :param log: Bound logger :param modifier: Callable as described in IScalingGroup.modify_state :return: Deferred with None if modification and convergence succeeded. Fails with :obj:`TenantSuspendedError` if group is suspended. """ def modifier_wrapper(_group, state, *_args, **_kwargs): # Ideally this will not be allowed by repose middleware but # adding check for mimic based integration tests if state.suspended: raise TenantSuspendedError(_group.tenant_id) return modifier(_group, state, *_args, **_kwargs) cannot_exec_pol_err = None try: yield group.modify_state(modifier_wrapper, *args, **kwargs) except CannotExecutePolicyError as ce: cannot_exec_pol_err = ce if tenant_is_enabled(group.tenant_id, config_value): eff = Effect( BoundFields(trigger_convergence(group.tenant_id, group.uuid), logargs)) yield perform(dispatcher, eff) if cannot_exec_pol_err is not None: raise cannot_exec_pol_err
def test_success(self): """ Divergent flag is set with bound log and msg is logged """ seq = [ (CreateOrSet(path="/groups/divergent/t_g", content="dirty"), noop), (Log("mark-dirty-success", {}), noop) ] self.assertEqual( perform_sequence(seq, trigger_convergence("t", "g")), None)
def test_failure(self): """ If setting divergent flag errors, then error is logged and raised """ seq = [ (CreateOrSet(path="/groups/divergent/t_g", content="dirty"), lambda i: raise_(ValueError("oops"))), (LogErr(CheckFailureValue(ValueError("oops")), "mark-dirty-failure", {}), noop) ] self.assertRaises( ValueError, perform_sequence, seq, trigger_convergence("t", "g"))
def trigger_convergence_deletion(dispatcher, group, trans_id): """ Trigger deletion of group that belongs to convergence tenant :param log: Bound logger :param otter.models.interface.IScalingGroup scaling_group: the scaling group object """ # Update group status and trigger convergence # DELETING status will take precedence over other status d = group.update_status(ScalingGroupStatus.DELETING) eff = with_log(trigger_convergence(group.tenant_id, group.uuid), tenant_id=group.tenant_id, scaling_group_id=group.uuid, transaction_id=trans_id) d.addCallback(lambda _: perform(dispatcher, eff)) return d
def check_and_trigger(tenant_id, group_id): """ Trigger convergence on given group if it is ACTIVE and not paused """ try: group, info = yield Effect( GetScalingGroupInfo(tenant_id=tenant_id, group_id=group_id)) except NoSuchScalingGroupError: # Nothing to do if group has been deleted yield msg("selfheal-group-deleted", tenant_id=tenant_id, scaling_group_id=group_id) else: state = info["state"] if state.status == ScalingGroupStatus.ACTIVE and (not state.paused): yield with_log( trigger_convergence(tenant_id, group_id), tenant_id=tenant_id, scaling_group_id=group_id)
def check_and_trigger(tenant_id, group_id): """ Trigger convergence on given group if it is ACTIVE and not paused """ try: group, info = yield Effect( GetScalingGroupInfo(tenant_id=tenant_id, group_id=group_id)) except NoSuchScalingGroupError: # Nothing to do if group has been deleted yield msg("selfheal-group-deleted", tenant_id=tenant_id, scaling_group_id=group_id) else: state = info["state"] if (state.status == ScalingGroupStatus.ACTIVE and not (state.paused or state.suspended)): yield with_log(trigger_convergence(tenant_id, group_id), tenant_id=tenant_id, scaling_group_id=group_id)
def modify_and_trigger(dispatcher, group, logargs, modifier, *args, **kwargs): """ Modify group state and trigger convergence after that :param IScalingGroup group: Scaling group whose state is getting modified :param log: Bound logger :param modifier: Callable as described in IScalingGroup.modify_state :return: Deferred with None """ cannot_exec_pol_err = None try: yield group.modify_state(modifier, *args, **kwargs) except CannotExecutePolicyError as ce: cannot_exec_pol_err = ce if tenant_is_enabled(group.tenant_id, config_value): eff = Effect(BoundFields(trigger_convergence(group.tenant_id, group.uuid), logargs)) yield perform(dispatcher, eff) if cannot_exec_pol_err is not None: raise cannot_exec_pol_err
def modify_and_trigger(dispatcher, group, logargs, modifier, *args, **kwargs): """ Modify group state and trigger convergence after that :param IScalingGroup group: Scaling group whose state is getting modified :param log: Bound logger :param modifier: Callable as described in IScalingGroup.modify_state :return: Deferred with None """ cannot_exec_pol_err = None try: yield group.modify_state(modifier, *args, **kwargs) except CannotExecutePolicyError as ce: cannot_exec_pol_err = ce if tenant_is_enabled(group.tenant_id, config_value): eff = Effect( BoundFields(trigger_convergence(group.tenant_id, group.uuid), logargs)) yield perform(dispatcher, eff) if cannot_exec_pol_err is not None: raise cannot_exec_pol_err
def kick_off_convergence(new_state): ceff = trigger_convergence(group.tenant_id, group.uuid) return ceff.on(lambda _: new_state)