Merge "Allow default section in ini to be specified"
This commit is contained in:
commit
c7b39fa597
@ -72,6 +72,7 @@ class MultiKeyDict(dict):
|
||||
>>> print(z)
|
||||
... {'a': tuple(['1', '2']), 'c': {'a': 1}, 'b': ['a', 'b', 'c']}
|
||||
"""
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key in self:
|
||||
if isinstance(self[key], tuple):
|
||||
@ -134,9 +135,11 @@ class ConfigTemplateParser(ConfigParser.RawConfigParser):
|
||||
key = var3
|
||||
key = var2
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._comments = {}
|
||||
self.ignore_none_type = bool(kwargs.pop('ignore_none_type', True))
|
||||
self.default_section = str(kwargs.pop('default_section', 'DEFAULT'))
|
||||
ConfigParser.RawConfigParser.__init__(self, *args, **kwargs)
|
||||
|
||||
def _write(self, fp, section, key, item, entry):
|
||||
@ -165,28 +168,33 @@ class ConfigTemplateParser(ConfigParser.RawConfigParser):
|
||||
self._write(fp, section, key, value, entry)
|
||||
|
||||
def write(self, fp):
|
||||
def _do_write(section_name, section, section_bool=False):
|
||||
_write_comments(section_name)
|
||||
fp.write("[%s]\n" % section_name)
|
||||
for key, value in sorted(section.items()):
|
||||
_write_comments(section_name, optname=key)
|
||||
self._write_check(fp, key=key, value=value,
|
||||
section=section_bool)
|
||||
else:
|
||||
fp.write("\n")
|
||||
|
||||
def _write_comments(section, optname=None):
|
||||
comsect = self._comments.get(section, {})
|
||||
if optname in comsect:
|
||||
fp.write(''.join(comsect[optname]))
|
||||
|
||||
if self.default_section != 'DEFAULT' and self._sections.get(
|
||||
self.default_section, False):
|
||||
_do_write(self.default_section,
|
||||
self._sections[self.default_section],
|
||||
section_bool=True)
|
||||
self._sections.pop(self.default_section)
|
||||
|
||||
if self._defaults:
|
||||
_write_comments('DEFAULT')
|
||||
fp.write("[%s]\n" % 'DEFAULT')
|
||||
for key, value in sorted(self._defaults.items()):
|
||||
_write_comments('DEFAULT', optname=key)
|
||||
self._write_check(fp, key=key, value=value)
|
||||
else:
|
||||
fp.write("\n")
|
||||
_do_write('DEFAULT', self._defaults)
|
||||
|
||||
for section in sorted(self._sections):
|
||||
_write_comments(section)
|
||||
fp.write("[%s]\n" % section)
|
||||
for key, value in sorted(self._sections[section].items()):
|
||||
_write_comments(section, optname=key)
|
||||
self._write_check(fp, key=key, value=value, section=True)
|
||||
else:
|
||||
fp.write("\n")
|
||||
_do_write(section, self._sections[section], section_bool=True)
|
||||
|
||||
def _read(self, fp, fpname):
|
||||
comments = []
|
||||
@ -293,7 +301,8 @@ class ActionModule(ActionBase):
|
||||
config_overrides,
|
||||
resultant,
|
||||
list_extend=True,
|
||||
ignore_none_type=True):
|
||||
ignore_none_type=True,
|
||||
default_section='DEFAULT'):
|
||||
"""Returns string value from a modified config file.
|
||||
|
||||
:param config_overrides: ``dict``
|
||||
@ -307,7 +316,8 @@ class ActionModule(ActionBase):
|
||||
config = ConfigTemplateParser(
|
||||
allow_no_value=True,
|
||||
dict_type=MultiKeyDict,
|
||||
ignore_none_type=ignore_none_type
|
||||
ignore_none_type=ignore_none_type,
|
||||
default_section=default_section
|
||||
)
|
||||
config.optionxform = str
|
||||
except Exception:
|
||||
@ -376,7 +386,8 @@ class ActionModule(ActionBase):
|
||||
config_overrides,
|
||||
resultant,
|
||||
list_extend=True,
|
||||
ignore_none_type=True):
|
||||
ignore_none_type=True,
|
||||
default_section='DEFAULT'):
|
||||
"""Returns config json
|
||||
|
||||
Its important to note that file ordering will not be preserved as the
|
||||
@ -390,7 +401,8 @@ class ActionModule(ActionBase):
|
||||
merged_resultant = self._merge_dict(
|
||||
base_items=original_resultant,
|
||||
new_items=config_overrides,
|
||||
list_extend=list_extend
|
||||
list_extend=list_extend,
|
||||
default_section=default_section
|
||||
)
|
||||
return json.dumps(
|
||||
merged_resultant,
|
||||
@ -402,7 +414,8 @@ class ActionModule(ActionBase):
|
||||
config_overrides,
|
||||
resultant,
|
||||
list_extend=True,
|
||||
ignore_none_type=True):
|
||||
ignore_none_type=True,
|
||||
default_section='DEFAULT'):
|
||||
"""Return config yaml.
|
||||
|
||||
:param config_overrides: ``dict``
|
||||
@ -537,6 +550,8 @@ class ActionModule(ActionBase):
|
||||
# name with out the '=' or ':' suffix. The default is true.
|
||||
ignore_none_type = self._task.args.get('ignore_none_type', True)
|
||||
|
||||
default_section = self._task.args.get('default_section', 'DEFAULT')
|
||||
|
||||
return True, dict(
|
||||
source=source,
|
||||
dest=user_dest,
|
||||
@ -544,7 +559,8 @@ class ActionModule(ActionBase):
|
||||
config_type=config_type,
|
||||
searchpath=searchpath,
|
||||
list_extend=list_extend,
|
||||
ignore_none_type=ignore_none_type
|
||||
ignore_none_type=ignore_none_type,
|
||||
default_section=default_section
|
||||
)
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
@ -618,7 +634,8 @@ class ActionModule(ActionBase):
|
||||
config_overrides=_vars['config_overrides'],
|
||||
resultant=resultant,
|
||||
list_extend=_vars.get('list_extend', True),
|
||||
ignore_none_type=_vars.get('ignore_none_type', True)
|
||||
ignore_none_type=_vars.get('ignore_none_type', True),
|
||||
default_section=_vars.get('default_section', 'DEFAULT')
|
||||
)
|
||||
|
||||
# Re-template the resultant object as it may have new data within it
|
||||
@ -651,6 +668,7 @@ class ActionModule(ActionBase):
|
||||
new_module_args.pop('config_type', None)
|
||||
new_module_args.pop('list_extend', None)
|
||||
new_module_args.pop('ignore_none_type', None)
|
||||
new_module_args.pop('default_section', None)
|
||||
# Content from config_template is converted to src
|
||||
new_module_args.pop('content', None)
|
||||
|
||||
@ -663,7 +681,7 @@ class ActionModule(ActionBase):
|
||||
if self._play_context.diff:
|
||||
rc['diff'] = []
|
||||
rc['diff'].append(self._get_diff_data(_vars['dest'],
|
||||
transferred_data, task_vars))
|
||||
transferred_data, task_vars))
|
||||
if self._task.args.get('content'):
|
||||
os.remove(_vars['source'])
|
||||
return rc
|
||||
|
@ -58,6 +58,12 @@ options:
|
||||
choices:
|
||||
- True
|
||||
- False
|
||||
default_section:
|
||||
description:
|
||||
- Specify the default section for INI configuration files. This is the
|
||||
section that will appear at the top of the configuration file. For
|
||||
example 'global'.
|
||||
default: 'DEFAULT'
|
||||
|
||||
author: Kevin Carter
|
||||
"""
|
||||
@ -68,6 +74,7 @@ EXAMPLES = """
|
||||
src: templates/test.ini.j2
|
||||
dest: /tmp/test.ini
|
||||
config_overrides: {}
|
||||
top_ini_section: 'global'
|
||||
config_type: ini
|
||||
|
||||
- name: run config template json
|
||||
|
5
releasenotes/notes/top_ini_section-c28d7acadf5fe836.yaml
Normal file
5
releasenotes/notes/top_ini_section-c28d7acadf5fe836.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- Allow the default section in an ini file to be specified
|
||||
using the ``default_section`` variable when calling a
|
||||
``config_template`` task. This defaults to ``DEFAULT``.
|
8
tests/files/test_default_section.ini.expected
Normal file
8
tests/files/test_default_section.ini.expected
Normal file
@ -0,0 +1,8 @@
|
||||
[global]
|
||||
test1 = 1
|
||||
test2 = 2
|
||||
|
||||
[section1]
|
||||
setting1 = 1
|
||||
setting2 = 2
|
||||
|
5
tests/templates/test_default_section.ini
Normal file
5
tests/templates/test_default_section.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[section1]
|
||||
setting1=1
|
||||
|
||||
[global]
|
||||
test1=1
|
@ -215,6 +215,21 @@
|
||||
- [ 0, 1, 2 ]
|
||||
- [ "{{ test_config_ini_overrides }}" ]
|
||||
|
||||
- name: Put down default_section_expected file
|
||||
copy:
|
||||
src: "{{ playbook_dir }}/files/test_default_section.ini.expected"
|
||||
dest: "/tmp/test_default_section.ini"
|
||||
|
||||
- name: Template using default_section
|
||||
config_template:
|
||||
src: "{{ playbook_dir }}/templates/test_default_section.ini"
|
||||
dest: "/tmp/test_default_section.ini"
|
||||
config_type: "ini"
|
||||
config_overrides: "{{ test_default_section_overrides }}"
|
||||
default_section: "global"
|
||||
register: template_changed
|
||||
failed_when: template_changed | changed
|
||||
|
||||
vars:
|
||||
test_config_ini_overrides:
|
||||
DEFAULT:
|
||||
@ -259,3 +274,8 @@
|
||||
- 4
|
||||
test_config_yml_hostvars_overrides:
|
||||
test_hostvar: "{{ ansible_default_ipv4.address }}"
|
||||
test_default_section_overrides:
|
||||
global:
|
||||
test2: 2
|
||||
section1:
|
||||
setting2: 2
|
||||
|
Loading…
x
Reference in New Issue
Block a user