Added an insertbefore option.

This commit is contained in:
Yves Dorfsman 2013-02-10 23:46:06 -07:00 committed by Michael DeHaan
parent fa8e653011
commit 4de1b4e8a9

View file

@ -61,11 +61,20 @@ options:
default: EOF default: EOF
description: description:
- Used with C(state=present). If specified, the line will be inserted - Used with C(state=present). If specified, the line will be inserted
after the specified regular expression. Two special values are after the specified regular expression. A special value is
available; C(BOF) for inserting the line at the beginning of the available; C(EOF) for inserting the line at the end of the file.
file, and C(EOF) for inserting the line at the end of the file. choices: [ EOF, *regex* ]
choices: [ 'BOF', 'EOF', '*regex*' ]
default: EOF default: EOF
insertbefore:
required: false
default: BOF
description:
- Used with C(state=present). If specified, the line will be inserted
before the specified regular expression. A value is available;
C(BOF) for inserting the line at the beginning of the
file.
choices: [ BOF, *regex* ]
default: BOF
create: create:
required: false required: false
choices: [ yes, no ] choices: [ yes, no ]
@ -85,9 +94,10 @@ examples:
- code: "lineinfile: \\\"dest=/etc/sudoers state=present regexp='^%wheel' line ='%wheel ALL=(ALL) NOPASSWD: ALL'\\\"" - code: "lineinfile: \\\"dest=/etc/sudoers state=present regexp='^%wheel' line ='%wheel ALL=(ALL) NOPASSWD: ALL'\\\""
- code: 'lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel"' - code: 'lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel"'
- code: 'lineinfile: dest=/etc/httpd/conf/httpd.conf regexp="^Listen " insertafter="^#Listen " line="Listen 8080"' - code: 'lineinfile: dest=/etc/httpd/conf/httpd.conf regexp="^Listen " insertafter="^#Listen " line="Listen 8080"'
- code: 'lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"'
""" """
def present(module, dest, regexp, line, insertafter, create, backup): def present(module, dest, regexp, line, insertafter, insertbefore, create, backup):
if os.path.isdir(dest): if os.path.isdir(dest):
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest) module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
@ -107,18 +117,31 @@ def present(module, dest, regexp, line, insertafter, create, backup):
if not mre.search(line): if not mre.search(line):
module.fail_json(msg="usage error: line= doesn't match regexp (%s)" % regexp) module.fail_json(msg="usage error: line= doesn't match regexp (%s)" % regexp)
if insertafter in ('BOF', 'EOF'): if insertbefore and insertafter:
iare = None module.fail_json(msg="usage error: \"insertbefore\" and \"insertafter\" cannot be combined")
else:
iare = re.compile(insertafter)
if insertafter in ('BOF', 'EOF', False):
if insertbefore in ('BOF', False):
insre = None
else:
insre = re.compile(insertbefore)
else:
insre = re.compile(insertafter)
# index[0] is the line num where regexp has been found
# index[1] is the line num where insertafter/inserbefore has been found
index = [-1, -1] index = [-1, -1]
for lineno in range(0, len(lines)): for lineno in range(0, len(lines)):
if mre.search(lines[lineno]): if mre.search(lines[lineno]):
index[0] = lineno index[0] = lineno
elif iare is not None and iare.search(lines[lineno]): elif insre is not None and insre.search(lines[lineno]):
if insertafter:
# + 1 for the next line # + 1 for the next line
index[1] = lineno + 1 index[1] = lineno + 1
if insertbefore:
# + 1 for the previous line
index[1] = lineno
# Regexp matched a line in the file # Regexp matched a line in the file
if index[0] != -1: if index[0] != -1:
@ -130,16 +153,17 @@ def present(module, dest, regexp, line, insertafter, create, backup):
msg = 'line replaced' msg = 'line replaced'
changed = True changed = True
# Add it to the beginning of the file # Add it to the beginning of the file
elif insertafter == 'BOF': # we keep insertafter == 'BOF' for backwards compatibility, but it should be removed eventually
elif insertbefore == 'BOF' or insertafter == 'BOF':
lines.insert(0, line + os.linesep) lines.insert(0, line + os.linesep)
msg = 'line added' msg = 'line added'
changed = True changed = True
# Add it to the end of the file if requested or if insertafter= didn't match # Add it to the end of the file if requested or if insertafter=/insertbefore didn't match
elif insertafter == 'EOF' or index[1] == -1: elif insertafter == 'EOF' or index[1] == -1:
lines.append(line + os.linesep) lines.append(line + os.linesep)
msg = 'line added' msg = 'line added'
changed = True changed = True
# insertafter= matched # insertafter/insertbefore= matched
else: else:
lines.insert(index[1], line + os.linesep) lines.insert(index[1], line + os.linesep)
msg = 'line added' msg = 'line added'
@ -185,7 +209,8 @@ def main():
state=dict(default='present', choices=['absent', 'present']), state=dict(default='present', choices=['absent', 'present']),
regexp=dict(required=True), regexp=dict(required=True),
line=dict(aliases=['value']), line=dict(aliases=['value']),
insertafter=dict(default='EOF'), insertafter=dict(default=False),
insertbefore=dict(default=False),
create=dict(default=False, choices=BOOLEANS), create=dict(default=False, choices=BOOLEANS),
backup=dict(default=False, choices=BOOLEANS), backup=dict(default=False, choices=BOOLEANS),
), ),
@ -199,7 +224,7 @@ def main():
if 'line' not in params: if 'line' not in params:
module.fail_json(msg='line= is required with state=present') module.fail_json(msg='line= is required with state=present')
present(module, params['dest'], params['regexp'], params['line'], present(module, params['dest'], params['regexp'], params['line'],
params['insertafter'], create, backup) params['insertafter'], params['insertbefore'], create, backup)
else: else:
absent(module, params['dest'], params['regexp'], backup) absent(module, params['dest'], params['regexp'], backup)