3 cj @sJddlZddlZddlZddlZddlZddlZddlmZmZm Z m Z m Z m Z ddl mZddlmZmZddlmZmZejeZdZdZdd d d gZd d dddddddddg ZejdfddZddZdddZddd Z dd!d"Z!d#d$Z"d%d&Z#d'd(Z$d)d*Z%d+d,Z&d-d.Z'd/d0Z(d1d2Z)ej*dd3e+d4d5d6Z,ej*dd3e-d4d7d8Z.e/e+d9d:d;Z0ddd?Z2d@dAZ3de+d4dBdCZ4ddDdEZ5ddFdGZ6dHdIZ7dJdKZ8dLdMZ9dNdOZ:dPdQZ;GdRdSdSe<Z=dTdUZ>e e/d4dVdWZ?e e/d4dXdYZ@e e/d4dZd[ZAe e/d4d\d]ZBe e/d4d^d_ZCe e/d4d`daZDe e/d4dbdcZEe e/d4dddeZFddfdgZGdhdiZHddkdlZIddndoZJddpdqZKdrdsZLdtduZMeNd4dvdwZOe/e e/dxdydzZPeNd4d{d|ZQeNd4d}d~ZReNd4ddZSeNd4ddZTde+e+e+e+e+e+e+e-dddZUede e e/e/e/e/fddddZVddZWe e/efe+dddZXee/dddZYe/e+dddZZe/e+dddZ[e/e+dddZ\e/e+dddZ]e/e+dddZ^e/e+dddZ_e+d4ddZ`e/d4ddZaebd4ddZcebd4ddZde/e/e/dddZeGdddefZgdS)N)AnyCallableDictListOptionalTuple)urlparse)subputil)UrlErrorreadurlz/sys/class/net/Zeth0dhcp6Z ipv6_slaaczipv6_dhcpv6-statelesszipv6_dhcpv6-statefulz ovs-vsctlz--formatZcsvz --no-headingsz --timeoutZ10z --columnsnamefind interfacez type=internalz([0-9]+)cCsddtj||DS)aDSorting for Humans: natural sort order. Can be use as the key to sort functions. This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as ['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8', 'eth0'].cSs$g|]}|jrt|n|jqS)isdigitintlower).0textrr/usr/lib/python3.6/__init__.py 4sz$natural_sort_key..)resplit)sZ_nsrerrrnatural_sort_key,srcCstS)z3Simple function to return the global SYS_CLASS_NET.) SYS_CLASS_NETrrrrget_sys_class_path9srcCst|d|S)N/)r)devnamepathrrr sys_dev_path>sr#c Cst||}ytj|}Wnpttfk r}zPt|dd} | tjtjfkrZ|dk rZ||S| tj fkrv|dk rv||SWYdd}~XnX|j }|dkr|Sy||St k r}z&|dk r||St j d||WYdd}~XnXdS)Nerrnoz5Found unexpected (not translatable) value '%s' in '%s)r#r Z load_fileOSErrorIOErrorgetattrr$ENOENTENOTDIRZEINVALstripKeyErrorLOGdebug) r!r" translate on_enoent on_keyerror on_einvalZdev_pathcontentseZe_errnorrr read_sys_netBs2   r4cCsdd}t||||||dS)NcSsdS)NFr)r3rrr on_excp_falsehsz(read_sys_net_safe..on_excp_false)r0r/r1r.)r4)ifacefieldr.r5rrrread_sys_net_safegsr8c Cs8t||}|dkrdSyt|Stk r2dSXdS)NF)r8r ValueError)r6r7valrrrread_sys_net_intus r;cCsdddd}t|d|dS)NTF)upunknowndown operstate)r.)r8)r!r.rrris_ups r@cCstjjt|dS)Nbridge)osr"existsr#)r!rrr is_bridgesrDcCstjjt|dS)Nbonding)rBr"rCr#)r!rrris_bondsrFcCs t|dd}tjj|r|SdS)z8Return the master path for devname, or None if no mastermaster)r"N)r#rBr"rC)r!r"rrr get_masters  rHcCsHt|}|dkrdStjj|d}tjj|d}tjj|pFtjj|S)z@Return a bool indicating if devname's master is a bridge or bondNFrErA)rHrBr"joinrC)r! master_pathZ bonding_pathZ bridge_pathrrrmaster_is_bridge_or_bonds rKcCs,t|}|dkrdSt|dd}tjj|S)z;Return a bool indicating if devname's master is openvswitchNFzupper_ovs-system)r")rHr#rBr"rC)r!rJZovs_pathrrrmaster_is_openvswitchs  rLcCst|ddkS)Ntype32)r8)r!rrris_ib_interfacesrO)maxsize)returncCs ttjd}|stjd|S)zDReturn a bool indicating if Open vSwitch is installed in the system.z ovs-vsctlztjk rP}z d|jkr>tjdgSWYdd}~Xn X|jSdS)zReturn a list of the names of OVS internal interfaces on the system. These will all be strings, and are used to exclude OVS-specific interface from cloud-init's network configuration handling. zdatabase connection failedzJOpen vSwitch is not yet up; no interfaces will be detected as OVS-internalN)r !OVS_INTERNAL_INTERFACE_LOOKUP_CMDZProcessExecutionErrorstderrr,info splitlines)out_errexcrrrget_ovs_internal_interfacess r\)r!rQcCs,ts dSt}||kr(tjd|dSdS)zReturns True if this is an OVS internal interface. If OVS is not installed or not yet running, this will return False. FzDetected %s as an OVS interfaceT)rTr\r,r-)r!Z ovs_bridgesrrr!is_openvswitch_internal_interfaces r]cCs,|dkrt|}t||s$t||r(dSdS)znetfailover driver uses 3 nics, master, primary and standby. this returns True if the device is either the primary or standby as these devices are to be ignored. NTF) device_driveris_netfail_primaryis_netfail_standby)r!driverrrris_netfailovers  rbc Cs,d}yt|d}Wntk r&YnX|S)zDReturns a str from reading /sys/class/net//device/features.rzdevice/features)r4 Exception)r!featuresrrrget_dev_featuress recCs*t|}| st|dkrdS|ddkS)z Return True if VIRTIO_NET_F_STANDBY bit (62) is set. https://github.com/torvalds/linux/blob/ 089cf7f6ecb266b6a4164919a2e69bd2f938374a/ include/uapi/linux/virtio_net.h#L60 @F>1)relen)r!rdrrrhas_netfail_standby_featuresrjcCs<t|dk rdS|dkr t|}|dkr,dSt|s8dSdS)zA device is a "netfail master" device if: - The device does NOT have the 'master' sysfs attribute - The device driver is 'virtio_net' - The device has the standby feature bit set Return True if all of the above is True. NF virtio_netT)rHr^rj)r!rarrris_netfail_masters rlcCstt|dd}tjj|sdS|dkr,t|}|dkr8dStjjtjj|}t|}|dkr`dSt|}|spdSdS)a7A device is a "netfail primary" device if: - the device has a 'master' sysfs file - the device driver is not 'virtio_net' - the 'master' sysfs file points to device with virtio_net driver - the 'master' device has the 'standby' feature bit set Return True if all of the above is True. rG)r"FNrkT)r#rBr"rCr^basenamerealpathrj)r!raZmaster_sysfs_pathZmaster_devnameZ master_driverZmaster_has_standbyrrrr_s  r_cCs<t|dkrdS|dkr t|}|dkr,dSt|s8dSdS)zA device is a "netfail standby" device if: - The device has a 'master' sysfs attribute - The device driver is 'virtio_net' - The device has the standby feature bit set Return True if all of the above is True. NFrkT)rHr^rj)r!rarrrr`:s r`cCst|d}|r|dkrdSdS)a /* interface name assignment types (sysfs name_assign_type attribute) */ #define NET_NAME_UNKNOWN 0 /* unknown origin (not exposed to user) */ #define NET_NAME_ENUM 1 /* enumerated by kernel */ #define NET_NAME_PREDICTABLE 2 /* predictably named by the kernel */ #define NET_NAME_USER 3 /* provided by user-space */ #define NET_NAME_RENAMED 4 /* renamed by user-space */ name_assign_type34TF)rprq)r8)r!rorrr is_renamedRs  rrcCstt|d}d|jkS)Nueventz DEVTYPE=vlan)strr8rX)r!rsrrris_vlanasrucCs0d}t|d}tjj|r,tjjtj|}|S)z8Return the device driver for net device named 'devname'.Nz device/driver)r#rBr"islinkrmreadlink)r!raZ driver_pathrrrr^fs   r^cCst|d}|dkrdS|S)z;Return the device id string for net device named 'devname'.z device/deviceFN)r8)r!Zdev_idrrr device_devidqs rxcCsjtjstjrttjSytjt}Wn6t k rd}z|j t j krRg}nWYdd}~XnX|S)N) r is_FreeBSDis_DragonFlyBSDlistget_interfaces_by_macvaluesrBlistdirrr%r$r()devsr3rrrget_devicelistzs rc@seZdZdZdS) ParserErrorz6Raised when a parser has issue parsing a file/content.N)__name__ __module__ __qualname____doc__rrrrrsrcCs$| st|t rdS|jddkS)NFconfigZdisabled) isinstancedictget)cfgrrris_disabled_cfgsrcCs6tjstjrtStjs&tjr,tStSdS)zqGet the list of network interfaces viable for networking. @return List of interfaces, sorted naturally. N)r ryrzfind_candidate_nics_on_freebsd is_NetBSD is_OpenBSD(find_candidate_nics_on_netbsd_or_openbsdfind_candidate_nics_on_linuxrrrrfind_candidate_nicss rcCs6tjstjrtStjs&tjr,tStSdS)z.Get the name of the 'fallback' network device.N)r ryrzfind_fallback_nic_on_freebsdrr&find_fallback_nic_on_netbsd_or_openbsdfind_fallback_nic_on_linuxrrrrfind_fallback_nics rcCsttjtdS)zmGet the names of the candidate network devices on NetBSD/OpenBSD. @return list of sorted interfaces )key)sortedr|r}rrrrrrsrcCst}|r|dSdS)zfGet the 'fallback' network device name on NetBSD/OpenBSD. @return default interface, or None rN)r)namesrrrrsrcCs8tjddddg\}}|j}|r&|SttjtdS)zgGet the names of the candidate network devices on FreeBSD. @return List of sorted interfaces. ifconfigz-lz-uether)r)r rrr|r}r)stdoutZ_stderrr}rrrrs rcCst}|r|dSdS)z_Get the 'fallback' network device name on FreeBSD. @return List of sorted interfaces. rN)r)rrrrrsrc Cs`dtjkrtjdn.z4Found unstable nic names: %s; calling udevadm settlez!Waiting for udev events to settle)funcFT)filter_openvswitch_internal2filter_slave_if_master_not_bridge_bond_openvswitch filter_vlanfilter_without_own_macfilter_zero_maclog_filtered_reasonsrZvethzIgnoring veth interface: %scarrierzInterface has no carrier: %sdormantr?r>lowerlayerdownr=zInterface ignored: %s)rr)rr>rr=)r Z get_cmdliner,r-rriZlog_timeZudevadm_settleget_interfaces startswithr;appendr8rrDEFAULT_PRIMARY_INTERFACEremoveinsert) ZunstablemsgZ connectedZpossibly_connectedr_rrr?Zsorted_interfaces interfacesrrrrs\                 rcCst}|r|dSdS)z]Get the 'fallback' network device name on Linux. @return List of sorted interfaces. rN)r)rrrrr!srcCsv|sd}t}|sdSt|r(d|i}ndt|dji}dd||d}|rdt|}|rd||dd <||id d }|S) zBGenerate network cfg v2 for dhcp on the NIC most likely connected.FNr macaddressaddressT)Zdhcp4r zset-namematchrra) ethernetsversion)rrlr8rr^)Z config_driverZ target_namerrraZnconfrrrgenerate_fallback_config-s$  rcCsJdd}dd}|jd}|dkr*||S|dkr:||Std|dS) NcSsg}x|jdiD]|}|jddkr&q|jd}|s6q|jd}|jdijd}|jdijd}|spt|}|s|t|}|j||||gqW|S) NrrMZphysicalZ mac_addressrparamsra device_id)rr^rxr)netcfgphysdevsentmacrrarrrr _version_1Ms   z$extract_physdevs.._version_1cSsg}x|jdijD]z}|jd}|s*q|jdijd}|sBq|jdijd}|jdijd}|srt|}|s~t|}|j||||gqW|S)Nrzset-namerrrar)rr}r^rxr)rrrrrrarrrr _version_2_s  z$extract_physdevs.._version_2rrz"Unknown network config version: %s)r RuntimeError)rrrrrrrextract_physdevsLs rFcCs*t|d}|dkr"|rtddS|dkS) areturn True if the provided interface has its own address. Based on addr_assign_type in /sys. Return true for any interface that does not have a 'stolen' address. Examples of such devices are bonds or vlans that inherit their mac from another device. Possible values are: 0: permanent address 2: stolen from another device 1: randomly generated 3: set using dev_set_mac_addressZaddr_assign_typeNz%s had no addr_assign_type.Trr)rrr)r;r9)ifnamestrictZ assign_typerrrinterface_has_own_mac|s rTc Csi}x4tD]*\}}}}d|||j|t|d||<q W|rtjd}tjdddddd d gd d \}}tjdd ddgd d \} }t} x || fD]} | j|j| qWx,|j D] } | ddkp| d| k| d<qW|S)aCollect information necessary for rename_interfaces. returns a dictionary by mac address like: {name: { 'downable': None or boolean indicating that the device has only automatically assigned ip addrs. 'device_id': Device id value (if it has one) 'driver': Device driver (if it has one) 'mac': mac address (in lower case) 'name': name 'up': boolean: is_up(name) }} N)downablerrarrr<z[0-9]+:\s+(\w+)[@:]ipz-6ZaddrZshowZ permanentZscopeglobalT)capturez-4r<Frr) rrr@rcompiler setupdatefindallr}) Zcheck_downablecur_inforrrarZnmatchZipv6rZZipv4Znics_with_addressesZ bytes_outdrrr_get_current_rename_infos(   rcst|stjddS|dkr$t}ixF|jD]:\}}|j}|jdr\|dj|d<||d<||<q2Wtjdfdd}dd}d d } d d } g} g} g} |}d }d"}ddfdd}x|D]\}}}}|r|j}g}||||}|s"|r| jd||fq|jd}||kr8q|sV|r| jd||fq|drd}|ds|r| j||||fqd|d<|jd|||ff| jd|||ff||kr||}|drd}|ds|r| j||||fqn|jd|||ffd}x*|dks,||kr@|d7}||}qW|jd||||ff||d<|}|dr| jd|||ff|jd|||d|ff||d<|}| |7} qW|| | d}t| t| dkrt| rtjd|n tjd|n~tjd|| | xj| | D]^\}}}}y|j||Wn<t k rz}z| jd |||||fWYdd}~XnXq Wt| rt d!j | dS)#Nzno interfaces to renamerrzDetected interfaces %scstddjDS)Ncss|]}|d|fVqdS)rNr)rdatarrr sz<_rename_interfaces..update_byname..)rr})Zbymac)rrr update_bynamesz)_rename_interfaces..update_bynamecSstjddd|d|gdddS)NrlinkrrT)r)r )curnewrrrrenamesz"_rename_interfaces..renamecSstjddd|dgdddS)Nrrrr>T)r)r )rrrrr>sz _rename_interfaces..downcSstjddd|dgdddS)Nrrrr<T)r)r )rrrrr<sz_rename_interfaces..upz cirename%drcSsd|r0|r0|r0|d|ko.|d|ko.|d|kS|rP|rP|d|koN|d|kS|r`|d|kSdS)zmatch if set and in datarrarFr)rrrarrrr entry_matchs     z'_rename_interfaces..entry_matchcsTfddjD}t|rPt|dkrHd|f}t||dSdS)Ncsg|]}|r|qSrr)rr)rrarrrrrsz:_rename_interfaces..find_entry..rzjFailed to match a single device. Matched devices "%s" with search values "(mac:%s driver:%s device_id:%s)"r)r}rir9)rrarrr)rr)rrarr find_entrys  z&_rename_interfaces..find_entryz<[nic not present] Cannot rename mac=%s to %s, not available.r<z*[busy] Error renaming mac=%s from %s to %srFr>z2[busy-target] Error renaming mac=%s from %s to %s.r)rr>r<rz(unable to do any work for renaming of %sz$no work necessary for renaming of %sz$achieving renaming of %s with ops %sz.[unknown] Error performing %s%s for %s, %s: %s ) rir,r-ritemscopyrrrrcrrI)renamesZstrict_presentZ strict_busyZ current_inforrrrrr>r<ZopserrorsZupsZ cur_bynameZ tmpname_fmtZtmpirrnew_namerarZcur_opsZcur_namertargetZtmp_nameZopmapoprr3r)rrr_rename_interfacess                   * rcCs$d}tjjt|drd}t||S)z6Returns the string value of an interface's MAC AddressrZ bonding_slavezbonding_slave/perm_hwaddr)rBr"isdirr#r8)rr"rrrget_interface_mac]srcCs>t|ddkr:t|}|r6|r6|dd|dd}|SdS)zReturns the string value of an Infiniband interface's hardware address. If ethernet_format is True, an Ethernet MAC-style 6 byte representation of the address will be returned. rMrN$3Ni)r8r)rZethernet_formatrrrrget_ib_interface_hwaddrgs rcCs<tjstjrtStjr$tStjr2tStSdS)N) r ryrz get_interfaces_by_mac_on_freebsdrget_interfaces_by_mac_on_netbsdr get_interfaces_by_mac_on_openbsdget_interfaces_by_mac_on_linuxrrrrr|usr|)rrQcCs0x*tjD]\}}|j|jkr |Sq WdS)N)r|rr)rZ interface_macZinterface_namerrrfind_interface_name_from_macsrcCs>tjdddg\}}dd}dd}dd |||D}|S) Nrz-arcssDd}x4|jdD]&}|jdr(||7}q|r2|V|}qW|VdS)Nrr )rr)rYZ curr_blocklinerrrflattens  z1get_interfaces_by_mac_on_freebsd..flattencss8x2|D]*}tjd|}|r|jd|jdfVqWdS)Nz2^(?P\S*): .*ether\s(?P[\da-f:]{17}).*rr)rsearchgroup)Z flat_listblockmrrrfind_macs  z2get_interfaces_by_mac_on_freebsd..find_maccSsi|]\}}||qSrr)rrrrrr sz4get_interfaces_by_mac_on_freebsd..)r )rYrrrresultsrrrrs  rcCsfi}d}tjddg\}}tjdd|j}x4|D],}tj||}|r2|j}|d||d<q2W|S)NzE(?P\w+).*address:\s(?P([\da-f]{2}[:-]){5}([\da-f]{2})).*rz-az\n\s+ rr)r rsubrXr groupdict)rSre_field_matchrYrif_linesrrfieldsrrrrs  rcCsfi}d}tjddg\}}tjdd|j}x4|D],}tj||}|r2|j}|d||d<q2W|S)NzC(?P\w+).*lladdr\s(?P([\da-f]{2}[:-]){5}([\da-f]{2})).*rz-az\n\s+rrr)r rrrXrr)rSrrYrrrrrrrrrs  rcCsi}xtD]\}}}}||krX|dkr>tjd||||q d||||f}t||||<t|d}|r ||kr|||<q tjd||||q W|S) zmBuild a dictionary of tuples {mac: name}. Bridges and any devices that have a 'stolen' mac are excluded. fsl_enetc mscc_felixqmi_wwanz>Ignoring duplicate macs from '%s' and '%s' due to driver '%s'.z6duplicate mac found! both '%s' and '%s' have mac '%s'.Tz^Ethernet and InfiniBand interfaces have the same address both '%s' and '%s' have address '%s'.)rrr)rr,r-rrwarning)rSrrraZ_devidrib_macrrrrs4   r)filter_hyperv_vf_with_syntheticrrrrrrrQcCs0|r tjndd}g}t} djd } x| D]} |r@t|  r@q,t| rT|d| q,|rbt| rbq,t| rv|d| q,|rt| dk rt |  rt |  rq,t | r|d | q,t | } | s|d | q,|r| d kr| | dt | krq,|ot| rq,t| } |j| | | t| fq,W|r,t|||S)zReturn list of interface tuples (name, mac, driver, device_id) Bridges and any devices that have a 'stolen' mac are excluded.cWsdS)Nr)argsrrrsz get_interfaces..:00zIgnoring bridge interface: %szIgnoring bond interface: %sNzIgnoring failover interface: %sz"Ignoring interface without mac: %sr)r)rrrrrrrrrrrrrrrr)r,r-rrIrrDrurFrHrKrLrbrrir]r^rrx)filter_hyperv_vf_with_synthetic_interface)rrrrrrrfiltered_loggerrSrZzero_macrrrarrrr sJ             r.)r rrQcs\dd|Dfdd|D}x6|D].}|\}}}}|d|||||j|q&WdS)aFilter Hyper-V SR-IOV/VFs when used with synthetic hv_netvsc. Hyper-V's netvsc driver may register an SR-IOV/VF interface with a mac that matches the synthetic (hv_netvsc) interface. This VF will be enslaved to the synthetic interface, but cloud-init may be racing this process. The [perhaps-yet-to-be-enslaved] VF should never be directly configured, so we filter interfaces that duplicate any hv_netvsc mac address, as this the most reliable indicator that it is meant to be subordinate to the synthetic interface. VF drivers will be mlx4_core, mlx5_core, or mana. However, given that this list of drivers has changed over time and mana's dependency on hv_netvsc is expected to be removed in the future, we no longer rely on these names. Note that this will not affect mlx4/5 instances outside of Hyper-V, as it only affects environments where hv_netvsc is present. cSs&i|]}|ddkr|d|dqS)r hv_netvscrrr)rirrrrZsz=filter_hyperv_vf_with_synthetic_interface..cs(g|] }|dkr|ddkr|qS)rrr r)rr )hv_netvsc_mac_to_namerrr^sz=filter_hyperv_vf_with_synthetic_interface..zdIgnoring %r VF interface with driver %r due to synthetic hv_netvsc interface %r with mac address %r.N)r)r rZinterfaces_to_removerrrrarr)rrr Fs   r cCsTi}xJtD]@\}}}}t|d}|r ||krDtd||||f|||<q W|S)zTBuild a dictionary mapping Infiniband interface names to their hardware address.Fz5duplicate mac found! both '%s' and '%s' have mac '%s')rrr)rSrrrrrrget_ib_hwaddrs_by_interfaceps  r)url_datarQcCsd|krtjd|dS|d}y6t|}t|jdk|jdkgsTtjd|jdSWn,tk r}ztjd|dSd}~XnXd |krd |d <ytf|Wntk rdSXd S) aDReturn true when the instance has access to the provided URL. Logs a warning if url is not the expected format. url_data is a dictionary of kwargs to send to readurl. E.g.: has_url_connectivity({ "url": "http://example.invalid", "headers": {"some": "header"}, "timeout": 10 }) urlz4Ignoring connectivity check. No 'url' to check in %sFZhttpZhttpsz2Ignoring connectivity check. Invalid URL scheme %sz+Ignoring connectivity check. Invalid URL %sNZtimeoutT)r,rranyschemer9r r )rrresulterrrrrhas_url_connectivitys,  r)convert_to_addressrc Ks&y ||f|Stk r dSXdS)aUse a function to return an address. If conversion throws a ValueError exception return False. :param check_cb: Test function, must return a truthy value :param address: The string to test. :return: Address or False FN)r9)rrkwargsrrrmaybe_get_addresss  r)rrQcCstttj|S)zReturns a bool indicating if ``s`` is an IP address. :param address: The string to test. :return: A bool indicating if the string is an IP address or not. )rRr ipaddress ip_address)rrrr is_ip_addresss rcCstttj|S)zReturns a bool indicating if ``s`` is an IPv4 address. :param address: The string to test. :return: A bool indicating if the string is an IPv4 address or not. )rRrrZ IPv4Address)rrrris_ipv4_addresss rcCstttj|S)zReturns a bool indicating if ``s`` is an IPv6 address. :param address: The string to test. :return: A bool indicating if the string is an IPv4 address or not. )rRrrZ IPv6Address)rrrris_ipv6_addresss rcCstttj|ddS)zReturns a bool indicating if ``s`` is an IPv4 or IPv6 network. :param address: The string to test. :return: A bool indicating if the string is an IPv4 address or not. F)r)rRrr ip_network)rrrr is_ip_networks r!cCstttj|ddS)zReturns a bool indicating if ``s`` is an IPv4 network. :param address: The string to test. :return: A bool indicating if the string is an IPv4 address or not. F)r)rRrr IPv4Network)rrrris_ipv4_networks r#cCstttj|ddS)zReturns a bool indicating if ``s`` is an IPv6 network. :param address: The string to test. :return: A bool indicating if the string is an IPv4 address or not. F)r)rRrrZ IPv6Network)rrrris_ipv6_networks r$cCs@|djds|dtkrdS|ddkr "255.255.255.0" Also supports input as a string.z0.0.0.0/)rtrr"netmask)prefixrrrnet_prefix_to_ipv4_masksr+cCstjd|jS)aConvert an ipv4 netmask into a network prefix length. If the input is already an integer or a string representation of an integer, then int(mask) will be returned. "255.255.255.0" => 24 str(24) => 24 "24" => 24 z0.0.0.0/)rr  prefixlen)maskrrripv4_mask_to_net_prefixs r.c Csytjd|j}|Stk r*YnXtj|}t|}|dkrJ|Sttj||d@j}||?}tj|}d|>d}||krtd||S)zConvert an ipv6 netmask (very uncommon) or prefix (64) to prefix. If the input is already an integer or a string representation of an integer, then int(mask) will be returned. "ffff:ffff:ffff::" => 48 "48" => 48 z::/rrzInvalid network mask '%s') rr r,r9rrminZ IPV6LENGTH bit_length)r-r,r)Zmask_intZtrailing_zeroesZ leading_onesZall_onesrrripv6_mask_to_net_prefix)s"    r1)r-rrQcCsttj|d|ddjS)zCGet string representation of broadcast address from an ip/mask pairr F)r)rtrr"Zbroadcast_address)r-rrrrmask_and_ipv4_to_bcast_addrLsr2c@s eZdZdS)RendererNotFoundErrorN)rrrrrrrr3Ssr3)r)NNNN)N)N)N)N)N)N)F)T)TTN)TTTTTTF).N)hr$ functoolsrZloggingrBrZtypingrrrrrrZ urllib.parserZ cloudinitr r Zcloudinit.url_helperr r Z getLoggerrr,rrr'rUrrrr#r4r8r;r@rDrFrHrKrLrO lru_cacherRrTr{r\rtr]rbrerjrlr_r`rrrur^rxrrcrrrrrrrrrrrrrrrrrrr|rrrrrrr rrrrrrr!r#r$r(r+rr.r1r2rr3rrrrs                !       I 0  /   H5''      #