
­­­­­­­­­­­­­­­­­­
<!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	|sd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\}}|rtjd| ntjd|ttj |  t|S )Nx   max_waitz Failed to get max wait. using %sr   F2   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 )zReturn 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 }xtD ]\}}}	}
|dkrPd| |f }nd| ||f }yXtj|}|||||d}|j r|	r|j||< qtj|j||< nt	j
d||j W q. t jk
r } z:|jdkr|
 rt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rtd| |rtd||f d}|jdrt }tj	|jd|td}||krtd|jd	|jd
|fS )zValidate 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$ qW |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rtj|j}d+|krt|d+ d, }x6|	j D ]*}||kr~|	| dkr~|| |	|< q~W |jdkrd-|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rd<n|j"  t!d= |j| t!d> |j|dkrd<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'

 