
    }fk;                        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                   ^    e Zd Zd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
    MAASNx   2   c                     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__2   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_helper8   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_dataB   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metadatar   convert_vendordatavendordata_raw
ValueErrorr7   r8   )r   rA   dataudmdvdes          r"   r3   zDataSourceMAAS._set_datai   so    
B+&-&@&@&D#   +@!D&*##+s   ; 	A+A&&A+c                      d| j                   z  S )z/Return the subplatform metadata source details.zseed-dir (%s))r   r(   s    r"   _get_subplatformzDataSourceMAAS._get_subplatformv   s    ..r#   c                    | j                         }|j                  dk(  ryt        j                         }|j	                  d      }|dt
        d}|g}| j                  j                  ||j                  |j                        \  }}|r!t        j                  d|       t        |      S t        j                  d|t        t        j                         |z
               t        |      S )Nr   F/z/meta-data/instance-id)urlsmax_waittimeoutzUsing metadata source: '%s'z(Giving up on md from %s after %i seconds)get_url_paramsmax_wait_secondstime	monotonicrstrip
MD_VERSIONr)   wait_for_urltimeout_secondsr7   debugcriticalintbool)r   rA   
url_params	starttime	check_urlrR   	_responses          r"   r:   z(DataSourceMAAS.wait_for_metadata_servicez   s    ((*
&&!+NN$	jjo58*E	{**7700.. 8 
Y II3S9 Cy LL:DNN$y01 Cyr#   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__rh   r   r&   url_max_waiturl_timeoutr   propertyr)   r,   rB   r3   rO   r:   rj    r#   r"   r   r      s\     FGM LK7 " "
1%N+/4	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_applicabler7   r]   superrB   )r   	__class__s    r"   rB   zDataSourceMAASLocal._get_data   s?    ')779 II67		56w ""r#   )rk   rl   rm   r   CMD_LINE
SYSTEM_CFGDS	INITRAMFSnetwork_config_sourcesrB   __classcell__)rx   s   @r"   rt   rt      s9    $$&&%%	# #r#   rt   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_secretrr   )dictr9   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   r9   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listdirr5   r;   )seed_ds    r"   r4   r4      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.
    NrQ   )r2   rT   ssl_detailsz4Fetching from %s resulted in an invalid http code %si  zMissing required z: )r   r1   endswith	DS_FIELDSr   fetch_ssl_detailsokcontentsdecode_binaryr7   r8   codeUrlErrorr6   check_seed_contents)seed_urlr1   rT   r   r!   r2   rK   r   	_dictnamebinaryoptionalrA   r   resprM   s                  r"   r;   r;      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
    rQ   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   r5   r6   r9   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)r5   Nrk   rl   rm   rr   r#   r"   r5   r5   0      r#   r5   c                       e Zd Zy)r6   Nr   rr   r#   r"   r6   r6   4  r   r#   r6   c                 6    t        j                  | t              S r%   )r   list_from_dependsdatasources)dependss    r"   get_datasource_listr   @  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)r9   zdo a single GET of provided url)
check-seedzread and verify seed at url)r   rA   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.
rf   r   r/   z)Must provide a url or a config with url.
r0   c                 >    j                  | d      j                  S )Nr0   )r2   )r<   r   )rA   r)   s    r"   geturlzmain.<locals>.geturl  s    ''Q'7@@@r#   c                 R    t        d| d |       j                         d       y )Nz== z ==

)printdecode)rA   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 )NrQ   r   z
meta-data/)r   r   
splitlines)rA   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
rQ   r      )r   r1   r2   z=== user-data ===zN/Az=== meta-data ===z=== vendor-data ===r9   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   rA   exitr'   r   r<   r   r4   r;   apiverr   r   r   )r   r   r   parsersubcmdsnamer   r   argscredsfnamefpathr   r   r<   userdatarE   rL   r   r   r)   r   s                     @@@@r"   mainr  F  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   rW   	cloudinitr   r   r   cloudinit.net.cmdliner   cloudinit.sourcesr   	getLoggerrk   r7   rZ   r   r   r   rt   r'   r   r4   r;   r   r=   r5   r6   DEP_FILESYSTEMDEP_NETWORKr   r   r  rr   r#   r"   <module>r     s      	  / / : 1g!
	~8W'' ~8B#. #$/EB 
7-t$?N	i 		9 	 71134g,,g.A.ABC; zHT 	FY r#   