o
    x[hg  ã                   @   sì   d 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	m
Z
mZ ddlmZmZ e e¡ZdZdd„ Zd	ed
efdd„Zd
eje fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd„ de	jƒZee	j ffgZ!dd„ Z"dS )zr
This file contains code used to gather the user data passed to an
instance on rootbox / hyperone cloud platforms
é    N)ÚIPv4Address)ÚsourcesÚsubpÚutil)Ú
EventScopeÚ	EventTypez
/etc/hostsc                  C   s.   t jtdd�} | rt d¡ dS t d¡ dS )NT)Úquietz5/etc/hosts exists - setting manage_etc_hosts to FalseFz=/etc/hosts does not exists - setting manage_etc_hosts to True)r   Úload_text_fileÚ	ETC_HOSTSÚLOGÚdebug)Úhosts© r   úF/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceRbxCloud.pyÚget_manage_etc_hosts   s   

r   ÚincÚreturnc                 C   s   t ttt| ƒƒ| ƒƒS ©N)Ústrr   Úint)Úaddrr   r   r   r   Úincrement_ip#   s   r   c                 C   s   | t | dƒt | dƒgS )z–Return a list of 3 IP addresses: [addr, addr + 2, addr + 3]

    @param addr: an object that is passed to IPvAddress
    @return: list of strings
    é   é   )r   )r   r   r   r   Úget_three_ips'   s   ýr   c                 C   s   t   dg|  ¡S )z©
    Uses the preferred cloud-init subprocess def of subp.subp
    and runs arping.  Breaking this to a separate function
    for later use in mocking and unittests
    Úarping)r   )Úcmdr   r   r   Ú_sub_arp4   s   r   c                 C   s|   d}|j dv r	d}| D ]0}ztdd||d |d gƒ W q tjy; } zt d|d |d |¡ W Y d }~qd }~ww d S )	Nz-S)ÚfedoraÚcentosÚrhelz-sz-cÚ2ÚsourceÚdestinationz&Failed to arping from "%s" to "%s": %s)Únamer   r   ÚProcessExecutionErrorr   Úwarning)ÚitemsÚdistroÚsource_paramÚitemÚerrorr   r   r   Úgratuitous_arp=   s$   
ÿü€üûr,   c                  C   s¸   t t d¡t d¡ ƒ} | sdS | D ]>}ztj|tg d¢d�}|r&|W   S W q ty@ } z|jtjkr6‚ W Y d}~qd}~w tjyP   t 	t
d|¡ Y qw t
 dd	 | ¡¡ dS )
zAReturns False (not found or error) or a dictionary with metadata.zLABEL=CLOUDMDzLABEL=cloudmdF)ÚvfatÚfatÚmsdosfs)ÚdeviceÚcallbackÚmtypeNz-Failed to mount %s when looking for user dataz0Did not find RbxCloud data, searched devices: %sú,)Úsetr   Úfind_devs_withÚmount_cbÚread_user_data_callbackÚOSErrorÚerrnoÚENOENTÚMountFailedErrorÚlogexcr   r   Újoin)Údevicesr0   Úrbx_dataÚerrr   r   r   Úget_mdR   s>   ÿÿý
ÿÿ€ÿÿ
ÿrA   c                 C   s   ddd„ t | ƒD ƒdœS )z‹Generate network configuration

    @param netadps: A list of network adapter settings

    @returns: A dict containing network config
    é   c                    sB   g | ]\}‰ d d  t|ƒ¡ˆ d  ¡ ‡ fdd„ˆ d D ƒdœ‘qS )Úphysicalzeth{}Ú
macaddressc              	      s>   g | ]}d |d ˆ d d dˆ d d ˆ d d d dœ‘qS )	ÚstaticÚaddressÚnetworkÚnetmaskÚautoÚgatewayÚdnsÚnameservers)ÚtyperF   rH   ÚcontrolrJ   Údns_nameserversr   )Ú.0Úip©Únetadpr   r   Ú
<listcomp>   s    ÷


ÿúÿz6generate_network_config.<locals>.<listcomp>.<listcomp>rQ   )rM   r$   Úmac_addressÚsubnets)Úformatr   Úlower)rP   Úir   rR   r   rT   z   s    ï

õüÿz+generate_network_config.<locals>.<listcomp>)ÚversionÚconfig)Ú	enumerate)Únetadpsr   r   r   Úgenerate_network_configq   s
   íþr^   c                 C   s  t jt jtj | d¡d�d�}t jtj | d¡dd�}d|vs#d|vr+t  td	¡ d
S | 	di ¡ 	d¡}| 	di ¡ 	dg ¡}d
}| 	di ¡ 	d¡rQ|d d d }t
|d ƒ}||d d |d d g dœdd„ |d D ƒddd||dg|d|dœi|tƒ dœdœ}t d¡ t |¡ |S )a   This callback will be applied by util.mount_cb() on the mounted
    drive.

    @param mount_dir: String representing path of directory where mounted drive
    is available

    @returns: A dict containing userdata, metadata and cfg based on metadata.
    z
cloud.json)Úfname)Útextz	user.dataT)r_   r   ÚvmrS   z(Failed to load metadata. Invalid format.NÚadditionalMetadataÚusernameÚsshKeysÚpasswordÚsha512Ú_idr$   )zinstance-idzlocal-hostnameúpublic-keysc                 S   s>   g | ]}|d  D ]}t |d d ƒD ]	}|d |dœ‘qqqS )rQ   rG   rJ   rF   )r"   r#   )r   )rP   rS   rQ   Útargetr   r   r   rT   ´   s    ýüý
ÿz+read_user_data_callback.<locals>.<listcomp>Údefault_userzALL=(ALL) NOPASSWD:ALLF)r$   ÚgecosÚsudoÚpasswdÚlock_passwdÚssh_authorized_keys)Ú
ssh_pwauthÚdisable_rootÚsystem_infoÚnetwork_configÚmanage_etc_hosts)ÚuserdataÚmetadatar,   Úcfgzreturning DATA object:)r   Ú	load_jsonÚload_binary_fileÚosÚpathr=   r	   r<   r   Úgetr^   r   r   )Ú	mount_dirÚ	meta_dataÚ	user_datarc   Ússh_keysÚhashrG   Údatar   r   r   r7   ’   sR   	ÿÿ

ýþúÿ
òó

r7   c                   @   sj   e Zd ZdZejejejej	hiZ
dd„ Zdd„ Zdd„ Zedd	„ ƒZd
d„ Zdd„ Zdd„ Zdd„ ZdS )ÚDataSourceRbxCloudÚRbxCloudc                 C   s(   t j | |||¡ d | _d | _d | _d S r   )r   Ú
DataSourceÚ__init__Úseedr,   rw   )ÚselfÚsys_cfgr(   Úpathsr   r   r   r†   Ü   s   
zDataSourceRbxCloud.__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DataSourceRbxCloud.__str__c                 C   s>   t ƒ }|du r	dS |d | _|d | _|d | _|d | _dS )zw
        Metadata is passed to the launching instance which
        is used to perform instance configuration.
        Fru   rv   r,   rw   T)rA   Úuserdata_rawrv   r,   rw   )rˆ   r?   r   r   r   Ú	_get_dataæ   s   



zDataSourceRbxCloud._get_datac                 C   ó
   | j d S )Nrs   ©rw   ©rˆ   r   r   r   rs   ô   s   
z!DataSourceRbxCloud.network_configc                 C   r�   )Nrh   )rv   r‘   r   r   r   Úget_public_ssh_keysø   s   
z&DataSourceRbxCloud.get_public_ssh_keysc                 C   ó   | j S r   )r�   r‘   r   r   r   Úget_userdata_rawû   ó   z#DataSourceRbxCloud.get_userdata_rawc                 C   r“   r   r�   r‘   r   r   r   Úget_config_objþ   r•   z!DataSourceRbxCloud.get_config_objc                 C   s   t | j | jƒ d S r   )r,   r(   )rˆ   rw   Úis_new_instancer   r   r   Úactivate  s   zDataSourceRbxCloud.activateN)Ú__name__Ú
__module__Ú__qualname__Údsnamer   ÚNETWORKr   ÚBOOT_NEW_INSTANCEÚBOOTÚBOOT_LEGACYÚdefault_update_eventsr†   r‹   rŽ   Úpropertyrs   r’   r”   r–   r˜   r   r   r   r   rƒ   Ò   s"    ýÿ
rƒ   c                 C   s   t  | t¡S r   )r   Úlist_from_dependsÚdatasources)Údependsr   r   r   Úget_datasource_list  s   r¦   )#Ú__doc__r9   Úloggingrz   Úos.pathÚtypingÚ	ipaddressr   Ú	cloudinitr   r   r   Úcloudinit.eventr   r   Ú	getLoggerr™   r   r
   r   r   r   r   ÚListr   r   r,   rA   r^   r7   r…   rƒ   ÚDEP_FILESYSTEMr¤   r¦   r   r   r   r   Ú<module>   s.   
		!@
5ÿ