def as_effect(self): """Produce a :obj:`Effect` to set a metadata item on a server""" eff = set_nova_metadata_item(server_id=self.server_id, key=self.key, value=self.value) return eff.on(success=lambda _: (StepResult.SUCCESS, []))
def convergence_remove_server_from_group(log, transaction_id, server_id, replace, purge, group, state): """ Remove a specific server from the group, optionally decrementing the desired capacity. The server may just be scheduled for deletion, or it may be evicted from the group by removing otter-specific metdata from the server. :param log: A bound logger :param bytes trans_id: The transaction id for this operation. :param bytes server_id: The id of the server to be removed. :param bool replace: Should the server be replaced? :param bool purge: Should the server be deleted from Nova? :param group: The scaling group to remove a server from. :type group: :class:`~otter.models.interface.IScalingGroup` :param state: The current state of the group. :type state: :class:`~otter.models.interface.GroupState` :return: The updated state. :rtype: Effect of :class:`~otter.models.interface.GroupState` :raise: :class:`CannotDeleteServerBelowMinError` if the server cannot be deleted without replacement, and :class:`ServerNotFoundError` if there is no such server to be deleted. """ effects = [_is_server_in_group(group, server_id)] if not replace: effects.append(_can_scale_down(group, server_id)) # the (possibly) two checks can happen in parallel, but we want # ServerNotFoundError to take precedence over # CannotDeleteServerBelowMinError both_checks = yield parallel_all_errors(effects) for is_error, result in both_checks: if is_error: reraise(*result) # Remove the server if purge: eff = set_nova_metadata_item(server_id, *DRAINING_METADATA) else: eff = Effect( EvictServerFromScalingGroup(log=log, transaction_id=transaction_id, scaling_group=group, server_id=server_id)) yield Effect( TenantScope( retry_effect(eff, retry_times(3), exponential_backoff_interval(2)), group.tenant_id)) if not replace: yield do_return(assoc_obj(state, desired=state.desired - 1)) else: yield do_return(state)
def convergence_remove_server_from_group( log, transaction_id, server_id, replace, purge, group, state): """ Remove a specific server from the group, optionally decrementing the desired capacity. The server may just be scheduled for deletion, or it may be evicted from the group by removing otter-specific metdata from the server. :param log: A bound logger :param bytes trans_id: The transaction id for this operation. :param bytes server_id: The id of the server to be removed. :param bool replace: Should the server be replaced? :param bool purge: Should the server be deleted from Nova? :param group: The scaling group to remove a server from. :type group: :class:`~otter.models.interface.IScalingGroup` :param state: The current state of the group. :type state: :class:`~otter.models.interface.GroupState` :return: The updated state. :rtype: Effect of :class:`~otter.models.interface.GroupState` :raise: :class:`CannotDeleteServerBelowMinError` if the server cannot be deleted without replacement, and :class:`ServerNotFoundError` if there is no such server to be deleted. """ effects = [_is_server_in_group(group, server_id)] if not replace: effects.append(_can_scale_down(group, server_id)) # the (possibly) two checks can happen in parallel, but we want # ServerNotFoundError to take precedence over # CannotDeleteServerBelowMinError both_checks = yield parallel_all_errors(effects) for is_error, result in both_checks: if is_error: reraise(*result) # Remove the server if purge: eff = set_nova_metadata_item(server_id, *DRAINING_METADATA) else: eff = Effect( EvictServerFromScalingGroup(log=log, transaction_id=transaction_id, scaling_group=group, server_id=server_id)) yield Effect(TenantScope( retry_effect(eff, retry_times(3), exponential_backoff_interval(2)), group.tenant_id)) if not replace: yield do_return(assoc_obj(state, desired=state.desired - 1)) else: yield do_return(state)
def _setup_for_set_nova_metadata_item(self): """ Produce the data needed to test :obj:`set_nova_metadata_item`: a tuple of (server_id, expected_effect, real_effect) """ server_id = unicode(uuid4()) real = set_nova_metadata_item(server_id=server_id, key='k', value='v') expected = service_request( ServiceType.CLOUD_SERVERS, 'PUT', 'servers/{0}/metadata/k'.format(server_id), data={'meta': {'k': 'v'}}, reauth_codes=(401,), success_pred=has_code(200)) return (server_id, expected, real)
def _setup_for_set_nova_metadata_item(self): """ Produce the data needed to test :obj:`set_nova_metadata_item`: a tuple of (server_id, expected_effect, real_effect) """ server_id = unicode(uuid4()) real = set_nova_metadata_item(server_id=server_id, key='k', value='v') expected = service_request(ServiceType.CLOUD_SERVERS, 'PUT', 'servers/{0}/metadata/k'.format(server_id), data={'meta': { 'k': 'v' }}, reauth_codes=(401, ), success_pred=has_code(200)) return (server_id, expected, real)
def as_effect(self): """Produce a :obj:`Effect` to set a metadata item on a server""" eff = set_nova_metadata_item( server_id=self.server_id, key=self.key, value=self.value) return eff.on(success=lambda _: (StepResult.SUCCESS, []))