Merge pull request #4380 from joshkehn/lineinfile_validate

Added validate option to lineinfile
This commit is contained in:
Michael DeHaan 2013-10-27 08:46:47 -07:00
commit 3778b39115
2 changed files with 47 additions and 3 deletions

View file

@ -107,6 +107,13 @@ options:
description:
- Create a backup file including the timestamp information so you can
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:
description:
- 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=/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):
@ -137,6 +147,15 @@ def write_changes(module,lines,dest):
f.writelines(lines)
f.close()
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):
@ -167,8 +186,6 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
lines = f.readlines()
f.close()
msg = ""
mre = re.compile(regexp)
if insertafter not in (None, 'BOF', 'EOF'):
@ -289,6 +306,7 @@ def main():
backrefs=dict(default=False, type='bool'),
create=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
validate=dict(default=None, type='str'),
),
mutually_exclusive=[['insertbefore', 'insertafter']],
add_file_common_args=True,

View file

@ -460,6 +460,32 @@ class TestRunner(unittest.TestCase):
idx = artifact.index('communication. Typically it is depicted as a lunch-box sized object with some')
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
os.unlink(sample)