Skip to content

Instantly share code, notes, and snippets.

@ageis
Created March 18, 2019 23:23
Show Gist options
  • Select an option

  • Save ageis/9a71a57c5c8e1011ec6cf273e345b45d to your computer and use it in GitHub Desktop.

Select an option

Save ageis/9a71a57c5c8e1011ec6cf273e345b45d to your computer and use it in GitHub Desktop.
INI lookup plugin with ConfigObj instead of ConfigParser
# (c) 2019 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 = """
lookup: ini_file
author: Kevin Gallagher <kevingallagher@gmail.com>
version_added: "2.0"
short_description: read data from a ini file
description:
- "This is a fork of the INI lookup which allows reading INI files that are without section headers."
options:
_terms:
description: The key(s) to look up
required: True
file:
description: Name of the file to load
default: ansible.ini
section:
default: global
description: section where to lookup for key.
encoding:
default: utf-8
description: Text encoding to use.
default:
description: return value if the key is not in the ini file
default: ''
"""
EXAMPLES = """
- debug: msg="User in integration is {{ lookup('ini_file', 'user section=integration file=users.ini') }}"
- debug:
msg: "{{ item }}"
with_ini_file:
- value[1-2]
- section: section1
- file: "lookup.ini"
"""
RETURN = """
_raw:
description:
- value(s) of the key(s) in the ini file
"""
import os
import re
from configobj import ConfigObj, ConfigObjError
from collections import MutableSequence
from io import StringIO
from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.module_utils._text import to_bytes, to_text
from ansible.plugins.lookup import LookupBase
def _parse_params(term):
'''Safely split parameter term to preserve spaces'''
keys = ['key', 'section', 'file', 'default', 'encoding']
params = {}
for k in keys:
params[k] = ''
thiskey = 'key'
for idp, phrase in enumerate(term.split()):
for k in keys:
if ('%s=' % k) in phrase:
thiskey = k
if idp == 0 or not params[thiskey]:
params[thiskey] = phrase
else:
params[thiskey] += ' ' + phrase
rparams = [params[x] for x in keys if params[x]]
return rparams
class LookupModule(LookupBase):
def get_value(self, key, section, dflt):
value = None
try:
value = self.cp[section][key]
except ConfigObjError:
return dflt
return value
def run(self, terms, variables=None, **kwargs):
ret = []
for term in terms:
params = _parse_params(term)
key = params[0]
paramvals = {
'file': 'ansible.ini',
'default': None,
'section': "renewalparams",
'encoding': 'utf-8'
}
try:
for param in params[1:]:
name, value = param.split('=')
if name not in paramvals:
raise AnsibleAssertionError('%s not in paramvals' % name)
paramvals[name] = value
except (ValueError, AssertionError) as e:
raise AnsibleError(e)
try:
self.cp = ConfigObj(paramvals['file'], encoding=paramvals['encoding'], file_error=True)
except (ConfigObjError, IOError) as e:
raise AnsibleError('Could not read "%s": %s' % (filename, e))
path = self.find_file_in_search_path(variables, 'files', paramvals['file'])
config = StringIO()
contents, show_data = self._loader._get_file_contents(path)
contents = to_text(contents, errors='surrogate_or_strict')
config.write(contents)
config.seek(0, os.SEEK_SET)
sec = self.cp[paramvals['section']]
var = sec[key]
if var is not None:
if isinstance(var, MutableSequence):
for v in var:
ret.append(v)
else:
ret.append(var)
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment