Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[master] Porting #50023 to master #54620

Merged
merged 4 commits into from
Jan 2, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 35 additions & 40 deletions salt/utils/roster_matcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
from __future__ import absolute_import, print_function, unicode_literals

# Import python libs
import copy
import fnmatch
import functools
import logging
import re
import copy

# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
Expand All @@ -31,6 +32,18 @@ def targets(conditioned_raw, tgt, tgt_type, ipv='ipv4'):
return rmatcher.targets()


def _tgt_set(tgt):
'''
Return the tgt as a set of literal names
'''
try:
# A comma-delimited string
return set(tgt.split(','))
except AttributeError:
# Assume tgt is already a non-string iterable.
return set(tgt)


class RosterMatcher(object):
'''
Matcher for the roster data structure
Expand All @@ -50,59 +63,47 @@ def targets(self):
except AttributeError:
return {}

def ret_glob_minions(self):
def _ret_minions(self, filter_):
'''
Return minions that match via glob
Filter minions by a generic filter.
'''
minions = {}
for minion in self.raw:
if fnmatch.fnmatch(minion, self.tgt):
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
for minion in filter_(self.raw):
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
return minions

def ret_glob_minions(self):
'''
Return minions that match via glob
'''
fnfilter = functools.partial(fnmatch.filter, pat=self.tgt)
return self._ret_minions(fnfilter)

def ret_pcre_minions(self):
'''
Return minions that match via pcre
'''
minions = {}
for minion in self.raw:
if re.match(self.tgt, minion):
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
return minions
tgt = re.compile(self.tgt)
refilter = functools.partial(filter, tgt.match)
return self._ret_minions(refilter)

def ret_list_minions(self):
'''
Return minions that match via list
'''
minions = {}
if not isinstance(self.tgt, list):
self.tgt = self.tgt.split(',')
for minion in self.raw:
if minion in self.tgt:
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
return minions
tgt = _tgt_set(self.tgt)
return self._ret_minions(tgt.intersection)

def ret_nodegroup_minions(self):
'''
Return minions which match the special list-only groups defined by
ssh_list_nodegroups
'''
minions = {}
nodegroup = __opts__.get('ssh_list_nodegroups', {}).get(self.tgt, [])
if not isinstance(nodegroup, list):
nodegroup = nodegroup.split(',')
for minion in self.raw:
if minion in nodegroup:
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
return minions
nodegroup = _tgt_set(nodegroup)
return self._ret_minions(nodegroup.intersection)

def ret_range_minions(self):
'''
Expand All @@ -113,13 +114,7 @@ def ret_range_minions(self):

minions = {}
range_hosts = _convert_range_to_list(self.tgt, __opts__['range_server'])

for minion in self.raw:
if minion in range_hosts:
data = self.get_data(minion)
if data:
minions[minion] = data.copy()
return minions
return self._ret_minions(range_hosts.__contains__)

def get_data(self, minion):
'''
Expand Down