
    Vh-.                        d dl mZ dZdZdZd dlZd dlZd dlZd dlm	Z	 d dl
mZmZ d dlmZ d	 Zd
 Zd Zedk(  r e        yy)    )annotationsa  
---
module: replace
author: Evan Kaufman (@EvanK)
extends_documentation_fragment:
    - action_common_attributes
    - action_common_attributes.files
    - files
    - validate
attributes:
    check_mode:
        support: full
    diff_mode:
        support: full
    platform:
        platforms: posix
    safe_file_operations:
        support: full
    vault:
        support: none
short_description: Replace all instances of a particular string in a
                   file using a back-referenced regular expression
description:
  - This module will replace all instances of a pattern within a file.
  - It is up to the user to maintain idempotence by ensuring that the
    same pattern would never match any replacements made.
version_added: "1.6"
options:
  path:
    description:
      - The file to modify.
      - Before Ansible 2.3 this option was only usable as O(dest), O(destfile) and O(name).
    type: path
    required: true
    aliases: [ dest, destfile, name ]
  regexp:
    description:
      - The regular expression to look for in the contents of the file.
      - Uses Python regular expressions; see
        U(https://docs.python.org/3/library/re.html).
      - Uses MULTILINE mode, which means V(^) and V($) match the beginning
        and end of the file, as well as the beginning and end respectively
        of I(each line) of the file.
      - Does not use DOTALL, which means the V(.) special character matches
        any character I(except newlines). A common mistake is to assume that
        a negated character set like V([^#]) will also not match newlines.
      - In order to exclude newlines, they must be added to the set like V([^#\\n]).
      - Note that, as of Ansible 2.0, short form tasks should have any escape
        sequences backslash-escaped in order to prevent them being parsed
        as string literal escapes. See the examples.
    type: str
    required: true
  replace:
    description:
      - The string to replace regexp matches.
      - May contain backreferences that will get expanded with the regexp capture groups if the regexp matches.
      - If not set, matches are removed entirely.
      - Backreferences can be used ambiguously like V(\\1), or explicitly like V(\\g<1>).
    type: str
    default: ''
  after:
    description:
      - If specified, only content after this match will be replaced/removed.
      - Can be used in combination with O(before).
      - Uses Python regular expressions; see
        U(https://docs.python.org/3/library/re.html).
      - Uses DOTALL, which means the V(.) special character I(can match newlines).
      - Does not use MULTILINE, so V(^) and V($) will only match the beginning and end of the file.
    type: str
    version_added: "2.4"
  before:
    description:
      - If specified, only content before this match will be replaced/removed.
      - Can be used in combination with O(after).
      - Uses Python regular expressions; see
        U(https://docs.python.org/3/library/re.html).
      - Uses DOTALL, which means the V(.) special character I(can match newlines).
      - Does not use MULTILINE, so V(^) and V($) will only match the beginning and end of the file.
    type: str
    version_added: "2.4"
  backup:
    description:
      - Create a backup file including the timestamp information so you can
        get the original file back if you somehow clobbered it incorrectly.
    type: bool
    default: no
  encoding:
    description:
      - The character encoding for reading and writing the file.
    type: str
    default: utf-8
    version_added: "2.4"
notes:
  - As of Ansible 2.3, the O(dest) option has been changed to O(path) as default, but O(dest) still works as well.
  - As of Ansible 2.7.10, the combined use of O(before) and O(after) works properly. If you were relying on the
    previous incorrect behavior, you may be need to adjust your tasks.
    See U(https://github.com/ansible/ansible/issues/31354) for details.
  - Option O(ignore:follow) has been removed in Ansible 2.5, because this module modifies the contents of the file
    so O(ignore:follow=no) does not make sense.
a(	  
- name: Replace old hostname with new hostname (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/hosts
    regexp: '(\s+)old\.host\.name(\s+.*)?$'
    replace: '\1new.host.name\2'

- name: Replace after the expression till the end of the file (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/apache2/sites-available/default.conf
    after: 'NameVirtualHost [*]'
    regexp: '^(.+)$'
    replace: '# \1'

- name: Replace before the expression from the beginning of the file (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/apache2/sites-available/default.conf
    before: '# live site config'
    regexp: '^(.+)$'
    replace: '# \1'

# Prior to Ansible 2.7.10, using before and after in combination did the opposite of what was intended.
# see https://github.com/ansible/ansible/issues/31354 for details.
# Note (?m) which turns on MULTILINE mode so ^ matches any line's beginning
- name: Replace between the expressions (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/hosts
    after: '(?m)^<VirtualHost [*]>'
    before: '</VirtualHost>'
    regexp: '^(.+)$'
    replace: '# \1'

- name: Supports common file attributes
  ansible.builtin.replace:
    path: /home/jdoe/.ssh/known_hosts
    regexp: '^old\.host\.name[^\n]*\n'
    owner: jdoe
    group: jdoe
    mode: '0644'

- name: Supports a validate command
  ansible.builtin.replace:
    path: /etc/apache/ports
    regexp: '^(NameVirtualHost|Listen)\s+80\s*$'
    replace: '\1 127.0.0.1:8080'
    validate: '/usr/sbin/apache2ctl -f %s -t'

- name: Short form task (in ansible 2+) necessitates backslash-escaped sequences
  ansible.builtin.replace: path=/etc/hosts regexp='\\b(localhost)(\\d*)\\b' replace='\\1\\2.localdomain\\2 \\1\\2'

- name: Long form task does not
  ansible.builtin.replace:
    path: /etc/hosts
    regexp: '\b(localhost)(\d*)\b'
    replace: '\1\2.localdomain\2 \1\2'

- name: Explicitly specifying positional matched groups in replacement
  ansible.builtin.replace:
    path: /etc/ssh/sshd_config
    regexp: '^(ListenAddress[ ]+)[^\n]+$'
    replace: '\g<1>0.0.0.0'

- name: Explicitly specifying named matched groups
  ansible.builtin.replace:
    path: /etc/ssh/sshd_config
    regexp: '^(?P<dctv>ListenAddress[ ]+)(?P<host>[^\n]+)$'
    replace: '#\g<dctv>\g<host>\n\g<dctv>0.0.0.0'
#N)
format_exc)to_textto_bytes)AnsibleModulec                   t        j                  | j                        \  }}t        j                  |d      }|j                  |       |j                          | j                  j                  dd       }| }|rSd|vr| j                  d|z         | j                  ||z        \  }}	}
|dk(  }|dk7  r| j                  d|d	|
       |r"| j                  ||| j                  d
          y y )N)dirwbvalidatez%szvalidate must contain %%s: %s)msgr   zfailed to validate: rc:z error:unsafe_writes)r   )tempfilemkstemptmpdirosfdopenwritecloseparamsget	fail_jsonrun_commandatomic_move)modulecontentspathtmpfdtmpfilefr   validrcouterrs              G/home/dcms/DCMS/lib/python3.12/site-packages/ansible/modules/replace.pywrite_changesr&      s    %%&--8NE7
		%AGGHGGI}}  T2HLEx!@H!MN++Hw,>?S#a757"> ?7Do8VW     c                    | j                  | j                        }| j                  |d      r|r|dz  }d}|dz  }||fS )NFz and Tz,ownership, perms or SE linux context changed)load_file_common_argumentsr    set_file_attributes_if_different)r   changedmessage	file_argss       r%   check_file_attrsr.      sN    11&--@I..y%@wGAAGr'   c                 `   t        t        t        ddg d      t        dd      t        dd      t        d	      t        d	      t        d
d      t        d	      t        dd            dd      } | j                  }|d   }|d   }t        d      }d }t        |d   dd      |d<   t        |d   dd      |d<   t        |d   dd      |d<   t        |d   dd      |d<   t        j
                  j                  |      r| j                  dd|z         t        j
                  j                  |      s| j                  dd|z         n2	 t        |d      5 }t        |j                         d|      }d d d        d}|d   r|d   r|d   d#|d   }n|d   r	d$|d   z  }n|d   rd%|d   z  }|rt        j                  |t        j                         }	t        j"                  |	|      }
|
r4|
j%                  d&      }|
j'                  d&      |
j)                  d&      g}n"d'|z  |d(<   d|d)<    | j*                  d2i | n|}t        j                  |d   t        j,                        }	 t        j.                  ||d   d      }d+   dkD  rJ|d   k7  rB|r|d d    |d   z   ||d+   d  z   |d+   f}d,|d+   z  }d}| j2                  r||||d   d-|d.<   nd}d}|r~| j4                  sr|d/   r3t        j
                  j                  |      r| j7                  |      |d0<   t        j
                  j9                  |      }t;        | t=        |d   |1      |       t?        | ||      \  |d(<   |d)<    | j*                  d2i | y # 1 sw Y   xY w# t        t        f$ r5}| j                  d |d!t        |      t               "       Y d }~Wd }~ww xY w# t        j0                  $ r2}| j                  d*t        |      z  t               "       Y d }~d }~ww xY w)3Nr   T)destdestfilename)typerequiredaliasesstr)r3   r4    )r3   default)r3   boolFzutf-8)r   regexpreplaceafterbeforebackupr   encoding)argument_specadd_file_common_argssupports_check_moder?   r   )r"   r<   surrogate_or_strictpassthru)errors	nonstringr=   r:   r;      zPath %s is a directory !)r"   r   i  zPath %s does not exist !rb)rE   r?   zUnable to read the contents of z: )r   	exceptionz(?P<subsection>.*?)z%s(?P<subsection>.*)z(?P<subsection>.*)%s
subsectionz@Pattern for before/after params did not match the given file: %sr   r+   z*Unable to process replace due to error: %s   z%s replacements made)before_headerr=   after_headerr<   diffr>   backup_file)r?    ) r   dictr   r   r   r   isdirr   existsopenreadOSErrorIOErrorr   recompileDOTALLsearchgroupstartend	exit_json	MULTILINEsubnerror_diff
check_modebackup_localrealpathr&   r   r.   )r   r   r   r?   res_argsr   r    epattern
section_rematchsectionindicesmreresultr   r+   s                    r%   mainrp      s?   6D:VWUT2eR0E"U#VU3u%ug6	
 " F ]]F&>Dj!HqzHHfWo6KWabF7Ovh/8MYcdF8vh/8MYcdF8y 1:O[efF9	ww}}TC%?$%FG77>>$C%?$%FG	5dD! ^Q"16684IT\]^ Gg6(+06wAQR	)F7O;		)F8,<<ZZ3
		*h/kk,/G{{<0%))L2IJG`cjjHUO"'HYF(x(
**VH%r||
4C1fY/!<
 ay1}F1I-{
+fQi7(71:;:OOQWXYQZ[F$vay0<<!%" $	 HV v(((t 4&,&9&9$&?H]#ww%fhvay8DdK+;FGS+Q(HUOXi(F x u^ ^! 	5DRYZ[R\!]'1|  5 5	58 88 1IGTUJV#-< 	 	1 	11sH   N! $NN! :O( NN! !O%0*O  O%(P-;'P((P-__main__)
__future__r   DOCUMENTATIONEXAMPLESRETURNr   rX   r   	tracebackr   +ansible.module_utils.common.text.convertersr   r   ansible.module_utils.basicr   r&   r.   rp   __name__rP   r'   r%   <module>rz      s[    #cJCJ 
 	 	    I 4X*
\!~ zF r'   