Add support for ranged patterns like webservers[0-49] for hitting the first 50 webservers.

pull/854/merge
Michael DeHaan 12 years ago
parent e9c9d8f523
commit 9041adddaa

@ -32,6 +32,7 @@ Ansible Changes By Release
* setup module now detects interfaces with aliases * setup module now detects interfaces with aliases
* new 'ansible_all_ipv4_addresses' and 'ansible_all_ipv6_addresses' facts -- which are simple lists * new 'ansible_all_ipv4_addresses' and 'ansible_all_ipv6_addresses' facts -- which are simple lists
* better handling of VM guest type detection in setup module * better handling of VM guest type detection in setup module
* adds ranged patterns like dbservers[0-49] for usage with patterns or --limit
0.6 "Cabo" -- August 6, 2012 0.6 "Cabo" -- August 6, 2012

@ -123,7 +123,7 @@ class Inventory(object):
if self._restriction is not None: if self._restriction is not None:
hosts = [ h for h in hosts if h.name in self._restriction ] hosts = [ h for h in hosts if h.name in self._restriction ]
return hosts return sorted(hosts, key=lambda x: x.name)
def _get_hosts(self, patterns): def _get_hosts(self, patterns):
""" """
@ -134,7 +134,9 @@ class Inventory(object):
by_pattern = {} by_pattern = {}
for p in patterns: for p in patterns:
(name, enumeration_details) = self._enumeration_info(p) (name, enumeration_details) = self._enumeration_info(p)
by_pattern[p] = self._hosts_in_unenumerated_pattern(name) hpat = self._hosts_in_unenumerated_pattern(name)
hpat = sorted(hpat, key=lambda x: x.name)
by_pattern[p] = hpat
ranged = {} ranged = {}
for (pat, hosts) in by_pattern.iteritems(): for (pat, hosts) in by_pattern.iteritems():
@ -156,17 +158,32 @@ class Inventory(object):
if not "[" in pattern: if not "[" in pattern:
return (pattern, None) return (pattern, None)
(first, rest) = pattern.split("[") (first, rest) = pattern.split("[")
rest.replace("]","") rest = rest.replace("]","")
if not "-" in rest: if not "-" in rest:
raise errors.AnsibleError("invalid pattern: %s" % pattern) raise errors.AnsibleError("invalid pattern: %s" % pattern)
(left, right) = rest.split("-",1) (left, right) = rest.split("-",1)
return (first, (left, right)) return (first, (left, right))
def _apply_ranges(self, pat, hosts): def _apply_ranges(self, pat, hosts):
"""
given a pattern like foo, that matches hosts, return all of hosts
given a pattern like foo[0:5], where foo matches hosts, return the first 6 hosts
"""
(loose_pattern, limits) = self._enumeration_info(pat) (loose_pattern, limits) = self._enumeration_info(pat)
if not limits: if not limits:
return hosts return hosts
raise Exception("ranges are not yet supported")
(left, right) = limits
enumerated = enumerate(hosts)
if left == '':
left = 0
if right == '':
right = 0
left=int(left)
right=int(right)
enumerated = [ h for (i,h) in enumerated if i>=left and i<=right ]
return enumerated
# TODO: cache this logic so if called a second time the result is not recalculated # TODO: cache this logic so if called a second time the result is not recalculated
def _hosts_in_unenumerated_pattern(self, pattern): def _hosts_in_unenumerated_pattern(self, pattern):
@ -252,7 +269,7 @@ class Inventory(object):
return [ h.name for h in self.get_hosts(pattern) ] return [ h.name for h in self.get_hosts(pattern) ]
def list_groups(self): def list_groups(self):
return [ g.name for g in self.groups ] return sorted([ g.name for g in self.groups ], key=lambda x: x.name)
def get_restriction(self): def get_restriction(self):
return self._restriction return self._restriction

@ -18,14 +18,14 @@ class TestInventory(unittest.TestCase):
def tearDown(self): def tearDown(self):
os.chmod(self.inventory_script, 0644) os.chmod(self.inventory_script, 0644)
def compare(self, left, right): def compare(self, left, right, sort=True):
if sort:
left = sorted(left) left = sorted(left)
right = sorted(right) right = sorted(right)
print left print left
print right print right
assert left == right assert left == right
def simple_inventory(self): def simple_inventory(self):
return Inventory(self.inventory_file) return Inventory(self.inventory_file)
@ -152,13 +152,32 @@ class TestInventory(unittest.TestCase):
def test_complex_exclude(self): def test_complex_exclude(self):
inventory = self.complex_inventory() inventory = self.complex_inventory()
hosts = inventory.list_hosts("nc:florida:!triangle:!orlando") hosts = inventory.list_hosts("nc:florida:!triangle:!orlando")
expected_hosts = ['miami', 'rtb_c', 'rtp_a', 'rtp_b'] expected_hosts = ['miami', 'rtp_a', 'rtp_b', 'rtp_c']
print "HOSTS=%s" % sorted(hosts) print "HOSTS=%s" % sorted(hosts)
print "EXPECTED=%s" % sorted(expected_hosts) print "EXPECTED=%s" % sorted(expected_hosts)
assert sorted(hosts) == sorted(expected_hosts) assert sorted(hosts) == sorted(expected_hosts)
def test_complex_enumeration(self):
expected1 = ['rtp_a', 'rtp_b']
expected2 = ['rtp_c', 'tri_a']
expected3 = ['rtp_b', 'rtp_c', 'tri_a', 'tri_b', 'tri_c']
expected4 = ['orlando', 'rtp_c', 'tri_a']
inventory = self.complex_inventory()
print "ALL NC=%s" % inventory.list_hosts("nc")
hosts = inventory.list_hosts("nc[0-1]")
self.compare(hosts, expected1, sort=False)
hosts = inventory.list_hosts("nc[2-3]")
self.compare(hosts, expected2, sort=False)
hosts = inventory.list_hosts("nc[1-99999]")
self.compare(hosts, expected3, sort=False)
hosts = inventory.list_hosts("nc[2-3]:florida[1-2]")
self.compare(hosts, expected4, sort=False)
################################################### ###################################################
### Inventory API tests ### Inventory API tests

@ -38,7 +38,7 @@ d=10002
[rtp] [rtp]
rtp_a rtp_a
rtp_b rtp_b
rtb_c rtp_c
[rtp:vars] [rtp:vars]
a=1 a=1

Loading…
Cancel
Save