Report job shadow errors to users
The Layout.addJob() method can raise an exception if the job definition
shadows a definition in another repo. Instead of reporting that as
"Unknown configuration error", give it the full Zuul syntax error
treatment.
This wraps the JobParser in two context managers each of which can
raise a ConfigurationSyntaxError, so make sure that if the outer one
sees such an error from the inner one, it simply passes it through.
Change-Id: I7c6d5c6fa9d6d9329a53cdd98c1e3c38683b38af
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index 71d94c2..2168a7f 100644
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -308,6 +308,26 @@
self.assertIn('syntax error', A.messages[1],
"A should have a syntax error reported")
+ def test_untrusted_shadow_error(self):
+ in_repo_conf = textwrap.dedent(
+ """
+ - job:
+ name: common-config-test
+ """)
+
+ file_dict = {'.zuul.yaml': in_repo_conf}
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
+ files=file_dict)
+ A.addApproval('code-review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('approved', 1))
+ self.waitUntilSettled()
+
+ self.assertEqual(A.data['status'], 'NEW')
+ self.assertEqual(A.reported, 2,
+ "A should report start and failure")
+ self.assertIn('not permitted to shadow', A.messages[1],
+ "A should have a syntax error reported")
+
class TestAnsible(AnsibleZuulTestCase):
# A temporary class to hold new tests while others are disabled
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 287c464..1d7eb12 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -65,6 +65,8 @@
def configuration_exceptions(stanza, conf):
try:
yield
+ except ConfigurationSyntaxError:
+ raise
except Exception as e:
conf = copy.deepcopy(conf)
context = conf.pop('_source_context')
@@ -1024,7 +1026,8 @@
layout.addSecret(SecretParser.fromYaml(layout, config_secret))
for config_job in data.jobs:
- layout.addJob(JobParser.fromYaml(tenant, layout, config_job))
+ with configuration_exceptions('job', config_job):
+ layout.addJob(JobParser.fromYaml(tenant, layout, config_job))
for config_semaphore in data.semaphores:
layout.addSemaphore(SemaphoreParser.fromYaml(config_semaphore))
@@ -1153,7 +1156,8 @@
layout.addSecret(SecretParser.fromYaml(layout, config_secret))
for config_job in config.jobs:
- layout.addJob(JobParser.fromYaml(tenant, layout, config_job))
+ with configuration_exceptions('job', config_job):
+ layout.addJob(JobParser.fromYaml(tenant, layout, config_job))
for config_template in config.project_templates:
layout.addProjectTemplate(ProjectTemplateParser.fromYaml(