Add YAML inventory format.

See test/yaml_hosts for an example.

Hosts can be part of multiple groups.

Groups can also have variables, inherited by the hosts.
There is no variable scope, last variable seen wins.
pull/146/head
Jeroen Hoekx 12 years ago
parent 54f4526160
commit 3a24aa9a70

@ -97,6 +97,8 @@ class Inventory(object):
results = []
groups = dict(ungrouped=[])
lines = file(self.inventory_file).read().split("\n")
if "---" in lines:
return self._parse_yaml()
group_name = 'ungrouped'
for item in lines:
item = item.lstrip().rstrip()
@ -154,6 +156,76 @@ class Inventory(object):
# *****************************************************
def _parse_yaml(self):
""" Load the inventory from a yaml file.
returns hosts and groups"""
data = utils.parse_yaml_from_file(self.inventory_file)
if type(data) != list:
raise errors.AnsibleError("YAML inventory should be a list.")
hosts = []
groups = {}
for item in data:
if type(item) == dict:
if "group" in item:
group_name = item["group"]
group_vars = []
if "vars" in item:
group_vars = item["vars"]
group_hosts = []
if "hosts" in item:
for host in item["hosts"]:
host_name = self._parse_yaml_host(host, group_vars)
group_hosts.append(host_name)
groups[group_name] = group_hosts
hosts.extend(group_hosts)
# or a host
elif "host" in item:
host_name = self._parse_yaml_host(item)
hosts.append(host_name)
else:
host_name = self._parse_yaml_host(item)
hosts.append(host_name)
# filter duplicate hosts
output_hosts = []
for host in hosts:
if host not in output_hosts:
output_hosts.append(host)
return output_hosts, groups
def _parse_yaml_host(self, item, variables=[]):
def set_variables(host, variables):
for variable in variables:
if len(variable) != 1:
raise AnsibleError("Only one item expected in %s"%(variable))
k, v = variable.items()[0]
self._set_variable(host, k, v)
if type(item) in [str, unicode]:
set_variables(item, variables)
return item
elif type(item) == dict:
if "host" in item:
host_name = item["host"]
set_variables(host_name, variables)
if "vars" in item:
set_variables(host_name, item["vars"])
return host_name
else:
raise AnsibleError("Unknown item in inventory: %s"%(item))
def _get_variables_from_script(self, host, extra_vars=None):
''' support per system variabes from external variable scripts, see web docs '''

@ -12,6 +12,7 @@ class TestInventory(unittest.TestCase):
self.inventory_file = os.path.join(self.test_dir, 'simple_hosts')
self.inventory_script = os.path.join(self.test_dir, 'inventory_api.py')
self.inventory_yaml = os.path.join(self.test_dir, 'yaml_hosts')
os.chmod(self.inventory_script, 0755)
@ -26,6 +27,9 @@ class TestInventory(unittest.TestCase):
def script_inventory(self):
return Inventory( self.inventory_script )
def yaml_inventory(self):
return Inventory( self.inventory_yaml )
def test_simple(self):
inventory = self.simple_inventory()
hosts = inventory.list_hosts()
@ -149,6 +153,76 @@ class TestInventory(unittest.TestCase):
assert vars == {"hammer":True, "simple": "yes"}
### Tests for yaml inventory file
def test_yaml(self):
inventory = self.yaml_inventory()
hosts = inventory.list_hosts()
print hosts
expected_hosts=['jupiter', 'saturn', 'zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
assert hosts == expected_hosts
def test_yaml_all(self):
inventory = self.yaml_inventory()
hosts = inventory.list_hosts('all')
expected_hosts=['jupiter', 'saturn', 'zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
assert hosts == expected_hosts
def test_yaml_norse(self):
inventory = self.yaml_inventory()
hosts = inventory.list_hosts("norse")
expected_hosts=['thor', 'odin', 'loki']
assert hosts == expected_hosts
def test_yaml_combined(self):
inventory = self.yaml_inventory()
hosts = inventory.list_hosts("norse:greek")
expected_hosts=['zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
assert hosts == expected_hosts
def test_yaml_restrict(self):
inventory = self.yaml_inventory()
restricted_hosts = ['hera', 'poseidon', 'thor']
expected_hosts=['zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
inventory.restrict_to(restricted_hosts)
hosts = inventory.list_hosts("norse:greek")
assert hosts == restricted_hosts
inventory.lift_restriction()
hosts = inventory.list_hosts("norse:greek")
assert hosts == expected_hosts
def test_yaml_vars(self):
inventory = self.yaml_inventory()
vars = inventory.get_variables('thor')
assert vars == {"hammer":True}
def test_yaml_host_vars(self):
inventory = self.yaml_inventory()
vars = inventory.get_variables('saturn')
assert vars == {"moon":"titan"}
def test_yaml_extra_vars(self):
inventory = self.yaml_inventory()
vars = inventory.get_variables('thor', 'a=5')
assert vars == {"hammer":True}
def test_yaml_port(self):
inventory = self.yaml_inventory()
vars = inventory.get_variables('hera')
assert vars == {'ansible_ssh_port': 3000}
### Test Runner class method
def test_class_method(self):

@ -0,0 +1,26 @@
---
- jupiter
- host: saturn
vars:
- moon: titan
- group: greek
hosts:
- zeus
- hera
- poseidon
vars:
- ansible_ssh_port: 3000
- group: norse
hosts:
- host: thor
vars:
- hammer: True
- odin
- loki
- group: multiple
hosts:
- saturn
Loading…
Cancel
Save