U
    Ldq7                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlmZ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 eeZdZdeiZdZdZdZddiZdZ G dd dZ!G dd de	j"Z#G dd de#Z$dd Z%dd Z&d:ddZ'd;d d!Z(d"d# Z)e$e	j*ffe#e	j*e	j+ffgZ,d$d% Z-ed&krd dl.Z.d dl/Z/d d'lm0Z0 e.j1d(d)Z2e2j3d*d+d,ed- e2j3d.d/d0d1dd2 e24 Z5e(e5j6e5j7d3Z8d4e8krze8d4 9 e8d4< W n< e:k
r   e/j;<d5 e8d4= e0e8d4 9 e8d6< Y nX e=ej>e8d7dd8d9 dS )<    N)	b64decode)dmi)log)netsources
url_helperutil)ug_util)
EventScope	EventType)NoDHCPLeaseError)EphemeralDHCPv4)DataSourceHostnamez3http://metadata.google.internal/computeMetadata/v1/metadata_url)instance-idavailability-zonelocal-hostnamezLhttp://metadata.google.internal/computeMetadata/v1/instance/guest-attributeshostkeyszMetadata-FlavorGoogleZens4c                   @   s   e Zd Zdd ZdddZdS )GoogleMetadataFetcherc                 C   s   || _ || _|| _d S N)metadata_addressnum_retriessec_between_retries)selfr   r   r    r   A/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceGCE.py__init__!   s    zGoogleMetadataFetcher.__init__Fc           	   
   C   s   d }z0| j | }|r|d7 }tj|t| j| jd}W n6 tjk
rj } zd}t||| W 5 d }~X Y n<X |j	dkr|rt
|j}q|jd}ntd||j	 |S )Nz/?recursive=True)urlheadersZretriesZsec_betweenzurl %s raised exception %s   utf-8zurl %s returned code %s)r   r   readurlHEADERSr   r   ZUrlErrorLOGdebugcoder   Zdecode_binarycontentsdecode)	r   pathis_textis_recursivevaluer   respexcmsgr   r   r   	get_value&   s(    

 
zGoogleMetadataFetcher.get_valueN)F)__name__
__module____qualname__r   r0   r   r   r   r   r       s   r   c                   @   s|   e Zd ZdZdZejejej	hiZ
dd Zdd Zedd Zd	d
 Zdd Zdd ZdddZedd Zedd ZdS )DataSourceGCEGCEFc                 C   sr   t j| ||| d | _|r<t||\}}t|\| _}t | _t	
t	|ddgi tg| _| jd | _d S )NZ
datasourcer5   r   )r   
DataSourcer   default_userr	   Znormalize_users_groupsZextract_defaultdictmetadatar   ZmergemanydictZget_cfg_by_pathBUILTIN_DS_CONFIGZds_cfgr   )r   Zsys_cfgdistropathsZusersZ_groupsZ_user_configr   r   r   r   K   s    zDataSourceGCE.__init__c                 C   s  |   }| jr>t }t|kr6|t |dt td| t	|dksVt
d|D ]}t| j|d}zz|l z tjtjdt| j|dd}W nD tk
r } z&td	|| W Y W 5 Q R  W qZW 5 d }~X Y nX W 5 Q R X W n tk
r   Y qZY nX |d
 rZ|| _td|  q"qZ| jd krZtd| j ntjtjdt| j|dd}|d
 s|d r~t|d  nt|d  dS |d | _|d | _dS )Nr   z"Looking for the primary NIC in: %s   z3The instance has to have at least one candidate NIC)ZifacezCrawl of GCE metadata service)address
url_params)kwargsz,Error fetching IMD with candidate NIC %s: %ssuccesszPrimary NIC found: %s.z(Did not find a fallback interface on %s.platform_reports_gcereasonF	meta-data	user-dataT)Zget_url_paramsperform_dhcp_setupr   Zfind_candidate_nicsDEFAULT_PRIMARY_INTERFACEremoveinsertr$   r%   lenAssertionErrorr   r;   r   Zlog_timeread_mdr   	Exceptionr   Z_fallback_interfacewarningZ
cloud_namer9   Zuserdata_raw)r   r?   Zcandidate_nicsZcandidate_nicZnetwork_contextreter   r   r   	_get_dataZ   sz    


	4
 




zDataSourceGCE._get_datac                 C   s   d S r   r   r   r   r   r   launch_index   s    zDataSourceGCE.launch_indexc                 C   s
   | j d S )Nr   r9   rR   r   r   r   get_instance_id   s    zDataSourceGCE.get_instance_idc                 C   s   | j d }t|| jS )Npublic-keys-data)r9   _parse_public_keysr7   )r   public_keys_datar   r   r   get_public_ssh_keys   s    
z!DataSourceGCE.get_public_ssh_keysc                 C   s   |D ]}t |  qd S r   )#_write_host_key_to_guest_attributes)r   r   keyr   r   r   publish_host_keys   s    zDataSourceGCE.publish_host_keysc                 C   s   t | jd dd dS )Nr   .r   F)r   r9   split)r   ZfqdnZ
resolve_ipZmetadata_onlyr   r   r   get_hostname   s     zDataSourceGCE.get_hostnamec                 C   s
   | j d S )Nr   rT   rR   r   r   r   availability_zone   s    zDataSourceGCE.availability_zonec                 C   s   | j ddd S )N-r=   r   )r`   rsplitrR   r   r   r   region   s    zDataSourceGCE.regionN)FFF)r1   r2   r3   ZdsnamerF   r
   ZNETWORKr   ZBOOT_NEW_INSTANCEZBOOTZdefault_update_eventsr   rQ   propertyrS   rU   rY   r\   r_   r`   rc   r   r   r   r   r4   @   s&   B


r4   c                   @   s   e Zd ZdZdS )DataSourceGCELocalTN)r1   r2   r3   rF   r   r   r   r   re      s   re   c                 C   sR   dt t| f }|d}tj||tddd}| rBtd|  ntd|  d S )Nz%s/%s/%sr!   ZPUTF)r   datar   Zrequest_methodZcheck_statusz&Wrote %s host key to guest attributes.z0Unable to write %s host key to guest attributes.)	GUEST_ATTRIBUTES_URLHOSTKEY_NAMESPACEencoder   r"   r#   okr$   r%   )Zkey_type	key_valuer   r-   r   r   r   rZ      s    
rZ   c              	   C   s   z|  d ddd  \}}W n ttfk
r6   Y dS X |dkrDdS zt|}W n tk
rh   Y dS X d|krvdS |d }d}ztj||}W n tk
r   Y dS X tj |kS )N      Fz
google-sshZexpireOnz%Y-%m-%dT%H:%M:%S+0000)r^   
ValueErrorAttributeErrorjsonloadsdatetimestrptimeZutcnow)
public_keyZschemaZjson_strZjson_objZ
expire_strZ
format_strZexpire_timer   r   r   _has_expired   s&    ru   c                 C   sr   g }| s|S | D ]\}|rt dd |D s,q|dd}t|dkrFq|\}}|d|fkrt|s|| q|S )Nc                 s   s   | ]}t |d k V  qdS )   N)ord).0cr   r   r   	<genexpr>   s     z%_parse_public_keys.<locals>.<genexpr>:r=   rm   	cloudinit)allr^   rJ   ru   append)rX   r7   Zpublic_keysrt   Zsplit_public_keyuserr[   r   r   r   rW      s    rW   Tc                 C   s  | d krt } d d dd d}t |d< |r<|d s<d|d< |S t| sbtd|  d|  |d< |S dd	d
ddg}t| |j|j}i }|D ]b\}}}	}
}d }|D ]}|	||
|}|d k	r|}q|	r|d krd}|| |d< |  S |||< qt
|d pd}t
|d pd}|d|dg}|dd }|dkrl|dsl||d ||d ddd |D }| |d< |d r|d dd |d< d|kr|d d}|d}|d krt|}n|rtd!| ||d< ||d"< d#|d$< |S )%NF)rD   rE   rA   rC   rB   zNot running on GCE.rC   z%s is not resolvablezaddress "%s" is not resolvable)r   )zinstance/idTTF)r   )zinstance/zoneTTF)r   )zinstance/hostnameTTF)instance-data)zinstance/attributesFFT)project-data)zproject/attributesFFTz)required key %s returned nothing. not GCEr   z{}r   ZsshKeyszssh-keyszblock-project-ssh-keys true
c                 S   s   g | ]}|r|qS r   r   )rx   r[   r   r   r   
<listcomp><  s      zread_md.<locals>.<listcomp>rV   r   /rE   r!   zuser-data-encodingbase64z(unknown user-data-encoding: %s, ignoringrD   TrA   )	MD_V1_URLrB   r   Zis_resolvable_urlr$   r%   r   r   r   r0   rp   rq   getlowerr~   join
splitlinesr^   ri   r   rN   )r>   r?   platform_checkrO   Zurl_mapZmetadata_fetcherZmdZmkeyr<   Zrequiredr*   r+   r,   r)   Z	new_valuer/   Zinstance_dataZproject_dataZ
valid_keysZblock_projectrX   Zudencodingr   r   r   rL     sx    

  





rL   c                  C   sP   t dpd} | dks| dkr"dS t dp.d}|dr>dS td| | d	S )
Nzsystem-product-namezN/AzGoogle Compute Enginer   Tzsystem-serial-numberzGoogleCloud-z6Not running on google cloud. product-name=%s serial=%sF)r   Zread_dmi_data
startswithr$   r%   )Zpnameserialr   r   r   rB   R  s    
  rB   c                 C   s   t | tS r   )r   Zlist_from_dependsdatasources)Zdependsr   r   r   get_datasource_listj  s    r   __main__)	b64encodezQuery GCE Metadata Service)Zdescriptionz
--endpointZURLz The url of the metadata service.)metavarhelpdefaultz--no-platform-checkr   zIgnore smbios platform checkZstore_false)destr   actionr   )r>   r   rE   z/User-data cannot be decoded. Writing as base64
zuser-data-b64r=   ),z: )indentZ	sort_keysZ
separators)N)NNT)?rr   rp   r   r   r|   r   r   Zloggingr   r   r   r   Zcloudinit.distrosr	   Zcloudinit.eventr
   r   Zcloudinit.net.dhcpr   Zcloudinit.net.ephemeralr   Zcloudinit.sourcesr   Z	getLoggerr1   r$   r   r:   ZREQUIRED_FIELDSrg   rh   r#   rG   r   r6   r4   re   rZ   ru   rW   rL   rB   ZDEP_FILESYSTEMZDEP_NETWORKr   r   argparsesysr   ArgumentParserparseradd_argument
parse_argsargsZendpointr   rf   r(   UnicodeDecodeErrorstderrwriteprintdumpsr   r   r   r   <module>   sz   
 {"

M


