From cfd6aeb83ae4a1f074c63f29d1f63aca9f1f072a Mon Sep 17 00:00:00 2001 From: Giulia Naponiello Date: Apr 30 2018 18:08:47 +0000 Subject: [PATCH 1/4] Introducing RemoteRule for extending policies Packagers become responsible for defining extensions to the policy for their specific packages defining a greenwave.yaml file in the dist-git repos of packages. Greenwave checks if the file exists, and, if it does it pulls it down, loads it, and uses it to additionally evaluate the subject of the decision. --- diff --git a/conf/policies/fedora.yaml b/conf/policies/fedora.yaml index 9f37374..fe77fd5 100644 --- a/conf/policies/fedora.yaml +++ b/conf/policies/fedora.yaml @@ -48,3 +48,11 @@ blacklist: [] rules: - !PassingTestCaseRule {test_case_name: compose.install_no_user, scenario: scenario1} - !PassingTestCaseRule {test_case_name: compose.install_no_user, scenario: scenario2} +--- !Policy +id: "taskotron_release_critical_tasks_with_remoterule" +product_versions: + - fedora-26 +decision_context: bodhi_update_push_stable_with_remoterule +blacklist: [] +rules: + - !RemoteOriginalSpecNvrRule {test_case_name: dist.upgradepath} diff --git a/functional-tests/conftest.py b/functional-tests/conftest.py index 0607c08..c8686f0 100644 --- a/functional-tests/conftest.py +++ b/functional-tests/conftest.py @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0+ import os +import sys +import tempfile import time import textwrap import itertools @@ -125,6 +127,20 @@ def waiverdb_server(tmpdir_factory): p.wait() +@pytest.yield_fixture(scope='session') +def distgit_server(): + """ Creating a fake dist-git process. It is just a serving some files in /tmp """ + tmpdir = tempfile.mkdtemp('data') + p = subprocess.Popen([sys.executable, '-m', 'SimpleHTTPServer', '5678'], cwd=tmpdir) + #p = subprocess.Popen('pushd /tmp;python -m SimpleHTTPServer 5678', shell=True) + log.debug('Started dist-git server as pid %s', p.pid) + wait_for_listen(5678) + yield 'http://localhost:5678' + log.debug('Terminating dist-git server pid %s', p.pid) + p.terminate() + p.wait() + + # This is only a fixture because some tests want to point the fedmsg consumers # at the same cache that the server process is using. # I would like to refactor those tests to send real messages to real consumers, @@ -179,10 +195,11 @@ class TestDataBuilder(object): ResultsDB and WaiverDB. """ - def __init__(self, requests_session, resultsdb_url, waiverdb_url): + def __init__(self, requests_session, resultsdb_url, waiverdb_url, distgit_url): self.requests_session = requests_session self.resultsdb_url = resultsdb_url self.waiverdb_url = waiverdb_url + self.distgit_url = distgit_url self._counter = itertools.count(1) def unique_nvr(self): @@ -207,12 +224,15 @@ class TestDataBuilder(object): response.raise_for_status() return response.json() - def create_result(self, item, testcase_name, outcome, scenario=None): + def create_result(self, item, testcase_name, outcome, scenario=None, key=None): data = { 'testcase': {'name': testcase_name}, - 'data': {'item': item, 'type': 'koji_build'}, 'outcome': outcome, } + if not key: + data['data'] = {'item': item, 'type': 'koji_build'} + else: + data['data'] = {key: item} if scenario: data['data']['scenario'] = scenario response = self.requests_session.post( @@ -244,5 +264,5 @@ class TestDataBuilder(object): @pytest.fixture(scope='session') -def testdatabuilder(requests_session, resultsdb_server, waiverdb_server): - return TestDataBuilder(requests_session, resultsdb_server, waiverdb_server) +def testdatabuilder(requests_session, resultsdb_server, waiverdb_server, distgit_server): + return TestDataBuilder(requests_session, resultsdb_server, waiverdb_server, distgit_server) diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index b2e2291..134d67e 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -1,6 +1,14 @@ # SPDX-License-Identifier: GPL-2.0+ import json +import os + +import pytest +from werkzeug.exceptions import InternalServerError + +from greenwave.app_factory import create_app +from greenwave.utils import load_policies +from greenwave.policies import RuleSatisfied all_rpmdiff_testcase_names = [ @@ -95,7 +103,7 @@ def test_inspect_policies(requests_session, greenwave_server): assert r.status_code == 200 body = r.json() policies = body['policies'] - assert len(policies) == 6 + assert len(policies) == 7 assert any(p['id'] == 'taskotron_release_critical_tasks' for p in policies) assert any(p['decision_context'] == 'bodhi_update_push_stable' for p in policies) assert any(p['product_versions'] == ['fedora-26'] for p in policies) @@ -253,6 +261,8 @@ def test_make_a_decison_on_failed_result_with_waiver( result = testdatabuilder.create_result(item=nvr, testcase_name=all_rpmdiff_testcase_names[0], outcome='FAILED') + #import pdb + #pdb.set_trace() waiver = testdatabuilder.create_waiver(result={ # noqa "subject": dict([(key, value[0]) for key, value in result['data'].items()]), "testcase": all_rpmdiff_testcase_names[0]}, product_version='rhel-7', @@ -602,6 +612,83 @@ def test_ignore_waiver(requests_session, greenwave_server, testdatabuilder): assert res_data['unsatisfied_requirements'] == expected_unsatisfied_requirements +def test_distgit_server(requests_session, distgit_server, tmpdir): + """ This test is checking if the distgit server is working. + Check that the file is present and that the server is running. + """ + + p = tmpdir.join('greenwave.yaml') + open(p.strpath, "w+") + # Removing "/tmp/" in the beginning... + url = '{0}/{1}'.format(distgit_server, '/'.join(p.strpath.split('/')[2:])) + r_ = requests_session.head(url, headers={'Content-Type': 'application/json'}, timeout=60) + assert r_.status_code == 200 + + +def test_remote_original_spec_nvr_rule_policy(requests_session, distgit_server, greenwave_server, + tmpdir, testdatabuilder): + """ This test is checking: + - that if there aren't results greenwave must return an error. + - a normal situation with the Remote Rule configured: all the rules are satisfied + """ + p = tmpdir.join('greenwave.yaml') + f = open(p.strpath, "w+") + f.write(""" +--- !Policy +id: "taskotron_release_critical_tasks_with_remoterule" +product_versions: + - fedora-26 +decision_context: bodhi_update_push_stable_with_remoterule +blacklist: [] +rules: + - !RemoteOriginalSpecNvrRule {test_case_name: dist.upgradepath} + """) + f.close() + policies = load_policies(p.dirname) + policy = policies[0] + # Ensure that absence of a result is failure. + item, results, waivers = {}, [], [] + with pytest.raises(InternalServerError): + decision = policy.check(item, results, waivers) + + nvr = testdatabuilder.unique_nvr() + key = "original_spec_nvr" + app = create_app('greenwave.config.TestingConfig') + with app.app_context(): + # now testing with rev, but without the greenwave.yaml file + rev_num = "rev_num" + results = [{ + "data": { + key: [nvr], + "rev": [rev_num], + }, + "testcase": {"name": "dist.upgradepath"}, + "outcome": "PASSED" + }] + + decision = policy.check(item, results, waivers) + assert len(decision) == 1 + assert isinstance(decision[0], RuleSatisfied) + + # now testing with rev and with the greenwave.yaml file + g = open("/tmp/{0}-{1}-greenwave.yaml".format(nvr.rsplit('-', 2)[0], rev_num), "w+") + g.write(""" +--- !Policy +id: "taskotron_release_critical_tasks" +product_versions: + - fedora-26 +decision_context: bodhi_update_push_stable +blacklist: [] +rules: + - !PassingTestCaseRule {test_case_name: dist.upgradepath} + """) + g.close() + decision = policy.check(item, results, waivers) + os.remove("/tmp/{0}-{1}-greenwave.yaml".format(nvr.rsplit('-', 2)[0], rev_num)) + assert len(decision) == 1 + assert isinstance(decision[0], RuleSatisfied) + + def test_cached_false_positive(requests_session, greenwave_server, testdatabuilder): """ Test that caching without invalidation produces false positives. diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index ed7e14b..7e45709 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0+ from flask import Blueprint, request, current_app, jsonify -from werkzeug.exceptions import BadRequest, NotFound, UnsupportedMediaType +from werkzeug.exceptions import BadRequest, NotFound, UnsupportedMediaType, InternalServerError from greenwave import __version__ -from greenwave.policies import summarize_answers +from greenwave.policies import summarize_answers, RemoteOriginalSpecNvrRule from greenwave.resources import retrieve_results, retrieve_waivers from greenwave.utils import insert_headers, jsonp @@ -204,6 +204,7 @@ def make_decision(): :statuscode 200: A decision was made. :statuscode 400: Invalid data was given. """ # noqa: E501 + if request.get_json(): if ('product_version' not in request.get_json() or not request.get_json()['product_version']): @@ -226,6 +227,18 @@ def make_decision(): raise BadRequest('Invalid verbose flag, must be a bool') 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, RemoteOriginalSpecNvrRule): + 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 RemoteOriginalSpecNvrRule" + " you need to configure 'DIST_GIT_BASE_URL'," + "'DIST_GIT_URL_TEMPLATE' and KOJI_BASE_URL in " + "your configuration.") + applicable_policies = [policy for policy in current_app.config['policies'] if policy.applies_to(decision_context, product_version)] if not applicable_policies: diff --git a/greenwave/app_factory.py b/greenwave/app_factory.py index 0580582..01c807b 100644 --- a/greenwave/app_factory.py +++ b/greenwave/app_factory.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ - from flask import Flask from greenwave.logger import init_logging from greenwave.api_v1 import api @@ -15,6 +14,7 @@ from werkzeug.exceptions import default_exceptions # applicaiton factory http://flask.pocoo.org/docs/0.12/patterns/appfactories/ def create_app(config_obj=None): app = Flask(__name__) + app.config.update(load_config(config_obj)) if app.config['PRODUCTION'] and app.secret_key == 'replace-me-with-something-random': raise Warning("You need to change the app.secret_key value for production") diff --git a/greenwave/config.py b/greenwave/config.py index b872100..fa0ed45 100644 --- a/greenwave/config.py +++ b/greenwave/config.py @@ -18,6 +18,12 @@ class Config(object): WAIVERDB_API_URL = 'https://waiverdb.fedoraproject.org/api/v1.0' # Options for outbound HTTP requests made by python-requests +<<<<<<< HEAD +======= + DIST_GIT_BASE_URL = 'https://src.fedoraproject.org' + DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}/{pkg_name}/{rev}/greenwave.yaml' + KOJI_BASE_URL = 'https://koji.fedoraproject.org/kojihub' +>>>>>>> 66e68b8... Introducing RemoteRule for extending policies REQUESTS_TIMEOUT = (6.1, 15) REQUESTS_VERIFY = True @@ -61,3 +67,5 @@ class TestingConfig(Config): os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'conf', 'policies' ) + DIST_GIT_BASE_URL = 'http://localhost:5678' + DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}/{pkg_name}-{rev}-greenwave.yaml' diff --git a/greenwave/policies.py b/greenwave/policies.py index c810d18..ec6827f 100644 --- a/greenwave/policies.py +++ b/greenwave/policies.py @@ -2,6 +2,23 @@ from fnmatch import fnmatch import yaml +from werkzeug.exceptions import InternalServerError +import greenwave.resources + + +def validate_policies(policies, disallowed_rules=[]): + for policy in policies: + if not isinstance(policy, Policy): + raise RuntimeError('Policies are not configured properly as policy %s ' + 'is not an instance of Policy' % policy) + for rule in policy.rules: + if not isinstance(rule, Rule): + raise RuntimeError('Policies are not configured properly as rule %s ' + 'is not an instance of Rule' % rule) + for disallowed_rule in disallowed_rules: + if isinstance(rule, disallowed_rule): + raise RuntimeError('Policies are not configured properly as rule %s ' + 'is an instance of %s' % (rule, disallowed_rule)) class Answer(object): @@ -143,6 +160,50 @@ class Rule(yaml.YAMLObject): raise NotImplementedError() +class RemoteOriginalSpecNvrRule(Rule): + yaml_tag = u'!RemoteOriginalSpecNvrRule' + yaml_loader = yaml.SafeLoader + + def check(self, item, results, waivers): + for result in results: + if 'original_spec_nvr' not in result['data']: # just go on to the next one + continue + if 'rev' not in result['data'] or len(result['data']['rev']) == 0: + # Trying to find the rev asking to koji + rev = greenwave.resources.retrieve_rev_from_koji( + result['data']['original_spec_nvr'][0]) + else: + rev = result['data']['rev'][0] + pkg_name = result['data']['original_spec_nvr'][0].rsplit('-', 2)[0] + response = greenwave.resources.retrieve_yaml_remote_original_spec_nvr_rule(rev, + pkg_name) + # greenwave file not found + if isinstance(response, RuleSatisfied): + return RuleSatisfied() + else: + policies = yaml.safe_load_all(response) + # policies is a generator, so listifying it + policies = list(policies) + validate_policies(policies, [RemoteOriginalSpecNvrRule]) + answers = [] + for policy in policies: + response = policy.check(item, results, waivers) + if isinstance(response, list): + answers.extend(response) + else: + answers.append(response) + return answers + + # if we arrived here it means that we don't have any result... + raise InternalServerError('Impossible to extend the policy.') + + def to_json(self): + return { + 'rule': self.__class__.__name__, + 'test_case_name': self.test_case_name, + } + + class PassingTestCaseRule(Rule): """ This rule requires either a passing result for the given test case, or @@ -279,7 +340,14 @@ class Policy(yaml.YAMLObject): item.get('item') and item['item'].rsplit('-', 2)[0] == package): return [RuleSatisfied() for rule in self.rules] - return [rule.check(item, results, waivers) for rule in self.rules] + answers = [] + for rule in self.rules: + response = rule.check(item, results, waivers) + if isinstance(response, list): + answers.extend(response) + else: + answers.append(response) + return answers def __repr__(self): return "%s(id=%r, product_versions=%r, decision_context=%r, rules=%r)" % ( diff --git a/greenwave/resources.py b/greenwave/resources.py index 5a4d57e..bb85695 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -7,23 +7,66 @@ waiverdb, etc..). """ import json - import requests import urllib3.exceptions +import urlparse +import xmlrpclib from flask import current_app +from werkzeug.exceptions import BadGateway from greenwave.cache import cached from greenwave.utils import retry +import greenwave.policies requests_session = requests.Session() @cached @retry(wait_on=urllib3.exceptions.NewConnectionError) +def retrieve_rev_from_koji(nvr): + """ Retrieve cached rev from koji using the nrv """ + proxy = xmlrpclib.ServerProxy(current_app.config['KOJI_BASE_URL']) + build = proxy.getBuild(nvr) + try: + url = urlparse(build['extra']['source']['original_url']) + if not url.scheme.startswith('git'): + raise BadGateway('Error occurred looking for the "rev" in koji.') + return url.fragment + except Exception: + raise BadGateway('Error occurred looking for the "rev" in koji.') + + +@cached +def retrieve_yaml_remote_original_spec_nvr_rule(rev, pkg_name): + """ Retrieve cached greenwave.yaml content for a given rev. """ + data = { + "DIST_GIT_BASE_URL": current_app.config['DIST_GIT_BASE_URL'], + "pkg_name": pkg_name, + "rev": rev + } + url = current_app.config['DIST_GIT_URL_TEMPLATE'].format(**data) + response = requests_session.request('HEAD', url, + headers={'Content-Type': 'application/json'}, + timeout=60) + if response.status_code == 404: + return greenwave.policies.RuleSatisfied() + elif response.status_code != 200: + raise BadGateway('Error occurred looking for greenwave.yaml file in the dist-git repo.') + + # greenwave.yaml found... + response = requests_session.request('GET', url, + headers={'Content-Type': 'application/json'}, + timeout=60) + response.raise_for_status() + return response.content + + +@cached def retrieve_results(item): """ Retrieve cached results from resultsdb for a given item. """ # XXX make this more efficient than just fetching everything + params = item.copy() params.update({'limit': '1000'}) timeout = current_app.config['REQUESTS_TIMEOUT'] diff --git a/greenwave/tests/test_policies.py b/greenwave/tests/test_policies.py index 614b6a3..01b0a94 100644 --- a/greenwave/tests/test_policies.py +++ b/greenwave/tests/test_policies.py @@ -3,6 +3,7 @@ import json import pytest +import mock from greenwave import __version__ from greenwave.app_factory import create_app @@ -378,3 +379,37 @@ rules: [] assert policy.applies_to('dummy_context', 'fedora-27') assert policy.applies_to('dummy_context', 'fedora-28') assert not policy.applies_to('dummy_context', 'epel-7') + + +def test_remote_original_spec_nvr_rule_policy(tmpdir): + """ Testing the RemoteOriginalSpecNvrRule with the koji interaction. + In this case we are just mocking koji """ + app = create_app('greenwave.config.TestingConfig') + with app.app_context(): + p = tmpdir.join('greenwave.yaml') + p.write(""" +--- !Policy +id: "taskotron_release_critical_tasks_with_remoterule" +product_versions: + - fedora-26 +decision_context: bodhi_update_push_stable_with_remoterule +blacklist: [] +rules: + - !RemoteOriginalSpecNvrRule {test_case_name: dist.upgradepath} + """) + with mock.patch('greenwave.resources.retrieve_rev_from_koji'): + policies = load_policies(tmpdir.strpath) + policy = policies[0] + + # Ensure that absence of a result is failure. + item, waivers = {}, [] + results = [{ + "data": { + "original_spec_nvr": ['nethack-1.2.3-1.el9000'] + }, + "testcase": {"name": "dist.upgradepath"}, + "outcome": "PASSED" + }] + decision = policy.check(item, results, waivers) + assert len(decision) == 1 + assert isinstance(decision[0], RuleSatisfied) diff --git a/greenwave/utils.py b/greenwave/utils.py index 7882168..456dcf3 100644 --- a/greenwave/utils.py +++ b/greenwave/utils.py @@ -10,7 +10,7 @@ import yaml from flask import jsonify, current_app, request from flask.config import Config from werkzeug.exceptions import HTTPException -from greenwave.policies import Policy, Rule +from greenwave.policies import validate_policies log = logging.getLogger(__name__) @@ -105,14 +105,7 @@ def load_policies(policies_dir): policies = [] for policy_pathname in policy_pathnames: policies.extend(yaml.safe_load_all(open(policy_pathname, 'r'))) - for policy in policies: - if not isinstance(policy, Policy): - raise RuntimeError('Policies are not configured properly as policy %s ' - 'is not an instance of Policy' % policy) - for rule in policy.rules: - if not isinstance(rule, Rule): - raise RuntimeError('Policies are not configured properly as rule %s ' - 'is not an instance of Rule' % rule) + validate_policies(policies) return policies From f4bd1f76cf37355a767ab0baf2ee761f43237cf5 Mon Sep 17 00:00:00 2001 From: Giulia Naponiello Date: Apr 30 2018 18:08:49 +0000 Subject: [PATCH 2/4] Fixed test for RemoteRule change. Changed the functional tests to work properly for distgit. Changed also the testing config for test-policies tests. --- diff --git a/functional-tests/conftest.py b/functional-tests/conftest.py index c8686f0..742d853 100644 --- a/functional-tests/conftest.py +++ b/functional-tests/conftest.py @@ -2,7 +2,6 @@ import os import sys -import tempfile import time import textwrap import itertools @@ -128,11 +127,12 @@ def waiverdb_server(tmpdir_factory): @pytest.yield_fixture(scope='session') -def distgit_server(): - """ Creating a fake dist-git process. It is just a serving some files in /tmp """ - tmpdir = tempfile.mkdtemp('data') - p = subprocess.Popen([sys.executable, '-m', 'SimpleHTTPServer', '5678'], cwd=tmpdir) - #p = subprocess.Popen('pushd /tmp;python -m SimpleHTTPServer 5678', shell=True) +def distgit_server(tmpdir_factory): + """ Creating a fake dist-git process. It is just a serving some files in a tmp dir """ + tmp_dir = tmpdir_factory.mktemp('distgit') + f = open(tmp_dir.strpath + "/greenwave.yaml", "w+") + f.close() + p = subprocess.Popen([sys.executable, '-m', 'SimpleHTTPServer', '5678'], cwd=tmp_dir.strpath) log.debug('Started dist-git server as pid %s', p.pid) wait_for_listen(5678) yield 'http://localhost:5678' diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index 134d67e..69c06c8 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -261,8 +261,6 @@ def test_make_a_decison_on_failed_result_with_waiver( result = testdatabuilder.create_result(item=nvr, testcase_name=all_rpmdiff_testcase_names[0], outcome='FAILED') - #import pdb - #pdb.set_trace() waiver = testdatabuilder.create_waiver(result={ # noqa "subject": dict([(key, value[0]) for key, value in result['data'].items()]), "testcase": all_rpmdiff_testcase_names[0]}, product_version='rhel-7', @@ -616,16 +614,12 @@ def test_distgit_server(requests_session, distgit_server, tmpdir): """ This test is checking if the distgit server is working. Check that the file is present and that the server is running. """ - - p = tmpdir.join('greenwave.yaml') - open(p.strpath, "w+") - # Removing "/tmp/" in the beginning... - url = '{0}/{1}'.format(distgit_server, '/'.join(p.strpath.split('/')[2:])) - r_ = requests_session.head(url, headers={'Content-Type': 'application/json'}, timeout=60) + r_ = requests_session.head(distgit_server, headers={'Content-Type': 'application/json'}, + timeout=60) assert r_.status_code == 200 -def test_remote_original_spec_nvr_rule_policy(requests_session, distgit_server, greenwave_server, +def test_remote_original_spec_nvr_rule_policy(requests_session, greenwave_server, tmpdir, testdatabuilder): """ This test is checking: - that if there aren't results greenwave must return an error. diff --git a/greenwave/config.py b/greenwave/config.py index fa0ed45..c04e007 100644 --- a/greenwave/config.py +++ b/greenwave/config.py @@ -67,5 +67,3 @@ class TestingConfig(Config): os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'conf', 'policies' ) - DIST_GIT_BASE_URL = 'http://localhost:5678' - DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}/{pkg_name}-{rev}-greenwave.yaml' From 54b68bb109ade19f5b6671a4e6f85835e0d7bfbd Mon Sep 17 00:00:00 2001 From: Giulia Naponiello Date: Apr 30 2018 18:33:29 +0000 Subject: [PATCH 3/4] Removing conflict in greenwave config --- diff --git a/greenwave/config.py b/greenwave/config.py index c04e007..663c21e 100644 --- a/greenwave/config.py +++ b/greenwave/config.py @@ -18,12 +18,9 @@ class Config(object): WAIVERDB_API_URL = 'https://waiverdb.fedoraproject.org/api/v1.0' # Options for outbound HTTP requests made by python-requests -<<<<<<< HEAD -======= DIST_GIT_BASE_URL = 'https://src.fedoraproject.org' DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}/{pkg_name}/{rev}/greenwave.yaml' KOJI_BASE_URL = 'https://koji.fedoraproject.org/kojihub' ->>>>>>> 66e68b8... Introducing RemoteRule for extending policies REQUESTS_TIMEOUT = (6.1, 15) REQUESTS_VERIFY = True From 8503b88ab7b48f8a195fac540a13c95fee249ad3 Mon Sep 17 00:00:00 2001 From: Giulia Naponiello Date: Apr 30 2018 18:48:44 +0000 Subject: [PATCH 4/4] Removed circular imports --- diff --git a/greenwave/resources.py b/greenwave/resources.py index bb85695..2aac254 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -16,14 +16,14 @@ from flask import current_app from werkzeug.exceptions import BadGateway from greenwave.cache import cached -from greenwave.utils import retry +import greenwave.utils import greenwave.policies requests_session = requests.Session() @cached -@retry(wait_on=urllib3.exceptions.NewConnectionError) +@greenwave.utils.retry(wait_on=urllib3.exceptions.NewConnectionError) def retrieve_rev_from_koji(nvr): """ Retrieve cached rev from koji using the nrv """ proxy = xmlrpclib.ServerProxy(current_app.config['KOJI_BASE_URL']) @@ -79,7 +79,7 @@ def retrieve_results(item): # NOTE - not cached, for now. -@retry(wait_on=urllib3.exceptions.NewConnectionError) +@greenwave.utils.retry(wait_on=urllib3.exceptions.NewConnectionError) def retrieve_waivers(product_version, item): timeout = current_app.config['REQUESTS_TIMEOUT'] verify = current_app.config['REQUESTS_VERIFY'] diff --git a/greenwave/utils.py b/greenwave/utils.py index 456dcf3..efb001e 100644 --- a/greenwave/utils.py +++ b/greenwave/utils.py @@ -10,7 +10,7 @@ import yaml from flask import jsonify, current_app, request from flask.config import Config from werkzeug.exceptions import HTTPException -from greenwave.policies import validate_policies +import greenwave.policies log = logging.getLogger(__name__) @@ -105,7 +105,7 @@ def load_policies(policies_dir): policies = [] for policy_pathname in policy_pathnames: policies.extend(yaml.safe_load_all(open(policy_pathname, 'r'))) - validate_policies(policies) + greenwave.policies.validate_policies(policies) return policies