Blob Blame History Raw
From 1d257931f4e55933babe2b221ee664976b109f92 Mon Sep 17 00:00:00 2001
From: Ralph Bean <rbean@redhat.com>
Date: Fri, 16 Feb 2018 12:39:20 -0500
Subject: [PATCH 2/2] Special relevance.

I'm not totally happy with this approach.  First, I'll describe the bug,
then the solution, then what I'm not happy with.

First, the bug is that when we changed the format of the `subject` to a
list, we didn't think about how policies would map to subjects of
different types in a single query.  Bodhi would like to make a single
query with all the artifacts it care about, and have greenwave do the
heavy lifting.  It will provide a query with a ``koji_build``, and a
``bodhi_update`` alias, and a new ``original_spec_nvr`` nvr from the
atomic ci pipeline.  The problem is that all of our policies apply
indiscriminately to all of those subjects - which can't make sense.
There is no `rpmlint` run on an "update".

The approach taken here is to introduce new attributes to our policies
that let them define what subjects they are relevant to.  They can
specify a relevance_key or a relevance_value which makes them only
narrowly applicable to certain subjects.

I don't like that we have to have relevance_key *and* relevance_value
(in order to handle the strange looking ``original_spec_nvr``).  I also
don't like that "is relevance to" and "is applicable to" mean almost
exactly the same thing in english, but here in greenwave they are
defined at different scopes of the query.  "applicable" applies to the
query as a whole while "relevant" applies to each item in the query's
subject.

Perhaps this can be rethought and thrown out.. but I wanted to post
something to have something to argue about.

I'll also apply this to the greenwave "stg" instance so we can poke at
it there.

Lastly, this is on top of the `disjunction`, branch from #62.
---
 greenwave/api_v1.py   |  4 +++-
 greenwave/policies.py | 13 +++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py
index d226201..34c2b4b 100644
--- a/greenwave/api_v1.py
+++ b/greenwave/api_v1.py
@@ -250,7 +250,9 @@ def make_decision():
         waivers = [w for w in waivers if w['id'] not in ignore_waivers]
         all_waivers.extend(waivers)
 
-        for policy in applicable_policies:
+        relevant_policies = [policy for policy in applicable_policies
+                             if policy.is_relevant_to(item)]
+        for policy in relevant_policies:
             answers.extend(policy.check(item, results, waivers))
 
     res = {
diff --git a/greenwave/policies.py b/greenwave/policies.py
index 95b02e8..449b5ed 100644
--- a/greenwave/policies.py
+++ b/greenwave/policies.py
@@ -246,6 +246,17 @@ class Policy(yaml.YAMLObject):
         return (decision_context == self.decision_context and
                 product_version in self.product_versions)
 
+    def is_relevant_to(self, item):
+        relevance_key = getattr(self, 'relevance_key', None)
+        relevance_value = getattr(self, 'relevance_value', None)
+        if relevance_key and relevance_value:
+            return item.get(relevance_key) == relevance_value
+        if relevance_key:
+            return relevance_key in item
+        if relevance_value:
+            return relevance_value in item.values()
+        return True
+
     def check(self, item, results, waivers):
         # If an item is about a package and it is in the blacklist, return RuleSatisfied()
         for package in self.blacklist:
@@ -267,4 +278,6 @@ class Policy(yaml.YAMLObject):
             'decision_context': self.decision_context,
             'rules': [rule.to_json() for rule in self.rules],
             'blacklist': self.blacklist,
+            'relevance_key': getattr(self, 'relevance_key', None),
+            'relevance_value': getattr(self, 'relevance_value', None),
         }
-- 
2.14.3