U
    Ӈg>                     @   s
  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	m
Z
mZmZmZ eeZdZdZdgZdZG dd dejZG d	d
 d
eZG dd deZG dd dZdd Zdd Zdd ZdddZdddZdd Z eZ!eej"ffgZ#dd Z$dS )    N)atomic_helpernetsourcessubputilziid-dsopennebulaZnobody
context.sh)ZEPOCHREALTIMEZEPOCHSECONDSZRANDOMZLINENOZSECONDS_ZSRANDOMZ__vc                   @   sF   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	dddZ
dS )DataSourceOpenNebulaZ
OpenNebulac                 C   s4   t j| ||| d | _tj|jd| _d | _d S )NZ
opennebula)	r   
DataSource__init__seedospathjoinseed_dirnetwork)selfZsys_cfgdistropaths r   H/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceOpenNebula.pyr   /   s    zDataSourceOpenNebula.__init__c                 C   s   t j| }d|| j| jf S )Nz%s [seed=%s][dsmode=%s])r   r
   __str__r   dsmode)r   rootr   r   r   r   5   s    zDataSourceOpenNebula.__str__c           
      C   s  dt i}d }d }t}d| jkr*| jd}| jg}|t  |D ]}zLtj	| jrht
|| j|d}n(|drtjt
|| jd}t||}W n\ tk
r   Y qBY nF tk
r } z|W 5 d }~X Y n" tjk
r   td| Y nX |rB|}td|  qqB|sdS |d	 }	t|	|g}	| |d
| jdg| _| jtjkr\dS || _|d| _|	| _|d| _dS )Nzinstance-id	parseuserasuserz/dev)r   r   z%s was not mountablezfound datasource in %sFmetadataZDSMODEr   network-interfacesuserdataT) DEFAULT_IIDDEFAULT_PARSEUSERZds_cfggetr   extendfind_candidate_devsr   r   isdirread_context_disk_dirr   
startswith	functoolspartialr   Zmount_cbNonContextDiskDirBrokenContextDiskDirZMountFailedErrorLOGwarningdebugZmergemanydictZ_determine_dsmoder   r   ZDSMODE_DISABLEDr   r   r   Zuserdata_raw)
r   defaultsresultsr   r   Z
candidatesZcdevZpartially_applied_funcexcZmdr   r   r   	_get_data9   s^    
  
zDataSourceOpenNebula._get_datac                 C   s$   | j | jkrd}nd}d|| jf S )z/Return the subplatform metadata source details.zseed-dirzconfig-diskz%s (%s))r   r   )r   Zsubplatform_typer   r   r   _get_subplatformv   s    z%DataSourceOpenNebula._get_subplatformc                 C   s   | j d k	r| j S d S d S N)r   )r   r   r   r   network_config~   s    
z#DataSourceOpenNebula.network_configFc                 C   s.   |d kr| j tjkrd}nd}tj| ||S )NTF)r   r   ZDSMODE_NETWORKr
   get_hostname)r   ZfqdnZ
resolve_ipZmetadata_onlyr   r   r   r6      s
    z!DataSourceOpenNebula.get_hostnameN)FFF)__name__
__module____qualname__Zdsnamer   r   r2   r3   propertyr5   r6   r   r   r   r   r	   +   s   =
r	   c                   @   s   e Zd ZdS )r*   Nr7   r8   r9   r   r   r   r   r*      s   r*   c                   @   s   e Zd ZdS )r+   Nr;   r   r   r   r   r+      s   r+   c                   @   sp   e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd ZdddZdd ZdS )OpenNebulaNetworkNc                 C   s|   || _ |d krt|}tdd t| dd dD | _i | _| D ],\}}t	d|}|rJ|
d| j| < qJd S )Nc                 S   s   g | ]}|qS r   r   .0kr   r   r   
<listcomp>   s   z.OpenNebulaNetwork.__init__.<locals>.<listcomp>c                 S   s   t | d S )N   )r   Znatural_sort_key)r?   r   r   r   <lambda>       z,OpenNebulaNetwork.__init__.<locals>.<lambda>)keyz
^(.+)_MAC$rA   )contextget_physical_nics_by_maccollectionsOrderedDictsorteditemsifacescontext_devnamerematchgrouplower)r   rE   r   Zsystem_nics_by_macr?   vmr   r   r   r      s     zOpenNebulaNetwork.__init__c                 C   s"   d dd |ddd  D S )N.c                 S   s   g | ]}t t|d qS )   )strint)r>   cr   r   r   r@      s     z,OpenNebulaNetwork.mac2ip.<locals>.<listcomp>:   )r   split)r   macr   r   r   mac2ip   s    zOpenNebulaNetwork.mac2ipc                 C   s\   i }|  |dd }|| jdd  |r:||d< |  |dd }|rX||d< |S )Ndns ZDNS	addressessearch_domainsearch)	get_fieldrZ   r#   rE   r"   )r   devnameserversr]   r`   r   r   r   get_nameservers   s    z!OpenNebulaNetwork.get_nameserversc                 C   s   |  |dS )Nmturb   r   rc   r   r   r   get_mtu   s    zOpenNebulaNetwork.get_mtuc                 C   s   |  |d| |S )NZip)rb   r\   )r   rc   r[   r   r   r   get_ip   s    zOpenNebulaNetwork.get_ipc                 C   s<   g }|  |d}|r|| |  |d}|r8|| |S )Nip6ip6_ula)rb   append)r   rc   
addresses6rk   rl   r   r   r   get_ip6   s    

zOpenNebulaNetwork.get_ip6c                 C   s   |  |ddS )NZip6_prefix_lengthZ64rg   rh   r   r   r   get_ip6_prefix   s    z OpenNebulaNetwork.get_ip6_prefixc                 C   s   |  |dS )Ngatewayrg   rh   r   r   r   get_gateway   s    zOpenNebulaNetwork.get_gatewayc                 C   s   |  |d|  |dS )NZip6_gatewaygateway6rg   rh   r   r   r   get_gateway6   s
      
zOpenNebulaNetwork.get_gateway6c                 C   s   |  |ddS )Nmaskz255.255.255.0rg   rh   r   r   r   get_mask   s    zOpenNebulaNetwork.get_maskc                 C   s*   | j d||f }|dkr&|S |S )zreturn the field name in context for device dev.

        context stores <dev>_<NAME> (example: eth0_DOMAIN).
        an empty string for value will return default.r   )Nr^   )rE   r"   r   upper)r   rc   namedefaultvalr   r   r   rb      s    	zOpenNebulaNetwork.get_fieldc                    s6  i }d|d< i |d< i }| j  D ]\}}| }| j||}i }d|i|d< g |d< | |}tt|}|d 	| 
||d |  | |}	|	r| | |d  fdd	|	D  | |}
|
r|
|d
< | |}|r||d< | |}|r||d< | |}|r ||d< |||< q"||d< |S )NrY   version	ethernetsZ
macaddressrN   r_   /c                    s   g | ]}|d    qS )r}   r   )r>   iZprefix6r   r   r@   	  s     z.OpenNebulaNetwork.gen_conf.<locals>.<listcomp>Zgateway4rs   rd   rf   )rK   rJ   rP   rL   r"   rv   rU   r   Zipv4_mask_to_net_prefixrm   rj   ro   rp   r#   rr   rt   re   ri   )r   Znetconfr|   r[   rc   Zc_devZdevconfru   prefixrn   rq   rs   rd   rf   r   r   r   gen_conf   sD    







zOpenNebulaNetwork.gen_conf)N)N)r7   r8   r9   r   r\   re   ri   rj   ro   rp   rr   rt   rv   rb   r   r   r   r   r   r<      s   


r<   c                  C   s@   g } dD ]2}t |}|  |D ]}|| kr"| | q"q| S )zE
    Return a list of devices that may contain the context disk.
    )zLABEL=CONTEXTzLABEL=CDROMzTYPE=iso9660)r   Zfind_devs_withsortrm   )Zcombinedfdevsdr   r   r   r$   &  s    
r$   c                 C   s
   dd| gS )NZsudoz-ur   userr   r   r   switch_user_cmd5  s    r   c                   C   s
   t dS )zDprint the shell environment variables within delimiters to be parsedz
        printf "%s\0" _start_
        [ $0 != 'sh' ] && set -o posix
        set
        [ $0 != 'sh' ] && set +o posix
        printf "%s\0" _start_
        )textwrapdedentr   r   r   r   
varprinter9  s    r   c                 C   s  d|   krtd t d|   t  d }g }|dk	rBt|}|ddg tj||dj}i }|d	d
d }|d |d  }}t	dd t
|D }	t	dd t
|D }
t|	 t|
 D ]6}|tkrq|
|}|dk	r||	|kr|||< q|S )a<  run content and return environment variables which changed

    WARNING: the special variable _start_ is used to delimit content

    a context.sh that defines this variable might break in unexpected
    ways

    compatible with posix shells such as dash and ash and any shell
    which supports `set -o posix`
    s   _start_ zYUser defined _start_ variable in context.sh, this may breakcloud-init in unexpected ways.z{
%s

:
} > /dev/null

NZshz-e)dataz_start_ rA   r   rY   c                 s   s   | ]}|j d ddV  qdS =rA   )maxsplitNrZ   r>   Zvariabler   r   r   	<genexpr>}  s    z%parse_shell_config.<locals>.<genexpr>c                 s   s   | ]}|j d ddV  qdS r   r   r   r   r   r   r     s    )encoder,   r-   r   r   r#   r   stdoutrZ   dictshlexsetkeysunionEXCLUDED_VARSr"   )contentr   ZbcmdcmdoutputZretZsectionsZbeforeZafterZpre_envZpost_envrD   valuer   r   r   parse_shell_configF  sB    

r   c              
   C   s  i }t D ]&}tj| |}tj|r|||< q|sDtd| df i }di d}d|kr8|dk	rzt| W n4 tk
r } zt	dj
|d|W 5 d}~X Y nX z(tj| d}	t|	}
t|
|d}W nd tjk
r } zt	d	| |W 5 d}~X Y n2 tk
r4 } ztd
| |W 5 d}~X Y nX ntd|sJ|S ||d< d}d|krfd}nd|krtd}|r|| }dd |D |d d< dD ]&}||kr|| |d d<  qʐqd|kr|d |d< nd|kr|d |d< d|krV|d|d}|dkrVzt|d |d< W n  tk
rT   td Y nX dd |D }|rt||}| |d< |S )z
    read_context_disk_dir(source_dir):
    read source_dir and return a tuple with metadata dict and user-data
    string populated.  If not a valid dir, raise a NonContextDiskDir
    z%s: %szno files foundN)r   r   r   z'configured user '{user}' does not existr   r   zError processing context.sh: %szError reading context.sh: %szMissing context.shr   ZSSH_KEYZSSH_PUBLIC_KEYc                 S   s"   g | ]}t |r|d s|qS )#)lenr'   )r>   liner   r   r   r@     s     
 z)read_context_disk_dir.<locals>.<listcomp>zpublic-keys)ZSET_HOSTNAMEZHOSTNAMEZ	PUBLIC_IPZ	IP_PUBLICZETH0_IPzlocal-hostnameZ	USER_DATAr   ZUSERDATAZUSERDATA_ENCODINGZUSER_DATA_ENCODINGbase64z"Failed base64 decoding of userdatac                 S   s   g | ]}t d |r|qS )z^ETH\d+_IP.*$)rM   rN   r=   r   r   r   r@     s      r   )CONTEXT_DISK_FILESr   r   r   isfiler*   pwdgetpwnamKeyErrorr+   formatr   Zload_text_filer   r   ZProcessExecutionErrorIOErrorr"   
splitlinesr   Zb64d	TypeErrorr,   r-   r<   r   )Z
source_dirr   r   foundZaffnrE   r0   er   r   Zssh_key_varlinesr?   encodingZipaddr_keysZonetr   r   r   r&     s    










 

r&   c                    s"   t  }t fdd| D S )Nc                    s$   g | ]\}} j |r||fqS r   )Z
networkingZis_physical)r>   rR   nr   r   r   r@     s      z,get_physical_nics_by_mac.<locals>.<listcomp>)r   Zget_interfaces_by_macr   rJ   )r   r   r   r   r   rF     s    rF   c                 C   s   t | tS r4   )r   Zlist_from_dependsdatasources)Zdependsr   r   r   get_datasource_list  s    r   )N)N)%rG   r(   Zloggingr   r   rM   r   r   Z	cloudinitr   r   r   r   r   Z	getLoggerr7   r,   r    r!   r   r   r
   r	   	Exceptionr*   r+   r<   r$   r   r   r   r&   rF   ZDataSourceOpenNebulaNetZDEP_FILESYSTEMr   r   r   r   r   r   <module>   s8   
c 
G
`
