lineinfile - add search_string parameter for non-regexp searching (#70647)
* Add tests for search_string * Improve examples * Add changelog
This commit is contained in:
parent
9a9272305a
commit
69631da889
8 changed files with 579 additions and 19 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- lineinfile - add search_string parameter for non-regexp searching (https://github.com/ansible/ansible/issues/70470)
|
|
@ -44,6 +44,17 @@ options:
|
|||
type: str
|
||||
aliases: [ regex ]
|
||||
version_added: '1.7'
|
||||
search_string:
|
||||
description:
|
||||
- The literal string to look for in every line of the file. This does not have to match the entire line.
|
||||
- For C(state=present), the line to replace if the string is found in the file. Only the last line found will be replaced.
|
||||
- For C(state=absent), the line(s) to remove if the string is in the line.
|
||||
- If the literal expression is not matched, the line will be
|
||||
added to the file in keeping with C(insertbefore) or C(insertafter)
|
||||
settings.
|
||||
- Mutually exclusive with C(backrefs) and C(regexp).
|
||||
type: str
|
||||
version_added: '2.11'
|
||||
state:
|
||||
description:
|
||||
- Whether the line should be there or not.
|
||||
|
@ -68,6 +79,7 @@ options:
|
|||
does not match anywhere in the file, the file will be left unchanged.
|
||||
- If the C(regexp) does match, the last matching line will be replaced by
|
||||
the expanded line parameter.
|
||||
- Mutually exclusive with C(search_string).
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "1.1"
|
||||
|
@ -136,6 +148,7 @@ seealso:
|
|||
author:
|
||||
- Daniel Hokka Zakrissoni (@dhozac)
|
||||
- Ahti Kitsik (@ahtik)
|
||||
- Jose Angel Munoz (@imjoseangel)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
|
@ -161,6 +174,15 @@ EXAMPLES = r'''
|
|||
group: root
|
||||
mode: '0644'
|
||||
|
||||
- name: Replace a localhost entry searching for a literal string to avoid escaping
|
||||
lineinfile:
|
||||
path: /etc/hosts
|
||||
search_string: '127.0.0.1'
|
||||
line: 127.0.0.1 localhost
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
- name: Ensure the default Apache port is 8080
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/httpd/conf/httpd.conf
|
||||
|
@ -168,6 +190,13 @@ EXAMPLES = r'''
|
|||
insertafter: '^#Listen '
|
||||
line: Listen 8080
|
||||
|
||||
- name: Ensure php extension matches new pattern
|
||||
lineinfile:
|
||||
path: /etc/httpd/conf/httpd.conf
|
||||
search_string: '<FilesMatch ".php[45]?$">'
|
||||
insertafter: '^\t<Location \/>\n'
|
||||
line: ' <FilesMatch ".php[34]?$">'
|
||||
|
||||
- name: Ensure we have our own comment added to /etc/services
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/services
|
||||
|
@ -253,7 +282,7 @@ def check_file_attrs(module, changed, message, diff):
|
|||
return message, changed
|
||||
|
||||
|
||||
def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||
def present(module, dest, regexp, search_string, line, insertafter, insertbefore, create,
|
||||
backup, backrefs, firstmatch):
|
||||
|
||||
diff = {'before': '',
|
||||
|
@ -301,8 +330,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
|||
# "If regular expressions are passed to both regexp and
|
||||
# insertafter, insertafter is only honored if no match for regexp is found."
|
||||
# Therefore:
|
||||
# 1. regexp was found -> ignore insertafter, replace the founded line
|
||||
# 2. regexp was not found -> insert the line after 'insertafter' or 'insertbefore' line
|
||||
# 1. regexp or search_string was found -> ignore insertafter, replace the founded line
|
||||
# 2. regexp or search_string was not found -> insert the line after 'insertafter' or 'insertbefore' line
|
||||
|
||||
# Given the above:
|
||||
# 1. First check that there is no match for regexp:
|
||||
|
@ -315,7 +344,17 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
|||
if firstmatch:
|
||||
break
|
||||
|
||||
# 2. When no match found on the previous step,
|
||||
# 2. Second check that there is no match for search_string:
|
||||
if search_string is not None:
|
||||
for lineno, b_cur_line in enumerate(b_lines):
|
||||
match_found = to_bytes(search_string, errors='surrogate_or_strict') in b_cur_line
|
||||
if match_found:
|
||||
index[0] = lineno
|
||||
match = match_found
|
||||
if firstmatch:
|
||||
break
|
||||
|
||||
# 3. When no match found on the previous step,
|
||||
# parse for searching insertafter/insertbefore:
|
||||
if not match:
|
||||
for lineno, b_cur_line in enumerate(b_lines):
|
||||
|
@ -350,9 +389,9 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
|||
if not b_new_line.endswith(b_linesep):
|
||||
b_new_line += b_linesep
|
||||
|
||||
# If no regexp was given and no line match is found anywhere in the file,
|
||||
# If no regexp or search_string was given and no line match is found anywhere in the file,
|
||||
# insert the line appropriately if using insertbefore or insertafter
|
||||
if regexp is None and match is None and not exact_line_match:
|
||||
if (regexp, search_string, match) == (None, None, None) and not exact_line_match:
|
||||
|
||||
# Insert lines
|
||||
if insertafter and insertafter != 'EOF':
|
||||
|
@ -428,7 +467,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
|||
msg = 'line added'
|
||||
changed = True
|
||||
|
||||
# insert matched, but not the regexp
|
||||
# insert matched, but not the regexp or search_string
|
||||
else:
|
||||
b_lines.insert(index[1], b_line + b_linesep)
|
||||
msg = 'line added'
|
||||
|
@ -456,7 +495,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
|||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist)
|
||||
|
||||
|
||||
def absent(module, dest, regexp, line, backup):
|
||||
def absent(module, dest, regexp, search_string, line, backup):
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
if not os.path.exists(b_dest):
|
||||
|
@ -483,6 +522,8 @@ def absent(module, dest, regexp, line, backup):
|
|||
def matcher(b_cur_line):
|
||||
if regexp is not None:
|
||||
match_found = bre_c.search(b_cur_line)
|
||||
elif search_string is not None:
|
||||
match_found = to_bytes(search_string, errors='surrogate_or_strict') in b_cur_line
|
||||
else:
|
||||
match_found = b_line == b_cur_line.rstrip(b'\r\n')
|
||||
if match_found:
|
||||
|
@ -521,6 +562,7 @@ def main():
|
|||
path=dict(type='path', required=True, aliases=['dest', 'destfile', 'name']),
|
||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||
regexp=dict(type='str', aliases=['regex']),
|
||||
search_string=dict(type='str'),
|
||||
line=dict(type='str', aliases=['value']),
|
||||
insertafter=dict(type='str'),
|
||||
insertbefore=dict(type='str'),
|
||||
|
@ -530,7 +572,8 @@ def main():
|
|||
firstmatch=dict(type='bool', default=False),
|
||||
validate=dict(type='str'),
|
||||
),
|
||||
mutually_exclusive=[['insertbefore', 'insertafter']],
|
||||
mutually_exclusive=[
|
||||
['insertbefore', 'insertafter'], ['regexp', 'search_string'], ['backrefs', 'search_string']],
|
||||
add_file_common_args=True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
@ -542,13 +585,17 @@ def main():
|
|||
path = params['path']
|
||||
firstmatch = params['firstmatch']
|
||||
regexp = params['regexp']
|
||||
search_string = params['search_string']
|
||||
line = params['line']
|
||||
|
||||
if regexp == '':
|
||||
module.warn(
|
||||
"The regular expression is an empty string, which will match every line in the file. "
|
||||
"This may have unintended consequences, such as replacing the last line in the file rather than appending. "
|
||||
"If this is desired, use '^' to match every line in the file and avoid this warning.")
|
||||
if '' in [regexp, search_string]:
|
||||
msg = ("The %s is an empty string, which will match every line in the file. "
|
||||
"This may have unintended consequences, such as replacing the last line in the file rather than appending.")
|
||||
param_name = 'search string'
|
||||
if regexp == '':
|
||||
param_name = 'regular expression'
|
||||
msg += " If this is desired, use '^' to match every line in the file and avoid this warning."
|
||||
module.warn(msg % param_name)
|
||||
|
||||
b_path = to_bytes(path, errors='surrogate_or_strict')
|
||||
if os.path.isdir(b_path):
|
||||
|
@ -567,13 +614,13 @@ def main():
|
|||
if ins_bef is None and ins_aft is None:
|
||||
ins_aft = 'EOF'
|
||||
|
||||
present(module, path, regexp, line,
|
||||
present(module, path, regexp, search_string, line,
|
||||
ins_aft, ins_bef, create, backup, backrefs, firstmatch)
|
||||
else:
|
||||
if regexp is None and line is None:
|
||||
module.fail_json(msg='one of line or regexp is required with state=absent')
|
||||
if (regexp, search_string, line) == (None, None, None):
|
||||
module.fail_json(msg='one of line, search_string, or regexp is required with state=absent')
|
||||
|
||||
absent(module, path, regexp, line, backup)
|
||||
absent(module, path, regexp, search_string, line, backup)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[section_one]
|
||||
|
||||
[section_two]
|
||||
|
||||
[section_three]
|
5
test/integration/targets/lineinfile/files/teststring.txt
Normal file
5
test/integration/targets/lineinfile/files/teststring.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
This is line 1
|
||||
This is line 2
|
||||
(\\w)(\\s+)([\\.,])
|
||||
This is line 4
|
||||
<FilesMatch ".py[45]?$">
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
case "`uname`" in
|
||||
Darwin*) if [ -z "$JAVA_HOME" ] ; then
|
|
@ -253,6 +253,8 @@
|
|||
that:
|
||||
- "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'"
|
||||
|
||||
- import_tasks: test_string01.yml
|
||||
|
||||
- name: use create=yes
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/new_test.txt"
|
||||
|
@ -806,7 +808,8 @@
|
|||
- oneline_insbefore_test2 is not changed
|
||||
- oneline_insbefore_file.stat.checksum == '4dca56d05a21f0d018cd311f43e134e4501cf6d9'
|
||||
|
||||
###################################################################
|
||||
- import_tasks: test_string02.yml
|
||||
|
||||
# Issue 29443
|
||||
# When using an empty regexp, replace the last line (since it matches every line)
|
||||
# but also provide a warning.
|
||||
|
@ -848,6 +851,49 @@
|
|||
This may have unintended consequences, such as replacing the last line in the file rather than appending.
|
||||
If this is desired, use '^' to match every line in the file and avoid this warning.
|
||||
|
||||
###################################################################
|
||||
# When using an empty search string, replace the last line (since it matches every line)
|
||||
# but also provide a warning.
|
||||
|
||||
- name: Deploy the test file for lineinfile
|
||||
copy:
|
||||
src: teststring.txt
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: Assert that the test file was deployed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.checksum == '481c2b73fe062390afdd294063a4f8285d69ac85'
|
||||
- result.state == 'file'
|
||||
|
||||
- name: Insert a line in the file using an empty string as a search string
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
search_string: ''
|
||||
line: This is line 6
|
||||
register: insert_empty_literal
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file contents match what is expected and a warning was displayed
|
||||
assert:
|
||||
that:
|
||||
- insert_empty_literal is changed
|
||||
- warning_message in insert_empty_literal.warnings
|
||||
- result.stat.checksum == 'eaa79f878557d4bd8d96787a850526a0facab342'
|
||||
vars:
|
||||
warning_message: >-
|
||||
The search string is an empty string, which will match every line in the file.
|
||||
This may have unintended consequences, such as replacing the last line in the file rather than appending.
|
||||
|
||||
- name: meta
|
||||
meta: end_play
|
||||
|
||||
###################################################################
|
||||
## Issue #58923
|
||||
## Using firstmatch with insertafter and ensure multiple lines are not inserted
|
||||
|
@ -1126,6 +1172,120 @@
|
|||
- insertbefore_test5 is not changed
|
||||
- insertbefore_test5_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7'
|
||||
|
||||
########################################################################################
|
||||
# Same tests for literal
|
||||
|
||||
# Test insertafter with literal
|
||||
- name: Deploy the test file
|
||||
copy:
|
||||
src: teststring_58923.txt
|
||||
dest: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: initial_file
|
||||
|
||||
- name: Assert that the test file was deployed
|
||||
assert:
|
||||
that:
|
||||
- initial_file is changed
|
||||
- initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e'
|
||||
- initial_file.state == 'file'
|
||||
|
||||
# Regarding the documentation:
|
||||
# If the search string is passed to both search_string and
|
||||
# insertafter, insertafter is only honored if no match for search_string is found.
|
||||
# Therefore,
|
||||
# when search_string expressions are passed to both search_string and insertafter, then:
|
||||
# 1. search_string was found -> ignore insertafter, replace the founded line
|
||||
# 2. search_string was not found -> insert the line after 'insertafter' line
|
||||
|
||||
# literal is not present in the file, so the line must be inserted after ^#!/bin/sh
|
||||
- name: Add the line using firstmatch, regexp, and insertafter
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
insertafter: '^#!/bin/sh'
|
||||
search_string: export FISHEYE_OPTS
|
||||
firstmatch: true
|
||||
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
|
||||
register: insertafter_test1
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: insertafter_test1_file
|
||||
|
||||
- name: Add the line using firstmatch, literal, and insertafter again
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
insertafter: '^#!/bin/sh'
|
||||
search_string: export FISHEYE_OPTS
|
||||
firstmatch: true
|
||||
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
|
||||
register: insertafter_test2
|
||||
|
||||
# Check of the prev step.
|
||||
# We tried to add the same line with the same playbook,
|
||||
# so nothing has been added:
|
||||
- name: Stat the file again
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: insertafter_test2_file
|
||||
|
||||
- name: Assert insertafter tests gave the expected results
|
||||
assert:
|
||||
that:
|
||||
- insertafter_test1 is changed
|
||||
- insertafter_test1_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08'
|
||||
- insertafter_test2 is not changed
|
||||
- insertafter_test2_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08'
|
||||
|
||||
# Test insertbefore with literal
|
||||
- name: Deploy the test file
|
||||
copy:
|
||||
src: teststring_58923.txt
|
||||
dest: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: initial_file
|
||||
|
||||
- name: Assert that the test file was deployed
|
||||
assert:
|
||||
that:
|
||||
- initial_file is changed
|
||||
- initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e'
|
||||
- initial_file.state == 'file'
|
||||
|
||||
- name: Add the line using literal, firstmatch, and insertbefore
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
insertbefore: '^#!/bin/sh'
|
||||
search_string: export FISHEYE_OPTS
|
||||
firstmatch: true
|
||||
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
|
||||
register: insertbefore_test1
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: insertbefore_test1_file
|
||||
|
||||
- name: Add the line using literal, firstmatch, and insertbefore again
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
insertbefore: '^#!/bin/sh'
|
||||
search_string: export FISHEYE_OPTS
|
||||
firstmatch: true
|
||||
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
|
||||
register: insertbefore_test2
|
||||
|
||||
- name: Stat the file again
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring_58923.txt"
|
||||
register: insertbefore_test2_file
|
||||
|
||||
- name: Assert insertbefore with literal tests gave the expected results
|
||||
assert:
|
||||
that:
|
||||
- insertbefore_test1 is changed
|
||||
- insertbefore_test1_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7'
|
||||
- insertbefore_test2 is not changed
|
||||
- insertbefore_test2_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7'
|
||||
|
||||
# Test inserting a line at the end of the file using regexp with insertafter
|
||||
# https://github.com/ansible/ansible/issues/63684
|
||||
|
@ -1155,3 +1315,32 @@
|
|||
- testend1 is changed
|
||||
- testend2 is changed
|
||||
- testend_file.stat.checksum == 'ef36116966836ce04f6b249fd1837706acae4e19'
|
||||
|
||||
# Test inserting a line at the end of the file using search_string with insertafter
|
||||
|
||||
- name: Create a file by inserting a line
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/testendliteral.txt"
|
||||
create: yes
|
||||
line: testline
|
||||
register: testend1
|
||||
|
||||
- name: Insert a line at the end of the file
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/testendliteral.txt"
|
||||
insertafter: testline
|
||||
search_string: line at the end
|
||||
line: line at the end
|
||||
register: testend2
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/testendliteral.txt"
|
||||
register: testend_file
|
||||
|
||||
- name: Assert inserting at the end gave the expected results.
|
||||
assert:
|
||||
that:
|
||||
- testend1 is changed
|
||||
- testend2 is changed
|
||||
- testend_file.stat.checksum == 'ef36116966836ce04f6b249fd1837706acae4e19'
|
||||
|
|
142
test/integration/targets/lineinfile/tasks/test_string01.yml
Normal file
142
test/integration/targets/lineinfile/tasks/test_string01.yml
Normal file
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
###################################################################
|
||||
# 1st search_string tests
|
||||
|
||||
- name: deploy the test file for lineinfile string
|
||||
copy:
|
||||
src: teststring.txt
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: assert that the test file was deployed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- "result.checksum == '481c2b73fe062390afdd294063a4f8285d69ac85'"
|
||||
- "result.state == 'file'"
|
||||
|
||||
- name: insert a line at the beginning of the file, and back it up
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: present
|
||||
line: "New line at the beginning"
|
||||
insertbefore: "BOF"
|
||||
backup: yes
|
||||
register: result1
|
||||
|
||||
- name: insert a line at the beginning of the file again
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: present
|
||||
line: "New line at the beginning"
|
||||
insertbefore: "BOF"
|
||||
register: result2
|
||||
|
||||
- name: Replace a line using string
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: present
|
||||
line: "Thi$ i^ [ine 3"
|
||||
search_string: (\\w)(\\s+)([\\.,])
|
||||
register: backrefs_result1
|
||||
|
||||
- name: Replace a line again using string
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: present
|
||||
line: "Thi$ i^ [ine 3"
|
||||
search_string: (\\w)(\\s+)([\\.,])
|
||||
register: backrefs_result2
|
||||
|
||||
- command: cat {{ output_dir }}/teststring.txt
|
||||
|
||||
- name: assert that the line with backrefs was changed
|
||||
assert:
|
||||
that:
|
||||
- backrefs_result1 is changed
|
||||
- backrefs_result2 is not changed
|
||||
- "backrefs_result1.msg == 'line replaced'"
|
||||
|
||||
- name: stat the test after the backref line was replaced
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: assert test checksum matches after backref line was replaced
|
||||
assert:
|
||||
that:
|
||||
- "result.stat.checksum == '8084519b53e268920a46592a112297715951f167'"
|
||||
|
||||
- name: remove the middle line using string
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: absent
|
||||
search_string: "Thi$ i^ [ine 3"
|
||||
register: result
|
||||
|
||||
- name: assert that the line was removed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- "result.msg == '1 line(s) removed'"
|
||||
|
||||
- name: stat the test after the middle line was removed
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: assert test checksum matches after the middle line was removed
|
||||
assert:
|
||||
that:
|
||||
- "result.stat.checksum == '89919ef2ef91e48ad02e0ca2bcb76dfc2a86d516'"
|
||||
|
||||
- name: run a validation script that succeeds using string
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: absent
|
||||
search_string: <FilesMatch ".py[45]?$">
|
||||
validate: "true %s"
|
||||
register: result
|
||||
|
||||
- name: assert that the file validated after removing a line
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- "result.msg == '1 line(s) removed'"
|
||||
|
||||
- name: stat the test after the validation succeeded
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: assert test checksum matches after the validation succeeded
|
||||
assert:
|
||||
that:
|
||||
- "result.stat.checksum == 'ba9600b34febbc88bfb3ca99cd6b57f1010c19a4'"
|
||||
|
||||
- name: run a validation script that fails using string
|
||||
lineinfile:
|
||||
dest: "{{ output_dir }}/teststring.txt"
|
||||
state: absent
|
||||
search_string: "This is line 1"
|
||||
validate: "/bin/false %s"
|
||||
register: result
|
||||
ignore_errors: yes
|
||||
|
||||
- name: assert that the validate failed
|
||||
assert:
|
||||
that:
|
||||
- "result.failed == true"
|
||||
|
||||
- name: stat the test after the validation failed
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.txt"
|
||||
register: result
|
||||
|
||||
- name: assert test checksum matches the previous after the validation failed
|
||||
assert:
|
||||
that:
|
||||
- "result.stat.checksum == 'ba9600b34febbc88bfb3ca99cd6b57f1010c19a4'"
|
||||
|
||||
# End of string tests
|
||||
###################################################################
|
166
test/integration/targets/lineinfile/tasks/test_string02.yml
Normal file
166
test/integration/targets/lineinfile/tasks/test_string02.yml
Normal file
|
@ -0,0 +1,166 @@
|
|||
---
|
||||
###################################################################
|
||||
# 2nd search_string tests
|
||||
|
||||
- name: Deploy the teststring.conf file
|
||||
copy:
|
||||
src: teststring.conf
|
||||
dest: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the teststring.conf file was deployed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38'
|
||||
- result.state == 'file'
|
||||
|
||||
# Test instertafter
|
||||
- name: Insert lines after with string
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
search_string: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
insertafter: "{{ item.after }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_5
|
||||
|
||||
- name: Do the same thing again and check for changes
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
search_string: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
insertafter: "{{ item.after }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_6
|
||||
|
||||
- name: Assert that the file was changed the first time but not the second time
|
||||
assert:
|
||||
that:
|
||||
- item.0 is changed
|
||||
- item.1 is not changed
|
||||
with_together:
|
||||
- "{{ _multitest_5.results }}"
|
||||
- "{{ _multitest_6.results }}"
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file contents match what is expected
|
||||
assert:
|
||||
that:
|
||||
- result.stat.checksum == '06e2c456e5028dd7bcd0b117b5927a1139458c82'
|
||||
|
||||
- name: Do the same thing a third time without string and check for changes
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
line: "{{ item.line }}"
|
||||
insertafter: "{{ item.after }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_7
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file was changed when no string was provided
|
||||
assert:
|
||||
that:
|
||||
- item is not changed
|
||||
with_items: "{{ _multitest_7.results }}"
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file contents match what is expected
|
||||
assert:
|
||||
that:
|
||||
- result.stat.checksum == '06e2c456e5028dd7bcd0b117b5927a1139458c82'
|
||||
|
||||
# Test insertbefore
|
||||
- name: Deploy the test.conf file
|
||||
copy:
|
||||
src: teststring.conf
|
||||
dest: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the teststring.conf file was deployed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38'
|
||||
- result.state == 'file'
|
||||
|
||||
- name: Insert lines before with string
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
search_string: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
insertbefore: "{{ item.before }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_8
|
||||
|
||||
- name: Do the same thing again and check for changes
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
search_string: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
insertbefore: "{{ item.before }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_9
|
||||
|
||||
- name: Assert that the file was changed the first time but not the second time
|
||||
assert:
|
||||
that:
|
||||
- item.0 is changed
|
||||
- item.1 is not changed
|
||||
with_together:
|
||||
- "{{ _multitest_8.results }}"
|
||||
- "{{ _multitest_9.results }}"
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file contents match what is expected
|
||||
assert:
|
||||
that:
|
||||
- result.stat.checksum == 'c3be9438a07c44d4c256cebfcdbca15a15b1db91'
|
||||
|
||||
- name: Do the same thing a third time without string and check for changes
|
||||
lineinfile:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
line: "{{ item.line }}"
|
||||
insertbefore: "{{ item.before }}"
|
||||
with_items: "{{ test_befaf_regexp }}"
|
||||
register: _multitest_10
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file was changed when no string was provided
|
||||
assert:
|
||||
that:
|
||||
- item is not changed
|
||||
with_items: "{{ _multitest_10.results }}"
|
||||
|
||||
- name: Stat the file
|
||||
stat:
|
||||
path: "{{ output_dir }}/teststring.conf"
|
||||
register: result
|
||||
|
||||
- name: Assert that the file contents match what is expected
|
||||
assert:
|
||||
that:
|
||||
- result.stat.checksum == 'c3be9438a07c44d4c256cebfcdbca15a15b1db91'
|
||||
|
||||
# End of string tests
|
||||
###################################################################
|
Loading…
Reference in a new issue