Merge "Add allowed-labels tenant setting"

This commit is contained in:
Zuul 2018-11-28 17:52:54 +00:00 committed by Gerrit Code Review
commit 21f29820c4
6 changed files with 63 additions and 1 deletions

View File

@ -247,3 +247,10 @@ configuration. Some examples of tenant definitions are:
The list of connections a tenant can report to. When set, this setting
can be used to restrict what connections a tenant can use as reporter.
Without this setting, the tenant can report to any connection.
.. attr:: allowed-labels
:default: []
The list of labels regexp a tenant can use in job's nodeset. When set,
this setting can be used to restrict what labels a tenant can use.
Without this setting, the tenant can use any labels.

View File

@ -0,0 +1,5 @@
---
features:
- |
A new tenant option :attr:`tenant.allowed-labels`
can be used to restrict what labels a tenant has access to.

View File

@ -23,7 +23,7 @@
name: nodeset1
nodes:
- name: controller
label: controller-label
label: tenant-one-controller-label
- job:
name: project1-test1

View File

@ -3,6 +3,10 @@
max-job-timeout: 1800
allowed-reporters:
- gerrit
allowed-labels:
- tenant-one-.*
- ubuntu-trusty
- fake
source:
gerrit:
config-projects:

View File

@ -3235,6 +3235,31 @@ class TestAllowedConnection(AnsibleZuulTestCase):
"B should not fail because of allowed-reporters")
class TestAllowedLabels(AnsibleZuulTestCase):
config_file = 'zuul-connections-gerrit-and-github.conf'
tenant_config_file = 'config/multi-tenant/main.yaml'
def test_allowed_labels(self):
in_repo_conf = textwrap.dedent(
"""
- job:
name: test
nodeset:
nodes:
- name: controller
label: tenant-two-label
""")
file_dict = {'zuul.d/test.yaml': in_repo_conf}
A = self.fake_gerrit.addFakeChange(
'tenant-one-config', 'master', 'A', files=file_dict)
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertIn(
'Label named "tenant-two-label" is not part of the allowed',
A.messages[0],
"A should fail because of allowed-labels")
class TestPragma(ZuulTestCase):
tenant_config_file = 'config/pragma/main.yaml'

View File

@ -22,6 +22,7 @@ import io
import re
import subprocess
import re2
import voluptuous as vs
from zuul import model
@ -79,6 +80,17 @@ class UnknownConnection(Exception):
super(UnknownConnection, self).__init__(message)
class LabelForbiddenError(Exception):
def __init__(self, label, allowed_labels):
message = textwrap.dedent("""\
Label named "{label}" is not part of the allowed
labels ({allowed_labels}) for this tenant.""")
message = textwrap.fill(message.format(
label=label,
allowed_labels=", ".join(allowed_labels)))
super(LabelForbiddenError, self).__init__(message)
class MaxTimeoutError(Exception):
def __init__(self, job, tenant):
message = textwrap.dedent("""\
@ -452,7 +464,14 @@ class NodeSetParser(object):
ns.start_mark = conf.get('_start_mark')
node_names = set()
group_names = set()
allowed_labels = self.pcontext.tenant.allowed_labels
for conf_node in as_list(conf['nodes']):
if allowed_labels:
if not [True for allowed_label in allowed_labels if
re2.match(allowed_label, conf_node['label'])]:
raise LabelForbiddenError(
label=conf_node['label'],
allowed_labels=allowed_labels)
for name in as_list(conf_node['name']):
if name in node_names:
raise DuplicateNodeError(name, conf_node['name'])
@ -1293,6 +1312,7 @@ class TenantParser(object):
'exclude-unprotected-branches': bool,
'allowed-triggers': to_list(str),
'allowed-reporters': to_list(str),
'allowed-labels': to_list(str),
'default-parent': str,
}
return vs.Schema(tenant)
@ -1309,6 +1329,7 @@ class TenantParser(object):
conf['exclude-unprotected-branches']
tenant.allowed_triggers = conf.get('allowed-triggers')
tenant.allowed_reporters = conf.get('allowed-reporters')
tenant.allowed_labels = conf.get('allowed-labels')
tenant.default_base_job = conf.get('default-parent', 'base')
tenant.unparsed_config = conf