U
    Adj'                     @   s   d dl Z d dlZd dlmZmZmZ d dl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dddZdd Zeejej ffgZ!dd Z"dS )    N)gaierrorgetaddrinfo	inet_ntoa)pack)log)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__*   s    z'CloudStackPasswordServerClient.__init__c                 C   s:   t  ddddddddd	d
|d| jg\}}| S )NZwgetz--quietz--tries3z	--timeoutZ20z--output-document-z--headerzDomU_Request: {0}z{0}:8080)r   formatr   strip)r   Zdomu_requestoutput_r   r   r   _do_request-   s    
z*CloudStackPasswordServerClient._do_requestc                 C   s4   |  d}|dkrd S |dkr&td|  d |S )NZsend_my_password) saved_passwordZbad_requestz-Error when attempting to fetch root password.r   )r   RuntimeError)r   passwordr   r   r   get_passwordB   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d	 Zd
d Z	dd Z
edd ZdS )DataSourceCloudStackZ
CloudStackx   2   c                 C   sX   t j| ||| tj|jd| _d| _t | _	| j	s@t
dd| j	f | _i | _d S )NZcsZlatestzNo virtual router found!z
http://%s/)r   
DataSourcer   ospathjoinseed_dirapi_verget_vr_addressvr_addrr   metadata_addresscfg)r   Zsys_cfgZdistropathsr   r   r   r   T   s    zDataSourceCloudStack.__init__c                 C   s~   |   }|jdkrdS t| jdg}t }tj||j|jtj	d\}}|r\t
d| ntd|tt |  t|S )Nr   Fzlatest/meta-data/instance-id)urlsZmax_waitZtimeoutZ	status_cbzUsing metadata source: '%s'z>Giving up on waiting for the metadata from %s after %s seconds)Zget_url_paramsZmax_wait_secondsuhelpZcombine_urlr/   timeZwait_for_urlZtimeout_secondsLOGZwarningdebugZcriticalintbool)r   Z
url_paramsr2   
start_timeZurlZ	_responser   r   r   wait_for_metadata_service`   s.    
 
z.DataSourceCloudStack.wait_for_metadata_servicec                 C   s   | j S r   )r0   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 z|  sNW dS t }t	
| j| j| _t	| j| j| _tdtt |  t| j}z| }W n$ tk
r   t td	| j Y nX |rd|d
did| _W dS  tk
r   t td| j Y dS X d S )N/)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 %sZexpire)Z
ssh_pwauthr   Zchpasswdz(Failed fetching from metadata service %s)r
   Zread_optional_seedr+   Zuserdata_rawmetadatar5   r6   r:   r4   r   Zget_instance_userdatar,   r/   Zget_instance_metadatar7   r   r.   r   	ExceptionZlogexcr0   )r   Zseed_retr9   Zpassword_clientZset_passwordr   r   r   	_get_data   s\    

  

 zDataSourceCloudStack._get_datac                 C   s
   | j d S )Nzinstance-idr?   r;   r   r   r   get_instance_id   s    z$DataSourceCloudStack.get_instance_idc                 C   s
   | j d S )Nzavailability-zonerB   r;   r   r   r   availability_zone   s    z&DataSourceCloudStack.availability_zoneN)r    r!   r"   ZdsnameZurl_max_waitZurl_timeoutr   r:   r<   rA   rC   propertyrD   r   r   r   r   r$   L   s   0r$   c                  C   sD   zt dd} W n  tk
r.   td Y d S X | d d d S d S )Nzdata-serverP   zDNS Entry data-server not foundr      )r   r   r5   r6   )Zaddrinfor   r   r   get_data_server   s    
rH   c                  C   s^   t d } | D ]F}|d}|d dkrttdt|d d}td| |  S qd S )	Nz/proc/net/route	   Z00000000z<L      z"Found default route, gateway is %s)	r
   Z	load_file
splitlinessplitr   r   r7   r5   r6   )lineslineitemsZgwr   r   r   get_default_gateway   s    

rR   c                  C   sJ   dddg} | D ]6}t j|rtt |dkrtd| |  S qd S )Nz/var/lib/dhclientz/var/lib/dhcpz/var/lib/NetworkManagerr   zUsing %s lease directory)r(   r)   existslenlistdirr5   r6   )Zsupported_dirsdr   r   r   get_dhclient_d   s    
rW   c                 C   s   | d krt  } | sd S t| }d}d }|D ]P}|dr<q,|dsR|dsRq,tj| |}tj|}||kr,|}|}q,|S )NZ	dhclient6z.leasez.leases)rW   r(   rU   
startswithendswithr)   r*   getmtime)Zlease_dZlease_filesZlatest_mtimeZlatest_filefnameZabs_pathmtimer   r   r   get_latest_lease   s$    


r^   c               	   C   s   t  } | rtd|  | S td} | r8td|  | S t }|sRtd t S t|dL}|D ]@}d|krb|d	d}t
|d	krb|d	 }td
| |} qbW 5 Q R X | std t S | S )Nz4Found metadata server '%s' via data-server DNS entryZSERVER_ADDRESSz-Found SERVER_ADDRESS '%s' via networkd_leasesz*No lease file found, using default gatewayrzdhcp-server-identifierz ;
 rK   zFound DHCP identifier %sz$No DHCP found, using default gateway)rH   r5   r6   r   Znetworkd_get_option_from_leasesr^   rR   openr   rN   rT   )Zlatest_addressZ
lease_filefdrP   ZwordsZdhcptokr   r   r   r-     s<    
 

r-   c                 C   s   t | tS r   )r   Zlist_from_dependsdatasources)Zdependsr   r   r   get_datasource_list3  s    rd   )N)#r(   r4   Zsocketr   r   r   Zstructr   Z	cloudinitr   Zloggingr   r   r	   r3   r
   Zcloudinit.netr   Zcloudinit.sources.helpersr   Z	getLoggerr    r5   r   r'   r$   rH   rR   rW   r^   r-   ZDEP_FILESYSTEMZDEP_NETWORKrc   rd   r   r   r   r   <module>   s(   
.n
!-