a -@=j §ã@s ddlZddlZddlZddlZddlZddlmZddlmZm Z ddl m Z m Z m Z ddl mZddl mZmZddlmZddlmZmZdd lmZdd lmZdd lmZdd lmZdd lm Z e !e"¡Z#dZ$dZ%Gdd„dƒZ&dd„Z'e&j(gZ)dZ*Gdd„de j+ƒZ,Gdd„de,ƒZ-dd„Z.dd„Z/dd„Z0dd „Z1d!d"„Z2d#d$„Z3d%d&„Z4d'd(„Z5d)d*„Z6d+d,„Z7ej8fee9efee9e9feee9e:fd-œd.d/„Z;eddd3ej8fd4d5„Z?d6d7„Z@d8d9„ZAe-e jBffe,e jBe jCffgZDd:d;„ZEdS)<éN)Úsuppress)ÚDictÚList)ÚdmiÚnetÚsources)Ú url_helper)ÚutilÚwarnings)ÚDistro)Ú EventScopeÚ EventType)Únetplan)ÚNoDHCPLeaseError)ÚEphemeralIPNetwork)ÚNicOrder)Úec2)Z datasourceÚEc2Z strict_idÚwarnc@s(eZdZdZdZdZdZdZdZdZ dS) Ú CloudNamesZawsZ brightboxZzstackÚe24cloudZoutscaleÚunknownzno-ec2-metadataN) Ú__name__Ú __module__Ú __qualname__ÚAWSÚ BRIGHTBOXÚZSTACKÚE24CLOUDÚOUTSCALEÚUNKNOWNÚNO_EC2_METADATA©r"r"úC/usr/lib/python3.9/site-packages/cloudinit/sources/DataSourceEc2.pyr$srcCs|jdkod|jvS)Né”zmeta-data/tags/)ÚcodeÚurl)Ú exceptionr"r"r#Úskip_404_tag_errors3sr(zS ENV{ID_NET_DRIVER}=="vif|ena|ixgbevf", GOTO="cloudinit_hook" GOTO="cloudinit_end" cs’eZdZUdZgd¢ZdZgd¢Zeee d<dZ dZ dZ e jZd ZejejejejejhiZejejejhiZeZ‡fd d „Zedd œ‡fd d„ Zdd„Zdd„Z dd„Z!e"dd„ƒZ#e"dd„ƒZ$e"dd„ƒZ%e"dd„ƒZ&e"dd„ƒZ'e"dd „ƒZ(e"d!d"„ƒZ)d#d$„Z*d%d&„Z+d'd(„Z,d)d*„Z-d+d,„Z.e"d-d.„ƒZ/e"d/d0„ƒZ0d1d2„Z1e"d3d4„ƒZ2d5d6„Z3dBd7d8„Z4d9d:„Z5d;d<„Z6dCd=d>„Z7dDd@dA„Z8‡Z9S)EÚ DataSourceEc2r)zhttp://169.254.169.254zhttp://[fd00:ec2::254]zhttp://instance-data.:8773z 2009-04-04)z 2021-03-23z 2018-09-24z 2016-09-02Úextended_metadata_versionséðé2NFcs,tt|ƒ |||¡d|_d|_tj|_dS©N)Úsuperr)Ú__init__Úmetadata_addressÚidentityrÚMACÚ_fallback_nic_order)ÚselfÚsys_cfgÚdistroÚpaths©Ú __class__r"r#r/uszDataSourceEc2.__init__)Úci_pkl_versionÚreturncstƒ |¡t|_tj|_dSr-)r.Ú _unpickleÚ_EXTRA_HOTPLUG_UDEV_RULESÚextra_hotplug_udev_rulesrr2r3)r4r:r8r"r#r<{s zDataSourceEc2._unpicklecCstƒS)z5Return the cloud name as identified during _get_data.)Úidentify_platform©r4r"r"r#Ú_get_cloud_name€szDataSourceEc2._get_cloud_namecCsFtt |jtt¡dƒ\}}t d||j|j ¡|dkrF|jt j krFdS|jt j krVdS|j rìt ¡rrt d¡dSzbt|j|jjddd��8}| ¡|_t d|jr®d |j›�nd ¡Wdƒn1sÈ0YWqötyèYdS0n | ¡|_|j�sdS|j d d¡|_|j d d¡|_|j d i¡ di¡ di¡|_dS)N)rNz0strict_mode: %s, cloud_name=%s cloud_platform=%sÚtrueFz1FreeBSD doesn't support running dhclient with -sfT)Úipv4Úipv6zCrawled metadata service%sú Úú meta-dataú user-dataÚdynamicúinstance-identityÚdocument)Úread_strict_moder Úget_cfg_by_pathr5ÚSTRICT_ID_PATHÚSTRICT_ID_DEFAULTÚLOGÚdebugÚ cloud_nameÚplatformrr r!Úperform_dhcp_setupZ is_FreeBSDrr6Úfallback_interfaceÚcrawl_metadataZ_crawled_metadataZ state_msgrÚgetÚmetadataZ userdata_rawr1)r4Z strict_modeZ_sleepZnetwr"r"r#Ú _get_data„s^ÿüü  ü þ&   ÿþÿzDataSourceEc2._get_datacCsL|js dS|j di¡ di¡}| di¡ ¡D]\}}d|vr0dSq0dS)z6Report if this instance type is Ec2 Classic (non-vpc).FÚnetworkÚ interfacesÚmacszvpc-idT)rXrWÚitems)r4Z ifaces_mdZ_macZmac_datar"r"r#Úis_classic_instance·sz!DataSourceEc2.is_classic_instancecCs|js dS|j d¡S)Nzami-launch-index)rXrWr@r"r"r#Ú launch_indexÄszDataSourceEc2.launch_indexcCs|jstj ¡|_|jSr-)Z_platform_typer)ÚdsnameÚlowerr@r"r"r#rSÊs zDataSourceEc2.platformcCsdS)Nzlatest/api/tokenr"r@r"r"r#Úapi_token_routeÑszDataSourceEc2.api_token_routecCsdS)NZ21600r"r@r"r"r#Úimdsv2_token_ttl_secondsÕsz&DataSourceEc2.imdsv2_token_ttl_secondscCsdS)NzX-aws-ec2-metadata-tokenr"r@r"r"r#Úimdsv2_token_put_headerÙsz%DataSourceEc2.imdsv2_token_put_headercCs |jdS)Nz -ttl-seconds)rdr@r"r"r#Úimdsv2_token_req_headerÝsz%DataSourceEc2.imdsv2_token_req_headercCs |j|jgSr-)rdrer@r"r"r#Úimdsv2_token_redactász!DataSourceEc2.imdsv2_token_redactc Cs´d}| ¡}|jD]š}| |j|¡}ztj|||jd�}Wn4tjyn}zt  d||¡WYd}~qd}~00|j dkrŽt  d|¡|S|j dkrd}t  |||j ¡q|j S) aEGet 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. z{0}/{1}/meta-data/instance-id)r&ÚheadersÚheaders_redactzurl %s raised exception %sNéÈz#Found preferred metadata version %sr$z0Metadata api version %s not present. Headers: %s) Ú _get_headersr*Úformatr0ÚuhelpÚreadurlrfÚUrlErrorrPrQr%rgÚmin_metadata_version)r4Zurl_tmplrgZapi_verr&ZrespÚeÚmsgr"r"r#Úget_metadata_api_versionås&  ý $   z&DataSourceEc2.get_metadata_api_versioncCsh|jtjkrZt|ddƒsF| ¡}tj||j|j|j |j d�  di¡|_ |j   d|j d¡S|j dSdS)Nr1©Ú headers_cbrhÚ exception_cbrKZ instanceIdz instance-id)rRrrÚgetattrrrrÚget_instance_identityr0rjrfÚ_refresh_stale_aws_token_cbrWr1rX)r4Ú api_versionr"r"r#Úget_instance_ids   ûú ÿzDataSourceEc2.get_instance_idc CsÂ|jtvrdSg}i}|j}d}|D]"}d ||¡}| |¡|||<q$t d¡d}d}| ¡} z0tj || j | j tj |j |j||jdd� \}}Wntjy¦Yn0|r¾|r¾||_||SdS)aGet an API token for EC2 Instance Metadata Service. On EC2. IMDS will always answer an API token, unless the instance owner has disabled the IMDS HTTP endpoint or the network topology conflicts with the configured hop-limit. NÚPUTú{0}/{1}zFetching Ec2 IMDSv2 API TokenF) ÚurlsÚmax_waitÚtimeoutÚ status_cbrtruÚrequest_methodrhZconnect_synchronously)rRÚ IDMSV2_SUPPORTED_CLOUD_PLATFORMSrbrkÚappendrPrQÚget_url_paramsrlÚ wait_for_urlÚmax_wait_secondsÚtimeout_secondsÚwarningrjÚ_imds_exception_cbrfrnÚ _api_token) r4Úmdurlsr}Úurl2baseÚurl_pathr�r&ÚcurÚresponseÚ url_paramsr"r"r#Ú_maybe_fetch_api_tokens@     ÷ z$DataSourceEc2._maybe_fetch_api_tokenc Csvg}d}|j}| ¡}|jdkr$dS| d|j¡}dd„|Dƒ}t|ƒt|ƒkrlt dtt|ƒt|ƒƒ¡t |ƒrz|}nt  d¡|j}|  |¡}|�s |j t v�r i}dj|jd �} d } |D]"} d  | | ¡} | | ¡| || <qÀt ¡}tj||j|jtj |j|j| d �\} } | �r || }|�r<||_t d |j¡n2|j t v�rTt  d¡nt d|tt ¡|ƒ¡t|ƒS)NrFÚ metadata_urlscSsg|]}t |¡r|‘qSr")r Zis_resolvable_url)Ú.0Úxr"r"r#Ú Uóz;DataSourceEc2.wait_for_metadata_service..z,Removed the following from metadata urls: %sz+Empty metadata url list! using default listz{ver}/meta-data/instance-id)ZverZGETr|)r}r~rr€rhrtr�zUsing metadata source: '%s'z)IMDS's HTTP endpoint is probably disabledz(Giving up on md from %s after %s seconds)Úds_cfgr„r†rWr’ÚsetrPrQÚlistÚlenrˆr‘rRr‚rkrorƒÚtimeÚ monotonicrlr…r‡rfrjr0ZcriticalÚintÚbool)r4r}Z start_timeZmcfgr�r‹Zfilteredr0rŒr�r�r&rŽÚ_r"r"r#Úwait_for_metadata_serviceJsl þ  ÿþÿ   ù   ýz'DataSourceEc2.wait_for_metadata_servicecCsâd|jvrdSd}|jd}t|tƒs6t d|¡dS| ¡D],\}}||krV|}ql|dkr>|dkr>|}q>|dur„t d|¡dS|}| d¡sšd|}tj  |¡rª|S|  tj  |¡¡}|rÒt d||¡|S|dkrÞdS|S) Nzblock-device-mappingz+block-device-mapping not a dictionary: '%s'Z ephemeralZ ephemeral0z Unable to convert %s to a deviceú/z/dev/%szRemapped device name %s => %s) rXÚ isinstanceÚdictrPrQr]Ú startswithÚosÚpathÚexistsZ _remap_deviceÚbasename)r4ÚnameÚfoundZbdmZentnameZdeviceZofoundZremappedr"r"r#Údevice_name_to_device”s8       z#DataSourceEc2.device_name_to_devicecCsTz:|jtjkr(|j d|jdd¡WS|jddWSWntyNYdS0dS)NZavailabilityZoneZ placementzavailability-zone)rRrrr1rWrXÚKeyErrorr@r"r"r#Úavailability_zoneÇs  þ zDataSourceEc2.availability_zonecCsR|jtjkr4|j d¡}|jr0|s0|jdd…}|S|j}|durN|dd…SdS)NÚregionéÿÿÿÿ)rRrrr1rWr­)r4r®Úazr"r"r#r®Ôs    zDataSourceEc2.regioncCs,|sdS|jtjkr(tt |tt¡|ƒdSr-)rRrr Úwarn_if_necessaryr rMrNrO)r4ÚcfgZis_new_instancer"r"r#Úactivateâs  þzDataSourceEc2.activatec CsÆ|jtjkr|jS|jdur*t d¡dSd}|jj}|j d¡}t |t ƒr®t ||j|t   |jdd¡|jd�}| ¡rºt |j¡|_|jtj tj¡|jtj tj¡n t d|¡||_|jS)z@Return a network config dict for rendering ENI or netplan files.Nz8Unexpected call to network_config when metadata is None.rZZapply_full_imds_network_configT)Ú fallback_nicÚfull_network_configÚfallback_nic_orderz%Metadata 'network' key not valid: %s.)Ú_network_configrÚUNSETrXrPrˆr6rUrWr¢r£Ú#convert_ec2_metadata_network_configr Zget_cfg_option_boolr—r3r^ÚcopyÚdeepcopyÚdefault_update_eventsr ÚNETWORKÚaddr ÚBOOTÚ BOOT_LEGACY)r4ÚresultZifaceZnet_mdr"r"r#Únetwork_configësB  ÿ  ÿù ÿ ÿ ÿ zDataSourceEc2.network_configc Cs| ¡s iS| ¡}|j}i}|jtvr:|j}|j}d}n&|jtjkrTd}}t }n d}}}zxt j ||j |j ||d�}t |¡|d<t j||j |j |||d�|d<|jtjkrÖt j||j |j ||d�}d|i|d<Wn(t�yt td|j ¡iYS0||d <|S) zªCrawl metadata service when available. @returns: Dictionary of crawled metadata content containing the keys: meta-data, user-data and dynamic. NrsrH)rtrhruZretrieval_exception_ignore_cbrGrJrIz'Failed reading from metadata address %sZ_metadata_api_version)r rrrfrRr‚rxÚ#_skip_or_refresh_stale_aws_token_cbrrr(rZget_instance_userdatar0rjr Zmaybe_b64decodeZget_instance_metadatarrwÚ ExceptionZlogexcrP) r4ryZredactZcrawled_metadataZexc_cbZ exc_cb_udZskip_cbZ raw_userdatar1r"r"r#rVs`   ûú  ûý zDataSourceEc2.crawl_metadatac Cs–|jtvrdS|dur|j}t d¡|j|i}d |j|j¡}zt j |||j dd�}Wn6t j yŽ}zt  d||¡WYd}~dSd}~00|jS)z�Request new metadata API token. @param seconds: The lifetime of the token in seconds @return: The API token or None if unavailable. Nz!Refreshing Ec2 metadata API tokenz{}/{}r{)rgrhr�z/Unable to get API token: %s raised exception %s)rRr‚rcrPrQrerkr0rbrlrmrfrnrˆÚcontents)r4ZsecondsZrequest_headerZ token_urlr�rpr"r"r#Ú_refresh_api_tokenSs(   ü ÿz DataSourceEc2._refresh_api_tokencCs$t tj||¡}|sdS| ||¡S)zSCallback will not retry on SKIP_USERDATA_CODES or if no token is available.F)rZskip_retry_on_codesZSKIP_USERDATA_CODESrx)r4rqr'Zretryr"r"r#rÃps ÿz1DataSourceEc2._skip_or_refresh_stale_aws_token_cbcCs*t|tjƒr&|jdkr&t d¡d|_dS)z=Exception handler for Ec2 to refresh token if token is stale.i‘z+Clearing cached Ec2 API token due to expiryNT)r¢rlrnr%rPrQrŠ©r4rqr'r"r"r#rxzs z)DataSourceEc2._refresh_stale_aws_token_cbcCsDt|tjƒr@|jr@|jdkr@|jdkr2t d¡n t d¡|‚dS)a2Fail quickly on proper AWS if IMDSv2 rejects API token request Guidance from Amazon is that if IMDSv2 had disabled token requests by returning a 403, or cloud-init malformed requests resulting in other 40X errors, we want the datasource detection to fail quickly without retries as those symptoms will likely not be resolved by retries. Exceptions such as requests.ConnectionError due to IMDS being temporarily unroutable or unavailable will still retry due to the callsite wait_for_url. i�i“zLEc2 IMDS endpoint returned a 403 error. HTTP endpoint is disabled. Aborting.z2Fatal error while requesting Ec2 IMDSv2 API tokensN)r¢rlrnr%rPrˆrÇr"r"r#r‰‚s  ÿÿz DataSourceEc2._imds_exception_cbrFcCsN|jtvriS|j|ji}|j|vr(|S|jsB| ¡|_|jsBiS|j|jiS)z·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. )rRr‚rercrbrŠrÆrd)r4r&Zrequest_token_headerr"r"r#rj�s ÿ  zDataSourceEc2._get_headers)N)N)rF):rrrr`r’ror*rÚstrÚ__annotations__Z url_max_waitZ url_timeoutrŠrr¸r·rTr r½r ZBOOT_NEW_INSTANCEr¿rÀZHOTPLUGZsupported_update_eventsr¼r=r>r/r�r<rArYr^Úpropertyr_rSrbrcrdrerfrrrzr‘r r«r­r®r³rÂrVrÆrÃrxr‰rjÚ __classcell__r"r"r8r#r)Bsv üÿ þÿ 3        2J3    /8   r)cs$eZdZdZdZ‡fdd„Z‡ZS)ÚDataSourceEc2LocalayDatasource 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. Tcs8tjtjf}|j|vr*t d||j¡dStt|ƒ ¡S)Nz+Local Ec2 mode only supported on %s, not %sF) rrrrRrPrQr.rÌÚget_data)r4Zsupported_platformsr8r"r#rÍÀs  ýzDataSourceEc2Local.get_data)rrrÚ__doc__rTrÍrËr"r"r8r#r̵srÌc CsBz t|ƒWSty<}zt |¡|WYd}~Sd}~00dSr-)Úparse_strict_modeÚ ValueErrorrPrˆ)ÚcfgvalÚdefaultrpr"r"r#rLÌs   rLc Csž|dur dS|durdS|s dS| d¡\}}}|dvrHtd||fƒ‚|r’z t|ƒ}Wq–tyŽ}ztd ||fƒ|‚WYd}~q–d}~00nd}||fS) NT)rBNF)ÚfalseN)rrú,)rBrÓrzUInvalid mode '%s' in strict_id setting '%s': Expected one of 'true', 'false', 'warn'.z2r–z#identify_platform..z'calling %s with %s raised exception: %s) Ú_collect_platform_datarÛrßrárãrårÄrPrˆ)rÚZchecksZcheckerrÁrpr"r"r#r?)s"úÿr?cCsªd}tttƒ�t d¡ ¡}Wdƒn1s20Y|pLt d¡pLd}t d¡pZd}t d¡phd}t d¡pvd}t d¡p„d}| ¡| ¡| ¡| ¡| ¡d œS) aFReturns 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 serial: dmi 'system-serial-number' (/sys/.../product_serial) asset_tag: 'dmidecode -s chassis-asset-tag' vendor: dmi 'system-manufacturer' (/sys/.../sys_vendor) product_name: dmi 'system-product-name' (/sys/.../system-manufacturer) On Ec2 instances experimentation is that product_serial is upper case, and product_uuid is lower case. This returns lower case values for both. Nz/sys/hypervisor/uuidz system-uuidrFzsystem-serial-numberzchassis-asset-tagzsystem-manufacturerzsystem-product-name©rØrÜràrârä) rÚOSErrorÚUnicodeDecodeErrorr Zload_text_fileÚstriprZ read_dmi_datararèr"r"r#rç?s  ,ûrç)Ú macs_metadataÚ macs_to_nicsr¶r;csni}tˆƒdkstˆƒdkr |Stdd„t‡‡fdd„ˆ ¡ƒƒ}dd„‰dd„tt|‡‡fd d„d �ƒDƒS) aI Builds a dictionary containing macs as keys and nic orders as values, taking into account `network-card` and `device-number` if present. Note that the first NIC will be the primary NIC as it will be the one with [network-card] == 0 and device-number == 0 if present. @param macs_metadata: dictionary with mac address as key and contents like: {"device-number": "0", "interface-id": "...", "local-ipv4s": ...} @macs_to_nics: dictionary with mac address as key and nic name as value @return: Dictionary with macs as keys and nic orders as values. rcSs |dduS)Nér"©Zmmdr"r"r#ræwr–z"_build_nic_order..cs|ˆ |¡ˆ|fSr-)rW)Úmac)rìrír"r#ræzr–cSs | |d¡}|durt|ƒS|Sr-)rWr�)ZdiktÚkeyZ alt_valueÚvaluer"r"r#Ú_get_key_as_int_ors z,_build_nic_order.._get_key_as_int_orcSsi|]\}\}}}||“qSr"r")r“ÚirðZ _mac_metadataZ _nic_namer"r"r#Ú ‹s ÿz$_build_nic_order..cs@ˆ|ddtdƒƒˆ|ddtdƒƒˆtjkr6|dn|dfS)Nrîz network-cardZinfinityú device-numberér)ÚfloatrZNIC_NAMErï)rór¶r"r#ræ�sÿÿÿ ö)rñ)ršÚfilterÚmapÚkeysÚ enumerateÚsorted)rìrír¶Ú nic_orderZvalid_macs_metadatar")rór¶rìrír#Ú_build_nic_order_s& þü   þÿþrÿ)Ú dev_configÚnic_nameÚ nic_metadatar6Úis_ipv4Útabler;c CsJ|r| d¡}| d¡}n| d¡}| d¡}|r6|sNt d|rDdnd¡dS| d ¡s`g|d <|rÊz|jj||d �}|d } Wn2ty²} zt d || ¡WYd} ~ n d} ~ 00|d  d | |dœ¡t|t ƒrÚ|gn|}|D]} |d  | |dœ¡qâ| d¡�sg|d<t|t ƒ�r"|gn|}|D]} |d | |dœ¡�q*dS)aÞ Configure policy-based routing on secondary NICs / secondary IPs to ensure outgoing packets are routed via the correct interface. @param: dev_config: network cfg v2 to be updated inplace. @param: nic_name: nic name. Only used if ipv4. @param: nic_metadata: nic metadata from IMDS. @param: distro: Instance of Distro. Only used if ipv4. @param: is_ipv4: Boolean indicating if we are acting over ipv4 or not. @param: table: Routing table id. úsubnet-ipv4-cidr-blockú local-ipv4szsubnet-ipv6-cidr-blocksÚipv6szANot enough IMDS information to configure policy routing for IPv%sÚ4Ú6NÚroutes)r6ZrouterszoCould not perform dhcp discovery on %s to find its gateway. Not adding default route via the gateway. Error: %sz 0.0.0.0/0)ÚtoZviar)r rúrouting-policy)Úfromr) rWrPrQZ dhcp_clientZdhcp_discoveryrrˆrƒr¢rÈ) rrrr6rrZsubnet_prefix_routesÚipsZleaseZgatewayrpZ prefix_routeÚipr"r"r#Ú_configure_policy_routing¢s`     ý  û ýÿ ÿýþÿ þÿrTc Cs2didœ}|st ¡}|dd}|s†| ¡D]\}} | |kr.qDq.ddd| ¡i| dœ} | |¡} |  d ¡rvd| d <| |d | <|St|jtjƒ} t |||ƒ} t |  ¡ƒ}|D�]}||} | |¡} | sÎq°| |}|d k}d |ddi}d|dd| ¡i| dœ} d|}| �rB|  d¡�rB|�sBd|d<t | || | d|d�|  d ¡�rŠd| d <|| d<| �rŠ|  d¡�rŠ|�sŠt | || | d|d�t | |ƒ| d<| d�s¬|  d¡| |d | <q°t|d ƒdk�r.|d   ¡D]T} |d |  d¡|d |  dd¡|d |  dd¡|d |  dd¡�qØ|S)a8Convert ec2 metadata to network config version 2 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: distro: instance of Distro. @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. @param: full_network_config: Boolean set True to configure all networking presented by IMDS. This includes rendering secondary IPv4 and IPv6 addresses on all NICs and rendering network config on secondary NICs. If False, only the primary nic will be configured and only with dhcp (IPv4/IPv6). @return A dict of network config version 2 based on the metadata and macs. r÷)ÚversionÚ ethernetsr[r\TFZ macaddress)Údhcp4Údhcp6Úmatchúset-namerrrrz route-metricrîéd)rúdhcp4-overridesrrrröz use-routes)r6rrrrzdhcp6-overridesÚ addressesrNr r )rZget_interfaces_by_macr]rarWr¢Znetwork_rendererrZRendererrÿrýrûrÚget_secondary_addressesÚpoprš)Z network_mdr6rír´rµr¶ZnetcfgrìrðrrrZ is_netplanrþr\Znic_idxZis_primary_nicZ dhcp_overriderr"r"r#r¹÷s¢   ü   ÿ    ûÿþýú ÿþýú  r¹cCs€| d¡}| d¡}g}tt|tƒo.t|ƒdkƒrH| t|d||dƒ¡tt|tƒo^t|ƒdkƒrx| t|d||dƒ¡t|ƒS)z Parse interface-specific nic metadata and return any secondary IPs :return: List of secondary IPv4 or IPv6 addresses to configure on the interface rrrîrZ24zsubnet-ipv6-cidr-blockZ128)rWržr¢r™ršÚextendÚ_get_secondary_addressesrý)rrðZipv4srrr"r"r#rss    ÿÿ ÿÿrc Cs†g}| |¡}|}|r(t| d¡ƒdkrNd|vr4dnd}t d|||||¡n| d¡d}|dd…D]} | dj| |d �¡qh|S) z£Return list of IP addresses as CIDRs for secondary IPs The CIDR prefix will be default_prefix if cidr_key is absent or not parseable in nic_metadata. r¡r÷rCrDzJCould not parse %s %s for mac %s. %s network config prefix defaults to /%srîNz {ip}/{prefix})rÚprefix)rWršÚsplitrPrˆrƒrk) rZcidr_keyrðrÚdefault_prefixrZcidrrZip_typerr"r"r#rŒs" ù rcCs t |t¡Sr-)rZlist_from_dependsÚ datasources)Zdependsr"r"r#Úget_datasource_list°sr")FrºZloggingr¥r›rØÚ contextlibrÚtypingrrZ cloudinitrrrrrlr r Zcloudinit.distrosr Zcloudinit.eventr r Z cloudinit.netrZcloudinit.net.dhcprZcloudinit.net.ephemeralrZcloudinit.sourcesrZcloudinit.sources.helpersrZ getLoggerrrPrNrOrr(rr‚r=Z DataSourcer)rÌrLrÏr±rÛrßrárãrår?rçr2rÈr�rÿr£ržrr¹rrZDEP_FILESYSTEMZ DEP_NETWORKr!r"r"r"r"r#Ú s‚         w! #ý   ü Dø Xú | þ