1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Alphabetic inventory hostname patterns.

- Code, docs, tests.
  - Also added test of large range 000-142 to verify alpha range did not
    break this.
This commit is contained in:
Norman J. Harman Jr 2012-12-10 20:48:38 -06:00
parent 959a461080
commit 6603737e4d
5 changed files with 54 additions and 37 deletions

View file

@ -48,8 +48,9 @@ Adding a lot of hosts? In 0.6 and later, if you have a lot of hosts following s
[webservers] [webservers]
www[01:50].example.com www[01:50].example.com
db-[a:f].example.com
Leading zeros can be included or removed, as desired, and the ranges are inclusive. For numeric patterns, leading zeros can be included or removed, as desired. Ranges are inclusive.
Selecting Targets Selecting Targets
+++++++++++++++++ +++++++++++++++++

View file

@ -20,8 +20,8 @@
''' '''
This module is for enhancing ansible's inventory parsing capability such This module is for enhancing ansible's inventory parsing capability such
that it can deal with hostnames specified using a simple pattern in the that it can deal with hostnames specified using a simple pattern in the
form of [beg:end], example: [1:5] where if beg is not specified, it form of [beg:end], example: [1:5], [a:c], [D:G]. If beg is not specified,
defaults to 0. it defaults to 0.
If beg is given and is left-zero-padded, e.g. '001', it is taken as a If beg is given and is left-zero-padded, e.g. '001', it is taken as a
formatting hint when the range is expanded. e.g. [001:010] is to be formatting hint when the range is expanded. e.g. [001:010] is to be
@ -30,6 +30,7 @@ expanded into 001, 002 ...009, 010.
Note that when beg is specified with left zero padding, then the length of Note that when beg is specified with left zero padding, then the length of
end must be the same as that of beg, else a exception is raised. end must be the same as that of beg, else a exception is raised.
''' '''
import string
from ansible import errors from ansible import errors
@ -81,17 +82,23 @@ def expand_hostname_range(line = None):
raise errors.AnsibleError("host range end value missing") raise errors.AnsibleError("host range end value missing")
if beg[0] == '0' and len(beg) > 1: if beg[0] == '0' and len(beg) > 1:
rlen = len(beg) # range length formatting hint rlen = len(beg) # range length formatting hint
if rlen != len(end):
raise errors.AnsibleError("host range format incorrectly specified!")
fill = lambda _: str(_).zfill(rlen) # range sequence
else: else:
rlen = None fill = str
if rlen > 1 and rlen != len(end):
raise errors.AnsibleError("host range format incorrectly specified!")
for _ in range(int(beg), int(end)+1): try:
if rlen: i_beg = string.ascii_letters.index(beg)
rseq = str(_).zfill(rlen) # range sequence i_end = string.ascii_letters.index(end)
else: if i_beg > i_end:
rseq = str(_) raise errors.AnsibleError("host range format incorrectly specified!")
hname = ''.join((head, rseq, tail)) seq = string.ascii_letters[i_beg:i_end+1]
except ValueError: # not a alpha range
seq = range(int(beg), int(end)+1)
for rseq in seq:
hname = ''.join((head, fill(rseq), tail))
all_hosts.append(hname) all_hosts.append(hname)
return all_hosts return all_hosts

View file

@ -9,9 +9,10 @@ class TestInventory(unittest.TestCase):
self.cwd = os.getcwd() self.cwd = os.getcwd()
self.test_dir = os.path.join(self.cwd, 'test') self.test_dir = os.path.join(self.cwd, 'test')
self.inventory_file = os.path.join(self.test_dir, 'simple_hosts') self.inventory_file = os.path.join(self.test_dir, 'simple_hosts')
self.complex_inventory_file = os.path.join(self.test_dir, 'complex_hosts') self.large_range_inventory_file = os.path.join(self.test_dir, 'large_range')
self.inventory_script = os.path.join(self.test_dir, 'inventory_api.py') self.complex_inventory_file = os.path.join(self.test_dir, 'complex_hosts')
self.inventory_script = os.path.join(self.test_dir, 'inventory_api.py')
os.chmod(self.inventory_script, 0755) os.chmod(self.inventory_script, 0755)
@ -29,38 +30,36 @@ class TestInventory(unittest.TestCase):
def simple_inventory(self): def simple_inventory(self):
return Inventory(self.inventory_file) return Inventory(self.inventory_file)
def large_range_inventory(self):
return Inventory(self.large_range_inventory_file)
def script_inventory(self): def script_inventory(self):
return Inventory(self.inventory_script) return Inventory(self.inventory_script)
def complex_inventory(self): def complex_inventory(self):
return Inventory(self.complex_inventory_file) return Inventory(self.complex_inventory_file)
all_simple_hosts=['jupiter', 'saturn', 'zeus', 'hera',
'cerberus001','cerberus002','cerberus003',
'cottus99', 'cottus100',
'poseidon', 'thor', 'odin', 'loki',
'thrudgelmir0', 'thrudgelmir1', 'thrudgelmir2',
'thrudgelmir3', 'thrudgelmir4', 'thrudgelmir5',
'Hotep-a', 'Hotep-b', 'Hotep-c',
'BastC', 'BastD', ]
##################################### #####################################
### Simple inventory format tests ### Simple inventory format tests
def test_simple(self): def test_simple(self):
inventory = self.simple_inventory() inventory = self.simple_inventory()
hosts = inventory.list_hosts() hosts = inventory.list_hosts()
self.assertEqual(sorted(hosts), sorted(self.all_simple_hosts))
expected_hosts=['jupiter', 'saturn', 'zeus', 'hera',
'cerberus001','cerberus002','cerberus003',
'cottus99', 'cottus100',
'poseidon', 'thor', 'odin', 'loki',
'thrudgelmir0', 'thrudgelmir1', 'thrudgelmir2',
'thrudgelmir3', 'thrudgelmir4', 'thrudgelmir5']
assert sorted(hosts) == sorted(expected_hosts)
def test_simple_all(self): def test_simple_all(self):
inventory = self.simple_inventory() inventory = self.simple_inventory()
hosts = inventory.list_hosts('all') hosts = inventory.list_hosts('all')
self.assertEqual(sorted(hosts), sorted(self.all_simple_hosts))
expected_hosts=['jupiter', 'saturn', 'zeus', 'hera',
'cerberus001','cerberus002','cerberus003',
'cottus99', 'cottus100',
'poseidon', 'thor', 'odin', 'loki',
'thrudgelmir0', 'thrudgelmir1', 'thrudgelmir2',
'thrudgelmir3', 'thrudgelmir4', 'thrudgelmir5']
assert sorted(hosts) == sorted(expected_hosts)
def test_simple_norse(self): def test_simple_norse(self):
inventory = self.simple_inventory() inventory = self.simple_inventory()
@ -132,6 +131,11 @@ class TestInventory(unittest.TestCase):
print expected print expected
assert vars == expected assert vars == expected
def test_large_range(self):
inventory = self.large_range_inventory()
hosts = inventory.list_hosts()
self.assertEqual(sorted(hosts), sorted('bob%03i' %i for i in range(0, 143)))
################################################### ###################################################
### INI file advanced tests ### INI file advanced tests

1
test/large_range Normal file
View file

@ -0,0 +1 @@
bob[000:142]

View file

@ -13,3 +13,7 @@ cottus[99:100]
thor thor
odin odin
loki loki
[egyptian]
Hotep-[a:c]
Bast[C:D]