Beispiel #1
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)
Beispiel #2
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)