Example #1
0
    def start(self, action_plan_uuid, **kwargs):
        """Start an action_plan

        :param action_plan_uuid: UUID of an action_plan.
        """

        action_plan_to_start = api_utils.get_resource('ActionPlan',
                                                      action_plan_uuid,
                                                      eager=True)
        context = pecan.request.context

        policy.enforce(context,
                       'action_plan:start',
                       action_plan_to_start,
                       action='action_plan:start')

        if action_plan_to_start['state'] != \
                objects.action_plan.State.RECOMMENDED:
            raise exception.StartError(state=action_plan_to_start.state)

        action_plan_to_start['state'] = objects.action_plan.State.PENDING
        action_plan_to_start.save()

        self.applier_client.launch_action_plan(pecan.request.context,
                                               action_plan_uuid)
        action_plan_to_start = objects.ActionPlan.get_by_uuid(
            pecan.request.context, action_plan_uuid)

        return ActionPlan.convert_with_links(action_plan_to_start)
Example #2
0
    def patch(self, audit, patch):
        """Update an existing audit.

        :param audit: UUID or name of an audit.
        :param patch: a json PATCH document to apply to this audit.
        """
        if self.from_audits:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        audit_to_update = api_utils.get_resource('Audit', audit, eager=True)
        policy.enforce(context,
                       'audit:update',
                       audit_to_update,
                       action='audit:update')

        try:
            audit_dict = audit_to_update.as_dict()

            initial_state = audit_dict['state']
            new_state = api_utils.get_patch_value(patch, 'state')
            if not api_utils.check_audit_state_transition(
                    patch, initial_state):
                error_message = _("State transition not allowed: "
                                  "(%(initial_state)s -> %(new_state)s)")
                raise exception.PatchError(
                    patch=patch,
                    reason=error_message %
                    dict(initial_state=initial_state, new_state=new_state))

            patch_path = api_utils.get_patch_key(patch, 'path')
            if patch_path in ('start_time', 'end_time'):
                patch_value = api_utils.get_patch_value(patch, patch_path)
                # convert string format to UTC time
                new_patch_value = wutils.parse_isodatetime(
                    patch_value).replace(tzinfo=tz.tzlocal()).astimezone(
                        tz.tzutc()).replace(tzinfo=None)
                api_utils.set_patch_value(patch, patch_path, new_patch_value)

            audit = Audit(**api_utils.apply_jsonpatch(audit_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.Audit.fields:
            try:
                patch_val = getattr(audit, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if audit_to_update[field] != patch_val:
                audit_to_update[field] = patch_val

        audit_to_update.save()
        return Audit.convert_with_links(audit_to_update)
Example #3
0
    def delete(self, audit_uuid):
        """Delete a audit.

        :param audit_uuid: UUID of a audit.
        """
        context = pecan.request.context
        audit_to_delete = api_utils.get_resource('Audit', audit_uuid)
        policy.enforce(context, 'audit:update', audit_to_delete,
                       action='audit:update')

        audit_to_delete.soft_delete()
Example #4
0
    def delete(self, action_plan_uuid):
        """Delete an action plan.

        :param action_plan_uuid: UUID of a action.
        """
        context = pecan.request.context
        action_plan = api_utils.get_resource('ActionPlan', action_plan_uuid)
        policy.enforce(context, 'action_plan:delete', action_plan,
                       action='action_plan:delete')

        action_plan.soft_delete()
    def delete(self, action_plan_uuid):
        """Delete an action plan.

        :param action_plan_uuid: UUID of a action.
        """
        context = pecan.request.context
        action_plan = api_utils.get_resource(
            'ActionPlan', action_plan_uuid, eager=True)
        policy.enforce(context, 'action_plan:delete', action_plan,
                       action='action_plan:delete')

        action_plan.soft_delete()
Example #6
0
    def delete(self, audit_template):
        """Delete a audit template.

        :param audit template_uuid: UUID or name of an audit template.
        """
        context = pecan.request.context
        audit_template_to_delete = api_utils.get_resource('AuditTemplate',
                                                          audit_template)
        policy.enforce(context, 'audit_template:update',
                       audit_template_to_delete,
                       action='audit_template:update')

        audit_template_to_delete.soft_delete()
Example #7
0
    def get_one(self, goal):
        """Retrieve information about the given goal.

        :param goal: UUID or name of the goal.
        """
        if self.from_goals:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_goal = api_utils.get_resource('Goal', goal)
        policy.enforce(context, 'goal:get', rpc_goal, action='goal:get')

        return Goal.convert_with_links(rpc_goal)
Example #8
0
    def get_one(self, action_uuid):
        """Retrieve information about the given action.

        :param action_uuid: UUID of a action.
        """
        if self.from_actions:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        action = api_utils.get_resource('Action', action_uuid)
        policy.enforce(context, 'action:get', action, action='action:get')

        return Action.convert_with_links(action)
Example #9
0
    def get_one(self, audit):
        """Retrieve information about the given audit.

        :param audit: UUID or name of an audit.
        """
        if self.from_audits:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_audit = api_utils.get_resource('Audit', audit)
        policy.enforce(context, 'audit:get', rpc_audit, action='audit:get')

        return Audit.convert_with_links(rpc_audit)
Example #10
0
    def delete(self, audit_template):
        """Delete a audit template.

        :param audit template_uuid: UUID or name of an audit template.
        """
        context = pecan.request.context
        audit_template_to_delete = api_utils.get_resource('AuditTemplate',
                                                          audit_template)
        policy.enforce(context, 'audit_template:update',
                       audit_template_to_delete,
                       action='audit_template:update')

        audit_template_to_delete.soft_delete()
Example #11
0
    def delete(self, audit_uuid):
        """Delete a audit.

        :param audit_uuid: UUID of a audit.
        """
        context = pecan.request.context
        audit_to_delete = api_utils.get_resource('Audit', audit_uuid)
        policy.enforce(context,
                       'audit:update',
                       audit_to_delete,
                       action='audit:update')

        audit_to_delete.soft_delete()
Example #12
0
    def get_one(self, action_uuid):
        """Retrieve information about the given action.

        :param action_uuid: UUID of a action.
        """
        if self.from_actions:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        action = api_utils.get_resource('Action', action_uuid)
        policy.enforce(context, 'action:get', action, action='action:get')

        return Action.convert_with_links(action)
Example #13
0
    def delete(self, audit):
        """Delete an audit.

        :param audit: UUID or name of an audit.
        """
        context = pecan.request.context
        audit_to_delete = api_utils.get_resource('Audit', audit, eager=True)
        policy.enforce(context,
                       'audit:update',
                       audit_to_delete,
                       action='audit:update')

        audit_to_delete.soft_delete()
Example #14
0
    def get_one(self, audit_uuid):
        """Retrieve information about the given audit.

        :param audit_uuid: UUID of a audit.
        """
        if self.from_audits:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_audit = api_utils.get_resource('Audit', audit_uuid)
        policy.enforce(context, 'audit:get', rpc_audit, action='audit:get')

        return Audit.convert_with_links(rpc_audit)
Example #15
0
    def get_one(self, strategy):
        """Retrieve information about the given strategy.

        :param strategy: UUID or name of the strategy.
        """
        if self.from_strategies:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_strategy = api_utils.get_resource('Strategy', strategy)
        policy.enforce(context, 'strategy:get', rpc_strategy,
                       action='strategy:get')

        return Strategy.convert_with_links(rpc_strategy)
Example #16
0
    def get_one(self, service):
        """Retrieve information about the given service.

        :param service: ID or name of the service.
        """
        if self.from_services:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_service = api_utils.get_resource('Service', service)
        policy.enforce(context, 'service:get', rpc_service,
                       action='service:get')

        return Service.convert_with_links(rpc_service)
Example #17
0
    def get_one(self, strategy):
        """Retrieve information about the given strategy.

        :param strategy: UUID or name of the strategy.
        """
        if self.from_strategies:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_strategy = api_utils.get_resource('Strategy', strategy)
        policy.enforce(context, 'strategy:get', rpc_strategy,
                       action='strategy:get')

        return Strategy.convert_with_links(rpc_strategy)
Example #18
0
    def patch(self, audit_uuid, patch):
        """Update an existing audit.

        :param audit_uuid: UUID of a audit.
        :param patch: a json PATCH document to apply to this audit.
        """
        if self.from_audits:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        audit_to_update = api_utils.get_resource('Audit',
                                                 audit_uuid,
                                                 eager=True)
        policy.enforce(context,
                       'audit:update',
                       audit_to_update,
                       action='audit:update')

        try:
            audit_dict = audit_to_update.as_dict()
            audit = Audit(**api_utils.apply_jsonpatch(audit_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        initial_state = audit_dict['state']
        new_state = api_utils.get_patch_value(patch, 'state')
        allowed_states = ALLOWED_AUDIT_TRANSITIONS.get(initial_state, [])
        if new_state is not None and new_state not in allowed_states:
            error_message = _("State transition not allowed: "
                              "(%(initial_state)s -> %(new_state)s)")
            raise exception.PatchError(
                patch=patch,
                reason=error_message %
                dict(initial_state=initial_state, new_state=new_state))

        # Update only the fields that have changed
        for field in objects.Audit.fields:
            try:
                patch_val = getattr(audit, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if audit_to_update[field] != patch_val:
                audit_to_update[field] = patch_val

        audit_to_update.save()
        return Audit.convert_with_links(audit_to_update)
Example #19
0
    def get_one(self, audit_template):
        """Retrieve information about the given audit template.

        :param audit audit_template: UUID or name of an audit template.
        """
        if self.from_audit_templates:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        rpc_audit_template = api_utils.get_resource('AuditTemplate',
                                                    audit_template)
        policy.enforce(context, 'audit_template:get', rpc_audit_template,
                       action='audit_template:get')

        return AuditTemplate.convert_with_links(rpc_audit_template)
Example #20
0
    def get_one(self, scoring_engine):
        """Retrieve information about the given Scoring Engine.

        :param scoring_engine_name: The name of the Scoring Engine.
        """
        context = pecan.request.context
        policy.enforce(context, 'scoring_engine:get',
                       action='scoring_engine:get')

        if self.from_scoring_engines:
            raise exception.OperationNotPermitted

        rpc_scoring_engine = api_utils.get_resource(
            'ScoringEngine', scoring_engine)

        return ScoringEngine.convert_with_links(rpc_scoring_engine)
Example #21
0
    def get_one(self, scoring_engine):
        """Retrieve information about the given Scoring Engine.

        :param scoring_engine_name: The name of the Scoring Engine.
        """
        context = pecan.request.context
        policy.enforce(context, 'scoring_engine:get',
                       action='scoring_engine:get')

        if self.from_scoring_engines:
            raise exception.OperationNotPermitted

        rpc_scoring_engine = api_utils.get_resource(
            'ScoringEngine', scoring_engine)

        return ScoringEngine.convert_with_links(rpc_scoring_engine)
Example #22
0
    def patch(self, audit_template, patch):
        """Update an existing audit template.

        :param audit template_uuid: UUID of a audit template.
        :param patch: a json PATCH document to apply to this audit template.
        """
        if self.from_audit_templates:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        audit_template_to_update = api_utils.get_resource('AuditTemplate',
                                                          audit_template)
        policy.enforce(context, 'audit_template:update',
                       audit_template_to_update,
                       action='audit_template:update')

        if common_utils.is_uuid_like(audit_template):
            audit_template_to_update = objects.AuditTemplate.get_by_uuid(
                pecan.request.context,
                audit_template)
        else:
            audit_template_to_update = objects.AuditTemplate.get_by_name(
                pecan.request.context,
                audit_template)

        try:
            audit_template_dict = audit_template_to_update.as_dict()
            audit_template = AuditTemplate(**api_utils.apply_jsonpatch(
                audit_template_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.AuditTemplate.fields:
            try:
                patch_val = getattr(audit_template, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if audit_template_to_update[field] != patch_val:
                audit_template_to_update[field] = patch_val

        audit_template_to_update.save()
        return AuditTemplate.convert_with_links(audit_template_to_update)
Example #23
0
    def patch(self, audit_template, patch):
        """Update an existing audit template.

        :param audit template_uuid: UUID of a audit template.
        :param patch: a json PATCH document to apply to this audit template.
        """
        if self.from_audit_templates:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        audit_template_to_update = api_utils.get_resource('AuditTemplate',
                                                          audit_template)
        policy.enforce(context, 'audit_template:update',
                       audit_template_to_update,
                       action='audit_template:update')

        if common_utils.is_uuid_like(audit_template):
            audit_template_to_update = objects.AuditTemplate.get_by_uuid(
                pecan.request.context,
                audit_template)
        else:
            audit_template_to_update = objects.AuditTemplate.get_by_name(
                pecan.request.context,
                audit_template)

        try:
            audit_template_dict = audit_template_to_update.as_dict()
            audit_template = AuditTemplate(**api_utils.apply_jsonpatch(
                audit_template_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.AuditTemplate.fields:
            try:
                patch_val = getattr(audit_template, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if audit_template_to_update[field] != patch_val:
                audit_template_to_update[field] = patch_val

        audit_template_to_update.save()
        return AuditTemplate.convert_with_links(audit_template_to_update)
Example #24
0
    def state(self, strategy):
        """Retrieve an information about strategy requirements.

        :param strategy: name of the strategy.
        """
        context = pecan.request.context
        policy.enforce(context, 'strategy:state', action='strategy:state')
        parents = pecan.request.path.split('/')[:-1]
        if parents[-2] != "strategies":
            raise exception.HTTPNotFound
        rpc_strategy = api_utils.get_resource('Strategy', strategy)
        de_client = rpcapi.DecisionEngineAPI()
        strategy_state = de_client.get_strategy_info(context,
                                                     rpc_strategy.name)
        strategy_state.extend([{
            'type': 'Name', 'state': rpc_strategy.name,
            'mandatory': '', 'comment': ''}])
        return strategy_state
Example #25
0
    def delete(self, audit):
        """Delete an audit.

        :param audit: UUID or name of an audit.
        """
        context = pecan.request.context
        audit_to_delete = api_utils.get_resource('Audit', audit, eager=True)
        policy.enforce(context,
                       'audit:delete',
                       audit_to_delete,
                       action='audit:delete')

        initial_state = audit_to_delete.state
        new_state = objects.audit.State.DELETED
        if not objects.audit.AuditStateTransitionManager().check_transition(
                initial_state, new_state):
            raise exception.DeleteError(state=initial_state)

        audit_to_delete.soft_delete()
Example #26
0
    def delete(self, action_plan_uuid):
        """Delete an action plan.

        :param action_plan_uuid: UUID of a action.
        """
        context = pecan.request.context
        action_plan = api_utils.get_resource(
            'ActionPlan', action_plan_uuid, eager=True)
        policy.enforce(context, 'action_plan:delete', action_plan,
                       action='action_plan:delete')

        allowed_states = (ap_objects.State.SUCCEEDED,
                          ap_objects.State.RECOMMENDED,
                          ap_objects.State.FAILED,
                          ap_objects.State.SUPERSEDED,
                          ap_objects.State.CANCELLED)
        if action_plan.state not in allowed_states:
            raise exception.DeleteError(
                state=action_plan.state)

        action_plan.soft_delete()
Example #27
0
    def post(self, audit_ident, body):
        """Trigger the given audit.

        :param audit_ident: UUID or name of an audit.
        """

        LOG.debug("Webhook trigger Audit: %s.", audit_ident)

        context = pecan.request.context
        audit = utils.get_resource('Audit', audit_ident)
        if audit is None:
            raise exception.AuditNotFound(audit=audit_ident)
        if audit.audit_type != objects.audit.AuditType.EVENT.value:
            raise exception.AuditTypeNotAllowed(audit_type=audit.audit_type)
        allowed_state = (
            objects.audit.State.PENDING,
            objects.audit.State.SUCCEEDED,
        )
        if audit.state not in allowed_state:
            raise exception.AuditStateNotAllowed(state=audit.state)

        # trigger decision-engine to run the audit
        self.dc_client.trigger_audit(context, audit.uuid)
Example #28
0
    def patch(self, action_plan_uuid, patch):
        """Update an existing action plan.

        :param action_plan_uuid: UUID of a action plan.
        :param patch: a json PATCH document to apply to this action plan.
        """
        if self.from_actionsPlans:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        action_plan_to_update = api_utils.get_resource('ActionPlan',
                                                       action_plan_uuid,
                                                       eager=True)
        policy.enforce(context,
                       'action_plan:update',
                       action_plan_to_update,
                       action='action_plan:update')

        try:
            action_plan_dict = action_plan_to_update.as_dict()
            action_plan = ActionPlan(
                **api_utils.apply_jsonpatch(action_plan_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        launch_action_plan = False
        cancel_action_plan = False

        # transitions that are allowed via PATCH
        allowed_patch_transitions = [
            (ap_objects.State.RECOMMENDED, ap_objects.State.PENDING),
            (ap_objects.State.RECOMMENDED, ap_objects.State.CANCELLED),
            (ap_objects.State.ONGOING, ap_objects.State.CANCELLING),
            (ap_objects.State.PENDING, ap_objects.State.CANCELLED),
        ]

        # todo: improve this in blueprint watcher-api-validation
        if hasattr(action_plan, 'state'):
            transition = (action_plan_to_update.state, action_plan.state)
            if transition not in allowed_patch_transitions:
                error_message = _("State transition not allowed: "
                                  "(%(initial_state)s -> %(new_state)s)")
                raise exception.PatchError(
                    patch=patch,
                    reason=error_message %
                    dict(initial_state=action_plan_to_update.state,
                         new_state=action_plan.state))

            if action_plan.state == ap_objects.State.PENDING:
                launch_action_plan = True
            if action_plan.state == ap_objects.State.CANCELLED:
                cancel_action_plan = True

        # Update only the fields that have changed
        for field in objects.ActionPlan.fields:
            try:
                patch_val = getattr(action_plan, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if action_plan_to_update[field] != patch_val:
                action_plan_to_update[field] = patch_val

            if (field == 'state'
                    and patch_val == objects.action_plan.State.PENDING):
                launch_action_plan = True

        action_plan_to_update.save()

        # NOTE: if action plan is cancelled from pending or recommended
        # state update action state here only
        if cancel_action_plan:
            filters = {'action_plan_uuid': action_plan.uuid}
            actions = objects.Action.list(pecan.request.context,
                                          filters=filters,
                                          eager=True)
            for a in actions:
                a.state = objects.action.State.CANCELLED
                a.save()

        if launch_action_plan:
            self.applier_client.launch_action_plan(pecan.request.context,
                                                   action_plan.uuid)

        action_plan_to_update = objects.ActionPlan.get_by_uuid(
            pecan.request.context, action_plan_uuid)
        return ActionPlan.convert_with_links(action_plan_to_update)
Example #29
0
    def patch(self, action_plan_uuid, patch):
        """Update an existing action plan.

        :param action_plan_uuid: UUID of a action plan.
        :param patch: a json PATCH document to apply to this action plan.
        """
        launch_action_plan = True
        if self.from_actionsPlans:
            raise exception.OperationNotPermitted

        context = pecan.request.context
        action_plan_to_update = api_utils.get_resource('ActionPlan',
                                                       action_plan_uuid)
        policy.enforce(context, 'action_plan:update', action_plan_to_update,
                       action='action_plan:update')

        try:
            action_plan_dict = action_plan_to_update.as_dict()
            action_plan = ActionPlan(**api_utils.apply_jsonpatch(
                action_plan_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        launch_action_plan = False

        # transitions that are allowed via PATCH
        allowed_patch_transitions = [
            (ap_objects.State.RECOMMENDED,
             ap_objects.State.PENDING),
            (ap_objects.State.RECOMMENDED,
             ap_objects.State.CANCELLED),
            (ap_objects.State.ONGOING,
             ap_objects.State.CANCELLED),
            (ap_objects.State.PENDING,
             ap_objects.State.CANCELLED),
        ]

        # todo: improve this in blueprint watcher-api-validation
        if hasattr(action_plan, 'state'):
            transition = (action_plan_to_update.state, action_plan.state)
            if transition not in allowed_patch_transitions:
                error_message = _("State transition not allowed: "
                                  "(%(initial_state)s -> %(new_state)s)")
                raise exception.PatchError(
                    patch=patch,
                    reason=error_message % dict(
                        initial_state=action_plan_to_update.state,
                        new_state=action_plan.state))

            if action_plan.state == ap_objects.State.PENDING:
                launch_action_plan = True

        # Update only the fields that have changed
        for field in objects.ActionPlan.fields:
            try:
                patch_val = getattr(action_plan, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if action_plan_to_update[field] != patch_val:
                action_plan_to_update[field] = patch_val

            if (field == 'state'
                    and patch_val == objects.action_plan.State.PENDING):
                launch_action_plan = True

        action_plan_to_update.save()

        if launch_action_plan:
            applier_client = rpcapi.ApplierAPI()
            applier_client.launch_action_plan(pecan.request.context,
                                              action_plan.uuid)

        action_plan_to_update = objects.ActionPlan.get_by_uuid(
            pecan.request.context,
            action_plan_uuid)
        return ActionPlan.convert_with_links(action_plan_to_update)