def test_direct_dhcp(self, *args, **kwargs): mb = defaults.NicBonding() mt = defaults.NetworkLayout() m = defaults.Network() mb.configure_8023ad("bond0", ["ens1", "ens2", "ens3"]) m.configure_dhcp("bond0") mt.configure_direct() run_tx_by_name(m.transaction(), "WriteConfiguration") assert ifcfg_has_items("bond0", [('BONDING_OPTS', 'mode=4'), ('BOOTPROTO', 'dhcp'), ('DEVICE', 'bond0'), ('HWADDR', 'th:em:ac:ad:dr'), ('ONBOOT', 'yes'), ('PEERNTP', 'yes')]) assert ifcfg_has_items("ens1", [('DEVICE', 'ens1'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert ifcfg_has_items("ens2", [('DEVICE', 'ens2'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert ifcfg_has_items("ens3", [('DEVICE', 'ens3'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert len(FakeFs.filemap) == (1 + 1 + 3)
def ui_content(self): """Describes the UI this plugin requires This is an ordered list of (path, widget) tuples. """ mbond = defaults.NicBonding().retrieve() bond_status = ", ".join(mbond["slaves"] or []) bond_lbl = "Remove %s (%s)" % (mbond["name"], bond_status) \ if bond_status else "Create Bond" ws = [ ui.Header("header[0]", "System Identification"), ui.Entry("hostname", "Hostname:"), ui.Divider("divider[0]"), ui.Entry("dns[0]", "DNS Server 1:"), ui.Entry("dns[1]", "DNS Server 2:"), ui.Divider("divider[1]"), ui.Entry("ntp[0]", "NTP Server 1:"), ui.Entry("ntp[1]", "NTP Server 2:"), ui.Divider("divider[2]"), NicTable("nics", height=3), ui.Row("row[0]", [ ui.Button("button.ping", "Ping"), ui.Button("button.toggle_bond", bond_lbl) ]) ] page = ui.Page("page", ws) # Save it "locally" as a dict, for better accessability self.widgets.add(page) return page
def test_unused_bond(self, *args, **kwargs): mb = defaults.NicBonding() m = defaults.Network() # bond0 is created, but ens42 is used mb.configure_8023ad("bond0", ["ens1", "ens2", "ens3"]) m.configure_dhcp("ens42") try: run_tx_by_name(m.transaction(), "WriteConfiguration") except RuntimeError as e: assert e.message == "Bond configured but not used"
def test_tagged_bridged_dhcp(self, *args, **kwargs): mb = defaults.NicBonding() mt = defaults.NetworkLayout() m = defaults.Network() mb.configure_8023ad("bond0", ["ens1", "ens2", "ens3"]) m.configure_dhcp("bond0", "42") mt.configure_bridged() run_tx_by_name(m.transaction(), "WriteConfiguration") assert ifcfg_has_items("ens1", [('DEVICE', 'ens1'), ('HWADDR', 'th:em:ac:ad:dr'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert ifcfg_has_items("ens2", [('DEVICE', 'ens2'), ('HWADDR', 'th:em:ac:ad:dr'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert ifcfg_has_items("ens3", [('DEVICE', 'ens3'), ('HWADDR', 'th:em:ac:ad:dr'), ('MASTER', 'bond0'), ('ONBOOT', 'yes'), ('SLAVE', 'yes')]) assert ifcfg_has_items("bond0", [('BONDING_OPTS', 'mode=4'), ('DEVICE', 'bond0'), ('ONBOOT', 'yes'), ('TYPE', 'Bond')]) assert ifcfg_has_items("bond0.42", [('BRIDGE', 'brbond0'), ('DEVICE', 'bond0.42'), ('ONBOOT', 'yes'), ('VLAN', 'yes')]) assert ifcfg_has_items("brbond0", [('BOOTPROTO', 'dhcp'), ('DELAY', '0'), ('DEVICE', 'brbond0'), ('ONBOOT', 'yes'), ('PEERNTP', 'yes'), ('TYPE', 'Bridge')])
def test_bond_slave_as_primary(self, *args, **kwargs): mb = defaults.NicBonding() m = defaults.Network() # ens1 is used as a slave, but then also as a primary device # this doesn't work mb.configure_8023ad("bond0", ["ens1", "ens2", "ens3"]) m.configure_dhcp("ens1") had_exception = False try: run_tx_by_name(m.transaction(), "WriteConfiguration") except RuntimeError as e: had_exception = True assert e.message == ("Bond slave can not be used as " + "primary device") assert had_exception
def test_no_bond_and_clean(self, *args, **kwargs): mb = defaults.NicBonding() self.test_unused_bond() # bond0 is created, but ens42 is used mb.configure_no_bond() mb.transaction().run() pprint.pprint(FakeFs.filemap) assert ifcfgfilename("bond0") not in FakeFs.filemap assert ifcfg_has_items("ens1", [('DEVICE', 'ens1'), ('ONBOOT', 'yes')]) assert ifcfg_has_items("ens2", [('DEVICE', 'ens2'), ('ONBOOT', 'yes')]) assert ifcfg_has_items("ens3", [('DEVICE', 'ens3'), ('ONBOOT', 'yes')])
def ui_content(self): """Describes the UI this plugin requires This is an ordered list of (path, widget) tuples. """ mbond = defaults.NicBonding().retrieve() bond_status = ", ".join(mbond["slaves"] or []) bond_lbl = _("Remove %s (%s)") % (mbond["name"], bond_status) \ if bond_status else _("Create Bond") ws = [ui.Header("header[0]", _("System Identification")), ui.Entry("hostname", _("Hostname:")), ui.Divider("divider[0]"), ui.Entry("dns[0]", _("DNS Server 1:")), ui.Entry("dns[1]", _("DNS Server 2:")), ui.Divider("divider[1]"), ui.Entry("ntp[0]", _("NTP Server 1:")), ui.Entry("ntp[1]", _("NTP Server 2:")), ui.Divider("divider[2]"), NicTable("nics", height=3), ui.Row("row[0]", [ui.Button("button.ping", _("Ping")), ui.Button("button.toggle_bond", bond_lbl) ]) ] page = ui.Page("page", ws) # Save it "locally" as a dict, for better accessability self.widgets.add(page) # # NIC Deatils Dialog and Bond creation is disabled # when Node is managed # if has_managed_ifnames(): self._nic_details_group.enabled(False) self.widgets["button.toggle_bond"].enabled(False) nictbl = self.widgets["nics"] nictbl.on_activate.clear() nictbl.label(nictbl.label() + " (read-only/managed)") return page
def migrate_network_layout(self): from ovirt.node.config import defaults from ovirt.node.utils import network bondcfg = defaults.NicBonding().retrieve() netlayoutcfg = defaults.NetworkLayout().retrieve() if bondcfg["name"] or netlayoutcfg["layout"]: # We can only reliably import pre node-3.0 # network configurations, therefor we abort # the import if it looks like a node-3.0 config self.logger.info("Looks like node-3.0 network, skipping import") return bridges = [x for x in network.Bridges().ifnames() if x.startswith("br")] bridged_nics = [x for x in network.all_ifaces() if network.NIC(x).config.bridge in bridges] self.logger.debug("Found bridges: %s" % bridges) self.logger.debug("Found bridged NICs: %s" % bridged_nics) def cfgset(k, v, prefix="OVIRT_"): if v: self.logger.debug(" Setting %s = %s" % (k, v)) self.aug.set("/files/etc/default/ovirt/%s%s" % (prefix, k), str(v)) found_mgmt = False for brn in ["rhevm", "ovirtmgmt"]: if brn in network.Bridges().ifnames(): self.logger.debug("Found managed nic: %s" % brn) cfgset("MANAGED_BY", "RHEV-M", "") cfgset("MANAGED_IFNAMES", brn, "") found_mgmt = True break self.logger.debug("Found management: %s" % found_mgmt) if not found_mgmt and bridges and bridged_nics: self.logger.debug("Assuming default bridged network") self.aug.set("/files/etc/default/ovirt/OVIRT_NETWORK_LAYOUT", "bridged") ifname = bridged_nics[0] br = bridges[0] vlanid = None self.logger.debug("Bridge and NIC: %s %s" % (br, ifname)) probably_vlan = "." in ifname if probably_vlan: ifname, vlanid = ifname.split(".", 1) self.logger.debug("Found VLAN setup, base NIC: %s %s" % (ifname, vlanid)) self.aug.set("/files/etc/default/ovirt/OVIRT_BOOTIF", ifname) def ifcfg(i, k): v = self.aug.get("/files/etc/sysconfig/network-" + "scripts/ifcfg-%s/%s" % (i, k)) self.logger.debug(" Getting %s.%s = %s" % (i, k, v)) return v proto = ifcfg(br, "BOOTPROTO") cfgset("BOOTPROTO", proto) addr = ifcfg(br, "IPADDR") if addr: cfgset("IP_ADDRESS", addr) cfgset("IP_GATEWAY", ifcfg(br, "GATEWAY")) cfgset("IP_NETMASK", ifcfg(br, "NETMASK")) if vlanid: cfgset("VLAN", vlanid)
def on_merge(self, effective_changes): self.logger.info("Saving network stuff") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.info("Effective changes %s" % effective_changes) self.logger.debug("Effective Model: %s" % effective_model) # This object will contain all transaction elements to be executed txs = utils.Transaction("Network Interface Configuration") # Special case: A NIC was selected, display that dialog! if "nics" in changes and len(changes) == 1: iface = changes["nics"] self.logger.debug("Opening NIC Details dialog for '%s'" % iface) self._model_extra["dialog.nic.ifname"] = iface self._nic_dialog = NicDetailsDialog(self, iface) return self._nic_dialog if "dialog.nic.close" in changes: self._nic_dialog.close() return if "button.toggle_bond" in changes: m_bond = defaults.NicBonding() mnet = defaults.Network() if m_bond.retrieve()["slaves"]: if mnet.retrieve()["iface"] == m_bond.retrieve()["name"]: # Remove network config if primary devce was this # bond mnet.configure_no_networking() m_bond.configure_no_bond() txs += m_bond.transaction() txs += mnet.transaction() else: self._bond_dialog = CreateBondDialog("dialog.bond") self.widgets.add(self._bond_dialog) return self._bond_dialog if "button.ping" in changes: self.logger.debug("Opening ping page") self.application.switch_to_plugin(ping.Plugin) return if "dialog.nic.identify" in changes: ifname = self._model_extra["dialog.nic.ifname"] utils.network.NIC(ifname).identify() self.application.notice("Flashing lights now") return nameservers = [] dns_keys = ["dns[0]", "dns[1]"] if effective_changes.contains_any(dns_keys): nameservers += effective_model.values_for(dns_keys) if nameservers: self.logger.info("Setting new nameservers: %s" % nameservers) model = defaults.Nameservers() model.update(nameservers) txs += model.transaction() timeservers = [] ntp_keys = ["ntp[0]", "ntp[1]"] if effective_changes.contains_any(ntp_keys): timeservers += effective_model.values_for(ntp_keys) if timeservers: self.logger.info("Setting new timeservers: %s" % timeservers) model = defaults.Timeservers() model.update(timeservers) txs += model.transaction() hostname_keys = ["hostname"] if effective_changes.contains_any(hostname_keys): value = effective_model.values_for(hostname_keys) self.logger.info("Setting new hostname: %s" % value) model = defaults.Hostname() model.update(*value) txs += model.transaction() # For the NIC details dialog: if effective_changes.contains_any(self._nic_details_group): # If any networking related key was changed, reconfigure networking # Fetch the values for the nic keys, they are used as arguments args = effective_model.values_for(self._nic_details_group) txs += self._configure_nic(*args) if effective_changes.contains_any(self._bond_group): mb = defaults.NicBonding() mnet = defaults.Network() args = effective_model.values_for( ["bond.name", "bond.slaves.selected", "bond.options"]) self.logger.debug("args: %s" % args) mb.update(*args) txs += mb.transaction() txs += mnet.transaction() self._bond_dialog.close() progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run() if "dialog.nic.save" in changes: # Close the remaing details dialog self._nic_dialog.close() # Behaves like a page reload return self.ui_content()