Last active
July 28, 2022 00:05
-
-
Save domrim/e1003192418399db04c13afda3456263 to your computer and use it in GitHub Desktop.
Ansible lookup plugin for os dependent variable loading
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DOCUMENTATION = """ | |
lookup: variable_loader | |
author: Dominik Rimpf <[email protected]> | |
short_description: tries to find variable files dependent on node operating system | |
description: | |
- this lookup checks for files in 'role_path/vars/' and returns the full path to the first combination found. | |
notes: | |
- If no arguments are passed following default list is used: | |
- "{{ ansible_distribution }}_{{ ansible_distribution_major_version }}.yml" | |
- "{{ ansible_distribution }}.yml" | |
- "{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml" | |
- "{{ ansible_os_family }}.yml" | |
- File names can be passed seperately as strings or in a list. (Or both mixed) | |
options: | |
_terms: | |
description: list of file names (or file name) | |
files: | |
description: list of file names | |
""" | |
EXAMPLES = """ | |
- name: read vars form os-dependent variable file | |
include_vars: "{{ lookup('variable_loader') }}" | |
- name: read vars from first found given variable file in role_path | |
include_vars: "{{ lookup('first_found', params) }}" | |
vars: | |
params: | |
- '{{ ansible_os_distribution }}.yml' | |
- '{{ ansible_os_family }}.yml' | |
- default.yml | |
""" | |
RETURN = """ | |
_raw: | |
description: | |
- path to file found | |
""" | |
import os | |
from jinja2.exceptions import UndefinedError | |
from ansible.errors import AnsibleFileNotFound, AnsibleLookupError, AnsibleUndefinedVariable | |
from ansible.module_utils.six import string_types | |
from ansible.plugins.lookup import LookupBase | |
class LookupModule(LookupBase): | |
def run(self, terms, variables, **kwargs): | |
# Variablen aus dem Dict holen | |
search_path = os.path.join(variables["role_path"], "vars") | |
ansible_distribution = variables["ansible_distribution"] | |
ansible_distribution_major_version = variables["ansible_distribution_major_version"] | |
ansible_os_family = variables["ansible_os_family"] | |
# Dateinamen nach denen gesucht werden soll | |
if terms == []: | |
filenames = [ | |
f"{ansible_distribution}_{ansible_distribution_major_version}.yml", | |
f"{ansible_distribution}.yml", | |
f"{ansible_os_family}_{ansible_distribution_major_version}.yml", # Macht der Eintrag überhaupt Sinn? bei Ubuntu 18.04 würde das "Debian_18" rauskommen, das ist doch nicht Sinn der Sache? | |
f"{ansible_os_family}.yml" | |
] | |
else: | |
filenames = [] | |
for term in self._flatten(terms): | |
if isinstance(term, string_types): | |
filenames.append(term) | |
else: | |
raise AnsibleLookupError("Only strings or lists of strings are allowed as arguments") | |
self._display.vv(f"Searching for files {filenames} in {search_path}.") | |
total_search = [] | |
for fn in filenames: | |
f = os.path.join(search_path, fn) | |
total_search.append(f) | |
for fn in total_search: | |
path = None | |
path = self.find_file_in_search_path(variables, 'vars', fn, ignore_missing=True) | |
if path is not None: | |
self._display.vvv(f"Found {fn} at {path}") | |
return [path] | |
else: | |
self._display.vvvv(f"Did not find {fn}.") | |
raise AnsibleLookupError("No file was found. Use errors='ignore' to allow this task to be skipped if no files are found") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment