|
|
@ -58,6 +58,22 @@ options:
|
|
|
|
- The string to replace regexp matches. May contain backreferences
|
|
|
|
- The string to replace regexp matches. May contain backreferences
|
|
|
|
that will get expanded with the regexp capture groups if the regexp
|
|
|
|
that will get expanded with the regexp capture groups if the regexp
|
|
|
|
matches. If not set, matches are removed entirely.
|
|
|
|
matches. If not set, matches are removed entirely.
|
|
|
|
|
|
|
|
after:
|
|
|
|
|
|
|
|
required: false
|
|
|
|
|
|
|
|
version_added: "2.3"
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- If specified, the line after the replace/remove will start. Can be used
|
|
|
|
|
|
|
|
in combination with C(before).
|
|
|
|
|
|
|
|
Uses Python regular expressions; see
|
|
|
|
|
|
|
|
U(http://docs.python.org/2/library/re.html).
|
|
|
|
|
|
|
|
before:
|
|
|
|
|
|
|
|
required: false
|
|
|
|
|
|
|
|
version_added: "2.3"
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- If specified, the line before the replace/remove will occur. Can be used
|
|
|
|
|
|
|
|
in combination with C(after).
|
|
|
|
|
|
|
|
Uses Python regular expressions; see
|
|
|
|
|
|
|
|
U(http://docs.python.org/2/library/re.html).
|
|
|
|
backup:
|
|
|
|
backup:
|
|
|
|
required: false
|
|
|
|
required: false
|
|
|
|
default: "no"
|
|
|
|
default: "no"
|
|
|
@ -88,6 +104,31 @@ EXAMPLES = r"""
|
|
|
|
replace: '\1new.host.name\2'
|
|
|
|
replace: '\1new.host.name\2'
|
|
|
|
backup: yes
|
|
|
|
backup: yes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace after the expression till the end of the file
|
|
|
|
|
|
|
|
- replace:
|
|
|
|
|
|
|
|
path: /etc/hosts
|
|
|
|
|
|
|
|
regexp: '(\s+)old\.host\.name(\s+.*)?$'
|
|
|
|
|
|
|
|
replace: '\1new.host.name\2'
|
|
|
|
|
|
|
|
after: 'Start after line.*'
|
|
|
|
|
|
|
|
backup: yes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace before the expression till the begin of the file
|
|
|
|
|
|
|
|
- replace:
|
|
|
|
|
|
|
|
path: /etc/hosts
|
|
|
|
|
|
|
|
regexp: '(\s+)old\.host\.name(\s+.*)?$'
|
|
|
|
|
|
|
|
replace: '\1new.host.name\2'
|
|
|
|
|
|
|
|
before: 'Start before line.*'
|
|
|
|
|
|
|
|
backup: yes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace between the expressions
|
|
|
|
|
|
|
|
- replace:
|
|
|
|
|
|
|
|
path: /etc/hosts
|
|
|
|
|
|
|
|
regexp: '(\s+)old\.host\.name(\s+.*)?$'
|
|
|
|
|
|
|
|
replace: '\1new.host.name\2'
|
|
|
|
|
|
|
|
after: 'Start after line.*'
|
|
|
|
|
|
|
|
before: 'Start before line.*'
|
|
|
|
|
|
|
|
backup: yes
|
|
|
|
|
|
|
|
|
|
|
|
- replace:
|
|
|
|
- replace:
|
|
|
|
path: /home/jdoe/.ssh/known_hosts
|
|
|
|
path: /home/jdoe/.ssh/known_hosts
|
|
|
|
regexp: '^old\.host\.name[^\n]*\n'
|
|
|
|
regexp: '^old\.host\.name[^\n]*\n'
|
|
|
@ -130,6 +171,7 @@ def write_changes(module, contents, path):
|
|
|
|
if valid:
|
|
|
|
if valid:
|
|
|
|
module.atomic_move(tmpfile, path, unsafe_writes=module.params['unsafe_writes'])
|
|
|
|
module.atomic_move(tmpfile, path, unsafe_writes=module.params['unsafe_writes'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_file_attrs(module, changed, message):
|
|
|
|
def check_file_attrs(module, changed, message):
|
|
|
|
|
|
|
|
|
|
|
|
file_args = module.load_file_common_arguments(module.params)
|
|
|
|
file_args = module.load_file_common_arguments(module.params)
|
|
|
@ -142,12 +184,15 @@ def check_file_attrs(module, changed, message):
|
|
|
|
|
|
|
|
|
|
|
|
return message, changed
|
|
|
|
return message, changed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
def main():
|
|
|
|
module = AnsibleModule(
|
|
|
|
module = AnsibleModule(
|
|
|
|
argument_spec=dict(
|
|
|
|
argument_spec=dict(
|
|
|
|
path=dict(required=True, aliases=['dest', 'destfile', 'name'], type='path'),
|
|
|
|
path=dict(required=True, aliases=['dest', 'destfile', 'name'], type='path'),
|
|
|
|
regexp=dict(required=True),
|
|
|
|
regexp=dict(required=True),
|
|
|
|
replace=dict(default='', type='str'),
|
|
|
|
replace=dict(default='', type='str'),
|
|
|
|
|
|
|
|
after=dict(required=False),
|
|
|
|
|
|
|
|
before=dict(required=False),
|
|
|
|
backup=dict(default=False, type='bool'),
|
|
|
|
backup=dict(default=False, type='bool'),
|
|
|
|
validate=dict(default=None, type='str'),
|
|
|
|
validate=dict(default=None, type='str'),
|
|
|
|
),
|
|
|
|
),
|
|
|
@ -169,8 +214,28 @@ def main():
|
|
|
|
contents = to_text(f.read(), errors='surrogate_or_strict')
|
|
|
|
contents = to_text(f.read(), errors='surrogate_or_strict')
|
|
|
|
f.close()
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
mre = re.compile(params['regexp'], re.MULTILINE)
|
|
|
|
pattern = ''
|
|
|
|
result = re.subn(mre, params['replace'], contents, 0)
|
|
|
|
if params['after']:
|
|
|
|
|
|
|
|
pattern = '%s(.*)' % params['after']
|
|
|
|
|
|
|
|
elif params['before']:
|
|
|
|
|
|
|
|
pattern = '(.*)%s' % params['before']
|
|
|
|
|
|
|
|
elif params['after'] and params['before']:
|
|
|
|
|
|
|
|
pattern = '%s(.*?)%s' % (params['before'], params['after'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if pattern:
|
|
|
|
|
|
|
|
section_re = re.compile(pattern, re.DOTALL)
|
|
|
|
|
|
|
|
match = re.search(section_re, contents)
|
|
|
|
|
|
|
|
if match:
|
|
|
|
|
|
|
|
section = match.group(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mre = re.compile(params['regexp'], re.MULTILINE)
|
|
|
|
|
|
|
|
result = re.subn(mre, params['replace'], section, 0)
|
|
|
|
|
|
|
|
if result[1] > 0 and section != result[0]:
|
|
|
|
|
|
|
|
result = (contents.replace(section, result[0]), result[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
mre = re.compile(params['regexp'], re.MULTILINE)
|
|
|
|
|
|
|
|
result = re.subn(mre, params['replace'], contents, 0)
|
|
|
|
|
|
|
|
|
|
|
|
if result[1] > 0 and contents != result[0]:
|
|
|
|
if result[1] > 0 and contents != result[0]:
|
|
|
|
msg = '%s replacements made' % result[1]
|
|
|
|
msg = '%s replacements made' % result[1]
|
|
|
@ -196,5 +261,6 @@ def main():
|
|
|
|
res_args['msg'], res_args['changed'] = check_file_attrs(module, changed, msg)
|
|
|
|
res_args['msg'], res_args['changed'] = check_file_attrs(module, changed, msg)
|
|
|
|
module.exit_json(**res_args)
|
|
|
|
module.exit_json(**res_args)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|
|
|
|
main()
|
|
|
|