a 'DgV@sdZddlZddlZddlmZddlmZmZmZm Z m Z m Z m Z ddl mZddlmZddlmZmZddlmZddlmZmZeeZGdd d ZGd d d ZGd d d ZGdddZe ee efe e dddZ!dS)z.Module for ephemeral network context managers N)partial)AnyCallableDictListLiteralOptionalTuple)NoDHCPLeaseErrormaybe_perform_dhcp_discovery)ProcessExecutionError)UrlError wait_for_urlc@sHeZdZdZdedddZddZdd Zd d Zd d Z ddZ dS)EphemeralIPv4NetworkaContext manager which sets up temporary static network configuration. No operations are performed if the provided interface already has the specified configuration. This can be verified with the connectivity_urls_data. If unconnected, bring up the interface with valid ip, prefix and broadcast. If router is provided setup a default route for that interface. Upon context exit, clean up the interface leaving no configuration behind. N)interface_addrs_before_dhcpc Cst||||gs$td||||zt||_Wn4tyh} ztd| | WYd} ~ n d} ~ 00||_||_||_||_ ||_ g|_ ||_ |jd|j|_ ||ji|_dS)aSetup context manager and validate call signature. @param interface: Name of the network interface to bring up. @param ip: IP address to assign to the interface. @param prefix_or_mask: Either netmask of the format X.X.X.X or an int prefix. @param broadcast: Broadcast address for the IPv4 network. @param router: Optionally the default gateway IP. @param static_routes: Optionally a list of static routes from DHCP z5Cannot init network on {0} with {1}/{2} and bcast {3}z4Cannot setup network, invalid prefix or netmask: {0}N/)all ValueErrorformatnetZipv4_mask_to_net_prefixprefix interfaceip broadcastrouter static_routes cleanup_cmdsdistrocidrgetr) selfrrrprefix_or_maskrrrrer#;/usr/lib/python3.9/site-packages/cloudinit/net/ephemeral.py__init__s6zEphemeralIPv4Network.__init__c Cszrz |WnBtyP}z*dt|jvrsz8EphemeralIPv4Network._bringup_device..ipv4cSsg|]}|dqSr2r3r4r#r#r$r6sz1Skip adding ip address: %s already has address %sz9Skip bringing up network link: interface %s is already upZinet)ZfamilyzLNot queueing link down: link [%s] was up prior before receiving a dhcp leasezSNot queueing address removal: address %s was assigned before receiving a dhcp leaseN)LOGdebugrrrnetinfo netdev_inforrrrnet_opsZadd_addrlink_uprappendrZ link_downZdel_addr)r Zinterface_addrs_after_dhcpZhas_linkZhad_linkZhas_ipZhad_ipr#r#r$r&wsl        z$EphemeralIPv4Network._bringup_devicec CsJ|jD]>\}}|jj|j|||jdt|jjj|j||dqdS)Nrgateway) rrr<Z append_routerrinsertr del_route)r Z net_addressr@r#r#r$r)sz+EphemeralIPv4Network._bringup_static_routesc Cs|jj}d|vr,td|j|dS|jjj|j|j|j d|j dt |jjj |j|j|j d|jjj|jd|jd|j dt |jjj |jddS)zrierror)r exceptionsZephemeral_obtainedZimds_urlZipv4_ephemeral_obtainedZipv4_exceptionZipv6_ephemeral_obtainedZipv6_exceptionr#r#r$r,sB      zEphemeralIPNetwork.__enter__)r7rd)rjreturnc Cszf|dkr$|jt|j|jdn.|dkrD|jt|j|jntd|td|j|WdSt t fy}z$td|j|d|fWYd }~Sd }~00d S) a Attempt to bring up an ephemeral network for the specified IP version. Args: ip_version (str): The IP version to bring up ("ipv4" or "ipv6"). Returns: Tuple: A tuple containing: - a boolean indicating whether an ephemeral network was successfully obtained - an optional exception if ephemeral network setup failed or None if successful r7)rrSrdzUnsupported IP version: z7Successfully brought up %s for ephemeral %s networking.)TNz2Failed to bring up %s for ephemeral %s networking.FN) rh enter_contextrOrrrKrr8r9r r )r rjr"r#r#r$rks:z3EphemeralIPNetwork._perform_ephemeral_network_setupcGs|jdSrR)rhcloserMr#r#r$r+szEphemeralIPNetwork.__exit__)FTN)rFrGrHrIboolrrrr'rr%r,rr Exceptionrkr+r#r#r#r$rcs  6 1rc)rQrnc sfdd}stddStddDp2d}z$tdd D||d d d \}}Wn0ty}ztd |WYd}~n d}~00|stddS|SdS)a Perform a connectivity check to the provided URLs to determine if the ephemeral network setup is necessary. This function attempts to reach one of the provided URLs and returns the URL that was successfully reached. If none of the URLs can be reached, it returns None. The timeout for the request is determined by the highest timeout value provided in the connectivity URLs data. If no timeout is provided, a default timeout of 5 seconds is used. Args: connectivity_urls_data: A list of dictionaries, each containing the following keys: - "url" (str): The URL to check connectivity for. - "headers" (dict, optional): Headers to include in the request. - "timeout" (int, optional): Timeout for the request in seconds. Returns: Optional[str]: The URL that was successfully reached, or None if no connectivity was established. csfddDd}|S)z Helper function to get headers for a given URL from the connectivity URLs data provided to _check_connectivity_to_imds. cs"g|]}|dkr|dqSurlZheadersr3r5Zurl_datartr#r$r68s zD_check_connectivity_to_imds.._headers_cb..rr#rsrPrvr$ _headers_cb3s  z0_check_connectivity_to_imds.._headers_cbzZNo connectivity URLs provided. Skipping connectivity check before ephemeral network setup.Ncss|]}|ddVqdS)timeoutrNr3rur#r#r$ Hz._check_connectivity_to_imds..cSsg|] }|dqSrvr#rur#r#r$r6Nrzz/_check_connectivity_to_imds..Fr)ZurlsZ headers_cbrxZconnect_synchronouslyZmax_waitz8Failed to reach IMDS without ephemeral network setup: %sz5Failed to reach IMDS without ephemeral network setup.)r8r9maxrr )rQrwrxZurl_that_worked_r"r#rPr$rWs6   rW)"rIrfZlogging functoolsrtypingrrrrrrr Z cloudinit.netrZcloudinit.netinfor:Zcloudinit.net.dhcpr r Zcloudinit.subpr Zcloudinit.url_helperr rZ getLoggerrFr8rrKrOrcr'rWr#r#r#r$s& $    f s