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/__pycache__/master.cpython-310.pyc
o

�N�gq�@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl!Zddl"Zddl#Zddl$Zddl%Zddl&Zddl'Zddl(Zddl)Zddl*Zddl+Zddl,Zddl-Zddl.Zddl/Zddl0Zddl1Zddl2Zddl3Zddl4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;ddl<m=Z=ddl>m?Z?dd	l@mAZAmBZBmCZCdd
l#mDZDddlEmFZFddl2mGZGmHZHzddlIZId
ZJWneK�y dZJYnwe�LeM�ZNGdd�d�ZOGdd�dejPjQjR�ZSGdd�dejPjQjR�ZTGdd�deO�ZUGdd�dejPjQjR�ZVGdd�dejPjQjR�ZWGdd�d�ZXGdd�deX�ZYGdd �d eX�ZZdS)!z�
This module contains all of the routines needed to set up a master server, this
involves preparing the three listeners and the workers needed by the master.
�N)�DEFAULT_INTERVAL)�DEFAULT_TARGET_DELIM)�StackContext)�
TRANSPORTS)�iter_transport_opts)�RequestContext)�enable_sigusr1_handler�enable_sigusr2_handler�
inspect_stack)�tagify)�OrderedDict)�ZMQ_VERSION_INFO�zmqTFcs\eZdZdZiZdd�Z�fdd�Z�fdd�Zdd	�Ze	ddd��Z
e	ddd��Z�ZS)�SMasterzN
    Create a simple salt-master, this will generate the top-level master
    cCs$||_tj�|j�|_|��|_dS)zm
        Create a salt master server instance

        :param dict opts: The salt options dictionary
        N)�opts�salt�cryptZ
MasterKeys�
master_key�_SMaster__prep_key�key��selfr�r�?/opt/saltstack/salt/lib/python3.10/site-packages/salt/master.py�__init__\szSMaster.__init__cs.t��|�|d|_|d|_|dt_dS)Nrr�secrets)�super�__setstate__rrrr�r�state��	__class__rrrks

zSMaster.__setstate__cs&t���}|�|j|jtjd��|S)N)rrr)r�__getstate__�updaterrrrrr rrr"qs
��zSMaster.__getstate__cCstjj�|j�S)z�
        A key needs to be placed in the filesystem with permissions 0400 so
        clients are required to run as root.
        )r�daemons�	masterapiZaccess_keysr�rrrrZ
__prep_key|szSMaster.__prep_keyNcCs�|jdd���0|jddjtjkr|j||dd�n|jddjd7_|jddjWd�S1s<wYdS)N�aes�secret�serialF)�use_lock�)r�get_lock�value�sys�maxsize�rotate_secrets)�clsr�eventrrr�
get_serial�s$�zSMaster.get_serialTc	Cs�t�d�|duri}|j��D]X\}}|rC|d���tjj�|d��|d_	d|vr3d|d_	Wd�n1s=wYntjj�|d��|d_	d|vrYd|d_	|rh|j
d|�d�did	d
�q|�d�r|t�d�tjj
�|�dSdS)
NzRotating master AES keyr(�reloadr)rZrotate_Z_keyTr)�tagZping_on_rotatez1Pinging all connected minions due to key rotation)�log�infor�itemsr,r�utils�stringutils�to_bytesr-�
fire_event�get�debug�masterZping_all_connected_minions)r1rr2r*Z
secret_keyZ
secret_maprrrr0�s4

�
���
�
�

�zSMaster.rotate_secrets)NN)NNT)
�__name__�
__module__�__qualname__�__doc__rrrr"r�classmethodr3r0�
__classcell__rrr rrSs�rcsXeZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Z�ZS)�MaintenancezP
    A generalized maintenance process which performs maintenance routines.
    csX|�dd�|_t�jdi|��||_t|jd�|_tt���|_t|jd�|_	dS)z[
        Create a maintenance instance

        :param dict opts: The salt options
        �master_secretsN�
loop_intervalZmaintenance_intervalr)
�poprGrrr�intrH�time�rotate�restart_interval)rr�kwargsr rrr�szMaintenance.__init__cCs(|jdur	|jt_t|j�}d|d<tj�|�}tj�	|ji�|_	tj
jj|j|�
�|j	d�|_tj
j�|j�|_tj
jj|j|jddd�|_tjj�|j�|_|jdrmtj
j��smt�d	|jd�t�|jd�d|_|j�d
d�r�d}t|j�D]
\}}|dkr�d}q~|s�d|_dSdSdS)a<
        Some things need to be init'd after the fork has completed
        The easiest example is that one of these module types creates a thread
        in the parent process, then once the fork happens you'll start getting
        errors like "WARNING: Mixing fork() and threads detected; memory leaked."
        NT�quiet)�	returners�sock_dirF��listenZmaintenance_nicenessz"setting Maintenance niceness to %d�presence_eventsZtcp) rGrr�dictrr�runner�RunnerClient�loaderrPr9�scheduleZScheduleZfunctions_dict�minions�	CkMinions�	ckminionsr2�get_master_eventr$r%Zinit_git_pillar�
git_pillar�platform�
is_windowsr6r7�os�nicerTr=r)rZropts�
runner_clientZtcp_only�	transport�_rrr�_post_fork_init�s<

��
��
�zMaintenance._post_fork_initcCs|��t��}d}d}tt���}|j�dd�}t�}t��||jkr�t�d�|r3|||j	krKt
jj�
|j�t
jj�|j�t
jj�|j�|rS|||krY|}|��|��|��|�|�|�|�t
jj�|j�|}tt���}t�|j	�t��||jks%dSdS)z�
        This is the general passive maintenance process controller for the Salt
        master.

        This is where any data that needs to be cleanly maintained from the
        master is maintained.
        Nr�git_pillar_update_intervalzRunning maintenance routines)rfrKrJrr=�setrMr6�tracerHrr$r%Zclean_old_jobsZclean_expired_tokensZclean_pub_auth�handle_git_pillar�handle_schedule�handle_key_cache�handle_presence�handle_key_rotater9�verifyZcheck_max_open_files�sleep)r�start�lastZlast_git_pillar_update�nowrg�old_presentrrr�run�s2	


�zMaintenance.runcCs�|jddkrog}|jdtvrd}nd}t�tj�|jd|��D]}|�d�s=tj�tj�|jd||��r=|�|�q"t	�
d�tjj
jtj�|jd|d	�d
d��}tj�||�Wd�dS1shwYdSdS)
z`
        Evaluate accepted keys and create a msgpack file
        which contains a list
        Z	key_cacheZschedrdrZZaccepted�pki_dir�.zWriting master key cachez
.key_cache�wb)�modeN)rrra�listdir�path�join�
startswith�isfile�appendr6r>rr9Z
atomicfileZatomic_open�payload�dump)r�keys�accZfn_Z
cache_filerrrrls&�
�
�"��zMaintenance.handle_key_cachecCs�d}tj�|jdd�}z3t�|�}tjj��r,t�	|tj
�s,d}t�|tjtj
B�n
|jdkr4d}nt�d�t�|�Wn	tyHYnw|j�d�r[||j|jdkr[d}|rjt�|j|j�||_dSdS)	z-
        Rotate the AES key rotation
        F�cachedir�.dfnTi�z6Found dropfile with incorrect permissions, ignoring...Zpublish_sessionN)rar{r|r�statrr9r_r`�access�W_OK�chmod�S_IRUSR�S_IWUSR�st_moder6�error�remove�OSErrorr=rLrr0r2)rrsZ	to_rotate�dfn�statsrrrrn1s*


�
�zMaintenance.handle_key_rotatec
CsPz
|jD]}|��qWdSty'}ztjddd�WYd}~dSd}~ww)z#
        Update git pillar
        z*Exception caught while updating git_pillarT��exc_infoN)r^Z
fetch_remotes�	Exceptionr6r�)r�pillar�excrrrrjOs

���zMaintenance.handle_git_pillarc
Csfz|j��|jj|jkr|jj|_Wnty+}zt�d|�WYd}~nd}~ww|j��dS)z(
        Evaluate the scheduler
        z&Exception %s occurred in scheduled jobN)rY�evalrHr�r6r�Zcleanup_subprocesses)rr�rrrrkYs

���zMaintenance.handle_schedulecCs�|jrK|jjdd�rM|j��}|�|�}|�|�}|s|r0t|�t|�d�}|j�|tdd��dt|�i}|j�|tdd��|�	�|�
|�dSdSdS)z1
        Fire presence events if enabled
        �)�timeout)�new�lostZchangeZpresence�presentN)rTr2Zconnect_pullr\Z
connected_ids�
difference�listr<r�clearr#)rrtr�r�r��datarrrrmgs


�zMaintenance.handle_presence)
r@rArBrCrrfrurlrnrjrkrmrErrr rrF�s-,
rFcsHeZdZdZ�fdd�Zdd�Zedd��Zedd	��Z	d
d�Z
�ZS)�FileserverUpdatezH
    A process from which to update any dynamic fileserver backends
    csBt�jdi|��||_i|_ddl}|j�|j�|_|��dS)Nrr)rrr�update_threads�salt.fileserver�
fileserver�
Fileserver�fill_buckets)rrrNrr rrr�szFileserverUpdate.__init__c		Cs|j��}i|_|j��D]w}|�d�}z|jj|}Wnty+t�d|�Yq
w||vrY||��D]!\}}|sDt	}t�d|�|j�
|t��}|�
||fg��|�q6q
z|�d�}|j
|}Wntywt	}t�d||�Ynwd|j�
|t��||f<q
dS)z�
        Get the configured backends and the intervals for any backend which
        supports them, and set up the update "buckets". There will be one
        bucket for each thing being updated at a given interval.
        z.updatez/No update function for the %s filserver backendz<An update_interval of 0 is not supported, falling back to %sZ_update_intervalzQ%s key missing from configuration. Falling back to default interval of %d secondsN)r��update_intervals�buckets�backends�servers�KeyErrorr6r>r8r�
setdefaultrrr�warning)	rr��backend�fstr�update_func�id_�intervalZi_ptrZinterval_keyrrrr��sJ

���
��
���zFileserverUpdate.fill_bucketscCs�|��D];\}}|\}}z|rt�d||�|f}nt�d|�d}||�Wqty?}zt�d|�WYd}~qd}~wwdS)z,
        Perform fileserver updates
        z:Updating %s fileserver cache for the following targets: %szUpdating %s fileserver cacherz5Uncaught exception while updating %s fileserver cacheN)r8r6r>r��	exception)r�r�Zupdate_argsZbackend_namer��argsr�rrr�
_do_update�s*�����zFileserverUpdate._do_updatecCs�t��}t��}t��||krCt�d|�|�|�t�d||�|�
|�|�Wd�n1s4wYt��||ksdSdS)zV
        Threading target which handles all updates for a given wait interval
        zEPerforming fileserver updates for items with an update interval of %dzXCompleted fileserver updates for items with an update interval of %d, waiting %d secondsN)rK�	threading�	Conditionr6r>r��wait)r1r�r�r�rqZ	conditionrrrr#�s"�
���zFileserverUpdate.updatecCs�|jdrtjj��st�d|jd�t�|jd�tj	j
�|j�|jD]}t
j|j||j||jdfd�|j|<|j|��q'|jrht|j���D]\}}|�d�|��sb|j�|�qO|jsHdSdS)z*
        Start the update threads
        Zfileserver_update_nicenessz'setting FileServerUpdate niceness to %dZfileserver_interval)�targetr�r+N)rrr9r_r`r6r7rarbr$r%Zclean_fsbackendr�r��Threadr#r�rqr�r8r|�is_aliverI)rr��name�threadrrrru�s4�
��
��
��zFileserverUpdate.run)r@rArBrCrr��staticmethodr�rDr#rurErrr rr�{s
5

r�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�Masterz 
    The salt master server
    cCs&trtdkrt�d�t�||�dS)z]
        Create a salt master server instance

        :param dict: The salt options
        )r��z�You have a version of ZMQ less than ZMQ 3.2! There are known connection keep-alive issues with ZMQ < 3.2 which may result in loss of contact with minions. Please upgrade your ZMQ!N)rr
r6r�rrrrrrrs
�zMaster.__init__cCs�tsdSt�tj�\}}|tjkr|}t�d||�|jd}||kr-t�d|||�|}||krct�d|�t�tj||f�zt�tj�\}}t�d||�WdSt	ybt�
d|�YdSwdS)Nz:Current values for max open files soft/hard setting: %s/%sZmax_open_filesz�The value for the 'max_open_files' setting, %s, is higher than the highest value the user running salt is allowed to set (%s). Defaulting to %s.z"Raising max open files value to %sz5New values for max open files soft/hard values: %s/%sz~Failed to raise max open files setting to %s. If this value is too low, the salt-master will most likely fail to run properly.)�HAS_RESOURCE�resourceZ	getrlimitZ
RLIMIT_NOFILEZ
RLIM_INFINITYr6r7rZ	setrlimit�
ValueError�critical)rZmof_sZmof_hZmof_crrrZ__set_max_open_files&sD
�
�
�
���zMaster.__set_max_open_filescCs�g}g}zt�d�Wnty&}z|�d|�d��WYd}~nd}~ww|j�dd�rlddl}|j�|j�}|j	sK|�d�
d	�|jd
���n!z|��Wn|j
jyk}z|�|��WYd}~nd}~ww|jd
sv|�d�|jdr�tj�tj�|jd
d��s�z&|jj�d��t�tj�|jd
d��Wd�n1s�wYWn	ty�Ynw|j�dd��r1zdd�|j�dg�D�}Wnty�g}|�d�Ynw|�r1zKt�|j�}ddl}|D];}	|	g|d<z|jjj||	d|jjj|jjj|jjjd�}
Wq�|j
j�y+}z|�|j �WYd}~q�d}~wwW~n~w|�s7|�r\|D]}t!�"|��q9|D]}t!�#|��qDt!�#d�t$�%|j&j'j(�dSdS)zv
        Run pre flight checks. If anything in this method fails then the master
        should not start up.
        �/z!Cannot change to root directory (�)NZfileserver_verify_configTrzCFailed to load fileserver backends, the configured backends are: {}z, Zfileserver_backendz%No fileserver backends are configuredZpillar_cacher��?Zgit_pillar_verify_configcSs&g|]}d|vrt|dt�s|�qS)�git)�
isinstance�str)�.0�xrrr�
<listcomp>�s
�z&Master._pre_flight.<locals>.<listcomp>Z
ext_pillarz�Invalid ext_pillar configuration. It is likely that the external pillar type was not specified for one or more external pillars.r�)Zper_remote_overridesZper_remote_onlyZglobal_onlyz)Master failed pre flight checks, exiting
))ra�chdirr�rrr=r�r�r�r��formatr|�init�
exceptionsZFileserverConfigErrorr{�isdirr9�filesZ	set_umask�mkdir�	TypeError�copy�deepcopyZsalt.pillar.git_pillarZgitfsZ	GitPillarr�r^ZPER_REMOTE_OVERRIDESZPER_REMOTE_ONLYZGLOBAL_ONLY�strerrorr6r�r�r.�exit�defaultsZ	exitcodesZ
EX_GENERIC)r�errorsZcritical_errors�errrr�r�Zgit_pillarsZnew_optsZrepor^r�rrr�_pre_flightWs������

����
���

����

�zMaster._pre_flightc
Cs\|��t�dtjj���t�t�|�	�tjj
�tj
tj����t�tjtjj�tjj����tjtjdd�tjjjd�tjd<t�d�tjj
jdd�|_g}t�d	�t|j�D]\}}tj j!j"�#|�}|j$|jd
tjid�|�%|�q^t�d�|jj&tjj'j(|jfd
d�|j�)d�r�t*|jdt+�r�d}|jdD]
}d|vr�d}nq�|s�|jd�%dii�nd|jdvr�t�d�i|jdd<tj,�-|j|j�t�d�|jj&t.|jfdtjidd�|j�)d��rt�d�|jj&tjj'j/|jfdd�|j�)dg�}|D]Q}t�d|�z8d�0|�1d�dd��}	|�1d�d}
t2|	t3�t4�|
gd�}|�5|
�}
d|
j6�d �}|jj&|
|jf|d�W�qt7�y_t�8d!|�Y�qw|jd"�r�t�d#�|jj&tjj9j:|jfd$d�t�;d%�t<�=d&�t�d'�i}
tjj>�?��r�tj|
d
<|jj&t@|j|jA|jBf|
d(d�|jj&tC|jfd)d�|jd*�r�tjjDjE�F��r�|jj&tjjDjE|jd*d+|jd,d-|jd*�)d-i�id.�jGd/d0�nt�8d1�tHjIjJd&k�r�t�8d2�Wd�n	1�s�wYt�Ktj
�tjLu�rt�tj
|jM�t�Ktj�tjLu�r't�tj|jM�|j�G�dS)3z6
        Turn on the master server components
        z$salt-master is starting as user '%s'F)�lock)r(r)r4r'zCreating master process manager�)�
wait_for_killz!Creating master publisher processr)rNz'Creating master event publisher process�EventPublisher�r�r�Zreactor�enginesTzEnabling the reactor enginez#Creating master maintenance processrGrF)r�rNr�Zevent_returnz$Creating master event return process�EventReturnZ
ext_processesz"Creating ext_processes process: %srwN���zExtProcess(r�z(Error creating ext_processes process: %sZ	con_cachez Creating master concache process�ConnectedCachez-Sleeping for two seconds to let concache restr�z&Creating master request server process�	ReqServerZFileServerUpdateZ	discovery�portZ	interface�mapping)r�Z	listen_ipZanswer�SSDPDiscoveryServer)r�z6Unable to load SSDP: asynchronous IO is not available.zRYou are using Python 2, please install "trollius" module to enable SSDP discovery.)Nr�r6r7rr9�user�get_userrr	�_Master__set_max_open_files�process�default_signals�signal�SIGINT�SIGTERM�multiprocessing�Array�ctypes�c_charr:r;rZ	CrypticleZgenerate_key_stringZValue�
c_longlongrr�ProcessManager�process_managerrr�channel�server�PubServerChannel�factory�pre_forkr�add_processr2r�r=r�r�r�Z
start_enginesrFr�r|�split�
__import__�globals�locals�__getattribute__rBr�r�r?r�r>rKrpr_Zspawning_platformr�rrr�Zssdpr�Zis_availablerur.�version_info�major�	getsignal�SIG_DFL�_handle_signals)rZpub_channelsrer�chanZrine�itemZ	ext_procs�proc�modr1Z_tmpr�rNrrrrq�s�
����



���

�
���
�



�
����
���zMaster.startcCs&|j�||�t�d�t�d�dS)Nr+r)r�r	rKrpr.r��r�signum�sigframerrrr	Hs
zMaster._handle_signalsN)	r@rArBrCrr�r�rqr	rrrrr�s1Vr�csTeZdZdZd�fdd�	Z�fdd�Zdd�Zd	d
�Zej	fdd�Z
d
d�Z�ZS)r�zZ
    Starts up the master request server, minions send results to this
    interface.
    Ncs.t�jdi|��||_||_||_||_dS)a
        Create a request server

        :param dict opts: The salt options dictionary
        :key dict: The user starting the server and the AES key
        :mkey dict: The user starting the server and the RSA key

        :rtype: ReqServer
        :returns: Request server
        Nr)rrrrrr)rrr�mkeyrrNr rrrUs

zReqServer.__init__cs|�|�t��||�dS�N)�destroyrr	rr rrr	gs
zReqServer._handle_signalscCs�|jdur	|jt_tj�|jdd�}tj�|�rAztjj	�
�r1t�|tj�s1t�
|tjtjB�t�|�Wn	ty@Ynwtjjjddd�|_g}t|j�D]\}}tjjj�|�}|�|j�|�|�qR|jdr�tjj	�
�s�t�d|jd�t�|jd�tjj� t!j"t!j#��)t$t%|jd	��D]}d
|��}|jj&t'|j|j(|j)|f|d�q�Wd�n1s�wY|j�*�dS)z(
        Binds the reply server
        Nr�r�ZReqServer_ProcessManagerr+)r�r��req_server_nicenessz/setting ReqServer_ProcessManager niceness to %dZworker_threadszMWorker-r�)+rrrar{r|rr~rr9r_r`r�r�r�r�r�r�r�r�r�r�r�rr�r�ZReqServerChannelr�r�rr6r7rbr�r�r�r��rangerJr��MWorkerrrru)rr��req_channelsrdrr
Zindr�rrr�__bindksH
���
���zReqServer.__bindcCs|��dS)z(
        Start up the ReqServer
        N)�_ReqServer__bindr&rrrru�sz
ReqServer.runcCs2t|d�r|j��|j�|�|j��dSdS)Nr�)�hasattrr�Zstop_restartingZsend_signal_to_processesZ
kill_children)rrrrrr�s


�zReqServer.destroycCs|��dSr)rr&rrr�__del__�szReqServer.__del__r)
r@rArBrCrr	rrur�r�rrrErrr rr�Os0r�cs�eZdZdZ�fdd�Z�fdd�Z�fdd�Z�fdd	�Zd
d�Ze	j
jjj
dd
��Zdd�Zdd�Zdd�Zdd�Z�ZS)rzd
    The worker multiprocess instance to manage the backend operations for the
    salt master.
    csNt�jdi|��||_||_||_||_d|_t�dd��|_	t
�
�|_dS)a.
        Create a salt master worker process

        :param dict opts: The salt options
        :param dict mkey: The user running the salt master and the RSA key
        :param dict key: The user running the salt master and the AES key

        :rtype: MWorker
        :return: Master worker
        rcS�
ddd�S�Nr)�mean�runsrrrrr�<lambda>��
z"MWorker.__init__.<locals>.<lambda>Nr)rrrrrr�k_mtime�collections�defaultdictr�rK�
stat_clock)rrrrrrNr rrr�szMWorker.__init__cs$t��|�|d|_|dt_dS)Nr"r)rrr"rrrr rrr�s
zMWorker.__setstate__cs"t���}|�|jtjd��|S)N)r"r)rr"r#r"rrrr rrr"�s
zMWorker.__getstate__c	svt|dd�D]}z|��WqtyYqwt|dd�}|dur2z|��Wn	ty1Ynwt��||�dS)Nrr�clear_funcs)�getattr�closer�rrr	)rrrr�r&r rrr	�s��zMWorker._handle_signalsc	Csbtjjj��|_|j��|jD]}|j|j	|jd�qz|j�
�WdSttfy0YdSw)z(
        Bind to the local port
        )�io_loopN)
r�ext�tornadoZioloopZIOLoopr)Zmake_currentrZ	post_fork�_handle_payloadrq�KeyboardInterrupt�
SystemExit)rZreq_channelrrrr�s

��zMWorker.__bindcCs>|d}|d}|dkr|�|�}n|�|�}tjjj�|��)a�
        The _handle_payload method is the key method used to figure out what
        needs to be done with communication to the server

        Example cleartext payload generated for 'salt myminion test.ping':

        {'enc': 'clear',
         'load': {'arg': [],
                  'cmd': 'publish',
                  'fun': 'test.ping',
                  'jid': '',
                  'key': 'alsdkjfa.,maljf-==adflkjadflkjalkjadfadflkajdflkj',
                  'kwargs': {'show_jid': False, 'show_timeout': False},
                  'ret': '',
                  'tgt': 'myminion',
                  'tgt_type': 'glob',
                  'user': 'root'}}

        :param dict payload: The payload route to the appropriate handler
        �enc�loadr')�_handle_aes�
_handle_clearrr*r+�genZReturn)rr�rr0�retrrrr,�s
zMWorker._handle_payloadcCs�t��}||}|j|d|j|dd||j|d|j|d<||j|jdkrR|jj�||j|j|jd�t|jd��t	�
dd��|_||_d	Sd	S)
zK
        Calculate the master stats and fire events with stat info
        rrr+Zmaster_stats_event_iter)rKZworkerr�r�cSrrrrrrrr *r!z%MWorker._post_stats.<locals>.<lambda>N)rKr�r%r�	aes_funcsr2r<r�rr#r$)rrq�cmd�endZdurationrrr�_post_statss "��
�
�zMWorker._post_statscCs�t�d|d�|d}|j�|�}|siddifS|jdr.t��}|j|dd7<||�ddif}|jdrA|�||�|S)z�
        Process a cleartext command

        :param dict load: Cleartext payload
        :return: The result of passing the load to a function in ClearFuncs corresponding to
                 the command specified in the load's 'cmd' key.
        z&Clear payload received with command %sr6�funZ
send_clear�master_statsrr+)r6rir&�
get_methodrrKr�r8)rr0r6�methodrqr4rrrr2-s

zMWorker._handle_clearcs�d|vrt�d|�iS|d}t�d|d��j�|�}|s&iddifS�jdr:t��}�j|dd7<�fd	d
�}tt	�
t|�jd����||�}Wd�n1s[wY�jdrk��||�|S)
z�
        Process a command sent via an AES key

        :param str load: Encrypted payload
        :return: The result of passing the load to a function in AESFuncs corresponding to
                 the command specified in the load's 'cmd' key.
        r6zReceived malformed command %sz$AES payload received with command %sr9�sendr:rr+cs�j�|d|�S)Nr6)r5�run_func)r�r&rrr>Vsz%MWorker._handle_aes.<locals>.run_func)r�rN)
r6r�rir5r;rrKr�r�	functools�partialrr8)rr�r6r<rqr>r4rr&rr1Bs(
�
�
zMWorker._handle_aescCs�tjj��sJd}|jdr0tjj��dkr't�d|j	�t
�d|jd�n	t�d|j	�d}|rJ|jdrJt�d	|j	|jd�t
�|jd�t
|j|j�|_|j��t|j�|_|��d
S)z'
        Start a Master Worker
        Tr�rootz1%s decrementing inherited ReqServer niceness to 0r�z@%s unable to decrement niceness for MWorker, not running as rootFZmworker_nicenesszsetting %s niceness to %iN)rr9r_r`rr�r�r6r7r�rarbr��
ClearFuncsrr&�connect�AESFuncsr5�_MWorker__bind)rZenforce_mworker_nicenessrrrrubs6
����
zMWorker.run)r@rArBrCrrr"r	rErr*r+r3�	coroutiner,r8r2r1rurErrr rr�s

 rc@seZdZdZdZdd�ZdS)�TransportMethodsz�
    Expose methods to the transport layer, methods with their names found in
    the class attribute 'expose_methods' will be exposed to the transport layer
    via 'get_method'.
    rcCsH||jvrzt||�WStyt�d|�YdSwt�d|�dS)zM
        Get a method which should be exposed to the transport layer
        z Requested method not exposed: %sN)�expose_methodsr'�AttributeErrorr6r�)rr�rrrr;�s
�zTransportMethods.get_methodN)r@rArBrCrHr;rrrrrG�srGc@s�eZdZdZdZdd�Zdd�Zdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5S)6rDzQ
    Set up functions that are available when the load is encrypted with AES
    )�
verify_minion�_master_tops�_master_opts�	_mine_get�_mine�_mine_delete�_mine_flush�
_file_recv�_pillar�
_minion_event�_handle_minion_event�_return�_syndic_return�
minion_runner�pub_ret�
minion_pub�minion_publish�revoke_auth�_serve_file�
_file_find�
_file_hash�_file_hash_and_stat�
_file_list�_file_list_emptydirs�	_dir_list�
_symlink_list�
_file_envscCs|||_tjjj|j|jddd�|_tjj�|�|_tj�	|jd�|_
tjj|jdddd�|_
|��tjj�|�|_dS)z�
        Create a new AESFuncs

        :param dict opts: The salt options

        :rtype: AESFuncs
        :returns: Instance for handling AES operations
        rQFrR�	conf_fileT�ZstatesZrendZignore_config_errorsN)rrr9r2r]rZr[r\�client�get_local_client�local�minion�MasterMinion�mminion�_AESFuncs__setup_fileserverr$r%ZRemoteFuncsrrrrr�s	�
�zAESFuncs.__init__cCsvddl}|j�|j�|_|jj|_|jj|_|jj	|_
|jj|_|jj
|_|jj|_|jj|_|jj|_|jj|_dS)zK
        Set the local file objects from the file server interface
        rN)r�r�r�r�fs_Z
serve_filer\Z
_find_filer]Z	file_hashr^Zfile_hash_and_statr_Z	file_listr`Zfile_list_emptydirsraZdir_listrbZsymlink_listrcZ	file_envsrd)rrrrrZ__setup_fileserver�s







zAESFuncs.__setup_fileserverc
Cs�tjj�|j|�sdStj�|jdd|�}ztj�	|�}Wn+t
y.t�d|�YdSt
ttfyI}z
t�d||�WYd}~nd}~wwz|�|�dkrUWdSWnt
yn}zt�d	|�WYd}~nd}~wwt�d
|�dS)�i
        Take a minion id and a string signed with the minion private key
        The string needs to verify as 'salt' with the minion public key

        :param str id_: A minion ID
        :param str token: A string signed with the minion private key

        :rtype: bool
        :return: Boolean indicating whether or not the token can be verified.
        FrvrZzzSalt minion claiming to be %s attempted to communicate with master, but key could not be read and verification was denied.z"Unable to load public key "%s": %sNssaltTzUnable to decrypt token: %szdSalt minion claiming to be %s has attempted to communicate with the master and could not be verified)rr9ro�valid_idrrar{r|rZ	PublicKeyr�r6r�r��
IndexErrorr�r�Zdecrypt)rr��tokenZpub_pathZpubr�rrrZ__verify_minion�s8�������zAESFuncs.__verify_minioncCs|�||�S)ro)�_AESFuncs__verify_minion)rr�rrrrrrJszAESFuncs.verify_minionc	s>d|jvrdSt|jdt�sdSt�fdd�dD��rdS�d�d�r'dS|��d�d	�s;t�d
�d�dS��d	�g}|jdD]}t	�
|�d�ret|jd|t�re|�|jd|�qGd�dvr��d�
d��d<g}�dD]	}|�|�
��q{|�d<|jj|�d�d�d
��dd�dd�S)a

        Verify that the passed information authorized a minion to execute

        :param dict clear_load: A publication load from a minion

        :rtype: bool
        :return: A boolean indicating if the minion is allowed to publish the command in the load
        ZpeerFc3��|]}|�vVqdSrr�r�r��
clear_loadrr�	<genexpr>.s�
�z3AESFuncs.__verify_minion_publish.<locals>.<genexpr>)r9�arg�tgtr4�tok�idr9zpublish.r|r{zOMinion id %s is not who it says it is and is attempting to issue a peer command�,ryrz�tgt_type�globT)Zpublish_validate)rr�rU�anyr}rsr6r�rI�re�matchr��extendrrr\�
auth_checkr=)rrwZpermsr�Zarg_ryrrvrZ__verify_minion_publish sJ

��
�
�z AESFuncs.__verify_minion_publishcs~t�fdd�|D��r
dSd�vr t�d�dt�dd�dS|��d�d�s4t�d�d�dSd�vr=��d��S)	a�
        A utility function to perform common verification steps.

        :param dict load: A payload received from a minion
        :param list verify_keys: A list of strings that should be present in a
        given load

        :rtype: bool
        :rtype: dict
        :return: The original load (except for the token) if the load can be
        verified. False if the load is invalid.
        c3rtrrru�r0rrrxe��z)AESFuncs.__verify_load.<locals>.<genexpr>Fr{�7Received incomplete call from %s for '%s', missing '%s'r|�co_name�&Minion id %s is not who it says it is!)r�r6r�r
rsr�rI)rr0Zverify_keysrr�rZ
__verify_loadXs 
�
zAESFuncs.__verify_loadcC�(|�|d�}|duriS|jj|dd�S)z�
        Return the results from an external node classifier if one is
        specified

        :param dict load: A payload received from a minion
        :return: The results from an external node classifier
        �r|r{FT�Zskip_verify)�_AESFuncs__verify_loadr%rK�rr0rrrrKzszAESFuncs._master_topscCsi}i}|��}|D]
}||vrg||<q
||d<|jd|d<|jd|d<|jd|d<|�d�r5|S|jd|d<|jd|d<|jd|d<|jd	|d	<|jd
|d
<|jd|d<|jd|d<|jd
|d
<|jd|d<|jd|d<|jd|d<|jd|d<|S)z�
        Return the master options to the minion

        :param dict load: A payload received from a minion

        :rtype: dict
        :return: The master options
        �
file_rootsZtop_file_merging_strategyZ	env_orderZdefault_topZenv_onlyZrendererZfailhardZ	state_topZstate_top_saltenvZ
nodegroupsZstate_auto_orderZstate_eventsZstate_aggregateZ	jinja_envZ
jinja_sls_envZjinja_lstrip_blocksZjinja_trim_blocks)rdrr=)rr0�moptsr�Zenvs�saltenvrrrrL�s4	�
zAESFuncs._master_optscCr�)z�
        Gathers the data from the specified minions' mine

        :param dict load: A payload received from a minion

        :rtype: dict
        :return: Mine data from the specified minions
        )r|rzr9r{FTr�)r�r%rMr�rrrrM�s	zAESFuncs._mine_getcCr�)z�
        Store the mine data

        :param dict load: A payload received from a minion

        :rtype: bool
        :return: True if the data has been stored in the mine
        )r|r�r{FTr�)r�r%rNr�rrrrN�s	zAESFuncs._minecCs$|�|d�}|duriS|j�|�S)a
        Allow the minion to delete a specific function from its own mine

        :param dict load: A payload received from a minion

        :rtype: bool
        :return: Boolean indicating whether or not the given function was deleted from the mine
        )r|r9r{F)r�r%rOr�rrrrO��	zAESFuncs._mine_deletecCr�)z�
        Allow the minion to delete all of its own mine contents

        :param dict load: A payload received from a minion
        r�FTr�)r�r%rPr�rrrrP�szAESFuncs._mine_flushc	sPt�fdd�dD��r
dSt�dt�sdS|jdsdStjj�|j�d�s*dSd|jd	}d
�vrB�d
dkrBt�	d�dSt
�d
���d
d�|kr[t�	d|�d�dSd�vrnt�	d�dt�dd�dS|�
�d�d�s�t�d�d�iS��d�tj��d�}tj�|�}tj�|�s�d�dvr�dStj�|jdd�dd|�}tj�|��|jd�s�t�d|�dStj�|�}tj�|�s�zt�|�Wn	ty�Ynwtj�|�r�d
dkr�d}nd}tjj�||��!}�d
�r	|��d
�|�tjj �!�d
��Wd�dS1�s!wYdS)zm
        Allows minions to send files to the master, files are sent to the
        master file cache
        c3rtrrrur�rrrx�r�z&AESFuncs._file_recv.<locals>.<genexpr>)r|r{�locFr{Z	file_recvr|i�file_recv_max_sizer�rz#Invalid file pointer: load[loc] < 0r�z�file_recv_max_size limit of %d MB exceeded! %s will be truncated. To successfully push this file, adjust file_recv_max_size to an integer (in MB) large enough to accommodate it.r{r�r�r�z../r�rZr�zdAttempt to write received file outside of master cache directory! Requested path: %s. Access denied.�abrxNT)"r�r�r�rrr9rorpr6r��lenr=r
rsr�rIra�sepr|r{�normpath�isabsr}�dirnamer��makedirsr�r~r��fopen�seek�writer:r;)	rr0r�Zsep_pathr�Zcpath�cdirry�fp_rr�rrQ�s|

��
���

��zAESFuncs._file_recvcst�fdd�dD��r
dStjj�|j�d�sdS�d�dd<tjj|j�d�d��d��d����d	���d
i���d���d���d
�d�	}|�	�}|j
��|j�dd�r�|jj
�d��d�d�d|d��|j�d�dur�|j�d�dit�ddd��|S)z�
        Return the pillar data for the minion

        :param dict load: Minion payload

        :rtype: dict
        :return: The pillar data for the minion
        c3rtrrrur�rrrx@r�z#AESFuncs._pillar.<locals>.<genexpr>)r|�grainsFr|r�r��envr*�pillar_override�	pillarenv�extra_minion_data�clean_cache)r*r�r�r�r�Zminion_data_cache�
minions/{}r�)r�r�Zminion_data_cache_eventsTzMinion data cache refreshZrefreshrj)r�rr9rorprr�Z
get_pillarr=Zcompile_pillarrnZupdate_optsr%�cache�storer�r2r<r)rr0r�r�rr�rrR7s<	
�
�
�zAESFuncs._pillarcCs2|�|d�}|duriS|j�|�|�|�dS)z�
        Receive an event from the minion and fire it on the master event
        interface

        :param dict load: The minion payload
        r�FN)r�r%rSrTr�rrrrS`s
zAESFuncs._minion_eventcCs�|d}|�dd�dkrt�d||dd�|�dg�D]G}|�di�}d	|vrd|�d
�}|s1q|d	}ztjjj|j|||j|d�Wqt	tj
jfyc}zt�d|||�WYd
}~qd
}~wwqd
S)z5
        Act on specific events from minions
        r|r5�Z_salt_errorz#Received minion error from [%s]: %sr��message�eventsrZ�jid)rlZ	syndic_idz)Could not add minion(s) %s for job %s: %sN)r=r6r�rr9�jobZ
store_minionsrrlr�r��SaltCacheError)rr0r�r2Z
event_datar�rZr�rrrrTos0�

������zAESFuncs._handle_minion_eventcCs|jdrd|vrt�d|d�dSd|vr_t�d�|�d�}tj�|jdd�|d��}t	j
j�|�}t	j
�|||�s[t�d	|d�|jd
rVt�d|d�dSt�d�||d<zt	jjj|j||j|jd
�WdSt	jjy�t�d|�YdSw)aU
        Handle the return data sent from the minions.

        Takes the return, verifies it and fires it on the master event bus.
        Typically, this event is consumed by the Salt CLI waiting on the other
        end of the event bus but could be heard by any listener on the bus.

        :param dict load: The minion payload
        Zrequire_minion_sign_messages�sigzo_return: Master is requiring minions to sign their messages, but there is no signature in this payload from %s.r|Fz*Verifying signed event publish from minionrvr�z0Failed to verify event signature from minion %s.Zdrop_messages_signature_failzAdrop_messages_signature_fail is enabled, dropping message from %szLBut 'drop_message_signature_fail' is disabled, so message is still accepted.)r2rlz,Could not store job information for load: %sN)rr6r�rirIrar{r|r�rZserializersZmsgpackZ	serializerZverify_signaturer7r9r�Z	store_jobr2rlr�r�r�)rr0r�Zthis_minion_pubkeyZserialized_loadrrrrU�sD
�

��
����zAESFuncs._returnc	s���d�}t|t�s
�g}|D]Љt�fdd�dD��rq��d�r<|jdr<d�|jd�}|jj|�d�d�tj	�
|jdd	�}tj	�
|jdd	�d
�}tjj
�||�r�tj	�|�s�tj	�|�d}tj	�|�stt�|�tjj�|d��
}|�d
�Wd�n1s�wY�d��D]G\}}	�d|d�}
|
�|	�d�vr��d|
d<d�vr��d|
d<d�vrňd|
d<d�vrψd|
d<d�vrوd|
d<|�|
�q�qdS)z�
        Receive a syndic minion return and format it to look like returns from
        individual minions.

        :param dict load: The minion payload
        r0c3rtrrrur�rrrx�r�z*AESFuncs._syndic_return.<locals>.<genexpr>)�returnr�r|�master_job_cache�{}.save_loadr�r�Zsyndicsr|r�wr�Nr�)r�r|�	master_idr9Zfun_args�outr�)r=r�r�r�rr�rlrPrar{r|rr9roZ
clean_path�existsrr�r�r�r�r8r#rU)rr0�loadsr�rAZsyndic_cache_path�	path_nameZwfhrrr4rr�rrV�sP

��
�
�
��zAESFuncs._syndic_returncCs$|�|d�}|duriS|j�|�S)z�
        Execute a runner from a minion, return the runner's function data

        :param dict clear_load: The minion payload

        :rtype: dict
        :return: The runner function data
        )r9ryr|r{F)r�r%rW)rrwr0rrrrW�r�zAESFuncs.minion_runnercCs�|�|d�}|duriStj�|jdd�}tj�|�s!t�|�tj�|t|d��}tj	j
�|d��}|d|��ksFiWd�SWd�n1sPwY|j
�|d�S)	a
        Request the return data from a specific jid, only allowed
        if the requesting minion also initiated the execution.

        :param dict load: The minion payload

        :rtype: dict
        :return: Return data corresponding to a given JID
        )r�r|r{Fr�Zpublish_authr��rr|N)r�rar{r|rr�r�r�rr9r�r��readriZget_cache_returns)rr0Z
auth_cacheZjid_fnr�rrrrX�s

��zAESFuncs.pub_retcC�|�|�siS|j�|�S)aL
        Publish a command initiated from a minion, this method executes minion
        restrictions so that the minion publication will only work if it is
        enabled in the config.

        The configuration on the master allows minions to be matched to
        salt functions, so the minions can only publish allowed salt functions

        The config will look like this:

        .. code-block:: bash

            peer:
                .*:
                    - .*

        This configuration will enable all minions to execute all commands:

        .. code-block:: bash

            peer:
                foo.example.com:
                    - test.*

        The above configuration will only allow the minion foo.example.com to
        execute commands from the test module.

        :param dict clear_load: The minion pay
        )� _AESFuncs__verify_minion_publishr%rY�rrwrrrrY�
zAESFuncs.minion_pubcCr�)aD
        Publish a command initiated from a minion, this method executes minion
        restrictions so that the minion publication will only work if it is
        enabled in the config.

        The configuration on the master allows minions to be matched to
        salt functions, so the minions can only publish allowed salt functions

        The config will look like this:

        .. code-block:: bash

            peer:
                .*:
                    - .*

        This configuration will enable all minions to execute all commands.
        peer:

        .. code-block:: bash

            foo.example.com:
                - test.*

        The above configuration will only allow the minion foo.example.com to
        execute commands from the test module.

        :param dict clear_load: The minion payload
        )r�r%rZr�rrrrZ:r�zAESFuncs.minion_publishcCsF|�|d�}|j�dd�st�d|d�|S|dur|S|j�|�S)a2
        Allow a minion to request revocation of its own key

        :param dict load: The minion payload

        :rtype: dict
        :return: If the load is invalid, it may be returned. No key operation is performed.

        :rtype: bool
        :return: True if key was revoked, False if not
        r�Zallow_minion_key_revokeFzKMinion %s requested key revoke, but allow_minion_key_revoke is set to Falser|)r�rr=r6r�r%r[r�rrrr[]s�zAESFuncs.revoke_authcCs�|�d�riddifSt||�r<zt��}t||�|�}t�d|t��|�Wnty;d}tjd|dd�Yn
wt�d	|�d
ddifS|dkrR|ddifS|dkrxd
|vrx|�d�dkrn|j	ddkrn|ddifS|dd|d
d�fS|ddifS)z�
        Wrapper for running functions executed with AES encryption

        :param function func: The function to run
        :return: The result of the master function that was called
        �__r9r=z'Master function call %s took %s secondsr�zError in function %s:
Tr�zHReceived function %s which is unavailable on the master, returning FalseFrUrRr|�ver�2Zpillar_versionr+Zsend_privater�)r9rrz)
r}rrKr'r6rir�r�r=r)r�funcr0rqr4rrrr>xs2

���zAESFuncs.run_funccCs,|j��|jdur|j��d|_dSdSr)r%rrir&rrrr�s




�zAESFuncs.destroyN)r@rArBrCrHrrmrsrJr�r�rKrLrMrNrOrPrQrRrSrTrUrVrWrXrYrZr[r>rrrrrrD�s8'
8"
#U)34##)rDc@s�eZdZdZdZdd�Zdd�Zdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zdd�Zdd�Z
edd��Zd#dd�Zdd�Zdd�Zdd�Zd d!�Zd"S)$rBz~
    Set up functions that are safe to execute when commands sent to the master
    without encryption and authentication
    )�ping�publish�	get_token�mk_token�wheelrVcCs�||_||_tjjj|j|jddd�|_tj�|jd�|_tjj	�
|�|_tj�
|�|_tjj|jdddd�|_tj�|�|_tjj�||�|_g|_dS)NrQFrRreTrf)rrrr9r2r]rgrhrirZr[r\�authZLoadAuth�loadauthrjrkrlr�ZWheel�wheel_r$r%Z
LocalFuncs�channels)rrrrrrr�s�
�
zClearFuncs.__init__c
Csv|�|�\}}}}|jj|||d�}|�d�}|rd|iS|�d�}|dkr\|j�|�dg�|d|�di��}	|	sEd|d�||�d	�iSt|	t�rPd|	vrP|	S|D]}
|�	|
d
�qRnd|vrt|d}t
j�|��
�rs|j�dd�}nt
jj��}z|�	d�}t
j�|j�}|j||�di�|dd
�WSty�}
zt�d||
�d|
jj|
jt|
�d�iWYd
}
~
Sd
}
~
ww)zJ
        Send a master control function back to the runner system
        �rr��usernamer��	auth_listr9�kwarg�9Authentication failure of type "{}" occurred for user {}.�r�r�NrAT)ri�-Exception occurred while introspecting %s: %s)r�r�r�)�_prep_auth_infor��check_authenticationr=r\�runner_checkr�r�rUrIrr��AuthUser�is_sudorr9r�r�rVrWZasynchronousr�r6r�r!r@r�r�)rrw�	auth_type�err_namer�sensitive_load_keysr�r�r�r�rr9rcr�rrrrV�s\



���	��
�����zClearFuncs.runnerc
Cs|�|�\}}}}|jj|||d�}|�d�}|rd|iS|�d�}|dkr\|j�|�dg�|d|�di��}	|	sEd|d�||�d	�iSt|	t�rPd|	vrP|	S|D]}
|�	|
d
�qRnd|vrt|d}t
j�|��
�rs|j�dd�}nt
jj��}zSt
jj�|j�}|�	d�}t|dd
�}
d|��||
|d�}|j�|t|dgd��|jj|fddi|��}|d|d<|d|d<|j�|t|dgd��|
|d�WSt�y}z-t�d||�d�||jj|�|d<d|d<|j�|t|dgd��|
|d�WYd
}~Sd
}~ww)zI
        Send a master control function back to the wheel system
        r�r�r�r�r�r9r�r�r�NrAr�)�prefixzwheel.)r9r�r5r�r�Zfull_returnTr��successr4)r5r�r�z&Exception occurred in wheel {}: {}: {}F)r�r�r�r=r\�wheel_checkr�r�rUrIrr�r�r�rr9r�r�r�Zgen_jidrr2r<r�Z	call_funcr�r6r�r!r@)rrwr�r�rr�r�r�r�r�rr�r9r5r�r4r�rrrr�sr



���	��
����zClearFuncs.wheelcCs"|j�|�}|st�d�dS|S)z�
        Create and return an authentication token, the clear load needs to
        contain the eauth key and the needed authentication creds.
        z0Authentication failure of type "eauth" occurred.r�)r�r�r6r�)rrwrrrrrr�bs

zClearFuncs.mk_tokencCsd|vrdS|j�|d�S)zZ
        Return the name associated with a token or False if the token is invalid
        rrF)r�Zget_tokr�rrrr�mszClearFuncs.get_tokenc	Cs\|�di�}tj�|jd�}|�|d�s|�|d�r/t�d|d|d�dddd	�iS|�d
t	�}|j
�|d|�dd
�|�}|�dt��}|�dt��}|�dd�}|�dd�}	|�
|�\}
}}}
|
dkrt|jj||
|d�}n|j�||
�}d}d|vr�|�dg�}|dur�|	||j�dd�kr�|}n|�dg�}d|
�d�}|�d�r�t�|�dddd	�i}d|vr�|j�i|�|�t|ddgd��|S|
dks�|
dk�rY|�rY|j
j||d|d|d|�dd
�|dgd�}|�s7|
d k�r|�sd!|v�rd |v�rt�d"|d |d!�t�|�dddd	�i}d|v�r5|j�i|�|�t|ddgd��|S|
d#k�rL|�d!�}||d<t�d$|�n
|
d k�rY|j�|�|d<|j�d%��sq|�sqd&d|d'�|d�d(�d)�S|�||�}|du�r�d&dd*id)�S|�|||||�}|j�d%��r�||d<|j||d+�|�|�d&|d||d,�d)�S)-zt
        This method sends out publications to the minions, it can only be used
        by the LocalClient.
        rNZpublisher_acl_blacklistr�r9zq%s does not have permissions to run %s. Please contact your local administrator if you believe this is in error.
r�ZAuthorizationErrorzAuthorization error occurred.r��	delimiterrzr~rrZ�missing�ssh_minionsFrNr�r�rAz Authentication failure of type "z" occurred.ZAuthenticationErrorzAuthentication error occurred.r�r�ryzsaltutil.find_job)rZZ	whitelist�eauthr�z8Auth configuration for eauth "%s" and user "%s" is emptyrrzMinion tokenized user = "%s"Z
order_mastersr�z.Master could not resolve minions for target {})r�rZr�)r/r0zMaster failed to assign jid)r�)r�rZr�)r=rZaclZPublisherACLrZuser_is_blacklistedZcmd_is_blacklistedr6r�rr\Z
check_minionsr�r�r�r�rIr�r2r<rr�r>Z	load_namer��	_prep_jid�	_prep_pub�
_send_ssh_pub�	_send_pub)rrw�extraZ
publisher_aclr�Z_resrZr�r�Zauth_keyr�r�rr�r�Zsyndic_auth_listr��err_msgr�Z
authorizedr�r�r�rrrr�us��������

���
�
�

�
��

�


���

�zClearFuncs.publishcCsTg}d}d|vrd}d}dg}nd|vrd}d}ddg}nd}d}|j}||||fS)	NrrZTokenAuthenticationErrorr�ZEauthAuthenticationErrorr��passwordr�ZUserAuthenticationErrorr�)rrwr�rr�r�rrrr�	s
zClearFuncs._prep_auth_infoc	Cs�|�d�r	|dnd}|�dd�}d�|jd�}z
|jj|||d�}W|SttfyDd�|�d	�d
�}t�	|�d|iYSw)z3
        Return a jid for this publication
        r�N�nocacheFz{}.prep_jidr�)r��
passed_jidzJFailed to allocate a jid. The requested returner '{}' could not be loaded.rwrr�)
r=r�rrlrPr�r�rr6r�)rrwr�r�r�r�r��msgrrrr�(	s	��
�zClearFuncs._prep_jidcCsP|jst|j�D]\}}tjjj�|�}|j�|�q|jD]}|�	|�qdS)zQ
        Take a load and send it across the network to connected minions
        N)
r�rrrr�r�r�r�rr�)rr0rdrr
rrrr�@	s
�zClearFuncs._send_pubcCs&t|d�stjjjj|jd�|_|jS)N�_ssh_client)r�)rrrgZsshZ	SSHClientrr�r&rrr�
ssh_clientK	s
zClearFuncs.ssh_clientFcCsB|jddur|durt�d�tj|jj|d���dSdSdS)zK
        Take a load and send it across the network to ssh minions
        Zenable_ssh_minionsTzSend payload to ssh minions)r�rNN)rr6r>r�r�r�r6rq)rr0r�rrrr�Q	s
�zClearFuncs._send_ssh_pubc
	Csd||d<|�di��dt�}|j�d|i|d�|d|d|d|d|d|d	||d
�}|j�|t|ddgd��|jd
r�d�|jd
�}d}	ztjj	�
|jj|�}
d|
j	vrgt
�d|jd
�Wnttfy~d}	t
�d|jd
�Ynw|	r�z|jj||d||d�Wnty�t
jddd�Ynwzd�|jd�}|jj||d||�Wn!ty�t
�d|jd�Ynty�t
jddd�Ynwddi}|d|d	|d|d|dd�}d|jvr�|jd|d<d|v�r|d|d<|tk�r||d<d|v�r|d|d<d|v�r%|d|d<d|v�r0|d|d<d|v�r�d|dv�rE|d�d�|d<d |dv�rU|d�d �|d <d!|dv�re|d�d!�|d!<d"|dv�ru|d�d"�|d"<d#|dv�r�|d�d#�|d#<d|v�r�t
�d$|d|d|d�|d|d<nt
�d%|d|d�t
�d&|�|S)'z�
        Take a given load and perform the necessary steps
        to prepare a publication.

        TODO: This is really only bound by temporal cohesion
        and thus should be refactored even further.
        r�rNr�rZr~rzr�r9ry)r�r~rzr�r9ryrZr�r�r�Z
ext_job_cacher�Tz�The specified returner used for the external job cache '%s' does not have a 'minions' kwarg in the returner's save_load function.Fz_The specified returner used for the external job cache "%s" does not have a save_load function!)rZz,The specified returner threw a stack trace:
r�r�z]The specified returner used for the master job cache "%s" does not have a save_load function!r/r'r4)r9ryrzr�r4r�r|�toZ
ret_config�metadataZmodule_executorsZ
executor_optsZ
ret_kwargsz(User %s Published command %s with jid %sz Published command %s with jid %szPublished command details %s)r=rr2r<rrr�rr9r�Zget_function_argspecrlrPr6r�rIr�r�r7r>)
rrZr�rwr�r�r�Znew_job_loadr�Zsave_load_funcZarg_specr�r0rrrr�Y	s��

�
����


�
����
�







��zClearFuncs._prep_pubcCs|S)z3
        Send the load back to the sender.
        rr�rrrr��	szClearFuncs.pingcCsZ|jdur
|j��d|_|jdur|j��d|_|jr+|j��}|��|jsdSdSr)r%rrir�rIr()rr
rrrr�	s




�zClearFuncs.destroycCs>|jrdSt|j�D]\}}tjjj�|�}|j�|�q
dSr)	r�rrrr�r�r�r�r)rrdrr
rrrrC�	s�zClearFuncs.connectN)F)r@rArBrCrHrrVr�r�r�r�r�r�r��propertyr�r�r�r�rrCrrrrrB�s*
AM"

rB)[rCr#r�r�r?�loggingr�rar�r�r�r.r�rKZsalt.aclrZ	salt.authZsalt.channel.serverZsalt.clientZsalt.client.ssh.clientZ
salt.cryptZsalt.daemons.masterapiZsalt.defaults.exitcodesZsalt.enginesZsalt.exceptionsZsalt.ext.tornado.genZsalt.keyZsalt.minionZsalt.payloadZsalt.pillarZsalt.runnerZsalt.serializers.msgpackZ
salt.stateZsalt.utils.argsZsalt.utils.atomicfileZsalt.utils.eventZsalt.utils.filesZsalt.utils.gitfsZsalt.utils.gzip_utilZsalt.utils.jidZsalt.utils.jobZsalt.utils.masterZsalt.utils.minionsZsalt.utils.platformZsalt.utils.processZsalt.utils.scheduleZsalt.utils.ssdpZsalt.utils.stringutilsZsalt.utils.userZsalt.utils.verifyZsalt.utils.zeromqZ
salt.wheelZsalt.configrZ
salt.defaultsrZsalt.ext.tornado.stack_contextrZsalt.transportrZsalt.utils.channelrZsalt.utils.ctxrZsalt.utils.debugrr	r
rZsalt.utils.odictrr
rr�r��ImportError�	getLoggerr@r6rr9r�ZSignalHandlingProcessrFr�r�r�rrGrDrBrrrr�<module>s��
WR?_\