Merge pull request #29139 from thomaso-mirodin/salt-ssh-flat-roster-range-filter

[salt-ssh] Add a range roster and range targeting options for the flat roster
This commit is contained in:
Mike Place 2015-11-30 14:25:50 -07:00
commit 3aa84b6763
2 changed files with 111 additions and 0 deletions

View file

@ -8,6 +8,15 @@ from __future__ import absolute_import
import fnmatch
import re
# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
try:
import seco.range
HAS_RANGE = True
except ImportError:
pass
# pylint: enable=import-error
# Import Salt libs
import salt.loader
from salt.template import compile_template
@ -107,6 +116,23 @@ class RosterMatcher(object):
minions[minion] = data
return minions
def ret_range_minions(self):
'''
Return minions that are returned by a range query
'''
if HAS_RANGE is False:
raise RuntimeError("Python lib 'seco.range' is not available")
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
return minions
def get_data(self, minion):
'''
Return the configured ip
@ -116,3 +142,15 @@ class RosterMatcher(object):
if isinstance(self.raw[minion], dict):
return self.raw[minion]
return False
def _convert_range_to_list(tgt, range_server):
'''
convert a seco.range range into a list target
'''
r = seco.range.Range(range_server)
try:
return r.expand(tgt)
except seco.range.RangeException as err:
log.error('Range server exception: %s', err)
return []

73
salt/roster/range.py Normal file
View file

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
'''
This roster resolves targets from a range server.
:depends: seco.range, https://github.com/ytoolshed/range
When you want to use a range query for target matching, use ``--roster range``. For example:
.. code-block:: bash
salt-ssh --roster range '%%%example.range.cluster' test.ping
'''
from __future__ import absolute_import
import fnmatch
import logging
log = logging.getLogger(__name__)
# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
try:
import seco.range
HAS_RANGE = True
except ImportError:
log.error("Unable to load range library")
# pylint: enable=import-error
def __virtual__():
return HAS_RANGE
def targets(tgt, tgt_type='range', **kwargs):
'''
Return the targets from a range query
'''
r = seco.range.Range(__opts__['range_server'])
log.debug("Range connection to '%s' established", __opts__['range_server'])
hosts = []
try:
log.debug("Querying range for '%s'", tgt)
hosts = r.expand(tgt)
except seco.range.RangeException as err:
log.error('Range server exception: %s', err)
return {}
log.debug("Range responded with: '%s'", hosts)
# Currently we only support giving a raw range entry, no target filtering supported other than what range returns :S
tgt_func = {
'range': target_range,
'glob': target_range,
# 'glob': target_glob,
}
log.debug("Filtering using tgt_type: '%s'", tgt_type)
try:
targeted_hosts = tgt_func[tgt_type](tgt, hosts)
except KeyError:
raise NotImplementedError
log.debug("Targeting data for salt-ssh: '%s'", targeted_hosts)
return targeted_hosts
def target_range(tgt, hosts):
return dict((host, {'host': host, 'user': __opts__['ssh_user']}) for host in hosts)
def target_glob(tgt, hosts):
return dict((host, {'host': host, 'user': __opts__['ssh_user']}) for host in hosts if fnmatch.fnmatch(tgt, host))