Current File : //lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyc
�
�jbc@s�ddlZddlZddlmZddlmZddlmZddlm	Z	m
Z
ddlmZddlmZ
ddlmZdd	lmZdd
lmZeje�Zee
jg�Zddd
fZdZdZdZdZdZedZeegZde fd��YZ!dej"fd��YZ#de#fd��YZ$d�Z%d�Z&d�Z'd�Z(d�Z)d�Z*d �Z+d!�Z,d"�Z-e.e.d#�Z/e$ej0ffe#ej0ej1ffgZ2d$�Z3dS(%i����N(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
Zd�Zd�Zd	�Zd
�Zed��Zed��Zd
�Zd�Zddd�Zd�Zd�Zed��Zed��Zd�Zed��Zed��Zd�Z e!d�Z"d�Z#d�Z$dd�Z%dd�Z&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"NscCst�S(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Cs�ttj|jtt�d�\}}tjd||j	|j
�|dkre|j	tjkret
S|j	tjkr{t
S|jr�tj�r�tjd�t
SyAt|j��,tjdtjddd|j�|_WdQXWq!tk
r�t
SXn'tjdtjddd|j�|_|js.t
S|jjd	d�|_|jjd
d�|_|jjdi�jdi�jd
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|jjdi�jdi�}x6|jdi�j�D]\}}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|jjd�S(Nsami-launch-index(RAR#R@(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytlaunch_index�s	cCsIt|d�s$tjj�|_n|jsBtjj�|_n|jS(Nt_platform_type(thasattrR tdsnametlowerRQ(R%((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR8�s
	cCs�d}|j�}x�|jD]�}|j|j|�}y"tjd|d|dt�}Wn)tjk
r�}tj	d||�qX|j
dkr�tj	d|�|S|j
dkrd	}tj	|||j�qqW|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 %si�s#Found preferred metadata version %si�s0Metadata 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_version�s 

c	Cs�|jtjkr�t|dd�so|j�}tj||jd|j	dt
d|j�jdi�|_
n|j
jd|jd�S|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_id�s		cCs�|jtjkrdSg}i}t}d}x7|D]/}dj||�}	|j|	�|||	<q5Wtjd�tj	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_token�s$


		cCs"|j}|j�}|jdkr(tS|jd|j�}g|D]}tj|�rD|^qD}t|�t|�kr�t	j
dtt|�t|���nt|�r�|}nt	j
d�|j}|j|�}|s�|jtkrt	j
d�ng}i}djd|j�}	d}
x7|D]/}d	j||	�}|j|�|||<q3Wtj�}
tjd
|d|jd|jd
t	j
dtd|jd|
�\}}|r�||}q�n|r�||_t	j
d|j�n#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@R�Rtis_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_service�sP	(	 	
		

			cCsAd|jkrdSd}|jd}t|t�sItjd|�dSxQ|j�D]C\}}||krx|}Pn|dkrV|dkrV|}qVqVW|dkr�tjd|�dS|}|jd�s�d|}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|jdd�S|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@R�R#(R%R�taz((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�Ss	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|jdkr9tjd�dSd}td|jko`|jt	j
k�}|r�tjd�tj
dtjddd|j�n|j}i|tj|�6}|jjd�}t|t�rt|d|d	|�}|j�r/|jdjtj�q/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#R5R�R�R7RRR6RR=tget_dataR<Rtget_interface_macR@R�R�t#convert_ec2_metadata_network_configROt
update_eventstaddR	tBOOT(R%tresulttno_network_metadata_on_awstifaceR�tnet_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#RiR�R!R R<(R%t
_legacy_fbnic((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR<�s	c	CsB|j�siS|j�}t}i}|jtjkrO|j}|j}n
d
}}y�t	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|j�iSX||d	<|S(s�Crawl 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(R�ReR]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�|jtjkrdStjd�i|t6}dj|jt	�}y%t
j|d|dtdd�}Wn*t
j
k
r�}tjd||�dSX|jS(	s�Request 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^R�tcontents(R%tsecondstrequest_headert	token_urlR~Rd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt_refresh_api_token�s



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.pyR��s
cCs>t|tj�r:|jdkr:tjd�d|_ntS(s=Exception handler for Ec2 to refresh token if token is stale.i�s+Clearing cached Ec2 API token due to expiryN(	R�R[R^R_R5R6R#RyRD(R%R-R�((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRl�s!
cCs6tj|�d|kr2tjd�t|_ndS(NsRead timed outs.Cannot use Ec2 IMDSv2 API tokens, using IMDSv1(R5R�R�Ry(R%R-texc((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRx�s

tcCsx|jtjks!|jtkr%iSitt6}t|krB|S|jsj|j�|_|jsjiSni|jt	6S(s�Return 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.
        (
R7RRRyR�tAWS_TOKEN_TTL_SECONDSR�RuR�tAWS_TOKEN_PUT_HEADER(R%RUtrequest_token_header((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyRX�s	
		N('RRRSR�R`RYturl_max_waitturl_timeoutR#RyRR�R�R9R:R"R*RGROtpropertyRPR8ReRnRR�R�R�R�R�R�R<R>R�R�R�RlRxRX(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR 5s>					#	
				8	3	/
	'			tDataSourceEc2LocalcBseZdZeZd�ZRS(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||j�tStt|�j�S(Ns+Local Ec2 mode only supported on %s, not %s(	RRR7R5R6R9R!R�R�(R%tsupported_platforms((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�s	
(RRt__doc__RDR:R�(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�scCs6yt|�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||f��n|r�yt|�}Wq�tk
r�td||f��q�Xnd}||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(R�N(swarni(strueR�swarn(RDR#R9t	partitionR�R�(R�tmodeR�tsleep((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�+s&
cCsjyt|�\}}Wn!tk
r9}tj|�dSX|dkrJdStjd|dtd|�dS(NR�t
non_ec2_mdR�R�(R�R�R5R�Rtshow_warningRD(R�R�R�R�Rd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�Is
cCsB|djd�r>|ddks7|d|dkr>tjSdS(NtuuidRjtuuid_sourcet
hypervisortserial(R�RRR#(tdata((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_awsVs
cCs|djd�rtjSdS(NR�s.brightbox.com(tendswithRR(R�((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytidentify_brightbox`scCs|djd�rtjSdS(Nt	asset_tags
.zstack.io(R�RR(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�}ttttd�f}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_dataR�R�R�R�R�R5R�(R�tcheckstcheckerR�Rd((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR)os		
	cCsi}y#tjd�j�}d|d<Wn*tk
rUtjd�}d|d<nX|dkrkd}n|j�|d<tjd�}|dkr�d}n|j�|d	<tjd
�}|dkr�d}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/uuidR�R�ssystem-uuidtdmiR�R�ssystem-serial-numberR�schassis-asset-tagR�ssystem-manufacturerR�N(Rt	load_filetstripR�t
read_dmi_dataR#RT(R�R�R�R�R�((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR�~s*

			c	Csidd6gd6}|s)tj�}n|dd}x�|j�D]�\}}|j|�}|skqDnidd6|d6gd	6}||d
<||ks�|jd�s�|jd�r�|d	jid
d6�n|jd�r�|d	jidd6�n|dj|�qDW|S(s�Convert 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.
    itversiontconfigRIRJtphysicalttypeR�tsubnetstmac_addressspublic-ipv4sslocal-ipv4stdhcp4tipv6stdhcp6(Rtget_interfaces_by_macRKR@Rv(	t
network_mdR�R�tnetcfgt
macs_metadatatmactnic_nametnic_metadatatnic_cfg((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyR��s"
cCstj|t�S(N(Rtlist_from_dependstdatasources(tdepends((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytget_datasource_list�s(4R�R�t	cloudinitRRjRtloggingRtcloudinit.net.dhcpRRRRR[RRtcloudinit.eventR	t	getLoggerRR5t	frozensett	NOT_FOUNDtSKIP_METADATA_URL_CODESR3R4RuR�R�R�R�R]tobjectRt
DataSourceR R�R1R�R�R�R�R�R�R)R�R#R�tDEP_FILESYSTEMtDEP_NETWORKRR(((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pyt<module>sL
��			
	
					+#