3 \mevK@sddlZddlZddlZddlZddlZddlZddlmZmZddl m Z m Z m Z m Z ddlmZmZmZmZmZddlmZmZdZejeZddZdeed d d Zd d ZdddZGdddej Z dddZ!dS)N)Optionalcast)featuressafeyamlsubputil)IPV6_DYNAMIC_TYPES SYS_CLASS_NETget_devicelistrenderersubnet_is_ipv6)NET_CONFIG_TO_V2 NetworkStates4# 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 cstfdd|jDS)Nc3s$|]\}}|jr||fVqdS)N) startswith).0keyvalue)match/usr/lib/python3.6/netplan.py *sz,_get_params_dict_by_match..)dictitems)configrr)rr_get_params_dict_by_match(s r)rentrycCsld(dd}|dkrg}g}g}g}g}|jdg} | dkr>g} x| D]} | jd} | jdr| dkrp| d7} |j| d iqF| tkr|jd d iqF| d)krFd | jd} d| kr| d| jd7} | jdrl| jddd} yDtj| d}tj| dd}||kr&tjd| d| d | d<Wn8t k r`}ztj d| d| |WYdd}~XnX|j | d| kr||| jdg7}d| kr||| jdg7}d| krd}t | rd|krd}|j|| jdixh| jdgD]X}d|jd|jdf}|jd|d} d |kr<| jd |jd d!i|j | qW|j | qFWd|kr|jd}|r|d|krtj d"||d|n |d|d<t |d#kr|jd$|it |d#kr|jd|it |d#krd$|i}|jd%|it |d#kr6|jd%i}|jd&|i|jd%|id'|krh|d'dk rh|jd'tj|jd'idS)*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}  cSs2| st|t r|S||kr(|j|S|gSdS)zT Helper to convert strings to list of strings, handle single string N) isinstancestrsplit)objtokenrrr_listifyUs  z$_extract_addresses.._listifyNsubnetstypeZdhcp4TZdhcp6staticstatic6z%sZaddressprefixz/%dZgatewaydefault)ZviaZtoF)strictzAGateway %s is not contained within subnet %s, adding on-link flagzon-linkzDFailed to check whether gateway %s is contained within subnet %s: %sdns_nameserversZ dns_searchZmtuzipv6-mturoutesz%s/%snetworkZmetricdzZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r addresses nameserverssearchz accept-ra)r)r&r')getrupdater ipaddressZ ip_addressZ ip_networkLOGdebug ValueErrorZwarningappendr lenrZis_true)rrifnamerr"r/r,r0 searchdomainsr#ZsubnetZsn_typeZaddrZ new_routeZsubnet_gatewayZsubnet_networkeZmtukeyZrouteZto_netZ entry_mtunsrrr_extract_addresses0s%                r>cs8tfdd|jD}t|dkr4|jd|idS)Ncs$g|]\}}|jddkr|qS)z bond-masterN)r2)rnamecfg) bond_masterrr sz0_extract_bond_slaves_by_name..r interfaces)sortedrr9r3)rCrrAZbond_slave_namesr)rAr_extract_bond_slaves_by_names   rEcstjd}tjj|sdStj|dd}|tkr6dSfddd D}d d|D}tj d ||x|g|D]}tj |qpWdS) Nz etc/netplan/00-snapd-config.yamlF)decodecsg|]}tj|qSr)r target_path)rf)targetrrrBsz"_clean_default..-run/systemd/network/10-netplan-all-en.network.run/systemd/network/10-netplan-all-eth.network#run/systemd/generator/netplan.stampcSsg|]}tjj|r|qSr)ospathisfile)rrHrrrrBsz9removing known config '%s' and derived existing files: %s)rJrKrL) rrGrMrNrOrZ load_fileKNOWN_SNAPD_CONFIGr5r6unlink)rIZtpathcontentZderivedZexistingrHr)rIr_clean_defaults"   rSc@szeZdZdZddgZddgZdddZedd Zde e e dd d d Z de e dddZdddZe edddZdS)RendererzBRenders network information in a /etc/netplan/network.yaml format.netplanZgenerateinfoNcCsR|si}|jdd|_|jdd|_|jdd|_|jdd|_|jdd|_dS) N netplan_pathzetc/netplan/50-cloud-init.yamlnetplan_headerZpostcmdsF clean_defaultTr)r2rWrX _postcmdsrY _features)selfrrrr__init__s zRenderer.__init__cCs|jdkry0tj|jdd\}}tj|}|dd|_WnFtjk rPYn2ttfk r}ztj d|WYdd}~XnX|jS)NT)capturez netplan.iorz-Failed to list features from netplan info: %s) r[r NETPLAN_INFOrZ load_yamlProcessExecutionError TypeErrorKeyErrorr5r6)r\Z info_blobZ_errrVr<rrrrs  zRenderer.features) network_state templatesreturnc Cs*tjjtj||j}tjtjj||j |}|j r>|j nd}|j dsT|d7}||}d}tjj |rtj tj|j}t|d} tj | } WdQRX|| krd}tjrdnd} | rtjj |rtj|} | | @| kr| } tj||| d|jrt|d |j|j|d |j|jd dS) N FrbTii)mode)rI)run same_content)rj)rMrNjoinrrGrWrZ ensure_dirdirname_render_contentrXendswithexistsZ hash_bufferioBytesIOencodeopenrZNETPLAN_CONFIG_ROOT_READ_ONLYZget_permissionsZ write_filerYrS_netplan_generaterZ_net_setup_link) r\rcrdrIZfpnplanrRheaderrkZhashed_contentrHZhashed_original_contentriZ current_moderrrrender_network_state s0        zRenderer.render_network_stateF)rjrkcCs8|stjddS|r$tjddStj|jdddS)Nz!netplan generate postcmd disabledzEskipping call to `netplan generate`. reason: identical netplan configT)r^)r5r6rNETPLAN_GENERATE)r\rjrkrrrru8s zRenderer._netplan_generatecCs|stjddSdddg}t}xtdD]l}y>x6tD],}tjjt|r8t j |t|gddq8WPWq*t j k r}z |}WYdd}~Xq*Xq*Wt d |dS) 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 disabledNZudevadmz test-builtinZnet_setup_linkT)r^zQ'udevadm test-builtin net_setup_link' unable to run successfully for all devices.) r5r6 Exceptionranger rMrNislinkr rr` RuntimeError)r\rjZ setup_lnkZlast_exception_Zifacer<rrrrvDs"   zRenderer._net_setup_link)rcrec+Csd|jdkr*tjdtjd|jidddSi}i}i}i}i}g}|jjdg}|j} |j } x4|j D]&} | jd} t t dd | j } | jd }|d kr| | jd dd }|d dkr| jdd}|dk rd|ji|d <n |d =|d=t| || |j|j| |iqh|dkr i}i}tt tjd}x^d/D]V}t| |}xD|j D]8\}}|j|jdd}|dkrzqR|j||iqRWq:Wt|dkr|jd|i| jdr| dj|d<| jd}|dkrt||| t| || |j|j| |iqh|dkr2| jd}ttj|}d|i}d}t| |}i}tt tjd} x|j D]t\}}| j|}|dkrqb|j||i|d0krbi}!x&|D]}"|"j\}#}$t|$|!|#<qW|j||!iqbWt|dkr|jd|i| jdr| dj|d<t| || |j|j| |iqh|dkrh| jd | jd!d"}%| jdd}|dk rr|j|%d<t| |%| |j|j| |%iqhW| s| r| | d#}&xV|||||gD]D}'x<|'j D]0\}(})d$|)ksd%|)krq|)jd$|&iqWqWd&d'}*|jd(||*d)|7}||*d*|7}||*d+|7}||*d,|7}||*d-|7}d.j|S)1NzV2 to V2 passthroughr-F)explicit_start explicit_endrCr?cSs |ddk S)Nr)itrrr}sz*Renderer._render_content..r$Zphysicalr)zset-namerZ mac_addressZ macaddresszset-namebondbond_bond-r-rZ parametersz bond-slavesZnonebridge bridge_portsZbridge_ path-cost port-priorityvlanZvlan_idzvlan-raw-device)idlink)r/r1r0r/cSs0|r,tj||idddd}tj|d}|gSgS)NFT)rrZnoaliasrz )rdumpstextwrapindent)r?sectiondumpZtxtrrr_render_sections z1Renderer._render_content.._render_sectionznetwork: version: 2 ethernetswifisbondsbridgesvlansrf)rr)rr)versionr5r6rrrZ_network_stater2r+Zdns_searchdomainsZiter_interfacesrfilterrlowerr>rr3rr rreplacer9rErDcopyrintr8rl)+r\rcrrrrrrRrCr0r;rr:ZifcfgZif_typeZethZmacaddrrZ bond_configZ v2_bond_maprZ bond_paramsZparamrZnewnameZslave_interfacesrZportsrZ match_prefixZparamsZ br_configZ v2_bridge_mapZnewvaluevalZportZportvalrZnscfgr_namer@rrrrrncs                              zRenderer._render_content)N)NN)FF)F)__name__ __module__ __qualname____doc__ryr_r]propertyrrrrrxboolrurvrrnrrrrrTs  ' rTcCs4dg}ddg}x |D]}tj|||dsdSqWdS)NrUz /usr/sbinz/sbin)r1rIFT)rZwhich)rIZexpectedr1prrr availables  r)N)N)N)"rrqr4ZloggingrMrZtypingrrZ cloudinitrrrrZ cloudinit.netrr r r r Zcloudinit.net.network_stater rrPZ getLoggerrr5rrr>rErSrTrrrrrs(