def setUp(self):
     super().setUp()
     OpenMock = mock.mock_open(read_data=self._file_data)
     with mock.patch('inventory_tool.object.inventory.open',
                     OpenMock,
                     create=True):
         self.obj = iv.InventoryData(paths.TMP_INVENTORY)
 def test_init_load_unsupported_file_format(self):
     data = self._file_data
     data = data.replace('version: 1', "version: 0")
     OpenMock = mock.mock_open(read_data=data)
     with self.assertRaises(BadDataException):
         with mock.patch('inventory_tool.object.inventory.open',
                         OpenMock,
                         create=True):
             iv.InventoryData(paths.TEST_INVENTORY)
 def test_recalculation_alias_normalization(self):
     obj = iv.InventoryData(paths.DENORMALIZED_ALIASES_INVENTORY)
     obj.recalculate_inventory()
     foobarator_aliases = obj.host_get("foobarator.y1").get_aliases()
     y1_aliases = obj.host_get("y1").get_aliases()
     y1_front_aliases = obj.host_get("y1-front.foobar").get_aliases()
     self.assertCountEqual(foobarator_aliases,
                           ['proper', 'gulgulator', 'other'])
     self.assertCountEqual(y1_aliases, ["other-proper"])
     self.assertCountEqual(y1_front_aliases, [])
 def test_recalculation_hosts_cleanup(self):
     obj = iv.InventoryData(paths.ORPHANED_HOSTS_INVENTORY)
     obj.recalculate_inventory()
     front_hosts = obj.group_get("front").get_hosts()
     guests_y1_hosts = obj.group_get("guests-y1").get_hosts()
     hypervisor_hosts = obj.group_get("hypervisor").get_hosts()
     self.assertCountEqual(guests_y1_hosts,
                           ['foobarator.y1', 'y1-front.foobar'])
     self.assertCountEqual(front_hosts, ['y1-front.foobar'])
     self.assertCountEqual(hypervisor_hosts, ['y1'])
    def test_init_load_bad_checksum(self, RecalculateInventoryMock):
        # mock out inventory recalculation
        data = self._file_data
        data = data.replace('6119b68e3bc8d569568a93', '6119b68e3bc8d569568a16')
        OpenMock = mock.mock_open(read_data=data)
        with mock.patch('inventory_tool.object.inventory.open',
                        OpenMock,
                        create=True):
            iv.InventoryData(paths.TEST_INVENTORY)

        RecalculateInventoryMock.assert_called_with()
 def test_recalculation_child_groups_cleanup(self):
     obj = iv.InventoryData(paths.ORPHANED_CHILD_GORUPS_INVENTORY)
     obj.recalculate_inventory()
     front_children = obj.group_get("front").get_children()
     guests_y1_children = obj.group_get("guests-y1").get_children()
     all_guests_children = obj.group_get("all-guests").get_children()
     all_children = obj.group_get("all").get_children()
     self.assertListEqual([], front_children)
     self.assertListEqual([], guests_y1_children)
     self.assertCountEqual(['guests-y1'], all_guests_children)
     self.assertCountEqual(['all-guests', 'front'], all_children)
 def test_recalculation_ippool_refresh(self):
     obj = iv.InventoryData(paths.REFRESHED_IPPOOL_INVENTORY)
     obj.recalculate_inventory()
     y1_guests_pool_allocated = obj.ippool_get(
         'y1_guests').get_hash()["allocated"]
     tunels_pool_allocated = obj.ippool_get(
         'tunels').get_hash()["allocated"]
     correct_tunnels_pool_allocation = ['192.168.1.125']
     correct_y1_guests_pool_allocation = ['192.168.125.2', '192.168.125.3']
     self.assertCountEqual(tunels_pool_allocated,
                           correct_tunnels_pool_allocation)
     self.assertCountEqual(y1_guests_pool_allocated,
                           correct_y1_guests_pool_allocation)
    def test_ansible_get_inventory(self):
        self.maxDiff = None
        OpenMock = mock.mock_open(read_data=self._file_data)
        with mock.patch('inventory_tool.object.inventory.open',
                        OpenMock,
                        create=True):
            obj = iv.InventoryData(paths.TMP_INVENTORY)
        correct_data = {
            '_meta': {
                'hostvars': {
                    'foobarator.y1': {
                        'aliases': [],
                        'ansible_ssh_host': '192.168.125.3'
                    },
                    'y1': {
                        'aliases': [],
                        'ansible_ssh_host': '1.2.3.4',
                        'tunnel_ip': '192.168.255.125'
                    },
                    'y1-front.foobar': {
                        'aliases': ['front-foobar.y1'],
                        'ansible_ssh_host': '192.168.125.2'
                    }
                }
            },
            'all': {
                'children': [],
                'hosts': ['foobarator.y1', 'y1', 'y1-front.foobar'],
                'vars': {}
            },
            'front': {
                'children': [],
                'hosts': ['y1-front.foobar'],
                'vars': {}
            },
            'guests-y1': {
                'children': [],
                'hosts': ['foobarator.y1', 'y1-front.foobar'],
                'vars': {}
            },
            'hypervisor': {
                'children': [],
                'hosts': ['y1'],
                'vars': {}
            }
        }

        test_data = obj.get_ansible_inventory()

        self.assertEqual(test_data, correct_data)
    def test_host_ipaddr_keyval_set_with_autoallocation(self):
        obj = iv.InventoryData(paths.IPADDR_AUTOALLOCATION_INVENTORY)
        obj.host_set_vars('y1-front.foobar', [{
            "key": 'tunnel_ip',
            "val": None
        }])

        host_hash = obj.host_get("y1-front.foobar").get_hash()
        correct_hash = {
            'aliases': [],
            'keyvals': {
                'tunnel_ip': '192.168.255.1'
            }
        }
        self.assertEqual(host_hash, correct_hash)
    def test_host_plain_keyval_removal_allok(self):
        # FIXME - this can be done without introducing another fabric file,
        # but hosts-production needs to be changed and with it a lot of tests.
        obj = iv.InventoryData(paths.HOSTVARS_INVENTORY)
        obj.host_del_vars('foobarator.y1', ['some_key'])

        host_hash = obj.host_get("foobarator.y1").get_hash()
        correct_hash = {
            'aliases': [],
            'keyvals': {
                'ansible_ssh_host': '192.168.125.3',
                "some_other_key": "12345"
            }
        }
        self.assertEqual(host_hash, correct_hash)
    def test_init_inventory(self):
        empty_inventory = {
            '_meta': {
                'hostvars': {}
            },
            'all': {
                'children': [],
                'hosts': [],
                'vars': {}
            }
        }
        OpenMock = mock.mock_open(read_data=self._file_data)
        with mock.patch('__main__.open', OpenMock, create=True):
            obj = iv.InventoryData(paths.TEST_INVENTORY, initialize=True)

        self.assertFalse(OpenMock.called)
        self.assertEqual(empty_inventory, obj.get_ansible_inventory())
    def test_init_inventory_file_missing(self):
        OpenMock = mock.mock_open(read_data=self._file_data)

        def raise_not_found(*unused):
            try:
                error_to_catch = FileNotFoundError
            except NameError:
                # Python < 3.4
                error_to_catch = IOError
            raise error_to_catch

        OpenMock.side_effect = raise_not_found
        with self.assertRaises(MalformedInputException):
            with mock.patch('inventory_tool.object.inventory.open',
                            OpenMock,
                            create=True):
                iv.InventoryData(paths.TEST_INVENTORY)
    def test_host_plain_inexistant_keyval_removal(self):
        obj = iv.InventoryData(paths.HOSTVARS_INVENTORY)
        with self.assertRaises(MalformedInputException):
            self.obj.host_del_vars('foobarator.y1',
                                   ['some_key', 'inexistant_keyval'])

        # Other keyvals should not be removed if at least one keyval does not
        # exists:
        host_hash = obj.host_get("foobarator.y1").get_hash()
        correct_hash = {
            'aliases': [],
            'keyvals': {
                'ansible_ssh_host': '192.168.125.3',
                'some_key': 'some_val',
                "some_other_key": "12345"
            }
        }
        self.assertEqual(host_hash, correct_hash)
    def test_save_all_ok(self):
        OpenMock = mock.mock_open(read_data=self._file_data)
        with mock.patch('inventory_tool.object.inventory.open',
                        OpenMock,
                        create=True):
            obj = iv.InventoryData(paths.TMP_INVENTORY)

        SaveMock = mock.mock_open()
        with mock.patch('inventory_tool.object.inventory.open',
                        SaveMock,
                        create=True):
            obj.save()
        SaveMock.assert_called_once_with(paths.TMP_INVENTORY, 'wb')
        # Comparing multi-line text is tricky:
        handle = SaveMock()
        self.maxDiff = None
        self.assertMultiLineEqual(self._file_data,
                                  handle.write.call_args[0][0])
    def test_init_all_ok(self):
        OpenMock = mock.mock_open(read_data=self._file_data)

        with mock.patch('inventory_tool.object.inventory.open',
                        OpenMock,
                        create=True):
            iv.InventoryData(paths.TEST_INVENTORY)

        OpenMock.assert_called_once_with(paths.TEST_INVENTORY, 'rb')
        proper_ippool_calls = [
            call(network='192.168.125.0/24',
                 reserved=['192.168.125.1'],
                 allocated=['192.168.125.2', '192.168.125.3']),
            call(network='192.168.255.0/24',
                 reserved=[],
                 allocated=['192.168.255.125'])
        ]
        self.mocks['inventory_tool.object.ippool.IPPool'].assert_has_calls(
            proper_ippool_calls, any_order=True)
        proper_group_calls = [
            call(ippools={'tunnel_ip': 'tunels'}, hosts=['y1'], children=[]),
            call(ippools={}, hosts=['y1-front.foobar'], children=[]),
            call(ippools={'ansible_ssh_host': 'y1_guests'},
                 hosts=['foobarator.y1', 'y1-front.foobar'],
                 children=[])
        ]
        self.mocks['inventory_tool.object.group.Group'].assert_has_calls(
            proper_group_calls, any_order=True)
        proper_host_calls = [
            call(keyvals={
                'ansible_ssh_host': '1.2.3.4',
                'tunnel_ip': '192.168.255.125'
            },
                 aliases=[]),
            call(keyvals={'ansible_ssh_host': '192.168.125.3'}, aliases=[]),
            call(keyvals={'ansible_ssh_host': '192.168.125.2'},
                 aliases=['front-foobar.y1'])
        ]
        self.mocks['inventory_tool.object.host.Host'].assert_has_calls(
            proper_host_calls, any_order=True)
 def test_group_del_child(self):
     obj = iv.InventoryData(paths.CHILD_GROUPS_INVENTORY)
     obj.group_child_del("all", "front")
     group_hash = obj.group_get("all").get_hash()
     self.assertCountEqual(group_hash["children"], ["all-guests"])
 def test_group_del_child_from_inexistant_group(self):
     obj = iv.InventoryData(paths.CHILD_GROUPS_INVENTORY)
     with self.assertRaises(MalformedInputException):
         obj.group_child_del("all2", "front")
 def testrecalculation__hostname_normalization(self, HostRenameMock):
     obj = iv.InventoryData(paths.DENORMALIZED_HOSTNAMES_INVENTORY)
     obj.recalculate_inventory()
     HostRenameMock.assert_called_once_with('foobarator.y1.example.com',
                                            'foobarator.y1')
 def test_recalculation_is_recalculated_flag(self):
     obj = iv.InventoryData(paths.EMPTY_CHECKSUM_OK_INVENTORY)
     self.assertFalse(obj.is_recalculated())
     obj = iv.InventoryData(paths.EMPTY_CHECKSUM_BAD_INVENTORY)
     self.assertTrue(obj.is_recalculated())
    def test_recalculation_with_nonoverlapping_ippools(self):
        obj = iv.InventoryData(paths.NONOVERLAPPING_IPPOOLS_INVENTORY)

        obj.recalculate_inventory()
    def test_recalculatio_with_overlapping_ippools(self):
        obj = iv.InventoryData(paths.OVERLAPPING_IPPOOLS_INVENTORY)

        with self.assertRaises(BadDataException):
            obj.recalculate_inventory()
 def test_ansible_missing_ssh_host(self):
     obj = iv.InventoryData(paths.MISSING_ANSIBLE_SSH_HOST_INVENTORY)
     with self.assertRaises(BadDataException):
         obj.get_ansible_inventory()