mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Added validate option to lineinfile
The validate option is constructed similarly to the template command's validate option. TestRunner.py has been updated to include two new tests, one for passing and one for failing validation.
This commit is contained in:
parent
ea73151757
commit
cc0c908cee
2 changed files with 47 additions and 3 deletions
|
@ -107,6 +107,13 @@ options:
|
||||||
description:
|
description:
|
||||||
- Create a backup file including the timestamp information so you can
|
- Create a backup file including the timestamp information so you can
|
||||||
get the original file back if you somehow clobbered it incorrectly.
|
get the original file back if you somehow clobbered it incorrectly.
|
||||||
|
validate:
|
||||||
|
required: false
|
||||||
|
description:
|
||||||
|
- validation to run before copying into place
|
||||||
|
required: false
|
||||||
|
default: None
|
||||||
|
version_added: "1.4"
|
||||||
others:
|
others:
|
||||||
description:
|
description:
|
||||||
- All arguments accepted by the M(file) module also work here.
|
- All arguments accepted by the M(file) module also work here.
|
||||||
|
@ -128,6 +135,9 @@ EXAMPLES = r"""
|
||||||
- lineinfile: "dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL'"
|
- lineinfile: "dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL'"
|
||||||
|
|
||||||
- lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\1Xms${xms}m\3' backrefs=yes
|
- lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\1Xms${xms}m\3' backrefs=yes
|
||||||
|
|
||||||
|
# Validate a the sudoers file before saving
|
||||||
|
- lineinfile: dest=/etc/sudoers state=present regexp='^%ADMIN ALL\=' line='%ADMIN ALL=(ALL) NOPASSWD:ALL' validate='visudo -cf %s'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def write_changes(module,lines,dest):
|
def write_changes(module,lines,dest):
|
||||||
|
@ -137,7 +147,16 @@ def write_changes(module,lines,dest):
|
||||||
f.writelines(lines)
|
f.writelines(lines)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
module.atomic_move(tmpfile, dest)
|
validate = module.params.get('validate', None)
|
||||||
|
valid = not validate
|
||||||
|
if validate:
|
||||||
|
(rc, out, err) = module.run_command(validate % tmpfile)
|
||||||
|
valid = rc == 0
|
||||||
|
if rc != 0:
|
||||||
|
module.fail_json(msg='failed to validate: '
|
||||||
|
'rc:%s error:%s' % (rc,err))
|
||||||
|
if valid:
|
||||||
|
module.atomic_move(tmpfile, dest)
|
||||||
|
|
||||||
def check_file_attrs(module, changed, message):
|
def check_file_attrs(module, changed, message):
|
||||||
|
|
||||||
|
@ -167,8 +186,6 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
msg = ""
|
|
||||||
|
|
||||||
mre = re.compile(regexp)
|
mre = re.compile(regexp)
|
||||||
|
|
||||||
if insertafter not in (None, 'BOF', 'EOF'):
|
if insertafter not in (None, 'BOF', 'EOF'):
|
||||||
|
@ -289,6 +306,7 @@ def main():
|
||||||
backrefs=dict(default=False, type='bool'),
|
backrefs=dict(default=False, type='bool'),
|
||||||
create=dict(default=False, type='bool'),
|
create=dict(default=False, type='bool'),
|
||||||
backup=dict(default=False, type='bool'),
|
backup=dict(default=False, type='bool'),
|
||||||
|
validate=dict(default=None, type='str'),
|
||||||
),
|
),
|
||||||
mutually_exclusive=[['insertbefore', 'insertafter']],
|
mutually_exclusive=[['insertbefore', 'insertafter']],
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
|
|
|
@ -460,6 +460,32 @@ class TestRunner(unittest.TestCase):
|
||||||
idx = artifact.index('communication. Typically it is depicted as a lunch-box sized object with some')
|
idx = artifact.index('communication. Typically it is depicted as a lunch-box sized object with some')
|
||||||
assert artifact[idx - 1] == testline
|
assert artifact[idx - 1] == testline
|
||||||
|
|
||||||
|
# Testing validate
|
||||||
|
testline = 'Tenth: Testing with validate'
|
||||||
|
testcase = ('lineinfile', [
|
||||||
|
"dest=%s" % sample,
|
||||||
|
"regexp='^Tenth: '",
|
||||||
|
"line='%s'" % testline,
|
||||||
|
"validate='grep -q Tenth %s'",
|
||||||
|
])
|
||||||
|
result = self._run(*testcase)
|
||||||
|
assert result['changed'], "File wasn't changed when it should have been"
|
||||||
|
assert result['msg'] == 'line added', "msg was incorrect"
|
||||||
|
artifact = [ x.strip() for x in open(sample) ]
|
||||||
|
assert artifact[-1] == testline
|
||||||
|
|
||||||
|
|
||||||
|
# Testing validate
|
||||||
|
testline = '#11: Testing with validate'
|
||||||
|
testcase = ('lineinfile', [
|
||||||
|
"dest=%s" % sample,
|
||||||
|
"regexp='^#11: '",
|
||||||
|
"line='%s'" % testline,
|
||||||
|
"validate='grep -q #12# %s'",
|
||||||
|
])
|
||||||
|
result = self._run(*testcase)
|
||||||
|
assert result['failed']
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
os.unlink(sample)
|
os.unlink(sample)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue