o x[hR@s,ddlZddlZddlZddlZddlZddlmZddlmZm Z m Z ddl m Z m Z mZmZddlmZmZmZmZmZmZddlmZmZdZdZeeZd d Zd e d e d efddZ!ddZ"d"ddZ#de$de%fddZ&de$de$de%fddZ'de$de$fddZ(Gdddej)Z)d"d d!Z*dS)#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 cstfdd|DS)Nc3s&|]\}}|r||fVqdSN) startswith).0keyvaluematch7/usr/lib/python3/dist-packages/cloudinit/net/netplan.py ,s z,_get_params_dict_by_match..)dictitems)configrrrr_get_params_dict_by_match+s rrentryrc Csd$dd}g}g}g}g}|dg} | durg} | D]} | d} | dr7| dkr/| d7} || d iq| tvrC|d d iq| d vrd | d } d| vr[| d| d7} | dr| ddd} t| d| r|td| d| d | d<|| d| vr||| dg7}d| vr||| dg7}d| vrd}t| rd|vrd}||| di| dgD]*}d|d|df}|d|d} d|vr| d|ddi|| q|| qd|vr|d}|r|d|krt d||d|n|d|d<t |dkr"|d |it |dkr0|d|it |dkrBd |i}|d!|it |dkr]|d!i}|d"|i|d!|id#|vrx|d#durz|d#t |d#idSdSdS)%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}  cSs*|rt|ts |S||vr||S|gS)zT Helper to convert strings to list of strings, handle single string ) isinstancestrsplit)objtokenrrr_listifyXs  z$_extract_addresses.._listifysubnetsNtypedhcp4Tdhcp6)staticstatic6z%saddressprefixz/%dgatewaydefault)viatozAGateway %s is not contained within subnet %s, adding on-link flagzon-linkdns_nameservers dns_searchmtuzipv6-mturoutesz%s/%snetworkmetricdzZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r addresses nameserverssearchz accept-ra)r!) getrupdater rLOGdebugappendrwarninglenr is_true)rr ifnamerr'r<r8r= searchdomainsr(subnetsn_typeaddr new_routemtukeyrouteto_net entry_mtunsrrr_extract_addresses3s %            rRcs<tfdd|D}t|dkr|d|idSdS)Ncs$g|]\}}|ddkr|qS)z bond-masterN)r?)rnamecfg bond_masterrr s z0_extract_bond_slaves_by_name..r interfaces)sortedrrEr@)rXr rVbond_slave_namesrrUr_extract_bond_slaves_by_names  r[cs~td}tj|sdSt|}|tkrdSfdddD}dd|D}t d|||g|D]}t |q5dS)Nz etc/netplan/00-snapd-config.yamlcsg|]}t|qSr)r target_pathrftargetrrrWs z"_clean_default..)z-run/systemd/network/10-netplan-all-en.networkz.run/systemd/network/10-netplan-all-eth.networkz#run/systemd/generator/netplan.stampcSsg|] }tj|r|qSr)ospathisfiler]rrrrWsz9removing known config '%s' and derived existing files: %s) rr\rarbrcr load_binary_fileKNOWN_SNAPD_CONFIGrArBunlink)r`tpathcontentderivedexistingr^rr_r_clean_defaults$     rknet_config_contentreturnc Cszddlm}ddlm}WntytdtYdSwz@tdd1}| || | dt j |}|||}|||tjtWdn1sYwYWntyy}ztd t|WYd}~dSd}~wwtd d S) 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.parserrn netplan.statero ImportErrorrArBCLOUDINIT_NETPLAN_FILErwriteflushseekioSEEK_SET load_yamlimport_parser_results_write_yaml_filerarbbasename ExceptionrD)rlrnror^parserstate_output_fileerrrnetplan_api_write_yaml_filesF        rcfg_filerhcCs.tj|sdStt|}|t|kS)zs z*Renderer._render_content..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<r>r=r<cSs0|rtj||idddd}t|d}|gSgS)NFT)rrnoaliasz )rdumpstextwrapindent)rSsectiondumptxtrrr_render_section s z1Renderer._render_content.._render_sectionznetwork: version: 2 ethernetswifisbondsbridgesvlansr)versionrArBrrr_network_stater?r5dns_searchdomainsiter_interfacesrfilterrlowerrRrr@rrreplacerEr[rDrYcopyr$intrCr)+rrrrrrrrhrXr=rHrrGifcfgif_typeethmacaddrr bond_config v2_bond_mapr bond_paramsparamrnewnameslave_interfacesrportsr match_prefixparams br_config v2_bridge_mapnewvaluevalportportvalrnscfgr_namerTrrrrrs                              zRenderer._render_contentr)NN)F)__name__ __module__ __qualname____doc__rrrrr#rrrrrboolrrrrrrrr+s$   ! !rcCs2dg}ddg}|D] }tj|||dsdSq dS)Nrz /usr/sbinz/sbin)r>r`FT)rwhich)r`expectedr>prrr available6sr r)+rrzloggingrartempfilertypingrrr cloudinitrrrr cloudinit.netr r r r rrcloudinit.net.network_staterrrvre getLoggerrrArrrRr[rkr#rrrrrr rrrrs2    4