Exemplo n.º 1
0
def origin_annotation_load(request, action, user):
    # Find last accepted review which means it was reviewed and annotated.
    review = review_find_last(request, user, ['accepted'])
    if not review:
        return False

    try:
        annotation = yaml.safe_load(review.comment)
    except yaml.scanner.ScannerError as e:
        # OBS used to prefix subsequent review lines with two spaces. At some
        # point it was changed to no longer indent, but still need to be able
        # to load older annotations.
        comment_stripped = re.sub(r'^  ',
                                  '',
                                  review.comment,
                                  flags=re.MULTILINE)
        annotation = yaml.safe_load(comment_stripped)

    if not annotation or type(
            annotation) is not dict or 'origin' not in annotation:
        # Only returned structured data (ie. dict) with a minimum of the origin
        # key available, otherwise None.
        return None

    if len(request.actions) > 1:
        action_key = request_action_key(action)
        if action_key not in annotation:
            return False

        return annotation[action_key]

    return annotation
Exemplo n.º 2
0
    def add_review(self,
                   req,
                   by_group=None,
                   by_user=None,
                   by_project=None,
                   by_package=None,
                   msg=None,
                   allow_duplicate=False):
        query = {'cmd': 'addreview'}
        if by_group:
            query['by_group'] = by_group
        elif by_user:
            query['by_user'] = by_user
        elif by_project:
            query['by_project'] = by_project
            if by_package:
                query['by_package'] = by_package
        else:
            raise osc.oscerr.WrongArgs("missing by_*")

        for r in req.reviews:
            if (r.by_group == by_group and r.by_project == by_project
                    and r.by_package == by_package and r.by_user == by_user and
                    # Only duplicate when allow_duplicate and state != new.
                (not allow_duplicate or r.state == 'new')):
                del query['cmd']
                self.logger.debug(
                    'skipped adding duplicate review for {}'.format('/'.join(
                        query.values())))
                return

        u = osc.core.makeurl(self.apiurl, ['request', req.reqid], query)
        if self.dryrun:
            self.logger.info('POST %s' % u)
            return

        if self.multiple_actions:
            key = request_action_key(self.action)
            msg = yaml.dump({key: msg}, default_flow_style=False)

        try:
            r = osc.core.http_POST(u, data=msg)
        except HTTPError as e:
            if e.code != 403:
                raise e
            del query['cmd']
            self.logger.info('unable to add review {} with message: {}'.format(
                query, msg))
            return

        code = ET.parse(r).getroot().attrib['code']
        if code != 'ok':
            raise Exception('non-ok return code: {}'.format(code))
Exemplo n.º 3
0
    def check_one_request(self, req):
        """
        check all actions in one request.

        calls helper functions for each action type

        return None if nothing to do, True to accept, False to reject
        """

        if len(req.actions) > 1:
            if self.only_one_action:
                self.review_messages[
                    'declined'] = 'Only one action per request supported'
                return False

            # Will cause added reviews and overall review message to include
            # each actions message prefixed by an action key.
            self.multiple_actions = True
            review_messages_multi = {}
        else:
            self.multiple_actions = False

            # Copy original values to revert changes made to them.
            self.review_messages = self.DEFAULT_REVIEW_MESSAGES.copy()

        if self.comment_handler is not False:
            self.comment_handler_add()

        overall = True
        for a in req.actions:
            if self.multiple_actions:
                self.review_messages = self.DEFAULT_REVIEW_MESSAGES.copy()

            # Store in-case sub-classes need direct access to original values.
            self.action = a
            key = request_action_key(a)
            with sentry_sdk.configure_scope() as scope:
                scope.set_extra('action.key', key)

            override = self.request_override_check()
            if override is not None:
                ret = override
            else:
                func = getattr(self, self.action_method(a))
                ret = func(req, a)

            # In the case of multiple actions take the "lowest" result where the
            # order from lowest to highest is: False, None, True.
            if overall is not False:
                if ((overall is True and ret is not True)
                        or (overall is None and ret is False)):
                    overall = ret

            if self.multiple_actions and ret is not None:
                message_key = self.review_message_key(ret)
                review_messages_multi[key] = self.review_messages[message_key]

        message_key = self.review_message_key(overall)
        if self.multiple_actions:
            message_combined = yaml.dump(review_messages_multi,
                                         default_flow_style=False)
            self.review_messages[message_key] = message_combined
        elif type(self.review_messages[message_key]) is dict:
            self.review_messages[message_key] = yaml.dump(
                self.review_messages[message_key], default_flow_style=False)

        return overall