509318396
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
\¼me€<  ã               @   s  d dl Z d dlZ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 ejeƒZdZd%d&d'd(d)gZG dd„ dejƒZG dd„ deƒZdd„ Zdd„ Zdd„ Zddeddfdd„Zdd„ ZG dd„ deƒZG dd„ deƒZeejffeejejffgZd d!„ Zed"k�rd#d$„ Z e ƒ  dS )*é    N)ÚsourcesÚ
url_helperÚutil)ÚKlibcNetworkConfigSource)ÚNetworkConfigSourcez
2012-03-01úmeta-data/instance-idFúmeta-data/local-hostnameúmeta-data/public-keysTúmeta-data/vendor-dataúvendor-dataú	user-datac               @   s`   e Zd ZdZdZdZdZdd„ Zedd„ ƒZ	dd	„ Z
d
d„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚDataSourceMAASzç
    DataSourceMAAS reads instance information from MAAS.
    Given a config metadata_url, and oauth tokens, it expects to find
    files under the root named:
      instance-id
      user-data
      hostname
      vendor-data
    ÚMAASNc             C   s:   t jj| |||ƒ d | _tjj|jdƒ| _t| j	ƒ| _
d S )NZmaas)r   Ú
DataSourceÚ__init__Úbase_urlÚosÚpathÚjoinÚseed_dirÚget_id_from_ds_cfgÚds_cfgÚid_hash)ÚselfÚsys_cfgZdistroÚpaths© r   ú$/usr/lib/python3.6/DataSourceMAAS.pyr   .   s    zDataSourceMAAS.__init__c             C   s   | j st| jƒ| _ | j S )N)Ú_oauth_helperÚget_oauth_helperr   )r   r   r   r   Úoauth_helper4   s    zDataSourceMAAS.oauth_helperc             C   s   t jj| ƒ}d|| jf S )Nz%s [%s])r   r   Ú__str__r   )r   Úrootr   r   r   r!   :   s    zDataSourceMAAS.__str__c             C   sÒ   | j }y| j| jt| jƒƒ dS  tk
r2   Y n4 tk
rd } ztjd| j|ƒ ‚ W Y d d }~X nX |jdd ƒ}|szdS y0| j	|ƒsŠdS | j|t
|| jj| jdd�ƒ dS  tk
rÌ   tjtd|ƒ dS X d S )NTz%s was malformed: %sÚmetadata_urlFé   )Úread_file_or_urlr   Úretriesz$Failed fetching metadata from url %s)r   Ú	_set_datar   Úread_maas_seed_dirÚMAASSeedDirNoneÚMAASSeedDirMalformedÚLOGÚwarningÚgetÚwait_for_metadata_serviceÚread_maas_seed_urlr    Úreadurlr   Ú	Exceptionr   Úlogexc)r   ÚmcfgÚexcÚurlr   r   r   Ú	_get_data>   s4    

zDataSourceMAAS._get_datac             C   sp   || _ |\}}}|| _|| _|| _|rlytj|ƒ| _W n4 tk
rj } ztj	d|ƒ d | _W Y d d }~X nX d S )Nz"Invalid content in vendor-data: %s)
r   Zuserdata_rawÚmetadataZvendordata_purer   Zconvert_vendordataZvendordata_rawÚ
ValueErrorr+   r,   )r   r5   ÚdataZudÚmdÚvdÚer   r   r   r'   e   s    
zDataSourceMAAS._set_datac             C   s
   d| j  S )z/Return the subplatform metadata source details.zseed-dir (%s))r   )r   r   r   r   Ú_get_subplatforms   s    zDataSourceMAAS._get_subplatformc       	      C   s
  | j }d}yt|jd|ƒƒ}W n" tk
r@   tjtd|ƒ Y nX |dkrNdS d}y||krlt|jd|ƒƒ}W n  tk
rŽ   tjd|ƒ Y nX tjƒ }|j	d	ƒr®|d d… }d|t
f }|g}| jj|||d�\}}|rètjd|ƒ ntjd|ttjƒ | ƒƒ t|ƒS )Néx   Úmax_waitz Failed to get max wait. using %sr   Fé2   ÚtimeoutzFailed to get timeout, using %sú/r$   z%s/%s/meta-data/instance-id)Úurlsr?   rA   zUsing metadata source: '%s'z(Giving up on md from %s after %i secondséÿÿÿÿ)r   Úintr-   r1   r   r2   r+   r,   ÚtimeÚendswithÚ
MD_VERSIONr    Zwait_for_urlÚdebugZcriticalÚbool)	r   r5   r3   r?   rA   Z	starttimeZ	check_urlrC   Z	_responser   r   r   r.   w   s8    
z(DataSourceMAAS.wait_for_metadata_servicec             C   s0   | j dkrdS tj|d| jfi ƒ}| j t|ƒkS )a  locally check if the current system is the same instance.

        MAAS doesn't provide a real instance-id, and if it did, it is
        still only available over the network.  We need to check based
        only on local resources.  So compute a hash based on Oauth tokens.NFÚ
datasource)r   r   Zget_cfg_by_pathÚdsnamer   )r   r   Zncfgr   r   r   Úcheck_instance_id�   s    
z DataSourceMAAS.check_instance_id)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rL   r   r   r   Úpropertyr    r!   r6   r'   r=   r.   rM   r   r   r   r   r      s   	'&r   c                   s0   e Zd ZejejejejfZ‡ fdd„Z	‡  Z
S )ÚDataSourceMAASLocalc                s,   t ƒ jƒ stjdƒ dS tjdƒ tƒ jƒ S )NzNo initramfs applicable configFz!Found initramfs applicable config)r   Zis_applicabler+   rI   Úsuperr6   )r   )Ú	__class__r   r   r6   ±   s
    


zDataSourceMAASLocal._get_data)rN   rO   rP   r   ZCMD_LINEZ
SYSTEM_CFGZDSZ	INITRAMFSZnetwork_config_sourcesr6   Ú__classcell__r   r   )rU   r   rS   ©   s
   rS   c                s&   d}t ‡ fdd„|D ƒƒ}tjf |ŽS )zªReturn an oauth helper instance for values in cfg.

    @raises ValueError from OauthUrlHelper if some required fields have
            true-ish values but others do not.Úconsumer_keyÚconsumer_secretÚ	token_keyÚtoken_secretc                s   g | ]}|ˆ j |ƒf‘qS r   )r-   )Ú.0Úr)Úcfgr   r   ú
<listcomp>Á   s    z$get_oauth_helper.<locals>.<listcomp>)rW   rX   rY   rZ   )Údictr   ZOauthUrlHelper)r]   ÚkeysÚkwargsr   )r]   r   r   »   s    r   c                s4   d	}dj ‡ fdd„|D ƒƒ}dtj|jdƒƒjƒ  S )
z;Given a config, generate a unique identifier for this node.rW   rY   rZ   ú c                s   g | ]}ˆ j |d ƒ‘qS )Ú )r-   )r[   Úf)r   r   r   r^   È   s    z&get_id_from_ds_cfg.<locals>.<listcomp>zv1:zutf-8)rW   rY   rZ   )r   ÚhashlibZsha256ÚencodeZ	hexdigest)r   ZfieldsZidstrr   )r   r   r   Å   s    r   c             C   sN   | j dƒr| dd … } tjj| ƒ s6ttj| ƒƒdkr>tdƒ‚td|  d d�S )Nzfile://é   r   z%s: not a directoryz	file://%s)Úversion)Ú
startswithr   r   ÚisdirÚlenÚlistdirr)   r/   )Zseed_dr   r   r   r(   Î   s
    
 r(   c             C   s   |dkrt j}| jdƒr$| dd
… } i }xìtD ]ä\}}}	}
|dkrPd| |f }nd| ||f }yXtj|ƒ}|||||d�}|jƒ r¤|	r’|j||< q´tj|jƒ||< nt	j
d||jƒ W q. t jk
�r } z:|jdkrð|
 rðtd	||f ƒ|‚n|jdk�r |‚W Y dd}~X q.X q.W t|| ƒS )a›  
    Read the maas datasource at seed_url.
      read_file_or_url is a method that should provide an interface
      like util.read_file_or_url

    Expected format of seed_url is are the following files:
      * <seed_url>/<version>/meta-data/instance-id
      * <seed_url>/<version>/meta-data/local-hostname
      * <seed_url>/<version>/user-data
    If version is None, then <version>/ will not be used.
    NrB   r$   z%s/%sz%s/%s/%s)r&   rA   Ússl_detailsz4Fetching from %s resulted in an invalid http code %si”  zMissing required %s: %srD   )r   r%   rG   Ú	DS_FIELDSr   Zfetch_ssl_detailsÚokÚcontentsZdecode_binaryr+   r,   ÚcodeZUrlErrorr*   Úcheck_seed_contents)Zseed_urlr%   rA   rh   r   r&   r:   r   Z	_dictnameZbinaryÚoptionalr5   rm   Zrespr<   r   r   r   r/   Ø   s:    

r/   c             C   sø   i }g }xrt D ]j\}}}}|| kr2|s|j|ƒ qd|krl|jdƒ\}}	}
||krZi ||< | | || |
< q| | ||< qW t|ƒdkr”td| ƒ‚|r¨td||f ƒ‚d}|jdƒrâtƒ }tj	|jdƒ|td�}||krâtdƒ‚|jd	ƒ|jd
ƒ|fS )z·Validate if dictionary content valid as a return for a datasource.
    Either return a (userdata, metadata, vendordata) tuple or
    Raise MAASSeedDirMalformed or MAASSeedDirNone
    rB   r   z%s: no data files foundz%s: missing files %sNzvendor-data)ÚdefaultZallowedz%vendor-data was not loadable as yaml.z	user-dataz	meta-data)
rn   ÚappendÚ	partitionrk   r)   r*   r-   Úobjectr   Z	load_yaml)ZcontentZseedÚretZmissingZspathZdpathZ_binaryrs   ÚtopÚ_ÚpZvd_dataÚerrr   r   r   rr     s2    

rr   c               @   s   e Zd ZdS )r)   N)rN   rO   rP   r   r   r   r   r)   9  s   r)   c               @   s   e Zd ZdS )r*   N)rN   rO   rP   r   r   r   r   r*   =  s   r*   c             C   s   t j| tƒS )N)r   Zlist_from_dependsÚdatasources)Zdependsr   r   r   Úget_datasource_listI  s    r~   Ú__main__c                 s.  ddl } ddl}ddl}| jdd�}|jddddd� |jd	d
ddd� |jdd
ddd� |jddddd� |jddddd� |jdddtd� |jddd�}x0dCD ](\}}|j||d �}|jd!d"d#dd$� q¤W |jƒ }|j	|j
|j|jd%œ}	|jdk�rJxNdDD ]F}
d(|
 d) }tjj|ƒ�r tj|tjƒ�r |jjd*| ƒ ||_�q W |j�rÌtj|jƒ}d+|k�rt|d+ d, }x6|	jƒ D ]*}||k�r~|	| dk�r~|| |	|< �q~W |jdk�rÌd-|k�rÌ|d- |_|jdk�rî|jjd.ƒ |jd/ƒ t|	ƒ‰‡fd0d1„‰‡fd2d3„‰‡ ‡‡fd4d5„‰ |jdk�râ|jjd6|j ƒ ˆj}|jd d7k�s`|jjd8ƒ�rrt|jƒ\}}}nt|j|j |d9d:�\}}}t!d;ƒ t!|dk�r¤d<n|j"ƒ ƒ t!d=ƒ |j|ƒ t!d>ƒ |j|dk�rÚd<n|ƒ nH|jdk�rúˆ|jƒ n0|jdk�r*|jj#d7ƒ�s d?|j |_ˆ |jƒ dS )Ezä
        Call with single argument of directory or http or https url.
        If url is given additional arguments are allowed, which will be
        interpreted as consumer_key, token_key, token_secret, consumer_secret
        r   NzInteract with MAAS DS)Údescriptionz--configÚfilezspecify DS config file)ÚmetavarÚhelprt   z--ckeyÚkeyzthe consumer key to auth withz--tkeyzthe token key to auth withz--csecZsecretzthe consumer secret (likely '')rc   z--tseczthe token secret to auth withz--apiverrh   z the apiver to use ( can be used)ZsubcommandsÚsubcmd)ÚtitleÚdestÚcrawlúcrawl the datasourcer-   údo a single GET of provided urlú
check-seedúread and verify seed at url)rƒ   r5   zthe datasource urlú?)rƒ   Únargsrt   )rW   rY   rZ   rX   Ú91_kernel_cmdline_urlÚ90_dpkg_maasz/etc/cloud/cloud.cfg.d/z.cfgzUsed config in %s.
rK   r   r#   z)Must provide a url or a config with url.
r$   c                s   ˆ j | dd�jS )Nr$   )r&   )r0   rp   )r5   )r    r   r   Úgeturlª  s    zmain.<locals>.geturlc                s   t d| ˆ | ƒjƒ f ƒ d S )Nz== %s ==
%s
)ÚprintÚdecode)r5   )r‘   r   r   Úprinturl®  s    zmain.<locals>.printurlc                sx   | j dƒrlxhˆ| ƒjƒ jƒ D ]J}|j dƒr<ˆ d| |f ƒ q|dkrVˆ d| df ƒ qˆd| |f ƒ qW nˆ| ƒ d S )NrB   z%s%sz	meta-dataz
meta-data/)rG   r“   Ú
splitlines)r5   Úline)rˆ   r‘   r”   r   r   rˆ   ±  s    

zmain.<locals>.crawlzChecking seed at %s
rB   zfile://é   )rh   r%   r&   z=== user-data ===zN/Az=== meta-data ===z=== vendor-data ===z%s/©rˆ   r‰   ©r-   rŠ   ©r‹   rŒ   )r˜   r™   rš   )r�   r�   )$ÚargparseÚpprintÚsysÚArgumentParserÚadd_argumentrH   Zadd_subparsersZ
add_parserÚ
parse_argsZckeyZtkeyZtsecZcsecÚconfigr   r   ÚexistsÚaccessÚR_OKÚstderrÚwriter   Z	read_confr`   r5   Úexitr   r…   r0   ri   r(   r/   Zapiverr’   r“   rG   )r›   rœ   r�   ÚparserZsubcmdsÚnamerƒ   r{   ÚargsZcredsZfnameZfpathr]   r„   r0   Zuserdatar7   r;   r   )rˆ   r‘   r    r”   r   ÚmainO  s¶      





r«   )r   r   FF)r   r   FF)r	   r	   FT)r
   r   TT)r   r   TT)!re   Zloggingr   rF   Z	cloudinitr   r   r   Zcloudinit.net.cmdliner   Zcloudinit.sourcesr   Z	getLoggerrN   r+   rH   rn   r   r   rS   r   r   r(   r/   rr   r1   r)   r*   ZDEP_FILESYSTEMZDEP_NETWORKr}   r~   r«   r   r   r   r   Ú<module>	   sD   
 
	4'

 