
    gqP                         d Z ddlZddlZddlZddlZddlmZ 	 ddlZdZddl	m
Z
 ddlZddlmZ  G d	 d
ej                        Zy# e$ r dZY /w xY w)znetplan migrate command line    N)globFT)OrderedDict   )utilsc                   J     e Zd Z fdZd Zd Zd Zd Zd Zd Z	d	dZ
 xZS )
NetplanMigratec                 ,    t         |   dddd       y )Nmigratez/Migration of /etc/network/interfaces to netplanT)
command_iddescriptionleaftesting)super__init__)self	__class__s    6/usr/share/netplan/netplan_cli/cli/commands/migrate.pyr   zNetplanMigrate.__init__%   s     I%V"!% 	 	'    c                 6   d|v rHd|vri |d<   d|d   vrg |d   d<   |d   j                  d      D ]  }|s|d   dxx   |gz  cc<    |d= d|v rId|vri |d<   d|d   vrg |d   d<   |d   j                  d      D ]  }|s|d   dxx   |gz  cc<    |d= yy)zParse dns options (dns-nameservers and dns-search) from if_options
        (an interface options dict) into the interface configuration if_config
        Mutates the arguments in place.
        zdns-nameserversnameservers	addresses z
dns-searchsearchN)split)r   
if_options	if_confignsdomains        r   parse_dns_optionsz NetplanMigrate.parse_dns_options+   s   
 
*I-+-	-()M"::8:	-(5 !2399#> >-(5"=5> ,-:%I-+-	-(y7757	-(2$\288= ?-(2vh>2	?
 <( &r   c                 0   d|v rT	 t        |d         }d|v r8|d   k(  s0t        j                  d|||d          t	        j
                  d       |d<   |d= yy# t        $ r2 t        j                  d||d          t	        j
                  d       Y w xY w)zParse out the MTU. Operates the same way as parse_dns_options
        iface is the name of the interface, used only to print error messages
        mtuz%s: cannot parse "%s" as an MTUr   z0%s: tried to set MTU=%d, but already have MTU=%dN)int
ValueErrorloggingerrorsysexit)r   ifacer   r   r!   s        r   	parse_mtuzNetplanMigrate.parse_mtuH   s    
 J*U+,
 	!)E*:c*APRWY\^ghm^no"Ie5!   ?
SXHYZs   A 8BBc                     d|v rNd|v r>|d   |d   k(  s3t        j                  d||d   |d          t        j                  d       |d   |d<   |d= yy)zParse out the manually configured MAC.
        Operates the same way as parse_dns_options
        iface is the name of the interface, used only to print error messages
        	hwaddress
macaddressz0%s: tried to set MAC %s, but already have MAC %sr   N)r$   r%   r&   r'   )r   r(   r   r   s       r   parse_hwaddresszNetplanMigrate.parse_hwaddress[   so     *$y(<1HJWbLc1cPRW(5y7NP&0&=Il#;' %r   c                 <   | j                   j                  dd       | j                   j                  ddd       | j                  | _        | j	                          t
        r*t        j                  d       t        j                  d	       | j                          y )
Nz
--root-dirzOSearch for and generate configuration files in this root directory instead of /)helpz	--dry-run
store_truezQPrint converted netplan configuration to stdout instead of writing/changing files)actionr/   zThe `yaml` Python package couldn't be imported, and is needed for the migrate command.
To install it on Debian or Ubuntu-based system, run `apt install python3-yaml`   )parseradd_argumentcommand_migratefunc
parse_argsNO_YAMLr$   r%   r&   r'   run_command)r   s    r   runzNetplanMigrate.runj   s      &w 	! 	y  \&y 	! 	{((	MM R SHHQKr   c           
         i }	 | j                  | j                  xs d      \  }}j                         D ]t  \  }}|j                         D ]Z  \  }}t        j                  d|||       |vr+t        j                  d|       t        j                  d       |d   dk(  rt        j                  d|       m|d   dk(  r|j                  d	i       j                  d
i       j                  |i       }	| j                  |d   |	       | j                  ||d   |	       |d   rLt        j                  d|dj                  |d   j                                      t        j                  d       |dk(  rd|	d<   /|dk(  sJ d|	d<   =|d   dk(  rd|v r|j                  d      d   }|j                  d	i       j                  d
i       j                  |i       }	d|	vrg |	d<   | j                  |d   |	       | j!                  ||d   |	       | j                  ||d   |	       |dk(  rt#        g d      }
t#        g d      }t#        |d   j                               }||
z
  }|rz|j%                  |      D ]/  }t        j                  d|||       t        j                  d       1 ||z
  D ]/  }t        j                  d|||       t        j                  d       1 d|d   vr+t        j                  d|       t        j                  d       d|d   d   v r#|d   d   j                  d      d   }|d   d   }nNd|d   vr+t        j                  d|       t        j                  d       |d   d   }|d   d   dz   |d   d   z   }	 t'        j(                  |      }	 t'        j,                  |d!"      }|	dxx   t              dz   t        j0                        z   gz  cc<   d$|d   v s|d   d$   |	d%<   |dk(  sJ t#        g d&      }
t#        g d'      }t#        |d   j                               }||
z
  }|rz|j%                  |      D ]/  }t        j                  d|||       t        j                  d       1 ||z
  D ]/  }t        j                  d|||       t        j                  d       1 d|d   vr+t        j                  d|       t        j                  d       d|d   d   v r#|d   d   j                  d      d   }|d   d   }nNd|d   vr+t        j                  d|       t        j                  d       |d   d   }|d   d   dz   |d   d   z   }	 t'        j2                  |      }	 t'        j4                  |d!"      }|	dxx   t              dz   t        j0                        z   gz  cc<   d$|d   v r|d   d$   |	d*<   d+|d   v s|d   d+   d,k(  rd!|	d+<   |d   d+   d-k(  rd|	d+<   |d   d+   d.k(  r-t        j                  d/|       t        j                  d       t        j                  d0||d   d+          t        j                  d       ,t        j                  d1||d          t        j                  d       ] w t6        j8                  j                  | j                  xs dd2      }|rd|d	   d3<   t;        j<                  |      }| j>                  rtA        |       nt6        j8                  j                  | j                  xs dd4      }	 t7        jB                  t6        j8                  jE                  |             	 tI        |d5      5 }|jK                  |       d d d        t        jL                  d8|       nt        jL                  d9       | j>                  s1t        jL                  d:||       t7        jN                  ||d;z          y y # t        $ r>}t        j                  t        |             t        j                  d       Y d }~!d }~ww xY w# t&        j*                  $ r8}t        j                  d |||       t        j                  d       Y d }~d }~ww xY w# t&        j.                  $ r8}t        j                  d#|||       t        j                  d       Y d }~$d }~ww xY w# t&        j*                  $ r8}t        j                  d(|||       t        j                  d       Y d }~d }~ww xY w# t&        j.                  $ r8}t        j                  d)|||       t        j                  d       Y d }~d }~ww xY w# tF        $ r Y w xY w# 1 sw Y   xY w# tF        $ r/ t        j                  d6|       t        j                  d7       Y @w xY w)<N r   zConverting %s family %s %sz.%s: non-automatic interfaces are not supportedmethodloopbackzIgnoring loopback interface %sdhcpnetwork	ethernetsoptionsz2%s: option(s) %s are not supported for dhcp methodz, inetTdhcp4inet6dhcp6static:r   r   )addressnetmaskgateway)	broadcastmetricpointopointscopez%s: unsupported %s option "%s"z%s: unknown %s option "%s"rI   z(%s: no address supplied in static method/rJ   zE%s: address does not specify prefix length, and netmask not specifiedz-%s: error parsing "%s" as an IPv4 address: %sF)strictz-%s: error parsing "%s" as an IPv4 network: %srK   gateway4)rI   rJ   rK   	accept_ra)rM   mediaautoconfprivextrO   zpreferred-lifetimezdad-attemptszdad-intervalz-%s: error parsing "%s" as an IPv6 address: %sz-%s: error parsing "%s" as an IPv6 network: %sgateway6rS   012z(%s: netplan does not support accept_ra=2z#%s: unexpected accept_ra value "%s"z%s: method %s is not supportedzetc/network/interfacesversionzetc/netplan/10-ifupdown.yamlxzC%s already exists; remove it if you want to run the migration again   zmigration complete, wrote %sz>ifupdown does not configure any interfaces, nothing to migratez#renaming %s to %s.netplan-convertedz.netplan-converted)(parse_ifupdownroot_dirr#   r$   r%   strr&   r'   itemsdebug
setdefaultr   r-   joinkeysr   r)   setintersection	ipaddressIPv4AddressAddressValueErrorIPv4NetworkNetmaskValueError	prefixlenIPv6AddressIPv6Networkospathyamldumpdry_runprintmakedirsdirnameFileExistsErroropenwriteinforename)r   netplan_configifacesauto_ifaceser(   family_configfamilyconfigcsupported_optsunsupported_optsoptsbad_optsunsupportedunknown	addr_specnet_specipaddraipnetr   netplan_yamldestfs                            r   r5   zNetplanMigrate.command_migratex   sT	   	"&"5"5dmm6Ir"JFK %+LLN j	  E="/"5"5"7 i :E66R+MM"RTYZHHQK(#z1MM"BEJH%/&11)R@KKKY[\gghmoqrA**6)+<a@((y0A1Ei(&Z&+TYYvi7H7M7M7O-PR'%)'
%000%)'
H%1u %C 0 3&11)R@KKKY[\gghmoqrA"!+)++**6)+<a@NN5&*;Q?((y0A1E '
 *--N)O+./^+_("6)#4#9#9#;<#'.#8#/7/D/DEU/V , '.NPUW]_j k #, ,46F+F , '.JESY[b c #, %F9,==#MM*TV[\HHQK&"3I">>(.y(9)(D(J(J3(OPQ(RI'-i'8'CH(y0AA '.u.3!5 #(.y(9)(DI'-i'8'Cc'IFS\L]^gLh'hH(%.%:%:9%EF
($-$9$9(5$QE
 +3v;+<s5???S+S*TT$y(99,29,=i,HAjM  &000 *--[)\+. 0o ,p(  #6)#4#9#9#;<#'.#8#/7/D/DEU/V , '.NPUW]_j k #, ,46F+F , '.JESY[b c #, %F9,==#MM*TV[\HHQK&"3I">>(.y(9)(D(J(J3(OPQ(RI'-i'8'CH(y0AA '.u.3!5 #(.y(9)(DI'-i'8'Cc'IFS\L]^gLh'hH(%.%:%:9%EF
($-$9$9(5$QE
 +3v;+<s5???S+S*TT$y(99,29,=i,HAjM&&*;;%i0=D16+!'	!2;!?3!F15+!'	!2;!?3!F '.XZ_ ` # '.SUZ.4Y.?.L!N # MM"BE6RZK[\HHQKSi j	 X GGLL!5#7OP	34N9%i099^4L||l#ww||DMM$8S:XYKK 56 dC .A-.
 ;TBLLYZ||LL>	9UIIi-A!AB M  	MM#a&!HHQKK	b  ):: (#MM*Y[`bkmnoHHQKK(  ):: (#MM*Y[`bjlmnHHQKK(l  ):: (#MM*Y[`bkmnoHHQKK(  ):: (#MM*Y[`bjlmnHHQKK(N ' . .&  MM"gimnHHQK s   "` a(b1c+d92f 5f$ ff$ 	a3aab"-bbc(0-c##c(+d6>-d11d69f-e??f	fff!f$ $4ggc                    d }g }t        |      dz   }	 t        |dz   |z         5 }t        j                  d|j                         |D ]\  }|j                         }|r|j                  d      r(|j                  d      rt        j                  d      } ||t        j                  j                  |j                        |      }	t        j                  |	      D ]J  }|j                  |      s|| j                  |t        j                  j                  |	|d |            z  }L |j                  d	      rYt!         ||t        j                  j                  |j                        |            D ]  }|| j                  |||d       z  } L|j#                  |       _ 	 ddd       |S # 1 sw Y   |S xY w# t$        $ r t        j                  d
||       Y |S w xY w)zvReturn normalized lines from ifupdown config

        This resolves "source" and "source-directory" includes.
        c                 d    |j                         d   }|j                  d      r| |z   S |dz   |z   S )Nr2   rP   )r   
startswith)rootdircurdirlineargs       r   expand_source_argzCNetplanMigrate._ifupdown_lines_from_file.<locals>.expand_source_argK  s6    **,q/C~~c"}$|c))r   r2   rP   z
reading %s#zsource-directory z^[a-zA-Z0-9_-]+$Nzsource z%s/%s does not exist, ignoring)lenry   r$   rb   namestripr   recompilerp   rq   rw   listdirmatch_ifupdown_lines_from_filerd   r   appendFileNotFoundError)
r   r   rq   r   linesrootdir_lenr   r   valid_reds
             r   r   z(NetplanMigrate._ifupdown_lines_from_fileF  s   
	* 'lQ&	Kgmd*+ +qlAFF3 +D::<D4??3#7 ':;#%::.@#A-grwwqvv7NPTU!#A sA'~~a0 %)G)GQSQXQXQ]Q]^_`k`l^mopQq)r rs 3!%&7QRQWQWAXZ^&_!` ^A!T%C%CGQ{|_%]]E^ T*!++* ++*  ! 	KMM:GTJ	Ks6   G CF42B7F4*G 4F>9G >G  G%$G%c           	         ddddddd}| j                  |d      }t               }t               }d}d}|D ]  }|j                         }		 ||	d      }
t	        j
                  d|	|
       d}d}t        |	      |
dz   k7  r t        d|
|	d   t        |	      dz
  fz        |	d   dv r|j                  |	d          |	d   dk(  rt        d      |	d   dk(  r|	d   dk(  rb|	d   dvrt        d|	d   z        |	d   dvrt        d|	d   z        |	d   }|	d   }|	d   i d|j                  |	d   t                     |<   t        d|	d   z         t	        j
                  d||       ||fS # t        $ rR |r>t	        j
                  d||       |j                  d	      d   ||   |   d
   |	d   <   Y t        d|	d   z        w xY w)uW  Parse ifupdown configuration.

        Return (iface_name →  family → {method, options}, auto_ifaces: set) tuple
        on successful parsing, or a ValueError when encountering an invalid file or
        ifupdown features which are not supported (such as "mapping").

        options is itself a dictionary option_name → value.
        r2   r]   )auto
allow-autoallow-hotplugmapping
no-scriptsr(   z/etc/network/interfacesNr   z$line fields %s (expected length: %i)z$in_options %s, parsing as option: %s)maxsplitrB   zUnknown stanza type %sz0Expected %i fields for stanza type %s but got %i)r   r   r   r   zmapping stanza is not supportedr   r(   r   )rC   rE   zUnknown address family %s)r>   rG   r?   zUnsupported method %s)r=   rB   z!stanza type %s is not implementedz,final parsed interfaces: %s; auto ifaces: %s)r   r   rf   r   r$   rb   KeyErrorr#   r   addrc   NotImplementedError)r   r   fieldlenr   r~   r   
in_options	in_familyr   fieldsexp_lens              r   r^   zNetplanMigrate.parse_ifupdownl  sJ    Qq`almn ..w8QRu
	  '	[DZZ\FK"6!9-DfgV!
 	 6{gk) !S")6!9c&kAo!F"G H H ayCC#i' !BCCl*g%!9$55$%@6!9%LMM!9$BB$%<vay%HII#AY
"1I	TZ[\T]jlIm!!&)[];IF)*MPVWXPY*YZZO'	[R 	DfdS~C  KMM"H*VZ[JN**^_*J`abJcF:&y1)<VAYG$%=q	%IJJKs   #E..AG	7G	)rP   )__name__
__module____qualname__r   r   r)   r-   r:   r5   r   r^   __classcell__)r   s   @r   r   r   $   s/    '):"&(LC\$L?r   r   )__doc__r$   rp   r&   r   r   rr   r8   ImportErrorcollectionsr   rh   r<   r   NetplanCommandr    r   r   <module>r      s[   $ #  	 
 	 G $  GU)) G  Gs   A AA