From d371e171719f559b8ac5c2d138801c043d8f1288 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Sat, 19 Oct 2024 13:29:07 -0700 Subject: [PATCH] More strictly enforce section inheritance We check section inheritance when validating references, but we don't actually enforce it when flatting a provider config; add it there as well to ensure we don't end up in a bad situation due to forced-merges. Change-Id: Ib06342a6717937337ba3da480aacab0cd1f5e016 --- tests/unit/test_configloader.py | 9 +++++++++ zuul/model.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/unit/test_configloader.py b/tests/unit/test_configloader.py index 6857035e9d..2840c94924 100644 --- a/tests/unit/test_configloader.py +++ b/tests/unit/test_configloader.py @@ -1427,6 +1427,10 @@ class TestNodepoolConfig(ZuulTestCase): - section: name: badsection parent: aws-base + - provider: + name: badprovider + section: badsection + region: foo """) file_dict = {'zuul.yaml': in_repo_conf} A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A', @@ -1436,3 +1440,8 @@ class TestNodepoolConfig(ZuulTestCase): self.assertEqual(A.reported, 1) self.assertEqual(A.patchsets[-1]['approvals'][0]['value'], '-1') self.assertIn('references a section', A.messages[0]) + A.setMerged() + self.fake_gerrit.addEvent(A.getChangeMergedEvent()) + self.waitUntilSettled() + tenant = self.scheds.first.sched.abide.tenants.get('tenant-one') + self.assertFalse('badprovider' in tenant.layout.providers) diff --git a/zuul/model.py b/zuul/model.py index f442ef9ac4..0ba726dd40 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -1834,12 +1834,21 @@ class ProviderConfig(ConfigObject): def flattenConfig(self, layout): config = copy.deepcopy(Freezable.thaw(self.config)) parent_name = self.section + previous_section = None while parent_name: parent_section = layout.sections[parent_name] + # Prevent sections from referencing sections in other projects + if (previous_section and + parent_section.source_context.project_canonical_name != + previous_section.source_context.project_canonical_name): + raise Exception( + f'The section "{previous_section.name}" references a ' + 'section in a different project.') parent_config = copy.deepcopy(Freezable.thaw( parent_section.config)) config = ProviderConfig._mergeDict(parent_config, config) parent_name = parent_section.parent + previous_section = parent_section # Provide defaults from the images/flavors/labels objects for image in config.get('images', []): layout_image = self._dropNone(