From 8c89050803bb81363b9c6cc9ef429dfaac83c25e Mon Sep 17 00:00:00 2001
From: Valerij Maljulin <vmaljuli@redhat.com>
Date: Mar 05 2020 20:22:23 +0000
Subject: Side-tags repo URL new parameters


Signed-off-by: Valerij Maljulin <vmaljuli@redhat.com>

---

diff --git a/conf/subject_types/brew-build-group.yaml b/conf/subject_types/brew-build-group.yaml
new file mode 100644
index 0000000..32c8493
--- /dev/null
+++ b/conf/subject_types/brew-build-group.yaml
@@ -0,0 +1,3 @@
+--- !SubjectType
+id: brew-build-group
+supports_remote_rule: true
diff --git a/greenwave/config.py b/greenwave/config.py
index c2de796..58fc093 100644
--- a/greenwave/config.py
+++ b/greenwave/config.py
@@ -30,8 +30,8 @@ class Config(object):
         'https://src.fedoraproject.org/{pkg_namespace}{pkg_name}/raw/{rev}/f/gating.yaml'
     REMOTE_RULE_POLICIES = {
         'brew-build-group': (
-            'https://git.example.com/devops/greenwave-policies/side-tags/raw/master/{pkg_namespace}'
-            '{pkg_name}.yaml'
+            'https://git.example.com/devops/greenwave-policies/side-tags/raw/master/'
+            '{subject_id}.yaml'
         ),
         '*': 'https://src.fedoraproject.org/{pkg_namespace}{pkg_name}/raw/{rev}/f/gating.yaml'
     }
diff --git a/greenwave/policies.py b/greenwave/policies.py
index 4304af3..48e5066 100644
--- a/greenwave/policies.py
+++ b/greenwave/policies.py
@@ -433,23 +433,11 @@ class RemoteRule(Rule):
         'required': SafeYAMLBool(optional=True, default=False),
     }
 
-    def _get_sub_policies(self, policy, subject):
+    @staticmethod
+    def _get_sub_policies(policy, subject):
         if not subject.supports_remote_rule:
             return []
 
-        try:
-            pkg_namespace, pkg_name, rev = greenwave.resources.retrieve_scm_from_koji(
-                subject.identifier
-            )
-        except greenwave.resources.NoSourceException as e:
-            log.error(e)
-            return None
-
-        # if the element is actually a container and not a pkg there will be a "-container"
-        # string at the end of the "pkg_name" and it will not match with the one in the
-        # remote rule file URL
-        if pkg_namespace == 'containers':
-            pkg_name = re.sub('-container$', '', pkg_name)
         rr_policies_conf = current_app.config.get('REMOTE_RULE_POLICIES', {})
         cur_subject_url = rr_policies_conf.get(
             policy.subject_type, current_app.config.get(
@@ -459,8 +447,36 @@ class RemoteRule(Rule):
         if not cur_subject_url:
             raise RuntimeError(f'Cannot use a remote rule for {subject} subject '
                                f'as it has not been configured')
+
+        response = None
+        url_params = {}
+        if '{pkg_name}' in cur_subject_url or '{pkg_namespace}' in cur_subject_url or \
+                '{rev}' in cur_subject_url:
+            try:
+                pkg_namespace, pkg_name, rev = greenwave.resources.retrieve_scm_from_koji(
+                    subject.identifier
+                )
+            except greenwave.resources.NoSourceException as e:
+                log.error(e)
+                return None
+
+            # if the element is actually a container and not a pkg there will be a "-container"
+            # string at the end of the "pkg_name" and it will not match with the one in the
+            # remote rule file URL
+            if pkg_namespace == 'containers':
+                pkg_name = re.sub('-container$', '', pkg_name)
+            if pkg_namespace:
+                pkg_namespace += '/'
+            url_params.update(rev=rev, pkg_name=pkg_name, pkg_namespace=pkg_namespace)
+
+        if '{subject_id}' in cur_subject_url:
+            subj_id = subject.identifier
+            if subj_id.startswith('sha256:'):
+                subj_id = subj_id[7:]
+            url_params.update(subject_id=subj_id)
+
         response = greenwave.resources.retrieve_yaml_remote_rule(
-            rev, pkg_name, pkg_namespace, cur_subject_url
+            cur_subject_url.format(**url_params)
         )
 
         if response is None:
diff --git a/greenwave/resources.py b/greenwave/resources.py
index 1bccd6c..72b786e 100644
--- a/greenwave/resources.py
+++ b/greenwave/resources.py
@@ -164,14 +164,8 @@ def retrieve_scm_from_koji_build(nvr, build, koji_url):
 
 
 @cached
-def retrieve_yaml_remote_rule(rev, pkg_name, pkg_namespace, url_template):
+def retrieve_yaml_remote_rule(url):
     """ Retrieve a remote rule file content from the git web UI. """
-    data = {
-        "pkg_namespace": pkg_namespace + ('/' if pkg_namespace else ''),
-        "pkg_name": pkg_name,
-        "rev": rev
-    }
-    url = url_template.format(**data)
     response = requests_session.request('HEAD', url)
     if response.status_code == 404:
         return None
diff --git a/greenwave/tests/test_api_v1.py b/greenwave/tests/test_api_v1.py
index 89e51e6..3147adb 100644
--- a/greenwave/tests/test_api_v1.py
+++ b/greenwave/tests/test_api_v1.py
@@ -188,6 +188,7 @@ def test_subject_types(client):
     assert len(data['subject_types'])
     assert [x['id'] for x in data['subject_types']] == [
         'bodhi_update',
+        'brew-build-group',
         'compose',
         'koji_build',
         'redhat-container-image',
diff --git a/greenwave/tests/test_policies.py b/greenwave/tests/test_policies.py
index 004ae67..1316615 100644
--- a/greenwave/tests/test_policies.py
+++ b/greenwave/tests/test_policies.py
@@ -339,16 +339,13 @@ def test_remote_rule_policy(tmpdir, namespace):
                 assert len(decision) == 1
                 assert isinstance(decision[0], TestResultFailed)
                 f.assert_called_with(
-                    'c3c47a08a66451cb9686c49f040776ed35a0d1bb',
-                    'nethack',
-                    namespace,
-                    'https://src.fedoraproject.org/{pkg_namespace}'
-                    '{pkg_name}/raw/{rev}/f/gating.yaml'
+                    'https://src.fedoraproject.org/{0}'.format(
+                        '' if not namespace else namespace + '/'
+                    ) + 'nethack/raw/c3c47a08a66451cb9686c49f040776ed35a0d1bb/f/gating.yaml'
                 )
 
 
-@pytest.mark.parametrize('namespace', ["rpms", ""])
-def test_remote_rule_policy_old_config(tmpdir, namespace):
+def test_remote_rule_policy_old_config(tmpdir):
     """ Testing the RemoteRule with the koji interaction.
     In this case we are just mocking koji """
 
@@ -385,14 +382,14 @@ def test_remote_rule_policy_old_config(tmpdir, namespace):
 
         config = TestingConfig()
         config.DIST_GIT_BASE_URL = 'http://localhost.localdomain/'
-        config.DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}{other_params}/blablabla/gating.yaml'
+        config.DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}{pkg_name}/{rev}/gating.yaml'
 
         app = create_app(config)
 
         with app.app_context():
             with mock.patch('greenwave.resources.retrieve_scm_from_koji') as scm:
                 scm.return_value = (
-                    namespace, 'nethack', 'c3c47a08a66451cb9686c49f040776ed35a0d1bb'
+                    'rpms', 'nethack', 'c3c47a08a66451cb9686c49f040776ed35a0d1bb'
                 )
                 with mock.patch('greenwave.resources.retrieve_yaml_remote_rule') as f:
                     f.return_value = remote_fragment
@@ -406,21 +403,22 @@ def test_remote_rule_policy_old_config(tmpdir, namespace):
                     assert isinstance(decision[0], RuleSatisfied)
 
                     f.assert_called_once_with(
-                        'c3c47a08a66451cb9686c49f040776ed35a0d1bb',
-                        'nethack',
-                        namespace,
-                        'http://localhost.localdomain/{other_params}/blablabla/gating.yaml'
+                        'http://localhost.localdomain/nethack/'
+                        'c3c47a08a66451cb9686c49f040776ed35a0d1bb/gating.yaml'
                     )
     finally:
         Config.REMOTE_RULE_POLICIES = config_remote_rules_backup
 
 
-@pytest.mark.parametrize('namespace', ["rpms", ""])
-def test_remote_rule_policy_brew_build_group(tmpdir, namespace):
+def test_remote_rule_policy_brew_build_group(tmpdir):
     """ Testing the RemoteRule with the koji interaction.
     In this case we are just mocking koji """
 
-    subject = create_test_subject('koji_build', 'nethack-1.2.3-1.el9000')
+    subject = create_test_subject(
+        'brew-build-group',
+        'sha256:0f41e56a1c32519e189ddbcb01d2551e861bd74e603d01769ef5f70d4b30a2dd'
+    )
+    namespace = 'rpms'
 
     serverside_fragment = dedent("""
         --- !Policy
@@ -472,12 +470,10 @@ def test_remote_rule_policy_brew_build_group(tmpdir, namespace):
                 assert len(decision) == 1
                 assert isinstance(decision[0], TestResultFailed)
                 f.assert_called_with(
-                    'c3c47a08a66451cb9686c49f040776ed35a0d1bb',
-                    'nethack',
-                    namespace,
                     'https://git.example.com/devops/greenwave-policies/side-tags/raw/'
-                    'master/{pkg_namespace}{pkg_name}.yaml'
+                    'master/0f41e56a1c32519e189ddbcb01d2551e861bd74e603d01769ef5f70d4b30a2dd.yaml'
                 )
+            scm.assert_not_called()
 
 
 def test_remote_rule_policy_with_no_remote_rule_policies_param_defined(tmpdir):
@@ -525,11 +521,8 @@ def test_remote_rule_policy_with_no_remote_rule_policies_param_defined(tmpdir):
                 assert len(decision) == 1
                 assert isinstance(decision[0], RuleSatisfied)
                 f.assert_called_with(
-                    'c3c47a08a66451cb9686c49f040776ed35a0d1bb',
-                    'nethack',
-                    'rpms',
-                    'https://src.fedoraproject.org/{pkg_namespace}'
-                    '{pkg_name}/raw/{rev}/f/gating.yaml'
+                    'https://src.fedoraproject.org/rpms/nethack/raw/'
+                    'c3c47a08a66451cb9686c49f040776ed35a0d1bb/f/gating.yaml'
                 )
 
 
diff --git a/greenwave/tests/test_retrieve_gating_yaml.py b/greenwave/tests/test_retrieve_gating_yaml.py
index 349dc04..73d4475 100644
--- a/greenwave/tests/test_retrieve_gating_yaml.py
+++ b/greenwave/tests/test_retrieve_gating_yaml.py
@@ -121,7 +121,9 @@ def test_retrieve_yaml_remote_rule_no_namespace():
             response.status_code = 404
             session.request.return_value = response
             retrieve_yaml_remote_rule(
-                "deadbeaf", "pkg", "", app.config['REMOTE_RULE_POLICIES']['*']
+                app.config['REMOTE_RULE_POLICIES']['*'].format(
+                    rev='deadbeaf', pkg_name='pkg', pkg_namespace=''
+                )
             )
 
             expected_call = mock.call(
@@ -141,7 +143,9 @@ def test_retrieve_yaml_remote_rule_connection_error():
 
             with pytest.raises(HTTPError) as excinfo:
                 retrieve_yaml_remote_rule(
-                    "deadbeaf", "pkg", "", app.config['REMOTE_RULE_POLICIES']['*']
+                    app.config['REMOTE_RULE_POLICIES']['*'].format(
+                        rev='deadbeaf', pkg_name='pkg', pkg_namespace=''
+                    )
                 )
 
             assert str(excinfo.value) == (

