From 064c0c75979ef0cdab85e8d98d290d47af6f77f4 Mon Sep 17 00:00:00 2001
From: Lukas Holecek <hluk@email.cz>
Date: Oct 24 2018 14:53:23 +0000
Subject: Check RemoteRule configuration at start


Signed-off-by: Lukas Holecek <hluk@email.cz>

---

diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py
index 4237206..dea968d 100644
--- a/greenwave/api_v1.py
+++ b/greenwave/api_v1.py
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 from flask import Blueprint, request, current_app, jsonify, url_for, redirect, Response
-from werkzeug.exceptions import BadRequest, NotFound, UnsupportedMediaType, InternalServerError
+from werkzeug.exceptions import BadRequest, NotFound, UnsupportedMediaType
 from prometheus_client import generate_latest
 from greenwave import __version__
-from greenwave.policies import summarize_answers, RemotePolicy, RemoteRule
+from greenwave.policies import summarize_answers, RemotePolicy
 from greenwave.resources import ResultsRetriever, retrieve_waivers
 from greenwave.safe_yaml import SafeYAMLError
 from greenwave.utils import insert_headers, jsonp
@@ -309,17 +309,6 @@ def make_decision():
     ignore_results = data.get('ignore_result', [])
     ignore_waivers = data.get('ignore_waiver', [])
 
-    for policy in current_app.config['policies']:
-        for rule in policy.rules:
-            if isinstance(rule, RemoteRule):
-                if ('DIST_GIT_BASE_URL' not in current_app.config or
-                    'DIST_GIT_URL_TEMPLATE' not in current_app.config or
-                        'KOJI_BASE_URL' not in current_app.config):
-                    raise InternalServerError("If you want to apply a RemoteRule"
-                                              " you need to configure 'DIST_GIT_BASE_URL',"
-                                              "'DIST_GIT_URL_TEMPLATE' and KOJI_BASE_URL in "
-                                              "your configuration.")
-
     answers = []
     verbose_results = []
     verbose_waivers = []
diff --git a/greenwave/app_factory.py b/greenwave/app_factory.py
index 971fd72..96c30d9 100644
--- a/greenwave/app_factory.py
+++ b/greenwave/app_factory.py
@@ -5,7 +5,7 @@ import logging
 from flask import Flask
 from greenwave.api_v1 import api
 from greenwave.utils import json_error, load_config, sha1_mangle_key
-from greenwave.policies import load_policies
+from greenwave.policies import load_policies, RemoteRule
 
 from dogpile.cache import make_region
 from requests import ConnectionError, Timeout
@@ -14,6 +14,22 @@ from werkzeug.exceptions import default_exceptions
 log = logging.getLogger(__name__)
 
 
+def _can_use_remote_rule(config):
+    return (
+        config.get('DIST_GIT_BASE_URL') and
+        config.get('DIST_GIT_URL_TEMPLATE') and
+        config.get('KOJI_BASE_URL')
+    )
+
+
+def _has_remote_rule(policies):
+    return any(
+        isinstance(rule, RemoteRule)
+        for policy in policies
+        for rule in policy.rules
+    )
+
+
 # applicaiton factory http://flask.pocoo.org/docs/0.12/patterns/appfactories/
 def create_app(config_obj=None):
     app = Flask(__name__)
@@ -26,6 +42,13 @@ def create_app(config_obj=None):
     log.debug("config: Loading policies from %r", policies_dir)
     app.config['policies'] = load_policies(policies_dir)
 
+    if not _can_use_remote_rule(app.config) and _has_remote_rule(app.config['policies']):
+        raise RuntimeError(
+            "If you want to apply a RemoteRule"
+            " you need to configure 'DIST_GIT_BASE_URL',"
+            "'DIST_GIT_URL_TEMPLATE' and KOJI_BASE_URL in "
+            "your configuration.")
+
     # register error handlers
     for code in default_exceptions.keys():
         app.register_error_handler(code, json_error)
diff --git a/greenwave/tests/test_app_factory.py b/greenwave/tests/test_app_factory.py
new file mode 100644
index 0000000..85591ea
--- /dev/null
+++ b/greenwave/tests/test_app_factory.py
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+import mock
+import pytest
+
+from textwrap import dedent
+
+from greenwave.app_factory import create_app
+from greenwave.policies import Policy
+from greenwave.config import TestingConfig
+
+
+@mock.patch('greenwave.policies.load_policies')
+def test_remote_rules_misconfigured(mock_load_policies):
+    """
+    The application shouldn't start if RemoteRule is in policy configuration
+    but if cannot be used because dist-git or koji URL is not configured.
+    """
+
+    policies = Policy.safe_load_all(dedent("""
+        --- !Policy
+        id: test_policy
+        product_versions: [fedora-rawhide]
+        decision_context: another_test_context
+        subject_type: koji_build
+        rules:
+          - !RemoteRule {}
+    """))
+    mock_load_policies.return_value = policies
+
+    config = TestingConfig()
+    config.DIST_GIT_BASE_URL = ''
+
+    expected_error = 'If you want to apply a RemoteRule you need to configure'
+
+    with pytest.raises(RuntimeError, match=expected_error):
+        create_app(config)

