o
    x[hÙ,  ã                   @   sä   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
 d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ e  e¡ZG d
d„ dƒZG dd„ dejƒZdd„ Zdd„ Zdd„ ZeejejffgZ dd„ Z!dS )é    N)Úsuppress)ÚgaierrorÚgetaddrinfoÚ	inet_ntoa)Úpack)ÚsourcesÚsubp)Ú
url_helper)Úutil)Údhcp)Úec2c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚCloudStackPasswordServerClienta–  
    Implements password fetching from the CloudStack password server.

    http://cloudstack-administration.readthedocs.org/
       en/latest/templates.html#adding-password-management-to-your-templates
    has documentation about the system.  This implementation is following that
    found at
    https://github.com/shankerbalan/cloudstack-scripts/
       blob/master/cloud-set-guest-password-debian
    c                 C   s
   || _ d S ©N)Úvirtual_router_address)Úselfr   © r   úH/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceCloudStack.pyÚ__init__+   ó   
z'CloudStackPasswordServerClient.__init__c                 C   s:   t   ddddddddd	d
 |¡d | j¡g¡\}}| ¡ S )NÚwgetz--quietz--triesÚ3z	--timeoutÚ20z--output-documentú-z--headerzDomU_Request: {0}z{0}:8080)r   Úformatr   Ústrip)r   Údomu_requestÚoutputÚ_r   r   r   Ú_do_request.   s   
õÿz*CloudStackPasswordServerClient._do_requestc                 C   s4   |   d¡}|dv rd S |dkrtdƒ‚|   d¡ |S )NÚsend_my_password)Ú Úsaved_passwordÚbad_requestz-Error when attempting to fetch root password.r!   )r   ÚRuntimeError)r   Úpasswordr   r   r   Úget_passwordC   s   

z+CloudStackPasswordServerClient.get_passwordN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r%   r   r   r   r   r      s
    r   c                       sl   e Zd ZdZdZdZdd„ Zdd„ Z			d‡ fd	d
„	Zdd„ Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZ‡  ZS )ÚDataSourceCloudStackÚ
CloudStackéx   é2   c                 C   sd   t j | |||¡ tj |jd¡| _d| _|| _t	| jƒ| _
| j
s%tdƒ‚d| j
› d�| _i | _d S )NÚcsÚlatestzNo virtual router found!zhttp://ú/)r   Ú
DataSourcer   ÚosÚpathÚjoinÚseed_dirÚapi_verÚdistroÚget_vr_addressÚvr_addrr#   Úmetadata_addressÚcfg)r   Úsys_cfgr7   Úpathsr   r   r   r   U   s   
zDataSourceCloudStack.__init__c                 C   sä   t  d¡ t d¡}|r|S t  d¡ ttjƒ� t ¡  | jd¡}|r-|W  d  ƒ S W d  ƒ n1 s7w   Y  t  d| jj	j
¡ ttƒ� | jj	 | jj¡}| d¡pYd}|W  d  ƒ S 1 sfw   Y  t  d¡ dS )z‰
        Try obtaining a "domain-name" DHCP lease parameter:
        - From systemd-networkd lease
        - From dhclient lease
        z.Try obtaining domain name from networkd leasesÚ
DOMAINNAMEzHCould not obtain FQDN from networkd leases. Falling back to ISC dhclientzdomain-nameNzBCould not obtain FQDN from ISC dhclient leases. Falling back to %szNo dhcp leases found)ÚLOGÚdebugr   Únetworkd_get_option_from_leasesr   ÚNoDHCPLeaseMissingDhclientErrorÚIscDhclientÚget_key_from_latest_leaser7   Údhcp_clientÚclient_nameÚFileNotFoundErrorÚget_newest_leaseÚfallback_interfaceÚget)r   Ú
domainnameÚdomain_nameÚlatest_leaser   r   r   Ú_get_domainnamec   s:   

ÿÿûüý
ÿ û
z$DataSourceCloudStack._get_domainnameFc                    sn   t ƒ  |||¡}|r5d|jvr5t d¡ |  ¡ }|r/|j› d|› �}t d|¡ t ||j¡S t d|¡ |S )zá
        Returns instance's hostname / fqdn
        First probes the parent class method.

        If fqdn is requested, and the parent method didn't return it,
        then attach the domain-name from DHCP response.
        Ú.zFQDN requestedzObtained the following FQDN: %szNCould not determine domain name for FQDN. Fall back to hostname as an FQDN: %s)	ÚsuperÚget_hostnameÚhostnamer?   r@   rN   r   ÚDataSourceHostnameÚ
is_default)r   ÚfqdnÚ
resolve_ipÚmetadata_onlyrR   rK   ©Ú	__class__r   r   rQ   �   s   
ýz!DataSourceCloudStack.get_hostnamec                 C   s„   |   ¡ }|jdkrdS t | jd¡g}t ¡ }tj||j|jt	j
d�\}}|r1t	 d|¡ t|ƒS t	 d|tt ¡ | ƒ¡ t|ƒS )Nr   Fzlatest/meta-data/instance-id)ÚurlsÚmax_waitÚtimeoutÚ	status_cbzUsing metadata source: '%s'z>Giving up on waiting for the metadata from %s after %s seconds)Úget_url_paramsÚmax_wait_secondsÚuhelpÚcombine_urlr:   ÚtimeÚ	monotonicÚwait_for_urlÚtimeout_secondsr?   Úwarningr@   ÚcriticalÚintÚbool)r   Ú
url_paramsrZ   Ú
start_timeÚurlÚ	_responser   r   r   Úwait_for_metadata_service©   s.   
ÿÿ
ü	ùüz.DataSourceCloudStack.wait_for_metadata_servicec                 C   s   | j S r   )r;   ©r   r   r   r   Úget_config_objÈ   s   z#DataSourceCloudStack.get_config_objc                 C   s  i }t j|| jd d�r|d | _|d | _t d| j¡ dS zV|  ¡ s'W dS t 	¡ }t
 | j| j¡| _t
 | j| j¡| _t dtt 	¡ | ƒ¡ t| jƒ}z| ¡ }W n tyg   t  td	| j¡ Y W dS w |rsd|d
didœ| _W dS  ty‡   t  td| j¡ Y dS w )Nr0   )Úbasez	user-dataz	meta-dataz%Using seeded cloudstack data from: %sTFz)Crawl of metadata service took %s secondsz/Failed to fetch password from virtual router %sÚexpire)Ú
ssh_pwauthr$   Úchpasswdz(Failed fetching from metadata service %s)r
   Úread_optional_seedr5   Úuserdata_rawÚmetadatar?   r@   rn   rb   rc   r   Úget_instance_userdatar6   r:   Úget_instance_metadatarh   r   r9   r%   Ú	ExceptionÚlogexcr;   )r   Úseed_retrk   Úpassword_clientÚset_passwordr   r   r   Ú	_get_dataË   s\   

ÿÿþ
ýñÿýýúzDataSourceCloudStack._get_datac                 C   ó
   | j d S )Nzinstance-id©rw   ro   r   r   r   Úget_instance_idû   r   z$DataSourceCloudStack.get_instance_idc                 C   r€   )Nzavailability-zoner�   ro   r   r   r   Úavailability_zoneþ   s   
z&DataSourceCloudStack.availability_zone)FFF)r&   r'   r(   ÚdsnameÚurl_max_waitÚurl_timeoutr   rN   rQ   rn   rp   r   r‚   Úpropertyrƒ   Ú__classcell__r   r   rX   r   r*   M   s     ,ü0r*   c                  C   s>   zt ddƒ} W n ty   t d¡ Y d S w | d d d S )Nzdata-serveréP   zDNS Entry data-server not foundr   é   )r   r   r?   r@   )Úaddrinfor   r   r   Úget_data_server  s   
þrŒ   c                  C   s^   t  d¡ ¡ } | D ]#}| d¡}|d dkr,ttdt|d dƒƒƒ}t d|¡ |  S q	d S )	Nz/proc/net/routeú	é   Ú00000000z<Lé   é   z"Found default route, gateway is %s)	r
   Úload_text_fileÚ
splitlinesÚsplitr   r   rh   r?   r@   )ÚlinesÚlineÚitemsÚgwr   r   r   Úget_default_gateway  s   
ür™   c                 C   s   t ƒ }|rt d|¡ |S t d¡}|rt d|¡ |S ttjƒ�! t ¡  | d¡}|r;t d|¡ |W  d   ƒ S W d   ƒ n1 sEw   Y  tt	ƒ�" | j
 | ¡}|rit d|| j
j¡ |W  d   ƒ S W d   ƒ n1 ssw   Y  t d¡ tƒ S )Nz4Found metadata server '%s' via data-server DNS entryÚSERVER_ADDRESSz-Found SERVER_ADDRESS '%s' via networkd_leaseszdhcp-server-identifierz&Found SERVER_ADDRESS '%s' via dhclientz1Found SERVER_ADDRESS '%s' via ephemeral %s lease z$No DHCP found, using default gateway)rŒ   r?   r@   r   rA   r   rB   rC   rD   rG   rE   rH   rF   r™   )r7   Úlatest_addressrM   r   r   r   r8     sJ   þ
ÿÿúü
ýøþ
r8   c                 C   s   t  | t¡S r   )r   Úlist_from_dependsÚdatasources)Údependsr   r   r   Úget_datasource_listR  s   rŸ   )"Úloggingr2   rb   Ú
contextlibr   Úsocketr   r   r   Ústructr   Ú	cloudinitr   r   r	   r`   r
   Úcloudinit.netr   Úcloudinit.sources.helpersr   Ú	getLoggerr&   r?   r   r1   r*   rŒ   r™   r8   ÚDEP_FILESYSTEMÚDEP_NETWORKr�   rŸ   r   r   r   r   Ú<module>   s*   
. 72ÿ