Skip to content

Instantly share code, notes, and snippets.

@domrim
Last active July 28, 2022 00:05
Show Gist options
  • Save domrim/e1003192418399db04c13afda3456263 to your computer and use it in GitHub Desktop.
Save domrim/e1003192418399db04c13afda3456263 to your computer and use it in GitHub Desktop.
Ansible lookup plugin for os dependent variable loading
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