HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.109.1.lve.el8.x86_64 #1 SMP Thu Mar 5 20:23:46 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/__pycache__/mysql.cpython-310.pyc
o

�N�g$j�@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddlZ
ddlZ
zddl
Z
ddlZ
ddlZ
ddl
mZddlmZmZmZWn;ey�z&ddlZe��ddl
Z
ddlZ
ddlZ
ddl
mZddlmZmZmZWney�dZ
YnwYnwzddlZdZWney�dZYnwe�e�Zgd�Zgd�Zed	d
gZgd�Z 	dd
�Z!dd�Z"dd�Z#dd�Z$dd�Z%dd�Z&dd�Z'dd�Z(dd�Z)dd�Z*d�d d!�Z+d�d"d#�Z,d$d%�Z-d&d'�Z.d(d)�Z/d*d+�Z0d,d-�Z1d.d/�Z2d0d1�Z3d2d3�Z4d�d4d5�Z5d6d7�Z6d8d9�Z7d:d;�Z8d�d<d=�Z9d>d?�Z:d@dA�Z;	B						Cd�dDdE�Z<	B						Cd�dFdG�Z=	B					d�dHdI�Z>d�dJdK�Z?	B						Cd�dLdM�Z@	B						Cd�dNdO�ZA	B						Cd�dPdQ�ZB	B						Cd�dRdS�ZC	B						Cd�dTdU�ZD	B					d�dVdW�ZEd�dXdY�ZFdZd[�ZGd�d\d]�ZHd�d^d_�ZId�d`da�ZJdbdc�ZKddde�ZLdfdg�ZM	B			d�dhdi�ZNd�djdk�ZO	B		d�dldm�ZP	B			d�dndo�ZQ	B		d�dpdq�ZRdrds�ZSdtdu�ZTdvdw�ZUdxdy�ZVdzd{�ZWd|d}�ZXd�d~d�ZYd�d��ZZd�d�d��Z[d�d��Z\d�d��Z]dS)�a�
Module to provide MySQL compatibility to salt.

:depends:   - Python module: MySQLdb, mysqlclient, or PyMYSQL

:configuration: In order to connect to MySQL, certain configuration is required
    in either the relevant minion config (/etc/salt/minion), or pillar.

    Some sample configs might look like::

        mysql.host: 'localhost'
        mysql.port: 3306
        mysql.user: 'root'
        mysql.pass: ''
        mysql.db: 'mysql'
        mysql.unix_socket: '/tmp/mysql.sock'
        mysql.charset: 'utf8'

    You can also use a defaults file::

        mysql.default_file: '/etc/mysql/debian.cnf'

.. versionchanged:: 2014.1.0
    'charset' connection argument added. This is a MySQL charset, not a python one.
.. versionchanged:: 0.16.2
    Connection arguments from the minion config file can be overridden on the
    CLI by using the arguments defined :mod:`here <salt.states.mysql_user>`.
    Additionally, it is now possible to setup a user with no password.
�N)�OperationalError)�CLIENT�
FIELD_TYPE�FLAGTF);�ALL PRIVILEGES�ALTER�
ALTER ROUTINE�BACKUP_ADMIN�BINLOG_ADMINzBINLOG ADMIN�BINLOG MONITORz
BINLOG REPLAY�CONNECTION_ADMINzCONNECTION ADMIN�CREATE�CREATE ROLE�CREATE ROUTINE�CREATE TABLESPACE�CREATE TEMPORARY TABLES�CREATE USER�CREATE VIEW�DELETEzDELETE HISTORY�DROP�	DROP ROLE�ENCRYPTION_KEY_ADMIN�EVENT�EXECUTEzFEDERATED ADMIN�FILEzGRANT OPTION�GROUP_REPLICATION_ADMIN�INDEX�INSERT�LOCK TABLES�PERSIST_RO_VARIABLES_ADMIN�PROCESSzREAD_ONLY ADMIN�
REFERENCES�RELOAD�REPLICA MONITOR�REPLICATION CLIENTzREPLICATION MASTER ADMIN�REPLICATION REPLICA�REPLICATION SLAVE�REPLICATION_SLAVE_ADMINzREPLICATION SLAVE ADMIN�RESOURCE_GROUP_ADMIN�RESOURCE_GROUP_USER�
ROLE_ADMIN�SELECTzSET USER�SET_USER_ID�SHOW DATABASES�	SHOW VIEW�SHUTDOWN�
SLAVE MONITOR�SUPER�SYSTEM_VARIABLES_ADMIN�TRIGGER�UPDATEZUSAGE�XA_RECOVER_ADMIN)ZCIPHERZISSUERZSUBJECTZSSLZX509)+rrr	r
rr
rrrrrrrrrrrrrrrrrrr r!r"r$r&r'r(r)r*r+r,r-r.r/r1r2r3r4r5cCstt�tdur
dfSdfS)z:
    Confirm that a python mysql client is installed.
    Nz!No python mysql client installed.�)�bool�MySQLdb�r9r9�F/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/mysql.py�__virtual__sr;cCs.t�|�����}dt�|�������}|S)N�*)�hashlib�sha1�encode�digest�	hexdigest�upper)�password�	_passwordr9r9r:�__mysql_hash_passwordsrEc	K�htdi|��}|dur
iS|�tjj�}t|�}t|�}d|�d|��}t||�|��}t�	|�|S)NzCHECK TABLE �.r9�
�_connect�cursorr8�cursors�
DictCursor�quote_identifier�_execute�fetchall�log�debug�	�name�table�connection_args�dbc�cur�s_nameZs_table�qry�resultsr9r9r:�
__check_table�

r[c	KrF)Nz
REPAIR TABLE rGr9rHrRr9r9r:�__repair_tabler\r]c	KrF)NzOPTIMIZE TABLE rGr9rHrRr9r9r:�__optimize_table,r\r^cKs|dtvrtdStd	i|��}|durdS|��}d}dddd�}t|||�t|j�dkr6dtd<tdSdtd<tdS)
Nzmysql.password_columnZPasswordz�SELECT column_name from information_schema.COLUMNS WHERE table_schema=%(schema)s and table_name=%(table)s and column_name=%(column)s�mysql�user)ZschemarT�columnrZauthentication_stringr9)�__context__rIrJrN�int�rowcount)rUrVrWrY�argsr9r9r:�__password_column;s��rfc

Ks�tdi|��}|dur
gS|�tjj�}zd}||d�}t|||�Wn#tjyF}zdj|j�}|t	d<t
�|�WYd}~dSd}~ww|��}	t
�
|	�|	rZ|	d�dd�SdS)	NzCSELECT plugin FROM mysql.user WHERE User=%(user)s and Host=%(host)s)r`�host�MySQL Error {}: {}�mysql.error�mysql_native_passwordrZpluginr9)rIrJr8rKrLrNr�formatrerbrP�errorrOrQ�get)
r`rgrUrVrWrYre�exc�errrZr9r9r:�__get_auth_pluginRs(

��
rpc	
st��d$��fdd�	}d�vrd}nd}d�d<i}tt�D]}|�d	�s.tt|�||��<q��d
g�D]}|�|�rG�d||O<q5t�d|�q5|dd
|�|dd|�|dd|�|dd|�|dd|�|dd|�|dd|�|dd|�|dd|�d�d<|dd�d t	_
t���D]	}�|s��|=q���dd�dur�t�
d!���d�z
t	jd%i���}WnFty�}zd"j|j�}|td#<t�|�WYd}~dSd}~wt	jj�y}zd"j|j�}|td#<t�|�WYd}~dSd}~ww|�d�|S)&z.
    wrap authentication credentials here
    NTcs�|dur|}|�vr�|�|<dS|rDd}|�|�r0z
|t|�d�}Wn
ty/YdSwtdd|��d�}|durF|�|<dSdSdS)a�
        Add key to connargs, only if name exists in our kwargs or,
        if get_opts is true, as mysql.<name> in __opts__ or __pillar__

        If get_opts is true, evaluate in said order - kwargs, opts
        then pillar. To avoid collision with other functions,
        kwargs-based connection arguments are prefixed with 'connection_'
        (i.e. 'connection_host', 'connection_user', etc.).
        NZconnection_z
config.optionzmysql.)�
startswith�len�
IndexError�__salt__)rS�key�get_opts�prefix�val�Zconnargs�kwargsr9r:�_connargos"

��z_connect.<locals>._connargZconnection_default_fileFrZclient_flag�__Zclient_flagsz)MySQL client flag %s not valid, ignoring.Zconnection_hostrg�connection_userr`�connection_pass�passwdZconnection_port�port�
connection_db�db�connection_conv�convZconnection_unix_socket�unix_socketZread_default_fileZconnection_default_groupZread_default_groupZuse_unicodeZconnection_charset�charsetZpyformatz<MySQL password of None found. Attempting passwordless login.rhri)NTr9)�dict�dirrrq�getattr�lowerrmrPrlr8Z
paramstyle�copy�deepcopy�warning�pop�connectrrkrerbroZ
InternalErrorZ
autocommit)	rzr{rvZavailable_client_flags�flagrurVrnror9ryr:rIisf
�

�


�
��
rIc	Cs�t�d|�d}t|t�r,d}|�dd��dd�}|�di�}|�d	d�}|�d
d�}n|}d}t�|�}d|_d|_d|_	|j
d
7_
t|�}g}g}	d}
d}d}d}
d}||
d�D]�}|dkrl|dkrl|
d7}
q]|dkr{|dkr{|
d7}
d}
q]|dkr�|dkr�|
d7}
d}
q]|dkr�|dkr�d}|
d7}
q]|dkr�|dkr�d
}|
d7}
q]|dkr�|dkr�d	}|
d7}
q]|dkr�||
ddks�||
ddks�||
ddvr�|	r�|	�|�|�d�
|	��g}	ng|
s�|}n|�d|��}|�|�nU|	�|�nO|dk�r||7}z
||
ddk�rd}Wn8t�yYn3w|dk�r)||7}n#|d
k�rC|�r3n||7}||
ddk�rBd}n	|d	k�rL|}n|
d7}
q]z|�s_|�d�}|�d�}t�d||||�Wnt�yud}Ynwt||||d�S) a�

    This should correspond fairly closely to the YAML rendering of a
    mysql_grants state which comes out as follows:

     OrderedDict([
        ('whatever_identifier',
         OrderedDict([
            ('mysql_grants.present',
             [
              OrderedDict([('database', 'testdb.*')]),
              OrderedDict([('user', 'testuser')]),
              OrderedDict([('grant', 'ALTER, SELECT, LOCK TABLES')]),
              OrderedDict([('host', 'localhost')])
             ]
            )
         ])
        )
     ])

    :param grant: An un-parsed MySQL GRANT statement str, like
        "GRANT SELECT, ALTER, LOCK TABLES ON `mydb`.* TO 'testuser'@'localhost'"
        or a dictionary with 'qry' and 'args' keys for 'user' and 'host'.
    :return:
        A Python dict with the following keys/values:
            - user: MySQL User
            - host: MySQL host
            - grant: [grant1, grant2] (ala SELECT, USAGE, etc)
            - database: MySQL DB
    z_grant_to_tokens entry '%s'FTrYZ	undefined�%%�%rergr`r6z'`�"��grantsN�,�(�)ZONr�ZTO�tables�@zpre-host)r�r�� rG�'z%grant to token '%s'::'%s'::'%s'::'%s')r`rg�grant�database)rPrQ�
isinstancer�rm�replace�shlex�quotesZwhitespace_splitZ
commentersZ	wordchars�list�append�joinrs�strip�UnboundLocalError)r�Z	dict_modeZ	grant_sqlZsql_argsrgr`ZlexZexploded_grant�grant_tokensZmultiword_statementZposition_trackerr��phraseraZ
current_grant�tokenr9r9r:�_grant_to_tokens�s�



��


�




��r�cCs�d|vr|Sd}d}d}g}|D]C}tjj�||�dkr&|dkr&|�d�qtjj�||�dkr:|dkr:|�d	�qtjj�||�dkrN|d
krN|�d�q|�|�q|S)a�

    There can be a situation where the database supports grants "A" and "B", where
    "B" is an alias for "A". In that case, when you want to grant "B" to a user,
    the database will actually report it added "A". We need to resolve those
    aliases to not report (wrong) errors.

    :param grants: the tokenized grants

    :param server_version: version string of the connected database

    �MariaDBz10.5.1z10.5.2z10.5.9rr%r&r$rr#r0)�salt�utils�versions�version_cmpr�)r��server_versionZ+mariadb_version_compare_replication_replicaZ&mariadb_version_compare_binlog_monitorZ%mariadb_version_compare_slave_monitorZresolved_tokensr�r9r9r:�_resolve_grant_aliasesvsB
��
��
��
r�cCsD|rd|�dd��dd��dd�dSd|�dd��dd�dS)a�
    Return an identifier name (column, table, database, etc) escaped for MySQL

    This means surrounded by "`" character and escaping this character inside.
    It also means doubling the '%' character for MySQLdb internal usage.

    :param identifier: the table, column or database identifier

    :param for_grants: is False by default, when using database names on grant
     queries you should set it to True to also escape "_" and "%" characters as
     requested by MySQL. Note that theses characters should only be escaped when
     requesting grants on the database level (`my\_\%db`.*) but not for table
     level grants (`my_%db`.`foo`)

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.quote_identifier 'foo`bar'
    �`z``�_z\_r�r�)r�)Z
identifier�
for_grantsr9r9r:rM�s���rMcCsP|dus|ikr|�dd�}t�d|�|�|�St�d|t|��|�||�S)a
    Internal wrapper around MySQLdb cursor.execute() function

    MySQLDb does not apply the same filters when arguments are used with the
    query. For example '%' characters on the query must be encoded as '%%' and
    will be restored as '%' when arguments are applied. But when there're no
    arguments the '%%' is not managed. We cannot apply Identifier quoting in a
    predictable way if the query are not always applying the same filters. So
    this wrapper ensure this escape is not made if no arguments are used.
    Nr�r�zDoing query: %szDoing query: %s args: %s )r�rPrQ�execute�repr)rWrYrer9r9r:rN�s
rNcCs ts	t�d�|Stj|dd�S)NzE_sanitize_comments unavailable, no python sqlparse library installed.T)Zstrip_comments)�HAS_SQLPARSErPrl�sqlparserk)�contentr9r9r:�_sanitize_comments�s�r�c
Kstjj}t|�}tt|tgt|���}ddi}|�tj	�
��rDtjtfg|t
j<tjtfg|t
j<tjtfg|t
j<tjtfg|t
j<|�||d��tdi|��}|durYiS|��}t��}	t�d||�zt||�}
Wn"ty�}zdj|j�}|td<t�|�WYd}~dSd}~ww|��}
t��|	}|d	kr�tt|d
d��d}n	tt|d
��d}i}|tt|d��d�|d<gd�}d}|D]}|�
�� ��!|�r�d}nq�|r�|
|d<d}|j"D]	}||df7}q�||d<|
|d<|S|
|d<|S)a
    Run an arbitrary SQL query and return the results or
    the number of affected rows.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.query mydb "UPDATE mytable set myfield=1 limit 1"

    Return data:

    .. code-block:: python

        {'query time': {'human': '39.0ms', 'raw': '0.03899'}, 'rows affected': 1L}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.query mydb "SELECT id,name,cash from users limit 3"

    Return data:

    .. code-block:: python

        {'columns': ('id', 'name', 'cash'),
            'query time': {'human': '1.0ms', 'raw': '0.001'},
            'results': ((1L, 'User 1', Decimal('110.000000')),
                        (2L, 'User 2', Decimal('215.636756')),
                        (3L, 'User 3', Decimal('0.040000'))),
            'rows returned': 3L}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.query mydb 'INSERT into users values (null,"user 4", 5)'

    Return data:

    .. code-block:: python

        {'query time': {'human': '25.6ms', 'raw': '0.02563'}, 'rows affected': 1L}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.query mydb 'DELETE from users where id = 4 limit 1'

    Return data:

    .. code-block:: python

        {'query time': {'human': '39.0ms', 'raw': '0.03899'}, 'rows affected': 1L}

    Jinja Example: Run a query on ``mydb`` and use row 0, column 0's data.

    .. code-block:: jinja

        {{ salt['mysql.query']('mydb', 'SELECT info from mytable limit 1')['results'][0][0] }}
    ZMYSQLDBT)r�r�NzUsing db: %s to run query %srhriFg�������?i�r��ms��s�)�human�raw�
query time)r+ZSHOWZDESC�
rows returnedr9r�columnsrZ�
rows affected)#r8Z
convertersZconversions�iterr��zip�strrrrm�__package__rBrZBINARYrZBLOB�STRINGZ
VAR_STRINGZVARCHAR�updaterIrJ�timerPrQrNrrkrerbrlrO�roundr�rq�description)r��queryrUZ	orig_convZ	conv_iterr�Zconv_mysqldbrVrW�startZaffectedrnrorZ�elapsedZ	elapsed_h�retZselect_keywordsZselect_query�keywordr�rar9r9r:r��sjF
�
�
�
�
���
r�c	s�ts	t�d�dSt�fdd�dD��rtd���tj���rBtj	j
��d��}tj	j�
|���}Wd�n1s<wYnt�d	��dSd
}dggdddid
�}t|�}|��D]m}t�d|�sk||}q^||}t||fi|��}d
}|dur�dSd|vr�|ddt|dd�7<d|vr�|d|d7<d|vr�|d�|d�d|vr�|d�|d�d|vr�|d|d7<q^ttt|dd�d��d|dd<tt|dd�d�|dd<dd�|��D�}|S)ar
    Run an arbitrary SQL query from the specified file and return the
    the number of affected rows.

    .. versionadded:: 2017.7.0

    database

        database to run script inside

    file_name

        File name of the script.  This can be on the minion, or a file that is reachable by the fileserver

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.file_query mydb file_name=/tmp/sqlfile.sql
        salt '*' mysql.file_query mydb file_name=salt://sqlfile.sql

    Return data:

    .. code-block:: python

        {'query time': {'human': '39.0ms', 'raw': '0.03899'}, 'rows affected': 1L}

    zCmysql.file_query unavailable, no python sqlparse library installed.Fc3s�|]}��|�VqdS�N)rq)�.0�proto��	file_namer9r:�	<genexpr>�s
��
�zfile_query.<locals>.<genexpr>)zsalt://zhttp://zhttps://zswift://zs3://z
cp.cache_file�rNzFile "%s" does not existr6rr�)r�r�rZr�r�z[^-;]+;r�r�r�rZr�r�r�r�r�cSsi|]	\}}|r||�qSr9r9)r��k�vr9r9r:�
<dictcomp>�szfile_query.<locals>.<dictcomp>)r�rPrl�anyrt�os�path�existsr�r��filesZfopenZstringutilsZ
to_unicode�readr��
splitlines�re�searchr��floatr�r�r��items)	r�r�rUZifile�contentsZquery_stringr��lineZquery_resultr9r�r:�
file_queryvs\
����
� �&r�c	
Ks�tdi|��}|dur
iS|��}d}zt||�Wn#ty=}zdj|j�}|td<t�|�iWYd}~Sd}~wwi}t	|j
�D]}|��}|d||d<qE|S)z�
    Return the status of a MySQL server using the output from the ``SHOW
    STATUS`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.status
    NzSHOW STATUSrhrir�rr9)rIrJrNrrkrerbrPrl�rangerd�fetchone)	rUrVrWrYrnror�r��rowr9r9r:�status�s&
��r�c
Ks�dtvrtdStdi|��}|durdS|��}d}zt||�Wn#tjyE}zdj|j�}|td<t�	|�WYd}~dSd}~wwzt
jj�
|��d�td<tdWStybYdSw)	z�
    Return the version of a MySQL server using the output from the ``SELECT
    VERSION()`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.version
    z
mysql.versionNr6zSELECT VERSION()rhrirr9)rbrIrJrNr8rrkrerPrlr�r��data�decoder�rs)rUrVrWrYrnror9r9r:�version�s,
��
�r�c
Ks�tdi|��}|dur
dS|�tjj�}d}zt||�Wn#tjy@}zdj|j�}|t	d<t
�|�WYd}~dSd}~ww|��}|j
dkrLdS|dd	krV|d
SdS)
a�
    Return the number of seconds that a slave SQL server is lagging behind the
    master, if the host is not a slave it will return -1.  If the server is
    configured to be a slave for replication but slave IO is not running then
    -2 will be returned. If there was an error connecting to the database or
    checking the slave status, -3 will be returned.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.slave_lag
    N����show slave statusrhrir���ZSlave_IO_RunningZYesZSeconds_Behind_Master���r9)rIrJr8rKrLrNrrkrerbrPrlr�rd�rUrVrWrYrnrorZr9r9r:�	slave_lags(
��
r�cKs�tdi|��}|dur
dS|�tjj�}|�d�|��}d|di}ztdi|��}|dur2WdS|��}|�d�|��Wn
tjyJYnw|�d�|�d�|�d	�|�d�|��}|durid
SdS)
z�
    Frees a slave from its master.  This is a WIP, do not use.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.free_slave
    Nr6r�rgZMaster_Hostz
flush logsz
stop slavezreset masterzchange master to MASTER_HOST=ZpromotedZfailedr9)	rIrJr8rKrLr�r��closer)rUZslave_dbZ	slave_curZslave_statusZmasterZ	master_dbZ
master_currZr9r9r:�
free_slave<s2


�



r�c	
Ks�tdi|��}|dur
gS|��}d}zt||�Wn$tjy>}zdj|j�}|td<t�	|�gWYd}~Sd}~wwg}|�
�}|D]	}|�|d�qGt�|�|S)z�
    Return a list of databases of a MySQL server using the output
    from the ``SHOW DATABASES`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_list
    Nr-rhrirr9�
rIrJrNr8rrkrerbrPrlrOr�rQ�	rUrVrWrYrnror�rZZdbsr9r9r:�db_listjs(
��
r�c
Ks�td
i|��}|dur
gS|��}t|fi|��}d�||p"|�d�|p(|�d��}i}zt|||�r<t�d|�WdSWd	Stj	ya}	zdj|	j
�}
|
td<t�|
�WYd}	~	d	Sd}	~	ww)z�
    Modify database using ``ALTER DATABASE %(dbname)s CHARACTER SET %(charset)s
    COLLATE %(collation)s;`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.alter_db testdb charset='latin1'
    Nz0ALTER DATABASE `{}` CHARACTER SET {} COLLATE {};�
character_set�collatezDB '%s' alteredTrhriFr9)
rIrJ�db_getrkrmrNrP�infor8rrerbrl)rSr�r�rUrVrW�existingrYrernror9r9r:�alter_db�s0�����rc	
Ks�td	i|��}|dur
gS|��}d}d|i}zt|||�Wn$tjyC}zdj|j�}|td<t�	|�gWYd}~Sd}~ww|j
rX|��}|dd|ddd�SiS)
a*
    Return a list of databases of a MySQL server using the output
    from the ``SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM
    INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='dbname';`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_get test
    NzxSELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=%(dbname)s;�dbnamerhrirr�)r�r�r9)rIrJrNr8rrkrerbrPrlrdrO)	rSrUrVrWrYrernroZrowsr9r9r:r�s(�
��rc
Ks�t|fi|��st�d|�dStdi|��}|durgS|��}t|�}d|��}zt||�Wn$tjyU}zdj	|j
�}|td<t�|�gWYd}~Sd}~wwg}|�
�}	|	D]	}
|�|
d�q^t�|�|S)	z�
    Shows the tables in the given MySQL database (if exists)

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_tables 'database'
    zDatabase '%s' does not existFNzSHOW TABLES IN rhrirr9)�	db_existsrPrrIrJrMrNr8rrkrerbrlrOr�rQ)rSrUrVrWrXrYrnror�rZrTr9r9r:�	db_tables�s0


��
rc
Ks�tdi|��}|dur
dS|��}d|i}d}zt|||�Wn#tjyB}zdj|j�}|td<t�	|�WYd}~dSd}~ww|�
�|jdkS)	z�
    Checks if a database exists on the MySQL server.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_exists 'dbname'
    NFrzSHOW DATABASES LIKE %(dbname)s;rhrir�r9)rIrJrNr8rrkrerbrPrlrOrd)rSrUrVrWrerYrnror9r9r:r�s"

��
rc
Ks�t|fi|��rt�d|�dStdi|��}|durdS|��}t|�}d|��}i}|dur8|d7}||d<|durD|d7}||d<|d	7}zt|||�rXt�d
|�WdSWdStjy}}	zdj	|	j
�}
|
td
<t�|
�WYd}	~	dSd}	~	ww)a�
    Adds a databases to the MySQL server.

    name
        The name of the database to manage

    character_set
        The character set, if left empty the MySQL default will be used

    collate
        The collation, if left empty the MySQL default will be used

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_create 'dbname'
        salt '*' mysql.db_create 'dbname' 'utf8' 'utf8_general_ci'
    zDB '%s' already existsFNzCREATE DATABASE IF NOT EXISTS z  CHARACTER SET %(character_set)sr�z COLLATE %(collate)sr��;zDB '%s' createdTrhrir9�
rrPrrIrJrMrNr8rrkrerbrl)rSr�r�rUrVrWrXrYrernror9r9r:�	db_creates<
����r	c
Ks�t|fi|��st�d|�dS|dvrt�d|�dStd
i|��}|dur)dS|��}t|�}d|�d�}zt||�Wn#tjya}zdj	|j
�}|td	<t�|�WYd}~dSd}~wwt|fi|��srt�d
|�dSt�d|�dS)z�
    Removes a databases from the MySQL server.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_remove 'dbname'
    zDB '%s' does not existF)r_Zinformation_schemezDB '%s' may not be removedNzDROP DATABASE rrhrizDatabase '%s' has been removedTz"Database '%s' has not been removedr9r)rSrUrVrWrXrYrnror9r9r:�	db_removeHs4
��r
c
Ks�tdi|��}|dur
gS|�tjj�}z	d}t||�Wn$tjyA}zdj|j�}|t	d<t
�|�gWYd}~Sd}~ww|��}t
�
|�|S)z�
    Return a list of users on a MySQL server

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_list
    Nz SELECT User,Host FROM mysql.userrhrir9)rIrJr8rKrLrNrrkrerbrPrlrOrQr�r9r9r:�	user_listts"

��
r�	localhostrjcKs6tjj�tdi|���}	d}
d}i}||d<||d<tjj�|�r@tjj�|�r4|d7}d|d<||fS|d|d	7}||fS|r�tjj�|	|
�d
krw|dkrhtt	|��}
|d|d7}t	|
�|d
<||fSd}t
�|�|td<||fS|d|d7}t	|�|d
<||fS|r�|d|d7}||d
<||fS)N�8.0.11�JSELECT User,Host FROM mysql.user WHERE User = %(user)s AND Host = %(host)sr`rg� AND plugin=%(unix_socket)s�auth_socketr�� AND � = ''rrj� = %(password)srCzUnable to verify password.ri� = PASSWORD(%(password)s)r9)
r�r�r�r�r��is_truer�r�rEr�rPrlrb)r`rgrC�
password_hash�passwordlessr��password_column�auth_pluginrUr��compare_versionrYrerDror9r9r:�_mysql_user_exists�s>���
��rcKs�d}	i}
||
d<||
d<tjj�|�r2tjj�|�r&|	d7}	d|
d<|	|
fS|	d|d7}	|	|
fS|rF|	d|d7}	t|�|
d	<|	|
fS|rT|	d|d
7}	||
d	<|	|
fS)Nrr`rgrr�rrrrCr)r�r�r�rr�)r`rgrCrrr�rrrUrYrer9r9r:�_mariadb_user_exists�s&
���rc
Ks�d}tjj�tdi|���}	|	s8|r8dtd<||d<tjj�tdi|���}	|	s8td}
d�|
�}t�|�dSt	di|��}|dur_td�
d|�d��r_|r_dtd<||d<t	di|��}|duredS|sntdi|��}t||fi|��}
|�
�}d|	vr�t||||||f||
d	�|��\}}nt||||||f||
d	�|��\}}zt|||�Wn#tjy�}zd
j|j�}|td<t�|�WYd}~dSd}~ww|jdkS)
ar
    Checks if a user exists on the MySQL server. A login can be checked to see
    if passwordless login is permitted by omitting ``password`` and
    ``password_hash``, and using ``passwordless=True``.

    .. versionadded:: 0.16.2
        The ``passwordless`` option was added.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_exists 'username' 'hostname' 'password'
        salt '*' mysql.user_exists 'username' 'hostname' password_hash='hash'
        salt '*' mysql.user_exists 'username' passwordless=True
        salt '*' mysql.user_exists 'username' password_column='authentication_string'
    FNrir~�IMySQL Error: Unable to fetch current server version. Last error was: "{}"z*MySQL Error 1045: Access denied for user 'z'@r��rrrhr�r9)r�r�r�r�r�rbrkrPrlrIrqrfrprJrrrNr8rrerd)r`rgrCrrr�rrUZ
run_verifyr��last_errrorVrrWrYrernr9r9r:�user_exists�s��

�����	���	
�
��
r c

Ks�tdi|��}|dur
dS|�tjj�}d}i}||d<||d<zt|||�Wn#tjyK}zdj|j�}|t	d<t
�|�WYd}~dSd}~ww|��}	t
�
|	�|	S)	z�
    Get full info on a MySQL user

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_info root localhost
    NFzBSELECT * FROM mysql.user WHERE User = %(user)s AND Host = %(host)sr`rgrhrir9)rIrJr8rKrLrNrrkrerbrPrlr�rQ)
r`rgrUrVrWrYrernro�resultr9r9r:�	user_infoGs(

��
r"cKsRtjj�tdi|���}	d}
d}i}||d<||d<|rOtdi|��s4d}
t�|
�|
td<d}||fS|d	kr@|d
7}||fSt�d�|
td<d}||fStjj�	|�s�|dur{tjj
�|	|
�dkrm||d
<|d7}n|d7}t|�|d<||fS|dur�tjj
�|	|
�dkr�||d
<|d7}n|d7}||d<||fSt�d�d}||fS)Nr
�CREATE USER %(user)s@%(host)sr`rgr�&The auth_socket plugin is not enabled.riFrz IDENTIFIED WITH auth_socket�7Auth via unix_socket can be set only for host=localhostrrz0 IDENTIFIED WITH %(auth_plugin)s BY %(password)s� IDENTIFIED BY %(password)srCz0 IDENTIFIED WITH %(auth_plugin)s AS %(password)s�$ IDENTIFIED BY PASSWORD %(password)s�Kpassword or password_hash must be specified, unless allow_passwordless=Truer9�r)
r�r�r�r�r��
plugin_statusrPrlrbrr�r�r�)r`rgrCr�allow_passwordlessr�rrrUr�rrYreror9r9r:�_mysql_user_creategsX
$�!
���
��
��r,cKs�d}	i}
||
d<||
d<|rAtdi|��s&d}t�|�|td<d}	|	|
fS|dkr2|	d	7}	|	|
fSt�d
�|td<d}	|	|
fStjj�|�sq|durZ|	d7}	t|�|
d<|	|
fS|durj|	d
7}	||
d<|	|
fSt�d�d}	|	|
fS)Nr#r`rgr��&The unix_socket plugin is not enabled.riFrz IDENTIFIED VIA unix_socketr%r&rCr'r(�r�)	r*rPrlrbr�r�r�rr�)r`rgrCrr+r�rrrUrYreror9r9r:�_mariadb_user_create�s@
�
��
���r/c
Ks�tjj�tdi|���}	|	s6|r6dtd<||d<tjj�tdi|���}	|	s6td}
d�|
�}t�|�dSt	||fi|��rHt�
d||�dStdi|��}|durUdS|s^tdi|��}|�
�}
d|	vryt||||||f||d�|��\}}nt||||||f||d�|��\}}t|t�r�|Szt|
||�Wn#tjy�}zd	j|j�}|td<t�|�WYd}~dSd}~wwt	||||fd
|i|��r�d|�d|�d
�}t||f�s�|d7}t�
|�dSt�
d||�dS)aq
    Creates a MySQL user

    host
        Host for which this user/password combo applies

    password
        The password to use for the new user. Will take precedence over the
        ``password_hash`` option if both are specified.

    password_hash
        The password in hashed form. Be sure to quote the password because YAML
        doesn't like the ``*``. A password hash can be obtained from the mysql
        command-line client like so::

            mysql> SELECT PASSWORD('mypass');
            +-------------------------------------------+
            | PASSWORD('mypass')                        |
            +-------------------------------------------+
            | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
            +-------------------------------------------+
            1 row in set (0.00 sec)

    allow_passwordless
        If ``True``, then ``password`` and ``password_hash`` can be omitted (or
        set to ``None``) to permit a passwordless login.

    unix_socket
        If ``True`` and allow_passwordless is ``True`` then will be used unix_socket auth plugin.

    password_column
        The password column to use in the user table.

    auth_plugin
        The authentication plugin to use, default is to use the mysql_native_password plugin.

    .. versionadded:: 0.16.2
        The ``allow_passwordless`` option was added.

    CLI Examples:

    .. code-block:: bash

        salt '*' mysql.user_create 'username' 'hostname' 'password'
        salt '*' mysql.user_create 'username' 'hostname' password_hash='hash'
        salt '*' mysql.user_create 'username' 'hostname' allow_passwordless=True
    Nrir~rFzUser '%s'@'%s' already existsr�rrhrzUser 'z'@'z' has been createdz with passwordless loginTzUser '%s'@'%s' was not createdr9)r�r�r�r�r�rbrkrPrlr rrIrfrJr/r,r�r7rNr8rrer�)r`rgrCrr+r�rrrUr�rrorVrWrYrern�msgr9r9r:�user_create�s�:�
��	���	
�

�����
r1cKs�tjj�tdi|���}	d}
i}|dur(tjj�|	|
�dkr!d}nd}||d<n|dur3d}||d<ntjj�|�sAt�	d�dSd}||d	<||d
<tjj�|	|
�dkrm||d<d}
|durd|
d
7}
n|durl|
d7}
n
d|d|d}
tjj�|�r�tjj�|�r�|dkr�t
di|��s�d}t�	|�|td<d}
|
|fSd|d<tjj�|	|
�dkr�d}
|
|fSd|d|dd}
|
|fSt�	d�|
|fS)Nr
r�%(password)s�PASSWORD(%(password)s)rCr(F�''r`rgrz=ALTER USER %(user)s@%(host)s IDENTIFIED WITH %(auth_plugin)s zBY %(password)s;zAS %(password)s;�UPDATE mysql.user SET �=�) WHERE User=%(user)s AND Host = %(host)s;rrr$rir�zIALTER USER %(user)s@%(host)s IDENTIFIED WITH %(unix_socket)s AS %(user)s;�, plugin=%(unix_socket)sr%r9r))r�r�r�r�r�r�r�rrPrlr*rb�r`rgrCrr+r�rrrUr�rreZpassword_sqlrYror9r9r:�_mysql_user_chpasscs�

�
�������
����������
�r:cKsHtjj�tdi|���}	d}
i}|durd}||d<n|dur&d}||d<ntjj�|�s4t�d�dSd}||d<||d	<tjj�	|	|
�d
krS||d<d}
|
|7}
n
d
|d|d}
tjj�|�r�tjj�|�r�|dkr�t
di|��s�d}t�|�|td<d}
|
|fSd|d<d
|d|dd}
|
|fSt�d�|
|fS)Nz10.4r3rCr2r(Fr4r`rgrrzBALTER USER %(user)s@%(host)s IDENTIFIED VIA %(auth_plugin)s USING r5r6r7rr�r-rir8r%r9r.)r�r�r�r�r�rrPrlr�r�r*rbr9r9r9r:�_mariadb_user_chpass�sr

�
������
�������
�r;c
Ks$tjj�tdi|���}|s6|r6dtd<||d<tjj�tdi|���}|s6td}	d�|	�}
t�|
�dSt	||fi|��sHt�
d||�dStdi|��}|durUdS|s^tdi|��}t
||fi|��}|��}
d|vr�t||||||f||d�|��\}}nt||||||f||d�|��\}}zt|
||�}Wn#tjy�}zd	j|j�}
|
td<t�|
�WYd}~dSd}~wwd|vr�d
nd}d}tjj�||�dkr�t|
d
�d}n	|r�t|
d
�d}|r�t�
d||t||f�r�d�dSd�dSt�
d||t||f��r
d�dSd�dS)a?
    Change password for a MySQL user

    host
        Host for which this user/password combo applies

    password
        The password to set for the new user. Will take precedence over the
        ``password_hash`` option if both are specified.

    password_hash
        The password in hashed form. Be sure to quote the password because YAML
        doesn't like the ``*``. A password hash can be obtained from the mysql
        command-line client like so::

            mysql> SELECT PASSWORD('mypass');
            +-------------------------------------------+
            | PASSWORD('mypass')                        |
            +-------------------------------------------+
            | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
            +-------------------------------------------+
            1 row in set (0.00 sec)

    allow_passwordless
        If ``True``, then ``password`` and ``password_hash`` can be omitted (or
        set to ``None``) to permit a passwordless login.

    .. versionadded:: 0.16.2
        The ``allow_passwordless`` option was added.

    CLI Examples:

    .. code-block:: bash

        salt '*' mysql.user_chpass frank localhost newpassword
        salt '*' mysql.user_chpass frank localhost password_hash='hash'
        salt '*' mysql.user_chpass frank localhost allow_passwordless=True
    Nrir~rF�User '%s'@'%s' does not existsr�rrhz10.4.0r
rzFLUSH PRIVILEGES;Tz'Password for user '%s'@'%s' has been %s�changedZclearedz&Password for user '%s'@'%s' was not %sr9)r�r�r�r�r�rbrkrPrlr rrIrfrprJr;r:rNr8rrer�r�r�)r`rgrCrr+r�rrUr�rrorVrrWrYrer!rnr�resr9r9r:�user_chpasss�0�
��	���	
�
��

������r?c	
Ks�t||fi|��sd||f}|td<t�|�dStdi|��}|dur&dS|��}d}i}||d<||d<zt|||�Wn#tjya}zdj	|j
�}|td<t�|�WYd}~dSd}~wwt||fi|��stt�d	||�d
St�d||�dS)
z{
    Delete MySQL user

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_remove frank localhost
    r<riFNzDROP USER %(user)s@%(host)sr`rgrhzUser '%s'@'%s' has been removedTz#User '%s'@'%s' has NOT been removedr9)r rbrPrrIrJrNr8rrkrerl)	r`rgrUrorVrWrYrernr9r9r:�user_remove�s6



��r@cCst|�S)z�
    External wrapper function
    :param grant:
    :return: dict

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.tokenize_grant             "GRANT SELECT, INSERT ON testdb.* TO 'testuser'@'localhost'"
    )r�)r�r9r9r:�tokenize_grant�s
rAcK�tg}|dur(t|fi|��}|D]}t�d||�|�t||fi|���q|St�d||�t||fi|��}|S)z�
    Repairs the full database or just a given table

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_check dbname
        salt '*' mysql.db_check dbname dbtable
    Nz Checking table '%s' in db '%s'..)rrPrr�r[�rSrTrUr�r�r9r9r:�db_check�s�rDcKrB)z�
    Repairs the full database or just a given table

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_repair dbname
    Nz!Repairing table '%s' in db '%s'..)rrPrr�r]rCr9r9r:�	db_repair��
�rEcKrB)z�
    Optimizes the full database or just a given table

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.db_optimize dbname
    Nz"Optimizing table '%s' in db '%s'..)rrPrr�r^rCr9r9r:�db_optimize�rFrGcCsN|����dkr
d}t|�}|D]\}}|����tvr$td|�d���q|S)N�ALLrzInvalid grant : 'r�)r�rB�
__grant_split�
__grants__�	Exception)r�Zexploded_grantsZchkgrantr�r9r9r:�__grant_normalize	s�rLcCst�d�}|�|�S)Nz([\w\s]+)(\([^)(]*\))?\s*,?)r��compile�findall)r��patternr9r9r:rI!	s

rIc
Cs�g}|D]9}tt|����}|����}|tvr td|�d���|tvr4|�d�	|||�
dd���q||r=|�|�qdd�|�S)NzInvalid SSL option : 'r�z{} '{}'r6z	 REQUIRE r)�nextr��keysr�rB�__ssl_options__rK�__ssl_options_parameterized__r�rkr�r�)�
ssl_optionZnew_ssl_option�optruZ
normal_keyr9r9r:�__ssl_option_sanitize&	s�
�rVcCs�t�dd|���}t|�}|�d�}|d}|d}	|r0|dkr(t||	dkd�}|	dkr0t|	�}	d|�d	|�d|	�d
�}
i}||d<||d<|rSt|t�rS|
t|�7}
t	j
j�|�r^|
d
7}
t
�d|
t|��|
|d�S)z�
    Validate grants and build the query that could set the given grants

    Note that this query contains arguments for user and host but not for
    grants or database.
    z\s*,\s*z, rGrr�r<�r�zGRANT � ON z TO %(user)s@%(host)sr`rg� WITH GRANT OPTIONz!Grant Query generated: %s args %s)rYre)r��subrBrL�
rpartitionrMr�r�rVr�r�r�rrPrQr�)r�r�r`rg�grant_option�escaperT�db_partrVrTrYrer9r9r:�__grant_generate?	s(

r_c

Kst||fi|��st�d||�dStd
i|��}|durdS|��}d}i}||d<||d<zt|||�Wn#tjyZ}zdj|j	�}|t
d<t�|�WYd}~dSd}~wwg}	tj
j�|���}
|
D]}|d	�d
�d	}d|d	vr�d|vr�|�d�}|	�|�qht�|	�|	S)z�
    Shows the grants for the given MySQL user (if it exists)

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_grants 'frank' 'localhost'
    zUser '%s'@'%s' does not existFNz!SHOW GRANTS FOR %(user)s@%(host)sr`rgrhrirz IDENTIFIED BYzWITH GRANT OPTIONrYr9)r rPrrIrJrNr8rrkrerbrlr�r�r�r�rO�splitr�rQ)
r`rgrUrVrWrYrernror�rZr��tmpr9r9r:�user_grantsl	s:

��

rbcs�tjj�tdi|���}|std}d�|�}	t�|	�dSd|�	�vrCtjj
�|d�dkrAd|vrA|dkrAd	�d
d�t
D��}nd}zt||||||�}
Wntyk}zt�d
�t�|�WYd}~dSd}~wwt||fi|��}|dur�t�d�dSi}
|D]6}t|�}t|d|�|d<|d|
vr�|d|d|d|dd�|
|d<q�|
|dd�|d�q�t|
�}t|d|�|d<|
��D]�\}�zei}i}�fdd�|dD�}dD]&}�|�dd��dd��dd�||<||�dd��dd��dd�||<q�|d|dk�r-|d|dk�r-|d|dk�r-t|��r-WdSt�d�|�Wq�t�yd}z"t�|�|du�rZ|
|v�rZt�d�WYd}~dSWYd}~q�d}~wwt�d�dS) z�
    Checks to see if a grant exists in the database

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.grant_exists              'SELECT,INSERT,UPDATE,...' 'database.*' 'frank' 'localhost'
    rirFrHz8.0rr�z*.*r�cSsg|]}|�qSr9r9�r��ir9r9r:�
<listcomp>�	sz grant_exists.<locals>.<listcomp>rzError during grant generation.Nz�Grant does not exist or may not be ordered properly. In some cases, this could also indicate a connection error. Check your configuration.r�r�r`rg)r`r�rgr�cs g|]}|�dvrdnd�qS)r�TFr9rc�r�r9r:re�	s��)r`r�rgr�r6�\r�Tzgrants mismatch '%s'<>'%s'z
Grant exists.z9Grant does not exist, or is perhaps not ordered properly?r9)r�r�r�r�r�rbrkrPrlrBr�r�r��__all_privileges__r_rKrbr�r��extendr�r��allrQ�	exception)r�r�r`rgr\r]rUr�rro�targetrnr�Z_grantsZgrant_tokenZ
target_tokensZ
_grant_tokensZ_target_tokensZ_grant_matches�itemr9rfr:�grant_exists�	s��


������
����

��
rnc

Ks
tdi|��}|dur
dS|��}	|��}zt|||||||�}
Wnty0t�d�YdSwzt|	|
d|
d�Wn&tj	tj
fyc}zdj|j�}|t
d<t�|�WYd}~dSd}~wwt||||||fi|��r{t�d|||�d	St�d
|||�dS)a
    Adds a grant to the MySQL server.

    For database, make sure you specify database.table or database.*

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.grant_add             'SELECT,INSERT,UPDATE,...' 'database.*' 'frank' 'localhost'
    NFzError during grant generationrYrerhriz/Grant '%s' on '%s' for user '%s' has been addedTz3Grant '%s' on '%s' for user '%s' has NOT been addedr9)rIrJr�r_rKrPrlrNr8rZProgrammingErrorrkrerbrnr)
r�r�r`rgr\r]rTrUrVrWrYrnror9r9r:�	grant_add
sF�
�
������roc
KsTtdi|��}|dur
dS|��}t|�}tjj�|�r |d7}|�d�}	|	d}|	d}
|dkr9t||
dkd�}|dkr?|}|
dkrGt|
�}
d	|�d
|�d|
�d�}i}
||
d<||
d
<zt	|||
�Wn#t
jy�}zdj|j
�}|td<t�|�WYd}~dSd}~wwt||||||fi|��s�t�d|||�dSt�d|||�dS)z�
    Removes a grant from the MySQL server.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.grant_revoke             'SELECT,INSERT,UPDATE' 'database.*' 'frank' 'localhost'
    NFz, GRANT OPTIONrGrr�r<rWzREVOKE rXz FROM %(user)s@%(host)s;r`rgrhriz1Grant '%s' on '%s' for user '%s' has been revokedTz5Grant '%s' on '%s' for user '%s' has NOT been revokedr9)rIrJrLr�r�r�rr[rMrNr8rrkrerbrPrlrnr)r�r�r`rgr\r]rUrVrWr^rTZ
s_databaserYrernror9r9r:�grant_revokeF
s`

������rpc
Ks�g}tdi|��}|durgS|��}t|d�dd�|jD�}t|j�D]}|��}i}t|�D]\}}	|||||<q1|�|�q%|�	�|S)a(
    Retrieves the processlist from the MySQL server via
    "SHOW FULL PROCESSLIST".

    Returns: a list of dicts, with each dict representing a process:

    .. code-block:: python

        {'Command': 'Query',
        'Host': 'localhost',
        'Id': 39,
        'Info': 'SHOW FULL PROCESSLIST',
        'Rows_examined': 0,
        'Rows_read': 1,
        'Rows_sent': 0,
        'State': None,
        'Time': 0,
        'User': 'root',
        'db': 'mysql'}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.processlist

    NzSHOW FULL PROCESSLISTcSsg|]}|d�qS)rr9)r��cr9r9r:re�
szprocesslist.<locals>.<listcomp>r9)
rIrJrNr�r�rdr��	enumerater�r�)
rUr�rVrW�hdrr�r�Zidx_rZidx_jZvalue_jr9r9r:�processlist�
s
rtcCst��jj}t�d||�g}d}z|��}Wntjy6t�	d||�|r,|�
�t�d|�|YSwzt||�Wntjy[t�	d||�|�
�t�d|�|YSw|��}|D]}d}i}|j
D]}	|	d}
||||
<|d7}qk|�|�qb|�
�t�d|�|S)zd
    Perform the query that is passed to it (sql_str).

    Returns:
       results in a dict.

    z	%s<--(%s)Nz %s: Can't get cursor for SQL->%sz%s-->z%s: try to execute : SQL->%srr�)�sys�	_getframe�f_code�co_namerPrQrJr8Z
MySQLErrorrlr�rNrOr�r�)�connZsql_str�modZrtn_resultsrJZqrsZrow_dataZcol_cntr�Zcol_dataZcol_namer9r9r:�__do_query_into_hash�
sB��

r{cK�pt��jj}t�d|�tdi|��}|durgSt|d�}|��|s)|�	g�t�d|t
|d��|dS)a_
    Retrieves the master status from the minion.

    Returns::

        {'host.domain.com': {'Binlog_Do_DB': '',
                         'Binlog_Ignore_DB': '',
                         'File': 'mysql-bin.000021',
                         'Position': 107}}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.get_master_status

    �%s<--NzSHOW MASTER STATUS�%s-->%srr9�rurvrwrxrPrQrIr{r�r�rr�rUrzryZrtnvr9r9r:�get_master_status�
s

r�cKr|)a�
    Retrieves the slave status from the minion.

    Returns::

        {'host.domain.com': {'Connect_Retry': 60,
                       'Exec_Master_Log_Pos': 107,
                       'Last_Errno': 0,
                       'Last_Error': '',
                       'Last_IO_Errno': 0,
                       'Last_IO_Error': '',
                       'Last_SQL_Errno': 0,
                       'Last_SQL_Error': '',
                       'Master_Host': 'comet.scion-eng.com',
                       'Master_Log_File': 'mysql-bin.000021',
                       'Master_Port': 3306,
                       'Master_SSL_Allowed': 'No',
                       'Master_SSL_CA_File': '',
                       'Master_SSL_CA_Path': '',
                       'Master_SSL_Cert': '',
                       'Master_SSL_Cipher': '',
                       'Master_SSL_Key': '',
                       'Master_SSL_Verify_Server_Cert': 'No',
                       'Master_Server_Id': 1,
                       'Master_User': 'replu',
                       'Read_Master_Log_Pos': 107,
                       'Relay_Log_File': 'klo-relay-bin.000071',
                       'Relay_Log_Pos': 253,
                       'Relay_Log_Space': 553,
                       'Relay_Master_Log_File': 'mysql-bin.000021',
                       'Replicate_Do_DB': '',
                       'Replicate_Do_Table': '',
                       'Replicate_Ignore_DB': '',
                       'Replicate_Ignore_Server_Ids': '',
                       'Replicate_Ignore_Table': '',
                       'Replicate_Wild_Do_Table': '',
                       'Replicate_Wild_Ignore_Table': '',
                       'Seconds_Behind_Master': 0,
                       'Skip_Counter': 0,
                       'Slave_IO_Running': 'Yes',
                       'Slave_IO_State': 'Waiting for master to send event',
                       'Slave_SQL_Running': 'Yes',
                       'Until_Condition': 'None',
                       'Until_Log_File': '',
                       'Until_Log_Pos': 0}}

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.get_slave_status

    r}NzSHOW SLAVE STATUSr~rr9rr�r9r9r:�get_slave_statuss6

r�cK�lt��jj}t�d|�tdi|��}|durgSt|d�}|��|s)|�	g�t�d|t
|d��|S)z�
    Retrieves the show variables from the minion.

    Returns::
        show variables full dict

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.showvariables

    r}NzSHOW VARIABLESr~rr9rr�r9r9r:�
showvariablesY�

r�cKr�)z�
    Retrieves the show global variables from the minion.

    Returns::
        show global variables full dict

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.showglobal

    r}NzSHOW GLOBAL VARIABLESr~rr9rr�r9r9r:�
showglobalur�r�cKs<||d<||d<tdi|��}|durdtvrtd=dSdS)z�
    Attempt to login using the provided credentials.
    If successful, return true.  Otherwise, return False.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.verify_login root password
    r}r~NriFTr9)rIrb)r`rCrUrVr9r9r:�verify_login�sr�c	
Ks�tdi|��}|dur
gS|��}d}zt||�Wn$tjy>}zdj|j�}|td<t�	|�gWYd}~Sd}~wwg}|�
�}|D]}|�|d|dd��qGt�|�|S)	z�
    Return a list of plugins and their status
    from the ``SHOW PLUGINS`` query.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.plugins_list
    NzSHOW PLUGINSrhrirr�)rSr�r9r�r�r9r9r:�plugins_list�s(
��
r�c
Ks�|s	t�d�dSt|fi|��rt�d|�dStdi|��}|dur&dS|��}d|��}|r:|d|�d�7}n|d|�d	�7}zt||�WdStjym}zd
j|j	�}|t
d<t�|�WYd}~dSd}~ww)
zs
    Add a plugina.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.plugin_add auth_socket
    �Plugin name is required.FzPlugin %s is already installed.TNzINSTALL PLUGIN z	 SONAME "r�z.so"rhrir9�rPrlr*rIrJrNr8rrkrerb)rSZsonamerUrVrWrYrnror9r9r:�
plugin_add�s0


�
��r�c
Ks�|s	t�d�dSt|fi|��st�d|�dStd
i|��}|dur&dS|��}d|��}i}||d<zt||�WdStjy`}zdj|j	�}|t
d	<t�|�WYd}~dSd}~ww)zx
    Remove a plugin.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.plugin_remove auth_socket
    r�FzPlugin %s is not installed.TNzUNINSTALL PLUGIN rSrhrir9r�)rSrUrVrWrYrernror9r9r:�
plugin_remove�s.


�
��r�c	
Ks�|s	t�d�dStd
i|��}|durdS|��}d}i}||d<zt|||�Wn#tjyM}zdj|j�}|t	d<t�|�WYd}~dSd}~wwz|�
�}|durZWdS|d	WStyhYdSw)z�
    Return the status of a plugin.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.plugin_status auth_socket
    r�FNr6zQSELECT PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = %(name)srSrhrirr9)rPrlrIrJrNr8rrkrerbr�rs)	rSrUrVrWrYrernror�r9r9r:r*s8

�
��
�r*)Fr�)NN)rNNFFNrj)rNNFFN)r)rNNFNNrj)rNNFNN)rFTF)rFT)^�__doc__r�r=�loggingr�r�r�rur�Zsalt.utils.datar�Zsalt.utils.filesZsalt.utils.stringutilsr8ZMySQLdb.convertersZMySQLdb.cursorsrZMySQLdb.constantsrrr�ImportErrorZpymysqlZinstall_as_MySQLdbr�r��	getLogger�__name__rPrJrSrRrhr;rEr[r]r^rfrprIr�r�rMrNr�r�r�r�r�r�r�r�rrrrr	r
rrrr r"r,r/r1r:r;r?r@rArDrErGrLrIrVr_rbrnrorprtr{r�r�r�r�r�r�r�r�r*r9r9r9r:�<module>sp����
>.Hb,
=
["*.
!"#%
5,
�/
�#
�
j"
�A
�0
�
�X
�J
�
)



�
--
�|
�=
�M.0"F

!(%