From 940829910346bd5d77f7d0d14e0f26f7fe09d8c3 Mon Sep 17 00:00:00 2001
From: Lukas Holecek <lholecek@redhat.com>
Date: Jun 05 2018 13:18:21 +0000
Subject: [PATCH 1/2] Fix showing all results and waivers with verbose flag


---

diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py
index af49fa8..4ed9b45 100644
--- a/greenwave/api_v1.py
+++ b/greenwave/api_v1.py
@@ -332,12 +332,16 @@ def make_decision():
     if build_policies:
         build_nvrs = retrieve_builds_in_update(subject_identifier)
         for nvr in build_nvrs:
-            results = retrieve_results('koji_build', nvr)
-            results = [r for r in results if r['id'] not in ignore_results]
-            waivers = retrieve_waivers(product_version, 'koji_build', nvr)
-            waivers = [w for w in waivers if w['id'] not in ignore_waivers]
+            nvr_results = retrieve_results('koji_build', nvr)
+            nvr_results = [r for r in nvr_results if r['id'] not in ignore_results]
+            results.extend(nvr_results)
+
+            nvr_waivers = retrieve_waivers(product_version, 'koji_build', nvr)
+            nvr_waivers = [w for w in nvr_waivers if w['id'] not in ignore_waivers]
+            waivers.extend(nvr_waivers)
+
             for policy in build_policies:
-                answers.extend(policy.check(nvr, results, waivers))
+                answers.extend(policy.check(nvr, nvr_results, nvr_waivers))
 
     res = {
         'policies_satisfied': all(answer.is_satisfied for answer in answers),

From 5950cf78106dd6be785c29ab9d6340b40ca30dbf Mon Sep 17 00:00:00 2001
From: Lukas Holecek <lholecek@redhat.com>
Date: Jun 05 2018 13:53:12 +0000
Subject: [PATCH 2/2] Get multiple results or waivers in single request


Fixes #117

---

diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py
index 4ed9b45..96e98ab 100644
--- a/greenwave/api_v1.py
+++ b/greenwave/api_v1.py
@@ -62,6 +62,19 @@ def subject_type_identifier_to_list(subject_type, subject_identifier):
         raise BadRequest('Unrecognised subject type: %s' % subject_type)
 
 
+def _koji_build_nvr(result):
+    data = result.get('data')
+
+    item = data.get('item')
+    if not item:
+        item = data.get('original_spec_nvr')
+
+    if item and isinstance(item, list):
+        return item[0]
+
+    return item[0]
+
+
 @api.route('/version', methods=['GET'])
 def version():
     """
@@ -323,22 +336,35 @@ def make_decision():
                 subject_type, decision_context, product_version))
 
     answers = []
-    results = retrieve_results(subject_type, subject_identifier)
+    results = retrieve_results(subject_type, [subject_identifier])
     results = [r for r in results if r['id'] not in ignore_results]
-    waivers = retrieve_waivers(product_version, subject_type, subject_identifier)
+    waivers = retrieve_waivers(product_version, subject_type, [subject_identifier])
     waivers = [w for w in waivers if w['id'] not in ignore_waivers]
+
     for policy in subject_policies:
         answers.extend(policy.check(subject_identifier, results, waivers))
+
     if build_policies:
         build_nvrs = retrieve_builds_in_update(subject_identifier)
-        for nvr in build_nvrs:
-            nvr_results = retrieve_results('koji_build', nvr)
-            nvr_results = [r for r in nvr_results if r['id'] not in ignore_results]
-            results.extend(nvr_results)
 
-            nvr_waivers = retrieve_waivers(product_version, 'koji_build', nvr)
-            nvr_waivers = [w for w in nvr_waivers if w['id'] not in ignore_waivers]
-            waivers.extend(nvr_waivers)
+        nvrs_results = retrieve_results('koji_build', build_nvrs)
+        nvrs_results = [r for r in nvrs_results if r['id'] not in ignore_results]
+        results.extend(nvrs_results)
+
+        nvrs_waivers = retrieve_waivers(product_version, 'koji_build', build_nvrs)
+        nvrs_waivers = [w for w in nvrs_waivers if w['id'] not in ignore_waivers]
+        waivers.extend(nvrs_waivers)
+
+        for nvr in build_nvrs:
+            nvr_results = [
+                item for item in nvrs_results
+                if nvr == _koji_build_nvr(item)
+            ]
+
+            nvr_waivers = [
+                item for item in nvrs_waivers
+                if nvr == item.get('subject_identifier')
+            ]
 
             for policy in build_policies:
                 answers.extend(policy.check(nvr, nvr_results, nvr_waivers))
diff --git a/greenwave/resources.py b/greenwave/resources.py
index 77c1199..37faaab 100644
--- a/greenwave/resources.py
+++ b/greenwave/resources.py
@@ -128,7 +128,7 @@ def retrieve_item_results(item):
 
 
 @cached
-def retrieve_results(subject_type, subject_identifier):
+def retrieve_results(subject_type, subject_identifiers):
     """
     Returns all results from ResultsDB which might be relevant for the given
     decision subject, accounting for all the different possible ways in which
@@ -138,15 +138,16 @@ def retrieve_results(subject_type, subject_identifier):
     # announcement_subjects() method of the Resultsdb consumer (it has to map
     # from a newly received result back to the possible subjects it is for).
     results = []
+    item_query = ','.join(subject_identifiers)
     if subject_type == 'bodhi_update':
         results.extend(retrieve_item_results(
-            {u'type': u'bodhi_update', u'item': subject_identifier}))
+            {u'type': u'bodhi_update', u'item': item_query}))
     elif subject_type == 'koji_build':
-        results.extend(retrieve_item_results({u'type': u'koji_build', u'item': subject_identifier}))
-        results.extend(retrieve_item_results({u'type': u'brew-build', u'item': subject_identifier}))
-        results.extend(retrieve_item_results({u'original_spec_nvr': subject_identifier}))
+        results.extend(retrieve_item_results({u'type': u'koji_build', u'item': item_query}))
+        results.extend(retrieve_item_results({u'type': u'brew-build', u'item': item_query}))
+        results.extend(retrieve_item_results({u'original_spec_nvr': item_query}))
     elif subject_type == 'compose':
-        results.extend(retrieve_item_results({u'productmd.compose.id': subject_identifier}))
+        results.extend(retrieve_item_results({u'productmd.compose.id': item_query}))
     else:
         raise RuntimeError('Unhandled subject type %r' % subject_type)
     return results
@@ -154,14 +155,14 @@ def retrieve_results(subject_type, subject_identifier):
 
 # NOTE - not cached, for now.
 @greenwave.utils.retry(wait_on=urllib3.exceptions.NewConnectionError)
-def retrieve_waivers(product_version, subject_type, subject_identifier):
+def retrieve_waivers(product_version, subject_type, subject_identifiers):
     timeout = current_app.config['REQUESTS_TIMEOUT']
     verify = current_app.config['REQUESTS_VERIFY']
     filters = [{
         'product_version': product_version,
         'subject_type': subject_type,
         'subject_identifier': subject_identifier,
-    }]
+    } for subject_identifier in subject_identifiers]
     response = requests_session.post(
         current_app.config['WAIVERDB_API_URL'] + '/waivers/+filtered',
         headers={'Content-Type': 'application/json'},

