diff --git a/bifrost/tests/functional/__init__.py b/bifrost/tests/functional/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bifrost/tests/functional/test_inventory_functional.py b/bifrost/tests/functional/test_inventory_functional.py new file mode 100644 index 000000000..e2b80c0ec --- /dev/null +++ b/bifrost/tests/functional/test_inventory_functional.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json + +from bifrost.tests import base +from bifrost.tests import utils + + +class TestBifrostInventoryFunctional(base.TestCase): + + def setUp(self): + self.maxDiff = None + super(TestBifrostInventoryFunctional, self).setUp() + + def test_csv_file_conversion_multiline_general(self): + # NOTE(TheJulia): While this is a massive amount of input + # and resulting output that is parsed as part of this + # and similar tests, we need to ensure consistency, + # and that is largely what this test is geared to ensure. + CSV = """00:01:02:03:04:05,root,undefined,192.0.2.2,1,8192,512, +unused,,00000000-0000-0000-0000-000000000001,hostname0, +192.168.1.2,,,,| +00:01:02:03:04:06,root,undefined,192.0.2.3,2,8192,1024, +unused,,00000000-0000-0000-0000-000000000002,hostname1, +192.168.1.3,,,,,agent_ipmitool""".replace('\n', '').replace('|', '\n') + expected_hostvars = """{"hostname1": + {"uuid": "00000000-0000-0000-0000-000000000002", "driver": "agent_ipmitool", + "name": "hostname1", "ipv4_address": "192.168.1.3", "ansible_ssh_host": + "192.168.1.3", "driver_info": {"power": {"ipmi_address": "192.0.2.3", + "ipmi_password": "undefined", "ipmi_username": "root", + "ipmi_target_address": null, "ipmi_target_channel": null, + "ipmi_transit_address": null, "ipmi_transit_channel": null}}, "nics": + [{"mac": "00:01:02:03:04:06"}], "properties": {"ram": "8192", "cpu_arch": + "x86_64", "disk_size": "1024", "cpus": "2"}}, "hostname0": + {"uuid": "00000000-0000-0000-0000-000000000001", "driver": "agent_ssh", + "name": "hostname0", "ipv4_address": "192.168.1.2", "ansible_ssh_host": + "192.168.1.2", "driver_info": {"power": {"ssh_virt_type": "virsh", + "ssh_key_filename": "/home/ironic/.ssh/id_rsa", "ssh_username": + "ironic", "ssh_port": 22, "ssh_address": "192.0.2.2"}}, "nics": + [{"mac": "00:01:02:03:04:05"}], "properties": {"ram": "8192", + "cpu_arch": "x86_64", "disk_size": "512", "cpus": "1"}}}""".replace('\n', '') + expected_groups = """{"baremetal": {"hosts": ["hostname0", + "hostname1"]}, "localhost": {"hosts": ["127.0.0.1"]}}""".replace('\n', '') + + (groups, hostvars) = utils.bifrost_csv_conversion(CSV) + self.assertDictEqual(json.loads(str(expected_hostvars)), hostvars) + self.assertDictEqual(json.loads(expected_groups), groups) + + def test_csv_file_conversion_ipmi_dual_bridging(self): + CSV = """00:01:02:03:04:06,root,undefined,192.0.2.3,2,8192,1024, +unused,,00000000-0000-0000-0000-000000000002,hostname1, +192.168.1.3,10,20,30,40,agent_ipmitool""".replace('\n', '').replace('|', '\n') + + expected_hostvars = """{"hostname1": + {"uuid": "00000000-0000-0000-0000-000000000002", "driver": "agent_ipmitool", + "name": "hostname1", "ipv4_address": "192.168.1.3", "ansible_ssh_host": + "192.168.1.3", "driver_info": {"power": {"ipmi_address": "192.0.2.3", + "ipmi_password": "undefined", "ipmi_username": "root", + "ipmi_target_address": "20", "ipmi_target_channel": "10", + "ipmi_transit_address": "40", "ipmi_transit_channel": "30", + "ipmi_bridging": "dual"}}, "nics": + [{"mac": "00:01:02:03:04:06"}], "properties": {"ram": "8192", "cpu_arch": + "x86_64", "disk_size": "1024", "cpus": "2"}}}""".replace('\n', '') + + expected_groups = """{"baremetal": {"hosts": ["hostname1"]}, + "localhost": {"hosts": ["127.0.0.1"]}}""".replace('\n', '') + + (groups, hostvars) = utils.bifrost_csv_conversion(CSV) + self.assertDictEqual(json.loads(str(expected_hostvars)), hostvars) + self.assertDictEqual(json.loads(expected_groups), groups) + + def test_csv_file_conversion_ipmi_single_bridging(self): + CSV = """00:01:02:03:04:06,root,undefined,192.0.2.3,2,8192,1024, +unused,,00000000-0000-0000-0000-000000000002,hostname1, +192.168.1.3,10,20,,,agent_ipmitool""".replace('\n', '').replace('|', '\n') + + expected_hostvars = """{"hostname1": + {"uuid": "00000000-0000-0000-0000-000000000002", "driver": "agent_ipmitool", + "name": "hostname1", "ipv4_address": "192.168.1.3", "ansible_ssh_host": + "192.168.1.3", "driver_info": {"power": {"ipmi_address": "192.0.2.3", + "ipmi_password": "undefined", "ipmi_username": "root", + "ipmi_target_address": "20", "ipmi_target_channel": "10", + "ipmi_transit_address": null, "ipmi_transit_channel": null, + "ipmi_bridging": "single"}}, "nics": + [{"mac": "00:01:02:03:04:06"}], "properties": {"ram": "8192", "cpu_arch": + "x86_64", "disk_size": "1024", "cpus": "2"}}}""".replace('\n', '') + + (groups, hostvars) = utils.bifrost_csv_conversion(CSV) + self.assertDictEqual(json.loads(str(expected_hostvars)), hostvars) + + def test_csv_file_conversion_dhcp(self): + CSV = """00:01:02:03:04:06,root,undefined,192.0.2.3,2,8192,1024, +unused,,00000000-0000-0000-0000-000000000002,hostname1 +,,,,,,agent_ipmitool""".replace('\n', '').replace('|', '\n') + + expected_hostvars = """{"hostname1": + {"uuid": "00000000-0000-0000-0000-000000000002", "driver": "agent_ipmitool", + "name": "hostname1", "addressing_mode": "dhcp", "ipv4_address": null, + "driver_info": {"power": {"ipmi_address": "192.0.2.3", "ipmi_password": + "undefined", "ipmi_username": "root", "ipmi_target_address": null, + "ipmi_target_channel": null, "ipmi_transit_address": null, + "ipmi_transit_channel": null}}, "nics": + [{"mac": "00:01:02:03:04:06"}], "properties": {"ram": "8192", "cpu_arch": + "x86_64", "disk_size": "1024", "cpus": "2"}}}""".replace('\n', '') + + (groups, hostvars) = utils.bifrost_csv_conversion(CSV) + self.assertDictEqual(json.loads(str(expected_hostvars)), hostvars) diff --git a/bifrost/tests/unit/test_inventory.py b/bifrost/tests/unit/test_inventory.py index c1ff3e6a4..4c024d262 100644 --- a/bifrost/tests/unit/test_inventory.py +++ b/bifrost/tests/unit/test_inventory.py @@ -20,10 +20,11 @@ Tests for `inventory` module. """ from bifrost import inventory + from bifrost.tests import base -class TestBifrostInventory(base.TestCase): +class TestBifrostInventoryUnit(base.TestCase): def test_inventory_preparation(self): (groups, hostvars) = inventory._prepare_inventory() diff --git a/bifrost/tests/utils.py b/bifrost/tests/utils.py new file mode 100644 index 000000000..9027e72ed --- /dev/null +++ b/bifrost/tests/utils.py @@ -0,0 +1,45 @@ +# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import contextlib +import tempfile + +from bifrost import inventory + + +@contextlib.contextmanager +def temporary_file(file_data): + file = None + file = tempfile.NamedTemporaryFile(mode='w') + file.write(file_data) + file.flush() + + try: + yield file.name + finally: + if file is not None: + file.close() + + +def bifrost_csv_conversion(csv_data): + # TODO(TheJulia): To call prep feels like a bug and should be fixed. + (groups, hostvars) = inventory._prepare_inventory() + with temporary_file(csv_data) as file: + (groups, hostvars) = inventory._process_baremetal_csv( + file, + groups, + hostvars) + # NOTE(TheJulia): Returning separately so the file is closed first + return (groups, hostvars) diff --git a/playbooks/inventory/baremetal.csv.example b/playbooks/inventory/baremetal.csv.example index ca9a47cfd..bc3e273f9 100644 --- a/playbooks/inventory/baremetal.csv.example +++ b/playbooks/inventory/baremetal.csv.example @@ -1,5 +1,5 @@ -00:1c:ab:8a:97:eb,root,undefined,192.168.122.1,1,8192,512,Control,VM,a8cb6624-0d9f-c882-affc-046ebb96ec01,hostname0,192.168.1.2,,,, -00:2b:b7:65:83:19,root,undefined,192.168.122.1,1,8192,512,Control,VM,a8cb6624-0d9f-c882-affc-046ebb96ec02,hostname1,192.168.1.3,,,, +00:1c:ab:8a:97:eb,root,undefined,192.168.122.1,1,8192,512,Control,VM,a8cb6624-0d9f-c882-affc-046ebb96ec01,hostname0,192.168.1.2,,,,,agent_ipmitool +00:2b:b7:65:83:19,root,undefined,192.168.122.1,1,8192,512,Control,VM,a8cb6624-0d9f-c882-affc-046ebb96ec02,hostname1,192.168.1.3,,,,,pxe_ipmitool 00:3a:ca:56:7d:2e,root,undefined,192.168.122.1,1,8192,512,Control,VM,a8cb6624-0d9f-c882-affc-046ebb96ec03,hostname2,192.168.1.4,,,, 00:4e:d5:45:6f:31,root,undefined,192.168.122.1,1,8192,512,SwiftStorage,VM,a8cb6624-0d9f-c882-affc-046ebb96ec04,hostname3,192.168.1.5,,,, 00:5a:ed:39:57:31,root,undefined,192.168.122.1,1,8192,512,SwiftStorage,VM,a8cb6624-0d9f-c882-affc-046ebb96ec05,hostname4,192.168.1.6,,,,