Add allowed-labels tenant setting
This changes adds a new tenant setting to limit the labels a tenant can use as job's nodeset. Change-Id: Ibcba034db76f200c216fe1b353ed122b11ac5014
This commit is contained in:
parent
be4dc6e9d2
commit
c00a01a5e8
|
@ -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.
|
||||
|
|
|
@ -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.
|
|
@ -23,7 +23,7 @@
|
|||
name: nodeset1
|
||||
nodes:
|
||||
- name: controller
|
||||
label: controller-label
|
||||
label: tenant-one-controller-label
|
||||
|
||||
- job:
|
||||
name: project1-test1
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
max-job-timeout: 1800
|
||||
allowed-reporters:
|
||||
- gerrit
|
||||
allowed-labels:
|
||||
- tenant-one-.*
|
||||
- ubuntu-trusty
|
||||
- fake
|
||||
source:
|
||||
gerrit:
|
||||
config-projects:
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -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'])
|
||||
|
@ -1282,6 +1301,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)
|
||||
|
@ -1298,6 +1318,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
|
||||
|
|
Loading…
Reference in New Issue