|
|
|
@ -61,11 +61,20 @@ options:
|
|
|
|
|
default: EOF
|
|
|
|
|
description:
|
|
|
|
|
- Used with C(state=present). If specified, the line will be inserted
|
|
|
|
|
after the specified regular expression. Two special values are
|
|
|
|
|
available; C(BOF) for inserting the line at the beginning of the
|
|
|
|
|
file, and C(EOF) for inserting the line at the end of the file.
|
|
|
|
|
choices: [ 'BOF', 'EOF', '*regex*' ]
|
|
|
|
|
after the specified regular expression. A special value is
|
|
|
|
|
available; C(EOF) for inserting the line at the end of the file.
|
|
|
|
|
choices: [ EOF, *regex* ]
|
|
|
|
|
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:
|
|
|
|
|
required: false
|
|
|
|
|
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=absent regexp="^%wheel"'
|
|
|
|
|
- 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):
|
|
|
|
|
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):
|
|
|
|
|
module.fail_json(msg="usage error: line= doesn't match regexp (%s)" % regexp)
|
|
|
|
|
|
|
|
|
|
if insertafter in ('BOF', 'EOF'):
|
|
|
|
|
iare = None
|
|
|
|
|
if insertbefore and insertafter:
|
|
|
|
|
module.fail_json(msg="usage error: \"insertbefore\" and \"insertafter\" cannot be combined")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if insertafter in ('BOF', 'EOF', False):
|
|
|
|
|
if insertbefore in ('BOF', False):
|
|
|
|
|
insre = None
|
|
|
|
|
else:
|
|
|
|
|
insre = re.compile(insertbefore)
|
|
|
|
|
else:
|
|
|
|
|
iare = re.compile(insertafter)
|
|
|
|
|
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]
|
|
|
|
|
for lineno in range(0, len(lines)):
|
|
|
|
|
if mre.search(lines[lineno]):
|
|
|
|
|
index[0] = lineno
|
|
|
|
|
elif iare is not None and iare.search(lines[lineno]):
|
|
|
|
|
# + 1 for the next line
|
|
|
|
|
index[1] = lineno + 1
|
|
|
|
|
elif insre is not None and insre.search(lines[lineno]):
|
|
|
|
|
if insertafter:
|
|
|
|
|
# + 1 for the next line
|
|
|
|
|
index[1] = lineno + 1
|
|
|
|
|
if insertbefore:
|
|
|
|
|
# + 1 for the previous line
|
|
|
|
|
index[1] = lineno
|
|
|
|
|
|
|
|
|
|
# Regexp matched a line in the file
|
|
|
|
|
if index[0] != -1:
|
|
|
|
@ -130,16 +153,17 @@ def present(module, dest, regexp, line, insertafter, create, backup):
|
|
|
|
|
msg = 'line replaced'
|
|
|
|
|
changed = True
|
|
|
|
|
# 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)
|
|
|
|
|
msg = 'line added'
|
|
|
|
|
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:
|
|
|
|
|
lines.append(line + os.linesep)
|
|
|
|
|
msg = 'line added'
|
|
|
|
|
changed = True
|
|
|
|
|
# insertafter= matched
|
|
|
|
|
# insertafter/insertbefore= matched
|
|
|
|
|
else:
|
|
|
|
|
lines.insert(index[1], line + os.linesep)
|
|
|
|
|
msg = 'line added'
|
|
|
|
@ -185,7 +209,8 @@ def main():
|
|
|
|
|
state=dict(default='present', choices=['absent', 'present']),
|
|
|
|
|
regexp=dict(required=True),
|
|
|
|
|
line=dict(aliases=['value']),
|
|
|
|
|
insertafter=dict(default='EOF'),
|
|
|
|
|
insertafter=dict(default=False),
|
|
|
|
|
insertbefore=dict(default=False),
|
|
|
|
|
create=dict(default=False, choices=BOOLEANS),
|
|
|
|
|
backup=dict(default=False, choices=BOOLEANS),
|
|
|
|
|
),
|
|
|
|
@ -199,7 +224,7 @@ def main():
|
|
|
|
|
if 'line' not in params:
|
|
|
|
|
module.fail_json(msg='line= is required with state=present')
|
|
|
|
|
present(module, params['dest'], params['regexp'], params['line'],
|
|
|
|
|
params['insertafter'], create, backup)
|
|
|
|
|
params['insertafter'], params['insertbefore'], create, backup)
|
|
|
|
|
else:
|
|
|
|
|
absent(module, params['dest'], params['regexp'], backup)
|
|
|
|
|
|
|
|
|
|