From f3cb6cbd5d3872a36ad4a510320575fbb1796094 Mon Sep 17 00:00:00 2001 From: Yashvardhan Nanavati Date: Mar 18 2019 16:17:03 +0000 Subject: Return warning if there is no parent policy for a remote rule policy Users mistakenly configure a parent policy with a decision_context and a gating.yaml file with another decision_context. This can cause unnecessary delays for the user. In order to avoid this, add a check in the validate_gating_yaml endpoint to print a warning message notifying the user about it. --- diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index f325e2e..b625494 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -958,7 +958,7 @@ def test_validate_gating_yaml_valid(requests_session, greenwave_server): id: "test" product_versions: - fedora-26 - decision_context: test + decision_context: container-image-test rules: - !PassingTestCaseRule {test_case_name: test} """) @@ -1031,6 +1031,34 @@ def test_validate_gating_yaml_missing_tag(requests_session, greenwave_server): assert result.status_code == 400 +def test_validate_gating_yaml_missing_decision_context(requests_session, greenwave_server): + gating_yaml = dedent(""" + --- !Policy + id: "test" + product_versions: + - fedora-26 + decision_context: test_missing_1 + rules: + - !PassingTestCaseRule {test_case_name: test} + + --- !Policy + id: "test_2" + product_versions: + - fedora-26 + decision_context: test_missing_2 + rules: + - !PassingTestCaseRule {test_case_name: test_2} + """) + result = requests_session.post( + greenwave_server + 'api/v1.0/validate-gating-yaml', data=gating_yaml) + assert result.json().get('message') == ('Greenwave could not find a parent policy(ies) for ' + 'following decision context(s): ' + 'test_missing_1, test_missing_2. Please change your' + ' policy so that it will match a decision' + ' context in the parent policies.') + assert result.status_code == 200 + + def test_make_a_decision_about_compose_all_variants_architectures( requests_session, greenwave_server, testdatabuilder): compose_id = testdatabuilder.unique_compose_id() diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index 9a83588..7c472e5 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -5,7 +5,9 @@ from flask import Blueprint, request, current_app, jsonify, url_for, redirect, R from werkzeug.exceptions import BadRequest, NotFound, UnsupportedMediaType from prometheus_client import generate_latest from greenwave import __version__ -from greenwave.policies import summarize_answers, RemotePolicy +from greenwave.policies import (summarize_answers, + RemotePolicy, + _missing_decision_contexts_in_parent_policies) from greenwave.resources import ResultsRetriever, retrieve_waivers from greenwave.safe_yaml import SafeYAMLError from greenwave.utils import insert_headers, jsonp @@ -437,11 +439,18 @@ def validate_gating_yaml_post(): log.error('No policies defined') raise BadRequest('No policies defined') + missing_decision_contexts = _missing_decision_contexts_in_parent_policies(policies) if any(True for policy in policies if policy.blacklist): msg = {'message': ('The gating.yaml file is valid but it is using the deprecated ' '"blacklist" key. Please use "excluded_packages" instead.')} + elif missing_decision_contexts: + msg = {'message': ('Greenwave could not find a parent policy(ies) for following decision' + ' context(s): {}. Please change your policy so that it will match a ' + 'decision context in the parent policies.'.format( + ', '.join(missing_decision_contexts)))} else: msg = {'message': 'All OK'} + return jsonify(msg) diff --git a/greenwave/policies.py b/greenwave/policies.py index b04e3b5..b3b6f4a 100644 --- a/greenwave/policies.py +++ b/greenwave/policies.py @@ -7,6 +7,7 @@ import logging import os import re import greenwave.resources +from flask import current_app from greenwave.safe_yaml import ( SafeYAMLChoice, @@ -638,3 +639,19 @@ def applicable_decision_context_product_version_pairs(policies, **attributes): log.debug("found %i decision contexts", len(contexts_product_versions)) return contexts_product_versions + + +def _missing_decision_contexts_in_parent_policies(policies): + missing_decision_contexts = [] + for policy in policies: + # Assume a parent policy is not present for a policy in the remote rule + parent_present = False + for parent_policy in current_app.config['policies']: + if parent_policy.decision_context == policy.decision_context: + parent_present = True + break + # If there are no parent policies for a decision_context in the remote rule, + # report it as missing to warn the user. + if not parent_present: + missing_decision_contexts.append(policy.decision_context) + return missing_decision_contexts