3 \me[@sddlZddlZddlZddlmZmZddlmZddlmZm Z ddl m Z ddl m Z ejeZggddd Zd d Ze jd d dddZddZddZd$ddZddZddZddZddZdd Zd%d"d#ZdS)&N)copydeepcopy) IPv4Network)subputil)net_prefix_to_ipv4_mask) SimpleTableF)ipv4ipv6hwaddrupc Cs\tj|}i}xF|D]<}d|kr,|dng}|jddkrF|dnd}|td|ko\d|kggd}x|jd gD]}|jd d krd |krttd |d jnd}|jdd||jdd|jddd} |dj| qv|d dkrv|jdd} | r$|jd r$| d|jd d} | |jddd} |dj| qvW|||d<qW|S)a&Get network device dicts from ip route and ip link info. ipaddr_json: Output string from 'ip --json addr' command. Returns a dict of device info keyed by network device name containing device configuration values. Raises json.JSONDecodeError if json could not be decoded flags link_typeetheraddressr UPLOWER_UP)r r r r Z addr_infoZfamilyinet prefixlenz0.0.0.0/Zlocal broadcastscope)ipmaskbcastrr inet6/@)rscope6r Zifname)jsonloadsgetboolstrrnetmaskappend) Z ipaddr_jsonZ ipaddr_datadevsdevrrZdev_infoaddrrZ parsed_addrrr)/usr/lib/python3.6/netinfo.py_netdev_info_iproute_json+s6      r+z22.1zqRequired by old iproute2 versions that don't support ip json output. Consider upgrading to a more recent version.)Zdeprecated_versionZ extra_messagec Csi}d}xt|jD]\}}tjd|}|r~|jdjjdd}|jdjd}ggdtd |kopd |kd ||<qd |krtjd |}|stj d||q||dj |j qd|krLtjd|}|stj d||q|j }|j d}|j d\} } } | sd} ||dj | |dr4|dndt| |ddqd|krtjd|}|svtj d||q|jddkr|jd||d<n d||d<qqqW|S)z @param ipaddr_out: Output string from 'ip addr show' command. @returns: A dict of device info keyed by network device name containing device configuration values. @raise: TypeError if ipaddr_out isn't a string. Nz.^\d+:\s(?P[^:]+):\s+<(?P\S+)>\s+.*r'@rr,r rr)r r r r rz?\s+inet6\s(?P\S+)(\s(peer\s\S+))?\sscope\s(?P\S+).*z*Could not parse ip addr show: (line:%d) %sr rzd\s+inet\s(?P\S+)(\smetric\s(?P\d+))?(\sbrd\s(?P\S+))?\sscope\s(?P\S+).*cidr4r32r rr)rrrrlinkz-\s+link/(?P\S+)\s(?P\S+).*rrr ) enumerate splitlinesrematchgrouplowersplitr"LOGwarningr% groupdictpop partitionr) ipaddr_outr&Zdev_nameZnumlinemrr4r.r(_prefixr)r)r*_netdev_info_iprouteasd        rBc Csi}xz|jD]l}t|dkr$q|ddkrf|jd}|jdrR|dd}||krftt||<|jjj}t|dkrtj d|drd||d<xt t|D]}||d kr||djd \}}||d j |t |d q||d kr ||d||d dd<q||dkrD||d||d<q||dkr||ddkr||dj d||din||dj d||diq||dkr||dddd ||d}|||ddd<q||j dr||jd||dd d<q||dkrtjd||d} | r^| jd||dd!d<q||d||dd"d<qWqW|S)#Nr  :zflags=[x\d]+Tr rrr )rrrrzaddress:r rzaddr:r rrzscope:rscopeidz .*<(\S+)>)rCrDrIrIrIrIrIrI)r2lenr7endswithrDEFAULT_NETDEV_INFOr6stripr3searchranger%r startswithlstripr4r5) ifconfig_datar&r>curdevtoksiZnetworkZnet_bitsaddr6resr)r)r*_netdev_info_ifconfig_netbsdsL            $  $rXcCs.i}x"|jD]}t|dkr$q|ddkrf|jd}|jdrR|dd}||krftt||<|jjj}|ddkrd||d<n(t|dkrtj d|drd||d<xjt t|D]X}||d kr||d j d ||dj d iq||j d r2||j d ||d d d<q||dkr^||d||d d!d<q||j dr||j d||d d"d<q||dkr||d||d d#d<q||dks||dkr||d||d<q||dkrL||dd kr,||dj d ||din||dj d ||diq||dkr||dd$d d||d}|||dd%d <q||j dr||j d||dd&d<q||dkrtjd||d}|r|jd||dd'd<q||d||dd(d<qWqW|S))NrrCrDrErFr Tz flags=\d+)rCrDrIrIrIrIrIrIrIrIrIrI)r2rJr7rKrrLr6rMr3rNrOr%rQrPr4r5)rRr&r>rSrTrUrVrWr)r)r*_netdev_info_ifconfigsZ              $  $rYc si}tjr0tjddgddgd\}}t|}ntjdry tjdddg\}}t|}Wqtjk rtjddd g\}}t|}YqXn8tjdrtjddgddgd\}}t|}n t j d |d kr|St t t fdfd d ||d|S)NZifconfigz-arrF)rcsrz--jsonr(Zshowz>Could not print networks: missing 'ip' and 'ifconfig' commandsr cspt|tr|j}n t|ttfr,t|}ntdx6|D].\}}||krT|||<q:t|r:||q:WdS)zQRecursively replace 'empty_vals' in data (dict, tuple, list) with new_valzUnexpected input to fillN) isinstancedictitemstuplelistr1 TypeError)datanew_valZ empty_valsZmyiterkeyval)fill recurse_typesr)r*rf9s     znetdev_info..fill)rcr r[)r rh)rZ is_NetBSDrrXwhichr+ProcessExecutionErrorrBrYr8r9r]r_r`)emptyr&Z ifcfg_out_errr=r))rfrgr* netdev_infos,       rmcCsi}g|d<g|d<|j}ddddddd}x<|D]2}t|}|sJq6|j}dg}|ddkrvd|d <d|d <n^d |dkr|djd \}} n"|d}d } |jd t| |d <||d <t| |d <d|d<xxtt|D]h} || dkr|| d|d<|jdd|| dkr.|| d|d<|| dkr|| d|d<qWdj||d<|dj|q6Wy(t j dddddddgddgd\} } Wnt j k rYnX| j} x| D]}i}|s֐q|j}|ddkrd|d <d|d<n|d|d <d |d<d|d<xtt|D]} || dkrR|| d|d<d|d<|| dkrp|| d|d<|| dkr|| d|d<|| d!kr(|dd"|d<q(W|dj|qW|S)#aP Get network route dicts from ip route info. @param iproute_data: Output string from ip route command. @returns: A dict containing ipv4 and ipv6 route entries as lists. Each item in the list is a route dictionary representing destination, gateway, flags, genmask and interface information. r r r ) destinationrgatewaygenmaskifacemetricUrdefaultz0.0.0.0rnrprr/HroZviarFGr'rqrrrrz --onelinez-6router`tableall)rZz::/0ZUGz::Zexpirese) r2rr7r%rrOrJinsertjoinrrj)Z iproute_dataroutesentriesZdefault_route_entryr>entryrTrr(ZcidrrUZ iproute_data6_err6entries6r)r)r*_netdev_route_info_iprouteMs           rc Cs4i}g|d<g|d<|j}x|D]}|s,q"|j}t|dks"|ddks"|ddks"|ddks"|ddks"|dd kr~q"t|d kr|jd |jd |d |d <d |d <|d|d|d|d|d|d |d|d d}|dj|q"Wy$tjdddddgddgd\}}Wntjk r6YnX|j}x|D]}|sTqF|j}t|d ksF|ddksF|ddksF|ddksF|ddksF|ddkrqF|d|d|d|d|d|d |dd}|ddkrqF|djdrtjd d!|d|d<|dj|qFW|S)"Nr r rZKernel DestinationZInternetZ Internet6ZRouting-rFrG)rnrorprrrrefuserqnetstatz-Arz--routez --numeric)rZZProtoZActive)rnrorrrrrrqrqlornz/128z\/128$r ) r2r7rJr%rrjrKr3sub) Z route_datar}r~r>rTrZ route_data6rrr)r)r*_netdev_route_info_netstatsx               rcCsni}tjdr.tjddddg\}}t|}nZ route_linesr)r)r* debug_infos      r)r )r)rZloggingr3rrZ ipaddressrZ cloudinitrrZcloudinit.net.network_staterZcloudinit.simpletablerZ getLogger__name__r8rLr+Zdeprecate_callrBrXrYrmrrrrrrr)r)r)r* s,    6Q09 0XU4I