x[hRNddlZddlZddlZddlZddlZddlmZddlmZm Z m Z ddl m Z m Z mZmZddlmZmZmZmZmZmZddlmZmZdZdZej8eZd Zd e d e d efd Z!dZ"ddZ#de$de%fdZ&de$de$de%fdZ'de$de$fdZ(GddejRZ)ddZ*y)N)SpooledTemporaryFile)CallableListOptional)featuressafeyamlsubputil)IPV6_DYNAMIC_TYPES SYS_CLASS_NETget_devicelistrenderershould_add_gateway_onlink_flagsubnet_is_ipv6)NET_CONFIG_TO_V2 NetworkStatez/etc/netplan/50-cloud-init.yamls4# This is the initial network config. # It can be overwritten by cloud-init or console-conf. network: version: 2 ethernets: all-en: match: name: "en*" dhcp4: true all-eth: match: name: "eth*" dhcp4: true cHtfd|jDS)Nc3NK|]\}}|jr||fywN) startswith).0keyvaluematchs 7/usr/lib/python3/dist-packages/cloudinit/net/netplan.py z,_get_params_dict_by_match..,s- S% >>%  e s"%)dictitems)configrs `r_get_params_dict_by_matchr +s# "LLN rentryrc d"d}g}g}g}g}|jdg} | g} | D] } | jd} | jdr| dk(r| dz } |j| diD| tvr|jddi`| d vsed | jd z} d | vr| d | jd zz } | jdrS| jddd} t | d| rt j d| d| d| d<|j| d| vr||| jdgz }d| vr||| jdgz }d| vr:d}t| r d|vrd}|j|| jdi| jdgD]s}|jdd|jd }|jd|d} d|vr#| jd|jddi|j| u|j| d|vr?|jd}|r$|d|k7rt jd||d|n|d|d<t|dkDr|jd|it|dkDr|jd|it|dkDrd|i}|jd|it|dkDr8|jdi}|jd |i|jd|id!|vr<|d!6|jd!tj|jd!iyyy)#aThis method parse a cloudinit.net.network_state dictionary (config) and maps netstate keys/values into a dictionary (entry) to represent netplan yaml. (config v1 -> netplan) An example config dictionary might look like: {'mac_address': '52:54:00:12:34:00', 'name': 'interface0', 'subnets': [ {'address': '192.168.1.2/24', 'mtu': 1501, 'type': 'static'}, {'address': '2001:4800:78ff:1b:be76:4eff:fe06:1000", 'mtu': 1480, 'netmask': 64, 'type': 'static'}], 'type: physical', 'accept-ra': 'true' } An entry dictionary looks like: {'set-name': 'interface0', 'match': {'macaddress': '52:54:00:12:34:00'}, 'mtu': 1501} After modification returns {'set-name': 'interface0', 'match': {'macaddress': '52:54:00:12:34:00'}, 'mtu': 1501, 'address': ['192.168.1.2/24', '2001:4800:78ff:1b:be76:4eff:fe06:1000"], 'ipv6-mtu': 1480} cZ|rt|ts|S||vr|j|S|gS)zT Helper to convert strings to list of strings, handle single string ) isinstancestrsplit)objtokens r_listifyz$_extract_addresses.._listifyXs:*S#.J C<99U# # r!subnetsNtypedhcp4Tdhcp6)staticstatic6z%saddressprefixz/%dgatewaydefault)viatozAGateway %s is not contained within subnet %s, adding on-link flagzon-linkdns_nameservers dns_searchmtuzipv6-mturoutesnetwork/metricdzZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r addresses nameserverssearchz accept-ra) ) getrupdater rLOGdebugappendrwarninglenr is_true)rr"ifnamerr*r@r;rA searchdomainsr+subnetsn_typeaddr new_routemtukeyrouteto_net entry_mtunss r_extract_addressesrW3sJ I FKMjjB'G0#**V$   f %& 3 LL'4 ) * * LL'4 ) - -&**Y//D6! 8 444zz)$!::i0# 2&2CTJII/y)  ,0Ii( i( F*x 3Db(IJJ v%&**\2*F!GG !&)jHJ.F'F ffjj&789Hb1 )$)IIi$8%))H:MN 99Y/  u$$$h (C0H%IJ i( )   T "a0#d IIe$ )3 KK6u   "%=E%L 9~ k9-. 6{Q h'( ;!; ' mR() =A YY}b ) 8]+, mR()f !4!@ k4<< ;0G#HIJ"Ar!c t|jDcgc]\}}|jdd|k(r|c}}}t|dkDr|j d|iyycc}}w)Nz bond-masterr interfaces)sortedrrDrJrE)rYr" bond_masternamecfgbond_slave_namess r_extract_bond_slaves_by_namer_sq *//1 sww}d+{:   q  l$456!  s!A% ctj|d}tjj |syt j |}|tk7rydDcgc]}tj||}}|Dcgc]$}tjj |s#|&}}tjd|||g|zD]}tj|ycc}wcc}w)Nz etc/netplan/00-snapd-config.yaml)z-run/systemd/network/10-netplan-all-en.networkz.run/systemd/network/10-netplan-all-eth.networkz#run/systemd/generator/netplan.stampz9removing known config '%s' and derived existing files: %s) r target_pathospathisfiler load_binary_fileKNOWN_SNAPD_CONFIGrFrGunlink)targettpathcontentfderivedexistings r_clean_defaultrns   V%G HE 77>>% ##E*G$$   #G#8abggnnQ&78H8IIC  Wx  ! 9sC =$C%"C%net_config_contentreturnc ddlm}ddlm} td5}|j||j|jdtj|}|j||}|j||j!t"j$j'tdddt j d y #t$rt j dtYywxYw#1swYHxYw#t($r%}t j+d t|Yd}~yd}~wwxYw) adUse netplan.State._write_yaml_file to write netplan config Where netplan python API exists, prefer to use of the private _write_yaml_file to ensure proper permissions and file locations are chosen by the netplan python bindings in the environment. By calling the netplan API, allow netplan versions to change behavior related to file permissions and treatment of sensitive configuration under the API call to _write_yaml_file. In future netplan releases, security-sensitive config may be written to separate file or directory paths than world-readable configuration parts. r)Parser)Statez.No netplan python module. Fallback to write %sFwmodeNzUUnable to render network config using netplan python module. Fallback to write %s. %sz0Rendered netplan config using netplan python APIT)netplan.parserrr netplan.staters ImportErrorrFrGCLOUDINIT_NETPLAN_FILErwriteflushseekioSEEK_SET load_yamlimport_parser_results_write_yaml_filerbrcbasename ExceptionrI)rorrrsrkparserstate_output_filees rnetplan_api_write_yaml_filers)' !s + q GG& ' GGI FF1bkk "XF   Q  %   3 3F ;  . .  !78  0II@A A  < "       ( "  s@ C DB$D?D#DDD D ED;;Ecfg_filerjctjj|sytjtj |}|tj|k7S)z>( #t228<=I w/ //r!ctjrdnd}tjj |rt j |}||z|k(r|}t j|||y)zDWrite netplan config to cfg_file because python API was unavailable.iiruN)rNETPLAN_CONFIG_ROOT_READ_ONLYrbrcrr get_permissions write_file)rrjrv current_modes rfallback_write_netplan_yamlr sS::5D ww~~h++H5 $ , .DOOHgD1r!ceZdZdZddgZddgZddZdeefdZ dd e d e e ddfd Z d ed efdZddZd e defdZy)RendererzBRenders network information in a /etc/netplan/network.yaml format.netplangenerateinfoNc|si}|jdt|_|jdd|_|jdd|_|jdd|_|jdxsg|_y)N netplan_pathnetplan_headerpostcmdsF clean_defaultTr)rDrzrr _postcmdsr _features)selfrs r__init__zRenderer.__init__1slF"JJ~7MN$jj)94@J6#ZZ>J/52r!rpc|jsS tj|jd\}}tj|}|dd|_|jS|jS#tj $rY|jSt tf$r+}tjd|Yd}~|jSd}~wwxYw)NTcapturez netplan.iorz-Failed to list features from netplan info: %s) rr NETPLAN_INFOr rProcessExecutionError TypeErrorKeyErrorrFrG)r info_blob_errrrs rrzRenderer.features:s~~ N"&))D,=,=t"L 4~~i0!%l!3J!?~~t~~ -- ~~x( N I1MM~~ NsAA,,C CCC network_state templatescVtjjtj||j }t jtjj||j|}|jr |jnd}|jds|dz }||z}t||}t|s t|||jr t!||j#|j$||j'|j$y)N )rh)runconfig_changed)r)rbrcjoinr rarr ensure_dirdirname_render_contentrendswithrrrrrn_netplan_generater_net_setup_link)rrrrhfpnplanrjheadernetplan_config_changeds rrender_network_statezRenderer.render_network_stateHs'',,t//79J9JK 01&&}5)-(;(;$$t$ dNF7"!;GW!M*73 ' 9    & ) /E   0r!rrc|stjdy|stjdytj|jdy)Nz"netplan generate postcmds disabledzEskipping call to `netplan generate`. reason: identical netplan configTr)rFrGr NETPLAN_GENERATE)rrrs rrzRenderer._netplan_generateisB II: ;  II4   $''6r!c|stjdydtjvrtjdygd}t dD]\} t D]K}t jjt|zs*tj|t|zgzdMytd #tj$r }|}Yd}~d}~wwxYw) zTo ensure device link properties are applied, we poke udev to re-evaluate networkd .link files and call the setup_link udev builtin command z'netplan net_setup_link postcmd disabledNz net.ifnames=0z%Predictable interface names disabled.)udevadmz test-builtinnet_setup_linkTrzQ'udevadm test-builtin net_setup_link' unable to run successfully for all devices.) rFrGr get_cmdlineranger rbrcislinkr r r RuntimeError)rr setup_lnk_ifacerlast_exceptions rrzRenderer._net_setup_linkus  II? @   0 0 2 2 II= > A q "A #+-Eww~~me&;< %)>(??  "0" "-- #!" #s3B? $B??CCCc  |jdk(r9tjdtjd|j iddSi}i}i}i}i}g}|j jdg}|j} |j} |jD]} | jd} ttd| j} | jd }|d k(rv| | jd dd }|d 0| jd d}|d|ji|d <n|d =|d=t| || |j |j#| |i|dk(ri}i}t$d}dD]]}t'| |}|jD]<\}}|j|j)dd}|*|j#||i>_t+|dkDr|j#d|i| jd r| d j|d<| jd}|dk(r t-||| t| || |j |j#| |i|dk(r`| jd}|tj/dd| dt1t3j2|}d|i}d}t'| |}i}t$d} |jD]n\}}| j|}||j#||i|dvs2i}!|D]#}"|"j5\}#}$t7|$|!|#<%|j#||!ipt+|dkDr|j#d|i| jd r| d j|d<t| || |j |j#| |i8|dk(s?| jd | jd!d"}%| jd d}||j|%d<t| |%| |j |j#| |%i| s| rE| | d#}&|||||fD]6}'|'jD]!\}(})d$|)vsd%|)vr|)j#d$|&i#8d&}*|j9d'||*d(|z }||*d)|z }||*d*|z }||*d+|z }||*d,|z }d-j;|S).NzV2 to V2 passthroughr<F)explicit_start explicit_endrYr\c|dduS)N)its rz*Renderer._render_content..s2a5+<r!r,physicalr)set-namer mac_address macaddressrbond)bond_zbond-r-r parametersz bond-slavesnonebridge bridge_portszInvalid config. The keyz'bridge_ports' is required in .bridge_)z path-costz port-priorityvlanvlan_idzvlan-raw-device)idlink)r@rBrAr@cr|r4tj||iddd}tj|d}|gSgS)NFT)rrnoaliasz )rdumpstextwrapindent)r\sectiondumptxts r_render_sectionz1Renderer._render_content.._render_section sA~~7O#(!&  oodG4u Ir!znetwork: version: 2 ethernetswifisbondsbridgesvlansr)versionrFrGrrr_network_staterDr8dns_searchdomainsiter_interfacesrfilterrlowerrWrrErr replacerJr_rIrZcopyr'intrHr)+rrrrrrrrjrYrArMrrLifcfgif_typeethmacaddrr bond_config v2_bond_mapr bond_paramsparamrnewnameslave_interfacesrportsr match_prefixparams br_config v2_bridge_mapnewvaluevalportportvalrnscfgr_namer]rs+ rrzRenderer._render_contentsH  A % II, ->>M001$"   "1155lBG #33 %77 #335g -FZZ'F LE5+//6G $$gu%56"@@#%#(:C.1iikOT7-0\HTN:"(('8)<= >y>A%MM<";<99]++0+?+E+E+GF<("5&&$--H/0F" ))I.!II&78 ))M48&)0D&"5$ F fd^,Og -V -"-GE%ueWeD 7")--/7JE3$+{#/E JJ u567 7  34?; ::?7E22?7E22?9g66?7E22wwwr!r)NN)F)__name__ __module__ __qualname____doc__rrrrr&rrrrrboolrrrrr!rrr+sL!:.v&L6 $s) "%) 1#1D>1  1B 7T 74 7"B] \] c] r!rcTdg}ddg}|D]}tj|||ryy)Nrz /usr/sbinz/sbin)rBrhFT)r which)rhexpectedrBps r availabler6s:{H7 #F zz!F6: r!r)+rr~loggingrbrtempfilertypingrrr cloudinitrrr r cloudinit.netr r r rrrcloudinit.net.network_staterrrzrf getLoggerrrFr rrWr_rnr&rrrrrrrr!rr#s  )++44G: g!CKtCKDCKHCKL 7:1C1D1h00s0t02#22H x  H Vr!