o
    x[hO3  ã                   @   s  d 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Zddlm	Z	m
Z
mZ e e¡ZG dd„ de	jƒZG dd„ deƒZd#d
d„Zdd„ Zdd„ Zd$dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd„ deƒZee	jffee	je	jfffZdd „ Z d!d"„ Z!dS )%zZCloud-Init DataSource for OVF

This module provides a cloud-init datasource for OVF data.
é    N)Úminidom)ÚsourcesÚsubpÚutilc                   @   sL   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	e
dd„ ƒZdS )ÚDataSourceOVFÚOVFc                 C   sF   t j | |||¡ d | _tj |jd¡| _d | _i | _	d| _
d | _d S )NÚovf)ú/zfile://)r   Ú
DataSourceÚ__init__ÚseedÚosÚpathÚjoinÚseed_dirÚenvironmentÚcfgÚsupported_seed_startsÚ_network_config©ÚselfÚsys_cfgÚdistroÚpaths© r   úA/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceOVF.pyr       s   
zDataSourceOVF.__init__c                 C   s   t j | ¡}d|| jf S )Nz%s [seed=%s])r   r
   Ú__str__r   )r   Úrootr   r   r   r   )   s   zDataSourceOVF.__str__c                 C   s”  g }i }d}d}ddi}t | jjƒ\}}|r/tj | jj|¡}t|ƒ\}}}	|| _| |¡ n7dt	fdt
fg}
d }|
D ]\}}|ƒ }|rF nq;|rft|dƒ\}}}	|| _d|v ra|d ra|d | _| |¡ |sjdS d	|v r¯|d	 r¯|d	 }d}| jD ]}| |¡r†|} nq{|s’t d
|| ¡ dS tj|d d�\}}}}t d|¡ t ||g¡}| |¡ t ||g¡}d |¡| _|| _|| _|| _|	| _dS )NÚ úinstance-idz	iid-dsovfzcom.vmware.guestInfoÚisoTúnetwork-configFÚseedfromz Seed from %s not supported by %s)ÚtimeoutzUsing seeded cache data from %sú,)Úget_ovf_envr   r   r   r   r   Úread_ovf_environmentr   ÚappendÚtransport_vmware_guestinfoÚtransport_iso9660r   r   Ú
startswithÚLOGÚdebugr   Úread_seededÚmergemanydictr   ÚmetadataÚuserdata_rawÚvendordata_rawr   )r   ÚfoundÚmdÚudÚvdÚdefaultsÚseedfileÚcontentsr   r   ÚnpÚnameÚ	transfuncr"   Ú	seedfoundÚprotoÚmd_seedÚ_r   r   r   Ú	_get_data-   sf   ÿþÿ



þ
zDataSourceOVF._get_datac                 C   s
   d| j  S )Nzovf (%s))r   ©r   r   r   r   Ú_get_subplatformo   s   
zDataSourceOVF._get_subplatformc                 C   s,   d| j vrg S | j d }t|tƒr|S |gS )Núpublic-keys)r/   Ú
isinstanceÚlist)r   Úpksr   r   r   Úget_public_ssh_keysr   s   


z!DataSourceOVF.get_public_ssh_keysc                 C   ó   | j S ©N)r   rA   r   r   r   Úget_config_obj~   s   zDataSourceOVF.get_config_objc                 C   rH   rI   )r   rA   r   r   r   Únetwork_config�   s   zDataSourceOVF.network_configN)Ú__name__Ú
__module__Ú__qualname__Údsnamer   r   r@   rB   rG   rJ   ÚpropertyrK   r   r   r   r   r      s    	Br   c                   @   s   e Zd Zdd„ ZdS )ÚDataSourceOVFNetc                 C   s,   t  | |||¡ tj |jd¡| _d| _d S )Nzovf-net)zhttp://zhttps://)r   r   r   r   r   r   r   r   r   r   r   r   ‡   s   
zDataSourceOVFNet.__init__N)rL   rM   rN   r   r   r   r   r   rQ   †   s    rQ   Fc              	   C   sø   t | ƒ}i }i }d }dg}g d¢}dg}| ¡ D ]^\}	}
|	dkr"d}	|	|v r+|
||	< q|	|v r4|
||	< q|	|v r[|r[zt |
 ¡ ¡}t|ƒ d¡||	< W q tyZ   t 	d¡ Y qw |	dkrvz	t |
 ¡ ¡}W q tyu   |
 ¡ }Y qw q|||fS )	NÚpassword)r"   úlocal-hostnamerC   r   r!   ÚhostnamerS   Únetworkz%Ignore network-config in wrong formatz	user-data)
Úget_propertiesÚitemsÚbase64Ú	b64decodeÚencodeÚsafeload_yaml_or_dictÚgetÚ	Exceptionr+   r,   )r8   Úread_networkÚpropsr3   r   r4   Ú	cfg_propsÚmd_propsÚnetwork_propsÚpropÚvalrK   r   r   r   r&   �   s:   

ÿÿý
r&   c              	   C   sf   d}|D ],}t j | |¡}t j |¡r0zt |¡}||fW   S  ty/   t td|¡ Y qw qdS )N)zovf-env.xmlzovf_env.xmlzOVF_ENV.XMLzOVF-ENV.XMLzFailed loading ovf file %s)NF)	r   r   r   Úisfiler   Úload_text_filer]   Úlogexcr+   )ÚdirnameÚ	env_namesÚfnameÚfull_fnr8   r   r   r   r%   ®   s   
ÿür%   c                 C   s    | sdS t | tƒstd|  ƒ‚tj | ¡} |  d¡r!|  d¡d } |  d¡r.|  d¡d } n	|  	d¡dkr7dS | s;dS d}tj
 d|¡}t |¡}| | ¡d	uS )
zûTest if devname matches known list of devices which may contain iso9660
       filesystems.

    Be helpful in accepting either knames (with no leading /dev/) or full path
    names, but do not allow paths outside of /dev/, like /dev/foo/bar/xxx.
    Fz Unexpected input for devname: %sz/dev/éÿÿÿÿr	   r   z^(sr[0-9]+|hd[a-z]|xvd.*)ÚCLOUD_INIT_CDROM_DEV_REGEXN)rD   ÚstrÚ
ValueErrorr   r   Únormpathr*   Ú	partitionÚsplitÚcountÚenvironr\   ÚreÚcompileÚmatch)ÚdevnameÚdefault_regexÚdevname_regexÚcdmatchr   r   r   Úmaybe_cdrom_device»   s"   



r|   Tc           
   	   C   sä   t  ¡ }| ¡ D ]&\}}|d }|dkr| rqt|ƒsq|d }t|ƒ\}}|dur.|  S q| r4d}nd }dd„ t  |rAd| nd ¡D ƒ}	|	D ]'}zt j|t|d�\}}W n t jyf   t 	d	|¡ Y qHw |duro|  S qHd S )
NÚfstypeÚiso9660Ú
mountpointFc                 S   s   g | ]}t |ƒr|‘qS r   )r|   )Ú.0Údevr   r   r   Ú
<listcomp>ø   s    ýÿz%transport_iso9660.<locals>.<listcomp>zTYPE=%s)Úmtypez%s not mountable as iso9660)
r   ÚmountsrW   r|   r%   Úfind_devs_withÚmount_cbÚMountFailedErrorr+   r,   )
Úrequire_isor„   r�   Úinfor}   ÚmpÚ_fnamer8   rƒ   Údevsr   r   r   r)   ä   s:   ÿþþÿr)   c                 C   s    | |g}t   |¡\}}|||fS rI   ©r   ©ÚrpctoolÚargÚcmdÚstdoutÚstderrr   r   r   Úexec_vmware_rpctool
  s   
r”   c                 C   s"   | d|g}t   |¡\}}|||fS )Nz--cmdr�   rŽ   r   r   r   Úexec_vmtoolsd  s   

r•   c                  C   sT  d\} }t  d¡}t  d¡}|r|t} }t d|¡ |r*|s$|t} }t d|¡ | s3t d¡ d S dd„ }z|| |ƒW S  t jy© } z_|r_| |kr_|jd	krXt 	td
|¡ W Y d }~d S |smt 
d¡ W Y d }~d S zt 
d¡ ||tƒW W  Y d }~S  t jy� } z|jd	kr“t 	td
|¡ W Y d }~nd }~ww W Y d }~d S d }~ww )N)NNÚvmtoolsdzvmware-rpctoolzdiscovered vmware-rpctool: %szdiscovered vmtoolsd: %szno rpctool discoveredc              
   S   sr   t  d| ¡ z|| dƒ\}}}|r|W S t  d|¡ W d S  tjy8 } z|jdkr2t  d| |j¡ |‚d }~ww )Nzquery guestinfo.ovfEnv with %szinfo-get guestinfo.ovfEnvz!cmd %s exited 0 with empty stdouté   z%s exited with code %d)r+   r‰   r,   r   ÚProcessExecutionErrorÚ	exit_codeÚwarning)r�   Ú
rpctool_fnr‘   r’   r?   Úerrorr   r   r   Úquery_guestinfo-  s   
€ýz3transport_vmware_guestinfo.<locals>.query_guestinfor—   z+vmtoolsd failed to get guestinfo.ovfEnv: %sz$vmtoolsd fallback option not presentzfallback to vmtoolsd)r   Úwhichr”   r+   r,   r•   r˜   r™   r   rg   r‰   )r�   r›   r–   Úvmware_rpctoolr�   rœ   r   r   r   r(     sP   





ÿ


ÿ€ý
€€är(   c                 C   s2   g }|   ¡ s|S | jD ]}||ƒr| |¡ q|S rI   )ÚhasChildNodesÚ
childNodesr'   )ÚnodeÚfilter_funcÚretÚchildr   r   r   Ú
find_child]  s   

€r¦   c           	      C   sœ   t  | ¡}|jjdkrtdƒ‚|j ¡ stdƒ‚d}t|jdd„ ƒ}|s(tdƒ‚i }t|d d	d„ ƒ}|D ]}|j |d
¡j	}|j |d¡j	}|||< q5|S )NÚEnvironmentzNo Environment NodezNo Child Nodesz)http://schemas.dmtf.org/ovf/environment/1c                 S   ó
   | j dkS )NÚPropertySection©Ú	localName©Únr   r   r   Ú<lambda>t  ó   
 z get_properties.<locals>.<lambda>zNo 'PropertySection'sr   c                 S   r¨   )NÚPropertyrª   r¬   r   r   r   r®   |  r¯   ÚkeyÚvalue)
r   ÚparseStringÚdocumentElementr«   ÚXmlErrorr    r¦   Ú
attributesÚgetNamedItemNSr²   )	r8   ÚdomÚenvNsURIÚpropSectionsr_   Ú	propElemsÚelemr±   rd   r   r   r   rV   g  s(   


ÿÿ
rV   c                   @   s   e Zd ZdS )rµ   N)rL   rM   rN   r   r   r   r   rµ   ‡  s    rµ   c                 C   s   t  | t¡S rI   )r   Úlist_from_dependsÚdatasources)Údependsr   r   r   Úget_datasource_list“  s   rÀ   c                 C   s   | si S t  | ¡S )z¶
    The meta data could be JSON or YAML. Since YAML is a strict superset of
    JSON, we will unmarshal the data as YAML. If data is None then a new
    dictionary is returned.
    )ÚyamlÚ	safe_load)Údatar   r   r   r[   —  s   
r[   )F)T)"Ú__doc__rX   Úloggingr   ru   Úxml.domr   rÁ   Ú	cloudinitr   r   r   Ú	getLoggerrL   r+   r
   r   rQ   r&   r%   r|   r)   r”   r•   r(   r¦   rV   r]   rµ   ÚDEP_FILESYSTEMÚDEP_NETWORKr¾   rÀ   r[   r   r   r   r   Ú<module>   s4   

i
	
)&G
 
þ