diff --git a/doc/source/zuul.rst b/doc/source/zuul.rst index 0ec9f88062..a03cc1c0ea 100644 --- a/doc/source/zuul.rst +++ b/doc/source/zuul.rst @@ -323,6 +323,13 @@ explanation of each of the parameters:: greedy matchers and to escapes dots! Example: ``email_filter: ^.*?@example\.org$``. + *username_filter* + This is used for any event. It takes a regex applied on the performer + username, i.e. Gerrit account name. If you want to specify several + username filters, you must use a YAML list. Make sure to use non greedy + matchers and to escapes dots! + Example: ``username_filter: ^jenkins$``. + *comment_filter* This is only used for ``comment-added`` events. It accepts a list of regexes that are searched for in the comment string. If any of these diff --git a/zuul/layoutvalidator.py b/zuul/layoutvalidator.py index bc82501507..d4ff14336d 100644 --- a/zuul/layoutvalidator.py +++ b/zuul/layoutvalidator.py @@ -44,6 +44,7 @@ class LayoutSchema(object): 'ref-updated')), 'comment_filter': toList(str), 'email_filter': toList(str), + 'username_filter': toList(str), 'branch': toList(str), 'ref': toList(str), 'approval': toList(variable_dict), diff --git a/zuul/model.py b/zuul/model.py index b71552df66..e62feeddc9 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -837,17 +837,20 @@ class TriggerEvent(object): class EventFilter(object): def __init__(self, types=[], branches=[], refs=[], approvals={}, - comment_filters=[], email_filters=[], timespecs=[]): + comment_filters=[], email_filters=[], username_filters=[], + timespecs=[]): self._types = types self._branches = branches self._refs = refs self._comment_filters = comment_filters self._email_filters = email_filters + self._username_filters = username_filters self.types = [re.compile(x) for x in types] self.branches = [re.compile(x) for x in branches] self.refs = [re.compile(x) for x in refs] self.comment_filters = [re.compile(x) for x in comment_filters] self.email_filters = [re.compile(x) for x in email_filters] + self.username_filters = [re.compile(x) for x in username_filters] self.approvals = approvals self.timespecs = timespecs @@ -867,6 +870,8 @@ class EventFilter(object): ret += ' comment_filters: %s' % ', '.join(self._comment_filters) if self._email_filters: ret += ' email_filters: %s' % ', '.join(self._email_filters) + if self._username_filters: + ret += ' username_filters: %s' % ', '.join(self._username_filters) if self.timespecs: ret += ' timespecs: %s' % ', '.join(self.timespecs) ret += '>' @@ -924,6 +929,16 @@ class EventFilter(object): if self.email_filters and not matches_email_filter: return False + # username_filters are ORed + account_username = event.account.get('username') + matches_username_filter = False + for username_filter in self.username_filters: + if (account_username is not None and + username_filter.search(account_username)): + matches_username_filter = True + if self.username_filters and not matches_username_filter: + return False + # approvals are ANDed for category, value in self.approvals.items(): matches_approval = False diff --git a/zuul/scheduler.py b/zuul/scheduler.py index 96bd624714..ea25948a42 100644 --- a/zuul/scheduler.py +++ b/zuul/scheduler.py @@ -217,7 +217,9 @@ class Scheduler(threading.Thread): comment_filters= toList(trigger.get('comment_filter')), email_filters= - toList(trigger.get('email_filter'))) + toList(trigger.get('email_filter')), + username_filters= + toList(trigger.get('username_filter'))) manager.event_filters.append(f) elif 'timer' in conf_pipeline['trigger']: pipeline.trigger = self.triggers['timer']