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

�N�gR��@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlmZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl!Zddl"Zddl#Zddl$Zddl%Zddl&Zddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-ddl.m/Z/ddl0m1Z1zddl2ZdZ3Wne4y�dZ3Ynwz6dd	l5m6Z7dd
l8m9Z9ddl:m;Z<ddl=m>Z>m?Z?dd
l@mAZAe�Bd��CejD�e�Bd��CejD�dZEWne4�ydZEYnwdZFz%ddlGZGddlHZHddlImJZJeG�Kd�ZLejMjN�OeLjPdeF��s+dZQndZQWne4�y:dZQYnwzddlRZRWne4�ySejMjS�T��sQ�YnwzddlUZUdZVWne4�yhdZVYnwdZWddddd�ZXe�YdejZ�Z[e�YdejZ�Z\dZ]dZ^e�Be_�Z`d�dd �Zad!d"�Zbd#d$�Zcd�d%d&�Zdd�d(d)�Zed*d+�Zfd,d-�Zgd.d/�Zhd0d1�Zid2d3�Zjd�d5d6�Zkd�d7d8�Zld�d9d:�Zmd�d<d=�Znd>d;de]e^fd?d@�ZoGdAdB�dB�Z6d�dDdE�Zpd�dFdG�Zqd�dHdI�Zrd�dJdK�Zs	d�dLdM�Zt	Pd�dQdR�Zu	Pd�dSdT�Zv	>	U	V			U	P			W	d�dXdY�ZwdZd[�Zx	C	;	N													U				\				]		d�d^d_�Zy	>	;	V																			U	U											`				d�dadb�Zz		>	;	V			U								cd�ddde�Z{dfdg�Z|d�didj�Z}d�dkdl�Z~d�dmdn�Zd�dodp�Z�d�dqdr�Z�dsdt�Z�dudv�Z�d�dwdx�Z�d�dzd{�Z�d|d}�Z�d~d�Z�d�d��Z�d�d�d��Z�			y	�	P	Od�d�d��Z�d�d�d��Z�d�d�d��Z�d�d��Z�d�d�d��Z�d�d�d��Z�d�d�d��Z�					d�d�d��Z�		d�d�d��Z�d�d�d��Z�d�d�d��Z�d�d�d��Z�d�d�d��Z�d�d��Z�d�d��Z�d�d��Z�d�d��Z�d�d��Z�d�d��Z�e��d�e��d�d��Z�d�d��Z�d�d�d��Z�d�d��Z�			d�d�d��Z�d�d��Z�d�d��Z�d�d��Z�dS)�z"
Utility functions for salt.cloud
�N)�Template)�SaltCloudConfigError�SaltCloudException�SaltCloudExecutionFailure�SaltCloudExecutionTimeout�SaltCloudPasswordError�SaltCloudSystemExit)�NonBlockingPopen)�is_writeableTF)�Client)�
SCMRException)�Service)�CannotDelete�SMBResponseException)�TreeConnectZsmbprotocolZpypsexecz0.3.0)�WinRMTransportErrorZpywinrmz>=zutf-8ZrunningZ	rebootingZ
terminated�pending)r���z"(?:.*)[Pp]assword(?: for .*)?:\ *$z((?:.*sudo)(?:.*)[Pp]assword(?: for .*)?:�<r�cCs�t�d|�z1tjj�|d��}ttjj�|�	���}t
|j|||d��Wd�WS1s0wYWdStyatjj�|d��}t
|�	��Wd�YS1sYwYYdSw)z$
    Return the rendered script
    zRendering deploy script: %s�r)�optsZvm�minionN)
�log�info�salt�utils�files�fopenr�stringutils�
to_unicode�read�str�render�AttributeError)�path�vm_rr�fp_�template�r+�D/opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/cloud.py�__render_script�s(�
*��r-cCs<i}|r|d|d<|d|d<|d|d<|d|d<|S)z�
    Return a dictionary with gateway options. The result is used
    to provide arguments to __ssh_gateway_arguments method.
    �ssh_gateway�ssh_gateway_key�ssh_gateway_user�ssh_gateway_commandr+)�gatewayZextended_kwargsr+r+r,�__ssh_gateway_config_dict�sr3cCs�d}|�dd�}d}d|vr|�d�\}}|�dd�}|rh|�d|�}d|vr.d	�|d�nd}|�d
d�}d�d
dd�|�dt��d�|�dt��ddt|�|�d|��dt|�t|�f�}t�d||||�|S)a
    Return ProxyCommand configuration string for ssh/scp command.

    All gateway options should not include quotes (' or "). To support
    future user configuration, please make sure to update the dictionary
    from __ssh_gateway_config_dict and get_ssh_gateway_config (ec2.py)
    rr.��:r1znc -q0 %h %p�ssh_gateway_portr/�-i {}r0�root� Zssh�-oStrictHostKeyChecking=no�-oServerAliveInterval={}�server_alive_interval�-oServerAliveCountMax={}�server_alive_count_max�-oUserKnownHostsFile=/dev/null�-oControlPath=none�@z-pzUsing SSH gateway %s@%s:%s %s)	�get�split�format�join�SERVER_ALIVE_INTERVAL�SERVER_ALIVE_COUNT_MAXr$rr)�kwargsZextended_argumentsr.r6r1r/r0r+r+r,�__ssh_gateway_arguments�sN��
�
����rIcCs�|rt|�}tj�|�rt||||�Stj�|�d��r&t|�d�|||�S|dD]:}tj�tj�||��rEttj�||�|||�Stj�tj�||�d���rdttj�||�d��|||�Sq*dS)z;
    Return the script as a string for the specific os
    �.sh�deploy_scripts_search_pathr)�salt_config_to_yaml�osr'�isabsr-�isfilerE)Zos_r(rrZsearch_pathr+r+r,�	os_script�s��rP�cCs�|dkrd}t��}tj�|d|�tj�|d�}tj�|d�}tjj	�
|��}tjj�|�
��}Wd�n1s;wYtjj	�
|��}tjj�|�
��}Wd�n1s[wYt�|�||fS)zG
    Generate Salt minion keys and return them as PEM file strings
    rQrz
minion.pemz
minion.pubN)�tempfileZmkdtempr�crypt�gen_keysrMr'rErrr r!r"r#�shutil�rmtree)�keysizeZtdirZ	priv_pathZpub_pathr)Zpriv�pubr+r+r,rT�s��
rTcCs�dD]}tj�||�}tj�|�st�|�qtj�|d|�}tjj�|d��}|�	tjj
�|��Wd�n1s<wYtj�|d|�}tj�|�r|tjj�|��}|�
�|krjt�|�Wd�dSWd�dS1suwYdSdS)z�
    If the master config was available then we will have a pki_dir key in
    the opts directory, this method places the pub key in the accepted
    keys dir and removes it from the unaccepted keys dir if that is the case.
    )�minions�minions_preZminions_rejectedrYzw+NrZ)rMr'rE�exists�makedirsrrrr �writer!�to_strrOr#�remove)�pki_dirrX�id_Zkey_dir�key_path�keyr)�oldkeyr+r+r,�
accept_keys$
���"��recCs:tj�|d|�}tj�|�rt�|�t�d|�dSdS)zH
    This method removes a specified key from the accepted keys dir
    rYzDeleted '%s'N)rMr'rErOr_r�debug)r`rarcr+r+r,�
remove_key!s

�rgcCs@tj�|d|�}tj�|d|�}tj�|�rt�||�dSdS)z>
    Rename a key, when an instance has also been renamed
    rYN)rMr'rErO�rename)r`raZnew_idrdZnewkeyr+r+r,�
rename_key+s
�ric	Cs�dddd�}|d|d<tj�d||�}|dur||d<|�tjjd	||id
d��tj�d||�}d
|vr>|d
ur>td��|�di��tjjd||id
d��|S)zI
    Return a minion's configuration for the provided options and VM
    rr�sha256)�master�	log_level�	hash_type�name�id�
master_fingerNrT��default�
search_global�make_masterrkz?A master setting was not defined in the minion's configuration.�grains)r�config�get_cloud_config_value�updater�
setdefault)rr(rrprtr+r+r,�
minion_config5s0�
��
�
��rzc	Cs>t�tjj�}|jdddd�|�tjjd||idd��|S)zI
    Return a master's configuration for the provided options and VM
    rrj)rlZlog_level_logfilermrkTrq)�copy�deepcopyrrvZDEFAULT_MASTER_OPTSrxrw)rr(rkr+r+r,�
master_configcs
��r}�
cCstjjj||dd�S)zR
    Return a salt configuration dictionary, master or minion, as a yaml dump
    F)�
line_breakZdefault_flow_style)rrZyamlZ	safe_dump)Z
configurationrr+r+r,rLxs�rLcCsV|durt}tjjd||dd�}tjjd||dd�}|dur(|dur(dddiiS|�d	�d
kr2d}nd}tjjd||dtjjd
||ddd�d�}|durZtj�|�sZtd|�d���d}|�dd�rudtj	vrut
�t�
tj	d�j�rud}|dur�tjjd||dd�dur�tjjd||dd�dur�|dur�t
d��i}t||�}ttjjd||dd�|||�}	tjjd||dd�}
d|vr�|�dd�|d<d|v�rd|v�rt�d|d�ttj�d ||��\|d<|d<|�d�}d!|vr�d"�||d!g�}t|d#|d|�d|v�rtj�d$||�|d<tj�d%||�}id&|�d'|�d(tjjd)||d*d��d+|�d+|��d,|
�d$|	�d|�d|d�d-|�d.tjjd.||d/d��d0|�d1|d1�d2|d2�d3|d3�d4|d4�d5|d�d6|d�id7tjjd7||dd��d8|d8�d9tjjd9|||
dkd��d:tjjd:||dd��d;tjjd;||dd��dtjjd||dd<��d|�d=tj�d=||��d>tj�d>||��d?|�d@tjjd@||dd��dA|�dAd��dBtjjdB||dd��dCtjjdC||dDd��dEtjjdE||dd��dFtjjdG||dHd��dItjjdI||gd���dJ|d	|dK|dLdM�i�}
|
��}dN|v�r2|
�dN|dNi�tj�dO||�du�rad|
dO<|dP|
dP<|dQ|
dQ<t||�}||
dR<|�dSd��rad|
dT<tjjdU||dd�|
dU<|�rtdV|
dG<tj�dW||�}|�r�tjjdX||dYd�|
d(<||
dW<t||�}|dZ|
dZ<tjjd[||d\d�|
d,<tjjd||d]d�}|�r�||
d<tjjd^||dd�|
d^<tjjd_||d`d�|
d_<tjjda||dd�|
da<tjjdb||dd�|
db<|�r�dc|
dd<t�|
�}|d&=|d5=|d6=|d:=d|v�r|d=||de<tdfdgdh�|d�ditjj�|�i|�d3tj�td3dZ��|�djdk�dl�|�rR|du�rRtdsi|��}|du�rLt�dm|d�d|dn<|S|�r]t dsi|
��}nt!dsi|
��}|�r{tdsi|��}|du�r{t�dm|d�|du�r�d|dn<|du�r�|�|�t�do|d�|St�"dp|d�ddqdr�|d�iiS)tz�
    This is the primary entry point for logging into any system (POSIX or
    Windows) to install Salt. It will make the decision on its own as to which
    deploy function to call.
    N�deployF�rr�
inline_script�Errorz	No Deployz''deploy' is not enabled. Not deploying.�driverZsaltifyT�key_filenameZssh_keyfile�rsrrzThe defined ssh_keyfile '�' does not existZ	ssh_agentZ
SSH_AUTH_SOCK�passwordZwin_passwordz�Cannot deploy Salt in a VM if the 'key_filename' setting is not set and there is no password set for the VM. Check the provider docs for 'change_password' option if it is supported by your provider.rM�bootstrap-salt�ssh_usernamer8�file_transport�sftpZpub_keyZpriv_keyzGenerating keys for '%s'rnrWZ
append_domain�.r`�scriptZssh_hostr�host�portZssh_portr4�	salt_host�username�
has_ssh_agent�tmp_dir�/tmp/.saltcloudr(�start_action�parallel�sock_dir�	conf_file�
minion_pem�
minion_pub�master_sign_pub_file�keep_tmp�sudo�
sudo_password�tty)rs�script_args�
script_env�minion_conf�force_minion_config�preseed_minion_keys�display_ssh_output�known_hosts_file�	/dev/null�file_map�maxtriesZwait_for_passwd_maxtries��preflight_cmds�cloud_grains�provider�profile)r�r�r�r2rt�
master_pub�
master_pem�master_confZ
syndic_master�make_syndic�make_minionr�
win_installerZsmb_port�rkZwin_username�
Administratorr�	use_winrm�
winrm_port�b�
winrm_use_ssl�winrm_verify_sslr�port_timeout�
deploy_kwargs�eventzexecuting deploy scriptzsalt/cloud/{}/deployingrH�	transport�zeromq��argsr�r�z#Inline script(s) ha(s|ve) run on %s�deployedzSalt installed on %szFailed to start Salt on host %szNot DeployedzFailed to start Salt on host {}r+)#�__opts__rrvrwrBrMr'rOr�environ�stat�S_ISSOCK�st_moderrzrPrrfrTrErer{rxr}r|�
fire_eventrDr�dataZsimple_types_filter�run_inline_scriptr�deploy_windows�
deploy_script�error)r(rZ
deploy_configZinline_script_configZsaltify_driverr�r��retr�Zdeploy_script_coder�Zkey_idr�r�Zinline_script_kwargsr�r�rZwin_passZevent_kwargsZinline_script_deployedr�r+r+r,�	bootstrap�s���
��	
�
�
����
���

��������	�
��
�����������������"�#�$�%�&��)�*��-��0��3��6��9��@


��
�

��
�
�
�
�


�	




�r�cCsr|durdg}tj�d||�}t|t�s|g}dd�|D�}|dd�}|D]}||vr1|�|�q&|�|�|S)zT
    Return the ssh_usernames. Defaults to a built-in list of users for trying.
    Nr8r�cSsg|]}|r|�qSr+r+)�.0�xr+r+r,�
<listcomp>�sz!ssh_usernames.<locals>.<listcomp>)rrvrw�
isinstance�list�append�extend)r(rZ
default_usersZ	usernames�initialrnr+r+r,�
ssh_usernames�s

�
r��c
Ks�t��}t�d|�d}	|d7}z|d
i|��}t|t�s!|WSWn$tyF}zt�d|�t�d�t�d||�WYd}~nd}~wwt��||krWt�d|�d	Sq
)z6
    Wait until a function finishes, or times out
    zAttempting function %srTrz$Caught exception in wait_for_fun: %sz!Retrying function %s on  (try %s)NzFunction timed out: %sFr+)�timerrfr��bool�	Exception�sleepr�)�fun�timeoutrH�start�trycount�response�excr+r+r,�wait_for_fun�s(
�
���r�r4cCs.t��}|}|}|r1|d}	d}
d|	vr|	�d�\}	}
d|vr#|d}
|	}|
}t�d|||	|
�nt�d||�d}	|d	7}zt�tj|�rPt�tjtj�}nt�tjtj�}Wnt	yjt�tjtj�}Ynwz|�
d
�|�|t|�f�|�
tj�|��Wn@t	y�}
z3t�d|
�t�d	�t��||kr�t�d|�WYd
}
~
dSt�d|r�dnd|||�WYd
}
~
nd
}
~
wwq;|s�dSt�d||�g}|�dd|��d|��ddg�d|vr�|�dddddd�|d�g�d|�d |��}d!�d �|�|d"|	|
t�d#��}d!�d �|�|d"|	|
t�|��}t�d$|�d|�d%d
�d&�}d}d}d
}	|d	7}|�sat|fd'di|��}|dk�rPd}n
|d	8}t�d(|�|�satd)��|�rut|fd'di|��}|dk�rudSt�d	�t��||k�r�t�d|�dSt�d*|||	|
|��q7)+a
    Wait until a connection to the specified port can be made on a specified
    host. This is usually port 22 (for SSH), but in the case of Windows
    installations, it might be port 445 (for psexec). It may also be an
    alternate port for SSH, depending on the base image.
    r.r4r5r6zEAttempting connection to host %s on port %s via gateway %s on port %sz+Attempting connection to host %s on port %srTr�z%Caught exception in wait_for_port: %szPort connection timed out: %sNFz0Retrying connection to %s %s on port %s (try %s)r2r�z#Gateway %s on port %s is reachable.r:z-oServerAliveInterval=z-oServerAliveCountMax=r?r@r/�-oPasswordAuthentication=no�$-oChallengeResponseAuthentication=no�-oPubkeyAuthentication=yes�-oIdentitiesOnly=yes�!-oKbdInteractiveAuthentication=nor7znc -z -w5 -q0 r9zssh {} {}@{} -p {} {}r0�date�SSH command: '%s'Zssh_gateway_password)r�r��
allow_failurezAGateway usage seems to be broken, password error ? Tries left: %sz-SSH gateway is reachable but we can not loginzMRetrying connection to host %s on port %s via gateway %s on port %s. (try %s))r�rCrrf�socket�	inet_pton�AF_INET6�SOCK_STREAM�AF_INET�OSError�
settimeout�connect�int�shutdown�	SHUT_RDWR�closer�r�r�rDrE�shlex�quoterB�
_exec_ssh_cmdr)r�r�r�r2r<r>r�Z
test_ssh_hostZ
test_ssh_portr.r6r��sockr��ssh_args�commandZpcmd�cmdrHZusable_gatewayZgateway_retriesZpstatus�statusr+r+r,�
wait_for_port�s���


����������
�
��

��rc@s^eZdZdZ					ddd�Zdd�Zd	d
�Zdd�Zd
d�Zdd�Z	dd�Z
ddd�ZdS)rat
    Wrap pypsexec.client.Client to fix some stability issues:

      - Set the service name from a keyword arg, this allows multiple service
        instances to be created in a single process.
      - Keep trying service and file deletes since they may not succeed on the
        first try. Raises an exception if they do not succeed after a timeout
        period.
    Nr�TcCs>||_|j�d�|_t|||||�|_t|j|jj�|j_dS)Nz.exe)�service_name�	_exe_file�PsExecClient�_client�ScmrService�session�_service)�selfZserverr�r�r��encryptrr+r+r,�__init__us	zClient.__init__cCs|��|��|S�N)r��create_service�rr+r+r,�	__enter__�szClient.__enter__cCs|��|��dSr)�remove_service�
disconnect)rZtb_typeZtb_value�tbr+r+r,�__exit__�szClient.__exit__cC�
|j��Sr)rr�rr+r+r,r���
zClient.connectc
CsJz|j��Wnty}zt�d|�WYd}~nd}~ww|j��S)Nz Exception cleaning up PAexec: %r)rZcleanuprrrfr)rr�r+r+r,r�s��
zClient.disconnectcCrr)rrrr+r+r,r�rzClient.create_servicecOs|jj|i|��Sr)r�run_executable)rr�rHr+r+r,r�szClient.run_executable�
rc
CsHt�d�t��}	z|jj��Wn)ty;}zt�dt|��t��||kr,|�t�|�WYd}~q	d}~ww	t	|jj
d|jjj�d��}t�
d|j�|��t��}	zt�
d�|j�||j�Wn+ty�}zt�d	|jt|��t��||kr�|�t�|�WYd}~qZd}~ww	t�
d
|j�|��dS)z�
        Removes the PAExec service and executable that was created as part of
        the create_service function. This does not remove any older executables
        or services from previous runs, use cleanup() instead for that purpose.
        z1Deleting PAExec service at the end of the processTz/Exception encountered while deleting service %sNz\\z\ADMIN$zConnecting to SMB Tree %sz7Creating open to PAExec file with delete on close flagszException deleting file %s %szDisconnecting from SMB Tree %s)rrfr�rr�deleter�reprr�rr
�
connectionZserver_namerZ
share_namer�Z_delete_filerrr)rZwait_timeoutZ
sleep_waitZ
wait_startr�Zsmb_treer+r+r,r�sH

���

��zClient.remove_service)NNr�TN)rr)�__name__�
__module__�__qualname__�__doc__rrrr�rrrrr+r+r+r,rjs

�	rr�c	Cs^d|�d|�d|��}d|�d|��}d|�d|�d|��}d|�d|�d|��}t||d�S)z:
    Run a command remotely via the winexe executable
    z-U '�%�' //z%XXX-REDACTED-XXX' //zwinexe r9��logging_command)�win_cmd)	rr�r�r�r�r�ZcredsZ
logging_creds�logging_cmdr+r+r,�run_winexe_command�s
r(cCs^dt����}t||||d|d��}|�||�\}}	}
Wd�n1s%wY||	|
fS)z:
    Run a command remotely using the psexec protocol
    zPS-Exec-F)r�r
rN)�uuid�uuid4rr)rr�r�r�r�r�r�client�stdout�stderr�ret_coder+r+r,�run_psexec_command�s��
r/c	
Cs�t��}t�d||�d}	|d7}ztdd||||�}|dkr(t�d�WdSt�d|�WntyG}zt�d	|�WYd
}~nd
}~wwt��||krRdSt�d�q)z:
    Wait until winexe connection can be established.
    z2Attempting winexe connection to host %s on port %srTrZsczquery winexesvczwinexe connected...�Return code was %sz*Caught exception in wait_for_winexesvc: %sNF)r�rrfr(r�r�)	r�r�r�r�r�r��	try_countr.r�r+r+r,�wait_for_winexe�s*�
��
�r2c
Cs�t��}d}	|d7}d}ztdd||||d�\}}	}Wnty3}
zt�d�WYd}
~
nd}
~
ww|dkr?t�d	�dSt��||krId
St�d|||�t�d�q)z:
    Wait until psexec connection can be established.
    rTr�cmd.exe�/c hostname�r�zUnable to execute commandNzpsexec connected...Fz9Retrying psexec connection to host %s on port %s (try %s))r�r/r�r�	exceptionrfr�)r�r�r�r�r�r�r1r.r,r-r�r+r+r,�wait_for_psexecsvc�s4���
�
�r7c
Cs>t|||d�t��}t�d||�d}|sd}d}		|	d7}	zI|||f|d�}
|s3t�d	�d
|
d<tjdi|
��}t|jd�rG|j�d
�t�	d|j
�|�d�}|jdkr`t�d�|WSt�d|j�Wnt
y�}
zt�d|
�WYd}
~
nd}
~
wwt��||kr�t�d|�dSt�d|||	�t�d�q)z9
    Wait until WinRM connection can be established.
    �r�r�r�z1Attempting WinRM connection to host %s on port %s�sslZntlmrTr)�targetZauthr�z"SSL validation for WinRM disabled.�ignoreZserver_cert_validation�set_timeoutr�zWinRM endpoint url: %szsc query winrmzWinRM session connected...r0z&Caught exception in wait_for_winrm: %sNzWinRM connection timed out: %sz8Retrying WinRM connection to host %s on port %s (try %s)r+)rr�rrf�winrmZSession�hasattr�protocolr<�trace�url�run_cmd�status_coderr�r�)r�r�r�r�r��use_ssl�verifyr�r�r�Zwinrm_kwargs�srr�r+r+r,�wait_for_winrmsR�



���
�rGr�rrc	CsFd|�d|�d|�d�}d�||�}t|�D]}t||d�}q|dkS)�4
    Check if the windows credentials are valid
    zwinexe -U 'r"r#z "hostname"z/winexe -U '{}%XXX-REDACTED-XXX' //{} "hostname"r$r)rD�ranger&)	r�r�r��retries�retry_delayrr'�ir.r+r+r,�validate_windows_cred_winexeKs�rMc
Cs�t|�D]9}d}ztdd|||dd�\}}}Wnty.}	zt�d�WYd}	~	nd}	~	ww|dkr8|dkSt�|�q|dkS)	rHrr3r4r�r5z Exception while executing psexecNr)rIr/r�rr6r�r�)
r�r�r�rJrKrLr.r,r-r�r+r+r,�validate_windows_credZs����rNr�r8r�c
Cs>d}||kr�d}
zr|||||||
||d�	}|�t|	��|r6tj�|�s+td�|���||d<t�d|�n|rA||d<t�d�|d	7}t�d
|||�t	dddd�|��}|dkrqd
}
||krht
�|�Wqt�d|�WdS|
durxWd
SWdSt
y��ty�||kr�YdSt
�|�Ynw||ksdSdS)zK
    Wait until ssh connection can be accessed via password or ssh key
    rF)	�hostnamer�r��password_retriesr�r�r��ssh_timeout�hard_timeoutz,The defined key_filename '{}' does not existr��Using %s as the key_filenamer�zUsing password authenticationrz/Attempting to authenticate as %s (try %s of %s)r�)r�r�Tz%Authentication failed: status code %sN)r�)rxr3rMr'rOrrDrrf�root_cmdr�r�r�rr�)r�r�rQr�r�r�r�Ztrysleepr�r2r�rRr�ZconnectfailrHrr+r+r,�wait_for_passwdnsj���
�
��rUcCst|t�r
d�|�S|S)zy
    If the master is a list, we need to convert it to a comma delimited string
    Otherwise, we just return master
    �,)r�r�rE)rkr+r+r,�_format_master_param�s

rW�
C:\salttmpr�c-Kspt|t�si}|rtst�dt�dSt�t���}t�	d||�t�
dt|�t|||dd�}|s5dSd}d}trQ|rQt|||||d||d�}|durPd	}nt
|||||dd
�}|�r6|�r6t�	d||�t�	d|||�tjj�||||�} | dur�t�d
�dStjjjd| d�d}!tjjj|!�d�| d�d}!|
r�tjjj|
|!�d�| d�|r�tjjj||!�d�| d�|r�t�	d|�ztjjj||!�d�| d�Wnty�}"zt�	d|�WYd}"~"nd}"~"ww|�d�}#d�|#dd��}$|#d}%tjjj|d|%��d| d�d|%��}&ddt|���d|��g}'|�r)t||&|'�nt|&d �|'�|||�\}(})}*|*d!k�rCtd"|*����|�r�t|t��sPtd#��|�d$i�}+|+�rjtjjjt|+d%d&�|!�d'�| d�|�d(d)�|�d*d�|�d+d	�d,�},|�r�d-|v�r�||,d-<|�r�d.|v�r�||,d.<t|fi|,��}tjjjt|d%d&�|!�d/�| d�|
�s�|�r�t|d0gd1��ntjjjd|%��d| d�tjjjdd| d�|�r�t|d2d3d4g�t|d2d5d4g�n)td6d7|||�\}(})}*|*d!k�r�dSt�	d8�td6d9|||�\}(})}*|*d!k�rdSt d:|�d;|��d<|�d=�d>|i|�!d?t"j#�t$d?d-��|�!d@dA�dB�d	SdS)CzJ
    Copy the install files to a remote Windows box, and execute them
    zbWinRM requested but module winrm could not be imported. Ensure you are using version %s or higher.FzDeploying %s at %s (Windows)zHAS_WINRM: %s, use_winrm: %srr8N)r�r�r�r�r�rDrET)r�r�r�r�r�zSMB port %s on %s is available�Logging into %s:%s as %sz6Please install smbprotocol to enable SMB functionalityZsalttemp)�connzProgramData/Salt Project/Saltz/conf/pki/minionzProgramData\Salt Project\Saltz\conf\pki\minion\minion.pubz\conf\pki\minion\minion.pemz.Copying master_sign.pub file from %s to minionz \conf\pki\minion\master_sign.pubz3Exception copying master_sign.pub file %s to minion�/���z	salttemp\zC$zc:\salttemp\�/Sz/master=z
/minion-name=r9rzFail installer zp`salt.utils.cloud.deploy_windows` now only accepts dictionaries for its `minion_conf` parameter. Loading YAML...ruz
)rz\conf\grains�ipc_modeZtcpr`�multiprocessing)r^r`r_rkroz\conf\minion�rmdir)z/Qr]zC:\salttemp\�net�stopzsalt-minionr�r3z/c net stop salt-minionz Run psexec: sc start salt-minionz/c net start salt-minionr�� has been deployed at �salt/cloud/z/deploy_windowsrnr�r�r�r�)%r��dict�	HAS_WINRMrr��
WINRM_MIN_VERr��mktime�	localtimerfr@rrGr7rr�smbZget_connZmkdirsZput_strZput_filer�rCrErW�	winrm_cmdr/�DeprecationWarning�poprLZdelete_fileZdelete_directoryr�rBrMr'r�)-r�r�r�r�r�rnr�r�r�r�r�r�r�r�r�r�r�r�r�rkr�rr�r�r�r�r�rH�	starttimeZport_availableZservice_availableZ
winrm_sessionZsmb_conn�root_dir�e�compsZ
local_pathZ	installerrr�r,r-r.�
minion_grainsZwindows_minion_confr+r+r,r��s4
!��	��
���
����

�
�
�
�
�


�
��

�



�


�	r�r�c'H
Ks<t|!t�si}!| p
i} |%pi}%d�|"�d�t���}"tjjd| |!t	j
�|"d�d�}(|dur;t	j
�|�s;t
d|�d���d})d	|'vrE|'d	})t��}*t�d
|t�d|*��|'�dd
�}+|!�dd�},t|||)d��r�t�d||�t||||||||)|+||,d��r�t�d|||�||||||||!�dd�d�}-|-�t|)��|r�t�d|�||-d<n|r�|'�dd�dur�||-d<td|"�d�||fddi|-��r�td|"�d�||fi|-��}.|.r�td |"�d!���|�r|"�d��d��d�}/|/�rt|/�d"ks�|/d#d$k�rtd%|�d&|"�d'�||fi|-��}.|.�rtd(|�d)|"����t|#t��s$i}#g}0g}1g}2|#D]}}3|3}4|#|3}5t	j
�|3��sKt�d*|4|5�|2�|4|5i��q,t	j
� |4��rdt	j
�!|4�}6t	j
�t	j
�"|5�|6�}7nt	j
�"|5�}7|7|0v�r�td+|7�d�||fi|-��|-d,d-k�r�td.�|-d,|7�||fi|-��|0�|7�t#|!|5|-|4d/�|1�|4|5i��q,|�r�t#|!|"�d0�||-�td1|"�d2�||fi|-��}.|.�r�td3|"�d0���|�r�t#|!|"�d4�||-�|$�r�t#|!|"�d5�|-|$d/�|�r)t|t��s�t$d6��|�%d7i�}8|8�r
t#|!|"�d8�t&|8�|-�|%�r|!�d9d��rd:|%i|d7<t#|!|"�d;�t&|�|-�|�rOt#|!|"�d<�||-�td1|"�d=�||fi|-��}.|.�rOtd>|"�d<���|
�r\t#|!|"�d?�|
|-�|�rut|t��sit$d@��t#|!|"�dA�t&|�|-�|"�dB�}9|du�r�tdC|9�d�||fi|-��}.|.�r�tdD|9����tdE|9�d�||fi|-��}.|.�r�td3|9����|-d,d-k�r�td.�|-d,|9�||fi|-��|�'�D]\}:};t	j
�|9|:�}<t#|!|<|;|-��q�|-d,d-k�r�tdF|9�d�||fi|-��|.�r�tdG�|9���|'�dHg�}=|=D]}>t|>||fi|-��}?|?�rtdI|>�d����q|�rDt#|!|"�dJ�||-�tdK|"�dL�||fi|-��}.|.�rDtd3|"�dJ���t�(t���t�(|*�}@||@}Ad}Bd}C|�r}|�s}t)�*�}Bt)j+t,t|||A|BdM�dN|�dO�dP�}Ct�dQ�|C�-�|�redR|v�r�|(dS|"�d�7}(|&�r�|(dT7}(|du�r�|(dU7}(|du�r�|(dV7}(|du�r�|(dW7}(|du�r�|(dX7}(|du�r�|(dY|9�d�7}(|�r�|(dZ|��7}(|�rt|t��s�td[�t.|����d\g}D|�'�D]\}E}F|D�d]�|E|F���q�|D�|(�t#|!|"�d^�d_�|D�|-�td`|"�da�||fi|-��db�|"�}(t|(||fi|-��d#k�r1tdc|(�dd���t�de|(�|�setdf|"�dg�||fi|-��t�dh|"�|�retdf|"�da�||fi|-��t�di|"�|�rot�dj|"�n�|�r�tdf|"�dk�||fi|-��t�dl|"�|�r�tdf|"�d2�||fi|-��t�dm|"�|�r�tdf|"�dn�||fi|-��t�do|"�tdf|"�dp�||fi|-��t�dq|"�|$�r�tdr|"�d5�||fi|-��t�ds|"�|
�r�tdf|"�dt�||fi|-��t�du|"�|�r
tdf|"�d=�||fi|-��t�dv|"�|�r$tdf|"�dw�||fi|-��t�dx|"�|du�r=tdy|9�d�||fi|-��t�dz|9�|�rj|�sj|B��}G|C��|G�rj|�rjt�/d{|�td||��||fi|-��t�/d}|�t0d~|�d|��d�|�d��||d��|!�d�t	j
�t1d�d���|!�d�d��d��|2�s�|1�r�|1|2d��SdSdS)�zL
    Copy a deploy script to a remote server, execute it, and remove it
    z{}-{}r[�deploy_commandz	deploy.shr�NzThe defined key_filename 'r�r2�Deploying %s at %sz%Y-%m-%d %H:%M:%Sr�r�rR�r�r�r2�SSH port %s on %s is available)
r�r�r�r�rQr�r2r�r�rRrY�use_sftpF)rOr�r�r�rQr�r�r�rSr�r�r�z	test -e '�'r�Tzsh -c "( mkdir -p -m 700 'z' )"z$Can't create temporary directory in z !rr�tmpzchown z "�"z	Cant set z ownership on zWThe local file "%s" does not exist, and will not be copied to "%s" on the target systemz
mkdir -p 'r�r8z
chown {} '{}')rH�
local_filez/minion.pemzchmod 600 'z/minion.pem'zCan't set perms on z/minion.pubz/master_sign.pubzo`salt.utils.cloud.deploy_script now only accepts dictionaries for it's `minion_conf` parameter. Loading YAML...ruz/grainsZenable_cloud_grainsz
salt-cloudz/minionz/master.pemz/master.pem'zCant set perms on z/master.pubzu`salt.utils.cloud.deploy_script now only accepts dictionaries for it's `master_conf` parameter. Loading from YAML ...z/masterz/preseed-minion-keyszmkdir 'zCant create zchmod 700 'zchown -R root 'zCan't set ownership for {}r�zPre-flight command failed: 'z
/deploy.shzsh -c "( chmod +x 'z/deploy.sh' )";exit $?)rnr�r��queuezDeployScriptCheckAuth(�))r:rHrnz,Starting new process to wait for salt-minionr�z -c 'z -Fz -Sz -Mz -Nz -Kz -k 'r9zHThe 'script_env' configuration setting NEEDS to be a dictionary not a {}z	#!/bin/shz4setenv {0} '{1}' >/dev/null 2>&1 || export {0}='{1}'z/environ-deploy-wrapper.shr~z
chmod +x 'z/environ-deploy-wrapper.sh'z'{}/environ-deploy-wrapper.sh'zExecuting the command 'z' failedzExecuted command '%s'zrm -f 'z/deploy.sh'zRemoved %s/deploy.shz$Removed %s/environ-deploy-wrapper.shz&Not removing deployment files from %s/z/minion.pub'zRemoved %s/minion.pubzRemoved %s/minion.pemz/grains'zRemoved %s/grainsz/minion'zRemoved %s/minionzrm -f zRemoved %s/master_sign.pubz/master.pub'zRemoved %s/master.pubzRemoved %s/master.pemz/master'zRemoved %s/masterzrm -rf 'z
Removed %szExecuting %s on the salt-minionz
salt-call z(Finished executing %s on the salt-minionr�rcrdz/deploy_script)rnr�r�rkr�r�r�)zFile Upload SuccesszFile Upload Failure)2r�rerD�rstripr)r*rrvrwrMr'rErOrr�rirrf�strftimerBrrUrxr3rTr�lstriprC�lenr[r�r��isdir�basename�dirname�ssh_filerlrmrL�itemsrhr_�QueueZProcess�
check_authr��typerr�r�)Hr�r�r�r�r�r�r�rnr�r�r�r�rtr�r�r�r�r�r�r�r�r�rQr�r�r�r�r�r�r�r�r�r(rr�r�r�r�r�rHrsr2rnr�rR�
ssh_kwargsr�rqZremote_dirsZfile_map_successZ
file_map_failZmap_itemr{Zremote_fileZdir_nameZ
remote_dirrrZpreseed_minion_keys_tempdir�	minion_idZ
minion_keyZrpathr�rZcmd_retZ	time_used�
newtimeoutr|�processZenviron_script_contentsrc�valueZqueuereturnr+r+r,r��s�
-�
��
�

���
��
�����
��
��
���������

���
������

�����
���
�







��
�
���
�
����

��
�
�
�r��/tmp/.saltcloud-inline_scriptcKs�d}d|vr
|d}t�t���}t�d||�|�dd�}t|||d�r�t�d||�|t�t���|}t|||||||||d�	r�t�d	|||�|t�t���|}||||||
|�d
d�d�}|�t	|��|ryt�d
|�||d<n|r�d|vr�|ddur�||d<t
d|�d�|
|fddi|��r�|r�t�d�|D]!}t�d|�t
d|�d�|
|fddi|��}|r�t�d||�q�dS)z�
    Run the inline script commands, one by one
    :**kwargs: catch all other things we may get but don't actually need/use
    Nr2rtr�r�rurv)r�r�r�r�rQr�r2r�rYrwF)rOr�r�r�r�r�r�rSr�r�r�z
test -e \"z\"r�TzFound inline script to execute.zExecuting inline command: %sz	sh -c "( z )"z[%s] Output: %s)r�rhrirrfrBrrUrxr3rTr)r�rnr�r�r�r�r�rQr�r�r�r�r�r�rr�rHr2rnr�r�r�Zcmd_liner�r+r+r,r��s��
�	
�
�����


����r�cCs�i}g}d}t�di�D]}||krqtd|d}td|�dd�}q|dur,g}t|t�s5t|�}tt||��}|D]}||vrK||||<q?|S)z�
    Accept a tag, a dict and a list of default keys to return from the dict, and
    check them against the cloud configuration for that tag
    TZ
filter_events�keys�use_defaultsF)r�rBr�r��set)�tagr��defaultsr�r�r�Zktagrcr+r+r,�filter_event�s$
�r�r�c	Cs�tjjjd|dd��4}z|�||�Wnty0t|t�r$|||<n||i}|�||�Ynwt�	d�Wd�dS1sAwYdS)z
    Fire deploy action
    rkF��listeng�������?N)
rrr��	get_eventr��
ValueErrorr�rer�r�)rc�msgr�r�r�r�r�r+r+r,r�s

�
"�r�c
Ks�|durd}|�dd�}z�z�d\}}tjjj|ddd|�dd�|�dd�d�}d}|jrp|��\}}|rht�|�rhd	|vrN|d	rNt	�|�rN|�
|d
�n|�dd�rd||krd|d7}|�
|d�nt|��t�
d
�|js,|jdkr�|dur�td|�d|j����|jWW|jddd�Stjjjy�}	zt��}
t�|�||	|
��WYd}	~	nd}	~	wwW|jddd�dS|jddd�w)Nz@A wrong password has been issued while establishing ssh session.rPr�NNTr�)�shellZ
log_stdoutZ
log_stderrZ
stream_stdoutZ
stream_stderrrr�r�r�r��?Fz	Command 'z' failed. Exit code: )�	terminate�kill)rBrrZvtZTerminalZhas_unread_data�recv�SSH_PASSWORD_PROMP_RE�search�SSH_PASSWORD_PROMP_SUDO_REZsendlinerr�r�Z
exitstatusrr�ZTerminalException�	traceback�
format_excrr�rD)r�	error_msgr�rHrPr,r-�procZ
sent_password�errr@r+r+r,r�sZ

���
��� ���r�cCs�d}�z$|durXz.t��\}}t�||�Wzt�|�Wn:ty6}z
|jtjkr,�WYd}~n&d}~wwzt�|�WwtyW}z
|jtjkrM�WYd}~wd}~wwt�	d||d�dd�
|�dt��d�
|�dt
��d	d
g}|dur�|}tj�|�r�|�d�d|vr�|�d
ddddd�
|d�g�d|vr�|�d�
|d��|�t|��zt�tj|d�r�d�
|d�}n|d}Wn
ty�|d}Ynw|dur�t�d�d�
d�|�||||�}	t�	d|	�t|	fddd�|��}
W|du�r&zt�|�W|
St�y%}z|jtjk�r�WYd}~|
Sd}~ww|
S|du�rPzt�|�Wwt�yO}z|jtjk�rE�WYd}~wd}~www)z4
    Use scp or sftp to copy a file to a server
    NzUploading %s to %srOr:r;r<r=r>r?r@�-rr�r�r�r�r�r�r7r��	-oPort={}�[{}]�nNo source file to upload. Please make sure that either file contents or the path to a local file are provided.z�scp {0} {1} {2[username]}@{4}:{3} || echo "put {1} {3}" | sftp {0} {2[username]}@{4} || rsync -avz -e "ssh {0}" {1} {2[username]}@{2[hostname]}:{3}r9zSCP command: '%s'�$Failed to upload file '{0}': {1}
{2}r�r�rP)rR�mkstemprMr]r�r��errno�EBADFrrfrDrBrFrGr'r�r�r�rIr�r�r��warningrEr�r_�ENOENT)�	dest_path�contentsrHr{�file_to_upload�tmpfdr�r�ipaddrr�retcoder+r+r,�scp_fileQs��������
�
��
����������
�
���
�����r�cCs,|�dd�dkrt||||�St||||�S)z]
    Copies a file to the remote SSH target using either sftp or scp, as
    configured.
    r�r�)rB�	sftp_filer�)rr�r�rHr{r+r+r,r��sr�cCs�g}|duri}d}�z6|duroz=t��\}}t|t�r&t�||�t��nt�||�Wzt�|�Wn:t	yM}z
|j
t
jkrC�WYd}~n&d}~wwzt�|�Wwt	yn}z
|j
t
jkrd�WYd}~wd}~ww|dur~|}tj�
|�r~dg}t�d||�d��dd�|�dt��d�|�d	t��d
dg}d|vr�|�d
ddddd�|d�g�d|vr�|�d�|d��|�t|��zt�tj|d�r�d�|d�}	n|d}	Wn
t	y�|d}	Ynw|dur�t�d�d�d�|�||d�|�||	�}
t�d|
�t|
fddd�|��}W|du�r@zt�|�W|St	�y?}z|j
t
jk�r4�WYd}~|Sd}~ww|S|du�rjzt�|�Wwt	�yi}z|j
t
jk�r_�WYd}~wd}~www)z/
    Use sftp to upload a file to a server
    Nr�zUploading %s to %s (sftp)rOr:r;r<r=r>r?r@r�r�r�r�r�r�z-oIdentityFile={}r�r�r�r�z3echo "put {0} {1} {2}" | sftp {3} {4[username]}@{5}r9zSFTP command: '%s'r�rr�)rRr�r�r$rMr]�encodeZ__salt_system_encoding__r�r�r�r�r'r�rrfrBrDrFrGr�r�rIr�r�r�r�rEr�r_r�)r�r�rHr{Zput_argsr�r�r�rr�rr�r+r+r,r��s�
��������
�
�����������
�
���
�����r�c
Ks�|�dd�}z1t|dtjtj|�dd�|d�}|dur$t�d|j|�nt�d|j|�|��|��|j	WSt
yP}z
t�d|�WYd}~dSd}~ww)	z>
    Wrapper for commands to be run against Windows boxes
    r%NTr�)r�r-r,Zstream_stdsr%zExecuting command(PID %s): '%s'zFailed to execute command '%s'r)rBr	�
subprocess�PIPErrf�pidZpoll_and_read_until_finish�communicate�
returncoder�r6)rrHr%r�r�r+r+r,r&,	s*
�	��r&cKs t�d||�|�||�}|jS)zK
    Wrapper for commands to be run against Windows boxes using WinRM.
    zExecuting WinRM command: %s %s)rrfrBrC)r
r�flagsrHrr+r+r,rkJ	srkc
Ks�|}|�dd�}|r&|durd|��}|}n
d|��}d|��}t�d|�g}|r1|�ddg�|�dd	�}d
}	|d	kr?d}	|�d|	��d
|��dg�d|vra|�dddddd�|d�g�d|vrp|�d�|d�g�|�t|�g�d|vr�|�d�|d�g�d�d�|�|�}
|
|}|
t�|�}
|�d�}|dur�d|�d|��}d|�d|
��}
t�d|�t	|
fd|i|��}|S) z0
    Wrapper for commands to be run as root
    r�Nzsudo zsudo -S "XXX-REDACTED-XXX" zsudo -S zUsing sudo to run command %sz-tr�r��noZyesz-oStrictHostKeyChecking=z-oUserKnownHostsFile=r@r�r�r�r�r�r�r7rQz-oConnectTimeout={}r�z-p {}z$ssh {0} {1[username]}@{1[hostname]} r9rRztimeout r�r�)
rBrrfr�rDrIrEr�r�r�)
rr�r�r�rHr%r�rr�Zhost_key_checkingrrRr�r+r+r,rTS	s^


����
rT�,cCs�tjjjd|dd��U}t�t���}|}t�d|�|dkrW|t�t���|}|j	dd�}|dur4q|dd	|�d
�krK|�
|�d}t�d|�|dksWd�dSWd�dS1sbwYdS)z�
    This function is called from a multiprocess instance, to wait for a minion
    to become available to receive salt commands
    rkTr�z1In check_auth, waiting for %s to become availabler)�fullNr�zsalt/minion/z/startz&Minion %s is ready to receive commands)rrr�Z	SaltEventr�rhrirrfr��put)rnr�r|r�r�rnr�r�r+r+r,r��	s"

��"�r�cCs(d}|�d�D]
}|dt|�}q|S)z.
    Converts an IP address to an integer
    rr��)rCr�)�ipr��octetr+r+r,�	ip_to_int�	sr�cCs�d|vr
|�d�rdSdSt|�}d|krdkrdSd|kr(dkr)dSd	|kr4d
kr5dSd|kr@dkrCdSdSdS)
zT
    Determines whether an IP address falls within one of the private IP ranges
    r5zfe80:FTi
i���
lPl�Ql Xl�?Xii���)�
startswithr�)r��addrr+r+r,�is_public_ip�	s$
����r�cCs0t�d|�d��}|�|�rtd�||���dS)zF
    Check whether the specified name contains invalid characters
    z[^�]zU{} contains characters not supported by this cloud provider. Valid characters are: {}N)�re�compiler�rrD)rnZ
safe_charsZregexpr+r+r,�
check_name�	s
��r�cCs�|dur)dtjvrd�tjd�}nz
d�t�t���j�}Wn	ty(Ynw|dur5t�	d||�nt�	d|�t
�dd|g�dS)z1
    Remove a host from the known_hosts file
    N�HOMEz{}/.ssh/known_hostsz0Removing ssh key for %s from known hosts file %sz-Removing ssh key for %s from known hosts filez
ssh-keygenz-R)rMr�rD�pwd�getpwuid�getuidZpwd_dirr�rrfr��call)r�Zknown_hostsr+r+r,�
remove_sshkey�	s
��r�r�c	Cs�|durd}|duri}|}	t�dt|d�t|d��||i|��}|dur<t�d|�|d8}|d	kr;td
��n|durB|S|d	krVtd�t|d�t|d����t�|�||8}|dkru||9}||kro|d}t�d|�q)
as
    Helper function that waits for an IP address for a specific maximum amount
    of time.

    :param update_callback: callback function which queries the cloud provider
                            for the VM ip address. It must return None if the
                            required data, IP included, is not available yet.
    :param update_args: Arguments to pass to update_callback
    :param update_kwargs: Keyword arguments to pass to update_callback
    :param timeout: The maximum amount of time(in seconds) to wait for the IP
                    address.
    :param interval: The looping interval, i.e., the amount of time to sleep
                     before the next iteration.
    :param interval_multiplier: Increase the interval by this multiplier after
                                each request; helps with throttling
    :param max_failures: If update_callback returns ``False`` it's considered
                         query failure. This value is the amount of failures
                         accepted before giving up.
    :returns: The update_callback returned data
    :raises: SaltCloudExecutionTimeout

    Nr+Tz-Waiting for VM IP. Giving up in 00:%02d:%02d.rFz^'update_callback' has returned 'False', which is considered a failure. Remaining Failures: %s.rrz<Too many failures occurred while waiting for the IP address.z&Unable to get IP for 00:{:02d}:{:02d}.z3Interval multiplier in effect; interval is now %ss.)	rrfr�rrrDr�r�r)	Zupdate_callbackZupdate_argsZ
update_kwargsr��intervalZinterval_multiplierZmax_failuresZdurationr�r+r+r,�wait_for_ip�	sN

������
�r�c	Cs�|dkrtd��d|vrtd�|dddd���i}|D]}i}||}|D]}t|�|vr9||}|||<q)|||<q|S)zO
    Return a list of the VMs that are on the provider, with select fields
    �actionzDThe list_nodes_select function must be called with -f or --function.r�z)An error occurred while listing nodes: {}ZErrorsr��Message)rrDr$)	�nodesZ	selectionr�r��node�pairsr�rcr�r+r+r,�list_nodes_selectH
s*����
r�r�cCs�t�d|�|d}t��}	tj�|�r+t��||kr%t�d|�dSt�|�nnqtj	j
�|d��	Wd�dS1sAwYdS)z�
    Lock a file; if it is already locked, then wait for it to become available
    before locking it.

    Note that these locks are only recognized by Salt Cloud, and not other
    programs or platforms.
    z Attempting to obtain lock for %s�.lockTzUnable to obtain lock for %sF�aN)rr@r�rMr'r[r�r�rrrr )�filenamer�r��lockr�r+r+r,�	lock_filee
s�	"�r�c
CsZt�d|�|d}zt�|�WdSty,}zt�d||�WYd}~dSd}~ww)z�
    Unlock a locked file

    Note that these locks are only recognized by Salt Cloud, and not other
    programs or platforms.
    zRemoving lock for %sr�z Unable to remove lock for %s: %sN)rr@rMr_r�)r�r�r�r+r+r,�unlock_file}
s��r�c	Cs�t|�}tj�|d�}t|�tj�|�r<tjj�	|d��}tjj
�tjjj
|td��}Wd�n1s6wYni}|�d�}|�|||||dd�i�tjj�	|d��}tjjj||td�Wd�n1snwYt|�dS)	a�
    Add an entry to the cachedir index. This generally only needs to happen when
    a new instance is created. This entry should contain:

    .. code-block:: yaml

        - minion_id
        - profile used to create the instance
        - provider and driver name

    The intent of this function is to speed up lookups for the cloud roster for
    salt-ssh. However, other code that makes use of profile information can also
    make use of this function.
    �index.p�rb��encodingNr5r)ror�r�r��wb)�
init_cachedirrMr'rEr�r[rrrr r��decode�msgpack�load�MSGPACK_ENCODINGrCrx�dumpr�)	r�r�r�r��base�
index_file�fh_�indexZ
prov_compsr+r+r,�cachedir_index_add�
s2���
����r�cCs�t|�}tj�|d�}t|�tj�|�r<tjj�	|d��}tjj
�tjjj
|td��}Wd�n1s6wYndS||vrE||=tjj�	|d��}tjjj||td�Wd�n1sbwYt|�dS)zw
    Delete an entry from the cachedir index. This generally only needs to happen
    when an instance is deleted.
    r�r�r�Nr�)r�rMr'rEr�r[rrrr r�r�r�r�r�r�r�)r�r�r�r�r�r+r+r,�cachedir_index_del�
s"����r�cCs^|durtd}|tj�|d�tj�|d�f}|D]}tj�|�s&t�|�t�|d�q|S)zP
    Initialize the cachedir needed for Salt Cloud to keep track of minions
    N�cachedir�	requested�activei�)r�rMr'rEr[r\�chmod)r�Zneeded_dirsZdir_r+r+r,r��
s
r�c
Cs�|durtd}|s|durtjjj||r|�d�pdd�}t|�|||d�}|�d�}tj�	|d|�}tjj
�|d	��}	tjjj
||	td
�Wd�dS1sSwYdS)a�
    Creates an entry in the requested/ cachedir. This means that Salt Cloud has
    made a request to a cloud provider to create an instance, but it has not
    yet verified that the instance properly exists.

    If the fingerprint is unknown, a raw pubkey can be passed in, and a
    fingerprint will be calculated. If both are empty, then the fingerprint
    will be set to None.
    Nr�rmrj)rcZsum_type)r��fingerprintr��.pr�r�r�)r�rrrSZ
pem_fingerrBr�rMr'rErr r�r�r�)
r�rr�Zpubkeyr�r�r��fnamer'r�r+r+r,�request_minion_cachedir�
s ��
"�r�cCs�t|t�sdS|durtd}|�d�}tj�|||�}tjj�	|d��}tjj
�tjjj
|td��}Wd�n1s=wY|�|�tjj�	|d��}tjjj||td�Wd�dS1sewYdS)a�
    Changes the info inside a minion's cachedir entry. The type of cachedir
    must be specified (i.e., 'requested' or 'active'). A dict is also passed in
    which contains the data to be changed.

    Example:

        change_minion_cachedir(
            'myminion',
            'requested',
            {'fingerprint': '26:5c:8c:de:be:fe:89:c0:02:ed:27:65:0e:bb:be:60'},
        )
    FNr�r�rr��w)r�rer�rMr'rErrrr r�r�r�r�r�rxr�)r�r�r�r�r�r'r��
cache_datar+r+r,�change_minion_cachedirs

��
"�rcCsH|durtd}|�d�}tj�|d|�}tj�|d�}t�||�dS)z�
    Moves a minion from the requested/ cachedir into the active/ cachedir. This
    means that Salt Cloud has verified that a requested instance properly
    exists, and should be expected to exist from here on out.
    Nr�r�r�r�)r�rMr'rErU�move)r�r�r��src�dstr+r+r,�activate_minion_cachedir2s
rcCs�t|t�r
t�|�t�dd�durdS|durtd}tttd|����}|�d�}dD]}tj	�
|||||�}t�d|�tj	�
|�rLt�|�q/dS)	z�
    Deletes a minion's entry from the cloud cachedir. It will search through
    all cachedirs to find the minion's cache file.
    Needs `update_cachedir` set to True.
    �update_cachedirFNr��	providersr�)r�r�zpath: %s)r�rer�rxrB�next�iterr�rMr'rErrfr[r_)r�r�rr�r�r�r�r'r+r+r,�delete_minion_cachedirAs



��r
cCs"|durt}|�dd�durdS|durtj�|dd�}i}t�|�D]j}i||<tj�||�}t�|�D]W}|r?||kr?q6i|||<tj�||�}t�|�D];}tj�||�}	|dd�}
tjj�	|	d��}tjj
�tjjj
|td��||||
<Wd�n1s�wYqQq6q$|S)	z�
    Return a list of minion data from the cloud cache, rather from the cloud
    providers themselves. This is the cloud cache version of list_nodes_full().
    NrFr�r����r�r�)r�rBrMr'rE�listdirrrrr r�r�r�r�r�)rr�r�rYr��prov_dirZprovZmin_dirr�Zfpathr�r�r+r+r,�list_cache_nodes_fullYs6�����rcCs"|�dd�}|s
|}|std��|�d�sd|vrXt�d�zddl}Wn
ty1d	d
iYSw|j|dd�}|jd
krGd	d�||j�iS|j	}||krQd}n@t
j�|�}n9t
j�
|�r�tjj�|��}tjj�|���}Wd�n1sywYt
j�|�}n|}t�|����d�}|s�td��t
j�t
j�t�d�}t
j�t
j�|d�d�}	t
j�|dd�}
g}|�dg�D]}|�|�r�q�||	|
fvr�|�|df�q�|�|df�q�|	|vr�|�|	df�|
|vr�|�|
df�g}
g}|D]�\}}||
v�rq�|
�|�|�r4t
j�|��s4zt
�|�Wnt�y3}zt�d|�WYd}~q�d}~wwt |��s@t�d|�q�t
j�||�}z*|�|�tjj�|d��}|�!tjj�"|��Wd�n	1�skwYWq�t�y�}zt�d|�WYd}~q�d}~wwdd|iiS)z�
    Update the salt-bootstrap script

    url can be one of:

        - The URL to fetch the bootstrap script from
        - The absolute path to the bootstrap
        - The content of the bootstrap script
    Zbootstrap_script_urlzVhttps://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.shzCant get any source to update�httpz://z6Updating the bootstrap-salt.sh script to latest stablerNr�zZUpdating the bootstrap-salt.sh script requires the Python requests library to be installed�x)r���zdFailed to download the latest stable version of the bootstrap-salt.sh script from {}. HTTP error: {}zbootstrap-salt.shrJz No content in bootstrap script !r�r�zcloud.deploy.dZ
config_dirrKTFzFailed to create directory '%s'z(The '%s' is not writeable. Continuing...r�z&Failed to write the updated script: %sZSuccessz
Files updated)#rBr�r�rrf�requests�ImportErrorrCrD�textrMr'r�r[rrrr r!r"r#�hashlib�sha1�	hexdigestrEr��__file__r�r�r\r�rr
r]r^)rvrAZdefault_urlrZreqZscript_content�script_nameZficZbuiltin_deploy_dirZdeploy_d_from_conf_fileZdeploy_d_from_syspathsZdeploy_scripts_search_paths�entry�finishedZ
finished_fullr\r�Zdeploy_pathr)r+r+r,�update_bootstraps�
�
��

���


��

����rc		Cs�d|vs|ds
dStj�t�d�}tt|d|����}tj�|||�}tj�|�s1t�|�t	||||�|D]9}t
|||||�tj�||�d��}tjj
�|d��}tjjj|||td�Wd�n1snwYq:dS)z�
    If configured to do so, update the cloud cachedir with the current list of
    nodes. Also fires configured events pertaining to the node list.

    .. versionadded:: 2014.7.0
    rNr�rr�r�r�)rMr'rEr�rr	r�r[r\�missing_node_cache�diff_node_cacherrrr r�r�r�)	r�r�rr�r�r
r�r'r�r+r+r,�cache_node_list�s 
���rcCs�t|t�r
t�|�dtvstdsdStj�tj�tdd��s$t�tj�tdd�}|�	d�\}}tj�|||�}tj�|�sGt�
|�tj�|d�|d��}tj
j�|d��}tj
jj||td	�Wd�dS1sqwYdS)
zA
    Cache node individually

    .. versionadded:: 2014.7.0
    rNr�r�r5z{}.prnr�r�)r�rer�rxrMr'r[rEr�rCr\rDrrrr r�r�r�)r�r�rr�r�r
r'r�r+r+r,�
cache_nodes


"�r c
Cs�g}t�|�D]
}|�tj�|�d�q|D]3}||vrJt|||�d|vrJ|drJtddd|�d�d|i|�dtj�t	dd	��|�d
d�d�qd
S)ag
    Check list of nodes to see if any nodes which were previously known about
    in the cache have been removed from the node list.

    This function will only run if configured to do so in the main Salt Cloud
    configuration file (normally /etc/salt/cloud).

    .. code-block:: yaml

        diff_cache_events: True

    .. versionadded:: 2014.7.0
    r�diff_cache_eventsr�z!cached node missing from providerrdz/cache_node_missingzmissing noder�rkr�r�r�N)
rMrr�r'�splitextr
r�rBrEr�)r
Z	node_listr�rZcached_nodesr�r+r+r,r-s&
�
���rc	Csld|vs|ds
dS|durdStj�||��d�}tj�|�sFt||�}tddd|�d�d|i|�d	tj�td	d
��|�dd�d
�dStj	j
�|d��*}ztj	j�
tj	jj|td��}Wntypt�d|�i}YnwWd�n1s{wYtj	j�||�}|dkr�tddd|�d�t||�t||�d�|�d	tj�td	d
��|�dd�d
�dSdS)aX
    Check new node data against current cache. If data differ, fire an event
    which consists of the new node data.

    This function will only run if configured to do so in the main Salt Cloud
    configuration file (normally /etc/salt/cloud).

    .. code-block:: yaml

        diff_cache_events: True

    .. versionadded:: 2014.7.0
    r!Nr�r�znew node foundrdz/cache_node_new�new_datar�rkr�r�r�rr�z"Cache for %s was corrupt: Deletingrznode data differsz/cache_node_diff)r#r)rMr'rEr[�_strip_cache_eventsr�rBr�rrrr r�r�r�r�r�r�rr��compat�cmp)	r
r�r#rr'�
event_datar�r�diffr+r+r,rOsP


�����
�

��rcCs2t�|�}|�dg�}|D]	}||vr||=q
|S)a9
    Strip out user-configured sensitive event data. The fields to be stripped
    are configured in the main Salt Cloud configuration file, usually
    ``/etc/salt/cloud``.

    .. code-block:: yaml

        cache_event_strip_fields:
          - password
          - priv_key

    .. versionadded:: 2014.7.0
    Zcache_event_strip_fields)r{r|rB)r�rr'Zstrip_fields�fieldr+r+r,r$�s
�r$cCs\t|ttf�std|����ddd�}|j|j|j�|vr,||j|j|j�|jfS|�)a~
    Helper method to try its best to convert any Unicode text into ASCII
    without stack tracing since salt internally does not handle Unicode strings

    This method is not supposed to be used directly. Once
    `py:module: salt.utils.cloud` is imported this method register's with
    python's codecs module for proper automatic conversion in case of encoding
    errors.
    z
Can't handle r9�-)� u–)r��UnicodeEncodeError�UnicodeTranslateError�	TypeError�objectr��end)r�Z
unicode_transr+r+r,�_salt_cloud_force_ascii�s
�r1zsalt-cloud-force-asciicCs6zddl}|�||�WStyt�d�YdSw)za
    Retrieve particular user's password for a specified credential set from system keyring.
    rNzHUSE_KEYRING configured as a password, but no keyring module is installedF)�keyringZget_passwordrrr�)�
credential_idr�r2r+r+r,�retrieve_password_from_keyring�s��r4cCs8zddl}|�|||�WStyt�d�YdSw)z3
    Saves provider password in system keyring
    rN�FTried to store password in keyring, but no keyring module is installedF)r2Zset_passwordrrr�)r3r�r�r2r+r+r,�_save_password_in_keyring�s��r6c
Cs�zRddl}ddl}|dur,d|�d�}zt�|�}Wnty%d}Ynw|s,td��z
t|||�WWdS|jjyR}zt�	d|�WYd}~WdSd}~wwt
yat�d�YdSw)	zS
    Interactively prompts user for a password and stores it in system keyring
    rNzPlease enter password for z: zInvalid password provided.z*Problem saving password in the keyring: %sr5F)r2Zkeyring.errors�getpass�EOFError�RuntimeErrorr6�errorsZPasswordSetErrorrrfrr�)r3r�r�r2�promptr�r+r+r,�store_password_in_keyring�s0�����r<cCs |�d�}|D]}||}q|S)z�
    Accepts index in form of a string
    Returns final value
    Example: dictionary = {'a': {'b': {'c': 'foobar'}}}
             index_string = 'a,b,c'
             returns 'foobar'
    rV)rC)Z
dictionaryZindex_stringr��kr+r+r,�_unwrap_dict
s

r>cCs�d}||krK|||d�}i}|D]}t|t�r-|d}	t|	t�r-|	��D]\}
}|||
<q$qt||�}t�dt|��d�d||�t	�
d�||ksdS)	z�
    Waits until the function retrieves some required argument.
    NOTE: Tested with ec2 describe_volumes and describe_snapshots only.
    N)r�rz+Function: %s, Watched arg: %s, Response: %sr9rr�T)r�r�rer�r>rrfr$rCr�r�)r�rHZfun_callZargument_being_watchedZrequired_argument_responserZf_resultZr_set�dZd0r=�vr+r+r,�run_func_until_ret_arg
s*


�
�
�rAcCs8tjjd||ddd�}|durtjjd||ddd�}|S)zk
    Return the salt_interface type to connect to. Either 'public_ips' (default)
    or 'private_ips'.
    Zsalt_interfaceFrqZ
ssh_interfaceZ
public_ips)rrvrw)r(rr�r+r+r,�get_salt_interface/
s
�
�rBcCsNtj�|�st�d||�dSt�t�|�j�}|dvr%t�d||�dSdS)aL
    Checks that the key_path exists and the key_mode is either 0400 or 0600.

    Returns True or False.

    .. versionadded:: 2016.3.0

    provider
        The provider name that the key_path to check belongs to.

    key_path
        The key_path to ensure that it exists and to check adequate permissions
        against.
    zJThe key file '%s' used in the '%s' provider configuration does not exist.
F)r�i�z`The key file '%s' used in the '%s' provider configuration needs to be set to mode 0400 or 0600.
T)rMr'r[rr�r��S_IMODEr�)r�rbZkey_moder+r+r,�check_key_path_and_mode@
s ��rDc
Cs�|dur|Stjjd||ddd�}|dur|S|dur |�d�n|}|dur(|S|��}|�|�tj�|i�}|d}|d}tjj	d|||||d�}	t
|	t�spz
d	�|	�
��}	W|	Styot�d
|	�t|	�}	Y|	Sw|	S)zL
    Use the configured templating engine to template the userdata file
    N�userdata_templateFr�Zrenderer_blacklistZrenderer_whitelistz:string:)Z
input_datarzKTemplated userdata resulted in non-string result (%s), converting to string)rrvrwrBr{rx�loaderr%r*Zcompile_templater�r$rE�	readlinesr&rr�)
rr(ZuserdatarEZrendererZrender_optsZrendZ	blacklistZ	whitelistZ	templatedr+r+r,rEe
sN
�
��
�
	��
�rE)NNr)rQ)r~r)r�)r�)r�TT)r�Nrr)r4r�r8NNr�rTNr�N)r�r�r�NNNNNFNNNFNNr�NNNrXNNFr�TT)&r4r�r8NNNNNNNNFNNNNNNFNNr�r�FTTNFNFNNNr�NNNF)Nr4r�r8NNr�TFNFNNNr�)Nr�)NF)NNN)F)NNr�)NNr�r�rr)r�r�)NrNNNr�)�r!�codecsr{r�r�loggingr_rMr�r�rUr�r�r�rRr�r�r)Zjinja2rZsalt.clientrZ
salt.cloudZsalt.configZ
salt.cryptZsalt.loaderZ
salt.templateZsalt.utils.compatZsalt.utils.cryptZsalt.utils.dataZsalt.utils.eventZsalt.utils.filesZsalt.utils.msgpackZsalt.utils.pathZsalt.utils.platformZsalt.utils.stringutilsZsalt.utils.versionsZ
salt.utils.vtZsalt.utils.yamlZsalt.exceptionsrrrrrrZsalt.utils.nb_popenr	Zsalt.utils.validate.pathr
Zsalt.utils.smbZHAS_SMBrZpypsexec.clientrrZpypsexec.exceptionsrZ
pypsexec.scmrr
r	Zsmbprotocol.exceptionsrrZsmbprotocol.treer�	getLogger�setLevel�WARNINGZ
HAS_PSEXECrgZ
pkg_resourcesr=Zwinrm.exceptionsrZget_distributionZ	winrm_pkgrZversionsZcompare�versionrfr��platformZ
is_windowsr7ZHAS_GETPASSr�ZNSTATESr��Mr�r�rFrGrrr-r3rIrPrTrergrirzr}rLr�r�r�rr(r/r2r7rGrMrNrUrWr�r�r�r�r�r�r�r�r�r&rkrTr�r�r�r�r�r�r�r�r�r�r�r�r�rrr
rrrr rrr$r1�register_errorr4r6r<r>rArBrDrEr+r+r+r,�<module>s@ ��
�������


9


.

	


�-
a



�3
�
�
�K
�g
�a
�c
!

6
e

l
	
P


�
J


.

�*
�
'


&{"=
!
�!%