\`f<dZddlZddlZddlmZddlmZmZmZm Z m Z ddl m Z ddl mZmZmZddlmZej&eZGddZGd d ZGd d ZGd deZGddZy)z.Module for ephemeral network context managers N)partial)AnyCallableDictListOptional)DhcpcdNoDHCPLeaseErrormaybe_perform_dhcp_discovery)ProcessExecutionErrorcReZdZdZ d deeeeffdZdZ dZ dZ dZ d Z y) 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_url_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. Nconnectivity_url_datac t||||gstdj|||| tj||_||_||_||_||_ ||_ ||_ g|_ ||_ |jd|j |_y#t$r } tdj| | d} ~ wwxYw)aXSetup 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 connectivity_url_data: Optionally, a URL to verify if a usable connection already exists. @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 ValueErrorformatnetipv4_mask_to_net_prefixprefixr interfaceip broadcastrouter static_routes cleanup_cmdsdistrocidr) selfrrrprefix_or_maskrrrres 9/usr/lib/python3/dist-packages/cloudinit/net/ephemeral.py__init__zEphemeralIPv4Network.__init__ s.Ir>9=>GNNr>9   55nEDK&;""" *,. wwiq .  %vay  sB!! C *CC cz|jrCtj|jr$tj d|jdy |j |j r|jy|jr|jyy#t$r|jdddwxYw)z>Perform ephemeral network setup if interface is not connected.z=Skip ephemeral network setup, instance has connectivity to %surlN) rrhas_url_connectivityLOGdebug_bringup_devicer_bringup_static_routesr_bringup_routerr __exit__r s r# __enter__zEphemeralIPv4Network.__enter__Ps  % %''(B(BC ..u5    "!!++-$$&$  MM$d +  s,B>BB:c4|jD] }| y)zTeardown anything we set up.N)r)r excp_type excp_valueexcp_tracebackcmds r#r-zEphemeralIPv4Network.__exit__rs$$ C E c^tjd|j|j|j |j j j|j|j|j|j j j|jd|jjt|j j j|jd|jjt|j j j|j|jy#t$rM}dt|j vrtjd|j|j"Yd}~yd}~wwxYw)z2Perform the ip commands to fully setup the device.z:Attempting setup of ephemeral network on %s with %s brd %sinetfamilyz File existsz7Skip ephemeral network setup, %s already has address %sN)r(r)rrrrnet_opsadd_addrlink_uprappendr link_downdel_addrr strstderrr)r r"s r#r*z$EphemeralIPv4Network._bringup_devicews6 H NN II NN    KK   ( ( 4>>  KK   ' 'v ' F    $ $KK''11NN!     $ $KK''00$..$)) %% CM1 III   sAE F,AF''F,c 0|jD]\}}|jjj|j|||j j dt|jjj|j||y)Nrgateway) rrr: append_routerrinsertr del_route)r net_addressrDs r#r+z+EphemeralIPv4Network._bringup_static_routess%)$6$6  K KK   , , W     $ $KK''11NN#   r5c  |jjj}d|vr0tj d|j |j y|jjj|j |j|j|jjdt|jjj|j |j|j|jjj|j d|j|jjdt|jjj|j dy)z>9 M r5NNN)__name__ __module__ __qualname____doc__rrr@rr$r/r-r*r+r,r5r#rrsJ":>./ (S#X7./` D "H0 r5rc"eZdZdZdZdZdZy)EphemeralIPv6NetworkzContext manager which sets up a ipv6 link local address The linux kernel assigns link local addresses on link-up, which is sufficient for link-local communication. cX|stdj|||_||_y)zSetup 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: IPv6 uses prefixes, not netmasks zCannot init network on {0}N)rrrr)r rrs r#r$zEphemeralIPv6Network.__init__s,9@@KL L" r5ctj|jddk7r0|jjj |jyy)zlinux kernel does autoconfiguration even when autoconf=0 https://www.kernel.org/doc/html/latest/networking/ipv6.html operstateupN)r read_sys_netrrr:r<r.s r#r/zEphemeralIPv6Network.__enter__s?   DNNK 8D @ KK   ' ' 7 Ar5cy)z%No need to set the link to down stateNrUr _argss r#r-zEphemeralIPv6Network.__exit__sr5N)rQrRrSrTr$r/r-rUr5r#rWrWs 84r5rWcTeZdZ d deeeeffdZdZdZ dZ dZ dZ d Z y) EphemeralDHCPv4NrcX||_d|_d|_||_||_||_yN)iface_ephipv4lease dhcp_log_funcrr)r rrdrrgs r#r$zEphemeralDHCPv4.__init__s0   *%:" r5c|jr@tj|jr!tj d|jy|j S)zUSetup sandboxed dhcp context, unless connectivity_url can already be reached.z:Skip ephemeral DHCP setup, instance has connectivity to %sN)rrr'r(r) obtain_leaser.s r#r/zEphemeralDHCPv4.__enter__sO  % %''(B(BC ..   ""r5c$|jy)z Teardown sandboxed dhcp context.N) clean_network)r r1r2r3s r#r-zEphemeralDHCPv4.__exit__s r5cfd|_|jr|jjdddyy)z@Exit _ephipv4 context to teardown of ip configuration performed.N)rfrer-r.s r#rkzEphemeralDHCPv4.clean_networks+ == MM " "4t 4 r5c:|jr |jSt|j|j|j|_|js t t jd|jd|jd|jdddddgddd}|j|}|d stj|d |d |d <|d r+|jjj|d |d <|jr|j|d <t|jjtrt!|jfi|}nt#|jfi|}|j%||_|jS)a9Perform dhcp discovery in a sandboxed environment if possible. @return: A dict representing dhcp options on the most recent lease obtained from the dhclient discovery if run, otherwise an error is raised. @raises: NoDHCPLeaseError if no leases could be obtained. z#Received dhcp lease on %s for %s/%srz fixed-addressz subnet-maskzbroadcast-address)zrfc3442-classless-static-routeszclassless-static-routesrrouters)rrr!rrrrr!rrr)rfr rrdrgr r(r)extract_dhcp_options_mappingrmask_and_ipv4_to_bcast_addr dhcp_clientparse_static_routesr isinstancer DhcpcdEphemeralIPv4Networkrr/re)r nmapkwargsephipv4s r#rizEphemeralDHCPv4.obtain_leases :::: 1 KKT%7%7  zz"$ $ 1 JJ{ # JJ ' JJ} %  %!+,    2248k""%"A"A'(&,#F;  / " '';;'    % %.2.H.HF* + dkk--v 60GGG*4;;A&AG zzr5ci}|jD]G\}}t|tr|j|||*|jj |||<I|Src)itemsrslistget_first_option_valuerfget)r ruresultinternal_referencelease_option_namess r#roz,EphemeralDHCPv4.extract_dhcp_options_mappingPsh6:jjl P 2  2,d3++&(:F.2ZZ^^>/+J'( Kr5rP)rQrRrSrrr@rr$r/r-rkriror{rUr5r#rarasI:>  (S#X7  #5 5n Kr5rac(eZdZdZfdZdZxZS)rtz3dhcpcd sets up its own ephemeral network and routescrt||i||jjt |j j j|jd|jjt |j j j|j|jy)Nr7r8) superr$rr=rrr:r>rr?r)r argsrv __class__s r#r$z#DhcpcdEphemeralIPv4Network.__init__fs $)&)    ##--     DKK''00$..$)) L r5cyrcrUr.s r#r/z$DhcpcdEphemeralIPv4Network.__enter__usr5)rQrRrSrTr$r/ __classcell__)rs@r#rtrtcs=  r5rtc2eZdZdZ ddedefdZdZdZy) EphemeralIPNetworkahCombined ephemeral context manager for IPv4 and IPv6 Either ipv4 or ipv6 ephemeral network may fail to initialize, but if either succeeds, then this context manager will not raise exception. This allows either ipv4 or ipv6 ephemeral network to succeed, but requires that error handling for networks unavailable be done within the context. ipv6ipv4c|||_||_||_tj|_d|_||_y)N)rrr contextlib ExitStackstack state_msgr)r rrrrs r#r$zEphemeralIPNetwork.__init__s7#  ))+   r5c|js|js|Sg}d}|jr< |jjt |j |j d}|jrQ |jjt|j |j d}|s |jsd|_ |stjd|d|S#ttf$r1}tjd||j|Yd}~d}~wwxYw#t$r1}tjd||j|Yd}~d}~wwxYw)NFTzFailed to bring up %s for ipv4.zusing link-local ipv6zFailed to bring up %s for ipv6.zGFailed to bring up EphemeralIPNetwork. Datasource setup cannot continuer)rrr enter_contextrarrr r r(infor=rWrerror)r exceptionsephemeral_obtainedr"s r#r/zEphemeralIPNetwork.__enter__s= TYYK " 99 % ((#  &*" 99 % (((  &*"TYY%rs}66 1g!{ { |44@mKmK`!5,DDr5