Enable autoloading of inventory plugins (#32709)
* Automatically loads and executes an inventory plugin specified by a standard YAML inventory config file containing a `plugin` key at its root. * Moved inventory PluginLoader to a shared global instance.
This commit is contained in:
parent
abc4210a33
commit
5ff36c3423
5 changed files with 67 additions and 5 deletions
|
@ -29,7 +29,7 @@ from ansible.module_utils._text import to_native
|
|||
from ansible.module_utils.six import string_types
|
||||
from ansible.parsing.yaml.dumper import AnsibleDumper
|
||||
from ansible.plugins.loader import module_loader, action_loader, lookup_loader, callback_loader, cache_loader, \
|
||||
vars_loader, connection_loader, strategy_loader, PluginLoader
|
||||
vars_loader, connection_loader, strategy_loader, inventory_loader
|
||||
from ansible.utils import plugin_docs
|
||||
try:
|
||||
from __main__ import display
|
||||
|
@ -97,7 +97,7 @@ class DocCLI(CLI):
|
|||
elif plugin_type == 'vars':
|
||||
loader = vars_loader
|
||||
elif plugin_type == 'inventory':
|
||||
loader = PluginLoader('InventoryModule', 'ansible.plugins.inventory', C.DEFAULT_INVENTORY_PLUGIN_PATH, 'inventory_plugins')
|
||||
loader = inventory_loader
|
||||
else:
|
||||
loader = module_loader
|
||||
|
||||
|
|
|
@ -1239,7 +1239,7 @@ HOST_KEY_CHECKING:
|
|||
type: boolean
|
||||
INVENTORY_ENABLED:
|
||||
name: Active Inventory plugins
|
||||
default: ['host_list', 'script', 'yaml', 'ini']
|
||||
default: ['host_list', 'script', 'yaml', 'ini', 'auto']
|
||||
description: List of enabled inventory plugins, it also determines the order in which they are used.
|
||||
env: [{name: ANSIBLE_INVENTORY_ENABLED}]
|
||||
ini:
|
||||
|
|
|
@ -30,7 +30,7 @@ from ansible.inventory.data import InventoryData
|
|||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.parsing.utils.addresses import parse_address
|
||||
from ansible.plugins.loader import PluginLoader
|
||||
from ansible.plugins.loader import inventory_loader
|
||||
from ansible.utils.path import unfrackpath
|
||||
|
||||
try:
|
||||
|
@ -178,7 +178,6 @@ class InventoryManager(object):
|
|||
def _setup_inventory_plugins(self):
|
||||
''' sets up loaded inventory plugins for usage '''
|
||||
|
||||
inventory_loader = PluginLoader('InventoryModule', 'ansible.plugins.inventory', C.DEFAULT_INVENTORY_PLUGIN_PATH, 'inventory_plugins')
|
||||
display.vvvv('setting up inventory plugins')
|
||||
|
||||
for name in C.INVENTORY_ENABLED:
|
||||
|
|
56
lib/ansible/plugins/inventory/auto.py
Normal file
56
lib/ansible/plugins/inventory/auto.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Copyright (c) 2017 Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
name: auto
|
||||
plugin_type: inventory
|
||||
authors:
|
||||
- Matt Davis <@nitzmahone>
|
||||
short_description: Loads and executes an inventory plugin specified in a YAML config
|
||||
description:
|
||||
- By whitelisting C(auto) as the final inventory plugin, any YAML inventory config file with a
|
||||
C(plugin) key at its root will automatically cause the named plugin to be loaded and executed with that
|
||||
config. This effectively provides automatic whitelisting of all installed/accessible inventory plugins.
|
||||
- To disable this behavior, remove C(auto) from the C(INVENTORY_ENABLED) config element.
|
||||
options:
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# This plugin is not intended for direct use; it is a fallback mechanism for automatic whitelisting of
|
||||
# all installed inventory plugins.
|
||||
'''
|
||||
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.plugins.loader import inventory_loader
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin):
|
||||
|
||||
NAME = 'auto'
|
||||
|
||||
def verify_file(self, path):
|
||||
if not path.endswith('.yml') and not path.endswith('.yaml'):
|
||||
return False
|
||||
return super(InventoryModule, self).verify_file(path)
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
config_data = loader.load_from_file(path)
|
||||
|
||||
plugin_name = config_data.get('plugin')
|
||||
|
||||
if not plugin_name:
|
||||
raise AnsibleParserError("no root 'plugin' key found, '{0}' is not a valid YAML inventory plugin config file".format(path))
|
||||
|
||||
plugin = inventory_loader.get(plugin_name)
|
||||
|
||||
if not plugin:
|
||||
raise AnsibleParserError("inventory config '{0}' specifies unknown plugin '{1}'".format(path, plugin_name))
|
||||
|
||||
if not plugin.verify_file(path):
|
||||
raise AnsibleParserError("inventory config '{0}' could not be verified by plugin '{1}'".format(path, plugin_name))
|
||||
|
||||
plugin.parse(inventory, loader, path, cache=cache)
|
|
@ -582,3 +582,10 @@ netconf_loader = PluginLoader(
|
|||
'netconf_plugins',
|
||||
required_base_class='NetconfBase'
|
||||
)
|
||||
|
||||
inventory_loader = PluginLoader(
|
||||
'InventoryModule',
|
||||
'ansible.plugins.inventory',
|
||||
C.DEFAULT_INVENTORY_PLUGIN_PATH,
|
||||
'inventory_plugins'
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue