Exemple #1
0
    def converge_scaling_group(self, request):
        """
        Trigger convergence on given scaling group
        """

        class ConvergeErrorGroup(Exception):
            pass

        def can_converge(group, state):
            if state.paused:
                raise GroupPausedError(group.tenant_id, group.uuid, "converge")
            conv_on_error = extract_bool_arg(request, 'on_error', True)
            if not conv_on_error and state.status == ScalingGroupStatus.ERROR:
                raise ConvergeErrorGroup()
            return state

        def converge_error_group_header(f):
            f.trap(ConvergeErrorGroup)
            request.setHeader("x-not-converging", "true")

        if tenant_is_enabled(self.tenant_id, config_value):
            group = self.store.get_scaling_group(
                self.log, self.tenant_id, self.group_id)
            return controller.modify_and_trigger(
                self.dispatcher,
                group,
                bound_log_kwargs(self.log),
                can_converge).addErrback(converge_error_group_header)
        else:
            request.setResponseCode(404)
Exemple #2
0
 def match(self, log):
     """
     Return None if log is bound with given args/kwargs. Otherwise return Mismatch
     """
     if not isinstance(log, BoundLog):
         return Mismatch('log is not a BoundLog')
     kwargs = bound_log_kwargs(log)
     if self.kwargs == kwargs:
         return None
     else:
         return Mismatch('Expected kwargs {} but got {} instead'.format(
             self.kwargs, kwargs))
Exemple #3
0
 def match(self, log):
     """
     Return None if log is bound with given args/kwargs. Otherwise return Mismatch
     """
     if not isinstance(log, BoundLog):
         return Mismatch('log is not a BoundLog')
     kwargs = bound_log_kwargs(log)
     if self.kwargs == kwargs:
         return None
     else:
         return Mismatch(
             'Expected kwargs {} but got {} instead'.format(self.kwargs,
                                                            kwargs))
Exemple #4
0
 def execute_policy((tenant_id, group_id, policy_id)):
     bound_log = self.log.bind(tenant_id=tenant_id,
                               scaling_group_id=group_id,
                               policy_id=policy_id)
     logl[0] = bound_log
     group = self.store.get_scaling_group(bound_log, tenant_id,
                                          group_id)
     return controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(bound_log),
         partial(controller.maybe_execute_scaling_policy,
                 bound_log, transaction_id(request),
                 policy_id=policy_id),
         modify_state_reason='execute_webhook')
Exemple #5
0
 def execute_policy((tenant_id, group_id, policy_id)):
     bound_log = self.log.bind(tenant_id=tenant_id,
                               scaling_group_id=group_id,
                               policy_id=policy_id)
     logl[0] = bound_log
     group = self.store.get_scaling_group(bound_log, tenant_id,
                                          group_id)
     return controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(bound_log),
         partial(controller.maybe_execute_scaling_policy,
                 bound_log,
                 transaction_id(request),
                 policy_id=policy_id),
         modify_state_reason='execute_webhook')
Exemple #6
0
 def _do_obey_config_change(result):
     group_id = result['id']
     config = result['groupConfiguration']
     launch = result['launchConfiguration']
     group = self.store.get_scaling_group(
         self.log, self.tenant_id, group_id)
     log = self.log.bind(scaling_group_id=group_id)
     d = controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(log),
         partial(
             controller.obey_config_change, log,
             transaction_id(request), config, launch_config=launch),
         modify_state_reason='create_new_scaling_group')
     return d.addCallback(lambda _: result)
Exemple #7
0
 def _do_obey_config_change(result):
     group_id = result['id']
     config = result['groupConfiguration']
     launch = result['launchConfiguration']
     group = self.store.get_scaling_group(
         self.log, self.tenant_id, group_id)
     log = self.log.bind(scaling_group_id=group_id)
     d = controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(log),
         partial(
             controller.obey_config_change, log,
             transaction_id(request), config, launch_config=launch),
         modify_state_reason='create_new_scaling_group')
     return d.addCallback(lambda _: result)
Exemple #8
0
    def edit_config_for_scaling_group(self, request, data):
        """
        Edit the configuration for a scaling group, which includes the minimum
        number of entities, the maximum number of entities, global cooldown,
        and other metadata.  This data provided in the request body in JSON
        format.  If successful, no response body will be returned.

        Example request::

            {
                "name": "workers",
                "cooldown": 60,
                "minEntities": 5,
                "maxEntities": 100,
                "metadata": {
                    "firstkey": "this is a string",
                    "secondkey": "1",
                }
            }

        The entire schema body must be provided.
        """
        if data['minEntities'] > data['maxEntities']:
            raise InvalidMinEntities(
                "minEntities must be less than or equal to maxEntities")

        def _get_launch_and_obey_config_change(scaling_group, state):
            d = scaling_group.view_launch_config()
            d.addCallback(partial(
                controller.obey_config_change,
                self.log,
                transaction_id(request),
                data, scaling_group, state))
            return d

        group = self.store.get_scaling_group(
            self.log, self.tenant_id, self.group_id)
        deferred = group.update_config(data)
        deferred.addCallback(
            lambda _: controller.modify_and_trigger(
                self.dispatcher,
                group,
                bound_log_kwargs(log),
                _get_launch_and_obey_config_change,
                modify_state_reason='edit_config_for_scaling_group'))
        return deferred
Exemple #9
0
 def delete_server(self, request, server_id):
     """
     Delete a server from the group.
     """
     group = self.store.get_scaling_group(self.log, self.tenant_id,
                                          self.scaling_group_id)
     log = self.log.bind(server_id=server_id)
     d = controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(log),
         partial(controller.remove_server_from_group, self.dispatcher, log,
                 transaction_id(request), server_id,
                 extract_bool_arg(request, 'replace', True),
                 extract_bool_arg(request, 'purge', True)),
         modify_state_reason='delete_server')
     return d
Exemple #10
0
    def converge_scaling_group(self, request):
        """
        Trigger convergence on given scaling group
        """
        def can_converge(group, state):
            if state.paused:
                raise GroupPausedError(group.tenant_id, group.uuid, "converge")
            return state

        if tenant_is_enabled(self.tenant_id, config_value):
            group = self.store.get_scaling_group(self.log, self.tenant_id,
                                                 self.group_id)
            return controller.modify_and_trigger(self.dispatcher, group,
                                                 bound_log_kwargs(self.log),
                                                 can_converge)
        else:
            request.setResponseCode(404)
Exemple #11
0
def execute_event(dispatcher, store, log, event, deleted_policy_ids):
    """
    Execute a single event

    :param dispatcher: Effect dispatcher
    :param store: `IScalingGroupCollection` provider
    :param log: A bound log for logging
    :param event: event dict to execute
    :param deleted_policy_ids: Set of policy ids that are deleted. Policy id
        will be added to this if its scaling group or policy has been deleted
    :return: a deferred with None. Any error occurred during execution is
        logged
    """
    tenant_id = event['tenantId']
    group_id = event['groupId']
    policy_id = event['policyId']
    log = log.bind(tenant_id=tenant_id,
                   scaling_group_id=group_id,
                   policy_id=policy_id,
                   scheduled_time=event["trigger"].isoformat() + "Z")
    log.msg('sch-exec-pol', cloud_feed=True)
    group = store.get_scaling_group(log, tenant_id, group_id)
    d = modify_and_trigger(dispatcher,
                           group,
                           bound_log_kwargs(log),
                           partial(maybe_execute_scaling_policy,
                                   log,
                                   generate_transaction_id(),
                                   policy_id=policy_id,
                                   version=event['version']),
                           modify_state_reason='scheduler.execute_event')
    d.addErrback(ignore_and_log,
                 CannotExecutePolicyError,
                 log,
                 "sch-cannot-exec",
                 cloud_feed=True)

    def collect_deleted_policy(failure):
        failure.trap(NoSuchScalingGroupError, NoSuchPolicyError)
        deleted_policy_ids.add(policy_id)

    d.addErrback(collect_deleted_policy)
    d.addErrback(log.err, "sch-exec-pol-err", cloud_feed=True)
    return d
Exemple #12
0
 def delete_server(self, request, server_id):
     """
     Delete a server from the group.
     """
     group = self.store.get_scaling_group(
         self.log, self.tenant_id, self.scaling_group_id)
     log = self.log.bind(server_id=server_id)
     d = controller.modify_and_trigger(
         self.dispatcher,
         group,
         bound_log_kwargs(log),
         partial(controller.remove_server_from_group,
                 self.dispatcher,
                 log,
                 transaction_id(request), server_id,
                 extract_bool_arg(request, 'replace', True),
                 extract_bool_arg(request, 'purge', True)),
         modify_state_reason='delete_server')
     return d
Exemple #13
0
def execute_event(dispatcher, store, log, event, deleted_policy_ids):
    """
    Execute a single event

    :param dispatcher: Effect dispatcher
    :param store: `IScalingGroupCollection` provider
    :param log: A bound log for logging
    :param event: event dict to execute
    :param deleted_policy_ids: Set of policy ids that are deleted. Policy id
        will be added to this if its scaling group or policy has been deleted
    :return: a deferred with None. Any error occurred during execution is
        logged
    """
    tenant_id = event["tenantId"]
    group_id = event["groupId"]
    policy_id = event["policyId"]
    log = log.bind(
        tenant_id=tenant_id,
        scaling_group_id=group_id,
        policy_id=policy_id,
        scheduled_time=event["trigger"].isoformat() + "Z",
    )
    log.msg("sch-exec-pol", cloud_feed=True)
    group = store.get_scaling_group(log, tenant_id, group_id)
    d = modify_and_trigger(
        dispatcher,
        group,
        bound_log_kwargs(log),
        partial(
            maybe_execute_scaling_policy, log, generate_transaction_id(), policy_id=policy_id, version=event["version"]
        ),
        modify_state_reason="scheduler.execute_event",
    )
    d.addErrback(ignore_and_log, CannotExecutePolicyError, log, "sch-cannot-exec", cloud_feed=True)

    def collect_deleted_policy(failure):
        failure.trap(NoSuchScalingGroupError, NoSuchPolicyError)
        deleted_policy_ids.add(policy_id)

    d.addErrback(collect_deleted_policy)
    d.addErrback(log.err, "sch-exec-pol-err", cloud_feed=True)
    return d
Exemple #14
0
    def converge_scaling_group(self, request):
        """
        Trigger convergence on given scaling group
        """

        def is_group_paused(group, state):
            if state.paused:
                raise GroupPausedError(group.tenant_id, group.uuid, "converge")
            return state

        if tenant_is_enabled(self.tenant_id, config_value):
            group = self.store.get_scaling_group(
                self.log, self.tenant_id, self.group_id)
            return controller.modify_and_trigger(
                self.dispatcher,
                group,
                bound_log_kwargs(log),
                is_group_paused)
        else:
            request.setResponseCode(404)
Exemple #15
0
    def execute_policy(self, request):
        """
        Execute this scaling policy.

        TBD: Response body.

        Example response::

            {}
        """
        group = self.store.get_scaling_group(self.log, self.tenant_id,
                                             self.scaling_group_id)
        d = controller.modify_and_trigger(
            self.dispatcher,
            group,
            bound_log_kwargs(self.log),
            partial(controller.maybe_execute_scaling_policy,
                    self.log, transaction_id(request),
                    policy_id=self.policy_id),
            modify_state_reason='execute_policy')
        d.addCallback(lambda _: "{}")  # Return value TBD
        return d
Exemple #16
0
    def execute_policy(self, request):
        """
        Execute this scaling policy.

        TBD: Response body.

        Example response::

            {}
        """
        group = self.store.get_scaling_group(self.log, self.tenant_id,
                                             self.scaling_group_id)
        d = controller.modify_and_trigger(
            self.dispatcher,
            group,
            bound_log_kwargs(self.log),
            partial(controller.maybe_execute_scaling_policy,
                    self.log,
                    transaction_id(request),
                    policy_id=self.policy_id),
            modify_state_reason='execute_policy')
        d.addCallback(lambda _: "{}")  # Return value TBD
        return d