HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.29
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/__pycache__/postgres.cpython-310.pyc
o

�N�g�`�@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddl
ZddlZddlZddlZddlmZmZddlmZddlmZzddlZdZWneyedZYnwzddlmZWney}dd	lmZYnwe�e�Z d
Z!dZ"dZ#dZ$d
Z%dZ&e#e$e%e&fZ'dddddddddddddd�
Z(e)d�Z*ddd d!d"d#d$d%�Z+d&d'�Z,d(d)�Z-d�d*d+�Z.	,			-				d�d.d/�Z/	d�d0d1�Z0	d�d2d3�Z1d�d4d5�Z2d6d7�Z3	d�d8d9�Z4							d�d:d;�Z5	d�d<d=�Z6						d�d>d?�Z7d�dAdB�Z8												d�dCdD�Z9									d�dEdF�Z:						d�dGdH�Z;	d�dIdJ�Z<						d�dKdL�Z=								d�dMdN�Z>										d�dOdP�Z?						d�dQdR�Z@							d�dSdT�ZA							d�dUdV�ZB						d�dWdX�ZCd�d[d\�ZDe!fd]d^�ZEd_d`�ZFdadb�ZGd�ddde�ZH	Z	f												d�dgdh�ZI																f		d�didj�ZJ																	d�dkdl�ZK							f											d�dmdn�ZL																	d�dodp�ZM						d�dqdr�ZN	d�dsdt�ZO	d�dudv�ZP						d�dwdx�ZQ						d�dydz�ZR						d�d{d|�ZSd}d~�ZT						d�dd��ZU								d�d�d��ZV									d�d�d��ZW										d�d�d��ZX						d�d�d��ZY															d�d�d��ZZ															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��Za	d�d�d��Zb	d�d�d��Zc	d�d�d��Zd	d�d�d��Ze	d�d�d��Zfd�d��Zg	�						d�d�d��Zhd�d��Zid�d��Zjd�d��Zk	�						d�d�d��Zl			�						d�d�d��Zm			�						d�d�d��Zn		�						d�d�d��Zo	,			-				d�d�d��Zpd�d��ZqdS)�a�
Module to provide Postgres compatibility to salt.

:configuration: In order to connect to Postgres, certain configuration is
    required in /etc/salt/minion on the relevant minions. Some sample configs
    might look like::

        postgres.host: 'localhost'
        postgres.port: '5432'
        postgres.user: 'postgres' -> db user
        postgres.pass: ''
        postgres.maintenance_db: 'postgres'

    The default for the maintenance_db is 'postgres' and in most cases it can
    be left at the default setting.
    This data can also be passed into pillar. Options passed into opts will
    overwrite options passed into pillar

To prevent Postgres commands from running arbitrarily long, a timeout (in seconds) can be set

    .. code-block:: yaml

        postgres.timeout: 60

    .. versionadded:: 3006.0

:note: This module uses MD5 hashing which may not be compliant with certain
    security audits.

:note: When installing postgres from the official postgres repos, on certain
    linux distributions, either the psql or the initdb binary is *not*
    automatically placed on the path. Add a configuration to the location
    of the postgres bin's path to the relevant minion for this module::

        postgres.bins_dir: '/usr/pgsql-9.5/bin/'
�N)�CommandExecutionError�SaltInvocationError)�saslprep��LooseVersionTF)�token_bytes)�urandom�md5zEXTENSION NOT INSTALLEDzEXTENSION INSTALLEDzEXTENSION TO UPGRADEzEXTENSION TO MOVEZINSERTZCREATEZTRUNCATEZCONNECTZTRIGGERZSELECTZUSAGEZ	TEMPORARYZUPDATEZEXECUTEZ
REFERENCESZDELETEZGRANT)
�a�C�D�c�t�r�U�T�w�X�x�d�*)�schema�
tablespace�language�sequence�table�group�database�functionZarwdDxtrrZrwUZUCZCTcr)rrrrrrrcCsDdg}tsdS|D]}tjj�|�st|�sd|�d�fSq	dS)z�
    Only load this module if the psql bin exist.
    initdb bin might also be used, but its presence will be detected on runtime.
    �psqlFz was not foundT)�HAS_CSV�salt�utils�path�which�_find_pg_binary)r"�util�r'�I/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/postgres.py�__virtual__|s�r)cCsBtdd�}tjj�|�}|s|rtjj�tj�||��SdS|S)za
    .. versionadded:: 2016.3.2

    Helper function to locate various psql related binaries
    �
config.optionzpostgres.bins_dirN)�__salt__r!r"r#r$�os�join)r&Z
pg_bin_dirZutil_binr'r'r(r%�s�r%c
Cs�ddtddtd�d�}|dur3|stdd�}|r|�d	�r3d
tdvr(d}nd
tdvr1d}nd}|dur9|}|r?||d<|durItdd�}|dur�tjjjdd�}tjj�|d��7}|�	tjj
�d�|rm|�d	�rodn||rt|nd|ry|nd|���td||d�d|i|d<Wd�n1s�wYtd|fddi|��}	|	�
dd�dkr�t�d�|dur�td|�s�t�d �|	S)!z�
    Helper function to call psql, because the password requirement
    makes this too much code to be repeated in each function below
    FTr*�postgres.timeout��default)Zreset_system_locale�	clean_env�timeoutN�
postgres.host�/�FreeBSD�	os_family�postgres�OpenBSD�_postgresql�runasz
postgres.pass��textrz
{}:{}:*:{}:{}Z	localhostr�
file.chown�Z
PGPASSFILE�env�cmd.run_all�python_shell�retcoderz%Error connecting to Postgresql server�file.removezRemove PGPASSFILE failed)r+�_DEFAULT_COMMAND_TIMEOUT_SECS�
startswith�
__grains__r!r"�files�mkstemp�fopen�write�stringutils�to_str�format�get�log�error�warning)
�cmdr:�password�host�port�user�kwargs�
pgpassfile�fp_�retr'r'r(�	_run_psql�sV��

���
�

r[rS�UTF8c	Cs�|durdtdvr
d}ndtdvrd}nd}|dur|}td�}	|	s(td��|	d	|��d
|��d|��d|��g}
|durG|
�d
|���|durU|
�d�|
�|�|r\|
�d�|dur�tjjjdd�}tjj�|d��}|�	tjj
�|���td||d�Wd�n1s�wY|
�
d|��g�t|dtddtd�d�}
t�|
�}td|fddi|
��}|�dd�dkr�t�d�|dur�td |�s�t�d!�|S)"z(
    Helper function to call initdb
    Nr5r6r7r8r9Zinitdbzinitdb executable not found.z	--pgdata=z--username=z--auth=z--encoding=z	--locale=z-Xz--data-checksumsTr;rr=r>z	--pwfile=r*r.r/)r:r1r2r@rAFrBrz-Error initilizing the postgres data directoryrCzRemoval of PGPASSFILE failed)rFr%r�appendr!r"rGrHrIrJrKrLr+�extend�dictrD�shlexr-rNrOrPrQ)�name�authrVrS�encoding�localer:�waldir�	checksumsZ_INITDB_BINrRrXrYrWZcmdstrrZr'r'r(�_run_initdb�sZ�


���


rgc

CsTd}td|d|||||d�}t||||||d�}tjj�|dd�D]}	|	SdS)	z�
    Return the version of a Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.version
    zHSELECT setting FROM pg_catalog.pg_settings WHERE name = 'server_version'�-cz-t)rTrVrU�maintenance_dbrS�r:rSrTrUrV�stdout�
N)�	_psql_cmdr[r!r"�	itertools�split)
rVrTrUrirSr:�queryrRrZ�liner'r'r(�versions"�
��rrcCs.t||||||d�}|rt|�St�d�dS)z�
    Returns the server version properly parsed and int casted for internal use.

    If the Postgres server does not respond, None will be returned.
    )rTrUrirSr:zMAttempt to parse version of Postgres server failed. Is the server responding?N)rrrrOrQ)rVrTrUrirSr:Zpsql_versionr'r'r(�_parsed_version<s	�	�rscCsL|stdd�}|stdd�}|stdd�}|s tdd�}||||fS)zz
    Returns a tuple of (user, host, port, db) with config, pillar, or default
    values assigned to missing values.
    r*z
postgres.userr3z
postgres.portzpostgres.maintenance_db)r+)rVrTrUrir'r'r(�_connection_defaultsXsrtcOs�t|�d�|�d�|�d�|�d��\}}}}td�}|dddd	g}|r*|d
|g7}|r2|d|g7}|r<|dt|�g7}|s@d
}|�d|g�|�|�|S)z�
    Return string with fully composed psql command.

    Accepts optional keyword arguments: user, host, port and maintenance_db,
    as well as any number of positional arguments to be added to the end of
    the command.
    rVrTrUrirz
--no-alignz
--no-readlinez--no-psqlrcz
--no-passwordz
--usernamez--hostz--portr7z--dbname)rtrNr%�strr^)�argsrWrVrTrUriZ	_PSQL_BINrRr'r'r(rmis0��
rmc	Cs,t|||||d��}t||||||d�}|S)N)rTrVrUrirj)rmr[)	rRrTrUrirSr:rVZrcmd�cmdretr'r'r(�_psql_prepare_and_run�s
��rxc	Cs�g}d�|���d��}	|rd�|	�}	tddd|	g||||||d�}
|
dd	kr*|St�|
d
�}i}tj|tj	j
�d�tj	j
�d�d
�D]}
|
sJqE|sO|
}qE|�t
t||
���qE|rb|d	d�}|S)a�
    Run an SQL-Query and return the results as a list. This command
    only supports SELECT statements.  This limitation can be worked around
    with a query like this:

    WITH updated AS (UPDATE pg_authid SET rolconnlimit = 2000 WHERE
    rolname = 'rolename' RETURNING rolconnlimit) SELECT * FROM updated;

    query
        The query string.

    user
        Database username, if different from config or default.

    host
        Database host, if different from config or default.

    port
        Database port, if different from the config or default.

    maintenance_db
        The database to run the query against.

    password
        User password, if different from the config or default.

    runas
        User to run the command as.

    write
        Mark query as READ WRITE transaction.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.psql_query 'select * from pg_stat_activity'
    z#COPY ({}) TO STDOUT WITH CSV HEADER�;z5START TRANSACTION READ WRITE; {}; COMMIT TRANSACTION;z-vzdatestyle=ISO,MDYrh�r:rTrVrUrirSrBrrk�,�")�	delimiterZ	quotechar���)rM�strip�rstriprx�io�StringIO�csv�readerr!r"rKrLr]r_�zip)rprVrTrUrirSr:rJrZZ	csv_queryrwZcsv_file�header�rowr'r'r(�
psql_query�sB0�
�	
�r�c
	CsJi}d}t|||||||d�}|D]}	|	||	d<||	d�d�q|S)z�
    Return dictionary with information about databases of a Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.db_list
    a6SELECT datname as "Name", pga.rolname as "Owner", pg_encoding_to_char(encoding) as "Encoding", datcollate as "Collate", datctype as "Ctype", datacl as "Access privileges", spcname as "Tablespace" FROM pg_database pgd, pg_roles pga, pg_tablespace pgts WHERE pga.oid = pgd.datdba AND pgts.oid = pgd.dattablespacerz�Name)r��pop�
rVrTrUrirSr:rZrp�rowsr�r'r'r(�db_list�s 
�	�
r�cC�t||||||d�}||vS)z�
    Checks if a database exists on the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.db_exists 'dbname'
    �rVrTrUrirSr:)r�)rarVrTrUrirSr:Z	databasesr'r'r(�	db_exists"s�r��'cCs6|durdS||vrtd|�d|����dj||d�S)NzUnsupported character z in value: z{quote}{value}{quote})�quote�value)rrM)r�r�r'r'r(�_quote_ddl_valueAs
r�c

Cs�d|�d�}
tjj�dt|d�fdt|
d�fd|fdt|�fdt|�fdt|	�fg�}g}|��D]\}}|d	ur@||d
|g7}q1|rP|�dd�|
d
�|�7}
td|
g||||||d�}|ddkS)z�
    Adds a databases to the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.db_create 'dbname'

        salt '*' postgres.db_create 'dbname' template=template_postgis

    zCREATE DATABASE "r|Z
TABLESPACEZOWNER�TEMPLATE�ENCODING�
LC_COLLATE�LC_CTYPEN�=r� WITH� rhr�rB)	r!r"Zodict�OrderedDictr��items�insertr-rx)rarVrTrUrirSrrcZ
lc_collateZlc_ctype�owner�templater:rpZ	with_argsZwith_chunks�keyr�rZr'r'r(�	db_createIs8


����	r�c


Cs�t||f�sdS|r|rt|||||||	d�}
n0g}|r(|�d|�d|�d��|r6|�d|�d|�d��|D]}td|g||||||	d�}
q8|
d	d
krPdSdS)z�
    Change tablespace or/and owner of database.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.db_alter dbname owner=otheruser
    T�rVrTrUrSr:zALTER DATABASE "�" OWNER TO "r|z" SET TABLESPACE "rhr�rBrF)�any�owner_tor]rx)
rarVrTrUrirSrr�Z
owner_recurser:rZ�queriesrpr'r'r(�db_alter�s0��
r�c	
Cs`d|�d�dj|d�d|�d�fD]}td|g||||||d�}|d	d
kr-td|����qdS)
z�
    Removes a databases from the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.db_remove 'dbname'
    zREVOKE CONNECT ON DATABASE "z" FROM public;zoSELECT pid, pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '{db}' AND pid <> pg_backend_pid();)ZdbzDROP DATABASE "�";rh�rVrTrUr:rirSrBrzFailed: ret=T)rMrx�	Exception�	rarVrTrUrirSr:rprZr'r'r(�	db_remove�s&
�
��	�r�c
	CsNi}d}td|||||||d�}|D]}	|	||	d<||	d�d�q|S)z�
    Return dictionary with information about tablespaces of a Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.tablespace_list

    .. versionadded:: 2015.8.0
    z�SELECT spcname as "Name", pga.rolname as "Owner", spcacl as "ACL", spcoptions as "Opts", pg_tablespace_location(pgts.oid) as "Location" FROM pg_tablespace pgts, pg_roles pga WHERE pga.oid = pgts.spcownerzpostgres.psql_queryrzr�)r+r�r�r'r'r(�tablespace_list�s ��
r�cCr�)z�
    Checks if a tablespace exists on the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.tablespace_exists 'dbname'

    .. versionadded:: 2015.8.0
    r�)r�)rarVrTrUrirSr:Ztablespacesr'r'r(�tablespace_existss�r�c
	Cstd}
d}|rd|�d�}
|rdd�|��D�}d�d�|��}d�||
||�}
td	|
g||||||	d
�}|ddkS)
z�
    Adds a tablespace to the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.tablespace_create tablespacename '/path/datadir'

    .. versionadded:: 2015.8.0
    r>zOWNER "r|cSsg|]\}}|�d|���qS)z = r')�.0�k�vr'r'r(�
<listcomp>Lsz%tablespace_create.<locals>.<listcomp>zWITH ( {} )z, z*CREATE TABLESPACE "{}" {} LOCATION '{}' {}rhr�rBr)r�rMr-rx)ra�location�optionsr�rVrTrUrirSr:Zowner_queryZ
options_queryZoptionstextrprZr'r'r(�tablespace_create/s(��	r�c
Cs�t||||	g�s
dSg}|r|�d|�d|�d��|r(|�d|�d|�d��|r<|�dj|gtt|�����R��|	rJ|�d|�d|	�d��|D]}td	|g||||||
d
�}
|
ddkrdd
SqLdS)a�
    Change tablespace name, owner, or options.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.tablespace_alter tsname new_owner=otheruser
        salt '*' postgres.tablespace_alter index_space new_name=fast_raid
        salt '*' postgres.tablespace_alter test set_option="{'seq_page_cost': '1.1'}"
        salt '*' postgres.tablespace_alter tsname reset_option=seq_page_cost

    .. versionadded:: 2015.8.0
    TzALTER TABLESPACE "z
" RENAME TO "r|r�z#ALTER TABLESPACE "{}" SET ({} = {})z	" RESET (�)rhr�rBrF)r�r]rM�next�iterr�rx)rarVrTrUrirS�new_nameZ	new_ownerZ
set_optionZreset_optionr:r�rprZr'r'r(�tablespace_alter`s>����	�r�c		Cs2d|�d�}td|g||||||d�}|ddkS)z�
    Removes a tablespace from the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.tablespace_remove tsname

    .. versionadded:: 2015.8.0
    zDROP TABLESPACE "r|rhr�rBr)rxr�r'r'r(�tablespace_remove�s�	r�c
s\i}t||||||d�}|r%|td�krd}	nd}	|td�kr"d}
n
d}
nt�d�dS�fd	d
�}d�d|d
�d|d�|d�g��|
|	�}t|||||||d�}
dd�}|
D]T}i}dD]	}|||�||<q]dD]}z
tj�||d�||<Wqit	y�d||<Yqiw|d|d<�r�|d|d<t
t�|d�
d�g��d|d<|||d<qW|S)z�
    Return a dict with information about users of a Postgres server.

    Set return_password to True to get password hash in the result.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.user_list
    r�z9.1zpg_roles.rolreplicationZNULLz9.5zpg_roles.rolcatupdatezBCould not retrieve Postgres version. Is Postgresql server running?Fcs�r|SdS)Nr>r')�s��return_passwordr'r(�_x�szuser_list.<locals>._xr>a�SELECT pg_roles.rolname as "name",pg_roles.rolsuper as "superuser", pg_roles.rolinherit as "inherits privileges", pg_roles.rolcreaterole as "can create roles", pg_roles.rolcreatedb as "can create databases", {0} as "can update system catalogs", pg_roles.rolcanlogin as "can login", {1} as "replication", pg_roles.rolconnlimit as "connections", (SELECT array_agg(pg_roles2.rolname)    FROM pg_catalog.pg_auth_members    JOIN pg_catalog.pg_roles pg_roles2 ON (pg_auth_members.roleid = pg_roles2.oid)    WHERE pg_auth_members.member = pg_roles.oid) as "groups",pg_roles.rolvaliduntil::timestamp(0) as "expiry time", pg_roles.rolconfig  as "defaults variables" zB, COALESCE(pg_shadow.passwd, pg_authid.rolpassword) as "password" zFROM pg_roles z4LEFT JOIN pg_authid ON pg_roles.oid = pg_authid.oid z8LEFT JOIN pg_shadow ON pg_roles.oid = pg_shadow.usesysidrzcSs$||dkrdS||dkrdSdS)zW
        Returns the boolean value of the key, instead of 't' and 'f' strings.
        rT�fFNr')Zrowdictr�r'r'r(�get_bools
zuser_list.<locals>.get_bool)�	superuserzinherits privilegeszcan create roleszcan create databaseszcan update system catalogsz	can login�replicationZconnections)zexpiry timez%Y-%m-%d %H:%M:%SNzdefaults variablesrS�groups�{}rra)rsrrOrPr-rMr��datetime�strptime�
ValueError�listr�r�r)rVrTrUrirSr:r�rZ�verZreplication_columnZrolcatupdate_columnr�rpr�r�r��retrowr�Zdate_keyr'r�r(�	user_list�sr�

����

��"r�c		CsDt|||||||d�}z|�|d�WSty!t�d�YdSw)z�
    Return a dict with information about users of a Postgres server.

    Set return_password to True to get password hash in the result.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.role_get postgres
    �rVrTrUrirSr:r�Nz6Could not retrieve Postgres role. Is Postgres running?)r�rN�AttributeErrorrOrP)	rarVrTrUrirSr:r�Z	all_usersr'r'r(�role_get7s�	
�r�cCstt|||||||dd��S)z�
    Checks if a user exists on the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.user_exists 'username'
    Fr�)�boolr��rarVrTrUrirSr:r'r'r(�user_exists\s��r��NOr>cCsT|s(|dur|}|dur|r|�d|��}n	|�d|�|��}|r(|�d|��}|S)Nr�r')�string�test�flag�cond�prefix�addtxt�skipr'r'r(�_add_role_flag|sr�cCs�|dur	t|�}ndS|durd}|dvrtdt|���|dkr,|�d�s,t|�}|S|dkrA|�d�sAt�d�t||�}|S|durJt�d	�|S)
NTr	)Fr	�
scram-sha-256zUnknown password algorithm: r��
SCRAM-SHA-256z:The md5 password algorithm was deprecated in PostgreSQL 10Fz3Unencrypted passwords were removed in PostgreSQL 10)rur�rE�_scram_sha_256rOrQ�
_md5_password)�rolerS�	encryptedr'r'r(�_maybe_encrypt_password�s"
�

�
r�cCs�|dks|dur|�d�r|}||kSt||�}||kS|dkrT|�d�r+|}||kSt�d|�}|rMt|�d��}t�|�d��}t|||d�}||kSt	�}||kS|d	ur^|}||kSt	�}||kS)
z�
    Test the given password against the verifier.

    The given password may already be a verifier, in which case test for
     simple equality.
    r	Tr�r�z!^SCRAM-SHA-256\$(\d+):([^\$]+?)\$��)�
salt_bytes�
iterationsF)
rEr��re�match�intr�base64�	b64decoder��object)r�rSZverifier�method�expectedr�r�r�r'r'r(�_verify_password�s2

��
��
���r�cCs&d�t�tjj�|�|�������S)Nzmd5{})rM�hashlibr	r!r"rK�to_bytes�	hexdigest)r�rSr'r'r(r��s��r��cCs�|durtd�}tjj�t|��}t�d|||�}t�	|dd��
�}t�|��
�}t�	|dd��
�}d�|t
�|��d�t
�|��d�t
�|��d��S)zw
    Build a SCRAM-SHA-256 password verifier.

    Ported from https://doxygen.postgresql.org/scram-common_8c.html
    N��sha256s
Client Keys
Server KeyzSCRAM-SHA-256${}:{}${}:{}�ascii)rr!r"rKr�rr��pbkdf2_hmac�hmac�new�digestr�rMr��	b64encode�decode)rSr�r�Zsalted_passwordZ
stored_keyZ
server_keyr'r'r(r��s�r�r�cCs�|dur
|dvr
d}|dur|dkrd}|dkrd}|dur t}d}d}d}|dur3t|t�r3t|�s:t|t�s:d}t|t�rQt|�rQd�t||�dd	�|d
��}t|
t�rct|
�rcd�|
�dd	��}d}t|�rut|	�t|d�krud}d|d
�d|d
�d|d
�d|	|d�d|d
�d|d
�dt|�t|�|dud�d|duo�t|�|p�t|t�t|�dd�dt|�||d�dt|
�|
du|d�f
}|D]
}t|fi|��}q�|�d�r�|�dd�}|
r�t|
t	�r�d�
|
�}
|
�d�D]
}|�d|�d |�d!�}q�|S)"N)rVrTrVrFr>z'{}'r�z'')r�r�ZINHERIT)r�r�ZCREATEDBZ
CREATEROLEZ	SUPERUSER)r�r�r�ZREPLICATIONZLOGINzCONNECTION LIMIT)r�r�r�r�Z	ENCRYPTEDZUN)r�r�r�r�r�ZPASSWORD)r�r�r�r�zVALID UNTIL�WITHr�r{z	; GRANT "z" TO "r|)�_DEFAULT_PASSWORDS_ENCRYPTION�
isinstancerur�rMr��replacer��endswithr�r-ro)ra�sub_cmd�typ_r��login�	connlimit�inherit�createdb�createrolesr�r�r��rolepassword�valid_until�db_roleZskip_passwdZescaped_passwordZescaped_valid_untilZskip_superuser�flags�datarr'r'r(�_role_cmd_args�s������
�
�����!


rcCs�t|||||||d�rt�d|��|�dSd|�d�}d�|t||||
|||||	||
||d�
�}td|g||||||d	�}|d
dkS)z|
    Creates a Postgres role. Users and Groups are both roles in postgres.
    However, users can login, groups cannot.
    �rSr:z%s '%s' already existsFz
CREATE ROLE "�" WITH�{} {})rr�rrrrr	r�r�r�r
rrhrzrBr)r�rO�info�
capitalizerMrrx)rarVrTrUrirSrr	r�r�rrrr�r
rrr�r:rrZr'r'r(�_role_create?sD����
rcCsxt|fidd�d|�d|�d|�d|�d|�d|�d|�d	|�d
|	�d|
�d|�d
|�d|
�d|�d|�d|�d|��S)a
    Creates a Postgres user.

    CLI Examples:

    .. code-block:: bash

        salt '*' postgres.user_create 'username' user='user' \
                host='hostname' port='port' password='password' \
                rolepassword='rolepassword' valid_until='valid_until'
    rrVrTrUrirSrr	rrrr�r�r�r
rr�r:�r)�usernamerVrTrUrirSrr	rrrr�r�r�r
rr�r:r'r'r(�user_create��N��������	�
���
�������rcCs�t|||||||dd�}t|�st�d|��|�dSd|�d�}d�|t|||
||	|||
|||||d�
�}td|g||||||d	�}|d
dkS)z"
    Updates a postgres role.
    Fr�z%s '%s' could not be foundzALTER ROLE "rr)r�rrrrr	r�r�r�r
rrrhrzrBr)r�r�rOrrrMrrx)rarVrTrUrirSrrr	rrrr�r�r�r
rr�r:r�rrZr'r'r(�_role_update�sT����
rcCsxt|fid|�d|�d|�d|�d|�dd�d|
�d|�d	|�d
|�d|�d|�d
|	�d|
�d|�d|�d|�d|��S)a
    Updates a Postgres user.

    CLI Examples:

    .. code-block:: bash

        salt '*' postgres.user_update 'username' user='user' \
                host='hostname' port='port' password='password' \
                rolepassword='rolepassword' valid_until='valid_until'
    rVrTrUrirSrrrrrr	r�r�r�r
rr�r:�r)rrVrTrUrirSrr	r�r�rrrr�r
rr�r:r'r'r(�user_update�rrc	Csvt|||||||d�st�d|�dSd|�d�}td|g||||||d�t|||||||d�s3dSt�d	|�dS)
z1
    Removes a role from the Postgres Server
    rzUser '%s' does not existFzDROP ROLE "r|rhrzTzFailed to delete user '%s'.)r�rOrrx)rarVrTrUrirSr:rr'r'r(�_role_remove4s*��
�rc
	C�Lg}d}t|||||||d�}i}|D]}	d|	vr#d|	vr#|	||	d<q|S)z�
    List available postgresql extensions

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.available_extensions

    z(select * from pg_available_extensions();r�Zdefault_versionra�r��
rVrTrUrirSr:�extsrprZr�r'r'r(�available_extensions]s"
�	�r"c
	Cr)z�
    List installed postgresql extensions

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.installed_extensions

    zgselect a.*, b.nspname as schema_name from pg_extension a,  pg_namespace b where a.extnamespace = b.oid;r��
extversionZextnamerr r'r'r(�installed_extensions|s$
��	�r$cC�t||||||d��|d�S)z�
    Get info about an available postgresql extension

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.get_available_extension plpgsql

    r�N)r"rNr�r'r'r(�get_available_extension����r&cCr%)z�
    Get info about an installed postgresql extension

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.get_installed_extension plpgsql

    r�N)r$rNr�r'r'r(�get_installed_extension�r'r(cCs2t||||||d�}|��dd�|D�vrdSdS)z�
    Test if a specific extension is available

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.is_available_extension

    r�cSsg|]}|���qSr')�lower)r�r
r'r'r(r���z*is_available_extension.<locals>.<listcomp>TF)r"r))rarVrTrUrirSr:r!r'r'r(�is_available_extension�s�r+cCst|�t|�kS)z�
    Compare versions of extensions using `looseversion.LooseVersion`.

    Returns ``True`` if version a is lesser than b.
    r)r
�br'r'r(�_pg_is_older_ext_ver�sr-c	Cst|||||||d�}t|�S)z�
    Test if a specific extension is installed

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.is_installed_extension

    r�)r(r�)rarVrTrUrirSr:�
installed_extr'r'r(�is_installed_extensions�	r/c		Cs�t|||||||d�}	tg}
|	r>tg}
|dur%t|	�d|�|�r%|
�t�|dur>|	�dd�dkr>|	�d|�|kr>|
�t�|
S)z�
    Get lifecycle information about an extension

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.create_metadata adminpack

    r�Nr#Zextrelocatabler�rZschema_name)r(�_EXTENSION_NOT_INSTALLED�_EXTENSION_INSTALLEDr-rNr]�_EXTENSION_TO_UPGRADE�_EXTENSION_TO_MOVE)ra�ext_versionrrVrTrUrirSr:r.rZr'r'r(�create_metadata s*�	
�

r5c

	Cs�|durd}|durd}|durd}dg}
|r|
�d�|
�|�|r(|
�d�|r/|
�d�|
�d�d	�|
�}t|||||||	d
�rQtd|g|	|||||d�t|||||||	d
�}|set�d
|�|S)z�
    Drop an installed postgresql extension

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.drop_extension 'adminpack'

    NTFzDROP EXTENSIONz	IF EXISTSZCASCADEZRESTRICTryr�r�rhrzzFailed to drop ext: %s)r]r-r/rxrOr)
raZ	if_existsZrestrictZcascaderVrTrUrirSr:rvrRrZr'r'r(�drop_extensionNs\





�	�	�	r6cCs�|durd}t||||||||	|
d�	}t|v}t||||||	|
d�}
|
r�|ssdg}|r0|�d�|�d|�d��g}|rF|�d|�d��|rP|�d	|���|rZ|�d
|���|rf|�d�|�|�|�d�d
�|���}n-g}|r�t|vr�|�d|�d|�d��|r�t|vr�|�d|�d|�d��d
�|���}|r�t	d|g|
|||||	d�t||||||||	|
d�	}d}t
D]}||vr�|tkr�d}q�|s�t�
d|�|S)z�
    Install a postgresql extension

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.create_extension 'adminpack'

    NT)r4rrVrTrUrirSr:r�zCREATE EXTENSIONz
IF NOT EXISTSr|zSCHEMA "zVERSION zFROM r�ryr�zALTER EXTENSION "z" SET SCHEMA "r�z" UPDATE TO rhrzFzFailed to create ext: %s)r5r0r+r]r^r-rr3r2rx�_EXTENSION_FLAGSr1rOr)raZ
if_not_existsrr4Zfrom_versionrVrTrUrirSr:ZmtdataZ	installedZinstallablervZsargsrRrZ�ir'r'r(�create_extension�s���	



�	��r9c	C�t|||||||d�S)z�
    Removes a user from the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.user_remove 'username'
    r��r)rrVrTrUrirSr:r'r'r(�user_remove���r<cCslt|fid|�dd�d|�d|�d|�d|�d|�d	|�d
|�d|	�d|
�d
|�d|�d|
�d|�d|��S)a?
    Creates a Postgres group. A group is postgres is similar to a user, but
    cannot login.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.group_create 'groupname' user='user' \
                host='hostname' port='port' password='password' \
                rolepassword='rolepassword'
    rVrrrTrUrirSrr	r�rrr�r�r
r�r:r)�	groupnamerVrTrUrirSrr	r�rrr�r�r
r�r:r'r'r(�group_createsF��������	�
���
�����r?cCslt|fid|�d|�d|�d|�d|�d|�dd�d	|�d
|�d|
�d|	�d
|�d|�d|
�d|�d|��S)z�
    Updates a postgres group

    CLI Examples:

    .. code-block:: bash

        salt '*' postgres.group_update 'username' user='user' \
                host='hostname' port='port' password='password' \
                rolepassword='rolepassword'
    rVrTrUrirSrrrr	r�rrr�r�r
r�r:r)r>rVrTrUrirSrr	r�rrr�r�r
r�r:r'r'r(�group_updateLsF��������	�
���
�����r@c	Cr:)z�
    Removes a group from the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.group_remove 'groupname'
    r�r;)r>rVrTrUrirSr:r'r'r(�group_remove~r=rAc
Cs�t��}|�d�|�d|�d|�d��d}|D]"\}	}
t|
||||||d�}|D]}|�|	j||dd�d	�q*q|�d
�|��t�|jd�t	d|jg||||||d
�}
|
S)z�
    Set the owner of all schemas, functions, tables, views and sequences to
    the given username.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.owner_to 'dbname' 'username'
    zbegin;
zalter database "z" owner to "z";
))z"alter schema {n} owner to {owner};zFselect quote_ident(schema_name) as n from information_schema.schemata;)z!alter table {n} owner to {owner};z�select quote_ident(table_schema)||'.'||quote_ident(table_name) as n from information_schema.tables where table_schema not in ('pg_catalog', 'information_schema');)z$alter function {n} owner to {owner};z�select p.oid::regprocedure::text as n from pg_catalog.pg_proc p join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where ns.nspname not in ('pg_catalog', 'information_schema')  and not p.proisagg;)z%alter aggregate {n} owner to {owner};z�select p.oid::regprocedure::text as n from pg_catalog.pg_proc p join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where ns.nspname not in ('pg_catalog', 'information_schema') and p.proisagg;)z$alter sequence {n} owner to {owner};zlselect quote_ident(sequence_schema)||'.'||quote_ident(sequence_name) as n from information_schema.sequences;r��n)r�rBrlzcommit;
i�z-f)rVr:rTrUrSri)
�tempfileZNamedTemporaryFilerJr�rM�flushr,�chmodrarx)�dbnameZ	ownernamerVrTrUrSr:Zsqlfiler��fmtrprZr�rwr'r'r(r��s<
%�	�
�	r�c
	Csrt|||||||d�rt�d||�dSd|�d�}|dur&|�d|�d�}td|g||||||d	�}	|	d
dkS)a
    Creates a Postgres schema.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.schema_create dbname name owner='owner' \
                user='user' \
                db_user='user' db_password='password'
                db_host='hostname' db_port='port'
    �rV�db_user�db_password�db_host�db_portz'%s' already exists in '%s'FzCREATE SCHEMA "r|Nz AUTHORIZATION "rh)rVrSrUrTrir:rBr��
schema_existsrOrrx)
rFrar�rVrIrJrKrLrrZr'r'r(�
schema_create�s0�	�
rOc	Csxt||d||||d�st�d||�dSd|�d�}td|g||||||d�t|||||||d	�s4d
St�d|�dS)as
    Removes a schema from the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.schema_remove dbname schemaname

    dbname
        Database name we work on

    schemaname
        The schema's name we'll remove

    user
        System user all operations should be performed on behalf of

    db_user
        database username if different from config or default

    db_password
        user password if any password for a specified user

    db_host
        Database host if different from config or default

    db_port
        Database port if different from config or default

    NrHz"Schema '%s' does not exist in '%s'Fz
DROP SCHEMA "r|rh)r:rirTrVrUrS)rIrJrKrLTzFailed to delete schema '%s'.rM)rFrarVrIrJrKrLrr'r'r(�
schema_remove(	sB$�	�
�	rPc
Cstt|||||||d��S)ap
    Checks if a schema exists on the Postgres server.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.schema_exists dbname schemaname

    dbname
        Database name we query on

    name
       Schema name we look for

    user
        The system user the operation should be performed on behalf of

    db_user
        database username if different from config or default

    db_password
        user password if any password for a specified user

    db_host
        Database host if different from config or default

    db_port
        Database port if different from config or default

    �rVrIrKrLrJ)r��
schema_get)rFrarVrIrJrKrLr'r'r(rNs	s"��rNcCsBt||||||d�}z|�|d�WSty t�d�YdSw)ap
    Return a dict with information about schemas in a database.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.schema_get dbname name

    dbname
        Database name we query on

    name
       Schema name we look for

    user
        The system user the operation should be performed on behalf of

    db_user
        database username if different from config or default

    db_password
        user password if any password for a specified user

    db_host
        Database host if different from config or default

    db_port
        Database port if different from config or default
    rQNz8Could not retrieve Postgres schema. Is Postgres running?F)�schema_listrNr�rOrP)rFrarVrIrJrKrLZall_schemasr'r'r(rR�	s!�
�rRc	CsZi}d�dg�}t|||||||d�}|D]}	i}
dD]}|	||
|<q|
||	d<q|S)aL
    Return a dict with information about schemas in a Postgres database.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.schema_list dbname

    dbname
        Database name we query on

    user
        The system user the operation should be performed on behalf of

    db_user
        database username if different from config or default

    db_password
        user password if any password for a specified user

    db_host
        Database host if different from config or default

    db_port
        Database port if different from config or default
    r>z�SELECT pg_namespace.nspname as "name",pg_namespace.nspacl as "acl", pg_roles.rolname as "owner" FROM pg_namespace LEFT JOIN pg_roles ON pg_roles.oid = pg_namespace.nspowner rz)r�Zaclra)r-r�)rFrVrIrJrKrLrZrpr�r�r�r�r'r'r(rS�	s(���
rSc
	Cs<i}d}t|||||||d�}|D]
}	|	d||	d<q|S)aI
    .. versionadded:: 2016.3.0

    Return a list of languages in a database.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.language_list dbname

    maintenance_db
        The database to check

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    z)SELECT lanname AS "Name" FROM pg_languagerzr�r)
rirVrTrUrSr:rZrpr�r�r'r'r(�
language_list
s!�
rTcCr�)a}
    .. versionadded:: 2016.3.0

    Checks if language exists in a database.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.language_exists plpgsql dbname

    name
       Language to check for

    maintenance_db
        The database to check in

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of

    r�)rT)rarirVrTrUrSr:�	languagesr'r'r(�language_existsE
s%�rVc		CsLt||�rt�d||�dSd|��}td|g||||||d�}|ddkS)a�
    .. versionadded:: 2016.3.0

    Installs a language into a database

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.language_create plpgsql dbname

    name
       Language to install

    maintenance_db
        The database to install the language in

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    z Language %s already exists in %sFzCREATE LANGUAGE rhr�rBr�rVrOrrx�	rarirVrTrUrSr:rprZr'r'r(�language_createq
�
$
�
rYc		CsLt||�st�d||�dSd|��}td|g||||||d�}|ddkS)a�
    .. versionadded:: 2016.3.0

    Removes a language from a database

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.language_remove plpgsql dbname

    name
       Language to remove

    maintenance_db
        The database to install the language in

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    z Language %s does not exist in %sFzDROP LANGUAGE rhr�rBrrWrXr'r'r(�language_remove�
rZr[cCs|dkrd�gd���||�}|S|dkr"d�gd���||�}|S|dkr2d�gd���|�}|S|dkrCd�gd	���||�}|S|d
krSd�gd���|�}|S|dkrcd�gd
���|�}|S|dkrsd�gd���|�}|S|dkr�d�gd���|�}|S)z<
    Generate the SQL required for specific object type
    rr�)�SELECT relacl AS name�FROM pg_catalog.pg_class c�JOIN pg_catalog.pg_namespace n�ON n.oid = c.relnamespace�WHERE nspname = '{0}'�AND relname = '{1}'zAND relkind in ('r', 'v')�ORDER BY relnamer)r\r]r^r_r`razAND relkind = 'S'rbr)zSELECT nspacl AS namezFROM pg_catalog.pg_namespacer`zORDER BY nspnamer)zSELECT proacl AS name�FROM pg_catalog.pg_proc pr^�ON n.oid = p.pronamespacer`�%AND p.oid::regprocedure::text = '{1}'�ORDER BY proname, proargtypesr)zSELECT spcacl AS namezFROM pg_catalog.pg_tablespace�WHERE spcname = '{0}'zORDER BY spcnamer)zSELECT lanacl AS namezFROM pg_catalog.pg_language�WHERE lanname = '{0}'zORDER BY lannamer)zSELECT datacl AS namezFROM pg_catalog.pg_database�WHERE datname = '{0}'zORDER BY datnamer)	zSELECT rolname, admin_optionz!FROM pg_catalog.pg_auth_members m�JOIN pg_catalog.pg_roles rzON m.member=r.oidzWHERE m.roleid INz(SELECT oidzFROM pg_catalog.pg_roleszWHERE rolname='{0}')zORDER BY rolname)r-rM)ra�object_type�prependrpr'r'r(�_make_privileges_list_query�
sp��h���Y���J���?���1���&�����
�rm�publicc		Cs|dkrd�gd���||�}	n[|dkr d�gd���||�}	nK|dkr/d�gd���|�}	n<|dkr?d�gd	���||�}	n,|d
krNd�gd���|�}	n|dkr]d�gd
���|�}	n|dkrkd�gd���|�}	t|	||||||d�}
z	|
dd}W|Sty�d}Y|Sw)z/
    Return the owner of a postgres object
    rr�)zSELECT tableowner AS namezFROM pg_tableszWHERE schemaname = '{0}'zAND tablename = '{1}'r)	�SELECT rolname AS namer]�JOIN pg_roles rzON c.relowner = r.oidr^r_zWHERE relkind='S'zAND nspname='{0}'rar)rozFROM pg_namespace nrpzON n.nspowner = r.oidr`r)	rorcr^rdrjzON p.proowner = r.oidr`rerfr)rozFROM pg_tablespace trpzON t.spcowner = r.oidrgr)rozFROM pg_language lrpzON l.lanowner = r.oidrhr)rozFROM pg_database drpzON d.datdba = r.oidrirzrraN)r-rMr��
IndexError)rarkrlrirVrTrUrSr:rpr�rZr'r'r(�_get_object_ownerOst��
�
��	��
��	��	��	��	��rrcCsr|dkr1dd�t|D�}|�d�|tvrtd|�d���t|��t|��s/td�||���d	S|r7td��d	S)
z*
    Validate the supplied privileges
    rcS�g|]}t|�qSr'��_PRIVILEGES_MAP�r��permr'r'r(r��r*z(_validate_privileges.<locals>.<listcomp>�ALL�Invalid object_type: �	 providedz/Invalid privilege(s): {} provided for object {}z=The privileges option should not be set for object_type groupN)�_PRIVILEGE_TYPE_MAPr]�_PRIVILEGES_OBJECTSr�set�issubsetrM)rkZprivs�
privileges�_permsr'r'r(�_validate_privileges�s"
�����r�cCs2|��}|dur
dn|}t�d|���}|||fS)z
    Format options
    Nr>z\s?,\s?)r)r�ro�upper)rkr�_privsr'r'r(�_mod_priv_opts�s
r�cCsZi}d}|D]$}|durd|t|<t|}q|dkr d||<qd|t|<t|}q|S)z
    Process part
    NFrTrt)�perms�_tmpZpreviousrwr'r'r(�_process_priv_part�s


r�c		Cs�|��}t|||�}	|tvrtd|�d���t|	||||||d�}
i}|
D]G}|dkr[|d}
|
�d�}
|
�d�}|D]}|�d�\}}|�d	�\}}|d
krQd}t|�}|||<q;q%|dd
krdd}nd}|||d<q%|S)aH
    .. versionadded:: 2016.3.0

    Return a list of privileges for the specified object.

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.privileges_list table_name table maintenance_db=db_name

    name
       Name of the object for which the permissions should be returned

    object_type
       The object type, which can be one of the following:

       - table
       - sequence
       - schema
       - tablespace
       - language
       - database
       - group
       - function

    prepend
        Table and Sequence object types live under a schema so this should be
        provided if the object is not under the default `public` schema

    maintenance_db
        The database to connect to

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    ryrzrzrrar�r{r4r�r>rn�admin_optionrTFZrolname)r)rmr|rr�rror�)rarkrlrirVrTrUrSr:rpr�rZr��result�parts�partZ
perms_part�_Zrolenamer�r�r�r'r'r(�privileges_lists@;�



�r�cCs
t||�\}}}t|||�|dkr)t|||||||	|
|d�	}
|
dur)||
kr)dSt|||||||	|
|d�	}||vr�|dkrJ|rF||}|Sd}|St|}|r_dd�|D�}|||k}|Sdd�|D�}d	|vrvt|�t||�k}|St|��t||��}|Sd
S)aQ
    .. versionadded:: 2016.3.0

    Check if a role has the specified privileges on an object

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.has_privileges user_name table_name table \
        SELECT,INSERT maintenance_db=db_name

    name
       Name of the role whose privileges should be checked on object_type

    object_name
       Name of the object on which the check is to be performed

    object_type
       The object type, which can be one of the following:

       - table
       - sequence
       - schema
       - tablespace
       - language
       - database
       - group
       - function

    privileges
       Comma separated list of privileges to check, from the list below:

       - INSERT
       - CREATE
       - TRUNCATE
       - CONNECT
       - TRIGGER
       - SELECT
       - USAGE
       - TEMPORARY
       - UPDATE
       - EXECUTE
       - REFERENCES
       - DELETE
       - ALL

    grant_option
        If grant_option is set to True, the grant option check is performed

    prepend
        Table and Sequence object types live under a schema so this should be
        provided if the object is not under the default `public` schema

    maintenance_db
        The database to connect to

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    r�rlrirVrTrUrSr:NTcSsi|]}t|d�qS)Trtrvr'r'r(�
<dictcomp>�sz"has_privileges.<locals>.<dictcomp>cSrsr'rtrvr'r'r(r��r*z"has_privileges.<locals>.<listcomp>rxF)r�r�rrr�r{�sortedr}r~)ra�object_namerkr�grant_optionrlrirVrTrUrSr:r�r�Z_privileges�retvalr�r�r'r'r(�has_privilegesds\V�����r�c
Csnt||�\}}}t|||�t|||||||||	|
|d�r't�d|||�dSd�|�}
|dvr9|�d|�d�}n|dkrA|�}nd|�d�}|rw|d	krWd
|�d|�d�}nM|dvrl|��d
krld�|
|��||�}n8d�|
|��||�}n-|d	kr�d
|�d|�d�}n|dvr�|��d
kr�d�|
|��||�}n
d�|
|��||�}td|g|||	||
|d�}|ddkS)aU
    .. versionadded:: 2016.3.0

    Grant privileges on a postgres object

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.privileges_grant user_name table_name table \
        SELECT,UPDATE maintenance_db=db_name

    name
       Name of the role to which privileges should be granted

    object_name
       Name of the object on which the grant is to be performed

    object_type
       The object type, which can be one of the following:

       - table
       - sequence
       - schema
       - tablespace
       - language
       - database
       - group
       - function

    privileges
       Comma separated list of privileges to grant, from the list below:

       - INSERT
       - CREATE
       - TRUNCATE
       - CONNECT
       - TRIGGER
       - SELECT
       - USAGE
       - TEMPORARY
       - UPDATE
       - EXECUTE
       - REFERENCES
       - DELETE
       - ALL

    grant_option
        If grant_option is set to True, the recipient of the privilege can
        in turn grant it to others

    prepend
        Table and Sequence object types live under a schema so this should be
        provided if the object is not under the default `public` schema

    maintenance_db
        The database to connect to

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    r�z9The object: %s of type: %s already has privileges: %s setFr{�rrz."r|rrzGRANT z TO "z" WITH ADMIN OPTIONrxz:GRANT {} ON ALL {}S IN SCHEMA {} TO "{}" WITH GRANT OPTIONz+GRANT {} ON {} {} TO "{}" WITH GRANT OPTIONz(GRANT {} ON ALL {}S IN SCHEMA {} TO "{}"zGRANT {} ON {} {} TO "{}"rhr�rBr)	r�r�r�rOrr-r�rMrx)rar�rkrr�rlrirVrTrUrSr:r��_grants�on_partrprZr'r'r(�privileges_grant�srW�
�
�����
r�c
Cs�t||�\}}}t|||�t||||||||||	|
d�s't�d|||�dSd�|�}|dvr8|�d|��}
n|}
|dkrGd|�d	|��}n
d
�||��|
|�}td|g|||||	|
d�}|d
dkS)a3
    .. versionadded:: 2016.3.0

    Revoke privileges on a postgres object

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.privileges_revoke user_name table_name table \
        SELECT,UPDATE maintenance_db=db_name

    name
       Name of the role whose privileges should be revoked

    object_name
       Name of the object on which the revoke is to be performed

    object_type
       The object type, which can be one of the following:

       - table
       - sequence
       - schema
       - tablespace
       - language
       - database
       - group
       - function

    privileges
       Comma separated list of privileges to revoke, from the list below:

       - INSERT
       - CREATE
       - TRUNCATE
       - CONNECT
       - TRIGGER
       - SELECT
       - USAGE
       - TEMPORARY
       - UPDATE
       - EXECUTE
       - REFERENCES
       - DELETE
       - ALL

    maintenance_db
        The database to connect to

    user
        database username if different from config or default

    password
        user password if any password for a specified user

    host
        Database host if different from config or default

    port
        Database port if different from config or default

    runas
        System user all operations should be performed on behalf of
    r�z;The object: %s of type: %s does not have privileges: %s setFr{r��.rzREVOKE z FROM zREVOKE {} ON {} {} FROM {}rhr�rBr)	r�r�r�rOrr-rMr�rx)rar�rkrrlrirVrTrUrSr:r�r�r�rprZr'r'r(�privileges_revoke�
sRN�
�
��
r�c	
Cs>t|�rt�d|�dSt|||||||||d�	}	|	ddkS)a�
    .. versionadded:: 2016.3.0

    Initializes a postgres data directory

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.datadir_init '/var/lib/pgsql/data'

    name
        The name of the directory to initialize

    auth
        The default authentication method for local connections

    password
        The password to set for the postgres user

    user
        The database superuser name

    encoding
        The default encoding for new databases

    locale
        The default locale for new databases

    waldir
        The transaction log (WAL) directory (default is to keep WAL
        inside the data directory)

        .. versionadded:: 2019.2.0

    checksums
        If True, the cluster will be created with data page checksums.

        .. note:: Data page checksums are supported since PostgreSQL 9.3.

        .. versionadded:: 2019.2.0

    runas
        The system user the operation should be performed on behalf of

    z%s already existsF)rbrVrSrcrdrerfr:rBr)�datadir_existsrOrrg)
rarbrVrSrcrdrerfr:rZr'r'r(�datadir_inits9�r�cCs4tj�|d�}tj�|d�}tj�|�otj�|�S)z�
    .. versionadded:: 2016.3.0

    Checks if postgres data directory has been initialized

    CLI Example:

    .. code-block:: bash

        salt '*' postgres.datadir_exists '/var/lib/pgsql/data'

    name
        Name of the directory to check
    Z
PG_VERSIONzpostgresql.conf)r,r#r-�isfile)raZ
_version_fileZ_config_filer'r'r(r�Zsr�)NNNNN)rSNNr\NNNF)NNNNNN)NNNN)NNNNNNF)r�)NNNNNNNNNNNN)	NNNNNNNFN)NNNNNNNN)
NNNNNNNNNN)Nr�r>F)Nr�)r>r�NNNNNNNNNNNN)NNNNNNNNNNNNNNNr�NN)NNNNNNNNNNNNNNNNN)NNNNNNr�NNNNNNNNNNN)	NNNNNNNNN)NNNNNNNNNNNNNNN)rnNNNNNN)	NNrnNNNNNN)NrnNNNNNN)rSNNr\NNFN)r�__doc__r�r�r�r�r��loggingr,r�r`rCZsalt.utils.filesr!Zsalt.utils.itertoolsZsalt.utils.odictZsalt.utils.pathZsalt.utils.stringutilsZsalt.exceptionsrrZsalt.ext.saslpreprZsalt.utils.versionsrr�r �ImportErrorZsecretsrr�	getLogger�__name__rOr�rDr0r1r2r3r7ru�	frozensetr|r{r)r%r[rgrrrsrtrmrxr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrrrr"r$r&r(r+r-r/r5r6r9r<r?r@rAr�rOrPrNrRrSrTrVrYr[rmrrr�r�r�r�r�r�r�r�r�r'r'r'r(�<module>s�%��
���
�
;
�J
�!
�
$
�
�b
�+
�


�D
�5
�*
�*
�#
�3
�?
�%
�x
�'
�
 !

�c
�C
�8
�J
�8
�*
� 
�$
�
�
� 
�!
�0
�H
�g
�"
�5
�4
�
�[
�6
�L
�0
�1
�@
�5
�-
�8
�7s
�{
�h
�
�"
�
�K