diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py index 2de5634da1b..7d1dfbb0a28 100644 --- a/lib/ansible/inventory/__init__.py +++ b/lib/ansible/inventory/__init__.py @@ -85,15 +85,22 @@ class Inventory(object): patterns = pattern.replace(";",":").split(":") groups = self.get_groups() - for group in groups: - for host in group.get_hosts(): - for pat in patterns: - if group.name == pat or pat == 'all' or self._match(host.name, pat): - #must test explicitly for None because [] means no hosts allowed - if self._restriction==None: - hosts[host.name] = host - elif host.name in self._restriction: - hosts[host.name] = host + for pat in patterns: + if pat.startswith("!"): + pat = pat[1:] + inverted = True + else: + inverted = False + for group in groups: + for host in group.get_hosts(): + if group.name == pat or pat == 'all' or self._match(host.name, pat): + #must test explicitly for None because [] means no hosts allowed + if self._restriction==None or host.name in self._restriction: + if inverted: + if host.name in hosts: + del hosts[host.name] + else: + hosts[host.name] = host return sorted(hosts.values(), key=lambda x: x.name) def get_groups(self): diff --git a/test/TestInventory.py b/test/TestInventory.py index a88236e75d8..883af98dcd8 100644 --- a/test/TestInventory.py +++ b/test/TestInventory.py @@ -99,6 +99,17 @@ class TestInventory(unittest.TestCase): print expected_hosts assert sorted(hosts) == sorted(expected_hosts) + def test_simple_exclude(self): + inventory = self.simple_inventory() + + hosts = inventory.list_hosts("all:!greek") + expected_hosts=['jupiter', 'saturn', 'thor', 'odin', 'loki'] + assert sorted(hosts) == sorted(expected_hosts) + + hosts = inventory.list_hosts("all:!norse:!greek") + expected_hosts=['jupiter', 'saturn'] + assert sorted(hosts) == sorted(expected_hosts) + def test_simple_vars(self): inventory = self.simple_inventory() vars = inventory.get_variables('thor') @@ -136,6 +147,13 @@ class TestInventory(unittest.TestCase): print expected assert vars == expected + def test_complex_exclude(self): + inventory = self.complex_inventory() + + hosts = inventory.list_hosts("nc:!triangle:florida:!orlando") + expected_hosts=['rtp_a', 'rtp_b', 'rtb_c', 'miami'] + assert sorted(hosts) == sorted(expected_hosts) + ###################################################