def apply(self, args): responses = self.check(args) if responses is False: log.error("Check failed. Not applying") log.error("%s" % (responses)) return False self.save(responses) if utils.is_post_deployment(): self.parent.apply_tasks.add(self.update_dhcp) return True
def apply(self, args): responses = self.check(args) if responses is False: log.error("Check failed. Not applying") return False if utils.is_post_deployment(): self.parent.apply_tasks.add(self.apply_to_master) self.save(responses) return True
def make_resolv_conf(filename): if self.netsettings[self.parent.managediface]["addr"] != "": managediface_ip = self.netsettings[ self.parent.managediface]["addr"] else: managediface_ip = "127.0.0.1" with open(filename, 'w') as f: f.write("search {0}\n".format(responses['DNS_SEARCH'])) f.write("domain {0}\n".format(responses['DNS_DOMAIN'])) if utils.is_post_deployment(): f.write("nameserver {0}\n".format(managediface_ip)) for upstream_dns in responses['DNS_UPSTREAM'].split(','): f.write("nameserver {0}\n".format(upstream_dns))
def apply(self, args): responses = self.check(args) if responses is False: log.error("Check failed. Not applying") log.error("%s", responses) return False oldsettings = self.parent.settings.get('FEATURE_GROUPS') newsettings = self.save(responses).get('FEATURE_GROUPS') if utils.is_post_deployment() and oldsettings != newsettings: self.parent.apply_tasks.add(self.apply_to_nailgun) return True
def _save_only(self): if utils.is_post_deployment(): print( "Not updating settings when invoked during post-deployment" ".\nRun fuelmenu manually to make changes." ) sys.exit(0) success, module_name = self.global_save() if not success: msg = ("Problems with module '{}'." " Settings have not been saved.".format(module_name)) log.error(msg) sys.stderr.write(msg + '\n') sys.exit(1)
def test_is_post_deployment(self, utils_mock): utils_mock.return_value = "pre" data = utils.is_post_deployment() self.assertEqual(data, False)
def check(self, args): """Validates all fields have valid values and some sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() # Refresh networking to make sure IP matches self.getNetwork() # Get field information responses = dict() for index, fieldname in enumerate(self.fields): if fieldname != "blank" and "label" not in fieldname: responses[fieldname] = self.edits[index].get_edit_text() # Validate each field errors = [] # Set internal_{ipaddress,netmask,interface} responses["ADMIN_NETWORK/interface"] = self.activeiface responses["ADMIN_NETWORK/netmask"] = self.netsettings[ self.activeiface]["netmask"] responses["ADMIN_NETWORK/mac"] = self.netsettings[ self.activeiface]["mac"] responses["ADMIN_NETWORK/ipaddress"] = self.netsettings[ self.activeiface]["addr"] # ensure management interface is valid if responses["ADMIN_NETWORK/interface"] not in self.netsettings.keys(): errors.append("Management interface not valid") else: self.parent.footer.set_text("Scanning for DHCP servers. \ Please wait...") self.parent.refreshScreen() try: dhcptimeout = 5 dhcp_server_data = network.search_external_dhcp( self.activeiface, dhcptimeout) except network.NetworkException: log.warning('DHCP scan failed.') dhcp_server_data = [] num_dhcp = len(dhcp_server_data) if num_dhcp == 0: log.debug("No DHCP servers found") else: # Problem exists, but permit user to continue log.error("%s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) # Build dialog elements dhcp_info = [] dhcp_info.append(urwid.Padding( urwid.Text(("header", "!!! WARNING !!!")), "center")) dhcp_info.append(widget.TextLabel("You have selected an \ interface that contains one or more DHCP servers. This will impact \ provisioning. You should disable these DHCP servers before you continue, or \ else deployment will likely fail.")) dhcp_info.append(widget.TextLabel("")) for index, dhcp_server in enumerate(dhcp_server_data): dhcp_info.append(widget.TextLabel("DHCP Server #%s:" % (index + 1))) dhcp_info.append(widget.TextLabel("IP address: %-10s" % dhcp_server['server_ip'])) dhcp_info.append(widget.TextLabel("MAC address: %-10s" % dhcp_server['mac'])) dhcp_info.append(widget.TextLabel("")) dialog.display_dialog(self, urwid.Pile(dhcp_info), "DHCP Servers Found on %s" % self.activeiface) # Ensure pool start and end are on the same subnet as mgmt_if # Ensure mgmt_if has an IP first if len(self.netsettings[responses[ "ADMIN_NETWORK/interface"]]["addr"]) == 0: errors.append("Go to Interfaces to configure management \ interface first.") else: # Ensure ADMIN_NETWORK/interface is not running DHCP if self.netsettings[responses[ "ADMIN_NETWORK/interface"]]["bootproto"] == "dhcp": errors.append("%s is running DHCP. Change it to static " "first." % self.activeiface) # Ensure DHCP Pool Start and DHCP Pool are valid IPs try: if netaddr.valid_ipv4(responses[ "ADMIN_NETWORK/dhcp_pool_start"]): dhcp_start = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_pool_start"]) if not dhcp_start: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Pool Start") try: if netaddr.valid_ipv4(responses[ "ADMIN_NETWORK/dhcp_gateway"]): dhcp_gateway = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_gateway"]) if not dhcp_gateway: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Gateway") try: if netaddr.valid_ipv4(responses[ "ADMIN_NETWORK/dhcp_pool_end"]): dhcp_end = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_pool_end"]) if not dhcp_end: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Pool end") # Ensure pool start and end are in the same # subnet of each other netmask = self.netsettings[responses[ "ADMIN_NETWORK/interface" ]]["netmask"] if not network.inSameSubnet( responses["ADMIN_NETWORK/dhcp_pool_start"], responses["ADMIN_NETWORK/dhcp_pool_end"], netmask): errors.append("DHCP Pool start and end are not in the " "same subnet.") # Ensure pool start and end are in the right netmask mgmt_if_ipaddr = self.netsettings[responses[ "ADMIN_NETWORK/interface"]]["addr"] if network.inSameSubnet(responses[ "ADMIN_NETWORK/dhcp_pool_start"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Pool start does not match management" " network.") if network.inSameSubnet(responses[ "ADMIN_NETWORK/dhcp_pool_end"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Pool end does not match management " "network.") if network.inSameSubnet(responses[ "ADMIN_NETWORK/dhcp_gateway"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Gateway does not match management " "network.") self.parent.footer.set_text("Scanning for duplicate IP address" "es. Please wait...") # Bind arping to mgmt_if_ipaddr if it assigned assigned_ips = [v.get('addr') for v in self.netsettings.itervalues()] arping_bind = mgmt_if_ipaddr in assigned_ips if network.duplicateIPExists(mgmt_if_ipaddr, self.activeiface, arping_bind): errors.append("Duplicate host found with IP {0}.".format( mgmt_if_ipaddr)) # Extra checks for post-deployment changes if utils.is_post_deployment(): settings = self.parent.settings # Admin interface cannot change if self.activeiface != settings["ADMIN_NETWORK"]["interface"]: errors.append("Cannot change admin interface after deployment") # PXE network range must contain previous PXE network range old_range = network.range( settings["ADMIN_NETWORK"]["dhcp_pool_start"], settings["ADMIN_NETWORK"]["dhcp_pool_end"]) new_range = network.range( responses["ADMIN_NETWORK/dhcp_pool_start"], responses["ADMIN_NETWORK/dhcp_pool_end"]) if old_range[0] not in new_range: errors.append("DHCP range must contain previous values.") if old_range[-1] not in new_range: errors.append("DHCP range can only be increased after " "deployment.") if len(errors) > 0: log.error("Errors: %s %s" % (len(errors), errors)) ModuleHelper.display_failed_check_dialog(self, errors) return False else: self.parent.footer.set_text("No errors found.") return responses
def save_only(iface, settingsfile=consts.SETTINGS_FILE): from fuelmenu.common import pwgen import netifaces if utils.is_post_deployment(): print("Not updating settings when invoked during post-deployment.\n" "Run fuelmenu manually to make changes.") sys.exit(0) # Calculate and set Static/DHCP pool fields # Max IPs = net size - 2 (master node + bcast) try: ip = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr'] netmask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['netmask'] mac = netifaces.ifaddresses(iface)[netifaces.AF_LINK][0]['addr'] except Exception: print("Interface %s is missing either IP address or netmask" % (iface)) sys.exit(1) net_ip_list = network.getNetwork(ip, netmask) try: dhcp_pool = net_ip_list[1:] dynamic_start = str(dhcp_pool[0]) dynamic_end = str(dhcp_pool[-1]) except Exception: print("Unable to define DHCP pools") sys.exit(1) try: hostname, sep, domain = os.uname()[1].partition('.') except Exception: print("Unable to calculate hostname and domain") sys.exit(1) try: dhcptimeout = 5 dhcp_server_data = network.search_external_dhcp(iface, dhcptimeout) except errors.NetworkException: log.error("DHCP scan failed") dhcp_server_data = [] num_dhcp = len(dhcp_server_data) if num_dhcp == 0: log.debug("No DHCP servers found") else: # Problem exists, but permit user to continue log.error("%s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) print("ERROR: %s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) if network.duplicateIPExists(ip, iface): log.error("Duplicate host found with IP {0}".format(ip)) print("ERROR: Duplicate host found with IP {0}".format(ip)) default_settings_file = os.path.join(os.path.dirname(__file__), "settings.yaml") mos_version = utils.get_fuel_version() settings = settings_module.Settings() settings.load( default_settings_file, template_kwargs={"mos_version": mos_version}) settings.load(settingsfile, template_kwargs={"mos_version": mos_version}) settings_upd = \ { "ADMIN_NETWORK/interface": iface, "ADMIN_NETWORK/ipaddress": ip, "ADMIN_NETWORK/netmask": netmask, "ADMIN_NETWORK/mac": mac, "ADMIN_NETWORK/dhcp_pool_start": dynamic_start, "ADMIN_NETWORK/dhcp_pool_end": dynamic_end, "ADMIN_NETWORK/dhcp_gateway": ip, "HOSTNAME": hostname, "DNS_DOMAIN": domain, "DNS_SEARCH": domain, "astute/user": "******", "astute/password": pwgen.password(), "cobbler/user": "******", "cobbler/password": pwgen.password(), "keystone/admin_token": pwgen.password(), "keystone/ostf_user": "******", "keystone/ostf_password": pwgen.password(), "keystone/nailgun_user": "******", "keystone/nailgun_password": pwgen.password(), "keystone/monitord_user": "******", "keystone/monitord_password": pwgen.password(), "mcollective/user": "******", "mcollective/password": pwgen.password(), "postgres/keystone_dbname": "keystone", "postgres/keystone_user": "******", "postgres/keystone_password": pwgen.password(), "postgres/nailgun_dbname": "nailgun", "postgres/nailgun_user": "******", "postgres/nailgun_password": pwgen.password(), "postgres/ostf_dbname": "ostf", "postgres/ostf_user": "******", "postgres/ostf_password": pwgen.password(), "FUEL_ACCESS/user": "******", "FUEL_ACCESS/password": "******", } for setting in settings_upd.keys(): if "/" in setting: part1, part2 = setting.split("/") settings.setdefault(part1, {}) # Keep old values for passwords if already set if "password" in setting: settings[part1].setdefault(part2, settings_upd[setting]) else: settings[part1][part2] = settings_upd[setting] else: if "password" in setting: settings.setdefault(setting, settings_upd[setting]) else: settings[setting] = settings_upd[setting] # Write astute.yaml settings.write(outfn=settingsfile)
def save_only(iface, settingsfile=consts.SETTINGS_FILE): from fuelmenu.common import pwgen import netifaces if utils.is_post_deployment(): print("Not updating settings when invoked during post-deployment.\n" "Run fuelmenu manually to make changes.") sys.exit(0) # Calculate and set Static/DHCP pool fields # Max IPs = net size - 2 (master node + bcast) try: ip = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr'] netmask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['netmask'] mac = netifaces.ifaddresses(iface)[netifaces.AF_LINK][0]['addr'] except Exception: print("Interface %s is missing either IP address or netmask" % (iface)) sys.exit(1) net_ip_list = network.getNetwork(ip, netmask) try: dhcp_pool = net_ip_list[1:] dynamic_start = str(dhcp_pool[0]) dynamic_end = str(dhcp_pool[-1]) except Exception: print("Unable to define DHCP pools") sys.exit(1) try: hostname, sep, domain = os.uname()[1].partition('.') except Exception: print("Unable to calculate hostname and domain") sys.exit(1) try: dhcptimeout = 5 dhcp_server_data = network.search_external_dhcp(iface, dhcptimeout) except errors.NetworkException: log.error("DHCP scan failed") dhcp_server_data = [] num_dhcp = len(dhcp_server_data) if num_dhcp == 0: log.debug("No DHCP servers found") else: # Problem exists, but permit user to continue log.error("%s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) print("ERROR: %s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) if network.duplicateIPExists(ip, iface): log.error("Duplicate host found with IP {0}".format(ip)) print("ERROR: Duplicate host found with IP {0}".format(ip)) default_settings_file = os.path.join(os.path.dirname(__file__), "settings.yaml") mos_version = utils.get_fuel_version() settings = settings_module.Settings() settings.load( default_settings_file, template_kwargs={"mos_version": mos_version}) settings.load(settingsfile, template_kwargs={"mos_version": mos_version}) settings_upd = \ { "ADMIN_NETWORK/interface": iface, "ADMIN_NETWORK/ipaddress": ip, "ADMIN_NETWORK/netmask": netmask, "ADMIN_NETWORK/mac": mac, "ADMIN_NETWORK/dhcp_pool_start": dynamic_start, "ADMIN_NETWORK/dhcp_pool_end": dynamic_end, "ADMIN_NETWORK/dhcp_gateway": ip, "ADMIN_NETWORK/ssh_network": network.getCidr(ip, netmask), "HOSTNAME": hostname, "DNS_DOMAIN": domain, "DNS_SEARCH": domain, "astute/user": "******", "astute/password": pwgen.password(), "cobbler/user": "******", "cobbler/password": pwgen.password(), "keystone/admin_token": pwgen.password(), "keystone/ostf_user": "******", "keystone/ostf_password": pwgen.password(), "keystone/nailgun_user": "******", "keystone/nailgun_password": pwgen.password(), "keystone/monitord_user": "******", "keystone/monitord_password": pwgen.password(), "mcollective/user": "******", "mcollective/password": pwgen.password(), "postgres/keystone_dbname": "keystone", "postgres/keystone_user": "******", "postgres/keystone_password": pwgen.password(), "postgres/nailgun_dbname": "nailgun", "postgres/nailgun_user": "******", "postgres/nailgun_password": pwgen.password(), "postgres/ostf_dbname": "ostf", "postgres/ostf_user": "******", "postgres/ostf_password": pwgen.password(), "FUEL_ACCESS/user": "******", "FUEL_ACCESS/password": "******", } for setting in settings_upd.keys(): if "/" in setting: part1, part2 = setting.split("/") settings.setdefault(part1, {}) # Keep old values for passwords if already set if "password" in setting: settings[part1].setdefault(part2, settings_upd[setting]) else: settings[part1][part2] = settings_upd[setting] else: if "password" in setting: settings.setdefault(setting, settings_upd[setting]) else: settings[setting] = settings_upd[setting] # Write astute.yaml settings.write(outfn=settingsfile)
def check(self, args): """Validates all fields have valid values and some sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() # Refresh networking to make sure IP matches self.getNetwork() # Get field information responses = dict() for index, fieldname in enumerate(self.fields): if fieldname != "blank" and "label" not in fieldname: responses[fieldname] = self.edits[index].get_edit_text() # Validate each field errors = [] # Set internal_{ipaddress,netmask,interface} responses["ADMIN_NETWORK/interface"] = self.activeiface responses["ADMIN_NETWORK/netmask"] = self.netsettings[ self.activeiface]["netmask"] responses["ADMIN_NETWORK/mac"] = self.netsettings[ self.activeiface]["mac"] responses["ADMIN_NETWORK/ipaddress"] = self.netsettings[ self.activeiface]["addr"] # ensure management interface is valid if responses["ADMIN_NETWORK/interface"] not in self.netsettings.keys(): errors.append("Management interface not valid") else: self.parent.footer.set_text("Scanning for DHCP servers. \ Please wait...") self.parent.refreshScreen() try: dhcptimeout = 5 dhcp_server_data = network.search_external_dhcp( self.activeiface, dhcptimeout) except network.NetworkException: log.warning('DHCP scan failed.') dhcp_server_data = [] num_dhcp = len(dhcp_server_data) if num_dhcp == 0: log.debug("No DHCP servers found") else: # Problem exists, but permit user to continue log.error("%s foreign DHCP server(s) found: %s" % (num_dhcp, dhcp_server_data)) # Build dialog elements dhcp_info = [] dhcp_info.append( urwid.Padding(urwid.Text(("header", "!!! WARNING !!!")), "center")) dhcp_info.append( widget.TextLabel("You have selected an \ interface that contains one or more DHCP servers. This will impact \ provisioning. You should disable these DHCP servers before you continue, or \ else deployment will likely fail.")) dhcp_info.append(widget.TextLabel("")) for index, dhcp_server in enumerate(dhcp_server_data): dhcp_info.append( widget.TextLabel("DHCP Server #%s:" % (index + 1))) dhcp_info.append( widget.TextLabel("IP address: %-10s" % dhcp_server['server_ip'])) dhcp_info.append( widget.TextLabel("MAC address: %-10s" % dhcp_server['mac'])) dhcp_info.append(widget.TextLabel("")) dialog.display_dialog( self, urwid.Pile(dhcp_info), "DHCP Servers Found on %s" % self.activeiface) # Ensure pool start and end are on the same subnet as mgmt_if # Ensure mgmt_if has an IP first if len(self.netsettings[responses["ADMIN_NETWORK/interface"]] ["addr"]) == 0: errors.append("Go to Interfaces to configure management \ interface first.") else: # Ensure ADMIN_NETWORK/interface is not running DHCP if self.netsettings[responses["ADMIN_NETWORK/interface"]][ "bootproto"] == "dhcp": errors.append("%s is running DHCP. Change it to static " "first." % self.activeiface) # Ensure DHCP Pool Start and DHCP Pool are valid IPs try: if netaddr.valid_ipv4( responses["ADMIN_NETWORK/dhcp_pool_start"]): dhcp_start = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_pool_start"]) if not dhcp_start: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Pool Start") try: if netaddr.valid_ipv4( responses["ADMIN_NETWORK/dhcp_gateway"]): dhcp_gateway = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_gateway"]) if not dhcp_gateway: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Gateway") try: if netaddr.valid_ipv4( responses["ADMIN_NETWORK/dhcp_pool_end"]): dhcp_end = netaddr.IPAddress( responses["ADMIN_NETWORK/dhcp_pool_end"]) if not dhcp_end: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except Exception: errors.append("Invalid IP address for DHCP Pool end") # Ensure pool start and end are in the same # subnet of each other netmask = self.netsettings[ responses["ADMIN_NETWORK/interface"]]["netmask"] if not network.inSameSubnet( responses["ADMIN_NETWORK/dhcp_pool_start"], responses["ADMIN_NETWORK/dhcp_pool_end"], netmask): errors.append("DHCP Pool start and end are not in the " "same subnet.") # Ensure pool start and end are in the right netmask mgmt_if_ipaddr = self.netsettings[ responses["ADMIN_NETWORK/interface"]]["addr"] if network.inSameSubnet( responses["ADMIN_NETWORK/dhcp_pool_start"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Pool start does not match management" " network.") if network.inSameSubnet( responses["ADMIN_NETWORK/dhcp_pool_end"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Pool end does not match management " "network.") if network.inSameSubnet( responses["ADMIN_NETWORK/dhcp_gateway"], mgmt_if_ipaddr, netmask) is False: errors.append("DHCP Gateway does not match management " "network.") self.parent.footer.set_text("Scanning for duplicate IP address" "es. Please wait...") # Bind arping to mgmt_if_ipaddr if it assigned assigned_ips = [ v.get('addr') for v in self.netsettings.itervalues() ] arping_bind = mgmt_if_ipaddr in assigned_ips if network.duplicateIPExists(mgmt_if_ipaddr, self.activeiface, arping_bind): errors.append("Duplicate host found with IP {0}.".format( mgmt_if_ipaddr)) # Extra checks for post-deployment changes if utils.is_post_deployment(): settings = self.parent.settings # Admin interface cannot change if self.activeiface != settings["ADMIN_NETWORK"]["interface"]: errors.append("Cannot change admin interface after deployment") # PXE network range must contain previous PXE network range old_range = network.range( settings["ADMIN_NETWORK"]["dhcp_pool_start"], settings["ADMIN_NETWORK"]["dhcp_pool_end"]) new_range = network.range( responses["ADMIN_NETWORK/dhcp_pool_start"], responses["ADMIN_NETWORK/dhcp_pool_end"]) if old_range[0] not in new_range: errors.append("DHCP range must contain previous values.") if old_range[-1] not in new_range: errors.append("DHCP range can only be increased after " "deployment.") if len(errors) > 0: log.error("Errors: %s %s" % (len(errors), errors)) ModuleHelper.display_failed_check_dialog(self, errors) return False else: self.parent.footer.set_text("No errors found.") return responses