# # Copyright (C) 2006-2007 Red Hat, Inc. # Copyright (C) 2006 Hugh O. Brock # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA. # import logging import re import ipaddr # pylint: disable=E0611 from gi.repository import Gtk from gi.repository import Gdk # pylint: enable=E0611 from virtManager.network import vmmNetwork from virtManager.baseclass import vmmGObjectUI PAGE_INTRO = 0 PAGE_NAME = 1 PAGE_IPV4 = 2 PAGE_IPV6 = 3 PAGE_MISC = 4 PAGE_SUMMARY = 5 class vmmCreateNetwork(vmmGObjectUI): def __init__(self, conn): vmmGObjectUI.__init__(self, "vmm-create-net.ui", "vmm-create-net") self.conn = conn self.builder.connect_signals({ "on_create_pages_switch_page" : self.page_changed, "on_create_cancel_clicked" : self.close, "on_vmm_create_delete_event" : self.close, "on_create_forward_clicked" : self.forward, "on_create_back_clicked" : self.back, "on_create_finish_clicked" : self.finish, "on_net_name_activate": self.forward, "on_net_forward_toggled" : self.change_forward_type, "on_net-ipv4-enable_toggled" : self.change_ipv4_enable, "on_net-ipv4-network_changed": self.change_network, "on_net-dhcpv4-enable_toggled": self.change_dhcpv4_enable, "on_net-dhcpv4-start_changed": self.change_dhcpv4_start, "on_net-dhcpv4-end_changed": self.change_dhcpv4_end, "on_net-ipv6-enable_toggled" : self.change_ipv6_enable, "on_net-ipv6-network_changed": self.change_ipv6_network, "on_net-dhcpv6-enable_toggled": self.change_dhcpv6_enable, "on_net-dhcpv6-start_changed": self.change_dhcpv6_start, "on_net-dhcpv6-end_changed": self.change_dhcpv6_end, }) self.bind_escape_key_close() finish_img = Gtk.Image.new_from_stock(Gtk.STOCK_QUIT, Gtk.IconSize.BUTTON) self.widget("create-finish").set_image(finish_img) self.set_initial_state() def show(self, parent): logging.debug("Showing new network wizard") self.reset_state() self.topwin.set_transient_for(parent) self.topwin.present() def is_visible(self): return self.topwin.get_visible() def close(self, ignore1=None, ignore2=None): logging.debug("Closing new network wizard") self.topwin.hide() return 1 def _cleanup(self): self.conn = None def set_initial_state(self): notebook = self.widget("create-pages") notebook.set_show_tabs(False) black = Gdk.Color.parse("#000")[1] for num in range(PAGE_SUMMARY + 1): name = "page" + str(num) + "-title" self.widget(name).modify_bg(Gtk.StateType.NORMAL, black) fw_list = self.widget("net-forward") # [ label, dev name ] fw_model = Gtk.ListStore(str, str) fw_list.set_model(fw_model) text = Gtk.CellRendererText() fw_list.pack_start(text, True) fw_list.add_attribute(text, 'text', 0) fw_model.append([_("Any physical device"), None]) for path in self.conn.list_net_device_paths(): net = self.conn.get_net_device(path) fw_model.append([_("Physical device %s") % (net.get_name()), net.get_name()]) mode_list = self.widget("net-forward-mode") # [ label, mode ] mode_model = Gtk.ListStore(str, str) mode_list.set_model(mode_model) text = Gtk.CellRendererText() mode_list.pack_start(text, True) mode_list.add_attribute(text, 'text', 0) mode_model.append([_("NAT"), "nat"]) mode_model.append([_("Routed"), "route"]) def reset_state(self): notebook = self.widget("create-pages") notebook.set_current_page(0) self.page_changed(None, None, 0) self.widget("net-name").set_text("") self.widget("net-name").set_sensitive(True) self.widget("net-domain-name").set_text("") self.widget("net-domain-name").set_sensitive(True) self.widget("net-ipv4-enable").set_active(True) self.widget("net-ipv4-network").set_text("192.168.100.0/24") self.widget("net-ipv4-network").set_sensitive(True) self.widget("net-dhcpv4-enable").set_active(True) self.widget("net-dhcpv4-start").set_text("192.168.100.128") self.widget("net-dhcpv4-end").set_text("192.168.100.254") self.widget("net-dhcpv4-start").set_sensitive(True) self.widget("net-dhcpv4-end").set_sensitive(True) self.widget("net-ipv6-enable").set_active(False) self.widget("net-ipv6-network").set_text("") self.widget("net-ipv6-network").set_sensitive(True) self.widget("net-dhcpv6-enable").set_active(False) self.widget("net-dhcpv6-start").set_text("") self.widget("net-dhcpv6-end").set_text("") self.widget("net-forward-none").set_active(True) self.widget("net-forward").set_active(0) self.widget("net-forward-mode").set_active(0) self.widget("net-enable-ipv6-networking").set_active(False) def forward(self, ignore=None): notebook = self.widget("create-pages") if self.validate(notebook.get_current_page()) is not True: return self.widget("create-forward").grab_focus() notebook.next_page() def back(self, ignore=None): notebook = self.widget("create-pages") notebook.prev_page() def change_ipv4_enable(self, src): ignore = src white = Gdk.Color.parse("#f0f0f0")[1] net4 = self.widget("net-ipv4-network") start4 = self.widget("net-dhcpv4-start") end4 = self.widget("net-dhcpv4-end") if self.get_config_ipv4_enable(): net4.set_sensitive(True) net4.set_text("") net4.modify_bg(Gtk.StateType.NORMAL, white) if self.get_config_dhcpv4_enable(): start4.set_sensitive(True) end4.set_sensitive(True) else: net4.set_text("") start4.set_text("") end4.set_text("") net4.set_sensitive(False) start4.set_sensitive(False) end4.set_sensitive(False) net4.modify_bg(Gtk.StateType.NORMAL, white) start4.modify_bg(Gtk.StateType.NORMAL, white) end4.modify_bg(Gtk.StateType.NORMAL, white) def change_ipv6_enable(self, src): ignore = src white = Gdk.Color.parse("#f0f0f0")[1] net6 = self.widget("net-ipv6-network") start6 = self.widget("net-dhcpv6-start") end6 = self.widget("net-dhcpv6-end") if self.get_config_ipv6_enable(): net6.set_sensitive(True) net6.set_text("") net6.modify_bg(Gtk.StateType.NORMAL, white) if self.get_config_dhcpv6_enable(): start6.set_sensitive(True) end6.set_sensitive(True) else: net6.set_text("") start6.set_text("") end6.set_text("") net6.set_sensitive(False) start6.set_sensitive(False) end6.set_sensitive(False) net6.modify_bg(Gtk.StateType.NORMAL, white) start6.modify_bg(Gtk.StateType.NORMAL, white) end6.modify_bg(Gtk.StateType.NORMAL, white) def change_network(self, src): ip = self.get_config_ip4() green = Gdk.Color.parse("#c0ffc0")[1] red = Gdk.Color.parse("#ffc0c0")[1] black = Gdk.Color.parse("#000000")[1] src.modify_text(Gtk.StateType.NORMAL, black) # No IP specified or invalid IP if ip is None or ip.version != 4: src.modify_bg(Gtk.StateType.NORMAL, red) self.widget("net-info-gateway").set_text("") self.widget("net-info-type").set_text("") self.widget("net-dhcpv4-start").set_text("") self.widget("net-dhcpv4-end").set_text("") return # We've got a valid IP if ip.numhosts < 16 or not ip.is_private: src.modify_bg(Gtk.StateType.NORMAL, red) else: src.modify_bg(Gtk.StateType.NORMAL, green) if ip.prefixlen == 32: self.widget("net-info-gateway").set_text("") else: self.widget("net-info-gateway").set_text(str(ip.network + 1)) if ip.is_private: self.widget("net-info-type").set_text(_("Private")) else: self.widget("net-info-type").set_text(_("Other/Public")) if self.get_config_dhcpv4_enable(): self.widget("net-dhcpv4-start").set_sensitive(True) self.widget("net-dhcpv4-end").set_sensitive(True) start = int(ip.numhosts / 2) end = int(ip.numhosts - 2) self.widget("net-dhcpv4-start").set_text(str(ip.network + start)) self.widget("net-dhcpv4-end").set_text(str(ip.network + end)) else: self.widget("net-dhcpv4-start").set_sensitive(False) self.widget("net-dhcpv4-end").set_sensitive(False) def change_ipv6_network(self, src): ip = self.get_config_ip6() green = Gdk.Color.parse("#c0ffc0")[1] red = Gdk.Color.parse("#ffc0c0")[1] black = Gdk.Color.parse("#000000")[1] src.modify_text(Gtk.StateType.NORMAL, black) # No IP specified or invalid IP if ip is None or ip.version != 6: src.modify_bg(Gtk.StateType.NORMAL, red) self.widget("net-info-gateway-ip6").set_text("") self.widget("net-info-type-ip6").set_text("") self.widget("net-dhcpv6-start").set_text("") self.widget("net-dhcpv6-end").set_text("") return if ip.prefixlen != 64 or not ip.is_private: src.modify_bg(Gtk.StateType.NORMAL, red) else: src.modify_bg(Gtk.StateType.NORMAL, green) if ip.prefixlen != 64: self.widget("net-info-gateway-ip6").set_text("") else: self.widget("net-info-gateway-ip6").set_text(str(ip.network + 1)) if ip.is_private: self.widget("net-info-type-ip6").set_text(_("Private")) elif ip.is_reserved: self.widget("net-info-type-ip6").set_text(_("Reserved")) elif ip.is_unspecified: self.widget("net-info-type-ip6").set_text(_("Unspecified")) else: self.widget("net-info-type-ip6").set_text(_("Other/Public")) if self.get_config_dhcpv6_enable(): self.widget("net-dhcpv6-start").set_sensitive(True) self.widget("net-dhcpv6-end").set_sensitive(True) start = 256 end = 512 - 1 self.widget("net-dhcpv6-start").set_text(str(ip.network + start)) self.widget("net-dhcpv6-end").set_text(str(ip.network + end)) else: self.widget("net-dhcpv6-start").set_sensitive(False) self.widget("net-dhcpv6-end").set_sensitive(False) def change_dhcpv4_enable(self, src): ignore = src white = Gdk.Color.parse("#f0f0f0")[1] start4 = self.widget("net-dhcpv4-start") end4 = self.widget("net-dhcpv4-end") start4.modify_bg(Gtk.StateType.NORMAL, white) end4.modify_bg(Gtk.StateType.NORMAL, white) start4.set_text("") end4.set_text("") if not self.get_config_dhcpv4_enable(): start4.set_sensitive(False) end4.set_sensitive(False) else: start4.set_sensitive(True) end4.set_sensitive(True) ip = self.get_config_ip4() if ip: start = int(ip.numhosts / 2) end = int(ip.numhosts - 2) start4.set_text(str(ip.network + start)) end4.set_text(str(ip.network + end)) def change_dhcpv4_start(self, src): start = self.get_config_dhcpv4_start() self.change_dhcpv4(src, start) def change_dhcpv4_end(self, src): end = self.get_config_dhcpv4_end() self.change_dhcpv4(src, end) def change_dhcpv4(self, src, addr): ip = self.get_config_ip4() black = Gdk.Color.parse("#000000")[1] src.modify_text(Gtk.StateType.NORMAL, black) if not ip: return if addr is None: white = Gdk.Color.parse("#f0f0f0")[1] src.modify_bg(Gtk.StateType.NORMAL, white) elif not ip.overlaps(addr): red = Gdk.Color.parse("#ffc0c0")[1] src.modify_bg(Gtk.StateType.NORMAL, red) else: green = Gdk.Color.parse("#c0ffc0")[1] src.modify_bg(Gtk.StateType.NORMAL, green) def change_dhcpv6_enable(self, src): ignore = src white = Gdk.Color.parse("#f0f0f0")[1] start6 = self.widget("net-dhcpv6-start") end6 = self.widget("net-dhcpv6-end") start6.modify_bg(Gtk.StateType.NORMAL, white) end6.modify_bg(Gtk.StateType.NORMAL, white) start6.set_text("") end6.set_text("") if not self.get_config_dhcpv6_enable(): start6.set_sensitive(False) end6.set_sensitive(False) else: start6.set_sensitive(True) end6.set_sensitive(True) ip = self.get_config_ip6() if ip: start = 256 end = 512 - 1 start6.set_text(str(ip.network + start)) end6.set_text(str(ip.network + end)) def change_dhcpv6_start(self, src): start = self.get_config_dhcpv6_start() self.change_dhcpv6(src, start) def change_dhcpv6_end(self, src): end = self.get_config_dhcpv6_end() self.change_dhcpv6(src, end) def change_dhcpv6(self, src, addr): ip = self.get_config_ip6() black = Gdk.Color.parse("#000000")[1] src.modify_text(Gtk.StateType.NORMAL, black) if not ip: return if addr is None: white = Gdk.Color.parse("#f0f0f0")[1] src.modify_bg(Gtk.StateType.NORMAL, white) elif not ip.overlaps(addr): red = Gdk.Color.parse("#ffc0c0")[1] src.modify_bg(Gtk.StateType.NORMAL, red) else: green = Gdk.Color.parse("#c0ffc0")[1] src.modify_bg(Gtk.StateType.NORMAL, green) def change_forward_type(self, src_ignore): skip_fwd = self.widget("net-forward-none").get_active() self.widget("net-forward-mode").set_sensitive(not skip_fwd) self.widget("net-forward").set_sensitive(not skip_fwd) def get_config_name(self): return self.widget("net-name").get_text() def get_config_domain_name(self): return self.widget("net-domain-name").get_text() def get_config_ip4(self): if not self.get_config_ipv4_enable(): return None try: return ipaddr.IPNetwork(self.widget("net-ipv4-network").get_text()) except: return None def get_config_dhcpv4_start(self): try: return ipaddr.IPNetwork(self.widget("net-dhcpv4-start").get_text()) except: return None def get_config_dhcpv4_end(self): try: return ipaddr.IPNetwork(self.widget("net-dhcpv4-end").get_text()) except: return None def get_config_ip6(self): if not self.get_config_ipv6_enable(): return None try: return ipaddr.IPNetwork(self.widget("net-ipv6-network").get_text()) except: return None def get_config_dhcpv6_start(self): try: return ipaddr.IPNetwork(self.widget("net-dhcpv6-start").get_text()) except: return None def get_config_dhcpv6_end(self): try: return ipaddr.IPNetwork(self.widget("net-dhcpv6-end").get_text()) except: return None def get_config_forwarding(self): if self.widget("net-forward-none").get_active(): return [None, None] else: dev = self.widget("net-forward") model = dev.get_model() active = dev.get_active() name = model[active][1] mode_w = self.widget("net-forward-mode") mode = mode_w.get_model()[mode_w.get_active()][1] return [name, mode] def get_config_ipv4_enable(self): return self.widget("net-ipv4-enable").get_active() def get_config_ipv6_enable(self): return self.widget("net-ipv6-enable").get_active() def get_config_dhcpv4_enable(self): return self.widget("net-dhcpv4-enable").get_active() def get_config_dhcpv6_enable(self): return self.widget("net-dhcpv6-enable").get_active() def populate_summary(self): self.widget("summary-name").set_text(self.get_config_name()) self.widget("summary-domain").set_text(self.get_config_domain_name()) self.widget("summary-ip4-network").set_text("") self.widget("summary-ip4-gateway").set_text("") self.widget("summary-ip6-network").set_text("") self.widget("summary-ip6-gateway").set_text("") ip = self.get_config_ip4() if ip: self.widget("label-ip4-gateway").show() self.widget("summary-ip4-gateway").show() self.widget("label-ip4-network").set_text(_("Network:")) self.widget("summary-ip4-network").set_text(str(ip)) self.widget("summary-ip4-gateway").set_text(str(ip.network + 1)) else: self.widget("label-ip4-gateway").hide() self.widget("summary-ip4-gateway").hide() self.widget("label-ip4-network").set_text("IPv4 Network:") self.widget("summary-ip4-network").set_text("Not Defined") if ip and self.get_config_dhcpv4_enable(): self.widget("label-dhcp-end").show() self.widget("summary-dhcp-end").show() start = self.get_config_dhcpv4_start() end = self.get_config_dhcpv4_end() self.widget("label-dhcp-start").set_text("Start Address:") if start and end: self.widget("summary-dhcp-start").set_text(str(start.network)) self.widget("summary-dhcp-end").set_text(str(end.network)) else: self.widget("summary-dhcp-start").set_text("?") self.widget("summary-dhcp-end").set_text("?") else: self.widget("label-dhcp-end").hide() self.widget("summary-dhcp-end").hide() self.widget("label-dhcp-start").set_text(_("DHCPv4 Status:")) self.widget("summary-dhcp-start").set_text(_("Disabled")) forward_txt = "" dev, mode = self.get_config_forwarding() forward_txt = vmmNetwork.pretty_desc(mode, dev) self.widget("summary-ipv4-forwarding").set_text(forward_txt) ip = self.get_config_ip6() if ip: self.widget("label-ip6-gateway").show() self.widget("summary-ip6-gateway").show() self.widget("label-ip6-network").set_text(_("Network:")) self.widget("summary-ip6-network").set_text(str(ip)) self.widget("summary-ip6-gateway").set_text(str(ip.network + 1)) else: self.widget("label-ip6-gateway").hide() self.widget("summary-ip6-gateway").hide() self.widget("label-ip6-network").set_text(_("IPV6 Network:")) self.widget("summary-ip6-network").set_text(_("Not Defined")) if ip and self.get_config_dhcpv6_enable(): self.widget("label-dhcpv6-end").show() self.widget("summary-dhcpv6-end").show() start = self.get_config_dhcpv6_start() end = self.get_config_dhcpv6_end() self.widget("label-dhcpv6-start").set_text("Start Address:") if start and end: self.widget("summary-dhcpv6-start").set_text(str(start.network)) self.widget("summary-dhcpv6-end").set_text(str(end.network)) else: self.widget("summary-dhcpv6-start").set_text("?") self.widget("summary-dhcpv6-end").set_text("?") else: self.widget("label-dhcpv6-end").hide() self.widget("summary-dhcpv6-end").hide() self.widget("label-dhcpv6-start").set_text(_("DHCPv6 Status:")) self.widget("summary-dhcpv6-start").set_text(_("Disabled")) if ip: self.widget("summary-ipv6-forwarding").set_text("Routed network") else: if self.widget("net-enable-ipv6-networking").get_active(): self.widget("summary-ipv6-forwarding").set_text("Isolated network, internal routing only") else: self.widget("summary-ipv6-forwarding").set_text("Isolated network") def populate_ipv4(self): if not self.get_config_ipv4_enable(): self.widget("net-ipv4-network").set_text("") self.widget("net-dhcpv4-end").set_text("") self.widget("net-dhcpv4-start").set_text("") self.widget("net-ipv4-network").set_sensitive(False) self.widget("net-dhcpv4-start").set_sensitive(False) self.widget("net-dhcpv4-end").set_sensitive(False) return self.widget("net-ipv4-network").set_sensitive(True) if not self.get_config_dhcpv4_enable(): self.widget("net-dhcpv4-end").set_text("") self.widget("net-dhcpv4-start").set_text("") self.widget("net-dhcpv4-start").set_sensitive(False) self.widget("net-dhcpv4-end").set_sensitive(False) return else: ip = self.get_config_ip4() if ip: start = int(ip.numhosts / 2) end = int(ip.numhosts - 2) if self.widget("net-dhcpv4-start").get_text() == "": self.widget("net-dhcpv4-start").set_text(str(ip.network + start)) self.widget("net-dhcpv4-end").set_text(str(ip.network + end)) self.widget("net-dhcpv4-start").set_sensitive(True) self.widget("net-dhcpv4-end").set_sensitive(True) def populate_ipv6(self): if not self.get_config_ipv6_enable(): self.widget("net-ipv6-network").set_text("") self.widget("net-dhcpv6-end").set_text("") self.widget("net-dhcpv6-start").set_text("") self.widget("net-ipv6-network").set_sensitive(False) self.widget("net-dhcpv6-start").set_sensitive(False) self.widget("net-dhcpv6-end").set_sensitive(False) return self.widget("net-ipv6-network").set_sensitive(True) if not self.get_config_dhcpv6_enable(): self.widget("net-dhcpv6-end").set_text("") self.widget("net-dhcpv6-start").set_text("") self.widget("net-dhcpv6-start").set_sensitive(False) self.widget("net-dhcpv6-end").set_sensitive(False) return else: ip = self.get_config_ip6() if ip: start = 256 end = 512 - 1 if self.widget("net-dhcpv6-start").get_text() == "": self.widget("net-dhcpv6-start").set_text(str(ip.network + start)) self.widget("net-dhcpv6-end").set_text(str(ip.network + end)) self.widget("net-dhcpv6-start").set_sensitive(True) self.widget("net-dhcpv6-end").set_sensitive(True) def page_changed(self, ignore1, ignore2, page_number): if page_number == PAGE_NAME: name_widget = self.widget("net-name") name_widget.set_sensitive(True) name_widget.grab_focus() elif page_number == PAGE_IPV4: self.populate_ipv4() elif page_number == PAGE_IPV6: self.populate_ipv6() elif page_number == PAGE_SUMMARY: self.populate_summary() if page_number == PAGE_INTRO: self.widget("create-back").set_sensitive(False) else: self.widget("create-back").set_sensitive(True) if page_number == PAGE_SUMMARY: self.widget("create-forward").hide() self.widget("create-finish").show() self.widget("create-finish").grab_focus() else: self.widget("create-forward").show() self.widget("create-finish").hide() def finish(self, ignore=None): name = self.get_config_name() dev, mode = self.get_config_forwarding() if self.widget("net-enable-ipv6-networking").get_active(): xml = "\n" else: xml = "\n" xml += " %s\n" % name domain_name = self.get_config_domain_name() if len(domain_name) != 0: xml += " \n" % domain_name if mode: if dev is not None: xml += " \n" % (mode, dev) else: xml += " \n" % mode if self.get_config_ipv4_enable(): ip = self.get_config_ip4() xml += " \n" % (str(ip.network + 1), str(ip.netmask)) if self.get_config_dhcpv4_enable(): start = self.get_config_dhcpv4_start() end = self.get_config_dhcpv4_end() xml += " \n" xml += " \n" % (str(start.network), str(end.network)) xml += " \n" xml += " \n" if self.get_config_ipv6_enable(): ip = self.get_config_ip6() xml += " \n" % (str(ip.network + 1), str(ip.prefixlen)) if self.get_config_dhcpv6_enable(): start = self.get_config_dhcpv6_start() end = self.get_config_dhcpv6_end() xml += " \n" xml += " \n" % (str(start.network), str(end.network)) xml += " \n" xml += " \n" xml += "\n" logging.debug("Generated network XML:\n" + xml) try: self.conn.create_network(xml) except Exception, e: self.err.show_err(_("Error creating virtual network: %s" % str(e))) return self.conn.tick(noStatsUpdate=True) self.close() def validate_name(self): name_widget = self.widget("net-name") name = name_widget.get_text() if len(name) > 50 or len(name) == 0: retcode = self.err.val_err(_("Invalid Network Name"), _("Network name must be non-blank and less than " "50 characters")) name_widget.grab_focus() return retcode if re.match("^[a-zA-Z0-9_]*$", name) is None: return self.err.val_err(_("Invalid Network Name"), _("Network name may contain alphanumeric and '_' " "characters only")) return True def validate_ipv4(self): if not self.get_config_ipv4_enable(): return True ip = self.get_config_ip4() if ip is None: return self.err.val_err(_("Invalid Network Address"), _("The network address could not be understood")) if ip.version != 4: return self.err.val_err(_("Invalid Network Address"), _("The network must be an IPv4 address")) if ip.numhosts < 16: return self.err.val_err(_("Invalid Network Address"), _("The network prefix must be at least /28 (16 addresses)")) if not ip.is_private: res = self.err.yes_no(_("Check Network Address"), _("The network should normally use a private IPv4 " "address. Use this non-private address anyway?")) if not res: return False enabled = self.get_config_dhcpv4_enable() if enabled: start = self.get_config_dhcpv4_start() end = self.get_config_dhcpv4_end() if enabled and start is None: return self.err.val_err(_("Invalid DHCP Address"), _("The DHCP start address could not be understood")) if enabled and end is None: return self.err.val_err(_("Invalid DHCP Address"), _("The DHCP end address could not be understood")) if enabled and not ip.overlaps(start): return self.err.val_err(_("Invalid DHCP Address"), (_("The DHCP start address is not with the network %s") % (str(ip)))) if enabled and not ip.overlaps(end): return self.err.val_err(_("Invalid DHCP Address"), (_("The DHCP end address is not with the network %s") % (str(ip)))) return True def validate_ipv6(self): if not self.get_config_ipv6_enable(): return True ip = self.get_config_ip6() if ip is None: return self.err.val_err(_("Invalid Network Address"), _("The network address could not be understood")) if ip.version != 6: return self.err.val_err(_("Invalid Network Address"), _("The network must be an IPv6 address")) if ip.prefixlen != 64: return self.err.val_err(_("Invalid Network Address"), _("For libvirt, the IPv6 network prefix must be 64")) if not ip.is_private: res = self.err.yes_no(_("Check Network Address"), _("The network should normally use a private IPv4 " "address. Use this non-private address anyway?")) if not res: return False enabled = self.get_config_dhcpv6_enable() if enabled: start = self.get_config_dhcpv6_start() end = self.get_config_dhcpv6_end() if start is None: return self.err.val_err(_("Invalid DHCPv6 Address"), _("The DHCPv6 start address could not be understood")) if end is None: return self.err.val_err(_("Invalid DHCPv6 Address"), _("The DHCPv6 end address could not be understood")) if not ip.overlaps(start): return self.err.val_err(_("Invalid DHCPv6 Address"), (_("The DHCPv6 start address is not with the network %s") % (str(ip)))) if not ip.overlaps(end): return self.err.val_err(_("Invalid DHCPv6 Address"), (_("The DHCPv6 end address is not with the network %s") % (str(ip)))) return True def validate_miscellaneous(self): domain_name = self.widget("net-domain-name").get_text() if len(domain_name) > 0: if len(domain_name) > 16: return self.err.val_err(_("Invalid Domain Name"), _("Domain name must be less than 17 characters")) if re.match("^[a-zA-Z0-9_]*$", domain_name) is None: return self.err.val_err(_("Invalid Domain Name"), _("Domain name may contain alphanumeric and '_' " "characters only")) if not self.widget("net-forward-dev").get_active(): return True dev = self.widget("net-forward") if dev.get_active() == -1: return self.err.val_err(_("Invalid forwarding mode"), _("Please select where the traffic should be forwarded")) return True def validate(self, page_num): if page_num == PAGE_NAME: return self.validate_name() elif page_num == PAGE_IPV4: return self.validate_ipv4() elif page_num == PAGE_IPV6: return self.validate_ipv6() elif page_num == PAGE_MISC: return self.validate_miscellaneous() return True