a '¡DgbŽã@s„UddlZddlZddlZddlmZmZmZmZddlm Z m Z m Z ddl m Z mZmZmZmZmZmZmZmZer‚ddlmZe e¡ZdZdgd¢iZgd¢Zd d d d d dddddddddddœdddddddddd dd!œ d"œZeeeeeffe d#<e!dd$œd%d&„Z"d'd(„Z#Gd)d*„d*e$ƒZ%d+d,„Z&Gd-d.„d.ƒZ'Gd/d0„d0ƒZ(d1d2„Z)d>d4d5„Z*d6d7„Z+d8d9„Z,d?e!e-e'd;œd.wrapper..decorator)Ú functoolsÚwraps)rFrH©rG)rFr4Úwrapperns z$ensure_command_keys..wrapperr3)rGrLr3rKr4Úensure_command_keysms rMc@sšeZdZefeedœdd„Zeedœdd„ƒZedd„ƒZ ed d „ƒZ ed d „ƒZ ed d„ƒZ ddd„Z ddd„Zdd„Zdd„Zeeddœdd„ƒZdS)Ú NetworkState)rrcCs*t |¡|_||_| dd¡|_d|_dS)NÚuse_ipv6F)ÚcopyÚdeepcopyÚ_network_stateÚ_versionÚgetrOÚ_has_default_route)rArrr3r3r4Ú__init__€s zNetworkState.__init__©r2cCs |jdS)Nr)rR©rAr3r3r4rˆszNetworkState.configcCs|jSr6)rSrXr3r3r4rŒszNetworkState.versioncCs,z|jddWSty&gYS0dS)NÚdnsr#©rRÚKeyErrorrXr3r3r4Údns_nameservers�s zNetworkState.dns_nameserverscCs,z|jddWSty&gYS0dS)NrYÚsearchrZrXr3r3r4Údns_searchdomains—s zNetworkState.dns_searchdomainscCs|jdur| ¡|_|jSr6)rUÚ_maybe_has_default_routerXr3r3r4Úhas_default_routežs  zNetworkState.has_default_routeNccs>|j di¡}| ¡D]"}|dur*|Vq||ƒr|VqdS)Nr )rRrTÚvalues)rAÚ filter_funcZifacesÚifacer3r3r4Úiter_interfaces¤s  zNetworkState.iter_interfacesccs6|j dg¡D]"}|dur*||ƒr0|Vq|VqdS©NÚroutes©rRrT)rArbÚrouter3r3r4Ú iter_routes­s zNetworkState.iter_routescCsh| ¡D]}| |¡rdSq| ¡D]<}| dg¡D]*}| dg¡D]}| |¡rFdSqFq6q&dS)NTÚsubnetsrfF)riÚ_is_default_routerdrT)rArhrcÚsubnetr3r3r4r_µs    z%NetworkState._maybe_has_default_routecCs d}| d¡dko| d¡|vS)N)z::z0.0.0.0ÚprefixrÚnetwork)rT)rArhZ default_netsr3r3r4rkÀsÿzNetworkState._is_default_route)rr2cCs,i}d|vr|d|d<|d|ifi|¤ŽS)záInstantiates a `NetworkState` without interpreting its data. That means only `config` and `version` are copied. :param network_state: Network state data. :return: Instance of `NetworkState`. rrr3)ÚclsrrDr3r3r4Úto_passthroughÆs  zNetworkState.to_passthrough)N)N)r>r?r@ÚNETWORK_STATE_VERSIONÚdictÚintrVÚpropertyrrr\r^r`rdrir_rkÚ classmethodrpr3r3r3r4rNs(ÿÿ       rNc@sšeZdZigggdœdddœZeddfddœdd„Zeed œd d „ƒZed d „ƒZ e j dd „ƒZ dd„Z dd„Z dd„Z dd„ZdHdd„ZdIdd„ZdJdd„Zedgƒdd „ƒZedgƒd!d"„ƒZegd#¢ƒd$d%„ƒZegd&¢ƒd'd(„ƒZedd)gƒd*d+„ƒZedgƒd,d-„ƒZd.d/„Zed0gƒd1d2„ƒZed0gƒd3d4„ƒZed5gƒd6d7„ƒZd8d9„Zd:d;„Zdd?„Z d@dA„Z!dd œdBdC„Z"dKdDdE„Z#dFdG„Z$dS)LÚNetworkStateInterpreter©r#r]FN)r rfrYrOrzOptional[Renderer])r$cCsv||_||_t |j¡|_||jd<d|_i|_||_|j |j |j |j |j |j|j|j|j|j|j|j|jdœ |_dS)NrF) r.Zbondsr/ZbridgesZ ethernetsZ infinibandZloopbackÚ nameserverÚphysicalrhÚvlanZvlansZwifis)rSÚ_configrPrQÚinitial_network_staterRÚ_parsedÚ_interface_dns_mapÚ _rendererÚ handle_bondÚ handle_bondsÚ handle_bridgeÚhandle_bridgesÚhandle_ethernetsÚhandle_infinibandÚhandle_loopbackÚhandle_nameserverÚhandle_physicalÚ handle_routeÚ handle_vlanÚ handle_vlansÚ handle_wifisÚcommand_handlers)rArrr$r3r3r4rVás* óz NetworkStateInterpreter.__init__rWcCsHddlm}|jdkr8t|j|ƒr8t d¡t |j ¡St|j |jd�S)NrrézPassthrough netplan v2 config©r) Úcloudinit.net.netplanrrSÚ isinstancerÚLOGÚdebugrNrpr{rR)rAÚNetplanRendererr3r3r4rþs    z%NetworkStateInterpreter.network_statecCs |j d¡S©NrOrgrXr3r3r4rOsz NetworkStateInterpreter.use_ipv6cCs|j d|i¡dSr•)rRÚupdate)rAÚvalr3r3r4rO scCs|j|j|jdœ}t |¡S)Nr)rSr{rRrÚdumps)rAÚstater3r3r4Údumps ýzNetworkStateInterpreter.dumpcCsvd|vrt d¡tdƒ‚t|d}t||ƒ}|rNd|}t |¡t|ƒ‚dd„|DƒD]}t||||ƒq\dS)Nrz$Invalid state, missing version fieldzInvalid state, missing keys: %scSsg|]}|dvr|‘qS)r�r3)Ú.0Úkr3r3r4Ú $óz0NetworkStateInterpreter.load..)r’ÚerrorÚ ValueErrorÚNETWORK_STATE_REQUIRED_KEYSr<Úsetattr)rAr™rGrEÚmsgr;r3r3r4Úloads    zNetworkStateInterpreter.loadcCs t |j¡Sr6)rr˜rRrXr3r3r4Údump_network_state'sz*NetworkStateInterpreter.dump_network_statecCs|j|jdœS)N)rr)rSr{rXr3r3r4Úas_dict*szNetworkStateInterpreter.as_dictTcCs>|jdkr|j|d�d|_n|jdkr:|j|d�d|_dS)Nr©Ú skip_brokenTrŽ)rSÚparse_config_v1r}Úparse_config_v2)rAr¨r3r3r4Ú parse_config-s     z$NetworkStateInterpreter.parse_configc Cs|jD]”}|d}z|j|}Wn2tyR}ztd|ƒ|‚WYd}~n d}~00z ||ƒWqty˜|sv‚ntjd|dd�t | ¡¡Yq0q|j   ¡D]n\}}d}z|j d|}Wn4tyø}zt d  |¡ƒ|‚WYd}~n d}~00|r¦|\} } | | dœ|d <q¦dS) NÚtypez"No handler found for command '%s'úSkipping invalid command: %sT©Úexc_infor zINameserver specified for interface {0}, but interface {0} does not exist!rwrY)r{r�r[Ú RuntimeErrorr=r’Úwarningr“r¥r~ÚitemsrRr Úformat) rAr¨rBÚ command_typeÚhandlerÚeÚ interfacerYrcr#r]r3r3r4r©5sH ÿþ  ÿÿÿýþz'NetworkStateInterpreter.parse_config_v1c CsÐddlm}t|j|ƒrdS|j ¡D]¤\}}|dvr8q&z|j|}Wn2tyx}ztd|ƒ|‚WYd}~n d}~00z||ƒ|  |¡Wq&t yÈ|s¦‚nt j d|dd�t   | ¡¡Yq&0q&dS)Nrr)rr$z!No handler found for command '%s'r­Tr®)r�rr‘rr{r²r�r[r°Ú _v2_commonr=r’r±r“r¥)rAr¨r”r´rBrµr¶r3r3r4rªXs0  ÿþ ÿz'NetworkStateInterpreter.parse_config_v2ÚnamecCs | |¡Sr6©rˆ©rArBr3r3r4r†tsz'NetworkStateInterpreter.handle_loopbackc Cs\|j di¡}| |di¡}| di¡ ¡D]\}}| ||i¡q.t| d¡ƒ}|jsŒ|D],}| d¡ d¡s€t| d¡ƒr^d|_qŒq^| d d ¡}|d urªt  |¡}| d d ¡} | d urÈt  | ¡} | d d ¡} | d uræt  | ¡} | | d ¡| d¡| d¡| d¡dd| d¡d d ||| | dœ ¡| d | d¡¡} |jd | |i¡|  ¡d S)zþ command = { 'type': 'physical', 'mac_address': 'c0:d6:9f:2c:e8:80', 'name': 'eth0', 'subnets': [ {'type': 'dhcp4'} ], 'accept-ra': 'true' } r r¹Úparamsrjr¬Ú6ÚaddressTr'Nr&r(Ú config_idÚ mac_addressÚinetZmanualr") r¿r¹r¬rÀrÁr)r"r¾Úgatewayrjr'r&r() rRrTr²r–Ú_normalize_subnetsrOÚendswithrrZis_truer¥) rArBr rcÚparamr—rjrlZ accept_rar&r(Z iface_keyr3r3r4rˆxsPÿ      óÿz'NetworkStateInterpreter.handle_physical)r¹Úvlan_idÚ vlan_linkcCs\|j di¡}| |¡| | d¡i¡}| d¡|d<| d¡|d<| |d|i¡dS)zâ auto eth0.222 iface eth0.222 inet static address 10.10.10.1 netmask 255.255.255.0 hwaddress ether BC:76:4E:06:96:B3 vlan-raw-device eth0 r r¹rÇzvlan-raw-devicerÆN)rRrTrˆr–)rArBr rcr3r3r4rеs  z#NetworkStateInterpreter.handle_vlan)r¹Úbond_interfacesr¼c Cs| |¡|j d¡}| | d¡i¡}| d¡ ¡D]\}}| ||i¡q6| ddi¡|jd |d|i¡| d¡D]€}||vrž|ddœ}| |¡|j di¡}| |¡}| d¡|d <| d¡ ¡D]\}}| ||i¡qÒ|jd ||i¡q~d S) aU #/etc/network/interfaces auto eth0 iface eth0 inet manual bond-master bond0 bond-mode 802.3ad auto eth1 iface eth1 inet manual bond-master bond0 bond-mode 802.3ad auto bond0 iface bond0 inet static address 192.168.0.10 gateway 192.168.0.1 netmask 255.255.255.0 bond-slaves none bond-mode 802.3ad bond-miimon 100 bond-downdelay 200 bond-updelay 200 bond-lacp-rate 4 r r¹r¼z bond-slavesZnonerÈr.)r¹r¬z bond-masterN)rˆrRrTr²r–) rArBr rcrÅr—ÚifnameÚcmdZbond_ifr3r3r4r€Æs&  þ  z#NetworkStateInterpreter.handle_bondÚbridge_interfacesc Cs|j di¡}| d¡D] }||vr&qd|i}| |¡q|j di¡}| |¡| | d¡i¡}|d|d<| di¡ ¡D]\}}| ||i¡q€| d¡}|durît|tƒsî|dvrÂd }n|d vrÐd }ntd j|d �ƒ‚| d|i¡| |d|i¡dS)a¿ auto br0 iface br0 inet static address 10.10.10.1 netmask 255.255.255.0 bridge_ports eth0 eth1 bridge_stp off bridge_fd 0 bridge_maxwait 0 bridge_params = [ "bridge_ports", "bridge_ageing", "bridge_bridgeprio", "bridge_fd", "bridge_gcint", "bridge_hello", "bridge_hw", "bridge_maxage", "bridge_maxwait", "bridge_pathcost", "bridge_portprio", "bridge_stp", "bridge_waitport", ] r rËr¹Z bridge_portsr¼r-N)ZonÚ1rT)ZoffÚ0rFz2Cannot convert bridge_stp value ({stp}) to boolean)r,) rRrTrˆr²r–r‘Úboolr r³) rArBr rÉrÊrcrÅr—r-r3r3r4r‚ûs4ÿ    ÿÿz%NetworkStateInterpreter.handle_bridgecCs| |¡dSr6rºr»r3r3r4r…<sz)NetworkStateInterpreter.handle_infinibandcCsxg}g}d|vr<|d}t|tƒs(|g}|D]}| |¡q,d|vrp|d}t|tƒs\|g}|D]}| |¡q`||fS)Nr¾r])r‘ÚlistÚappend)rArBr#r]ÚaddrsÚaddrÚpathsÚpathr3r3r4Ú _parse_dns@s    z"NetworkStateInterpreter._parse_dnsr¾cCsV|j d¡}| |¡\}}d|vr6||f|j|d<n|d |¡|d |¡dS)NrYr·r#r])rRrTrÕr~Úextend)rArBrYr#r]r3r3r4r‡Qs þz)NetworkStateInterpreter.handle_nameservercCs0|j d¡}| |¡\}}||dœ||d<dS)Nr rwrY)rRrTrÕ)rArBrcZ_ifacer#r]r3r3r4Ú_handle_individual_nameserver^s z5NetworkStateInterpreter._handle_individual_nameserverÚ destinationcCs|jd t|ƒ¡dSre)rRrÐÚ_normalize_router»r3r3r4r‰dsz$NetworkStateInterpreter.handle_routecCs|j|dd�dS)aç v2_command = { bond0: { 'interfaces': ['interface0', 'interface1'], 'parameters': { 'mii-monitor-interval': 100, 'mode': '802.3ad', 'xmit_hash_policy': 'layer3+4'}}, bond1: { 'bond-slaves': ['interface2', 'interface7'], 'parameters': { 'mode': 1, } } } v1_command = { 'type': 'bond' 'name': 'bond0', 'bond_interfaces': [interface0, interface1], 'params': { 'bond-mode': '802.3ad', 'bond_miimon: 100, 'bond_xmit_hash_policy': 'layer3+4', } } r.©Úcmd_typeN©Ú_handle_bond_bridger»r3r3r4r�isz$NetworkStateInterpreter.handle_bondscCs|j|dd�dS)a÷ v2_command = { br0: { 'interfaces': ['interface0', 'interface1'], 'forward-delay': 0, 'stp': False, 'maxwait': 0, } } v1_command = { 'type': 'bridge' 'name': 'br0', 'bridge_interfaces': [interface0, interface1], 'params': { 'bridge_stp': 'off', 'bridge_fd: 0, 'bridge_maxwait': 0 } } r/rÚNrÜr»r3r3r4rƒˆsz&NetworkStateInterpreter.handle_bridgescCstƒ}| ¡D�]\}}|ddœ}| di¡}| dd¡}|sPt d|t|ƒ¡||d<|}| d¡} | rp| }n |r�|r�| ¡} t| ƒ} | r�| }||d <| d d¡} | r´d | i|d <d D]} | |vr¸|| || <q¸t|ƒ|  |¡}t |ƒd krþ|  d|i¡t d|¡|  |¡qdS)a� ethernets: eno1: match: macaddress: 00:11:22:33:44:55 driver: hv_netvsc wakeonlan: true dhcp4: true dhcp6: false addresses: - 192.168.14.2/24 - 2001:1::1/64 gateway4: 192.168.14.1 gateway6: 2001:1::2 nameservers: search: [foo.local, bar.local] addresses: [8.8.8.8, 8.8.4.4] lom: match: driver: ixgbe set-name: lom1 dhcp6: true accept-ra: true switchports: match: name: enp2* mtu: 1280 command = { 'type': 'physical', 'mac_address': 'c0:d6:9f:2c:e8:80', 'name': 'eth0', 'subnets': [ {'type': 'dhcp4'} ] } ry)r¿r¬r!Z macaddressNzHNetworkState Version2: missing "macaddress" info in config entry: %s: %srÀr%r¹Údriverr¼)r"r!r&r'r(rrjz!v2(ethernets) -> v1(physical): %s) r r²rTr’r“ÚstrÚlowerr r5Ú_v2_to_v1_ipcfgÚlenr–rˆ)rArBZ ifaces_by_macZethÚcfgZphy_cmdr!rÀr¹Zset_nameZlcase_mac_addressZmacrÞr;rjr3r3r4r„¡sH-þ  ü      z(NetworkStateInterpreter.handle_ethernetscCs†| ¡D]x\}}d|| d¡| d¡dœ}d|vr>|d|d<t|ƒ| |¡}t|ƒdkrj| d|i¡t d|¡| |¡qd S) aq v2_vlans = { 'eth0.123': { 'id': 123, 'link': 'eth0', 'dhcp4': True, } } v1_command = { 'type': 'vlan', 'name': 'eth0.123', 'vlan_link': 'eth0', 'vlan_id': 123, 'subnets': [{'type': 'dhcp4'}], } rzÚidÚlink)r¬r¹rÆrÇr"rrjzv2(vlans) -> v1(vlan): %sN) r²rTr5rárâr–r’r“rŠ)rArBrzrãZvlan_cmdrjr3r3r4r‹sü    z$NetworkStateInterpreter.handle_vlanscCst d¡dS)NzOWifi configuration is only available to distros with netplan rendering support.)r’r±r»r3r3r4rŒ"sÿz$NetworkStateInterpreter.handle_wifiscCsvt d|¡| ¡D]\\}}d|vr| d¡ d¡}| d¡ d¡}ddi}|rX||d<|rd||d<| ||¡qdS)Nzv2_common: handling config: %sr#r]rr¬rxr¾)r’r“r²rTr×)rArãrcZdev_cfgr]rYZname_cmdr3r3r4r¸(s z"NetworkStateInterpreter._v2_commonc s.tdd„t |¡ ¡Dƒƒ‰| ¡D�]\}}tdd„| ¡Dƒƒ}| di¡}| dd¡}|rh||d<d|d ||d | d ¡d t‡fd d„| ¡Dƒƒi}d|vr°|d|d<t|ƒ| |¡} t| ƒdkrÜ| d| i¡t   d|||¡|dk�r|  |¡q$|dk�r|  |¡q$t dj|d�ƒ‚q$dS)z(Common handler for bond and bridge typescss|]\}}||fVqdSr6r3©r›rœÚvr3r3r4Ú :sz>NetworkStateInterpreter._handle_bond_bridge..css"|]\}}|tvr||fVqdSr6)ÚNETWORK_V2_KEY_FILTER)r›r;Úvaluer3r3r4rè?sþÚ parameterszgratuitious-arpNr*r¬r¹Z _interfacesr r¼c3s|]\}}ˆ||fVqdSr6r3ræ©Z v2key_to_v1r3r4rèOržr"rrjzv2(%s) -> v1(%s): %sr/r.z Unknown command type: {cmd_type}rÚ)rrr0rTr²Úpopr5rárâr–r’r“r‚r€r r³) rArBrÛZ item_nameZitem_cfgZ item_paramsr¼Z grat_valueZv1_cmdrjr3rìr4rÝ6s@ ÿþ  ü       ÿÿz+NetworkStateInterpreter._handle_bond_bridgec Cs¼dd„}g}| d¡r:ddi}|| di¡|ƒ| |¡| d¡rnddi}d|_|| di¡|ƒ| |¡d }d }i}| d g¡D]È}d |d œ}d |vrÆd|vrî|d urî| d¡}| d|i¡n(d|vrî|d urî| d¡}| d|i¡d|v�rD|�sD| d¡ d ¡} | �r| |d<| d¡ d¡} | �r:| |d<| |¡| |¡q†g} | dg¡D]6} |  t|  d¡|  d¡|  d¡|  d¡dœƒ¡�q`t|ƒ�r¸t| ƒ�r¸| |dd<|S)z7Common ipconfig extraction from v2 to v1 subnets array.cSsd|vr|d|d<dS)Nz route-metricÚmetricr3)Z overridesrlr3r3r4Ú_add_dhcp_overrideshszDNetworkStateInterpreter._v2_to_v1_ipcfg.._add_dhcp_overridesrr¬rrTrNrÚstatic)r¬r¾ú:rrÂrr#r\r]Ú dns_searchrfÚtoZviarîr")rØrÂrîr"r)rTrÐrOr–rÙrâ) rArãrïrjrlrrr#r¾rr]rfrhr3r3r4ráes`    þ    üÿÿ  z'NetworkStateInterpreter._v2_to_v1_ipcfg)T)T)T)N)%r>r?r@r|rqrVrtrNrrOÚsetterršr¤r¥r¦r«r©rªrMr†rˆrŠr€r‚r…rÕr‡r×r‰r�rƒr„r‹rŒr¸rÝrár3r3r3r4rvÕslþø üü     #   <    4  @    _" /rvcCszt |¡}tdd„| ¡Dƒƒ}| d¡dvr@| t|dd�¡dd„| d g¡Dƒ|d <d d „}d D]}|||ƒqf|S) Ncss|]\}}|r||fVqdSr6r3rær3r3r4rè¬ržz$_normalize_subnet..r¬)rðZstatic6)r¾Ú ip_address©Ú address_keyscSsg|] }t|ƒ‘qSr3)rÙ)r›Úrr3r3r4r�¸sz%_normalize_subnet..rfcSs*||vr&t||tƒs&|| ¡||<dSr6)r‘rÏÚsplit)Zsnetr¹r3r3r4Úlistify¼sz"_normalize_subnet..listify)ròr\)rPrQrrr²rTr–Ú_normalize_net_keys)rlZ normal_subnetrúrœr3r3r4Ú_normalize_subnet©s  þÿ  ÿ  rür3cCs¼dd„| ¡Dƒ}d}|D]}| |¡r|}q2q|sZdd |¡|f}t |¡t|ƒ‚t| |¡ƒ}t|ƒsŒt d|¡td|›d�ƒ‚t|ƒ}t |ƒ}| d ¡} d |v�r|  d ¡\} } } | ||<|rÖt | ƒ} n*|rät | ƒ} nt d|¡td|›d�ƒ‚nRd |v�rt |d ƒ} n:| �r0|�r0t | ƒ} n$| �rF|�rFt | ƒ} n|�rPd nd } d |v�r‚t|d ƒt| ƒk�r‚t d| |¡| |d <|�r¢d |v�r¸|d =n|�r¸t|d ƒ|d <|S)a¬Normalize dictionary network keys returning prefix and address keys. @param network: A dict of network-related definition containing prefix, netmask and address_keys. @param address_keys: A tuple of keys to search for representing the address or cidr. The first address_key discovered will be used for normalization. @returns: A dict containing normalized prefix and matching addr_key. cSs"i|]\}}|s|dkr||“qS)rr3rær3r3r4Ú Ñržz'_normalize_net_keys..Nz/No config network address keys [%s] found in %sú,z$Address %s is not a valid ip networkzAddress z is not a valid ip addressÚnetmaskú/rmé@éz;Overwriting existing 'prefix' with '%s' in network info: %s)r²rTÚjoinr’rŸr rßr rrÚ partitionr r rsr±r)rnr÷ÚnetZaddr_keyr;ÚmessagerÒZipv6Zipv4rÿZ addr_partÚ_Z maybe_prefixrmr3r3r4rûÆsb  þ             ý rûc Csštdd„| ¡Dƒƒ}d|vr0|d|d<|d=| t|dd�¡| d¡}|r–zt|ƒ|d<Wn4ty”}ztd |¡ƒ|‚WYd }~n d }~00|S) aƒnormalize a route. return a dictionary with only: 'type': 'route' (only present if it was present in input) 'network': the network portion of the route as a string. 'prefix': the network prefix for address as an integer. 'metric': integer metric (only if present in input). 'netmask': netmask (string) equivalent to prefix iff network is ipv4. css"|]\}}|dvr||fVqdS))ÚNNr3rær3r3r4rèsz#_normalize_route..rØrn)rnrØrörîz(Route config metric {} is not an integerN) rrr²r–rûrTrsr Ú TypeErrorr³)rhZ normal_routerîr¶r3r3r4rÙs, ÿ ÿÿ ÿþrÙcCs|sg}dd„|DƒS)NcSsg|] }t|ƒ‘qSr3)rü)r›Úsr3r3r4r�7ržz&_normalize_subnets..r3)rjr3r3r4rÃ4srÃT)Ú net_configr¨r2cCsfd}| d¡}| d¡}|dkr$|}|rP|durPt|||d�}|j|d�|j}|sbtd|›�ƒ‚|S)zfParses the config, returns NetworkState object :param net_config: curtin network config dict NrrrŽ)rrr$r§zpNo valid network_state object created from network config. Did you specify the correct version? Network config: )rTrvr«rr°)r r¨r$r™rrZnsir3r3r4Úparse_net_config_data:s$    ÿ þÿr )r3)TN)/rPrIZloggingÚtypingrrrrZ cloudinitrrrZ cloudinit.netr r r r r rrrrZcloudinit.net.rendererrZ getLoggerr>r’rqr¡rér0rßÚ__annotations__rrr5r<Ú Exceptionr=rMrNrvrürûrÙrÃrÎr r3r3r3r4Ús~ ,   ÿñõî" VY L"ýü