oB]c@sddlmZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ej e Z dZddeefd d eefd d eefd d eefd d eefgZdejfdYZdZdZdZddedddZdZdefdYZdefdYZeejejffgZdZ e dkrdZ!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 ZdZedZ dZ dZ dZ dZ dZd 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|jtSWn<tk r@n,tk rk}tjd|j|nX|j dd}|st SyL|j |st S|j|t |d|jjd|jddtSWn%tk rtjtd|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+||krt|jd|}nWn!tk rtjd|nXt j }|j dr|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/is%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_idsN(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(sReturn 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.pyRs.cCsTd}djg|D]}|j|d^q}dtj|jdjS( 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.pyRs.cCsm|jdr|d}ntjj| sJttj|dkrYtdntd|ddS(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|jdr4|d }ni}x.tD]&\}}} } |d krrd||f} nd|||f} ytj|} || d|d|d| } | jr| r| j||//meta-data/instance-id * //meta-data/local-hostname * //user-data If version is None, then / will not be used. R?is%s/%ss%s/%s/%sRR>t ssl_detailss4Fetching from %s resulted in an invalid http code %sisMissing 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}xtD]\}}}}||krM|s|j|qqnd|kr|jd\}} } ||kri||\}}}t"d?t"|dkrd@n |j#t"dA|j|t"dB|j|dkr'd@n|nc|jdkrP|jnD|jdkr|jj$d:sdC|j|_n|jndS(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 iNt 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. icsj|ddjS(NRi(R*Rr(R/(R(sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytgeturlescs$td||jfdS(Ns == %s == %s (tprinttdecode(R/(R(sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pytprinturliscs|jdrx|jjD]c}|jdrTd||fq(|dkrwd|dfq(d||fq(Wn |dS(NR?s%s%ss meta-datas meta-data/(RCRt splitlines(R/tline(RRR(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(RR(%targparsetpprinttsystArgumentParsert add_argumentR RDtadd_subparserst add_parsert parse_argstckeyttkeyttsectcsectconfigR R texiststaccesstR_OKtstderrtwriteRt read_confR\R/texitRRR*RiR R)tapiverRRRC(RRRtparsertsubcmdstnameRRtargstcredstfnametfpathR[RR*tuserdataR2R:((RRRRsD/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_NETWORKRRR(((sD/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceMAAS.pyt s8    . &   i