Пример #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)
Пример #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))
Пример #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))
Пример #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')
Пример #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')
Пример #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)
Пример #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)
Пример #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
Пример #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
Пример #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)
Пример #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
Пример #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
Пример #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
Пример #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)
Пример #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
Пример #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