From c2968d6d84fb5aa66ae50d9df0bed963f22abbd8 Mon Sep 17 00:00:00 2001 From: Yannig Perre Date: Wed, 27 May 2015 21:51:20 +0200 Subject: [PATCH] New lookup plugin : ini. Can handle ini file and java properties file. Can also read a list of value in a section using regexp. --- lib/ansible/runner/lookup_plugins/ini.py | 92 +++++++++++++++++++++ test/integration/lookup.ini | 24 ++++++ test/integration/lookup.properties | 5 ++ test/integration/test_lookup_properties.yml | 29 +++++++ 4 files changed, 150 insertions(+) create mode 100644 lib/ansible/runner/lookup_plugins/ini.py create mode 100644 test/integration/lookup.ini create mode 100644 test/integration/lookup.properties create mode 100644 test/integration/test_lookup_properties.yml diff --git a/lib/ansible/runner/lookup_plugins/ini.py b/lib/ansible/runner/lookup_plugins/ini.py new file mode 100644 index 0000000000..002dda0908 --- /dev/null +++ b/lib/ansible/runner/lookup_plugins/ini.py @@ -0,0 +1,92 @@ +# (c) 2015, Yannig Perre +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +from ansible import utils, errors +import StringIO +import os +import codecs +import ConfigParser +import re + +class LookupModule(object): + + def __init__(self, basedir=None, **kwargs): + self.basedir = basedir + self.cp = ConfigParser.ConfigParser() + + def read_properties(self, filename, key, dflt, is_regexp): + config = StringIO.StringIO() + config.write('[java_properties]\n' + open(filename).read()) + config.seek(0, os.SEEK_SET) + self.cp.readfp(config) + return self.get_value(key, 'java_properties', dflt, is_regexp) + + def read_ini(self, filename, key, section, dflt, is_regexp): + self.cp.readfp(open(filename)) + return self.get_value(key, section, dflt, is_regexp) + + def get_value(self, key, section, dflt, is_regexp): + # Retrieve all values from a section using a regexp + if is_regexp: + return [v for k, v in self.cp.items(section) if re.match(key, k)] + # Retrieve a single value + value = self.cp.get(section, key) + if value == None: + return dflt + return value + + def run(self, terms, inject=None, **kwargs): + + terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject) + + if isinstance(terms, basestring): + terms = [ terms ] + + ret = [] + for term in terms: + params = term.split() + key = params[0] + + paramvals = { + 'file' : 'ansible.ini', + 're' : False, + 'default' : None, + 'section' : "global", + 'type' : "ini", + } + + # parameters specified? + try: + for param in params[1:]: + name, value = param.split('=') + assert(name in paramvals) + paramvals[name] = value + except (ValueError, AssertionError), e: + raise errors.AnsibleError(e) + + path = utils.path_dwim(self.basedir, paramvals['file']) + if paramvals['type'] == "properties": + var = self.read_properties(path, key, paramvals['default'], paramvals['re']) + else: + var = self.read_ini(path, key, paramvals['section'], paramvals['default'], paramvals['re']) + if var is not None: + if type(var) is list: + for v in var: + ret.append(v) + else: + ret.append(var) + return ret diff --git a/test/integration/lookup.ini b/test/integration/lookup.ini new file mode 100644 index 0000000000..ce0dbf8486 --- /dev/null +++ b/test/integration/lookup.ini @@ -0,0 +1,24 @@ +[global] +# A comment +value1=Text associated with value1 and global section +value2=Same for value2 and global section +value.dot=Properties with dot +field.with.space = another space + +[section1] +value1=Another value for section1 +# No value2 in this section + +[value_section] +value1=1 +value2=2 +value3=3 +other1=4 +other2=5 + +[other_section] +value1=1 +value2=2 +value3=3 +other1=4 +other2=5 diff --git a/test/integration/lookup.properties b/test/integration/lookup.properties new file mode 100644 index 0000000000..f388d8cfbf --- /dev/null +++ b/test/integration/lookup.properties @@ -0,0 +1,5 @@ +# A comment +value1=Text associated with value1 +value2=Same for value2 +value.dot=Properties with dot +field.with.space = another space diff --git a/test/integration/test_lookup_properties.yml b/test/integration/test_lookup_properties.yml new file mode 100644 index 0000000000..dcd5eb698b --- /dev/null +++ b/test/integration/test_lookup_properties.yml @@ -0,0 +1,29 @@ +--- +- name: "Lookup test" + hosts: "localhost" +# connection: local + tasks: + - name: "read properties value" + set_fact: + test1: "{{lookup('ini', 'value1 type=properties file=lookup.properties')}}" + test2: "{{lookup('ini', 'value2 type=properties file=lookup.properties')}}" + test_dot: "{{lookup('ini', 'value.dot type=properties file=lookup.properties')}}" + field_with_space: "{{lookup('ini', 'field.with.space type=properties file=lookup.properties')}}" + - debug: var={{item}} + with_items: [ 'test1', 'test2', 'test_dot', 'field_with_space' ] + - name: "read ini value" + set_fact: + value1_global: "{{lookup('ini', 'value1 section=global file=lookup.ini')}}" + value2_global: "{{lookup('ini', 'value2 section=global file=lookup.ini')}}" + value1_section1: "{{lookup('ini', 'value1 section=section1 file=lookup.ini')}}" + - debug: var={{item}} + with_items: [ 'value1_global', 'value2_global', 'value1_section1' ] + - name: "read ini value with section and regexp" + set_fact: + value_section: "{{lookup('ini', 'value[1-2] section=value_section file=lookup.ini re=true')}}" + other_section: "{{lookup('ini', 'other[1-2] section=other_section file=lookup.ini re=true')}}" + - debug: var={{item}} + with_items: [ 'value_section', 'other_section' ] + - name: "Reading unknown value" + set_fact: + value2_section2: "{{lookup('ini', 'value2 section=section1 file=lookup.ini')}}"