
    fK                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZmZmZ d dlmZmZmZmZmZ d dlmZmZ dZdZ ej2                  e      Zd Zdd	ed
efdZd ZddZ  G d dejB                        Z!ddZ"y)    N)Optionalcast)featuressafeyamlsubputil)IPV6_DYNAMIC_TYPESSYS_CLASS_NETget_devicelistrenderersubnet_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
c                 H    t        fd| j                         D              S )Nc              3   N   K   | ]  \  }}|j                        r||f  y wN)
startswith).0keyvaluematchs      7/usr/lib/python3/dist-packages/cloudinit/net/netplan.py	<genexpr>z,_get_params_dict_by_match.<locals>.<genexpr>+   s-      S%>>%  
es   "%)dictitems)configr   s    `r   _get_params_dict_by_matchr   *   s#     "LLN      r   entryc           	      x   d%d}|g }g }g }g }g }| j                  dg       }	|	g }	|	D ],  }
|
j                  d      }|j                  d      r|dk(  r|dz  }|j                  |di       D|t        v r|j                  ddi       `|d	v sed
|
j                  d      z  }d|
v r|d|
j                  d      z  z  }|
j                  d      rx|
j                  d      dd}	 t	        j
                  |
d         }t	        j                  |d      }||vrt        j                  d|
d   |       d|d<   |j                  |       d|
v r| ||
j                  dg             z  }d|
v r| ||
j                  dg             z  }d|
v r5d}t        |
      rd|v rd}|j                  ||
j                  d      i       |
j                  dg       D ]s  }|j                  d      d|j                  d      }|j                  d      |d}d|v r#|j                  d|j                  dd      i       |j                  |       u |j                  |       / d| v r?|j                  d      }|r$| d   |k7  rt        j                  d|| d   |       n| d   |d<   t        |      d kD  r|j                  d!|i       t        |      d kD  r|j                  d|i       t        |      d kD  rd!|i}|j                  d"|i       t        |      d kD  r8|j                  d"i       }|j                  d#|i       |j                  d"|i       d$| v r<| d$   6|j                  d$t        j                  | j                  d$            i       yyy# t        $ r&}t        j                  d|
d   ||       Y d}~d}~ww xY w)&a  This 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}

    c                 Z    | rt        | t              s| S || v r| j                  |      S | gS )zT
        Helper to convert strings to list of strings, handle single string
        )
isinstancestrsplit)objtokens     r   _listifyz$_extract_addresses.<locals>._listifyW   s:     *S#.JC<99U##  r   Nsubnetstypedhcp4Tdhcp6)staticstatic6z%saddressprefixz/%dgatewaydefault)viatoF)strictzAGateway %s is not contained within subnet %s, adding on-link flagzon-linkzDFailed to check whether gateway %s is contained within subnet %s: %sdns_nameservers
dns_searchmtuzipv6-mturoutesnetwork/metricd   zZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r   	addressesnameserverssearchz	accept-ra) )getr   updater	   	ipaddress
ip_address
ip_networkLOGdebug
ValueErrorwarningappendr   lenr   is_true)r   r   ifnamer   r'   r>   r9   r?   searchdomainsr(   subnetsn_typeaddr	new_routesubnet_gatewaysubnet_networkemtukeyrouteto_net	entry_mtunss                         r   _extract_addressesr\   2   s   J IFKMjjB'G ;#**V$f%& 3LL'4)**LL'4)--&**Y//D6!

8 444zz)$!::i0#	%.%9%9&:K%LN%.%9%9$u%MN &^;		3"9- 	 04	), i( F*x

3Db(IJJv%&**\2*F!GG!&)jH.D'Fffjj&789Hb1 )$)IIi$8%))H:MN 99Y/ 	 u$$$h		(C0H%IJi() T"w;#z IIe$	)3KK6u "%=E%L
9~k9-.
6{Qh'(
;!;'mR()
=AYY}b)
		8]+,mR()f!4!@k4<<

;0G#HIJ "Ak " KK=y) s   #AN

	N9N44N9c           
          t        | j                         D cg c]  \  }}|j                  dd       |k(  r| c}}      }t        |      dkD  r|j	                  d|i       y y c c}}w )Nzbond-masterr   
interfaces)sortedr   rB   rL   rC   )r^   r   bond_masternamecfgbond_slave_namess         r   _extract_bond_slaves_by_namerd      sq      *//1	
sww}d+{: 	
 q l$456 !	
s   !A%
c                    t        j                  | d      }t        j                  j	                  |      sy t        j                  |      }|t        k7  ry dD cg c]  }t        j                  | |       }}|D cg c]$  }t        j                  j	                  |      s#|& }}t        j                  d||       |g|z   D ]  }t        j                  |        y c c}w c c}w )Nz etc/netplan/00-snapd-config.yaml)z-run/systemd/network/10-netplan-all-en.networkz.run/systemd/network/10-netplan-all-eth.networkz#run/systemd/generator/netplan.stampz9removing known config '%s' and derived existing files: %s)r   target_pathospathisfiler   load_binary_fileKNOWN_SNAPD_CONFIGrG   rH   unlink)targettpathcontentfderivedexistings         r   _clean_defaultrs      s     V%GHE77>>% ##E*G$$
 	#G  #8abggnnQ&78H8IIC Wx 
		! 9s   C =$C%"C%c                       e Zd ZdZddgZddgZddZed        Z	 	 dde	d	e
e   d
dfdZddedefdZddZde	d
efdZy)RendererzBRenders network information in a /etc/netplan/network.yaml format.netplangenerateinfoNc                     |si }|j                  dt              | _        |j                  dd       | _        |j                  dd      | _        |j                  dd      | _        |j                  dd       | _        y )Nnetplan_pathnetplan_headerpostcmdsFclean_defaultTr   )rB   CLOUDINIT_NETPLAN_FILErz   r{   	_postcmdsr}   	_features)selfr   s     r   __init__zRenderer.__init__   si    F"JJ~7MN$jj)94@J6#ZZ>J5r   c                    | j                   S	 t        j                  | j                  d      \  }}t        j                  |      }|d   d   | _         | j                   S | j                   S # t        j
                  $ r Y | j                   S t        t        f$ r+}t        j                  d|       Y d }~| j                   S d }~ww xY w)NTcapturez
netplan.ior   z-Failed to list features from netplan info: %s)
r   r   NETPLAN_INFOr   	load_yamlProcessExecutionError	TypeErrorKeyErrorrG   rH   )r   	info_blob_errrx   rV   s        r   r   zRenderer.features   s    >>!	N"&))D,=,=t"L	4~~i0!%l!3J!? ~~t~~ --   ~~ x( N		I1MM~~Ns   AA, ,CCC  Cnetwork_state	templatesreturnc                    t         j                  j                  t        j                  |      | j
                        }t        j                  t         j                  j                  |             | j                  |      }| j                  r| j                  nd}|j                  d      s|dz  }||z   }d}t         j                  j                  |      rgt        j                  t        j                  |j!                                     }t#        |d      5 }	t        j                  |	      }
d d d        |
k(  rd}t$        j&                  rdnd}|s>t         j                  j                  |      rt        j(                  |      }||z  |k(  r|}t        j*                  |||       | j,                  rt/        |	       | j1                  | j2                  |
       | j5                  | j2                         y # 1 sw Y   xY w)N 
FrbTi  i  )mode)rm   )runsame_content)r   )rg   rh   joinr   rf   rz   r   
ensure_dirdirname_render_contentr{   endswithexistshash_bufferioBytesIOencodeopenr   NETPLAN_CONFIG_ROOT_READ_ONLYget_permissions
write_filer}   rs   _netplan_generater   _net_setup_link)r   r   r   rm   fpnplanro   headerr   hashed_contentrp   hashed_original_contentr   current_modes                r   render_network_statezRenderer.render_network_state  s    '',,t//79J9JK01 &&}5 )-(;(;$$t$dNF7" 77>>'"!--bjj9I.JKNgt$ >*.*:*:1*='>!88# >>uEw 7//8Ld"l2#t4&)4>>M0!> >s   G<<Hr   r   c                     |st         j                  d       y |rt         j                  d       y t        j                  | j                  d       y )Nz!netplan generate postcmd disabledzEskipping call to `netplan generate`. reason: identical netplan configTr   )rG   rH   r   NETPLAN_GENERATE)r   r   r   s      r   r   zRenderer._netplan_generate8  sB    II9:II4 		$''6r   c                 v   |st         j                  d       yg d}t        }t        d      D ]\  }	 t	               D ]K  }t
        j                  j                  t        |z         s*t        j                  |t        |z   gz   d       M  y t        d      |# t        j                  $ r}|}Y d}~d}~ww xY w)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 disabledN)udevadmztest-builtinnet_setup_link   Tr   zQ'udevadm test-builtin net_setup_link' unable to run successfully for all devices.)rG   rH   	Exceptionranger   rg   rh   islinkr
   r   r   RuntimeError)r   r   	setup_lnklast_exception_ifacerV   s          r   r   zRenderer._net_setup_linkD  s    
 II?@A	 #q 	"A#+- Eww~~me&;<		%)>(??
 	" 0 "" -- #!"#s   3B&$BB8,B33B8c           	       
   |j                   dk(  r9t        j                  d       t        j                  d|j
                  idd      S i }i }i }i }i }g }|j                  j                  dg       }|j                  }	|j                  }
|j                         D ]  }|j                  d      }t        t        d |j                                     }|j                  d	      }|d
k(  rv||j                  dd       d}|d   0|j                  dd       }|d|j                         i|d<   n|d= |d= t        |||| j                          |j#                  ||i       |dk(  r!i }i }t%        t        t'        j                  d            }dD ]]  }t)        ||      }|j                         D ]<  \  }}|j                  |j+                  dd            }|*|j#                  ||i       > _ t-        |      dkD  r|j#                  d|i       |j                  d      r|d   j                         |d<   |j                  d      }|dk(  rt/        |||       t        |||| j                          |j#                  ||i       |dk(  r\|j                  d      }t1        t3        j2                  |            }d|i}d}t)        ||      }i }t%        t        t'        j                  d            } |j                         D ]n  \  }}| j                  |      }||j#                  ||i       |dv s2i }!|D ]#  }"|"j5                         \  }#}$t7        |$      |!|#<   % |j#                  ||!i       p t-        |      dkD  r|j#                  d|i       |j                  d      r|d   j                         |d<   t        |||| j                          |j#                  ||i       N|dk(  sU|j                  d      |j                  d      d}%|j                  dd       }||j                         |%d<   t        ||%|| j                          |j#                  ||%i        |	s|
rE|	|
d }&|||||fD ]6  }'|'j                         D ]!  \  }(})d!|)v sd"|)vr|)j#                  d!|&i       # 8 d# }*|j9                  d$       | |*d%|      z  }| |*d&|      z  }| |*d'|      z  }| |*d(|      z  }| |*d)|      z  }d*j;                  |      S )+N   zV2 to V2 passthroughr:   F)explicit_startexplicit_endr^   ra   c                     | d   d uS )N    )its    r   <lambda>z*Renderer._render_content.<locals>.<lambda>}  s    2a5+< r   r)   physicalr   )set-namer   mac_address
macaddressr   bond)bond_zbond-r   -r   
parameterszbond-slavesnonebridgebridge_portsbridge_)z	path-costzport-priorityvlanvlan_idzvlan-raw-device)idlink)r>   r@   r?   r>   c                 r    |r4t        j                  | |iddd      }t        j                  |d      }|gS g S )NFT)r   r   noaliasz    )r   dumpstextwrapindent)ra   sectiondumptxts       r   _render_sectionz1Renderer._render_content.<locals>._render_section  sA    ~~7O#(!& 	 oodG4uIr   znetwork:
    version: 2
	ethernetswifisbondsbridgesvlansr   )versionrG   rH   r   r   r   _network_staterB   r6   dns_searchdomainsiter_interfacesr   filterr   lowerr\   r   rC   r   r   r   replacerL   rd   r_   copyr$   intrK   r   )+r   r   r   r   r   r   r   ro   r^   r?   rO   r   rN   ifcfgif_typeethmacaddrr   bond_configv2_bond_mapr   bond_paramsparamr   newnameslave_interfacesr   portsr   match_prefixparams	br_configv2_bridge_mapnewvaluevalportportvalr   nscfgr   _namerb   r   s+                                              r   r   zRenderer._render_contentc  sB      A%II,->>M001$"  	"1155lBG
#33%77#335 d	-FZZ'F <fllnMNEii'G*$ !'"YYw5 w<'#iit<G*(4gmmo'FGL
O"5#vt}}E  &#/F"  #4)9)=)=f)EF 0 =E";E5"IK*5*;*;*= ="-//%--S2I"J"?$#**GU+;<	== {#a'KK{ ;<99]+).})=)C)C)ED&#(99]#; #v-0T6J"5$Ffd^,H$$yy8tyy67 % 
  )25,G	 !%T+;+?+?+I J '-lln >NUE+//6G $$gu%56"@@#%#( :C.1iikOT7-0\HTN: "(('8)<=> y>A%MM<";<99]++0+?+E+E+GF<("5&&$--H/0F"  ))I.!II&78  ))M48&)0D&"5$Ffd^,Id	-P -"-GE%ueWeD 7")--/ 7JE3$+{#/E JJu5677
	 	34?;	::?7E22?7E22?9g66?7E22wwwr   r   )NN)FF)F)__name__
__module____qualname____doc__r   r   r   propertyr   r   r   r   r   boolr   r   r#   r   r   r   r   ru   ru      s    L!:.v&L6  " %)	*1#*1 D>*1
 
*1X
7T 
7 
7">[ \ [ c [ r   ru   c                 T    dg}ddg}|D ]  }t        j                  |||       r y y)Nrv   z	/usr/sbinz/sbin)r@   rm   FT)r   which)rm   expectedr@   ps       r   	availabler
    s:    {H7#F zz!F6: r   r   )#r   r   rD   loggingrg   r   typingr   r   	cloudinitr   r   r   r   cloudinit.netr	   r
   r   r   r   cloudinit.net.network_stater   r   r~   rk   	getLoggerr   rG   r   r   r\   rd   rs   ru   r
  r   r   r   <module>r     s     	   	  ! 4 4  G:    g!PKt PKD PKf	7:P x   P fr   