
    Vh	[                        d dl mZmZmZ eZdZdZd dlZd dl	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlZdZdZ	 d dlZd	Z	 d dlmZ d	Zd dlmZmZmZ d dl m!Z!m"Z" d dl#m$Z$ d dl%m&Z& 	 d dl'm(Z(m)Z) d dl*m+Z+m,Z, d	Z- G d de$      Z.y# e$ r  ej0                         Zd
ZY `w xY w# e$ r 	 d dlZd	Zn# e$ r d
ZY nw xY wY ww xY w# e$ r d
Z- ej0                         ZY dw xY w)    )absolute_importdivisionprint_functionaV  
    author:
    - Deric Crago (@dericcrago) <deric.crago@gmail.com>
    name: vmware_tools
    short_description: Execute tasks inside a VM via VMware Tools
    description:
      - Use VMware tools to run tasks in, or put/fetch files to guest operating systems running in VMware infrastructure.
      - In case of Windows VMs, set C(ansible_shell_type) to C(powershell).
      - Does not work with C(become).
    requirements:
      - requests (Python library)
    options:
      vmware_host:
        description:
          - FQDN or IP Address for the connection (vCenter or ESXi Host).
        env:
          - name: VI_SERVER
          - name: VMWARE_HOST
        vars:
          - name: ansible_host
          - name: ansible_vmware_host
        required: true
      vmware_user:
        description:
          - Username for the connection.
          - "Requires the following permissions on the VM:
               - VirtualMachine.GuestOperations.Execute
               - VirtualMachine.GuestOperations.Modify
               - VirtualMachine.GuestOperations.Query"
        env:
          - name: VI_USERNAME
          - name: VMWARE_USER
        vars:
          - name: ansible_vmware_user
        required: true
      vmware_password:
        description:
          - Password for the connection.
        env:
          - name: VI_PASSWORD
          - name: VMWARE_PASSWORD
        vars:
          - name: ansible_vmware_password
        required: true
      vmware_port:
        description:
          - Port for the connection.
        env:
          - name: VI_PORTNUMBER
          - name: VMWARE_PORT
        vars:
          - name: ansible_port
          - name: ansible_vmware_port
        required: false
        default: 443
      validate_certs:
        description:
          - Verify SSL for the connection.
          - "Note: This will validate certs for both O(vmware_host) and the ESXi host running the VM."
        env:
          - name: VMWARE_VALIDATE_CERTS
        vars:
          - name: ansible_vmware_validate_certs
        default: true
        type: bool
      vm_path:
        description:
          - Mutually exclusive with O(vm_uuid)
          - VM path absolute to the connection.
          - "vCenter Example: V(Datacenter/vm/Discovered virtual machine/testVM)."
          - "ESXi Host Example: V(ha-datacenter/vm/testVM)."
          - Must include VM name, appended to 'folder' as would be passed to M(community.vmware.vmware_guest).
          - Needs to include I(vm) between the Datacenter and the rest of the VM path.
          - Datacenter default value for ESXi server is C(ha-datacenter).
          - Folder I(vm) is not visible in the vSphere Web Client but necessary for VMware API to work.
        vars:
          - name: ansible_vmware_guest_path
        required: false
      vm_uuid:
        description:
          - UUID of the virtual machine
          - Mutually exclusive with O(vm_path)
        vars:
          - name: ansible_vmware_guest_uuid
        required: false
      vm_user:
        description:
          - VM username.
          - C(ansible_vmware_tools_user) is used for connecting to the VM.
          - C(ansible_user) is used by Ansible on the VM.
        vars:
          - name: ansible_user
          - name: ansible_vmware_tools_user
        required: true
      vm_password:
        description:
          - Password for the user in guest operating system.
        vars:
          - name: ansible_password
          - name: ansible_vmware_tools_password
        required: true
      exec_command_sleep_interval:
        description:
          - Time in seconds to sleep between execution of command.
        vars:
          - name: ansible_vmware_tools_exec_command_sleep_interval
        default: 0.5
        type: float
      file_chunk_size:
        description:
          - File chunk size.
          - "(Applicable when writing a file to disk, example: using the M(ansible.builtin.fetch) module.)"
        vars:
          - name: ansible_vmware_tools_file_chunk_size
        default: 128
        type: integer
      executable:
        description:
            - shell to use for execution inside container
        default: /bin/sh
        ini:
          - section: defaults
            key: executable
        env:
          - name: ANSIBLE_EXECUTABLE
        vars:
            - name: ansible_executable
            - name: ansible_vmware_tools_executable
a  
# example vars.yml
---
ansible_connection: vmware_tools
ansible_user: "{{ ansible_vmware_tools_user }}"

ansible_vmware_host: vcenter.example.com
ansible_vmware_user: administrator@vsphere.local
ansible_vmware_password: Secr3tP4ssw0rd!12
ansible_vmware_validate_certs: false  # default is true

# vCenter Connection VM Path Example
ansible_vmware_guest_path: DATACENTER/vm/FOLDER/{{ inventory_hostname }}
# ESXi Connection VM Path Example
ansible_vmware_guest_path: ha-datacenter/vm/{{ inventory_hostname }}

ansible_vmware_tools_user: root
ansible_vmware_tools_password: MyR00tPassw0rD

# if the target VM guest is Windows set the 'ansible_shell_type' to 'powershell'
ansible_shell_type: powershell


# example playbook_linux.yml
---
- name: Test VMware Tools Connection Plugin for Linux
  hosts: linux
  tasks:
    - command: whoami

    - ping:

    - copy:
        src: foo
        dest: /home/user/foo

    - fetch:
        src: /home/user/foo
        dest: linux-foo
        flat: true

    - file:
        path: /home/user/foo
        state: absent


# example playbook_windows.yml
---
- name: Test VMware Tools Connection Plugin for Windows
  hosts: windows
  tasks:
    - win_command: whoami

    - win_ping:

    - win_copy:
        src: foo
        dest: C:\Users\user\foo

    - fetch:
        src: C:\Users\user\foo
        dest: windows-foo
        flat: true

    - win_file:
        path: C:\Users\user\foo
        state: absent
N)existsgetsize)gaierror)SSLError)sleepTF)urllib3)AnsibleErrorAnsibleFileNotFoundAnsibleConnectionFailure)to_bytes	to_native)ConnectionBase)missing_required_lib)
DisconnectSmartConnect)vimvmodlc                        e Zd ZdZdZed        Zed        Zed        Zed        Z	ed        Z
ed        Z fd	Zd
 ZddZd fd	Z fdZd ZddZd Zd Zd Zd Zd Zd Zd fd	Z fdZ fdZ xZS )
ConnectionzVMware Tools Connection.zcommunity.vmware.vmware_toolsc                 $    | j                  d      S )z2Read-only property holding the connection address.vmware_host
get_optionselfs    t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/vmware/plugins/connection/vmware_tools.pyr   zConnection.vmware_host   s     }--    c                 $    | j                  d      S )zHRead-only property holding whether the connection should validate certs.validate_certsr   r   s    r   r"   zConnection.validate_certs  s     /00r    c                 V    | j                   j                  j                  j                  S )zGuest Authentication Manager.)_sicontentguestOperationsManagerauthManagerr   s    r   r'   zConnection.authManager        xx66BBBr    c                 V    | j                   j                  j                  j                  S )zGuest File Manager.)r$   r%   r&   fileManagerr   s    r   r*   zConnection.fileManager  r(   r    c                 V    | j                   j                  j                  j                  S )zGuest Process Manager.)r$   r%   r&   processManagerr   s    r   r,   zConnection.processManager  s      xx66EEEr    c                 H    | j                   j                  j                  dk(  S )z%Return if VM guest family is windows.windowsGuest)vmguestguestFamilyr   s    r   r.   zConnection.windowsGuest  s     ww}}((N::r    c                     t        t        | 
  |i | t        | d      r=| j                  j
                  dk(  r$d| _        dg| _        d| _        d| _	        d| _
        d| _        y)zinit._shell
powershell)z.ps1z.exe runasFTN)superr   __init__hasattrr3   SHELL_FAMILY!module_implementation_preferencesbecome_methodsallow_executablehas_pipeliningallow_extrasr$   )r   argskwargs	__class__s      r   r8   zConnection.__init__  sc    j$($9&94"t{{'?'?<'O5ID2#*)D$)D!"'D $Dr    c                     | j                   | j                  d      | j                  d      | j                  d      d}| j                  s8t        r-t	        j
                  t        j                  j                         d|d<   	 t        di || _	        y # t        $ r t        d      t        $ r t        dt        |d	         z        t        j                  j                   $ r&}t        d
t        |j"                        z        d }~ww xY w)Nvmware_uservmware_passwordvmware_port)hostuserpwdportTdisableSslCertValidationz+SSL Error: Certificate verification failed.z,Connection Error: Unable to connect to '%s'.rG   zConnection Login Error: %s )r   r   r"   HAS_URLLIB3r   disable_warnings
exceptionsInsecureRequestWarningr   r$   r	   r   r   r   r   faultInvalidLoginmsg)r   connection_kwargses      r   _establish_connectionz Connection._establish_connection'  s    $$OOM2??#45OOM2	
 ""((););)R)RS<@89	P#8&78DH 	NLMM 	vMPYZklrZsPttuuyy%% 	P;i>NNOO	Ps   B AD'!DDc           	         | j                   j                  j                  }d | _        | j	                  d      W|j                  | j	                  d            | _        | j                  t        dt        | j	                  d            z        | j	                  d      Y|j                  d | j	                  d      d      | _        | j                  &t        dt        | j	                  d            z        t        j                  | j	                  d      | j	                  d      d	      | _        	 |r2| j                  j                  | j                  | j                  
       y y # t        j                  j                  $ r&}t        dt        |j                         z        d }~wt        j                  j"                  $ r&}t        dt        |j                         z        d }~wt        j                  j$                  $ r&}t        dt        |j                         z        d }~wt        j                  j&                  $ r&}t        dt        |j                         z        d }~wt        j                  j(                  $ r<}t+        dt        |j                         dt        |j,                              d }~wt.        j                  j0                  $ rV}|j2                  dk(  r!t+        dt        |j2                        z        t+        dt        |j2                        z        d }~wt        j                  j$                  $ r t+        d      w xY w)Nvm_pathzUnable to find VM by path '%s'vm_uuidTzUnable to find VM by uuid '%s'vm_uservm_passwordF)usernamepasswordinteractiveSession)r/   authzVM Power State Error: %szRestricted Version Error: %sz,VM Guest Operations (VMware Tools) Error: %szVM Login Error: %sNo Permission Error:  vix error codes = (3016, 0).
<Connection failed, is the vm currently rebooting? Reason: %sConnection failed. Reason %sACannot connect to guest. Native error: GuestOperationsUnavailable)r$   r%   searchIndexr/   r   FindByInventoryPathr   r   
FindByUuidr   NamePasswordAuthenticationvm_authr'   ValidateCredentialsInGuestrQ   InvalidPowerStaterS   RestrictedVersionGuestOperationsUnavailableInvalidGuestLoginNoPermissionr   privilegeIdr   SystemErrorreason)r   check_vm_credentialsrf   rU   s       r   _establish_vmzConnection._establish_vm=  s   hh&&22??9%1!55dooi6PQDGww"#CiPTP_P_`iPjFk#kll__Y'3!,,T4??93MtTDGww"#CiPTP_P_`iPjFk#kll55__Y/$//-:Xmr
	p#  ;;twwT\\;Z $yy** 	N9Iaee<LLMMyy** 	R=	!%%@PPQQyy33 	bMPYZ[Z_Z_P``aayy** 	H3i6FFGGyy%% 	x*9UVUZUZK[]fghgtgt]u+vww{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	psU   63E+ +M !F)) M 	!G** M 
!H++ M !I,, M 7K M #AL44,M c                 "   t         st        t        d      dt              t        st        t        d      dt
              t        t        | #          | j                  s*| j                          | j                  |       d| _        y y )Nrequestsz : PyVmomirt   T)HAS_REQUESTSr   r   REQUESTS_IMP_ERRHAS_PYVMOMIPYVMOMI_IMP_ERRr7   r   _connect	connectedrV   ru   
_connected)r   rt   rB   s     r   r~   zConnection._connectf  st    ,@,LN^_``,@,K_]^^j$(*~~&&(4HI"DO r    c                 b    t         t        |           t        | j                         d| _        y)zClose connection.FN)r7   r   closer   r$   r   )r   rB   s    r   r   zConnection.closet  s#    j$%'488r    c                 H    | j                          | j                  d       y)z Reset the connection to vcenter.Fry   N)r   r~   r   s    r   resetzConnection.reset{  s    
 	

51r    c           	      R   	 | j                   j                  | j                  | j                  ||      S # t        j
                  j                  $ r<}t        dt        |j                        dt        |j                              d}~wt        j
                  j                  $ rV}|j                  dk(  r!t        dt        |j                        z        t        dt        |j                        z        d}~wt        j
                  j                  $ r t        d      w xY w)	z"Create a temporary file in the VM.)r/   r_   prefixsuffixr`   ra   Nrb   rc   rd   re   )r*   CreateTemporaryFileInGuestr/   rj   r   rQ   rp   r   r   rS   rq   r   rr   rs   r   rn   )r   r   r   rU   s       r   create_temporary_file_in_guestz)Connection.create_temporary_file_in_guest  s    	p##>>$''PTP\P\ektz>{{yy%% 	ly?OQZ[\[h[hQijkk{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	p"   25 D&7B		 D&)AC::,D&c                     | j                   r	 d}d|z  }||fS | j                  d      }t        j                  d|z  d|      }||fS )Nzcmd.exez/c %s
executablez^%s\s*r5   )r.   r   resub)r   cmdprogram_path	argumentss       r   ,_get_program_spec_program_path_and_argumentsz7Connection._get_program_spec_program_path_and_arguments  s_    
 %L#I
 Y&&  ??<8Ly<7SAIY&&r    c                     t        j                         }| j                  |      \  }}|d|d|z  }||_        ||_        |S )Nz 1> z 2> )r   GuestProgramSpecr   programPathr   )r   r   stdoutstderrguest_program_specr   r   s          r   _get_guest_program_specz"Connection._get_guest_program_spec  sN     113"&"S"STW"Xivv66	)5&'0$!!r    c           	         	 | j                   j                  | j                  | j                  |g      }|d	   S # t        j
                  j                  $ r<}t        dt        |j                        dt        |j                              d }~wt        j
                  j                  $ rV}|j                  dk(  r!t        dt        |j                        z        t        dt        |j                        z        d }~wt        j
                  j                  $ r t        d      t        j
                  j                   $ r t        d      w xY w)
N)r/   r_   pidsr`   ra   zvix error codes = (1, 0).
zNConnection failed, Netlogon service stopped or dcpromo in progress. Reason: %sz$Connection plugin failed. Reason: %sre   z3Guest login failed. Native error: InvalidGuestLoginr   )r,   ListProcessesInGuestr/   rj   r   rQ   rp   r   r   rS   rq   r   rr   rs   r   rn   ro   )r   pid	processesrU   s       r   _get_pid_infozConnection._get_pid_info  s&   	b++@@DGGRVR^R^fiej@kI& |% yy%% 	ly?OQZ[\[h[hQijkk{{&& 
	o xx88.d!!((+  //UYbcdckckYl/mnnyy33 	p*+nooyy** 	b*+`aa	bs#   3: E7B E.AC??AEc                 :    |j                  d| j                        S )ad  
        Fix url if connection is a host.

        The host part of the URL is returned as '*' if the hostname to be used is the name of the server to which the call was made. For example, if the call is
        made to esx-svr-1.domain1.com, and the file is available for download from http://esx-svr-1.domain1.com/guestFile?id=1&token=1234, the URL returned may
        be http://*/guestFile?id=1&token=1234. The client replaces the asterisk with the server name on which it invoked the call.

        https://code.vmware.com/apis/358/vsphere#/doc/vim.vm.guest.FileManager.FileTransferInformation.html
        *)replacer   )r   urls     r   _fix_url_for_hostszConnection._fix_url_for_hosts  s     {{3 0 011r    c           	         	 | j                   j                  | j                  | j                  |      }| j!                  |j"                        }t%        j&                  || j(                  d	      }|j*                  d
k7  rt        d      |S # t        j
                  j                  $ r<}t        dt        |j                        dt        |j                              d }~wt        j
                  j                  $ rV}|j                  dk(  r!t        dt        |j                        z        t        dt        |j                        z        d }~wt        j
                  j                  $ r t        d      w xY w)N)r/   r_   guestFilePathr`   ra   rb   rc   rd   re   T)verifystream   zFailed to fetch file)r*   InitiateFileTransferFromGuestr/   rj   r   rQ   rp   r   r   rS   rq   r   rr   rs   r   rn   r   r   rw   getr"   status_code)r   r   fileTransferInformationrU   r   responses         r   _fetch_file_from_vmzConnection._fetch_file_from_vm  sQ   	p&*&6&6&T&TX\X_X_fjfrfr  CP&T  'Q# %%&=&A&AB<<D,?,?M3&566) yy%% 	ly?OQZ[\[h[hQijkk{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	ps$   2B E>*7C!! E>AE,E>c           	      R   	 | j                   j                  | j                  | j                  |       y# t        j
                  j                  $ r<}t        dt        |j                        dt        |j                              d}~wt        j
                  j                  $ rV}|j                  dk(  r!t        dt        |j                        z        t        dt        |j                        z        d}~wt        j
                  j                  $ r t        d      w xY w)	zDelete file from VM.)r/   r_   filePathr`   ra   Nrb   rc   rd   re   )r*   DeleteFileInGuestr/   rj   r   rQ   rp   r   r   rS   rq   r   rr   rs   r   rn   )r   r   rU   s      r   delete_file_in_guestzConnection.delete_file_in_guest  s    	p..$''W_.`yy%% 	ly?OQZ[\[h[hQijkk{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	pr   c           	         t         t        |   |||       | j                  d      }| j                  d      }| j	                  |||      }	 | j
                  j                  | j                  | j                  |      }| j-                  |      }	|	j.                  8t1        | j3                  d             | j-                  |      }	|	j.                  8| j5                  |      }
| j7                  |       | j5                  |      }| j7                  |       |	j8                  |
j:                  |j:                  fS # t        j                  j                  $ r<}t        dt        |j                        dt        |j                              d}~wt        j                  j                   $ r&}t        d	t        |j                        z        d}~wt"        j                  j$                  $ rV}|j&                  d
k(  r!t)        dt        |j&                        z        t)        dt        |j&                        z        d}~wt        j                  j*                  $ r t)        d      w xY w)zExecute command.)in_datasudoablez.stdout)r   z.stderr)r/   r_   specr`   ra   NzStartProgramInGuest Error: %srb   rc   rd   re   exec_command_sleep_interval)r7   r   exec_commandr   r   r,   StartProgramInGuestr/   rj   r   rQ   rp   r   r   rS   rq   FileNotFoundr   rr   rs   r   rn   r   endTimer
   r   r   r   exitCodetext)r   r   r   r   r   r   r   r   rU   pid_infostdout_responsestderr_responserB   s               r   r   zConnection.exec_command  s   j$,S'H,U44I4F44I4F!99#vvN	p%%99TWW4<<^p9qC" %%c*&$//"?@A))#.H & 226:!!&)226:!!&)  /"6"68L8LLL9 yy%% 	ly?OQZ[\[h[hQijkkyy%% 	S>155AQQRR{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	ps1   2D> >I07F I02!G I03AI,I0c                    t         t        |   ||       | j                  |      }t	        |d      5 }|j                  | j                  d            D ]  }|j                  |        	 ddd       y# 1 sw Y   yxY w)zFetch file.wbfile_chunk_size)
chunk_sizeN)r7   r   
fetch_filer   openiter_contentr   write)r   in_pathout_pathin_path_responsefdchunkrB   s         r   r   zConnection.fetch_file'  sx    j$*7H=33G<(D! 	 R)66$//RcBd6e   	  	  	 s   8A55A>c           	         t         t        |   ||       t        t	        |d            st        dt        |      z        	 | j                  j                  | j                  | j                  |t        j                         t        |      d      }| j1                  |      }t3        |d      5 }t5        j6                  || j8                  |      }ddd       j:                  dk7  rt!        d      y# t        j                  j                  $ r<}t!        dt        |j"                        dt        |j$                              d}~wt&        j                  j(                  $ rV}|j*                  d	k(  r!t-        d
t        |j*                        z        t-        dt        |j*                        z        d}~wt        j                  j.                  $ r t-        d      w xY w# 1 sw Y   xY w)z	Put file.surrogate_or_strict)errorsz#file or module does not exist: '%s'T)r/   r_   r   fileAttributesfileSize	overwriter`   ra   Nrb   rc   rd   re   rb)r   datar   zFile transfer failed)r7   r   put_filer   r   r   r   r*   InitiateFileTransferToGuestr/   rj   r   GuestFileAttributesr   rQ   rp   r   rS   rq   r   rr   rs   r   rn   r   r   rw   putr"   r   )	r   r   r   put_urlrU   r   r   r   rB   s	           r   r   zConnection.put_file1  s   j$((;hw/DEF%&KiX_N`&`aa	p&&BB77XVYVmVmVo  {B  CJ  {K  W[ C G" %%g. '4  	NB||C0C0C"MH	N 3&566 ') yy%% 	ly?OQZ[\[h[hQijkk{{&& 	gxx;;.R!!((+  //MQZ[\[c[cQd/effyy33 	p*+noo	p	N 	Ns2   AC7 1#G+7G(7E G(+AF<<,G(+G5)T)r5   r5   )NT)__name__
__module____qualname____doc__	transportpropertyr   r"   r'   r*   r,   r.   r8   rV   ru   r~   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)rB   s   @r   r   r      s    "/I. . 1 1 C C C C F F ; ;	P,'pR# 2p$'
".
22p$'MR  7  7r    r   )/
__future__r   r   r   type__metaclass__DOCUMENTATIONexampler   os.pathr   r   socketr   sslr	   timer
   	tracebackr{   r}   rw   rz   ImportError
format_excrequests.packagesr   rM   ansible.errorsr   r   r   ansible.module_utils._textr   r   ansible.plugins.connectionr   ansible.module_utils.basicr   pyVim.connectr   r   pyVmomir   r   r|   r   rL   r    r   <module>r      s   A @@DCJ 
 #     L
)K W V : 5 ;-6"KX7 X7;  +y++-L   	"  -K*i**,O-sX   B B" &C BB"B?(B/.B?/B96B?8B99B?>B?CC