B
    `V                 @   s   d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlmZ d dlmZmZmZmZ d dlmZ d d	lmZ g Zd
d Zdd Zd"ddZd#ddZd$ddZd%ddZd&ddZd'ddZd(ddZdd  Z e!d!k re   dS ))    )absolute_importdivisionprint_functiona  
---
module: mysql_replication
short_description: Manage MySQL replication
description:
- Manages MySQL server replication, replica, master status, get and change master host.
author:
- Balazs Pocze (@banyek)
- Andrew Klychkov (@Andersson007)
options:
  mode:
    description:
    - Module operating mode. Could be
      C(changemaster) (CHANGE MASTER TO),
      C(getmaster) (SHOW MASTER STATUS),
      C(getreplica | getslave) (SHOW REPLICA | SLAVE STATUS),
      C(startreplica | startslave) (START REPLICA | SLAVE),
      C(stopreplica | stopslave) (STOP REPLICA | SLAVE),
      C(resetmaster) (RESET MASTER) - supported since community.mysql 0.1.0,
      C(resetreplica, resetslave) (RESET REPLICA | SLAVE),
      C(resetreplicaall, resetslave) (RESET REPLICA | SLAVE ALL).
    type: str
    choices:
    - changemaster
    - getmaster
    - getreplica
    - getslave
    - startreplica
    - startslave
    - stopreplica
    - stopslave
    - resetmaster
    - resetreplica
    - resetslave
    - resetreplicaall
    - resetslaveall
    default: getreplica
  master_host:
    description:
    - Same as mysql variable.
    type: str
  master_user:
    description:
    - Same as mysql variable.
    type: str
  master_password:
    description:
    - Same as mysql variable.
    type: str
  master_port:
    description:
    - Same as mysql variable.
    type: int
  master_connect_retry:
    description:
    - Same as mysql variable.
    type: int
  master_log_file:
    description:
    - Same as mysql variable.
    type: str
  master_log_pos:
    description:
    - Same as mysql variable.
    type: int
  relay_log_file:
    description:
    - Same as mysql variable.
    type: str
  relay_log_pos:
    description:
    - Same as mysql variable.
    type: int
  master_ssl:
    description:
    - Same as mysql variable.
    type: bool
    default: false
  master_ssl_ca:
    description:
    - Same as mysql variable.
    type: str
  master_ssl_capath:
    description:
    - Same as mysql variable.
    type: str
  master_ssl_cert:
    description:
    - Same as mysql variable.
    type: str
  master_ssl_key:
    description:
    - Same as mysql variable.
    type: str
  master_ssl_cipher:
    description:
    - Same as mysql variable.
    type: str
  master_auto_position:
    description:
    - Whether the host uses GTID based replication or not.
    type: bool
    default: false
  master_use_gtid:
    description:
    - Configures the replica to use the MariaDB Global Transaction ID.
    - C(disabled) equals MASTER_USE_GTID=no command.
    - To find information about available values see
      U(https://mariadb.com/kb/en/library/change-master-to/#master_use_gtid).
    - Available since MariaDB 10.0.2.
    - C(replica_pos) has been introduced in MariaDB 10.5.1 and
      it is an alias for C(slave_pos).
    choices: [current_pos, replica_pos, slave_pos, disabled]
    type: str
    version_added: '0.1.0'
  master_delay:
    description:
    - Time lag behind the master's state (in seconds).
    - Available from MySQL 5.6.
    - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/replication-delayed.html).
    type: int
    version_added: '0.1.0'
  connection_name:
    description:
    - Name of the master connection.
    - Supported from MariaDB 10.0.1.
    - Mutually exclusive with I(channel).
    - For more information see U(https://mariadb.com/kb/en/library/multi-source-replication/).
    type: str
    version_added: '0.1.0'
  channel:
    description:
    - Name of replication channel.
    - Multi-source replication is supported from MySQL 5.7.
    - Mutually exclusive with I(connection_name).
    - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/replication-multi-source.html).
    type: str
    version_added: '0.1.0'
  fail_on_error:
    description:
    - Fails on error when calling mysql.
    type: bool
    default: False
    version_added: '0.1.0'

notes:
- If an empty value for the parameter of string type is needed, use an empty string.

extends_documentation_fragment:
- community.mysql.mysql


seealso:
- module: community.mysql.mysql_info
- name: MySQL replication reference
  description: Complete reference of the MySQL replication documentation.
  link: https://dev.mysql.com/doc/refman/8.0/en/replication.html
- name: MariaDB replication reference
  description: Complete reference of the MariaDB replication documentation.
  link: https://mariadb.com/kb/en/library/setting-up-replication/
a  
- name: Stop mysql replica thread
  community.mysql.mysql_replication:
    mode: stopreplica

- name: Get master binlog file name and binlog position
  community.mysql.mysql_replication:
    mode: getmaster

- name: Change master to master server 192.0.2.1 and use binary log 'mysql-bin.000009' with position 4578
  community.mysql.mysql_replication:
    mode: changemaster
    master_host: 192.0.2.1
    master_log_file: mysql-bin.000009
    master_log_pos: 4578

- name: Check replica status using port 3308
  community.mysql.mysql_replication:
    mode: getreplica
    login_host: ansible.example.com
    login_port: 3308

- name: On MariaDB change master to use GTID current_pos
  community.mysql.mysql_replication:
    mode: changemaster
    master_use_gtid: current_pos

- name: Change master to use replication delay 3600 seconds
  community.mysql.mysql_replication:
    mode: changemaster
    master_host: 192.0.2.1
    master_delay: 3600

- name: Start MariaDB replica with connection name master-1
  community.mysql.mysql_replication:
    mode: startreplica
    connection_name: master-1

- name: Stop replication in channel master-1
  community.mysql.mysql_replication:
    mode: stopreplica
    channel: master-1

- name: >
    Run RESET MASTER command which will delete all existing binary log files
    and reset the binary log index file on the master
  community.mysql.mysql_replication:
    mode: resetmaster

- name: Run start replica and fail the task on errors
  community.mysql.mysql_replication:
    mode: startreplica
    connection_name: master-1
    fail_on_error: yes

- name: Change master and fail on error (like when replica thread is running)
  community.mysql.mysql_replication:
    mode: changemaster
    fail_on_error: yes

z
queries:
  description: List of executed queries which modified DB's state.
  returned: always
  type: list
  sample: ["CHANGE MASTER TO MASTER_HOST='master2.example.com',MASTER_PORT=3306"]
  version_added: '0.1.0'
N)AnsibleModule)mysql_connectmysql_drivermysql_driver_fail_msgmysql_common_argument_spec)	to_native)LooseVersionc             C   s^   |  d |  }t|tr&|d }n|d }t|}d| krN|tdkS |tdkS dS )z/Checks if REPLICA must be used instead of SLAVEzSELECT VERSION() AS versionversionr   Zmariadbz10.5.1z8.0.22N)executefetchone
isinstancedictr   lower)cursorresultversion_strr    r   t/home/dcms/DCMS/lib/python3.7/site-packages/ansible_collections/community/mysql/plugins/modules/mysql_replication.pyuses_replica_terminology  s    


r   c             C   s   |  d |  }|S )NzSHOW MASTER STATUS)r   r   )r   Zmasterstatusr   r   r   get_master_status  s    
r    REPLICAc             C   s@   |rd||f }nd| }|r*|d| 7 }|  | |  }|S )NzSHOW %s '%s' STATUSzSHOW %s STATUSz FOR CHANNEL '%s')r   r   )r   connection_namechanneltermqueryZreplica_statusr   r   r   get_replica_status  s    
r   Fc       	   
   C   s   |rd||f }nd| }|r*|d| 7 }yt | || d}W nd tjk
rn } zd}W d d }~X Y n> tk
r } z |r| jdt| d d}W d d }~X Y nX |S )NzSTOP %s '%s'zSTOP %sz FOR CHANNEL '%s'TFzSTOP SLAVE failed: %s)msg)executed_queriesappendr   r   Warning	Exception	fail_jsonr
   )	moduler   r   r   fail_on_errorr   r   stoppeder   r   r   stop_replica,  s     

r*   c       	   
   C   s   |rd||f }nd| }|r*|d| 7 }yt | || d}W nd tjk
rn } zd}W d d }~X Y n> tk
r } z |r| jdt| d d}W d d }~X Y nX |S )NzRESET %s '%s'zRESET %sz FOR CHANNEL '%s'TFzRESET SLAVE failed: %s)r    )r!   r"   r   r   r#   r$   r%   r
   )	r&   r   r   r   r'   r   r   resetr)   r   r   r   reset_replicaB  s     

r,   c       	   
   C   s   |rd||f }nd| }|r*|d| 7 }yt | || d}W nd tjk
rn } zd}W d d }~X Y n> tk
r } z |r| jdt| d d}W d d }~X Y nX |S )NzRESET %s '%s' ALLzRESET %s ALLz FOR CHANNEL '%s'TFzRESET SLAVE ALL failed: %s)r    )r!   r"   r   r   r#   r$   r%   r
   )	r&   r   r   r   r'   r   r   r+   r)   r   r   r   reset_replica_allX  s     

r-   c          
   C   s   d}yt | || d}W nd tjk
rH } zd}W d d }~X Y n> tk
r } z |rp| jdt| d d}W d d }~X Y nX |S )NzRESET MASTERTFzRESET MASTER failed: %s)r    )r!   r"   r   r   r#   r$   r%   r
   )r&   r   r'   r   r+   r)   r   r   r   reset_mastern  s    

r.   c       	   
   C   s   |rd||f }nd| }|r*|d| 7 }yt | || d}W nd tjk
rn } zd}W d d }~X Y n> tk
r } z |r| jdt| d d}W d d }~X Y nX |S )NzSTART %s '%s'zSTART %sz FOR CHANNEL '%s'TFzSTART SLAVE failed: %s)r    )r!   r"   r   r   r#   r$   r%   r
   )	r&   r   r   r   r'   r   r   startedr)   r   r   r   start_replica}  s     

r0   c             C   sN   |rd|d |f }ndd | }|r6|d| 7 }t| | | d S )NzCHANGE MASTER '%s' TO %s,zCHANGE MASTER TO %sz FOR CHANNEL '%s')joinr!   r"   r   )r   chmr   r   r   r   r   r   changemaster  s    
r4   c        *      C   s(  t  } | jtdddddddddd	d
ddddgdtdddtddtddtdddtddtddtddtddtddtddtdddtddtddtddtddtddtdddddgdtddtddtddtdddd t| ddggd}|jd  }|jd! }|jd" }|jd# }|jd$ }|jd% }|jd& }|jd' }	|jd( }
|jd) }|jd* }|jd+ }|jd, }|jd- }|jd. }|jd/ }|jd0 }|jd1 }|jd2 }|jd3 }|jd4 }|jd5 }|jd6 }|jd7 }|jd8dkr
d9}n
|jd8 }|jd }|jd }|jd: }td krJ|jtd; nt	j
d<tjd= |jd> }|jd? }y&t|||||||d d@||dA\} }!W nd tk
r }" zDtj|r|jdB|t|"f d; n|jdC|t|"f d; W d d }"~"X Y nX t| r(dD}#|dkr:|jdEdFdGdH d}ndI}#|dkr:d}|dkrt| }$t|$tsftddJdK}$nd|$dL< |jf dMti|$ n|dNkr|dkr|jdOdFdGdH t| |||#}$t|$tstddPdQ}$nd|$dR< |jf dMti|$ n(|dkrDg }%i }&|d k	r|%dS|  |d k	r4|%dT|  |d k	rL|%dU|  |d k	rd|%dV|  |d k	r||%dW|  |d k	r|%dX|  |	d k	r|%dY|	  |d k	r|%dZ|  |
d k	r|%d[|
  |d k	r|%d\|  |r|%d] |d k	r|%d^|  |d k	r4|%d_|  |d k	rL|%d`|  |d k	rd|%da|  |d k	r||%db|  |r|%dc |d k	r|%dd|  yt| |%|| W nl tjk
r }" zt|"|&de< W d d }"~"X Y n< tk
r" }" z|jdft|"|%f d; W d d }"~"X Y nX d|&dg< |jf dMti|& n|dhkr|d	krh|jdidFdGdH t|| ||||#}'|'dkr|jdjdtdk n|jdldtdk np|dmkr|dkr|jdndFdGdH t|| ||||#}(|(dkr|jdodtdk n|jdpdtdk n
|d
krTt|| |})|)dkrB|jdqdtdk n|jdrdtdk n|dskr|dkrx|jdtdFdGdH t|| ||||#})|)dkr|jdudtdk n|jdvdtdk nb|dwkr|dkr|jdxdFdGdH t|| ||||#})|)dkr
|jdudtdk n|jdvdtdk t	 dy d S )zNstr
getreplicaZ	getmastergetslaver4   stopreplica	stopslavestartreplica
startslaveZresetmasterresetreplica
resetslaveresetreplicaallresetslaveall)typedefaultchoicesboolF)r@   rA   )r@   T)r@   Zno_logintZcurrent_posZreplica_posZ	slave_posdisabled)r@   rB   )modemaster_auto_positionmaster_hostmaster_usermaster_passwordmaster_portmaster_connect_retrymaster_log_filemaster_log_posrelay_log_filerelay_log_pos
master_sslmaster_ssl_camaster_ssl_capathmaster_ssl_certmaster_ssl_keymaster_ssl_ciphermaster_use_gtidmaster_delayr   r   r'   r   r   )argument_specZmutually_exclusiverF   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rG   client_certZ
client_keyZca_certcheck_hostnameconnect_timeoutconfig_filerX   rW   nor'   )r    error)categorylogin_password
login_userZ
DictCursor)Zcursor_classr\   r[   zunable to connect to database, check login_user and login_password are correct or %s has the credentials. Exception message: %sz(unable to find %s. Exception message: %sr   zKmaster_use_gtid "slave_pos" value is deprecated, use "replica_pos" instead.z3.0.0zcommunity.mysql)r   Zcollection_nameZSLAVEz(Server is not configured as mysql master)	Is_Masterr    rc   queries)r6   r7   z:"getslave" option is deprecated, use "getreplica" instead.z'Server is not configured as mysql slave)Is_Slaver    re   zMASTER_HOST='%s'zMASTER_USER='%s'zMASTER_PASSWORD='%s'zMASTER_PORT=%szMASTER_CONNECT_RETRY=%szMASTER_LOG_FILE='%s'zMASTER_LOG_POS=%szMASTER_DELAY=%szRELAY_LOG_FILE='%s'zRELAY_LOG_POS=%szMASTER_SSL=1zMASTER_SSL_CA='%s'zMASTER_SSL_CAPATH='%s'zMASTER_SSL_CERT='%s'zMASTER_SSL_KEY='%s'zMASTER_SSL_CIPHER='%s'zMASTER_AUTO_POSITION=1zMASTER_USE_GTID=%swarningz %s. Query == CHANGE MASTER TO %schanged)r:   r;   z>"startslave" option is deprecated, use "startreplica" instead.zSlave started )r    rg   rd   z,Slave already started (Or cannot be started))r8   r9   z<"stopslave" option is deprecated, use "stopreplica" instead.zSlave stoppedzSlave already stoppedzMaster resetzMaster already reset)r<   r=   z>"resetslave" option is deprecated, use "resetreplica" instead.zSlave resetzSlave already reset)r>   r?   zD"resetslaveall" option is deprecated, use "resetreplicaall" instead.ignore)!r	   updater   r   paramsgetr   r%   r   warningsfilterwarningsr#   r   r$   ospathexistsr
   r   Z	deprecater   r   Z	exit_jsonr!   r   r"   r4   r0   r*   r.   r,   r-   simplefilter)*rY   r&   rF   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rG   Zssl_certZssl_keyZssl_car[   r\   r]   rX   rW   r   r   r'   ra   rb   r   Zdb_connr)   Zreplica_termstatusr3   r   r/   r(   r+   r   r   r   main  sr   




































*


























*

















rs   __main__)r   r   r   )r   r   Fr   )r   r   Fr   )r   r   Fr   )F)r   r   Fr   )r   r   )"
__future__r   r   r   r@   __metaclass__ZDOCUMENTATIONZEXAMPLESZRETURNrn   rl   Zansible.module_utils.basicr   Z>ansible_collections.community.mysql.plugins.module_utils.mysqlr   r   r   r	   Zansible.module_utils._textr
   Zdistutils.versionr   r!   r   r   r   r*   r,   r-   r.   r0   r4   rs   __name__r   r   r   r   <module>	   s2    $>	






 \
