Server IP : 85.214.239.14 / Your IP : 18.216.167.229 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible/plugins/inventory/ |
Upload File : |
# 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: yaml version_added: "2.4" short_description: Uses a specific YAML file as an inventory source. description: - "YAML-based inventory, should start with the C(all) group and contain hosts/vars/children entries." - Host entries can have sub-entries defined, which will be treated as variables. - Vars entries are normal group vars. - "Children are 'child groups', which can also have their own vars/hosts/children and so on." - File MUST have a valid extension, defined in configuration. notes: - If you want to set vars for the C(all) group inside the inventory file, the C(all) group must be the first entry in the file. - Enabled in configuration by default. options: yaml_extensions: description: list of 'valid' extensions for files containing YAML type: list elements: string default: ['.yaml', '.yml', '.json'] env: - name: ANSIBLE_YAML_FILENAME_EXT - name: ANSIBLE_INVENTORY_PLUGIN_EXTS ini: - key: yaml_valid_extensions section: defaults - section: inventory_plugin_yaml key: yaml_valid_extensions ''' EXAMPLES = ''' all: # keys must be unique, i.e. only one 'hosts' per group hosts: test1: test2: host_var: value vars: group_all_var: value children: # key order does not matter, indentation does other_group: children: group_x: hosts: test5 # Note that one machine will work without a colon #group_x: # hosts: # test5 # But this won't # test7 # group_y: hosts: test6: # So always use a colon vars: g2_var2: value3 hosts: test4: ansible_host: 127.0.0.1 last_group: hosts: test1 # same host as above, additional group membership vars: group_last_var: value ''' import os from collections.abc import MutableMapping from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.six import string_types from ansible.module_utils._text import to_native, to_text from ansible.plugins.inventory import BaseFileInventoryPlugin NoneType = type(None) class InventoryModule(BaseFileInventoryPlugin): NAME = 'yaml' def __init__(self): super(InventoryModule, self).__init__() def verify_file(self, path): valid = False if super(InventoryModule, self).verify_file(path): file_name, ext = os.path.splitext(path) if not ext or ext in self.get_option('yaml_extensions'): valid = True return valid def parse(self, inventory, loader, path, cache=True): ''' parses the inventory file ''' super(InventoryModule, self).parse(inventory, loader, path) self.set_options() try: data = self.loader.load_from_file(path, cache=False) except Exception as e: raise AnsibleParserError(e) if not data: raise AnsibleParserError('Parsed empty YAML file') elif not isinstance(data, MutableMapping): raise AnsibleParserError('YAML inventory has invalid structure, it should be a dictionary, got: %s' % type(data)) elif data.get('plugin'): raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory') # We expect top level keys to correspond to groups, iterate over them # to get host, vars and subgroups (which we iterate over recursivelly) if isinstance(data, MutableMapping): for group_name in data: self._parse_group(group_name, data[group_name]) else: raise AnsibleParserError("Invalid data from file, expected dictionary and got:\n\n%s" % to_native(data)) def _parse_group(self, group, group_data): if isinstance(group_data, (MutableMapping, NoneType)): # type: ignore[misc] try: group = self.inventory.add_group(group) except AnsibleError as e: raise AnsibleParserError("Unable to add group %s: %s" % (group, to_text(e))) if group_data is not None: # make sure they are dicts for section in ['vars', 'children', 'hosts']: if section in group_data: # convert strings to dicts as these are allowed if isinstance(group_data[section], string_types): group_data[section] = {group_data[section]: None} if not isinstance(group_data[section], (MutableMapping, NoneType)): # type: ignore[misc] raise AnsibleParserError('Invalid "%s" entry for "%s" group, requires a dictionary, found "%s" instead.' % (section, group, type(group_data[section]))) for key in group_data: if not isinstance(group_data[key], (MutableMapping, NoneType)): # type: ignore[misc] self.display.warning('Skipping key (%s) in group (%s) as it is not a mapping, it is a %s' % (key, group, type(group_data[key]))) continue if isinstance(group_data[key], NoneType): # type: ignore[misc] self.display.vvv('Skipping empty key (%s) in group (%s)' % (key, group)) elif key == 'vars': for var in group_data[key]: self.inventory.set_variable(group, var, group_data[key][var]) elif key == 'children': for subgroup in group_data[key]: subgroup = self._parse_group(subgroup, group_data[key][subgroup]) self.inventory.add_child(group, subgroup) elif key == 'hosts': for host_pattern in group_data[key]: hosts, port = self._parse_host(host_pattern) self._populate_host_vars(hosts, group_data[key][host_pattern] or {}, group, port) else: self.display.warning('Skipping unexpected key (%s) in group (%s), only "vars", "children" and "hosts" are valid' % (key, group)) else: self.display.warning("Skipping '%s' as this is not a valid group definition" % group) return group def _parse_host(self, host_pattern): ''' Each host key can be a pattern, try to process it and add variables as needed ''' try: (hostnames, port) = self._expand_hostpattern(host_pattern) except TypeError: raise AnsibleParserError( f"Host pattern {host_pattern} must be a string. Enclose integers/floats in quotation marks." ) return hostnames, port