Improve bifrost inventory module

- Attempt to load both JSON and YAML formats with YAML parser.
  JSON is a strict subset of YAML, and any valid JSON must be parsable
  by YAML parser.
- yaml.load is not gerenally safe. Since the data source is a simple data
  structure lets be more strict and use yaml.safe_load instead.
- Do not continue working with parsed data while the file is still open,
  exit the open file context manager as soon as file is parsed.

Change-Id: Ic617e886fd7d1d35b784ee40d836921332ecca1f
This commit is contained in:
Pavlo Shchelokovskyy 2016-12-09 12:48:11 +00:00
parent fc9bb0f6fb
commit ac5b258b94
2 changed files with 18 additions and 23 deletions

View File

@ -171,31 +171,26 @@ def _process_baremetal_data(data_source, groups, hostvars):
"""Process data through as pre-formatted data"""
with open(data_source, 'rb') as file_object:
try:
file_data = json.load(file_object)
file_data = yaml.safe_load(file_object)
except Exception as e:
LOG.debug("Attempting to parse JSON: %s" % e)
try:
file_object.seek(0)
file_data = yaml.load(file_object)
except Exception as e:
LOG.debug("Attempting to parse YAML: %s" % e)
raise Exception("Failed to parse JSON and YAML")
LOG.debug("Failed to parse JSON or YAML: %s" % e)
raise Exception("Failed to parse JSON or YAML")
for name in file_data:
host = file_data[name]
# Perform basic validation
if ('ipv4_address' not in host or
not host['ipv4_address']):
host['addressing_mode'] = "dhcp"
else:
host['ansible_ssh_host'] = host['ipv4_address']
for name in file_data:
host = file_data[name]
# Perform basic validation
if ('ipv4_address' not in host or
not host['ipv4_address']):
host['addressing_mode'] = "dhcp"
else:
host['ansible_ssh_host'] = host['ipv4_address']
if ('provisioning_ipv4_address' not in host and
'addressing_mode' not in host):
host['provisioning_ipv4_address'] = host['ipv4_address']
# Add each host to the values to be returned.
groups['baremetal']['hosts'].append(host['name'])
hostvars.update({host['name']: host})
if ('provisioning_ipv4_address' not in host and
'addressing_mode' not in host):
host['provisioning_ipv4_address'] = host['ipv4_address']
# Add each host to the values to be returned.
groups['baremetal']['hosts'].append(host['name'])
hostvars.update({host['name']: host})
return (groups, hostvars)

View File

@ -208,7 +208,7 @@ unused,,00000000-0000-0000-0000-000000000002,hostname1,
[{"mac": "00:01:02:03:04:05"}], "properties": {"ram": "8192",
"cpu_arch": "x86_64", "disk_size": "512", "cpus": "1"}}}""".replace('\n', '')
(groups, hostvars) = utils.bifrost_data_conversion(
yaml.dump(json.loads(str(expected_hostvars))))
yaml.safe_dump(json.loads(str(expected_hostvars))))
self.assertDictEqual(json.loads(str(expected_hostvars)), hostvars)
def test_minimal_json(self):