From ade9f76205f7164f178013d8a821d6525484e06a Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Sep 16 2017 11:15:01 +0000 Subject: New API endpoint to return the currently loaded policies. This adds and tests a new endpoint. The endpoint returns a JSON representation of the currently loaded global policies. This is intended for human/operator inspection to see if the application has correctly loaded a given configuration change. Fixes #72. --- diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index e6bf409..3a269ad 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -84,6 +84,26 @@ TASKTRON_RELEASE_CRITICAL_TASKS = [ ] +def test_inspect_policies(requests_session, greenwave_server): + r = requests_session.get(greenwave_server.url + 'api/v1.0/policies', + headers={'Content-Type': 'application/json'}) + assert r.status_code == 200 + body = r.json() + assert len(body['policies']) == 3 + policy = body['policies'][0] + assert policy['id'] == 'taskotron_release_critical_tasks' + assert policy['decision_context'] == 'bodhi_update_push_stable' + assert policy['product_versions'] == ['fedora-26'] + expected_rules = [ + {'rule': 'PassingTestCaseRule', + 'test_case_name': 'dist.abicheck'}, + {'rule': 'PassingTestCaseRule', + 'test_case_name': 'dist.rpmdeplint'}, + {'rule': 'PassingTestCaseRule', + 'test_case_name': 'dist.upgradepath'}] + assert policy['rules'] == expected_rules + + def test_cannot_make_decision_without_product_version(requests_session, greenwave_server): data = { 'decision_context': 'errata_newfile_to_qe', diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index 267f926..9199996 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -21,6 +21,55 @@ def version(): return resp +@api.route('/policies', methods=['GET']) +def get_policies(): + """ Returns all currently loaded policies. + + **Sample response**: + + .. sourcecode:: http + + HTTP/1.0 200 + Content-Length: 228 + Content-Type: application/json + Date: Thu, 16 Mar 2017 17:42:04 GMT + Server: Werkzeug/0.12.1 Python/2.7.13 + + { + "policies": [ + { + "id": "taskotron_release_critical_tasks", + "decision_context": "bodhi_update_push_stable", + "product_versions": [ + "fedora-26" + ], + "rules": [ + { + "test_case_name": "dist.abicheck", + "rule": "PassingTestCaseRule" + }, + { + "test_case_name": "dist.rpmdeplint", + "rule": "PassingTestCaseRule" + }, + { + "test_case_name": "dist.upgradepath", + "rule": "PassingTestCaseRule" + } + ] + } + ] + } + + :statuscode 200: Currently loaded policies are returned. + """ + policies = [policy.to_json() for policy in current_app.config['policies']] + resp = jsonify({'policies': policies}) + resp = insert_headers(resp) + resp.status_code = 200 + return resp + + @api.route('/decision', methods=['OPTIONS']) def make_decision_options(): """ Handles the OPTIONS requests to the /decision endpoint. """ diff --git a/greenwave/policies.py b/greenwave/policies.py index b95fe03..8fa9b58 100644 --- a/greenwave/policies.py +++ b/greenwave/policies.py @@ -128,6 +128,14 @@ class Rule(yaml.YAMLObject): """ raise NotImplementedError() + def to_json(self): + """ Return a dict representation of this rule. + + Returns: + dict: A representation of this Rule as a dict for an API response. + """ + raise NotImplementedError() + class PassingTestCaseRule(Rule): """ @@ -158,6 +166,12 @@ class PassingTestCaseRule(Rule): def __repr__(self): return "%s(test_case_name=%r)" % (self.__class__.__name__, self.test_case_name) + def to_json(self): + return { + 'rule': self.__class__.__name__, + 'test_case_name': self.test_case_name, + } + class Policy(yaml.YAMLObject): yaml_tag = u'!Policy' @@ -180,3 +194,11 @@ class Policy(yaml.YAMLObject): return "%s(id=%r, product_versions=%r, decision_context=%r, rules=%r)" % ( self.__class__.__name__, self.id, self.product_versions, self.decision_context, self.rules) + + def to_json(self): + return { + 'id': self.id, + 'product_versions': self.product_versions, + 'decision_context': self.decision_context, + 'rules': [rule.to_json() for rule in self.rules], + }