mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #2168 from archtaku/develop
Add Subnet/IP address matcher
This commit is contained in:
commit
6bbef3df8e
5 changed files with 64 additions and 12 deletions
|
@ -94,7 +94,11 @@ Options
|
|||
.. option:: -N, --nodegroup
|
||||
|
||||
Use a predefined compound target defined in the Salt master configuration
|
||||
file
|
||||
file.
|
||||
|
||||
.. option:: -S, --ipcidr
|
||||
|
||||
Match based on Subnet (CIDR notation) or IPv4 address.
|
||||
|
||||
.. option:: -R, --range
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ E PCRE Minion id match ``E@web\d+\.(dev|qa|prod)\.loc``
|
|||
P Grains PCRE match ``P@os:(RedHat|Fedora|CentOS)``
|
||||
L List of minions ``L@minion1.example.com,minion3.domain.com and bl*.domain.com``
|
||||
I Pillar glob match ``I@pdata:foobar``
|
||||
S Subnet/IP addr match ``S@192.168.1.0/24`` or ``S@192.168.1.100``
|
||||
====== ==================== ===============================================================
|
||||
|
||||
Matchers can be joined using boolean ``and``, ``or``, and ``not`` operators.
|
||||
|
|
|
@ -857,6 +857,25 @@ class Matcher(object):
|
|||
comps[1].lower(),
|
||||
))
|
||||
|
||||
def ipcidr_match(self, tgt):
|
||||
'''
|
||||
Matches based on ip address or CIDR notation
|
||||
'''
|
||||
num_parts = len(tgt.split('/'))
|
||||
if num_parts > 2:
|
||||
return False
|
||||
elif num_parts == 2:
|
||||
return self.functions['network.in_subnet'](tgt)
|
||||
else:
|
||||
import socket
|
||||
try:
|
||||
socket.inet_aton(tgt)
|
||||
except socket.error:
|
||||
# Not a valid IPv4 address
|
||||
return False
|
||||
else:
|
||||
return tgt in self.functions['network.ip_addrs']()
|
||||
|
||||
def compound_match(self, tgt):
|
||||
'''
|
||||
Runs the compound target check
|
||||
|
@ -869,12 +888,13 @@ class Matcher(object):
|
|||
'X': 'exsel',
|
||||
'I': 'pillar',
|
||||
'L': 'list',
|
||||
'S': 'ipcidr',
|
||||
'E': 'pcre'}
|
||||
results = []
|
||||
opers = ['and', 'or', 'not']
|
||||
for match in tgt.split():
|
||||
# Try to match tokens from the compound target, first by using
|
||||
# the 'G, X, I, L, E' matcher types, then by hostname glob.
|
||||
# the 'G, X, I, L, S, E' matcher types, then by hostname glob.
|
||||
if '@' in match and match[1] == '@':
|
||||
comps = match.split('@')
|
||||
matcher = ref.get(comps[0])
|
||||
|
|
|
@ -293,8 +293,6 @@ def in_subnet(cidr):
|
|||
log.error('Invalid CIDR \'{0}\''.format(cidr))
|
||||
return False
|
||||
|
||||
ifaces = interfaces()
|
||||
|
||||
netstart_bin = _ipv4_to_bits(netstart)
|
||||
|
||||
if netsize < 32 and len(netstart_bin.rstrip('0')) > netsize:
|
||||
|
@ -303,18 +301,41 @@ def in_subnet(cidr):
|
|||
return False
|
||||
|
||||
netstart_leftbits = netstart_bin[0:netsize]
|
||||
for ipv4_info in ifaces.values():
|
||||
for ipv4 in ipv4_info.get('inet', []):
|
||||
if ipv4['address'] == '127.0.0.1': continue
|
||||
if netsize == 32:
|
||||
if netstart == ipv4['address']: return True
|
||||
else:
|
||||
ip_leftbits = _ipv4_to_bits(ipv4['address'])[0:netsize]
|
||||
if netstart_leftbits == ip_leftbits: return True
|
||||
for ip_addr in ip_addrs():
|
||||
if netsize == 32:
|
||||
if netstart == ip_addr: return True
|
||||
else:
|
||||
ip_leftbits = _ipv4_to_bits(ip_addr)[0:netsize]
|
||||
if netstart_leftbits == ip_leftbits: return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def ip_addrs():
|
||||
'''
|
||||
Returns a list of IPv4 addresses assigned to the host. (127.0.0.1 is
|
||||
ignored)
|
||||
'''
|
||||
ret = []
|
||||
ifaces = interfaces()
|
||||
for ipv4_info in ifaces.values():
|
||||
for ipv4 in ipv4_info.get('inet',[]):
|
||||
if ipv4['address'] != '127.0.0.1': ret.append(ipv4['address'])
|
||||
return ret
|
||||
|
||||
|
||||
def ip_addrs6():
|
||||
'''
|
||||
Returns a list of IPv6 addresses assigned to the host. (::1 is ignored)
|
||||
'''
|
||||
ret = []
|
||||
ifaces = interfaces()
|
||||
for ipv6_info in ifaces.values():
|
||||
for ipv6 in ipv6_info.get('inet6',[]):
|
||||
if ipv6['address'] != '::1': ret.append(ipv6['address'])
|
||||
return ret
|
||||
|
||||
|
||||
def ping(host):
|
||||
'''
|
||||
Performs a ping to a host
|
||||
|
|
|
@ -487,6 +487,12 @@ class ExtendedTargetOptionsMixIn(TargetOptionsMixIn):
|
|||
'for the target is the pillar key followed by a glob'
|
||||
'expression:\n"role:production*"')
|
||||
)
|
||||
group.add_option(
|
||||
'-S', '--ipcidr',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=('Match based on Subnet (CIDR notation) or IPv4 address.')
|
||||
)
|
||||
|
||||
self._create_process_functions()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue