1# Copyright (C) 2006, 2013-2014 Red Hat, Inc. 2# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com> 3# 4# This work is licensed under the GNU GPLv2 or later. 5# See the COPYING file in the top-level directory. 6 7import ipaddress 8 9from virtinst import log 10from virtinst import Network 11 12from .libvirtobject import vmmLibvirtObject 13from ..lib import testmock 14 15 16def _make_addr_str(addrStr, prefix, netmaskStr): 17 if prefix: 18 return str( 19 ipaddress.ip_network( 20 str("{}/{}").format(addrStr, prefix), strict=False 21 ) 22 ) 23 elif netmaskStr: 24 netmask = ipaddress.ip_address(str((netmaskStr))) 25 network = ipaddress.ip_address(str((addrStr))) 26 return str( 27 ipaddress.ip_network( 28 str("{}/{}").format(network, netmask), strict=False 29 ) 30 ) 31 else: 32 return str(ipaddress.ip_network(str(addrStr), strict=False)) 33 34 35class vmmNetwork(vmmLibvirtObject): 36 def __init__(self, conn, backend, key): 37 vmmLibvirtObject.__init__(self, conn, backend, key, Network) 38 39 self._leases = None 40 41 42 ########################## 43 # Required class methods # 44 ########################## 45 46 def _conn_tick_poll_param(self): 47 return "pollnet" 48 def class_name(self): 49 return "network" 50 51 def _XMLDesc(self, flags): 52 return self._backend.XMLDesc(flags) 53 def _define(self, xml): 54 return self.conn.define_network(xml) 55 def _using_events(self): 56 return self.conn.using_network_events 57 def _get_backend_status(self): 58 return (bool(self._backend.isActive()) and 59 self._STATUS_ACTIVE or 60 self._STATUS_INACTIVE) 61 62 63 ########### 64 # Actions # 65 ########### 66 67 @vmmLibvirtObject.lifecycle_action 68 def start(self): 69 self._backend.create() 70 71 @vmmLibvirtObject.lifecycle_action 72 def stop(self): 73 self._backend.destroy() 74 75 @vmmLibvirtObject.lifecycle_action 76 def delete(self, force=True): 77 ignore = force 78 self._backend.undefine() 79 self._backend = None 80 81 82 ############################### 83 # XML/config handling parsing # 84 ############################### 85 86 def get_autostart(self): 87 return self._backend.autostart() 88 def set_autostart(self, value): 89 self._backend.setAutostart(value) 90 91 def _refresh_dhcp_leases(self): 92 ret = [] 93 try: 94 ret = self._backend.DHCPLeases() 95 except Exception as e: 96 log.debug("Error getting %s DHCP leases: %s", self, str(e)) 97 if self.conn.is_test(): 98 ret = testmock.fake_dhcp_leases() 99 self._leases = ret 100 101 def get_dhcp_leases(self, refresh=False): 102 if self._leases is None or refresh: 103 self._refresh_dhcp_leases() 104 return self._leases 105 106 def get_bridge_device(self): 107 return self.get_xmlobj().bridge 108 def get_name_domain(self): 109 return self.get_xmlobj().domain_name 110 def get_ipv6_enabled(self): 111 return self.get_xmlobj().ipv6 112 def get_ipv4_forward_mode(self): 113 return self.get_xmlobj().forward.mode 114 115 def _get_network(self, family): 116 dhcpstart = None 117 dhcpend = None 118 119 xmlobj = self.get_xmlobj() 120 ip = None 121 for i in xmlobj.ips: 122 if (i.family == family or 123 (family == "ipv4" and not i.family)): 124 if i.ranges: 125 ip = i 126 dhcpstart = i.ranges[0].start 127 dhcpend = i.ranges[0].end 128 break 129 130 if not ip: 131 for i in xmlobj.ips: 132 if (i.family == family or 133 (family == "ipv4" and not i.family)): 134 ip = i 135 break 136 137 ret = None 138 if ip: 139 ret = _make_addr_str(ip.address, ip.prefix, ip.netmask) 140 141 dhcp = [None, None] 142 if dhcpstart and dhcpend: 143 dhcp = [str(ipaddress.ip_address(str(dhcpstart))), 144 str(ipaddress.ip_address(str(dhcpend)))] 145 return [ret, dhcp] 146 147 def get_ipv4_network(self): 148 return self._get_network("ipv4") 149 def get_ipv6_network(self): 150 return self._get_network("ipv6") 151 152 def pretty_forward_mode(self): 153 mode = self.xmlobj.forward.mode 154 dev = self.xmlobj.forward.dev 155 156 if not mode: 157 return _("Isolated network") 158 159 if mode == "nat": 160 if dev: 161 desc = _("NAT to %s") % dev 162 else: 163 desc = _("NAT") 164 elif mode == "route": 165 if dev: 166 desc = _("Route to %s") % dev 167 else: 168 desc = _("Routed network") 169 else: 170 modestr = mode.capitalize() 171 desc = _("%s network") % modestr 172 173 return desc 174