jbc@sddlZddlZddlmZddlmZddlmZddlm Z m Z ddlm Z ddlm Z ddlmZdd lmZdd lmZejeZee jgZd d d fZdZdZdZdZdZedZeegZde fdYZ!de j"fdYZ#de#fdYZ$dZ%dZ&dZ'dZ(dZ)dZ*d Z+d!Z,d"Z-e.e.d#Z/e$e j0ffe#e j0e j1ffgZ2d$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 j Z e ZdZdZd Zd Zed Zed Zd ZdZdddZdZdZedZedZdZedZedZdZ e!dZ"dZ#dZ$ddZ%ddZ&RS(R shttp://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 t j kret S|j t jkr{t S|jrtjrtjdt SyAt|j,tjdtjddd|j|_WdQXWq!tk rt SXn'tjdtjddd|j|_|js.t S|jjd d|_|jjd d|_|jjd ijd 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%t strict_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 |||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 %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|j j di|_ n|j j d|jdS|jdSdS(NRCt headers_cbRWt exception_cbR0t instanceIds instance-id(R7RRtgetattrR#Retec2tget_instance_identityR$RXR]t_refresh_stale_aws_token_cbR@RCRA(R%t api_version((sC/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceEc2.pytget_instance_ids     c Cs|jtjkrdSg}i}t}d}x7|D]/}dj||} |j| ||| %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|jd kr9tjdd Sd }td|jko`|jt j k}|rtj dt j dtj ddd|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 ||j d|j d|d||ds>              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_waitt url_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\}}}|d krgtd||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(NtuuidRjt uuid_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.pytsss'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 sL           + #