From 5bacb732ce5dbaa8e00bda186c74fb9e7c1c6e32 Mon Sep 17 00:00:00 2001 From: John R Barker Date: Wed, 31 Oct 2018 17:04:29 +0000 Subject: [PATCH] Backport/2.7/44324 Fixes #30599 ini_file module: Options within no section managed (#47741) * Addresses comments in #38971 (#44324) * Controlled params within no section * Added tests to control params within no section * Cleaning output_file before creating no-section params and check the content * addresses comment in PR "s/hate/beverage/g" (cherry picked from commit d3fe6c01f2f8d3ad317a4ed1429d4c42bd065dec) * 44324-ini_file --- ..._file-options-with-no-section-managed.yaml | 4 + lib/ansible/modules/files/ini_file.py | 16 ++- .../targets/ini_file/tasks/main.yml | 105 +++++++++++++++++- 3 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/44324-ini_file-options-with-no-section-managed.yaml diff --git a/changelogs/fragments/44324-ini_file-options-with-no-section-managed.yaml b/changelogs/fragments/44324-ini_file-options-with-no-section-managed.yaml new file mode 100644 index 00000000000..4c6e24ae94f --- /dev/null +++ b/changelogs/fragments/44324-ini_file-options-with-no-section-managed.yaml @@ -0,0 +1,4 @@ +--- +bugfixes: +- "ini_file: Options within no sections aren't included, deleted or modified. These are just unmanged. This pull request solves this. + (see https://github.com/ansible/ansible/pull/44324)" diff --git a/lib/ansible/modules/files/ini_file.py b/lib/ansible/modules/files/ini_file.py index 38f8d3fa78a..684a3cf0615 100644 --- a/lib/ansible/modules/files/ini_file.py +++ b/lib/ansible/modules/files/ini_file.py @@ -171,9 +171,22 @@ def do_ini(module, filename, section=None, option=None, value=None, ini_lines[-1] += '\n' changed = True - # append a fake section line to simplify the logic + # append fake section lines to simplify the logic + # At top: + # Fake random section to do not match any other in the file + # Using commit hash as fake section name + fake_section_name = "ad01e11446efb704fcdbdb21f2c43757423d91c5" + + # Insert it at the beginning + ini_lines.insert(0, '[%s]' % fake_section_name) + + # At botton: ini_lines.append('[') + # If no section is defined, fake section is used + if not section: + section = fake_section_name + within_section = not section section_start = 0 msg = 'OK' @@ -241,6 +254,7 @@ def do_ini(module, filename, section=None, option=None, value=None, break # remove the fake section line + del ini_lines[0] del ini_lines[-1:] if not within_section and option and state == 'present': diff --git a/test/integration/targets/ini_file/tasks/main.yml b/test/integration/targets/ini_file/tasks/main.yml index 2f3eb16919b..4c44d918d0f 100644 --- a/test/integration/targets/ini_file/tasks/main.yml +++ b/test/integration/targets/ini_file/tasks/main.yml @@ -61,11 +61,11 @@ - result2.changed == False - result2.msg == 'OK' -- name: Ensure "hate=coke" is in section "[drinks]" +- name: Ensure "beverage=coke" is in section "[drinks]" ini_file: path: "{{ output_file }}" section: drinks - option: hate + option: beverage value: coke register: result3 @@ -75,7 +75,7 @@ [drinks] fav = lemonade - hate = coke + beverage = coke content3: "{{ lookup('file', output_file) }}" - name: assert 'changed' is true and content is OK @@ -85,11 +85,11 @@ - result3.msg == 'option added' - content3 == expected3 -- name: Remove option "hate=coke" +- name: Remove option "beverage=coke" ini_file: path: "{{ output_file }}" section: drinks - option: hate + option: beverage state: absent register: result4 @@ -251,3 +251,98 @@ - result10.changed == True - result10.msg == 'option changed' - content10 == expected10 + +- name: Clean test file + copy: + content: "" + dest: "{{ output_file }}" + force: yes + +- name: Ensure "beverage=coke" is created within no section + ini_file: + section: + path: "{{ output_file }}" + option: beverage + value: coke + register: result11 + +- name: set expected content and get current ini file content + set_fact: + expected11: "beverage = coke" + content11: "{{ lookup('file', output_file) }}" + +- name: assert 'changed' is true and content is OK (no section) + assert: + that: + - result11 is changed + - result11.msg == 'option added' + - content11 == expected11 + +- name: Ensure "beverage=coke" is modified as "beverage=water" within no section + ini_file: + path: "{{ output_file }}" + option: beverage + value: water + section: + register: result12 + +- name: set expected content and get current ini file content + set_fact: + expected12: "beverage = water" + + content12: "{{ lookup('file', output_file) }}" + +- name: assert 'changed' is true and content is OK (no section) + assert: + that: + - result12 is changed + - result12.msg == 'option changed' + - content12 == expected12 + +- name: remove option 'beverage' within no section + ini_file: + section: + path: "{{ output_file }}" + option: beverage + state: absent + register: result13 + +- name: get current ini file content + set_fact: + content13: "{{ lookup('file', output_file) }}" + +- name: assert changed (no section) + assert: + that: + - result13 is changed + - result13.msg == 'option changed' + - content13 == "" + +- name: Check add option without section before existing section + block: + - name: Add option with section + ini_file: + path: "{{ output_file }}" + section: drinks + option: beverage + value: water + - name: Add option without section + ini_file: + path: "{{ output_file }}" + section: + option: like + value: tea + +- name: set expected content and get current ini file content + set_fact: + expected14: |- + like = tea + + [drinks] + beverage = water + content14: "{{ lookup('file', output_file) }}" + +- name: Verify content of ini file is as expected + assert: + that: + - content14 == expected14