
    Vh=                       e Zd dlZd dlmc mc mZ d dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZ d dlmZ dZ	 d dlZdZdZ	 d dl m!Z! d d	l"m#Z#m$Z$m%Z% dZ&d d
l'm(Z(m)Z) d dl*m+Z+m,Z,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4  G d de5      Z6d Z7d Z8d Z9d@dZ:dAdZ;dBdZ<d Z=dCdZ>dCdZ?dDdZ@d ZAd ZBdDdZCd ZDdEdZEdDd ZFdDd!ZGd" ZHdFd#ZIdDd$ZJdDd%ZK	 	 dGd&ZLdCd'ZMd( ZNd) ZOd* ZPd+ ZQd, ZRd- ZSd. ZTd/ ZUd0 ZVd1 ZWd2 ZX	 	 dHd3ZYdCd4ZZd5 Z[d6 Z\dId7Z]dAd8Z^dJd9Z_d: Z`d; ZadKd<ZbdDd=Zc G d> d?e      Zdy# e$ r  ej<                         ZdZY w xY w# e$ r  ej<                         ZdZ&Y w xY w)L    N)OrderedDict)StrictVersion)PyvmomiClientApiAccessError)randintTF)connect)vimvmodlVmomiSupport)to_text	to_native)integer_types	iteritemsstring_types
raise_from)missing_required_lib)unquotebase_argument_specc                        e Zd Z fdZ xZS )	TaskErrorc                 ,    t        t        | 
  |i | y N)superr   __init__)selfargskwargs	__class__s      p/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/vmware/plugins/module_utils/vmware.pyr   zTaskError.__init__6   s    i'88    )__name__
__module____qualname__r   __classcell__r   s   @r    r   r   5   s    9 9r!   r   c                 J    t        | d      r| j                  j                  ryy)zxCheck whether locked a virtual machine.

    Args:
        vm: Virtual machine management object

    Returns: bool
    runtimeTF)hasattrr(   question)vms    r    check_answer_question_statusr,   :   s      r9"**"5"5r!   c                    i }| j                   j                  j                  D ]t  }i ||j                  <   | j                   j                  j                  j
                  D ]6  }||j                     j                  |j                  |j                  i       8 v g }	 |D ]@  }|j                  | j                   j                  j                  ||d      |d      d       B 	 |S # t        $ r t        dd   d|d   d      w xY w)zMake the response contents to answer against locked a virtual machine.

    Args:
        vm: Virtual machine management object
        answers: Answer contents

    Returns: Dict with answer id and number
    Raises: TaskError on failure
    r*   response)idresponse_numz
not found z or z or both in the response list)r(   r*   messager/   choice
choiceInfoupdatelabelkeyappend	Exceptionr   )r+   answersresponse_listr1   r2   	responsesanswers          r    make_answer_responser=   H   s    M::&&.. $&gjj!jj))00;; 	F'**%,,fjj. 	 Iv 	Fjj)),, -fZ.@ A&BT U 	   vVT^M_aghrastuuvs   AC% %"Dc                     |D ]  }	 | j                  |d   |d           y# t        $ r}t        dt        |      z        d}~ww xY w)zAnswer against the question for unlocking a virtual machine.

    Args:
        vm: Virtual machine management object
        responses: Answer contents to unlock a virtual machine
    r/   r0   zanswer failed: %sN)AnswerVMr8   r   r   )r+   r;   r.   es       r    answer_questionrA   g   sV      >	>KK(@A>  	>/'!*<==	>s   "	AAAc                    d}t        j                          }	 t        |      rP|rt        ||      }t        ||       n5t	        dt        |j                  j                  j                        z        t        j                          |z
  |k\  rt	        d      | j                  j                  t        j                  j                  j                  k(  rd| j                  j                  fS | j                  j                  t        j                  j                  j                   k(  r| j                  j                   }d}		 |j"                  }t%        | j                  j                   d      r | j                  j                   j&                  }	t+        t	        ||	      | j                  j                          | j                  j                  t        j                  j                  j,                  t        j                  j                  j.                  fv r9t1        d|z  t3        dd	      d	z  z   |      }
t        j4                  |
       |dz  }6# t(        $ r Y w xY w# t+        t	        ||	      | j                  j                          w xY w)
a<  Wait for given task using exponential back-off algorithm.

    Args:
        task: VMware task object
        max_backoff: Maximum amount of sleep time in seconds
        timeout: Timeout for the given task in seconds

    Returns: Tuple with True and result for successful task
    Raises: TaskError on failure
    r   T%sTimeoutN
thumbprint      i  )timer,   r=   rA   r   r   r(   r*   textinfostater	   TaskInfoStatesuccessresulterrormsgr)   rE   AttributeErrorr   runningqueuedminr   sleep)taskmax_backofftimeoutr+   r9   failure_counter
start_timer;   	error_msghost_thumbprint
sleep_times              r    wait_for_taskr_   u   s    OJ
'+0W=	I.wrzz/B/B/G/G'H HII99;#w.I&&99??cll00888))))99??cll00666		I"OS%MM	499??L9&*iioo&@&@O 9Y@$))//R99??s||11993<<;M;M;T;TUUQ/1GAt4Dt4KK[YJJJz"q O3 $ "  9Y@$))//Rs%   ?AI 	II II ,J	c                     t               }d}|dkD  r;t        | |      }|d   s|d   r|}	 |S t        j                  |       ||z  }|dkD  r;|S )N   r   ipv4ipv6)dictgather_vm_factsrH   rV   )contentr+   rY   factsinterval_factss         r    wait_for_vm_iprj      se    FEH
A+ "-&>VF^E L 	

88 A+ Lr!   c           	      :   | j                   j                  |xs | j                  d|      }|j                  D cg c]:  }|r4t	        t        |j                              t	        t        |            k(  s9|< }}|j                          |r|r|d   S y |S c c}w )NT)	recursivetyper   )viewManagerCreateContainerView
rootFolderviewr   r   nameDestroy)rf   vimtyperr   firstfolder	containerobjobj_lists           r    find_objrz      s    ##778T'BTBT`dkr7sI(~~rTWWSXXEV=W[bcjkocp[q=qrHr A; O ss   :B6Bc                 f    t        |      }| j                  }|D ]  }|j                  |k(  s|c S  y r   )quote_obj_name	portgrouprr   )	dv_switchportgroup_name
portgroupspgs       r    find_dvspg_by_namer      s<    #N3N$$J 77n$I r!   c                     t        |t              s|g}|j                         }t        | |||      }|D ]  }	 t	        |j
                        |k(  r|c S ! y # t        j                  j                  $ r Y Bw xY wN)rv   recurse)	
isinstanceliststripget_all_objsr   rr   r
   faultManagedObjectNotFound)rf   rr   obj_typerv   r   objectsrx   s          r    find_object_by_namer      s    h%:::<D7HVWMG 	sxx D(
 )  {{00 		s   AA87A8c                    t        |t              s|g}|j                         }g }t        | |||      }|D ],  }	 t	        |j
                        |k(  r|j                  |       . |S # t        j                  j                  $ r Y Pw xY wr   )
r   r   r   r   r   rr   r7   r
   r   r   )rf   rr   r   rv   r   rO   r   rx   s           r    find_all_objects_by_namer      s    h%:::<DF7HVWMG 	sxx D(c" M {{00 		s   )A((BBc                     |rt        |d      r|j                  }n| j                  }t        | |t        j
                  g|      S N
hostFolderrv   )r)   r   rp   r   r	   ClusterComputeResource)rf   cluster_name
datacenterrv   s       r    find_cluster_by_namer      s?    gj,7&&##ws7Q7Q6R[abbr!   c                 :    t        | |t        j                  g      S r   )r   r	   
Datacenter)rf   datacenter_names     r    find_datacenter_by_namer      s    w#..9IJJr!   c                     t        | t        j                        r| S d}	 t        | d      s	 |S | j                  xs | j
                  } t        | t        j                        r| }	 |S I)z5 Walk the parent tree to find the objects datacenter Nparent)r   r	   r   r)   r   
parentVApp)rx   r   s     r    get_parent_datacenterr      sg    #s~~&
J
sH%
 	 jj*CNNc3>>*J r!   c                 <    t        | |t        j                  g|      S r   )r   r	   	Datastore)rf   datastore_namer   s      r    find_datastore_by_namer     s    wYYr!   c                 :    t        | |t        j                  g      S r   )r   r	   Folder)rf   folder_names     r    find_folder_by_namer   
  s    wcjj\BBr!   c                 d   |j                  d      }|j                  d      j                  d      }t        |      dkD  r |s|d   }||d   k(  r|j                  d       t	        | |      }|syt        |      dkD  r |s|d   }||d   k(  r|j                  d       |dv rt        |d|j                         z        }nyt        |      dkD  r`|D ]Y  }d}	|j                  D ]B  }
|
j                  |k(  sd|
j                  v st        j                  |
j                  v s>|
}	|
} n |	rY y 	S |}	|	S )z
    Find the folder by its given fully qualified path name.
    The Fully Qualified Path Name is I(datacenter)/I(folder type)/folder name/
    for example - Lab/vm/someparent/myfolder is a vm folder in the Lab datacenter.
    /r   N)r+   host	datastorenetworkz%sFolderr   )r   splitlenpopr   getattrlowerchildEntityrr   	childTyper	   r   )rf   r   r   folder_typerv   folder_partsr   
parent_objpart
folder_objpart_objs              r    find_folder_by_fqpnr     s_    s#F<<$**3/L <1*1oOl1o-Q(/BJ <1&q/K,q/)Q<<Zk6G6G6I)IJ
 <1  	DJ&22 ==D(h(:L:L.LPSPZPZ^f^p^pPp!)J!)J	
 	   
r!   c                 >    t        | |t        j                  g|      S Nr   )r   r	   DistributedVirtualSwitch)rf   switch_namerv   s      r    find_dvs_by_namer   =  s    wc6R6R5S\bccr!   c                     |rt        |d      r|j                  }n| j                  }t        | |t        j
                  g|      S r   )r)   r   rp   r   r	   
HostSystem)rf   hostnamer   rv   s       r    find_hostsystem_by_namer   A  s<    gj,7&&##w3>>2B6RRr!   c                 :    t        | |t        j                  g      S r   r   r	   ResourcePool)rf   resource_pool_names     r    find_resource_pool_by_namer   I  s    w(:S=M=M<NOOr!   c                 >    t        | |t        j                  g|      S r   r   )rf   r   clusters      r    find_resource_pool_by_clusterr   M  s    w(:S=M=M<NW^__r!   c                 <    t        | |t        j                  g|      S r   )r   r	   Networkrf   network_namer   s      r    find_network_by_namer   Q  s    ws{{m_UUr!   c                 <    t        | |t        j                  g|      S r   )r   r	   r   r   s      r    find_all_networks_by_namer   U  s    #G\CKK=/ZZr!   c                 V   | j                   }d}|dk(  r|j                  ||d      }|S |dk(  r|j                  |d|d      }|S |dk(  r|j                  |d|d      }|S |d	k(  r|j                  ||d
      }|S |dk(  r$d}|r|}n|r|j                  }t        | ||      }|S |dk(  r~|}	|j                  |	      }
|
rit        |
t        j                        r|
j                  }
|
j                  D ]4  }t        |t        j                        s|j                  |k(  s.|}|s3 |S  |S )zA UUID is unique to a VM, every other id returns the first match. Ndns_nameT)r   dnsNamevmSearchuuidF)r   instanceUuidr   r   instance_uuidip)r   r   r   vm_nameinventory_path)searchIndexFindByDnsName
FindByUuidFindByIpr   find_vm_by_nameFindByInventoryPathr   r	   r   vmFolderr   VirtualMachinerr   )rf   vm_id
vm_id_typer   r   rv   match_firstsir+   
searchpathf_objc_objs               r    find_vm_by_idr   Y  sn    
		B	BZUTR: I9 
v	]]ju5[_]`4 I3 
	&]]jt%Z^]_0 I/ 
t	[[J54[H, I+ 
y	 F**FWeV4 I 
'	'
&&z2%0** !%););<::&B"I Ir!   c                 @    t        | |t        j                  g||      S r   )r   r	   r   )rf   r   rv   r   s       r    r   r     s    w#2D2D1Ef^effr!   c                     | j                   j                  j                  D ]  }|j                  j                  |k(  s|c S  y r   configr   r}   specrr   r   r   r}   s      r    find_host_portgroup_by_namer     s>    [[((22 	>>.0 r!   c                    g }t        | t        j                        r|j                  | j                         | }t        |d      r`|j                  }	 |j                  }|dv rnBt        |t        j                        r|j                  |j                         t        |d      r`|j                          ddj                  |      z   S # t        $ r d}Y xw xY w)z7 make a /vm/foo/bar/baz like folder path for an object r   N)zgroup-d1zha-folder-rootr   )r   r	   r   r7   rr   r)   r   _moIdrR   reversejoin)vobjpathsthisobjmoids       r    compile_folder_path_for_objectr     s     E$

#TYYG
'8
$..	==D 11gszz*LL& '8
$ 
MMO%    	D	s   C
 
CCc                 ^    | }|D ]  }	 t        ||      } |S # t        t        f$ r Y  yw xY w)z$Safely get a property or return NoneN)r   rR   
IndexError)r+   
attributesrO   	attributes       r    _get_vm_propr    sG    F 		VY/F
 M 
+ 		s   ,,c                    i ddd|j                   j                  d|j                  j                  j                  d|j                  j
                  j                  d|j                  j
                  j                  d|j                   j                  d|j                   j                  j                  d	|j                   j                  j                  d
|j                   j                  j                  dg dg dg ddddd|j                   j                  ddd|j                   j                  |j                   j                  t!        |d      t!        |d      t#        j$                  t#        j&                  |j                  j                  j(                  t*        j,                  dd            |j                  j                  j.                  dd|j                   j0                  i g di |j2                  d|j2                  z  i d}|j                  j                  j4                  r	 |j                  j                  j4                  }|j                  j                   j                  |d<   |j6                  r:t9        |j6                  t:        j<                        r|j6                  j                  nd|d<   |j                  j                  jB                  r-|j                  j                  jB                  jD                  |d<   |jF                  }|D ]*  }|d   jI                  |jJ                  j                         , 	 |j                   jL                  }|jN                  }|rL|jP                  g|d<   |jR                  D ],  }|jT                  D ]  }	d|	v s|d   jI                  |	        . |jV                  D ][  }|d   jI                  tX        jZ                  j]                  tX        jZ                  j_                  |jP                        |             ] |jN                  j`                  D ]>  }|d   jI                  tX        jZ                  j]                  |jb                  |             @ |jN                  jd                  D ]'  }|jf                  D ]  }
|d   jI                  |
        ) tj        jm                  | |      |d<   | jn                  }|j                  jp                  D ]f  }|jr                  }|D|jt                  r8|jt                  D ])  }|jr                  |jr                  k(  s|j                  } n |jv                  |d   |<   h |j                   jx                  D ]  }|jv                  |d   |jr                  <     i }t!        |d      }|r9|D ]4  }|jz                  dkD  st}        |j~                        ||j                  <   6 |j
                  j~                  rKd|j
                  j~                  v r|j
                  j~                  |d <   n|j
                  j~                  |d!<   d}|j                   j                  j                  D ]s  }t        |d"      s|j                  r|j                  }|j                  dd#      }ndx}}t        |d$      rt        |j                  d%      rt        |j                  j                  d&      rat        |j                  j                  d'      rA|j                  j                  j                  }|j                  j                  j                  }nd}d}d(t        |      z   }|j                  |j                  j                  ||j                  |j                  d      ||j                  j                  ||d)||<   |d   jI                  d*t        |      z          |d+z  }v t        |      }d,|v r|d,   |d,<   |d-   |d-<   t        |      |d.<   t        |j                  j                   d/      r |j                  j                   j                  nd|j                   j                  r*|j                   j                  j                  j                  ndd0|d1<   |S # t:        j>                  j@                  $ r Y w xY w# th        $ r Y w xY w)2z. Gather facts from vim.VirtualMachine object. 	module_hwThw_namehw_power_statushw_guest_full_namehw_guest_idhw_product_uuidhw_processor_counthw_cores_per_sockethw_memtotal_mbhw_interfaceshw_datastoreshw_fileshw_esxi_hostNhw_guest_ha_statehw_is_template	hw_folder
hw_version)guesttoolsRunningStatus)r  toolsVersioncls	sort_keysstrip_dynamiczvim.VirtualMachine:%s)r   guest_tools_statusguest_tools_versionguest_questionguest_consolidation_neededrb   rc   
annotationcustomvalues	snapshotscurrent_snapshotvncr   vimrefadvanced_settings
hw_clustervmsnr!  r&  )r  netr   :rc   rb   
macAddress-backingportportKeyportgroupKeyhw_eth)addresstyper5   
macaddressipaddressesmacaddress_dashsummaryportgroup_portkeyportgroup_keyethrG   r"  r#  r$  
tpmPresent)tpm_presentprovider_idtpm_info)Sr   rr   r6  r(   
powerStater  guestFullNameguestIdr   hardwarenumCPUnumCoresPerSocketmemoryMBtemplateversionr   r  jsonloadsdumpsr*   r   VmomiJSONEncoderconsolidationNeededr   r   r   r   r   r	   r   r   NoPermissiondasVmProtectiondasProtectedr   r7   rJ   fileslayout
vmPathNamesnapshotsnapshotFile
configFileospathr   dirnamelogFilelogDirectorydiskdiskFiler8   PyVmomiget_vm_pathcustomFieldsManagercustomValuer6   fieldvalueextraConfigdeviceConfigIdr   	ipAddressr+  devicer)   replacer-  r.  r0  r/  straddressType
deviceInfor5   getlist_snapshotsget_vnc_extraconfigr:  keyId
providerIdr/   )rf   r+   rg   r   
datastoresdsrO  rP  itemsnaprZ  cfm	value_objknfadvanced_settingnet_dictvmnetre  ethernet_idxentrymac_addrmac_addr_dashport_group_keyport_keyfactnamesnapshot_factss                              r    re   re     s   "T"299>>" 	2::--88" 	bjj..<<	"
 	rzz''//" 	299>>" 	bii0077" 	ryy11CC" 	")),,55" 	" 	" 	B" 	" 	T" 	")),,"  	T!"" 	bii''#"$ //*2/NO+B0IJ**TZZ

0B0B0K0KQ]QnQn:>d&T U&(jj&8&8&L&Lii** )BHH4C"EJ 
zz		::%%**D$(LL$7$7$<$<E.!6:kkjQUQ\Q\^a^x^xFy$++"2"2  @DE, 
zz))%'ZZ%7%7%G%G%T%T!"J 4o%%bggll34		!&!1!1 2E* 7 -- 7D~j)00677 )) `j!((bggooeFVFV6WY])^_`		)) Qj!((e6H6H$)OPQ		 3 MM 3D*%,,T233 !,,Wb9E+

%
%CZZ++ 	4	]]?syyYY 55IMM)B	 %.OOnb!	4 II11 R;K;Q;Q!"#3#7#78R H-.E 	EF$$q(.263C3C.D**+	E 
xx"(($$$HH..E&MHH..E&ML##** "ul+''H$,,S#6M'++H} E9%v.**I6**N;"]]//<<N}}))11H!NHc,// ,,%%++"#<<(8(8$?,''//!)+	
h 	o%%ec,.?&?@E"H $B'Nn$+K8k$23E$F !&r*E%L 8?rzz?P?PR^7_rzz((33ei8:		ryy1144TE* La yy%% 	 		8  s-   4Bb Ab5 #Db5 b21b25	ccc                 4   i }| |S | j                  t        j                  j                        }| j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d	      |d
<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d<   |j	                  d      |d<   |j	                  d      |d<   | j	                  d      |d<   | j	                  d      |d <   | j	                  d!      |d"<   | j	                  d#      |d$<   |S )%Nz%Yyearz%mmonthz%Aweekdayz%wweekday_numberz%W
weeknumberz%ddayz%Hhourz%Mminutez%SsecondrC   epochz%Y-%m-%ddatez%H:%M:%SrH   z%Y-%m-%dT%H:%M:%S.%fZiso8601_microz%Y-%m-%dT%H:%M:%SZiso8601z%Y%m%dT%H%M%S%fiso8601_basicz%Y%m%dT%H%M%Siso8601_basic_shortz%Ztzz%z	tz_offset)
astimezonedatetimetimezoneutcstrftime)	timestampdate_time_factsutctimestamps      r    ansible_date_time_factsr  M  s   O''(9(9(=(=>L'006OF(11$7OG!*!3!3D!9OI(1(:(:4(@O$%$-$6$6t$<OL!&//5OE'006OF ) 2 24 8OH ) 2 24 8OH(11$7OG'00<OF'00<OF'3'<'<=T'UOO$!-!6!67K!LOI'0'9'9:K'LOO$-6-?-?-PO)*%..t4OD#,#5#5d#;OK r!   c                     | j                   | j                  | j                  | j                  | j                  | j
                  dS )N)r/   rr   descriptioncreation_timerK   quiesced)r/   rr   r  
createTimerK   r  )rx   s    r    deserialize_snapshot_objr  k  s6    &&HH?? ^^YY& &r!   c                 |    g }| D ]4  }|j                  t        |             |t        |j                        z   }6 |S r   )r7   r  list_snapshots_recursivelychildSnapshotList)r"  snapshot_datarR  s      r    r  r  t  sJ    M _5h?@%(B8C]C](^^_ r!   c                     g }| D ];  }|j                   |k(  r|j                  |       |t        |j                  |      z   }= |S r   )rR  r7   get_current_snap_objr  )r"  snapobsnap_objrR  s       r    r  r  |  sQ    H W&OOH%283M3MvVVW Or!   c                 :   i }t        | d      }|s|S | j                  |S t        | j                  j                        |d<   | j                  j                  }t        | j                  j                  |      }|rt        |d         |d<   |S t               |d<   |S )N)rR  r"  r   r#  )r  rR  r  rootSnapshotListcurrentSnapshotr  r  rd   )r+   rO   rR  current_snaprefcurrent_snap_objs        r    rk  rk    s    FB.H	{{4R[[5Q5QRF;kk11O+BKK,H,H/Z%=>Nq>Q%R!" M &*V!"Mr!   c                     i }| j                   j                  D ]9  }dD ]2  }|j                  j                         d|z   k(  s$|j                  ||<   4 ; |S )N)enabledr   r.  passwordzremotedisplay.vnc.)r   rb  r6   r   ra  )r+   rO   opts
optkeynames       r    rl  rl    s]    F		%% 0? 	0Jxx~~#7*#DD%)ZZz"	00 Mr!   c                      t               S r   r    r!   r    vmware_argument_specr    s    r!   c
                      r|s j                   d   }|s j                   d   }|s j                   d   }|s j                   j                  d      }|	s j                   j                  d      }	|s j                   j                  dd      }|s j                   d   } fd	}
|s	 |
d
       |s	 |
d       |s	 |
d       |rt        t        d      s
 |
d       n|rPt        j                  t        j
                        }t        j                  |_        d|_        |j                          nRt        t        d      r@t        j                  t        j
                        }t        j                  |_        d|_        nd }d }t        ||      }r|j                  |       d}	 |rzd||	fz  }|j                  ||	       t        j                  d&i |}t        j                  |t        j                  j!                  ||            }t#        j$                  d|      }n(|j                  ||       t        j&                  d&i |}|d%|d|} |
||z          |r$t=        j>                  t        j@                  |       |r||jC                         fS |jC                         S # t"        j(                  j*                  $ r1}d|d|d} |
|d|d|j,                  |z          Y d }~d }~wt"        j(                  j.                  $ r)} |
d|d|d|d |j,                         Y d }~d }~wt0        j2                  t        j4                  f$ r} |
d!|d"|d|       Y d }~+d }~wt6        j(                  j8                  $ r/}d#|d|d} |
|d$|j,                  |z          Y d }~ud }~wt:        $ r$}d%|d||z   } |
|d |       Y d }~d }~ww xY w)'Nr   usernamer  
proxy_host
proxy_portr.  i  validate_certsc                 B    j                  |        t        |       )NrQ   )	fail_jsonr   )rQ   modules    r    _raise_or_failz&connect_to_api.<locals>._raise_or_fail  s%    %S!!r!   zHostname parameter is missing. Please specify this parameter in task or export environment variable like 'export VMWARE_HOST=ESXI_HOSTNAME'r  zUsername parameter is missing. Please specify this parameter in task or export environment variable like 'export VMWARE_USER=ESXI_USERNAME'zPassword parameter is missing. Please specify this parameter in task or export environment variable like 'export VMWARE_PASSWORD=ESXI_PASSWORD'
SSLContextzxpyVim does not support changing verification mode with python < 2.7.9. Either update python or use validate_certs=false.TF)r   r.  )
sslContext z [proxy: %s:%d])httpProxyHosthttpProxyPortServiceInstance)userpwdz+Unable to log on to vCenter or ESXi API at r*   z as z: zUser zG does not have required permission to log on to vCenter or ESXi API at z : z,Unable to connect to vCenter or ESXi API at z on TCP/z%Failed to get a response from server z as request is malformed: z9Unknown error while connecting to vCenter or ESXi API at r  )"paramsrj  r)   sslr  PROTOCOL_SSLv23CERT_REQUIREDverify_modecheck_hostnameload_default_certs	CERT_NONErd   r4   r   SmartStubAdapterVimSessionOrientedStubmakeUserLoginMethodr	   r  SmartConnectr   InvalidLoginrQ   rL  requestsConnectionErrorSSLErrorr
   InvalidRequestr8   atexitregister
DisconnectRetrieveContent)r  disconnect_atexit	return_sir   r  r  r.  r  r  r  r  ssl_contextservice_instanceconnect_args
msg_suffix
smart_stubsession_stubinvalid_loginrQ   no_permissiongeneric_req_excinvalid_requestgeneric_excs   `                      r    connect_to_apir    s   }}Z0H}}Z0H}}Z0H"MM--l;M"MM--l;M==$$VS1D#]]+;<N"
  ^ 	_  ^ 	_  b 	c gc<8 A 	B	nnS%8%89"%"3"3%)"&&(	l	#nnS%8%89"%--%*"L {3J;*m]-KKJm=Y 11ALAJ"99*gFdFdFxFx  zB  DL  GM  NL"223DlSX8<&33ClC" RZ\`a3+,
 **,<=!1!A!A!CCC++--7 99!! ]EMtTS(M<M<MNQ[[\\99!! ~PXZbdhjwj{j{} 	~ 	~$$cll3 ]egkm|}~~;;%% g?GNsODWDWX[eeff ;RZ\`adnn[9::;sI   ,B$J0 0O5'K99 O5L==&O5#M;; O5$OO5O00O5c                    |s| j                   }i }| j                  j                  |||      }|j                  D ]   }	 |j	                  ||j
                  i       " |S # t        j                  j                  $ r Y Dw xY wr   )	rp   rn   ro   rq   r4   rr   r
   r   r   )rf   rt   rv   r   rx   rw   managed_object_refs          r    r   r     s    ##
C##77QI'nn 	JJ*,>,C,CDE
 J {{00 		s   AA?>A?c                 T   i }t        |       }|D cg c]  }|j                  d      r| }}|D ]  }t        | |      }t        |      rt	        |      }|d||<   /t        |t        j                  j                        rt        |      ||<   bt        |t        j                  j                        rt        |      ||<   t        |t        j                  j                  j                        rt        |      ||<   t        |t        j                  j                  j                  j                        rt        |      ||<   t        |t        j                         rXt        |j"                        t        |j$                        t        |j&                        t        |j(                        d||<   t+        |d      r)t        |      dz   t        |j,                        z   ||<   t        |t        j                  j.                        rt1        |t2              r+g ||<   |D ]  }||   j5                  t        |             ! "t1        |t6        t8        z   t:        t<        fz         r0t1        |t8              rt?        |      ||<   ft        |      ||<   vt1        |t<              r|||<   t1        |t@              rDi |t        |      <   |jC                         D ]!  \  }}t        |      }t        |      ||   |<   # tE        |      ||<    |S c c}w )z*Serialize a clonespec or a relocation spec_N)dynamicPropertydynamicTyper5   r6  rr   r*  )#dir
startswithr   callablerm   r   r	   r+   
ConfigSpecserialize_specRelocateSpecre  VirtualDiskVirtualDeviceSpecFileOperationr   Descriptionr  r  r5   r6  r)   rr   ProfileSpec
issubclassr   r7   r   r   floatboolintrd   itemsrg  )		clonespecdataattrsxxoxtxekvs	            r    r  r    s}   D	NE71Q\\#%6Q7E7 +Y"B<"X:DGCFF--.$R(DGCFF//0$R(DGCFFMM556$R(DGCFFMM;;IIJbkDGCOO,#1"2D2D#E-bnn='1)"**5	DG R bkC''"''*::DGCFF../D!DG 3Q~b123L=8E4=HI"m,b'Q!"+QD!DGD!!D
 /1AJ+A.Q
/ "gDGW+Z K] 8s
   L%L%c                     t        ||      }|| j                  d|z         t        |||      }|| j                  d|z         |j                  D ]  }|j                  |k(  s||fc S  d |fS )Nz&Unable to find datacenter with name %sr  r   z#Unable to find cluster with name %s)r   r  r   r   rr   )r  rf   r   r   	host_namedcr   r   s           r    find_host_by_cluster_datacenterr  N  s    	 /	:B	zEWX"7LRHGB\QR !99	!= ! =r!   c                 ~   t        | |      }|dk(  rd}|j                  dd      j                  dd      j                         }|d   j                         }t        dd      }	|s"|d	vrd
|	d<   d|z  |	d<   t        | |      |	d<   |	S ||k7  rd}
	 |dk(  r|j	                         }
n|dk(  r|j                         }
n|dk(  r#|dv r|j                         }
nd
|	d<   d|z  |	d<   n|dk(  r#|dv r|j                         }
nd
|	d<   d|z  |	d<   n|dv r|dk(  rp|j                  j                  dk(  rL|dk(  r1|j                         }
|dkD  r,|	j                  t        ||             n|j                         }
d
|	d<   n;d
|	d<   d|	d<   n0|dk(  rd|	d<   n%d
|	d<   d|j                  z  |	d<   nd
|	d<   d|z  |	d<   |
rW	 t#        |
||       |
j&                  j(                  d k(  r)d
|	d<   |
j&                  j*                  j,                  |	d<   nd
|	d<   	 t        | |      |	d<   |	S # t        $ r}d
|	d<   t!        |      |	d<   Y d}~d}~ww xY w# t$        $ r}d
|	d<   t!        |      |	d<   Y d}~d}~ww xY w# |
j&                  j(                  d k(  r)d
|	d<   |
j&                  j*                  j,                  |	d<   w d
|	d<   w xY w)!zm
    Set the power status for a VM determined by the current and
    requested states. force is forceful
    present	poweredonr  r  r,  r  F)changedfailed)r  
poweredoffTr  z8Virtual Machine is in %s power state. Force is required!rQ   instanceNr  	restarted)r  
poweringon	resettingr  z6Cannot restart virtual machine in the current state %s	suspended)r  r  z6Cannot suspend virtual machine in the current state %s)shutdownguestrebootguestguestToolsRunningr  r   r  z:VMware tools should be installed for guest shutdown/rebootz>Virtual machine %s must be in poweredon state for guest rebootz'Unsupported expected state provided: %s)r+   r9   rP   )re   rf  r   rd   PowerOffPowerOnResetSuspendr  r  ShutdownGuestr4   wait_for_poweroffRebootGuestrr   r8   r   r_   r   rJ   rK   rP   rQ   )rf   r+   rK   forcerY   r9   rg   expected_statecurrent_staterO   rW   r@   s               r    set_vm_power_stater*  ]  s   
 GR(E	]]3+33C<BBDN+,224MF ]*EExRUbbu,Wb9z &0	'-{{};.zz|;. $ZZ88:D'+F8$$\_l$lF5M;. $??::<D'+F8$$\_l$lF5M#CC K/xx226II)_<#%#3#3#5D&{ &.?G.L M#%>>#3D -1y)+/x((du"l2(-F9%'+F8$$dgigngn$nF5M $(x  IN Zu 
-dr7;
 99??g-'+F8$$(IIOO$7$7F5M(,F9% )"5F:M)  	'#F8#AJF5M	'  +#'x  '
u+ 99??g-'+F8$$(IIOO$7$7F5M(,F9%sD   D&H! :I
 !	I*II
	I0I+&I3 +I00I3 3A	J<c                     t               }d}|dkD  rJ| j                  j                  j                         dk(  r	 |S t	        j
                  |       ||z  }|dkD  rJd|d<   d|d<   |S )Nra   r   r  Tr  z'Timeout while waiting for VM power off.rQ   )rd   r(   r>  r   rH   rV   )r+   rY   rO   rh   s       r    r%  r%    su    VFH
A+::  &&(L8 M 	

88	 A+  xAuMr!   c                 `    	 t        j                  |   |        y# t        t        f$ r Y yw xY w)NTF)r   
vmodlTypes	TypeError
ValueError)ra  type_ofs     r    
is_integerr1    s4    (/z" s    --c                 <    t        |       j                         dv ryy)N)trueonyesfalseoffnoTFrg  r   ra  s    r    
is_booleanr;    s    
5zHHr!   c                 <    t        |       j                         dv ryy)N)r3  r4  r5  TFr9  r:  s    r    	is_truthyr=    s    
5z22r!   c                 J   i }|D ]  }|j                   ||j                  <    g }| j                         D ]  \  }}|r-t        |      r"t	        j
                  d   t        |            }nzt        |t              rt	        j
                  d   |      }nQt        |t              rt	        j
                  d   |      }n(t        |t              rt	        j
                  d   |      }||vs	||   |k7  s|j                  t        j                  j                  ||              |S )Nr  r  r   string)r6   ra  )ra  r6   r  r;  r   r-  r=  r   r  r   rg  r7   r	   optionOptionValue)optionscurrent_optionstruthy_strings_as_boolcurrent_options_dictr@  change_option_list
option_keyoption_values           r    option_diffrI    s   ! 8+1<<VZZ(8 $+MMO b 
L!j&>'226:9\;RSLc*'2259,GLe,'227;LILc*'228<\JL115I*5UYe5e%%cjj&<&<S_&<&`ab r!   c                     | syt        dddd      }|j                         D ]  }|| v s| j                  |||         }  | S )zU
    Replace special characters in object name
    with urllib quote equivalent

    Nz%25z%2fz%5c)%r   \)r   keysrf  )object_nameSPECIAL_CHARSr6   s      r    r|   r|     se     ! M
 !!# G+%--c=3EFKG r!   c                   .    e Zd Z fdZd Zd&dZd'dZd&dZd Zd Z	e
d        Zd&d	Zd&d
Zd Zd&dZd'dZd(dZe
d        Zd Zd&dZd&dZd Zd&dZd&dZd Zd'dZd'dZd&dZd)dZd)dZd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d&d#Z&d$ Z'd% Z( xZ)S )*r\  c           
         || _         t        s |j                  t        d      t               t
        s |j                  t        d      t               	 t        | !  |j                  d   |j                  d   |j                  d   |j                  d   |j                  d   |j                  d	   |j                  d
          |j                  | _	        d | _        g | _        | j                  j                  r&| j                  j                  j                   | _        y y # t        $ r%}|j                  t        |             Y d }~d }~ww xY w)Nr  )rQ   	exceptionr\  r   r  r  r.  r  r  r  )r   r  r  r.  r  http_proxy_hosthttp_proxy_portr  )r  HAS_REQUESTSr  r   REQUESTS_IMP_ERRHAS_PYVMOMIPYVMOMI_IMP_ERRr   r   r  r   rg  current_vm_objcustom_field_mgrrf   r^  r`  )r   r  aaer   s      r    r   zPyVmomi.__init__  s+   !5j!A'7  9 !5i!@'6  8		+GfmmJ&?&,mmJ&?&,mmJ&?"(--"7,2MM:J,K-3]]<-H-3]]<-H  J mm" "<<++$(LL$D$D$J$JD! ,  	+S**	+s   A1D# #	E,EEc                 (   d}	 | j                   j                  j                  }|dk(  ry|dk(  ryy# t        j                  t
        j                  j                  f$ r3}| j                  j                  d|j                  z         Y d}~hd}~ww xY w)z
        Check if given hostname is vCenter or ESXi host
        Returns: True if given connection is with vCenter server
                 False if given connection is with ESXi server

        Nz+Failed to get status of vCenter server : %sr  VirtualCenterT	HostAgentF)rf   aboutapiTyper
   RuntimeFaultr	   r   VimFaultr  r  rQ   )r   api_typeexcs      r    
is_vcenterzPyVmomi.is_vcenter'  s     	_||))11H &$ % ""CII$6$67 	_KK!!&SVYV]V]&]!^^	_s    1 -B)BBc           	          |rT| j                   j                  j                  }t        |      t        dj	                  t        t        |                  k\  S | j                  j                  d|z         y)z
        Check that the vCenter server is at least a specific version number
        Args:
            version (tuple): a version tuple, for example (6, 7, 0)
        Returns: bool
        .z'The passed vCenter version: %s is None.r  N)	rf   r_  rF  r   r   maprg  r  r  )r   rF  
vc_versions      r    vcenter_version_at_leastz PyVmomi.vcenter_version_at_least9  s]     ++33J ,chhs3PWGX>Y0ZZZ"Kg"UVr!   c           
         |r0t        j                   t         j                  t         j                        }|j                  d       |j	                  ||f       d||fz  }|j                  |j                                |j                  d      j                         }|j                         d   dk7  r| j                  j                  d       t        j                         }d|_        t        j                  |_        |j#                  ||      j%                  d	      }	|j'                          n-	 t        j(                  ||f      }
t        j,                  
      }	|	rZt/        t1        j2                  |	      j5                               }dj7                  d t9        |d d d   |dd d         D              S | j                  j                  d|        y # t*        $ r" | j                  j                  d
|        Y w xY w)NrG   zCONNECT %s:%d HTTP/1.0

i    200zFailed to connect to the proxyr  F)server_hostnameTzCannot connect to host: r*  c              3   ,   K   | ]  \  }}||z     y wr   r  ).0abs      r    	<genexpr>z/PyVmomi.get_cert_fingerprint.<locals>.<genexpr>^  s     MdaAEMs   rF   z3Unable to obtain certificate fingerprint for host: )socketAF_INETSOCK_STREAM
settimeoutr   sendencoderecvdecoder   r  r  r  create_default_contextr  r  r  wrap_socketgetpeercertcloseget_server_certificater8   PEM_cert_to_DER_certrg  hashlibsha1	hexdigestr   zip)r   fqdnr.  r  r  sockcommandbufctxder_cert_binpemr?  s               r    get_cert_fingerprintzPyVmomi.get_cert_fingerprintE  s   ==1C1CDDOOALL  7$EGIIgnn&'))D/((*Cyy{1~&%%*J%K,,.C!&C!mmCO??4?FRRSWXLJJLM00$> 33C8Ll3==?@F88Mc&1+vadd|.LMMMKK!!([\`[a&b!c  M%%,DTF*K%LMs   5G (HHc                 l   | j                   j                  }|dg}| j                   j                  j                  ||gd      }t        j
                  j                  j                  dddt        j                  j                        }t        j
                  j                  j                  |d|      }t        j
                  j                  j                  |d|g      }t        j
                  j                  j                  |g|gd	      }| j                   j                  j                  |g      S )
a  
        Look up a Managed Object Reference in vCenter / ESXi Environment
        :param vim_type: Type of vim object e.g, for datacenter - vim.Datacenter
        :param properties: List of properties related to vim object e.g. Name
        :return: local content object
        rr   Ttraversal_specrq   F)rr   rV  skiprm   )rm   allpathSet)rx   r  	selectSet)	objectSetpropSetreportMissingObjectsInResults)rf   rp   rn   ro   r
   queryPropertyCollectorTraversalSpecr	   rq   ContainerViewPropertySpec
ObjectSpec
FilterSpecpropertyCollectorRetrieveContents)	r   vim_type
propertiesroot_foldermorr  property_specobject_specfilter_specs	            r    get_managed_objects_propertiesz&PyVmomi.get_managed_objects_propertiesb  s     ll-- J ll&&::;
TXY 66DD!''	 E 
 55BB C 
 kk33>>%& ? 
 kk33>>"m"O*/ ? 
 ||-->>}MMr!   c                    d}d}| j                   j                  d      xs d}d| j                   v rb| j                   d   rS|s't        | j                  | j                   d   d      }n|rt        | j                  | j                   d   d      }nd| j                   v rI| j                   d   r9| j	                  t
        j                  dg      }g }|D ]i  }t        |j                        d	k(  st        |j                  d
   j                        | j                   d   k(  sO|j                  |j                         k t        |      d	kD  r>| j                   d   | j                   d   -| j                  j                  d| j                   d   z  d       | j                   d   }| j                   d   }t        | j                  | j                   d         }	t!        |	      }
|
j#                  d      s|
dz  }
|dv r-| j                  j                  d| j                   d   z         n|j%                  d      r	|
||}n|}|D ]=  }| j'                  | j                  |      }|j%                  |
|      s6||v s;|} n n|r| j'                  | j                  |d
         }| j                   j                  d      |d
   }n~| j                   d   |v rm|d
   }ngd| j                   v rY| j                   d   rJ t)        j*                  d      | j                   d   | j,                  j.                        }	 t1        |d       |r|| _        |S # t2        j4                  j6                  $ r d}Y ,w xY w)z
        Find unique virtual machine either by UUID, MoID or Name.
        Returns: virtual machine object if found, else None.

        Nuse_instance_uuidFr   r   r   r   rr   r  r  rG   r   rv   r   zMultiple virtual machines with same name [%s] found, try to specify folder and / or datacenter to ensure uniqueness of the virtual machinezIPlease see documentation of the vmware_guest module for folder parameter.)rQ   details)r   r   )Nr  r   ztvmware_guest found multiple virtual machines with same name [%s], please specify folder path other than blank or '/'r  z/vm/)rf   r   r   r   )r  rj  r   rf   r  r	   r   r   r  r   valr7   rx   r  r  r   r   endswithr  r]  r   
templateOfr   _stubr   r
   r   r   rY  )r   vm_objuser_desired_pathr  r   vmstemp_vm_objectuser_folderuser_defined_dcdatacenter_objdcpathr+   actual_vm_folder_paths                r    get_vmzPyVmomi.get_vm  se      KKOO,?@IET[[ T[[%8$&t||4;;v;N[ab"&t||-1[[-@2AC t{{"t{{6':993CUCUcibj9kGC") 3../14 6 6q 9 = =>$++fBUUJJ~1123 3x!|;;x(0DKK4M4UKK)) /CEI[[QWEX/Y3B * C #kk(3"&++l";!8t{{S_G`!a7^L s+cMF/1 KK)) /359[[5H/I) J !++F34:O[(Y% )4% B,0,<,<T\\[],<,^)0;;fo<^_ (,AA!# (,(8(8WZ[\W](8(^%;;??8,4 VF[[*.CC VFt{{"t{{6':>\,,-=>t{{6?RTXT[T[TaTabF' "(D ;;44 s   M N ?N c                 .    t        | j                  |      S )z
        Gather facts of virtual machine.
        Args:
            vm: Name of virtual machine.

        Returns: Facts dictionary of the given virtual machine.

        )re   rf   )r   r+   s     r    gather_factszPyVmomi.gather_facts  s     t||R00r!   c                 2   d}|j                   }|rw|j                  }|j                   }|X|j                  L|| j                  k7  r=|j                  dz   |z   }	 |j                   }||j                  || j                  k7  r=d|z   }|S # t        $ r Y w xY w)z
        Find the path of virtual machine.
        Args:
            content: VMware content object
            vm_name: virtual machine managed object

        Returns: Folder of virtual machine if exists, else None

        Nr   )r   rr   rp   r8   )rf   r   r   rv   fps        r    r]  zPyVmomi.get_vm_path  s      ++KB.RWW%8R7CUCU=U ggmk9B .RWW%8R7CUCU=U +K ! s   B
 
	BBc                 z   d}|s|S d|v r]t         j                  j                  |      }t         j                  j                  |      }t	        | j
                  |d|      }|r|S |S t	        | j
                  |d      }|r|S | j                  t        j                  dg      }g }|D ]X  }t        |j                        d	k7  r|j                  D ].  }|j                  |k(  s|j                  |j                          X Z t        |      d	kD  r!| j                  j                  d
|z         |S |r|d   }|S )a  
        Find the virtual machine or virtual machine template using name
        used for cloning purpose.
        Args:
            template_name: Name of virtual machine or virtual machine template

        Returns: virtual machine or virtual machine template object

        Nr   r   )r   rv   r   r  rr   r  rG   zAMultiple virtual machines or templates with same name [%s] found.r  r   )rU  rV  rW  basenamer   rf   r  r	   r   r   r  r  r7   rx   r  r  )	r   template_nametemplate_objvm_obj_pathvm_obj_namer   	templatesr  temp_vm_object_propertys	            r    get_vm_or_templatezPyVmomi.get_vm_or_template  sO    -''//-8K''**=9K({O_hstL##. + )]W]^L##993CUCUcibj9kGI") ~--.!3/=/E/E +.22mC!((););< 9~!%%*mp}*}%~  (|r!   c                 2    t        | j                  ||      S )z
        Find Cluster by name in given datacenter
        Args:
            cluster_name: Name of cluster name to find
            datacenter_name: (optional) Name of datacenter

        Returns: True if found

        r  )r   rf   )r   r   r   s      r    r   zPyVmomi.find_cluster_by_nameE  s     $DLL,?[[r!   c                 X    | j                  |      }|rt        |j                        S g S )z
        Get all hosts from cluster by cluster name
        Args:
            cluster_name: Name of cluster

        Returns: List of hosts

        r   )r   r   r   )r   r   cluster_objs      r    get_all_hosts_by_clusterz PyVmomi.get_all_hosts_by_clusterQ  s0     //\/J(())Ir!   c                 2    t        | j                  ||      S )z
        Find Host by name
        Args:
            host_name: Name of ESXi host
            datacenter: (optional) Datacenter of ESXi resides

        Returns: True if found

        )r   r   )r   rf   )r   r  r   s      r    r   zPyVmomi.find_hostsystem_by_namea  s     't||iT^__r!   c                 4   g }| j                         sTt        | j                  t        j                  g      j                         }|r|j                  t        |      d          |S |rM| j                  |      }|rt        |j                        }|S | j                  j                  dd|z         |S |r`t        |t              r|g}|D ]H  }| j                  |      }|r|j                  |       )| j                  j                  dd|z         J |S )z
        Get all host system managed object

        Args:
            cluster_name: Name of Cluster
            esxi_host_name: Name of ESXi server

        Returns: A list of all host system managed objects, else empty list

        r   r  FzCluster '%s' not found)r  rQ   r  zESXi '%s' not found)re  r   rf   r	   r   rM  r7   r   r   r   r  r  r   rg  r   )r   r   esxi_host_namehost_obj_listhostsr  r   esxi_host_objs           r    get_all_host_objszPyVmomi.get_all_host_objsm  s!      /?@EEGE$$T%[^4& # "77\7R$()9)9$:M  KK))%=UXd=d)e   nc2&4%5N* _D$($@$@4$@$PM$%,,];--eAVY]A]-^_ r!   c           	         |r!|j                   j                  j                  }n1|r| j                  |      }n| j                  j                  d       r`|r^|j                   j                  j                  j                  }t        |      t        dj                  t        t        |                  k\  S | j                  j                  d|d|d|d       y	)
a5  
        Check that the ESXi Host is at least a specific version number
        Args:
            vm_obj: virtual machine object, required one of vm_obj, host_name
            host_name (string): ESXi host name
            version (tuple): a version tuple, for example (6, 7, 0)
        Returns: bool
        r  z,VM object or ESXi host name must be set one.r  rg  z%Unable to get the ESXi host from vm: z, or hostname z,or the passed ESXi version: z	 is None.N)r6  r(   r   r   r  r  r   productrF  r   r   rh  rg  )r   rF  r  r  host_systemhost_versions         r    host_version_at_leastzPyVmomi.host_version_at_least  s      ..0055K666KKKK!!&T!U7&..55==EEL .-SRYIZ@[2\\\KK!!SY[dfm'o! pr!   c                     | j                   j                  j                  D ]  }|j                  j                  |k(  s|c S  y)z
        Find Portgroup on given host
        Args:
            host: Host config object
            portgroup_name: Name of portgroup

        Returns: True if found else False

        Fr   r   s      r    r   z#PyVmomi.find_host_portgroup_by_name  s@     ,,66 	!I~~""n4  	! r!   c                 v    g }|j                   j                  j                  D ]  }|j                  |        |S )z
        Get all Port Group by host
        Args:
            host_system: Name of Host System

        Returns: List of Port Group Spec
        )r   r   r}   r7   )r   r  pgs_listr   s       r    get_all_port_groups_by_hostz#PyVmomi.get_all_port_groups_by_host  s;     $$,,66 	 BOOB	 r!   c                    g }|s|S | j                  t        j                  dg      }|D ]X  }t        |j                        dk7  r|j                  D ].  }|j
                  |k(  s|j                  |j                          X Z |S )z
        Get network specified by name
        Args:
            network_name: Name of network

        Returns: List of network managed objects
        rr   r  rG   )r  r	   r   r   r  r  r7   rx   )r   r   networksr   r  r  s         r    r   zPyVmomi.find_network_by_name  s     O55s{{X^W_5`% 	N>))*a/+9+A+A '*..,>OON$6$67	 r!   c                 B    d}|s|S | j                  |      rd}|S d}|S )z
        Check if network with a specified name exists or not
        Args:
            network_name: Name of network

        Returns: True if network exists else False
        F)r   T)r   )r   r   rets      r    network_exists_by_namezPyVmomi.network_exists_by_name  s9     J//\/Jd
 QV
r!   c                 0    t        | j                  |      S )z
        Get datacenter managed object by name

        Args:
            datacenter_name: Name of datacenter

        Returns: datacenter managed object if found else None

        )r   )r   rf   )r   r   s     r    r   zPyVmomi.find_datacenter_by_name  s     't||_UUr!   c                 h    |r/|j                   j                  dk7  s|j                   j                  syy)z
        Check if datastore selected is valid or not
        Args:
            datastore_obj: datastore managed object

        Returns: True if datastore is valid, False if not
        normalFT)r6  maintenanceMode
accessible)r   datastore_objs     r    is_datastore_validzPyVmomi.is_datastore_valid  s0     ##33x?''22r!   c                 2    t        | j                  ||      S )a  
        Get datastore managed object by name
        Args:
            datastore_name: Name of datastore
            datacenter_name: Name of datacenter where the datastore resides.  This is needed because Datastores can be
            shared across Datacenters, so we need to specify the datacenter to assure we get the correct Managed Object Reference

        Returns: datastore managed object if found else None

        )r   r   )r   rf   )r   r   r   s      r    r   zPyVmomi.find_datastore_by_name  s     &dll>crssr!   c                 0    t        | j                  |      S )z
        Get vm folder managed object by name
        Args:
            folder_name: Name of the vm folder

        Returns: vm folder managed object if found else None

        )r   )r   rf   )r   r   s     r    r   zPyVmomi.find_folder_by_name  s     #4<<[IIr!   c                 4    t        | j                  |||      S )a  
        Get a unique folder managed object by specifying its Fully Qualified Path Name
        as datacenter/folder_type/sub1/sub2
        Args:
            folder_name: Fully Qualified Path Name folder name
            datacenter_name: Name of the datacenter, taken from Fully Qualified Path Name if not defined
            folder_type: Type of folder, vm, host, datastore or network,
                         taken from Fully Qualified Path Name if not defined

        Returns: folder managed object if found, else None

        )r   r   r   )r   rf   )r   r   r   r   s       r    r   zPyVmomi.find_folder_by_fqpn  s%     #4<<[Zi  xC  D  	Dr!   c                     |rt        |d      r|j                  }|s| j                  j                  }t	        | j                  t
        j                  g|      }|D ]  }|j                  |k(  s|c S  y)aQ  
        Get datastore cluster managed object by name
        Args:
            datastore_cluster_name: Name of datastore cluster
            datacenter: Managed object of the datacenter
            folder: Managed object of the folder which holds datastore

        Returns: Datastore cluster managed object if found else None

        datastoreFolderr   N)r)   r  rf   rp   r   r	   
StoragePodrr   )r   datastore_cluster_namer   rv   data_store_clustersdscs         r    find_datastore_cluster_by_namez&PyVmomi.find_datastore_cluster_by_name.  so     '*.?@//F\\,,F*4<<#..9IRXY& 	Cxx11
	 r!   c                    |y|j                   j                  j                  j                  }|rt        j
                  j                         }||_        t        j
                  j                         }||_	        d|_
        	 | j                  j                  j                  |      }|j                  d   j                  d   }|j                   j"                  S d}d}|j&                  D ]b  }	t)        |	t        j*                        s|	j,                  j.                  |kD  s8| j1                  |	      sK|	}|	j,                  j.                  }d |r|j"                  S y# t$        $ r Y w xY w)z
        Return Storage DRS recommended datastore from datastore cluster
        Args:
            datastore_cluster_obj: datastore cluster managed object

        Returns: Name of recommended datastore from the given datastore cluster

        Ncreate)storageSpecr   )r  )podStorageDrsEntrystorageDrsConfig	podConfigr  r	   
storageDrsPodSelectionSpec
storagePodStoragePlacementSpecpodSelectionSpecrm   rf   storageResourceManagerRecommendDatastoresrecommendationsactiondestinationrr   r8   r   r   r   r6  	freeSpacer  )
r   datastore_cluster_objsdrs_statuspod_sel_specstorage_specrec
rec_actionr   datastore_freespacerp  s
             r    get_recommended_datastorez!PyVmomi.get_recommended_datastoreD  sJ    !(+>>OOYYaa>>::<L&;L#>>>>@L,8L) (Lll99MMZfMg 003::1=
!--222 	'33 	;B"cmm,1E1EH[1[..R.@	&(jj&:&:#	; >>!  s   AE 	E*)E*c                     |s| j                   j                  }t        | j                   t        j                  g|      }|D ]  }|j
                  |k(  s|c S  y)z
        Get resource pool managed object by name
        Args:
            resource_pool_name: Name of resource pool

        Returns: Resource pool managed object if found else None

        r   N)rf   rp   r   r	   r   rr   )r   r   rv   resource_poolsrps        r    r   z"PyVmomi.find_resource_pool_by_nameo  sW     \\,,F%dllS5E5E4FvV  	Bww,,		 r!   c                     d}|s|S |dk7  r5|j                   j                   }|r|D ]  }|j                  |k(  s|} |S  |S |j                   }|S )z
        Get resource pool managed object by cluster object
        Args:
            resource_pool_name: Name of resource pool
            cluster: Managed object of cluster

        Returns: Resource pool managed object if found else None

        N	Resources)resourcePoolrr   )r   r   r   
desired_rpr  r  s         r    r   z%PyVmomi.find_resource_pool_by_cluster  su     
,$11>>N( Bww"44%'
   !--Jr!   c           	         	 t        j                  d|t         j                        j                         d   }t        j                  d|      j                         d   }t        j
                  j                  |      }t        j
                  j                  |      }||||fS # t        t        f$ r5}| j                  j                  d|dt        |             Y d}~yd}~ww xY w)a  
        Takes a string in the format

            [datastore_name] path/to/vm_name.vmdk

        Returns a tuple with multiple strings:

        1. datastore_name: The name of the datastore (without brackets)
        2. vmdk_fullpath: The "path/to/vm_name.vmdk" portion
        3. vmdk_filename: The "vm_name.vmdk" portion of the string (os.path.basename equivalent)
        4. vmdk_folder: The "path/to/" portion of the string (os.path.dirname equivalent)
        z
^\[(.*?)\]r   z\[.*?\] (.*)$z
Bad path 'z ' for filename disk vmdk image: r  N)rematchDOTALLgroupsrU  rV  r  rW  r   rR   r  r  r   )r   	vmdk_pathr   vmdk_fullpathvmdk_filenamevmdk_folderr@   s          r    vmdk_disk_path_splitzPyVmomi.vmdk_disk_path_split  s    	tXXmY		JQQSTUVNHH%5yAHHJ1MMGG,,];M''//-8K!=-LLN+ 	tKK!!Zcenopeq&r!ss	ts   B B# #C'2+C""C'c                 b   |j                   }|j                  }d|z   dz   }|| j                  j                  d|z         t        j
                  j                  j                  j                  dddd      }t        j
                  j                  j                  ||gd      }	|j                  ||		      }
d
}|dz   |z   }	 t        |
      \  }}|s| j                  j                  d|z         |dz   |z   dz   |dz   |z   g}|
j                  j                  D ]7  }t!        |d      D ]&  }|j"                  |k(  s|j$                  |v s"|c c S  9 | j                  j                  d|z         y# t        $ r/}| j                  j                  t        |             Y d}~d}~ww xY w)aF  
        Return vSphere file object or fail_json
        Args:
            datastore_obj: Managed object of datastore
            vmdk_fullpath: Path of VMDK file e.g., path/to/vm/vmdk_filename.vmdk
            vmdk_filename: Name of vmdk e.g., VM0001_1.vmdk
            vmdk_folder: Base dir of VMDK e.g, path/to/vm

        []Nz)Unable to access browser for datastore %sr  T)	fileOwnerfileSizefileTypemodification)r  matchPatternsearchCaseInsensitive)datastorePath
searchSpecFr  z*No valid disk vmdk image found for path %sr   filez*No vmdk file found for path specified [%s])browserrr   r  r  r	   r   DatastoreBrowserFileInfoDetails
SearchSpecSearchSubFoldersr_   r   r   rJ   rO   r   rV  
folderPath)r   r  r  r  r  r)  r   datastore_name_sqdetail_querysearch_spec
search_resr  r  rO   task_etarget_folder_pathsfile_resultrv  s                     r    find_vmdk_filezPyVmomi.find_vmdk_file  s     ''&++.036?KK!!&QTb&b!cxx0099AA	 B 
 hh//:: '"& ; 

 --+" . 


 %+m;		9+J7OGV KK!!&RU^&^!_ #k1C7#k1

 &??11 	K[&1 66]*{/E/EI\/\H	
 	"NQZ"Z[!  	9KK!!i&7!88	9s   E6 6	F.?%F))F.c                    | j                         rn| j                  j                  j                  |      D ]E  }| j                  j                  j	                  ||      }|j
                  j                  |k(  sC|c S  y| j                  j                  j                  |      D ]E  }| j                  j                  j                  ||      }|j
                  j                  |k(  sC|c S  y)z
        Get first-class disk managed object by name
        Args:
            disk_name: Name of the first-class disk
            datastore_obj: Managed object of datastore

        Returns: First-class disk managed object if found else None

        N)	re  rf   vStorageObjectManagerListVStorageObjectRetrieveVStorageObjectr   rr   HostListVStorageObjectHostRetrieveVStorageObject)r   	disk_namer  r/   rZ  s        r    find_first_class_disk_by_namez%PyVmomi.find_first_class_disk_by_name  s     ??ll88KKMZ  ||99PPQSUbc;;##y0K   ll88OOP]^  ||99TTUWYfg;;##y0K 
 r!   c                    g }| j                         r`| j                  j                  j                  |      D ]7  }|j	                  | j                  j                  j                  ||             9 n_| j                  j                  j                  |      D ]7  }|j	                  | j                  j                  j                  ||             9 |g k(  ry|S )z
        Get first-class disks managed object
        Args:
            datastore_obj: Managed object of datastore

        Returns: First-class disks managed object if found else None

        N)re  rf   r9  r:  r7   r;  r<  r=  )r   r  disksr/   s       r    find_first_class_diskszPyVmomi.find_first_class_disks  s     ??ll88KKMZ kT\\??VVWY[hijk ll88OOP]^ oT\\??ZZ[]_lmno B;Lr!   c                     t        |      D ]J  \  }}t        |t        j                        r&| j	                  |j                  |i       |      ||<   F|||<   L |S )a  
        Deep merges u into d.

        Credit:
          https://bit.ly/2EDOs1B (stackoverflow question 3232943)
        License:
          cc-by-sa 3.0 (https://creativecommons.org/licenses/by-sa/3.0/)
        Changes:
          using collections_compat for compatibility

        Args:
          - d (dict): dict to merge into
          - u (dict): dict to merge into d

        Returns:
          dict, with u merged into d
        )r   r   collections_compatMapping
_deepmergerj  )r   dur  r  s        r    rF  zPyVmomi._deepmerge  sZ    $ aL 	DAq!/778quuQ|Q7!!		
 r!   c                 B   t               }d|vr
||   ||<   |S |j                  dd      \  }}t        |t              rIg }t	        t        |            D ])  }|j                  | j                  ||   |   |             + |||<   |S | j                  ||   |      ||<   |S )z
        This is used to break down dotted properties for extraction.

        Args:
          - data (dict): result of _jsonify on a property
          - remainder: the remainder of the dotted property to select

        Return:
          dict
        rg  rG   )rd   r   r   r   ranger   r7   _extract)r   r  	remainderrO   r6   temp_dsis          r    rK  zPyVmomi._extract7  s     i $YF9M"a0YdD!G3t9% Gt}}T!WS\9EFG!F3K  --S	9=F3Kr!   c                 v    t        j                  t        j                  |t        j                  dd            S )z
        Convert an object from pyVmomi into JSON.

        Args:
          - obj (object): vim object

        Return:
          dict
        Tr  )rG  rH  rI  r   rJ  )r   rx   s     r    _jsonifyzPyVmomi._jsonifyP  s2     zz$**Sl.K.K/34I J 	Jr!   c           	      D   t               }|r|D ]  }	 d|v r`|j                  dd      \  }}t               }| j                  | j                  t	        ||            |      ||<   | j                  ||       nS| j                  t	        ||            ||<   |}|j                         dk(  rd}n|j                         dk(  rd}||   ||<    |S | j                  |      }|S # t        t        f$ r/ | j                  j                  dj                  |             Y w xY w)	a|  
        Convert a vSphere (pyVmomi) Object into JSON.  This is a deep
        transformation.  The list of properties is optional - if not
        provided then all properties are deeply converted.  The resulting
        JSON is sorted to improve human readability.

        Args:
          - obj (object): vim object
          - properties (list, optional): list of properties following
                the property collector specification, for example:
                ["config.hardware.memoryMB", "name", "overallStatus"]
                default is a complete object dump, which can be large

        Return:
          dict
        rg  rG   _moidr   _vimrefr%  zProperty '{0}' not found.r  )rd   r   rK  rP  r   rF  r   rR   KeyErrorr  r  format)	r   rx   r  rO   propr6   rL  tmp	prop_names	            r    to_jsonzPyVmomi.to_json]  s#   " " XXd{)-C);Y"f#'==wsC?P1QS\#]C4'+}}WS$5G'Ht$(	::<72(.I!ZZ\Y6(0I,24Ly)X(  ]]3'F	 '1 XKK)).I.P.PQU.V)WXs   B7C!!:DDc                    d|j                   z   }t        |d      ri|j                  r]|j                  | j                  j                  k(  r	 |S |j                  }d|j                   z   |z   }t        |d      r|j                  r]|S )Nr   r   )rr   r)   r   rf   rp   )r   cur	full_paths      r    get_folder_pathzPyVmomi.get_folder_path  sw    #((N	c8$zzT\\444  **Cchh2I	 c8$
 r!   c                      t        j                  |      || j                  j                        }	 t	        |d       |S # t
        j                  j                  $ r d}Y |S w xY w)aG  
        Get Managed Object based on an object type and moid.
        If you'd like to search for a virtual machine, recommended you use get_vm method.

        Args:
          - object_type: Managed Object type
                It is possible to specify types the following.
                ["Datacenter", "ClusterComputeResource", "ResourcePool", "Folder", "HostSystem",
                 "VirtualMachine", "DistributedVirtualSwitch", "DistributedVirtualPortgroup", "Datastore"]
          - moid: moid of Managed Object
        :return: Managed Object if it exists else None
        rr   N)r   r  r   r  r   r
   r   r   )r   object_typer   rx   s       r    find_obj_by_moidzPyVmomi.find_obj_by_moid  s`     3l%%k24G	C  
 {{00 	C
	s   A   A#"A#r   NN)NNNr  N)*r"   r#   r$   r   re  rj  r  r  r  r  staticmethodr]  r  r   r  r   r  r  r   r  r   r  r   r  r   r   r   r  r  r   r   r  r7  r?  rB  rF  rK  rP  rY  r]  r`  r%   r&   s   @r    r\  r\    s    K4$
Wd:-N`_B	1  2*Z
\ 
`"Hp.  0
Vt	JD ,(V$8t,5\n0822J'Rr!   r\  )@   i  NN)i,  )TN)NTr   ra  rb  )r   NNNF)	TFNNNNNNN)r   N)r  )T)erm   __metaclass__r  /ansible.module_utils.common._collections_compatmodule_utilscommon_collections_compatrD  rG  rU  r  rs  r  r  rH   	tracebackr  collectionsr   #ansible.module_utils.compat.versionr   Iansible_collections.community.vmware.plugins.module_utils.clients._vmwarer   r   randomr   rV  r  rU  ImportError
format_excrX  pyVimr   pyVmomir	   r
   r   rW  ansible.module_utils._textr   r   ansible.module_utils.sixr   r   r   r   ansible.module_utils.basicr   +ansible.module_utils.six.moves.urllib.parser   Hansible_collections.community.vmware.plugins.module_utils._argument_specr   r8   r   r,   r=   rA   r_   rj   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  re   r  r  r  r  rk  rl  r  r  r   r  r  r*  r%  r1  r;  r=  rI  r|   r\  r  r!   r    <module>rx     s     L L  	 	  
     # = s   L
 00K
 : W W ; ? g9	 9
>>'!T ""cKZC,^dSP`V[ DH9>$Ng!,]@<&$  LP59d.N2j[|,*Wm WW  +y++-L  *i**,OKs$   E E, E)(E),FF