oB]c@sddlZddlmZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl m Z ddlmZddl mZdd l mZdd l mZdd lmZdd lmZd ZdZdZdZeeegZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&e j'e(Z)iddfd6ddfd 6d!d"fd#6Z*d$d%d&d'd(fZ+ed)e+e+Z,d*e-fd+YZ.d,e-fd-YZ/d.fd/Z0e#d0Z1ed1d2d3d4gZ2ej3ej4de5fd5YZ6d6Z7d7Z8d8Z9d9d:Z:d;Z;e<d<Z=d=e>fd>YZ?d?Z@dS(@iN(t namedtuple(t write_json(timporter(tlog(tnet(t EventType(t type_utils(t user_data(tutil(t launch_index(teventstdisabledtlocalRtpasst FILESYSTEMtNETWORKt DataSources|EXPERIMENTAL: The structure and format of content scoped under the 'ds' key may change in subsequent releases of cloud-init.sinstance-data.jsonsinstance-data-sensitive.jsonsredacted for non-root users cloud-namet_unsettunknowns aws-chinacCs |dkS(Ntaws((tc((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt@sscn-saws-govcCs |dkS(NR((R((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRAssus-gov-s azure-chinacCs |dkS(Ntazure((R((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRBstchinatcmdlinetdst system_cfgtfallbackt initramfstNetworkConfigSourcetDataSourceNotFoundExceptioncBseZRS((t__name__t __module__(((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRMstInvalidMetaDataExceptioncBseZdZRS(s8Raised when metadata is broken, unavailable or disabled.(RR t__doc__(((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR!QstcCs7tj|}g|d/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR0Vs*    cCs|jdgs|Stj|}xw|jdD]f}|jd}|}x>|D]6}t||trW||dkrW||}qWqWW|||/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytredact_sensitive_keysus #tURLParmstmax_wait_secondsttimeout_secondst num_retriescBsmeZeZdZdZd5Zd5Zd5Z d5Z e j e j e je jfZdZdZdZieejgd6Zdefdefdifd6d7d8d9fZeZd:Zd5dZdZdZd;dZ dZ!dZ"dZ#dZ$edZ%dZ&e'dZ(e'dZ)e'dZ*dZ+e'dZ,dZ-e'dZ.dZ/e'd Z0d!Z1d"Z2d#Z3d$Z4d%Z5d&Z6d'Z7d(Z8e'd)Z9e'd*Z:d+Z;eeed,Z<d-Z=d.Z>d/Z?e@d5d5d0ZAe'd1ZBe'd2ZCd3ZDd4ZERS(<s en_US.UTF-8t_undefii itnetworkt ec2_metadatat network_jsonR3tuserdatat userdata_rawt vendordatatvendordata_rawssecurity-credentialscCs||_||_||_d|_i|_d|_d|_d|_t j |jd|j fi|_ |j si|_ n|st j|j|_n ||_dS(Nt datasource(tsys_cfgtdistrotpathstNoneRIR3RJRKRLRtget_cfg_by_pathtdsnametds_cfgtudtUserDataProcessortud_proc(tselfRNRORPRW((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt__init__s          cCs tj|S(N(Rtobj_name(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt__str__scCs|j}|j}|j}ii dgd6|d6|d6|jd6|jd6|jd6|jd6|d 6|d 6|d 6|d 6|jd 6|jd6d6S(s2Return a dictionary of standardized metadata keys.t subplatformt _beta_keyssavailability-zonetavailability_zones cloud-namet cloud_nametplatformtpublic_ssh_keyss instance-idt instance_idslocal-hostnametlocal_hostnametregiontv1(t get_hostnametget_instance_idR^R_t platform_typetget_public_ssh_keysRdR\(RXRcRbR^((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt_get_standardized_metadatas$         cCst|js dS|r|}n |j}x6|D].\}}t||r,t|||q,q,W|spt|_ndS(sReset any cached metadata attributes to datasource defaults. @param attr_defaults: Optional tuple of (attr, value) pairs to set instead of cached_attr_defaults. N(t _dirty_cachetcached_attr_defaultsthasattrtsetattrtFalse(RXt attr_defaultst attr_valuest attributetvalue((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytclear_cached_attrss   cCs-t|_|j}|s|S|j|S(sDatasources implement _get_data to setup metadata and userdata_raw. Minimally, the datasource should return a boolean True on success. (tTrueRkt _get_datatpersist_instance_data(RXt return_value((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytget_data s    c Cst|drWtjt|d}|jdd |jdd i|d6}nii|jd6d6}t|drt|d}|tkr||dd/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRwsH     cCstddS(s@Walk metadata sources, process crawled data and save attributes.slSubclasses of DataSource must implement _get_data which sets self.metadata, vendordata_raw and userdata_raw.N(tNotImplementedError(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRvIscCsE|j}y"t|jjd|j}Wn3tk r`tjtd|jjd|nX|j}y+t dt|jjd|j}Wn<tk r|j}tjtd|jjd|nX|j }y"t|jjd|j }Wn3t k r4tjtd|jjd|nXt |||S(sReturn the Datasource's prefered url_read parameters. Subclasses may override url_max_wait, url_timeout, url_retries. @return: A URLParams object with max_wait_seconds, timeout_seconds, num_retries. tmax_waits6Config max_wait '%s' is not an int, using default '%s'ittimeouts5Config timeout '%s' is not an int, using default '%s'tretriess5Config retries '%s' is not an int, using default '%s'( t url_max_waittintRTR:t ValueErrorRtlogexcRt url_timeouttmaxt url_retriest Exceptiont URLParams(RXRRR((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytget_url_paramsOs0 "  (   " cCsJ|jdkr-|jj|j|_n|rC|j|jS|jS(N(RIRQRWtprocesstget_userdata_rawt _filter_xdata(RXt apply_filter((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt get_userdatass cCs4|jdkr-|jj|j|_n|jS(N(RKRQRWRtget_vendordata_raw(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytget_vendordatazscCsM|jdkrFtj|_|jdkrFtjd|jqFn|jS(sADetermine the network interface used during local network config.s(Did not find a fallback interface on %s.N(t_fallback_interfaceRQRtfind_fallback_nicRRR_(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytfallback_interfacescCsIt|ds$|jj|_n|jsB|jj|_n|jS(Nt_platform_type(RmRStlowerR(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRhs  cCsCt|ds!|j|_n|js<|j|_n|jS(sReturn a string representing subplatform details for the datasource. This should be guidance for where the metadata is sourced. Examples of this on different clouds: ec2: metadata (http://169.254.169.254) openstack: configdrive (/dev/path) openstack: metadata (http://169.254.169.254) nocloud: seed-dir (/seed/dir/path) lxd: nocloud (/seed/dir/path) t _subplatform(Rmt_get_subplatformR(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR\s  cCs$t|dr dt|dStS(s?Subclasses should implement to return a "slug (detail)" string.tmetadata_addresss metadata (%s)(RmR~tMETADATA_UNKNOWN(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRscCs|jr|jS|jr|jjtr|jjt}t|tjra|j|_q|jj|_t j dtt |n|jj|_|jS(sReturn lowercase cloud name as determined by the datasource. Datasource can determine or define its own cloud product name in metadata. s5Ignoring metadata provided key %s: non-string type %s( t _cloud_nameR3R:tMETADATA_CLOUD_NAME_KEYR+tsixt string_typesRt_get_cloud_nameRtdebugttype(RXR_((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR_s cCs|jS(sReturn the datasource name as it frequently matches cloud name. Should be overridden in subclasses which can run on multiple cloud names, such as DatasourceEc2. (RS(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRscCs+|js dSd|jkr'|jdSdS(Ns launch-index(R3RQ(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR s   cCsHtjtj|jg}|}x|D]}|j|}q+W|S(N(R tFilterRtsafe_inttapply(RXt processed_udtfilterstnew_udtf((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRs  cCstS(N(Ro(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytis_disconnectedscCs|jS(N(RJ(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRscCs|jS(N(RL(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRscCsiS(N((RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytget_config_objscCst|jjdS(Ns public-keys(tnormalize_pubkey_dataR3R:(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRiscCsdS(s5Publish the public SSH host keys (found in /etc/ssh/*.pub). @param hostkeys: List of host key tuples (key_type, key_value), where key_type is the first field in the public key file (e.g. 'ssh-rsa') and key_value is the key itself (e.g. 'AAAAB3NzaC1y...'). N((RXthostkeys((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytpublish_host_keysscCsidd6}xp|jD]b\}}|j|s;qnx>|D]6}d||t|f}tjj|rB|SqBWqWdS(Ntvdtxvdtvtbtsds /dev/%s%s(RRR(R)R-tlenRR?texistsRQ(RXt short_nametmappingstnfromttlisttntotcand((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt _remap_devices   cCsdS(N(RQ(RXt_name((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytdevice_name_to_devicescCs4|j}y|jj}Wntk r/nX|S(s<Default locale is en_US.UTF-8, but allow distros to override(tdefault_localeROt get_localeR(RXtlocale((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRs   cCsG|jjd|jjd}|r+|S|jjdijdS(Nsavailability-zoneR^t placement(R3R:(RXt top_level_az((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR^s  cCs|jjdS(NRd(R3R:(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRd!scCs.|j sd|jkrdSt|jdS(Ns instance-idsiid-datasource(R3R,(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRg%sc Csd}d}|}|j s/|jjd r|r9d Sg}tj}tj|} | r| jddkrt| jd}qg|r|jddkrt|jd}qg|r||g}qg||g}n|jd} tj | rXg}|rtj | }n|r<t|jd}qgd| j ddg}n| jd}t |dkr|d}dj |d}n |d}|r||krd ||fS|Sd S( s;Get hostname or fqdn from the datasource. Look it up if desired. @param fqdn: Boolean, set True to return hostname with domain. @param resolve_ip: Boolean, set True to attempt to resolve an ipv4 address provided in local-hostname meta-data. @param metadata_only: Boolean, set True to avoid looking up hostname if meta-data doesn't have local-hostname present. @return: hostname or qualified hostname. Optionally return None when metadata_only is True and local-hostname data is not available. t localdomaint localhostslocal-hostnamet.isip-%st-is%s.%sN(R3R:RQRRftget_fqdn_from_hoststfindR,R;tis_ipv4t gethostbyaddrR.RR( RXtfqdnt resolve_ipt metadata_onlyt defdomaintdefhosttdomainttoksthostnamet hosts_fqdntlhost((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRf+s@     cCs|jjd|S(Nt data_source(ROtget_package_mirror_info(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRhsc Csi}xm|D]e}x\|jjD]K\}}||kr#|j|sZt||/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytupdate_metadataks(      cCstS(N(Ro(RXRN((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytcheck_instance_idscCsx|dkrt}n|dkr*t}nxG|D]?}|dkrIq1n||krY|Stjd|||Sq1W|S(Ns%invalid dsmode '%s', using default=%s(RQtDSMODE_NETWORKt VALID_DSMODESRR(t candidatestdefaulttvalidt candidate((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt_determine_dsmodes         cCsdS(N(RQ(RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytnetwork_configscCsdS(N((RX((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytfirst_instance_bootscCsdS(s(setup(is_new_instance) This is called before user-data and vendor-data have been processed. Unless the datasource has set mode to 'local', then networking per 'fallback' or per 'network_config' will have been written and brought up the OS at this point. N((RXtis_new_instance((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytsetups cCsdS(sactivate(cfg, is_new_instance) This is called before the init_modules will be called but after the user-data and vendor-data have been fully processed. The cfg is fully up to date config, it contains a merged view of system config, datasource config, user config, vendor config. It should be used rather than the sys_cfg passed to __init__. is_new_instance is a boolean indicating if this is a new instance. N((RXtcfgR((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytactivates N(suserdataN(s userdata_rawN(s vendordataN(svendordata_rawN(ssecurity-credentials((FRR RtdsmodeRRSRQRRRRRRRRRtnetwork_config_sourcesRRRRRtBOOT_NEW_INSTANCERRRlRoRkRRYR[RjRtRyRwRvRRRtpropertyRRhR\RR_RR RRRRRRiRRRRR^RdRgRfRRRt staticmethodRRRRR(((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRsx        2  $               =  %  cCsg}|s|St|tjr2t|jSt|ttfrQt|St|trxz|jD]i\}}t|tjr|g}nt|ttfrmx'|D]}|r|j |qqWqmqmWn|S(N( R+RRR,t splitlinestlistRR/R)R*(t pubkey_datatkeyst_keynametklisttpkey((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRs    c Cst|||}g|D]}tj|^q} t|krFdnd} tjd| | xt| |D]\} } tjdd| j dddd | | fd d | | fd |} yn| btjd | | |||}|j t j gr*d| | f| _ |tj| fSWdQXWqotk rWtjtd| qoXqoWddj| }t|dS(NRFR s#Searching for %s data source in: %stnames search-%sRR#t descriptionssearching for %s data from %stmessagesno %s data found from %stparents%Seeing if we can get any data from %ssfound %s data from %ssGetting data from %s faileds4Did not find any data source, searched classes: (%s)s, (t list_sourcesRRZt DEP_NETWORKRRtzipR tReportEventStackR.RRR RRRRRR(RNRORPtds_depstcfg_listtpkg_listtreportertds_listRtds_namesR}Rtclstmyreptstmsg((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt find_sources,"   c Csg}tjd|||x|D]}|jtsKdt|f}ntj||dg\}}xO|D]G}tj|}t|d} | |} | rp|j| PqpqpWq#W|S(NsLLooking for data source in: %s, via packages %s that matches dependencies %ss%s%stget_datasource_list( RRR-t DS_PREFIXRt find_modulet import_moduleR~R1( RtdependsRtsrc_listtds_nametm_locst _looked_locstm_loctmodtlistertmatches((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRs"        s system-uuidcCs9|s tStj|}|s#tS|j|jkS(N(RoRt read_dmi_dataR(Rbtfieldt dmi_value((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytinstance_id_matches_system_uuids cCs|st}n|st}n|tkr>|tkr:|S|SxEtjD]7\}}|\}}|j|rK||rK|SqKW|tkr|S|S(s@Lookup the canonical cloud-id for a given cloud_name and region.(RtCLOUD_ID_REGION_PREFIX_MAPR)R-(R_RdR`tprefixt cloud_id_testtcloud_idt valid_cloud((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytcanonical_cloud_id(s      cCs|s dSt|tjr |St|tr<tj|St|tr|tkrpt |j ddt St dnt dt |dS(sLdata: a loaded object (strings, arrays, dicts). return something suitable for cloudinit vendordata_raw. if data is: None: return None string: return string list: return data the list is then processed in UserDataProcessor dict: return convert_vendordata(data.get('cloud-init')) s cloud-inittrecurses'vendordata['cloud-init'] cannot be dicts$Unknown data type for vendordata: %sN(RQR+RRRR'R(R/Rutconvert_vendordataR:RoRR(tdataR>((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyR?;s   tBrokenMetadatacBseZRS((RR (((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyRATscCsOg}t|}x6|D].\}}|t|kr|j|qqW|S(N(RR*(R+R tret_listtdepsetR"tdeps((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pytlist_from_depends_s  (Atabct collectionsRR'RRRtcloudinit.atomic_helperRt cloudinitRRtloggingRtcloudinit.eventRRRRURtcloudinit.filtersR tcloudinit.reportingR tDSMODE_DISABLEDt DSMODE_LOCALRt DSMODE_PASSRtDEP_FILESYSTEMRR(RRRtREDACT_SENSITIVE_VALUERRRt getLoggerRRR8t_NETCFG_SOURCE_NAMESRRRR!R0R@Rt add_metaclasstABCMetatobjectRRR&RR7R=RuR?tIOErrorRARE(((s>/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.pyt sp      A