mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-10-03 23:14:02 -07:00
Implement contructable support for opennebula inventory plugin: keyed… (#4524)
* Implement contructable support for opennebula inventory plugin: keyed_groups, compose, groups * Fixed templating mock issues in unit tests, corrected some linting errors * trying to make the linter happy * Now trying to make python2.7 happy * Added changelog fragment * changelog fragment needs pluralization * Update changelogs/fragments/4524-update-opennebula-inventory-plugin-to-match-documentation.yaml Co-authored-by: Felix Fontein <felix@fontein.de> Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
d9ba598938
commit
8e72e98adb
4 changed files with 342 additions and 26 deletions
|
@ -9,14 +9,18 @@ from __future__ import (absolute_import, division, print_function)
|
|||
__metaclass__ = type
|
||||
|
||||
from collections import OrderedDict
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from ansible.inventory.data import InventoryData
|
||||
from ansible.parsing.dataloader import DataLoader
|
||||
from ansible.template import Templar
|
||||
from ansible_collections.community.general.plugins.inventory.opennebula import InventoryModule
|
||||
from ansible_collections.community.general.tests.unit.compat.mock import create_autospec
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@pytest.fixture
|
||||
def inventory():
|
||||
r = InventoryModule()
|
||||
r.inventory = InventoryData()
|
||||
|
@ -33,6 +37,18 @@ def test_verify_file_bad_config(inventory):
|
|||
assert inventory.verify_file('foobar.opennebula.yml') is False
|
||||
|
||||
|
||||
def get_vm_pool_json():
|
||||
with open('tests/unit/plugins/inventory/fixtures/opennebula_inventory.json', 'r') as json_file:
|
||||
jsondata = json.load(json_file)
|
||||
|
||||
data = type('pyone.bindings.VM_POOLSub', (object,), {'VM': []})()
|
||||
|
||||
for fake_server in jsondata:
|
||||
data.VM.append(type('pyone.bindings.VMType90Sub', (object,), fake_server)())
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def get_vm_pool():
|
||||
data = type('pyone.bindings.VM_POOLSub', (object,), {'VM': []})()
|
||||
|
||||
|
@ -195,36 +211,99 @@ def get_vm_pool():
|
|||
return data
|
||||
|
||||
|
||||
def get_option(option):
|
||||
if option == 'api_url':
|
||||
return 'https://opennebula:2633/RPC2'
|
||||
if option == 'api_username':
|
||||
return 'username'
|
||||
elif option == 'api_password':
|
||||
return 'password'
|
||||
elif option == 'api_authfile':
|
||||
return '~/.one/one_auth'
|
||||
elif option == 'hostname':
|
||||
return 'v4_first_ip'
|
||||
elif option == 'group_by_labels':
|
||||
return True
|
||||
elif option == 'filter_by_label':
|
||||
return None
|
||||
else:
|
||||
return False
|
||||
options_base_test = {
|
||||
'api_url': 'https://opennebula:2633/RPC2',
|
||||
'api_username': 'username',
|
||||
'api_password': 'password',
|
||||
'api_authfile': '~/.one/one_auth',
|
||||
'hostname': 'v4_first_ip',
|
||||
'group_by_labels': True,
|
||||
'filter_by_label': None,
|
||||
}
|
||||
|
||||
options_constructable_test = options_base_test.copy()
|
||||
options_constructable_test.update({
|
||||
'compose': {'is_linux': "GUEST_OS == 'linux'"},
|
||||
'filter_by_label': 'bench',
|
||||
'groups': {
|
||||
'benchmark_clients': "TGROUP.endswith('clients')",
|
||||
'lin': 'is_linux == True'
|
||||
},
|
||||
'keyed_groups': [{'key': 'TGROUP', 'prefix': 'tgroup'}],
|
||||
|
||||
})
|
||||
|
||||
|
||||
# given a dictionary `opts_dict`, return a function that behaves like ansible's inventory get_options
|
||||
def mk_get_options(opts_dict):
|
||||
def inner(opt):
|
||||
return opts_dict.get(opt, False)
|
||||
return inner
|
||||
|
||||
|
||||
def test_get_connection_info(inventory, mocker):
|
||||
inventory.get_option = mocker.MagicMock(side_effect=get_option)
|
||||
inventory.get_option = mocker.MagicMock(side_effect=mk_get_options(options_base_test))
|
||||
|
||||
auth = inventory._get_connection_info()
|
||||
assert (auth.username and auth.password)
|
||||
|
||||
|
||||
def test_populate_constructable_templating(inventory, mocker):
|
||||
# bypass API fetch call
|
||||
inventory._get_vm_pool = mocker.MagicMock(side_effect=get_vm_pool_json)
|
||||
inventory.get_option = mocker.MagicMock(side_effect=mk_get_options(options_constructable_test))
|
||||
|
||||
# the templating engine is needed for the constructable groups/vars
|
||||
# so give that some fake data and instantiate it.
|
||||
fake_config_filepath = '/fake/opennebula.yml'
|
||||
fake_cache = {fake_config_filepath: options_constructable_test.copy()}
|
||||
fake_cache[fake_config_filepath]['plugin'] = 'community.general.opennebula'
|
||||
dataloader = create_autospec(DataLoader, instance=True)
|
||||
dataloader._FILE_CACHE = fake_cache
|
||||
inventory.templar = Templar(loader=dataloader)
|
||||
|
||||
inventory._populate()
|
||||
|
||||
# note the vm_pool (and json data file) has four hosts,
|
||||
# but options_constructable_test asks ansible to filter it out
|
||||
assert len(get_vm_pool_json().VM) == 4
|
||||
assert set([vm.NAME for vm in get_vm_pool_json().VM]) == set([
|
||||
'terraform_demo_00',
|
||||
'terraform_demo_01',
|
||||
'terraform_demo_srv_00',
|
||||
'bs-windows',
|
||||
])
|
||||
assert set(inventory.inventory.hosts) == set(['terraform_demo_00', 'terraform_demo_01', 'terraform_demo_srv_00'])
|
||||
|
||||
host_demo00 = inventory.inventory.get_host('terraform_demo_00')
|
||||
host_demo01 = inventory.inventory.get_host('terraform_demo_01')
|
||||
host_demosrv = inventory.inventory.get_host('terraform_demo_srv_00')
|
||||
|
||||
assert 'benchmark_clients' in inventory.inventory.groups
|
||||
assert 'lin' in inventory.inventory.groups
|
||||
assert inventory.inventory.groups['benchmark_clients'].hosts == [host_demo00, host_demo01]
|
||||
assert inventory.inventory.groups['lin'].hosts == [host_demo00, host_demo01, host_demosrv]
|
||||
|
||||
# test group by label:
|
||||
assert 'bench' in inventory.inventory.groups
|
||||
assert 'foo' in inventory.inventory.groups
|
||||
assert inventory.inventory.groups['bench'].hosts == [host_demo00, host_demo01, host_demosrv]
|
||||
assert inventory.inventory.groups['serv'].hosts == [host_demosrv]
|
||||
assert inventory.inventory.groups['foo'].hosts == [host_demo00, host_demo01]
|
||||
|
||||
# test `compose` transforms GUEST_OS=Linux to is_linux == True
|
||||
assert host_demo00.get_vars()['GUEST_OS'] == 'linux'
|
||||
assert host_demo00.get_vars()['is_linux'] is True
|
||||
|
||||
# test `keyed_groups`
|
||||
assert inventory.inventory.groups['tgroup_bench_clients'].hosts == [host_demo00, host_demo01]
|
||||
assert inventory.inventory.groups['tgroup_bench_server'].hosts == [host_demosrv]
|
||||
|
||||
|
||||
def test_populate(inventory, mocker):
|
||||
# bypass API fetch call
|
||||
inventory._get_vm_pool = mocker.MagicMock(side_effect=get_vm_pool)
|
||||
inventory.get_option = mocker.MagicMock(side_effect=get_option)
|
||||
inventory.get_option = mocker.MagicMock(side_effect=mk_get_options(options_base_test))
|
||||
inventory._populate()
|
||||
|
||||
# get different hosts
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue