U
    Ӈg2                     @   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 )DataSourceOVFZOVFc                 C   sF   t j| ||| d | _tj|jd| _d | _i | _	d| _
d | _d S )NZovf)/zfile://)r   
DataSource__init__seedospathjoinseed_direnvironmentcfgsupported_seed_starts_network_configselfZsys_cfgZ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|\}}}	|| _|| nndt	fdt
fg}
d }|
D ]\}}| }|rv qqv|rt|d\}}}	|| _d|kr|d r|d | _|| t|dkrd	S d
|krr|d
 rr|d
 }d	}| jD ]}||r|} q q|s8td||  d	S tj|d d\}}}}td| t||g}|| t||g}d|| _|| _|| _|| _|	| _dS )N instance-idz	iid-dsovfzcom.vmware.guestInfoZisoTnetwork-configr   Fseedfromz Seed from %s not supported by %s)ZtimeoutzUsing seeded cache data from %s,)get_ovf_envr   r   r   r   r   read_ovf_environmentr   appendtransport_vmware_guestinfotransport_iso9660r   lenr   
startswithLOGdebugr   Zread_seededZmergemanydictr
   metadataZuserdata_rawZvendordata_rawr   )r   foundmdudZvddefaultsZseedfilecontentsr
   r   ZnpnameZ	transfuncr   Z	seedfoundprotoZmd_seed_r   r   r   	_get_data-   sd     




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   s0   d| j krg S | j d }t|tr&|S |gS d S )Npublic-keys)r(   
isinstancelist)r   Zpksr   r   r   get_public_ssh_keysr   s    


z!DataSourceOVF.get_public_ssh_keysc                 C   s   | j S N)r   r2   r   r   r   get_config_obj~   s    zDataSourceOVF.get_config_objc                 C   s   | j S r8   )r   r2   r   r   r   network_config   s    zDataSourceOVF.network_configN)__name__
__module____qualname__Zdsnamer	   r   r1   r3   r7   r9   propertyr:   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)r;   r<   r=   r	   r   r   r   r   r?      s   r?   Fc              	   C   s  t | }i }i }d }dg}ddddg}dg}| D ]\}	}
|	dkrHd}	|	|krZ|
||	< q4|	|krl|
||	< q4|	|kr|rz$t|
 }t|d||	< W q tk
r   t	d	 Y qX q4|	d
kr4zt|
 }W q4 tk
r   |
 }Y q4X q4|||fS )NZpasswordr   zlocal-hostnamer4   r   r   ZhostnameZnetworkz%Ignore network-config in wrong formatz	user-data)
get_propertiesitemsbase64Z	b64decodeencodesafeload_yaml_or_dictget	Exceptionr&   r'   )r-   Zread_networkpropsr*   r   r+   Z	cfg_propsZmd_propsZnetwork_propsZpropvalr:   r   r   r   r       s4    

r    c              	   C   sh   d}|D ]Z}t j| |}t j|rzt|}||fW   S  tk
r`   ttd| Y qX 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   Zload_text_filerF   logexcr&   )dirnameZ	env_namesfnameZfull_fnr-   r   r   r   r      s    
r   c                 C   s   | sdS t | tstd|  tj| } | drB| dd } | dr\| dd } n| 	ddkrndS | svdS d}tj
d|}t|}|| d	k	S )
zTest 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.*)ZCLOUD_INIT_CDROM_DEV_REGEXN)r5   str
ValueErrorr   r   normpathr%   	partitionsplitcountenvironrE   recompilematch)ZdevnameZdefault_regexZdevname_regexZcdmatchr   r   r   maybe_cdrom_device   s"    



rX   Tc           
   	   C   s   t  }| D ]L\}}|d }|dkr.| r.qt|s8q|d }t|\}}|dk	r|  S q| rhd}nd }dd t |rd| nd D }	|	D ]T}zt j|t|d\}}W n& t jk
r   t	d	| Y qY nX |dk	r|  S qd S )
NfstypeZiso9660Z
mountpointFc                 S   s   g | ]}t |r|qS r   )rX   ).0devr   r   r   
<listcomp>   s   z%transport_iso9660.<locals>.<listcomp>zTYPE=%s)mtypez%s not mountable as iso9660)
r   mountsrA   rX   r   Zfind_devs_withZmount_cbZMountFailedErrorr&   r'   )
Zrequire_isor^   r[   inforY   ZmpZ_fnamer-   r]   Zdevsr   r   r   r#      s4    


r#   c                 C   s    | |g}t  |\}}|||fS r8   r   rpctoolargcmdstdoutstderrr   r   r   exec_vmware_rpctool
  s    rg   c                 C   s"   | d|g}t  |\}}|||fS )Nz--cmdr`   ra   r   r   r   exec_vmtoolsd  s    
rh   c                  C   s6  d\} }t d}t d}|r6|t } }td| |rT|sH|t } }td| | sftd d S dd }z|| |W S  t jk
r0 } z|r| |krttd	| W Y td S |st	d
 W Y \d S zt	d ||tW  W Y :S  t jk
r } zttd	| W 5 d }~X Y nX W 5 d }~X Y nX d S )N)NNvmtoolsdzvmware-rpctoolzdiscovered vmware-rpctool: %szdiscovered vmtoolsd: %szno rpctool discoveredc              
   S   s   t d|  z,|| d\}}}|r(|W S t d| W d S  tjk
rz } z"|jdkrft d| |j |W 5 d }~X Y nX d S )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   ProcessExecutionErrorZ	exit_codeZwarning)rb   
rpctool_fnrd   re   r0   errorr   r   r   query_guestinfo-  s    
z3transport_vmware_guestinfo.<locals>.query_guestinfoz+vmtoolsd failed to get guestinfo.ovfEnv: %sz$vmtoolsd fallback option not presentzfallback to vmtoolsd)
r   Zwhichrg   r&   r'   rh   rk   r   rJ   r_   )rb   rl   ri   Zvmware_rpctoolrn   rm   r   r   r   r"     sJ    




  



  (r"   c                 C   s2   g }|   s|S | jD ]}||r|| q|S r8   )hasChildNodesZ
childNodesr!   )ZnodeZfilter_funcZretZchildr   r   r   
find_child[  s    
rp   c           	      C   s   t | }|jjdkrtd|j s0tdd}t|jdd }t|dkrXtdi }t|d d	d }|D ],}|j	|d
j
}|j	|dj
}|||< qr|S )NZEnvironmentzNo Environment NodezNo Child Nodesz)http://schemas.dmtf.org/ovf/environment/1c                 S   s
   | j dkS )NZPropertySection	localNamenr   r   r   <lambda>r      z get_properties.<locals>.<lambda>r   zNo 'PropertySection'sc                 S   s
   | j dkS )NZPropertyrq   rs   r   r   r   ru   z  rv   keyvalue)r   ZparseStringZdocumentElementrr   XmlErrorro   rp   r$   Z
attributesZgetNamedItemNSrx   )	r-   ZdomZenvNsURIZpropSectionsrG   Z	propElemselemrw   rH   r   r   r   r@   e  s,    

  
r@   c                   @   s   e Zd ZdS )ry   N)r;   r<   r=   r   r   r   r   ry     s   ry   c                 C   s   t | tS r8   )r   Zlist_from_dependsdatasources)Z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.
    )yamlZ	safe_load)datar   r   r   rD     s    rD   )F)T)"__doc__rB   Zloggingr   rU   Zxml.domr   r}   Z	cloudinitr   r   r   Z	getLoggerr;   r&   r   r   r?   r    r   rX   r#   rg   rh   r"   rp   r@   rF   ry   ZDEP_FILESYSTEMZDEP_NETWORKr{   r|   rD   r   r   r   r   <module>   s2   
i	
)
&E
 
