o
    fg                     @   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 )zReturn 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 )zGenerate 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