2013-09-21 04:40:07 +04:00
#
# Copyright 2013 Red Hat, Inc.
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2013-09-21 04:40:07 +04:00
"""
Classes for building and installing libvirt < network > XML
"""
2013-09-30 23:06:52 +04:00
import logging
2013-09-21 04:40:07 +04:00
import libvirt
2019-06-08 01:16:53 +03:00
from . import generatename
2014-09-12 23:59:22 +04:00
from . xmlbuilder import XMLBuilder , XMLChildProperty , XMLProperty
2013-09-21 04:40:07 +04:00
class _NetworkDHCPRange ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " range "
2013-09-21 04:40:07 +04:00
start = XMLProperty ( " ./@start " )
end = XMLProperty ( " ./@end " )
class _NetworkDHCPHost ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " host "
2013-09-21 04:40:07 +04:00
macaddr = XMLProperty ( " ./@mac " )
name = XMLProperty ( " ./@name " )
ip = XMLProperty ( " ./@ip " )
class _NetworkIP ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " ip "
2013-09-21 04:40:07 +04:00
family = XMLProperty ( " ./@family " )
address = XMLProperty ( " ./@address " )
prefix = XMLProperty ( " ./@prefix " , is_int = True )
netmask = XMLProperty ( " ./@netmask " )
tftp = XMLProperty ( " ./tftp/@root " )
bootp_file = XMLProperty ( " ./dhcp/bootp/@file " )
bootp_server = XMLProperty ( " ./dhcp/bootp/@server " )
ranges = XMLChildProperty ( _NetworkDHCPRange , relative_xpath = " ./dhcp " )
hosts = XMLChildProperty ( _NetworkDHCPHost , relative_xpath = " ./dhcp " )
class _NetworkRoute ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " route "
2013-09-21 04:40:07 +04:00
family = XMLProperty ( " ./@family " )
address = XMLProperty ( " ./@address " )
prefix = XMLProperty ( " ./@prefix " , is_int = True )
gateway = XMLProperty ( " ./@gateway " )
2013-09-23 17:10:43 +04:00
netmask = XMLProperty ( " ./@netmask " )
2013-09-21 04:40:07 +04:00
2017-03-31 15:12:00 +03:00
class _NetworkForwardPf ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " pf "
2017-03-31 15:12:00 +03:00
dev = XMLProperty ( " ./@dev " )
2017-09-22 14:39:09 +03:00
class _NetworkForwardAddress ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " address "
2017-09-22 14:39:09 +03:00
type = XMLProperty ( " ./@type " )
domain = XMLProperty ( " ./@domain " , is_int = True )
bus = XMLProperty ( " ./@bus " , is_int = True )
slot = XMLProperty ( " ./@slot " , is_int = True )
function = XMLProperty ( " ./@function " , is_int = True )
2013-09-21 04:40:07 +04:00
class _NetworkForward ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " forward "
2013-09-21 04:40:07 +04:00
mode = XMLProperty ( " ./@mode " )
dev = XMLProperty ( " ./@dev " )
2017-03-31 15:12:00 +03:00
managed = XMLProperty ( " ./@managed " )
pf = XMLChildProperty ( _NetworkForwardPf )
2017-09-22 14:39:09 +03:00
vfs = XMLChildProperty ( _NetworkForwardAddress )
2017-03-31 15:12:00 +03:00
2013-09-21 04:40:07 +04:00
def pretty_desc ( self ) :
return Network . pretty_forward_desc ( self . mode , self . dev )
2014-06-25 14:27:00 +04:00
class _NetworkBandwidth ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " bandwidth "
2014-06-25 14:27:00 +04:00
inbound_average = XMLProperty ( " ./inbound/@average " )
inbound_peak = XMLProperty ( " ./inbound/@peak " )
inbound_burst = XMLProperty ( " ./inbound/@burst " )
inbound_floor = XMLProperty ( " ./inbound/@floor " )
outbound_average = XMLProperty ( " ./outbound/@average " )
outbound_peak = XMLProperty ( " ./outbound/@peak " )
outbound_burst = XMLProperty ( " ./outbound/@burst " )
def is_inbound ( self ) :
2015-07-10 15:07:02 +03:00
return bool ( self . inbound_average or self . inbound_peak or
self . inbound_burst or self . inbound_floor )
2014-06-25 14:27:00 +04:00
def is_outbound ( self ) :
2015-07-10 15:07:02 +03:00
return bool ( self . outbound_average or self . outbound_peak or
self . outbound_burst )
2014-06-25 14:27:00 +04:00
def pretty_desc ( self , inbound = True , outbound = True ) :
items_in = [ ( self . inbound_average , _ ( " Average " ) , " KiB/s " ) ,
( self . inbound_peak , _ ( " Peak " ) , " KiB " ) ,
( self . inbound_burst , _ ( " Burst " ) , " KiB/s " ) ,
( self . inbound_floor , _ ( " Floor " ) , " KiB/s " ) ]
items_out = [ ( self . outbound_average , _ ( " Average " ) , " KiB/s " ) ,
( self . outbound_peak , _ ( " Peak " ) , " KiB " ) ,
( self . outbound_burst , _ ( " Burst " ) , " KiB/s " ) ]
def stringify_items ( items ) :
return " , " . join ( [ " %s : %s %s " % ( desc , val , unit )
for val , desc , unit in items if val ] )
ret = " "
show_name = inbound and outbound
if inbound :
if show_name :
ret + = _ ( " Inbound: " )
ret + = stringify_items ( items_in )
if outbound :
if ret :
ret + = " \n "
if show_name :
ret + = _ ( " Outbound: " )
ret + = stringify_items ( items_out )
return ret
2014-05-31 22:20:56 +04:00
class _NetworkPortgroup ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " portgroup "
2014-05-31 22:20:56 +04:00
name = XMLProperty ( " ./@name " )
default = XMLProperty ( " ./@default " , is_yesno = True )
2013-09-21 04:40:07 +04:00
class Network ( XMLBuilder ) :
"""
Top level class for < network > object XML
"""
2019-05-05 20:58:20 +03:00
@staticmethod
def find_free_name ( conn , basename , * * kwargs ) :
cb = conn . networkLookupByName
2019-06-08 01:16:53 +03:00
return generatename . generate_name ( basename , cb , * * kwargs )
2019-05-05 20:58:20 +03:00
2013-09-21 04:40:07 +04:00
@staticmethod
def pretty_forward_desc ( mode , dev ) :
2019-05-05 00:22:15 +03:00
if not mode :
return _ ( " Isolated network " )
if mode == " nat " :
if dev :
desc = _ ( " NAT to %s " ) % dev
else :
desc = _ ( " NAT " )
elif mode == " route " :
if dev :
desc = _ ( " Route to %s " ) % dev
2013-09-21 04:40:07 +04:00
else :
2019-05-05 00:22:15 +03:00
desc = _ ( " Routed network " )
2013-09-21 04:40:07 +04:00
else :
2019-05-05 00:22:15 +03:00
modestr = mode . capitalize ( )
if dev :
desc = ( _ ( " %(mode)s to %(device)s " ) %
{ " mode " : modestr , " device " : dev } )
else :
desc = _ ( " %s network " ) % modestr
2013-09-21 04:40:07 +04:00
return desc
2013-09-23 01:04:22 +04:00
###################
# Helper routines #
###################
def can_pxe ( self ) :
forward = self . forward . mode
if forward and forward != " nat " :
return True
for ip in self . ips :
if ip . bootp_file :
return True
return False
2013-09-21 04:40:07 +04:00
######################
# Validation helpers #
######################
2018-09-03 22:45:26 +03:00
@staticmethod
def validate_name ( conn , name ) :
2019-06-08 01:02:42 +03:00
XMLBuilder . validate_generic_name ( _ ( " Network " ) , name )
2014-01-18 03:40:30 +04:00
2013-09-21 04:40:07 +04:00
try :
2018-09-03 22:45:26 +03:00
conn . networkLookupByName ( name )
2013-09-21 04:40:07 +04:00
except libvirt . libvirtError :
return
raise ValueError ( _ ( " Name ' %s ' already in use by another network. " %
name ) )
##################
# XML properties #
##################
2018-03-21 17:53:34 +03:00
XML_NAME = " network "
2017-03-23 18:06:56 +03:00
_XML_PROP_ORDER = [ " ipv6 " , " name " , " uuid " , " forward " , " virtualport_type " ,
2013-09-21 04:40:07 +04:00
" bridge " , " stp " , " delay " , " domain_name " ,
2014-06-25 14:27:00 +04:00
" macaddr " , " ips " , " routes " , " bandwidth " ]
2013-09-21 04:40:07 +04:00
ipv6 = XMLProperty ( " ./@ipv6 " , is_yesno = True )
2018-09-03 22:45:26 +03:00
name = XMLProperty ( " ./name " )
2017-12-14 20:10:28 +03:00
uuid = XMLProperty ( " ./uuid " )
2013-09-21 04:40:07 +04:00
2017-03-23 18:06:56 +03:00
virtualport_type = XMLProperty ( " ./virtualport/@type " )
2013-09-21 04:40:07 +04:00
# Not entirely correct, there can be multiple routes
forward = XMLChildProperty ( _NetworkForward , is_single = True )
domain_name = XMLProperty ( " ./domain/@name " )
bridge = XMLProperty ( " ./bridge/@name " )
stp = XMLProperty ( " ./bridge/@stp " , is_onoff = True )
delay = XMLProperty ( " ./bridge/@delay " , is_int = True )
macaddr = XMLProperty ( " ./mac/@address " )
2014-05-31 22:20:56 +04:00
portgroups = XMLChildProperty ( _NetworkPortgroup )
2013-09-21 04:40:07 +04:00
ips = XMLChildProperty ( _NetworkIP )
routes = XMLChildProperty ( _NetworkRoute )
2014-06-25 14:27:00 +04:00
bandwidth = XMLChildProperty ( _NetworkBandwidth , is_single = True )
2013-09-21 04:40:07 +04:00
2014-05-31 22:20:56 +04:00
2013-09-30 23:06:52 +04:00
##################
# build routines #
##################
def install ( self , start = True , autostart = True ) :
2018-08-31 23:52:02 +03:00
xml = self . get_xml ( )
2013-09-30 23:06:52 +04:00
logging . debug ( " Creating virtual network ' %s ' with xml: \n %s " ,
self . name , xml )
net = self . conn . networkDefineXML ( xml )
try :
if start :
net . create ( )
if autostart :
net . setAutostart ( autostart )
2017-07-24 11:26:48 +03:00
except Exception :
2013-09-30 23:06:52 +04:00
net . undefine ( )
raise
return net