
    f<                        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g dZ G d dej"                        Z G d	 d
e      Zd Zd Zd ZddeddfdZd Z G d de      Z G d de      Zeej8                  ffeej8                  ej:                  ffgZd Zedk(  rd Z  e         yy)    N)sources
url_helperutil)KlibcNetworkConfigSource)NetworkConfigSourcez
2012-03-01))meta-data/instance-idr   FF)meta-data/local-hostnamer	   FF)meta-data/public-keysr
   FT)zmeta-data/vendor-datavendor-dataTT)	user-datar   TTc                   V    e Zd ZdZdZdZdZd Zed        Z	d Z
d Zd Zd	 Zd
 Zd Zy)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                     t         j                  j                  | |||       d | _        t        j
                  j                  |j                  d      | _        t        | j                        | _
        y )Nmaas)r   
DataSource__init__base_urlospathjoinseed_dirget_id_from_ds_cfgds_cfgid_hash)selfsys_cfgdistropathss       B/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceMAAS.pyr   zDataSourceMAAS.__init__.   sM    ##D'65AU^^V<)$++6    c                 f    | j                   st        | j                        | _         | j                   S N)_oauth_helperget_oauth_helperr   r   s    r    oauth_helperzDataSourceMAAS.oauth_helper4   s(    !!!1$++!>D!!!r!   c                 d    t         j                  j                  |       }|d| j                  dS )Nz [])r   r   __str__r   )r   roots     r    r*   zDataSourceMAAS.__str__:   s'    !!))$/ $--00r!   c           	         | j                   }	 | j                  | j                  t        | j                               y# t        $ r Y n2t
        $ r'}t        j                  d| j                  |        d }~ww xY w|j                  dd       }|sy	 | j                  |      sy| j                  |t        || j                  j                  | j                  d             y# t        $ r t        j                   t        d|       Y yw xY w)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urls       r    	_get_datazDataSourceMAAS._get_data>   s    {{	NN4==*<T]]*KL 	# 	KK.sC	
 hh~t,	
 11#6NN"%)%6%6%>%>**	  	KKCSI	s3   /> 	A8	A8"A33A8C! #=C! !$DDc                     || _         |\  }}}|| _        || _        || _        |r	 t	        j
                  |      | _        y y # t        $ r'}t        j                  d|       d | _        Y d }~y d }~ww xY w)Nz"Invalid content in vendor-data: %s)
r   userdata_rawmetadatavendordata_purer   convert_vendordatavendordata_raw
ValueErrorr5   r6   )r   r?   dataudmdvdes          r    r1   zDataSourceMAAS._set_datae   sw    
B!+&-&@&@&D#   +@!D&*##+s   A 	A2A--A2c                      d| j                   z  S )z/Return the subplatform metadata source details.zseed-dir (%s))r   r&   s    r    _get_subplatformzDataSourceMAAS._get_subplatforms   s    ..r!   c                    | j                   }d}	 t        |j                  d|            }|dk(  ryd}	 ||v rt        |j                  d|            }t        j                         }|j                  d	      r|d d
 }|d	t        d}|g}| j                  j                  |||      \  }}|r!t        j                  d|       t        |      S t        j                  d|t        t        j                         |z
               t        |      S # t        $ r t	        j
                  t        d|       Y w xY w# t        $ r t        j                  d|       Y 
w xY w)Nx   max_waitz Failed to get max wait. using %sr   F2   timeoutzFailed to get timeout, using %s/z/meta-data/instance-id)urlsrQ   rS   zUsing metadata source: '%s'z(Giving up on md from %s after %i seconds)r   intr7   r;   r   r<   r5   r6   timeendswith
MD_VERSIONr'   wait_for_urldebugcriticalbool)	r   r?   r=   rQ   rS   	starttime	check_urlrV   	_responses	            r    r8   z(DataSourceMAAS.wait_for_metadata_servicew   sQ   {{	K488J9:H q=	D$dhhy':; IIK	<<cr(C58*E	{**77' 8 
Y II3S9 Cy LL:DIIK)+, Cy?  	KKK?J	K  	DKK97C	Ds"   D D; $D87D8;EEc                     | j                   y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.F
datasource)r   r   get_cfg_by_pathdsnamer   )r   r   ncfgs      r    check_instance_idz DataSourceMAAS.check_instance_id   sC     <<##GlDKK-H"M||1$777r!   )__name__
__module____qualname____doc__re   r   r$   r   propertyr'   r*   r@   r1   rN   r8   rg    r!   r    r   r      sQ     FGM7 " "
1%N+/$L	8r!   r   c                   z     e Zd Zej                  ej
                  ej                  ej                  fZ fdZ	 xZ
S )DataSourceMAASLocalc                     t               j                         st        j                  d       yt        j                  d       t        |          S )NzNo initramfs applicable configFz!Found initramfs applicable config)r   is_applicabler5   r\   superr@   )r   	__class__s    r    r@   zDataSourceMAASLocal._get_data   s?    ')779 II67		56w ""r!   )rh   ri   rj   r   CMD_LINE
SYSTEM_CFGDS	INITRAMFSnetwork_config_sourcesr@   __classcell__)rs   s   @r    ro   ro      s9    $$&&%%	# #r!   ro   c           	          d}t        |D cg c]  }|| j                  |      f c}      }t        j                  di |S c c}w )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_secretrm   )dictr7   r   OauthUrlHelper)cfgkeysrkwargss       r    r%   r%      sD    
 LDD1qAswwqz?12F$$.v.. 2s   Ac           	          d}dj                  |D cg c]  }| j                  |d       c}      }dt        j                  |j	                  d            j                         z   S c c}w )z;Given a config, generate a unique identifier for this node.)r{   r}   r~     zv1:zutf-8)r   r7   hashlibsha256encode	hexdigest)r   fieldsfidstrs       r    r   r      sX    :FII&9Qvzz!R(9:E 7>>%,,w"78BBDDD :s   A'c                     | j                  d      r| dd  } t        j                  j                  |       r!t	        t        j
                  |             dk(  rt        d      t        d| z  d       S )Nfile://   r   z%s: not a directoryz	file://%s)version)
startswithr   r   isdirlenlistdirr3   r9   )seed_ds    r    r2   r2      s`    #77== C

6(:$;q$@344 kF2DAAr!   c                 n   |t         j                  }| j                  d      r| dd } i }t        D ]  \  }}}	}
|| d|}n
| d|d|}	 t	        j
                  |      } |||||      }|j                         r5|	r|j                  ||<   nDt	        j                  |j                        ||<   n!t        j                  d||j                          t        ||       S # t         j                  $ r>}|j                  dk(  r|
st        d|d|      ||j                  dk7  r|Y d}~d}~ww xY w)	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.
    NrT   rU   )r0   rS   ssl_detailsz4Fetching from %s resulted in an invalid http code %si  zMissing required z: )r   r/   rY   	DS_FIELDSr   fetch_ssl_detailsokcontentsdecode_binaryr5   r6   codeUrlErrorr4   check_seed_contents)seed_urlr/   rS   r   r   r0   rJ   r   	_dictnamebinaryoptionalr?   r   resprL   s                  r    r9   r9      s?   & %66CR=	B-6 )i?%t,C ('48C	007K#Wg;D wwy#}}BtH#11$--@BtHJII!: r8,, "" 	vv}X*15q9 3 	s   BC##D464D//D4c                    i }g }t         D ]U  \  }}}}|| vr|s|j                  |        d|v r*|j                  d      \  }}	}
||vri ||<   | |   ||   |
<   N| |   ||<   W t        |      dk(  rt	        d|z        |rt        |d|      d}|j                  d      rDt               }t        j                  |j                  d      |t              }||u rt        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
    rT   r   z%s: no data files foundz: missing files Nr   )defaultallowedz%vendor-data was not loadable as yaml.r   	meta-data)
r   append	partitionr   r3   r4   r7   objectr   	load_yaml)contentseedretmissingspathdpath_binaryr   top_pvd_dataerrs                r    r   r     s$   
 CG+4 ('ugxu%%<,ICA#~C!%.CHQK CJ( 3x1}7$>??"T7#KLLG
ww}h..GGM"C&
 c>&'NOO77;!5w>>r!   c                       e Zd Zy)r3   Nrh   ri   rj   rm   r!   r    r3   r3   9      r!   r3   c                       e Zd Zy)r4   Nr   rm   r!   r    r4   r4   =  r   r!   r4   c                 6    t        j                  | t              S r#   )r   list_from_dependsdatasources)dependss    r    get_datasource_listr   I  s    $$Wk::r!   __main__c                     ddl } ddl}ddl}| j                  d      }|j	                  dddd       |j	                  d	d
dd       |j	                  dd
dd       |j	                  dddd       |j	                  dddd       |j	                  dddt
               |j                  dd      }dD ]-  \  }}|j                  ||      }|j	                  dddd       / |j                         }|j                  |j                  |j                  |j                  d }	|j                  yd!D ]t  }
d"|
z   d#z   }t        j                  j!                  |      s+t        j"                  |t        j$                        sP|j&                  j)                  d$|z         ||_        v |j                  rmt+        j,                  |j                        }d%|v r|d%   d&   }|	j/                         D ]  }||v s|	|   ||   |	|<    |j0                  d'|v r
|d'   |_        |j0                  ,|j&                  j)                  d(       |j3                  d)       t5        |	      fd*fd+fd,|j6                  d-k(  r|j&                  j)                  d.|j0                  z         j8                  }|j0                  d   d/k(  s|j0                  j;                  d0      rt=        |j0                        \  }}}n't?        |j0                  |j@                  |d12      \  }}}tC        d3       tC        |d4n|jE                                tC        d5       |j                  |       tC        d6       |j                  |d4       y|       y|j6                  d7k(  r |j0                         y|j6                  d8k(  rB|j0                  jG                  d/      sd9|j0                  z  |_         |j0                         yy):z
        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helpr   z--ckeykeyzthe consumer key to auth withz--tkeyzthe token key to auth withz--csecsecretzthe consumer secret (likely '')r   z--tseczthe token secret to auth withz--apiverr   z the apiver to use ( can be used)subcommandssubcmd)titledest))crawlzcrawl the datasource)r7   zdo a single GET of provided url)
check-seedzread and verify seed at url)r   r?   zthe datasource url?)r   nargsr   )r{   r}   r~   r|   )91_kernel_cmdline_url90_dpkg_maasz/etc/cloud/cloud.cfg.d/z.cfgzUsed config in %s.
rc   r   r-   z)Must provide a url or a config with url.
r.   c                 >    j                  | d      j                  S )Nr.   )r0   )r:   r   )r?   r'   s    r    geturlzmain.<locals>.geturl  s    ''Q'7@@@r!   c                 R    t        d| d |       j                         d       y )Nz== z ==

)printdecode)r?   r   s    r    printurlzmain.<locals>.printurl  s    c6#;+=+=+?@Ar!   c                    | j                  d      rf |       j                         j                         D ]>  }|j                  d      r | |       !|dk(  r | d       3 | |       @ y  |        y )NrT   r   z
meta-data/)rY   r   
splitlines)r?   liner   r   r   s     r    r   zmain.<locals>.crawl  sx    ||C "3K..0;;= 7D}}S)T23,\:; 3!567 r!   r   zChecking seed at %s
rT   r      )r   r/   r0   z=== user-data ===zN/Az=== meta-data ===z=== vendor-data ===r7   r   z%s/)$argparsepprintsysArgumentParseradd_argumentrZ   add_subparsers
add_parser
parse_argsckeytkeytseccsecconfigr   r   existsaccessR_OKstderrwriter   	read_confr   r?   exitr%   r   r:   r   r2   r9   apiverr   r   rY   )r   r   r   parsersubcmdsnamer   r   argscredsfnamefpathr   r   r:   userdatarC   rK   r   r   r'   r   s                     @@@@r    mainr   O  s    	((5L(M)	 	 	
 	0	 	 	
 	-	 	 	
 	2	 	 	
 	0	 	 	
 	3	 	 	
 ''m('K
 	LT4
 ""4d"3ANN0T  	   " !II II#yy	
 ;;B (1E9FB77>>%(RYYubgg-FJJ$$%;e%CD"'DK	( ;;..-Cs",'/zz| *#:%*"4!$SE#J* xxNc$9~.88JJIJHHQK'.	A	B	 ;;,&JJ4txx?@"**Gxx{c!TXX%8%8%C+=dhh+G(8R+=HH KK%,	,(8R %&8+%1BC%&MM(#'(MM2:%626[[E!TXX[[G#88$$S) 488+$((O $r!   )!r   loggingr   rX   	cloudinitr   r   r   cloudinit.net.cmdliner   cloudinit.sourcesr   	getLoggerrh   r5   rZ   r   r   r   ro   r%   r   r2   r9   r   r;   r3   r4   DEP_FILESYSTEMDEP_NETWORKr   r   r   rm   r!   r    <module>r     s      	  / / : 1g!
	G8W'' G8T#. #$/EB 
7-t$?N	i 		9 	 71134g,,g.A.ABC; zHT 	FY r!   