Viewing File: /usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyc


jbc@sddlZddlZddlmZddlmZddlmZddlm	Z	m
Z
ddlmZddlmZ
ddlmZdd	lmZdd
lmZejeZee
jgZddd
fZdZdZdZdZdZedZeegZde fdYZ!dej"fdYZ#de#fdYZ$dZ%dZ&dZ'dZ(dZ)dZ*d Z+d!Z,d"Z-e.e.d#Z/e$ej0ffe#ej0ej1ffgZ2d$Z3dS(%iN(t	ec2_utils(tlog(tnet(tEphemeralDHCPv4tNoDHCPLeaseError(tsources(t
url_helper(tutil(twarnings(t	EventTypet
datasourcetEc2t	strict_idtwarnslatest/api/tokent_ec2_disable_api_tokent21600sX-aws-ec2-metadata-tokens-ttl-secondst
CloudNamescBs2eZdZdZdZdZdZdZdZRS(taliyuntawst	brightboxtzstackte24cloudtunknownsno-ec2-metadata(	t__name__t
__module__tALIYUNtAWSt	BRIGHTBOXtZSTACKtE24CLOUDtUNKNOWNtNO_EC2_METADATA(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR'st
DataSourceEc2cBsCeZdZddgZdZdgZdZdZdZ	e
jZe
ZdZdZd	Zd
ZedZedZd
ZdZdddZdZdZedZedZdZedZedZdZ e!dZ"dZ#dZ$ddZ%ddZ&RS(Rshttp://169.254.169.254shttp://instance-data.:8773s
2009-04-04s
2016-09-02ixi2cCs)tt|j|||d|_dS(N(tsuperR t__init__tNonetmetadata_address(tselftsys_cfgtdistrotpaths((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR"NscCstS(s5Return the cloud name as identified during _get_data.(tidentify_platform(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt_get_cloud_nameRscCsttj|jttd\}}tjd||j	|j
|dkre|j	tjkret
S|j	tjkr{t
S|jrtjrtjdt
SyAt|j,tjdtjddd|j|_WdQXWq!tk
rt
SXn'tjdtjddd|j|_|js.t
S|jjd	d|_|jjd
d|_|jjdijdijd
i|_tS(NR
s0strict_mode: %s, cloud_name=%s cloud_platform=%sttrues1FreeBSD doesn't support running dhclient with -sftlogfunctmsgsCrawl of metadata servicetfuncs	meta-datas	user-datatdynamicsinstance-identitytdocument(swarnN(tread_strict_modeRtget_cfg_by_pathR&tSTRICT_ID_PATHtSTRICT_ID_DEFAULTR#tLOGtdebugt
cloud_nametplatformRRtFalseRtperform_dhcp_setupt
is_FreeBSDRtfallback_interfacetlog_timetcrawl_metadatat_crawled_metadataRtgettmetadatatuserdata_rawtidentitytTrue(R%tstrict_modet_sleep((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt	_get_dataVs<		
	
			'cCsk|js
tS|jjdijdi}x6|jdijD]\}}d|krGtSqGWtS(s6Report if this instance type is Ec2 Classic (non-vpc).tnetworkt
interfacestmacssvpc-id(RAR9R@titemsRD(R%t	ifaces_mdt_mactmac_data((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytis_classic_instanceys	!%cCs|js
dS|jjdS(Nsami-launch-index(RAR#R@(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytlaunch_indexs	cCsIt|ds$tjj|_n|jsBtjj|_n|jS(Nt_platform_type(thasattrR tdsnametlowerRQ(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR8s
	cCsd}|j}x|jD]}|j|j|}y"tjd|d|dt}Wn)tjk
r}tj	d||qX|j
dkrtj	d||S|j
dkrd	}tj	|||jqqW|jS(
sEGet the best supported api version from the metadata service.

        Loop through all extended support metadata versions in order and
        return the most-fully featured metadata api version discovered.

        If extended_metadata_versions aren't present, return the datasource's
        min_metadata_version.
        s{0}/{1}/meta-data/instance-idturltheaderstheaders_redactsurl %s raised exception %sis#Found preferred metadata version %sis0Metadata api version %s not present. Headers: %s(
t_get_headerstextended_metadata_versionstformatR$tuhelptreadurltAWS_TOKEN_REDACTtUrlErrorR5R6tcodeRVtmin_metadata_version(R%turl_tmplRVtapi_verRUtrespteR-((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytget_metadata_api_versions 

c	Cs|jtjkrt|ddso|j}tj||jd|j	dt
d|jjdi|_
n|j
jd|jdS|jdSdS(NRCt
headers_cbRWtexception_cbR0t
instanceIdsinstance-id(R7RRtgetattrR#Retec2tget_instance_identityR$RXR]t_refresh_stale_aws_token_cbR@RCRA(R%tapi_version((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytget_instance_ids		cCs|jtjkrdSg}i}t}d}x7|D]/}dj||}	|j|	|||	<q5Wtjdtj	d|ddddd|j
d	|jd
|dt\}}
|r|
r|
|_
||SdS(NtPUTs{0}/{1}sFetching Ec2 IMDSv2 API Tokenturlstmax_waitittimeoutt	status_cbRftrequest_methodRW(R7RRtAPI_TOKEN_ROUTERZtappendR5R6R[twait_for_urlt
_status_cbRXR]t
_api_token(R%tmdurlsRrRqRpturl2baseturl_pathRtRUtcurtresponse((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt_maybe_fetch_api_tokens$


		cCs"|j}|j}|jdkr(tS|jd|j}g|D]}tj|rD|^qD}t|t|krt	j
dtt|t|nt|r|}nt	j
d|j}|j|}|s|jtkrt	j
dng}i}djd|j}	d}
x7|D]/}d	j||	}|j||||<q3Wtj}
tjd
|d|jd|jd
t	j
dtd|jd|
\}}|r||}qn|r||_t	j
d|jn#t	jd|ttj|
t|S(Nit
metadata_urlss,Removed the following from metadata urls: %ss+Empty metadata url list! using default listsRetrying with IMDSv1s{ver}/meta-data/instance-idtvertGETs{0}/{1}RpRqRrRsRWRfRtsUsing metadata source: '%s's(Giving up on md from %s after %s seconds(tds_cfgtget_url_paramstmax_wait_secondsR9R@RRtis_resolvable_urltsetR5R6tlisttlentwarningRRytAPI_TOKEN_DISABLEDRZR`RvttimeR[Rwttimeout_secondsR]RXR$tcriticaltinttbool(R%tmcfgt
url_paramsRztxtfilteredR$RpR{R|RtRUR}t
start_timet_((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytwait_for_metadata_servicesP	(	 	
		

			cCsAd|jkrdSd}|jd}t|tsItjd|dSxQ|jD]C\}}||krx|}Pn|dkrV|dkrV|}qVqVW|dkrtjd|dS|}|jdsd|}ntj	j
|r|S|jtj	j|}|r-tjd|||S|dkr=dS|S(	Nsblock-device-mappings+block-device-mapping not a dictionary: '%s't	ephemeralt
ephemeral0s Unable to convert %s to a devicet/s/dev/%ssRemapped device name %s => %s(
RAR#t
isinstancetdictR5R6RKt
startswithtostpathtexistst
_remap_devicetbasename(R%tnametfoundtbdmtentnametdevicetofoundtremapped((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytdevice_name_to_devices8


cCs\yC|jtjkr3|jjd|jddS|jddSWntk
rWdSXdS(NtavailabilityZonet	placementsavailability-zone(R7RRRCR@RAtKeyErrorR#(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytavailability_zoneGs	
cCsi|jtjkrH|jjd}|jrD|rD|jd }n|S|j}|dk	re|d SdS(Ntregioni(R7RRRCR@RR#(R%Rtaz((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRSs	cCs?|s
dS|jtjkr;ttj|tt|ndS(N(R7RRtwarn_if_necessaryRR2R3R4(R%tcfgtis_new_instance((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytactivateascCs?|jtjkr|jS|jdkr9tjddSd}td|jko`|jt	j
k}|rtjdtj
dtjddd|jn|j}i|tj|6}|jjd}t|trt|d|d	|}|jr/|jdjtjq/ntjd
|||_|jS(s@Return a network config dict for rendering ENI or netplan files.s8Unexpected call to network_config when metadata is None.RHsPMetadata 'network' not present: Refreshing stale metadata from prior to upgrade.R,R-sRe-crawl of metadata serviceR.tmacs_to_nicstfallback_nics%Metadata 'network' key not valid: %s.N(t_network_configRtUNSETRAR#R5RRR7RRR6RR=tget_dataR<Rtget_interface_macR@RRt#convert_ec2_metadata_network_configROt
update_eventstaddR	tBOOT(R%tresulttno_network_metadata_on_awstifaceRtnet_md((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytnetwork_configis4
	
	
	cCsV|jdkrOt|dd}|r<||_d|_qOtt|jSn|jS(NR(t_fallback_interfaceR#RiRR!R R<(R%t
_legacy_fbnic((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR<s	c	CsB|jsiS|j}t}i}|jtjkrO|j}|j}n
d
}}yt	j
||jd|jd|d||d<t	j
||jd|jd|d||d<|jtjkrt	j||jd|jd|d|}i|d6|d<nWn(tk
r3tjtd|jiSX||d	<|S(sCrawl metadata service when available.

        @returns: Dictionary of crawled metadata content containing the keys:
          meta-data, user-data and dynamic.
        RfRWRgs	user-datas	meta-datasinstance-identityR/s'Failed reading from metadata address %st_metadata_api_versionN(RReR]R7RRRlt#_skip_or_refresh_stale_aws_token_cbR#Rjtget_instance_userdataR$RXtget_instance_metadataRkt	ExceptionRtlogexcR5(R%Rmtredacttcrawled_metadatatexc_cbt	exc_cb_udRC((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR>s>	


	


cCs|jtjkrdStjdi|t6}dj|jt	}y%t
j|d|dtdd}Wn*t
j
k
r}tjd||dSX|jS(	sRequest new metadata API token.
        @param seconds: The lifetime of the token in seconds

        @return: The API token or None if unavailable.
        s!Refreshing Ec2 metadata API tokens{}/{}RVRWRtRos/Unable to get API token: %s raised exception %sN(R7RRR#R5R6tAWS_TOKEN_REQ_HEADERRZR$RuR[R\R]R^Rtcontents(R%tsecondstrequest_headert	token_urlR~Rd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt_refresh_api_tokens



cCs2tjtj||}|s"tS|j||S(sVCallback will not retry on SKIP_USERDATA_CODES or if no token
           is available.(Rjtskip_retry_on_codestSKIP_USERDATA_CODESR9Rl(R%R-t	exceptiontretry((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRs
cCs>t|tjr:|jdkr:tjdd|_ntS(s=Exception handler for Ec2 to refresh token if token is stale.is+Clearing cached Ec2 API token due to expiryN(	RR[R^R_R5R6R#RyRD(R%R-R((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRls!
cCs6tj|d|kr2tjdt|_ndS(NsRead timed outs.Cannot use Ec2 IMDSv2 API tokens, using IMDSv1(R5RRRy(R%R-texc((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRxs

tcCsx|jtjks!|jtkr%iSitt6}t|krB|S|jsj|j|_|jsjiSni|jt	6S(sReturn a dict of headers for accessing a url.

        If _api_token is unset on AWS, attempt to refresh the token via a PUT
        and then return the updated token header.
        (
R7RRRyRtAWS_TOKEN_TTL_SECONDSRRuRtAWS_TOKEN_PUT_HEADER(R%RUtrequest_token_header((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRXs	
		N('RRRSRR`RYturl_max_waitturl_timeoutR#RyRRRR9R:R"R*RGROtpropertyRPR8ReRnRRRRRRRR<R>RRRRlRxRX(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR 5s>					#	
				8	3	/
	'			tDataSourceEc2LocalcBseZdZeZdZRS(syDatasource run at init-local which sets up network to query metadata.

    In init-local, no network is available. This subclass sets up minimal
    networking with dhclient on a viable nic so that it can talk to the
    metadata service. If the metadata service provides network configuration
    then render the network configuration for that instance based on metadata.
    cCsHtjf}|j|kr5tjd||jtStt|jS(Ns+Local Ec2 mode only supported on %s, not %s(	RRR7R5R6R9R!RR(R%tsupported_platforms((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRs	
(RRt__doc__RDR:R(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRscCs6yt|SWn!tk
r1}tj||SXdS(N(tparse_strict_modet
ValueErrorR5R(tcfgvaltdefaultRd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR1#s

cCs|tkrdS|tkr d	S|s*d
S|jd\}}}|dkrgtd||fn|ryt|}Wqtk
rtd||fqXnd}||fS(NR+tfalseR
it,sUInvalid mode '%s' in strict_id setting '%s': Expected one of 'true', 'false', 'warn'.s<Invalid sleep '%s' in strict_id setting '%s': not an integer(strueN(RN(swarni(strueRswarn(RDR#R9t	partitionRR(RtmodeRtsleep((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR+s&
cCsjyt|\}}Wn!tk
r9}tj|dSX|dkrJdStjd|dtd|dS(NRt
non_ec2_mdRR(RRR5RRtshow_warningRD(RRRRRd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRIs
cCsB|djdr>|ddks7|d|dkr>tjSdS(NtuuidRjtuuid_sourcet
hypervisortserial(RRRR#(tdata((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_awsVs
cCs|djdrtjSdS(NRs.brightbox.com(tendswithRR(R((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_brightbox`scCs|djdrtjSdS(Nt	asset_tags
.zstack.io(RRR(R((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_zstackescCs|ddkrtjSdS(NtvendorR(RR(R((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_e24cloudjscCs|t}ttttdf}xT|D]L}y||}|rG|SWq(tk
rs}tjd|||q(Xq(WdS(NcSstjS(N(RR(R((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt<lambda>sss'calling %s with %s raised exception: %s(t_collect_platform_dataRRRRRR5R(RtcheckstcheckerRRd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR)os		
	cCsi}y#tjdj}d|d<Wn*tk
rUtjd}d|d<nX|dkrkd}n|j|d<tjd}|dkrd}n|j|d	<tjd
}|dkrd}n|j|d<tjd}|r|ndj|d
<|S(s9Returns a dictionary of platform info from dmi or /sys/hypervisor.

    Keys in the dictionary are as follows:
       uuid: system-uuid from dmi or /sys/hypervisor
       uuid_source: 'hypervisor' (/sys/hypervisor/uuid) or 'dmi'
       serial: dmi 'system-serial-number' (/sys/.../product_serial)
       asset_tag: 'dmidecode -s chassis-asset-tag'
       vendor: dmi 'system-manufacturer' (/sys/.../sys_vendor)

    On Ec2 instances experimentation is that product_serial is upper case,
    and product_uuid is lower case.  This returns lower case values for both.
    s/sys/hypervisor/uuidRRssystem-uuidtdmiRRssystem-serial-numberRschassis-asset-tagRssystem-manufacturerRN(Rt	load_filetstripRt
read_dmi_dataR#RT(RRRRR((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR~s*

			c	Csidd6gd6}|s)tj}n|dd}x|jD]\}}|j|}|skqDnidd6|d6gd	6}||d
<||ks|jds|jdr|d	jid
d6n|jdr|d	jidd6n|dj|qDW|S(sConvert ec2 metadata to network config version 1 data dict.

    @param: network_md: 'network' portion of EC2 metadata.
       generally formed as {"interfaces": {"macs": {}} where
       'macs' is a dictionary with mac address as key and contents like:
       {"device-number": "0", "interface-id": "...", "local-ipv4s": ...}
    @param: macs_to_nics: Optional dict of mac addresses and nic names. If
       not provided, get_interfaces_by_mac is called to get it from the OS.
    @param: fallback_nic: Optionally provide the primary nic interface name.
       This nic will be guaranteed to minimally have a dhcp4 configuration.

    @return A dict of network config version 1 based on the metadata and macs.
    itversiontconfigRIRJtphysicalttypeRtsubnetstmac_addressspublic-ipv4sslocal-ipv4stdhcp4tipv6stdhcp6(Rtget_interfaces_by_macRKR@Rv(	t
network_mdRRtnetcfgt
macs_metadatatmactnic_nametnic_metadatatnic_cfg((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRs"
cCstj|tS(N(Rtlist_from_dependstdatasources(tdepends((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytget_datasource_lists(4RRt	cloudinitRRjRtloggingRtcloudinit.net.dhcpRRRRR[RRtcloudinit.eventR	t	getLoggerRR5t	frozensett	NOT_FOUNDtSKIP_METADATA_URL_CODESR3R4RuRRRRR]tobjectRt
DataSourceR RR1RRRRRRR)RR#RtDEP_FILESYSTEMtDEP_NETWORKRR(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt<module>sL
			
	
					+#
Back to Directory File Manager