ó oBú]c@s¢ddlmZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ej e ƒZ dZddeefd d eefd d eefd d eefd d eefgZdejfd„ƒYZd„Zd„Zd„Zddeddd„Zd„Zdefd„ƒYZdefd„ƒYZeejejffgZd„Z e dkržd„Z!e!ƒndS(iÿÿÿÿ(tprint_functionN(tlog(tsources(t url_helper(tutils 2012-03-01smeta-data/instance-idsmeta-data/local-hostnamesmeta-data/public-keyssmeta-data/vendor-datas vendor-datas user-datatDataSourceMAAScBsneZdZdZd Zd Zd„Zed„ƒZ d„Z d„Z d„Z d„Z d„Zd „ZRS( sç 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 tMAAScCsStjj||||ƒd|_tjj|jdƒ|_t |j ƒ|_ dS(Ntmaas( Rt DataSourcet__init__tNonetbase_urltostpathtjointseed_dirtget_id_from_ds_cfgtds_cfgtid_hash(tselftsys_cfgtdistrotpaths((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR 0s cCs%|jst|jƒ|_n|jS(N(t _oauth_helpertget_oauth_helperR(R((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyt oauth_helper6s cCs#tjj|ƒ}d||jfS(Ns%s [%s](RRt__str__R (Rtroot((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR<sc Cs|j}y$|j|jt|jƒƒtSWn<tk r@n,tk rk}tjd|j|ƒ‚nX|j ddƒ}|sˆt SyL|j |ƒsžt S|j|t |d|jjd|jddƒƒtSWn%tk rûtjtd|ƒt SXdS(Ns%s was malformed: %st metadata_urltread_file_or_urlRtretriesis$Failed fetching metadata from url %s(Rt _set_dataRtread_maas_seed_dirtTruetMAASSeedDirNonetMAASSeedDirMalformedtLOGtwarningtgetR tFalsetwait_for_metadata_servicetread_maas_seed_urlRtreadurlRt ExceptionRtlogexc(Rtmcfgtexcturl((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyt _get_data@s.   cCs…||_|\}}}||_||_||_|rytj|ƒ|_Wqtk r}}tj d|ƒd|_qXndS(Ns"Invalid content in vendor-data: %s( R t userdata_rawtmetadatatvendordata_pureRtconvert_vendordatatvendordata_rawt ValueErrorR$R%R (RR/tdatatudtmdtvdte((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyRbs    cCs d|jS(s/Return the subplatform metadata source details.s seed-dir (%s)(R (R((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyt_get_subplatformpsc Cse|j}d}yt|jd|ƒƒ}Wn$tk rQtjtd|ƒnX|dkrbtSd}y+||kr’t|jd|ƒƒ}nWn!tk r¶tjd|ƒnXt j ƒ}|j dƒrß|d }nd |t f}|g}|j j d |d|d|ƒ\}}|r8tjd |ƒn#tjd |tt j ƒ|ƒƒt|ƒS(Nixtmax_waits Failed to get max wait. using %sii2ttimeoutsFailed to get timeout, using %st/iÿÿÿÿs%s/%s/meta-data/instance-idturlssUsing metadata source: '%s's(Giving up on md from %s after %i seconds(RtintR&R+RR,R$R'R%ttimetendswitht MD_VERSIONRt wait_for_urltdebugtcriticaltbool( RR/R-R=R>t starttimet check_urlR@t _response((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR(ts4          cCsD|jdkrtStj|d|jfiƒ}|jt|ƒkS(slocally 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.t datasourceN(RR R'Rtget_cfg_by_pathtdsnameR(RRtncfg((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytcheck_instance_id–sN(t__name__t __module__t__doc__RNR RRR tpropertyRRR0RR<R(RP(((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR!s    "   "cCsAd}tg|D]}||j|ƒf^qƒ}tj|S(s°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.t consumer_keytconsumer_secrett token_keyt token_secret(RURVRWRX(tdictR&RtOauthUrlHelper(tcfgtkeystrtkwargs((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR¢s.cCsTd}djg|D]}|j|dƒ^qƒ}dtj|jdƒƒjƒS( s;Given a config, generate a unique identifier for this node.RURWRXttsv1:sutf-8(s consumer_keys token_keys token_secret(RR&thashlibtsha256tencodet hexdigest(Rtfieldstftidstr((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR¬s.cCsm|jdƒr|d}ntjj|ƒ sJttj|ƒƒdkrYtdƒ‚ntd|ddƒS(Nsfile://iis%s: not a directorys file://%stversion( t startswithR R tisdirtlentlistdirR"R)R (tseed_d((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR µs  .c Csx|d krtj}n|jdƒr4|d }ni}x.tD]&\}}} } |d krrd||f} nd|||f} y‚tj|ƒ} || d|d|d| ƒ} | jƒrð| r×| j||//meta-data/instance-id * //meta-data/local-hostname * //user-data If version is None, then / will not be used. R?iÿÿÿÿs%s/%ss%s/%s/%sRR>t ssl_detailss4Fetching from %s resulted in an invalid http code %si”sMissing required %s: %sN(R RRRCt DS_FIELDSRtfetch_ssl_detailstoktcontentst decode_binaryR$R%tcodetUrlErrorR#tcheck_seed_contents(tseed_urlRR>RhRRR9R t _dictnametbinarytoptionalR/RntrespR;((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyR)¿s4       c Csti}g}x¢tD]š\}}}}||krM|s|j|ƒqqnd|krŸ|jdƒ\}} } ||krŠi||ƒ\}}}t"d?ƒt"|dkrád@n |j#ƒƒt"dAƒ|j|ƒt"dBƒ|j|dkr'd@n|ƒnc|jdkrPˆ|jƒnD|jdkr”|jj$d:ƒs„dC|j|_nˆ|jƒndS(Hsä 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 iÿÿÿÿNt descriptionsInteract with MAAS DSs--configtmetavartfilethelpsspecify DS config fileR|s--ckeytkeysthe consumer key to auth withs--tkeysthe token key to auth withs--csectsecretsthe consumer secret (likely '')R`s--tsecsthe token secret to auth withs--apiverRhs the apiver to use ( can be used)ttitlet subcommandstdesttsubcmdtcrawlscrawl the datasourceR&sdo a single GET of provided urls check-seedsread and verify seed at urlR/sthe datasource urltnargst?RURWRXRVt91_kernel_cmdline_urlt 90_dpkg_maass/etc/cloud/cloud.cfg.d/s.cfgsUsed config in %s. RLRRs)Must provide a url or a config with url. icsˆj|ddƒjS(NRi(R*Rr(R/(R(sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytgeturlescs$td|ˆ|ƒjƒfƒdS(Ns == %s == %s (tprinttdecode(R/(R¢(sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytprinturliscs |jdƒr’xŠˆ|ƒjƒjƒD]c}|jdƒrTˆd||fƒq(|dkrwˆd|dfƒq(ˆd||fƒq(Wn ˆ|ƒdS(NR?s%s%ss meta-datas meta-data/(RCR¤t splitlines(R/tline(RR¢R¥(sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyRls sChecking seed at %s iR?sfile://RRis=== user-data ===sN/As=== meta-data ===s=== vendor-data ===s%s/(scrawlscrawl the datasource(sgetsdo a single GET of provided url(s check-seedsread and verify seed at url(R R¡(%targparsetpprinttsystArgumentParsert add_argumentR RDtadd_subparserst add_parsert parse_argstckeyttkeyttsectcsectconfigR R texiststaccesstR_OKtstderrtwriteRt read_confR\R/texitRRœR*RiR R)tapiverR£R¤RC(R¨R©RªtparsertsubcmdstnameR–R‹targstcredstfnametfpathR[R—R*tuserdataR2R:((RR¢RR¥sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytmain(sŠ           '     % "   "("t __future__RRaR RBt cloudinitRtloggingRRRt getLoggerRQR$RDR'R!RoRRRRR R R)RvR+R"R#tDEP_FILESYSTEMt DEP_NETWORKRR‘RÅ(((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyt s8    . &   i