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
This commit is contained in:
James E. Blair 2024-10-19 13:29:07 -07:00
parent 08a3c43dd7
commit d371e17171
2 changed files with 18 additions and 0 deletions

View File

@ -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)

View File

@ -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(