Handle greedy project name regexes

Some users (and our documentation [0]) may want to have project name
regexes that match all projects: ^.*$. If the zuul installation has
colliding project names this is always an error because we evaluate the
non canonical names first then check for collisions.

We have realized the point of the regex system is to simplify
configuration and apply configs to any projects that match. Collisions
don't impact this. Stop returning an error if there are collisions and
instead apply the configs to those projects.

[0] https://zuul-ci.org/docs/zuul/latest/tutorials/quick-start.html#configure-zuul-pipelines

Change-Id: I48fbab74fb42ba7c8005ef1a07b61c090acc154d
This commit is contained in:
Clark Boylan
2022-03-31 17:19:21 -07:00
parent 08348143f5
commit c393e41d00
2 changed files with 13 additions and 12 deletions
@@ -0,0 +1,8 @@
---
fixes:
- |
Project name regex handling has been updated to return all possible
matches. Previously if there were collisions with short names it was an
error. The point of the regex system is to simplify configuration and
apply configs to all projects that match. Collisions don't impact this
behavior so we don't need to raise an error in these cases.
+5 -12
View File
@@ -7467,8 +7467,7 @@ class Tenant(object):
:arg str regex: The regex to match
:returns: A list of tuples (trusted, project) describing the found
projects. Raises an exception if the same project name is found
several times across multiple hostnames.
projects.
"""
matcher = re2.compile(regex)
@@ -7476,18 +7475,12 @@ class Tenant(object):
result = []
for name, hostname_dict in self.projects.items():
if matcher.fullmatch(name):
# validate that this match is unambiguous
values = list(hostname_dict.values())
if len(values) > 1:
raise Exception("Project name '%s' is ambiguous, "
"please fully qualify the project "
"with a hostname. Valid hostnames "
"are %s." % (name, hostname_dict.keys()))
projects.append(values[0])
projects.extend(hostname_dict.values())
else:
# try to match canonical project names
# It is possible for the regex to match specific connection
# prefixes. Check these more specific names if we didn't add
# all of the possible canonical names already.
for project in hostname_dict.values():
if matcher.fullmatch(project.canonical_name):
projects.append(project)