def _update_nailgun(self, settings): msg = "Apply changes to Nailgun" log.info(msg) self.parent.footer.set_text(msg) self.parent.refreshScreen() # TODO(mzhnichkov) this manifest apply twice(here and in feature # groups). Need to combine this calls result, msg = puppet.puppetApplyManifest(consts.PUPPET_NAILGUN) if not result: ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False data = { "gateway": settings["dhcp_gateway"], "ip_ranges": [ [settings["dhcp_pool_start"], settings["dhcp_pool_end"]] ] } try: NetworkGroup(consts.ADMIN_NETWORK_ID).set(data) except error.HTTPError as e: log.error(e.message) ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False return True
def load(self): settings = self.parent.settings ModuleHelper.load_to_defaults(settings, self.defaults) iface = settings.get("ADMIN_NETWORK", {}).get("interface") if iface in self.netsettings.keys(): self.activeiface = iface
def load(self): # Precedence of DNS information: # Class defaults, fuelmenu default YAML, astute.yaml, uname, # /etc/resolv.conf oldsettings = self.parent.settings # Read hostname from uname try: hostname, sep, domain = os.uname()[1].partition('.') oldsettings["HOSTNAME"] = hostname oldsettings["DNS_DOMAIN"] = domain oldsettings["DNS_SEARCH"] = domain except Exception: log.warning("Unable to look up system hostname") # Parse /etc/resolv.conf if it contains data search, domain, nameservers = self.getDNS() if search: oldsettings["DNS_SEARCH"] = search if domain: oldsettings["DNS_DOMAIN"] = domain if nameservers: oldsettings["DNS_UPSTREAM"] = nameservers ModuleHelper.load_to_defaults(oldsettings, self.defaults, ignoredparams=['TEST_DNS'])
def load(self): settings = self.parent.settings ModuleHelper.load_to_defaults(settings, self.defaults) iface = settings["ADMIN_NETWORK"]["interface"] if iface in self.netsettings.keys(): self.activeiface = iface
def radioSelectIface(self, current, state, user_data=None): """Update network details and display information.""" ### This makes no sense, but urwid returns the previous object. ### The previous object has True state, which is wrong. ### Somewhere in current.group a RadioButton is set to True. ### Our quest is to find it. for rb in current.group: if rb.get_label() == current.get_label(): continue if rb.base_widget.state is True: self.activeiface = rb.base_widget.get_label() break ModuleHelper.getNetwork(self) self.setNetworkDetails()
def radioSelectIface(self, current, state, user_data=None): """Update network details and display information.""" # This makes no sense, but urwid returns the previous object. # The previous object has True state, which is wrong. # Somewhere in current.group a RadioButton is set to True. # Our quest is to find it. for rb in current.group: if rb.get_label() == current.get_label(): continue if rb.base_widget.state is True: self.activeiface = rb.base_widget.get_label() break ModuleHelper.getNetwork(self) self.setNetworkDetails()
def save(self, responses): ## Generic settings start ## newsettings = ModuleHelper.save(self, responses) for setting in responses.keys(): if "/" in setting: part1, part2 = setting.split("/") if part1 not in newsettings: #We may not touch all settings, so copy oldsettings first newsettings[part1] = self.oldsettings[part1] newsettings[part1][part2] = responses[setting] else: newsettings[setting] = responses[setting] ## Generic settings end ## ## Need to calculate and netmask newsettings['ADMIN_NETWORK']['netmask'] = \ self.netsettings[newsettings['ADMIN_NETWORK']['interface']][ "netmask"] Settings().write(newsettings, defaultsfile=self.parent.defaultsettingsfile, outfn=self.parent.settingsfile) #Set oldsettings to reflect new settings self.oldsettings = newsettings #Update self.defaults for index, fieldname in enumerate(self.fields): if fieldname != "blank" and "label" not in fieldname: self.defaults[fieldname]['value'] = responses[fieldname] self.parent.footer.set_text("Changes saved successfully.")
def save(self, responses): newsettings = ModuleHelper.make_settings_from_responses(responses) self.parent.settings.merge(newsettings) self.parent.footer.set_text("Changes applied successfully.") # Reset fields self.cancel(None)
def save(self, responses): newsettings = ModuleHelper.make_settings_from_responses(responses) self.parent.settings.merge(newsettings) # Update self.defaults for index, fieldname in enumerate(self.fields): if fieldname != "blank": self.defaults[fieldname]['value'] = newsettings[fieldname]
def check(self, args): """Validate that all fields have valid values through sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() responses = self.responses errors = [] if not responses.get(BOOTSTRAP_SKIP_BUILD_KEY): errors.extend(self.check_apt_repos(responses)) if errors: log.error("Errors: %s", errors) ModuleHelper.display_failed_check_dialog(self, errors) return False else: self.parent.footer.set_text("No errors found.") return responses
def save(self, responses): newsettings = ModuleHelper.make_settings_from_responses(responses) self.parent.settings.merge(newsettings) log.debug('done saving servicepws') # Update defaults for index, fieldname in enumerate(self.fields): if fieldname != "blank" and fieldname in newsettings: self.defaults[fieldname]['value'] = newsettings[fieldname]
def load(self): # Precedence of DNS information: # Class defaults, fuelmenu default YAML, astute.yaml, uname, # /etc/resolv.conf oldsettings = self.parent.settings # Read hostname from uname try: hostname, sep, domain = os.uname()[1].partition('.') oldsettings["HOSTNAME"] = hostname oldsettings["DNS_DOMAIN"] = domain oldsettings["DNS_SEARCH"] = domain except Exception: log.warning("Unable to look up system hostname") oldsettings.update(self.resolv_conf_settings()) ModuleHelper.load_to_defaults(oldsettings, self.defaults, ignoredparams=['TEST_DNS'])
def apply(self, args): responses = self.check(args) if responses is False: self.log.error("Check failed. Not applying") self.parent.footer.set_text("Check failed. Not applying.") self.log.error("%s" % (responses)) return False self.parent.footer.set_text("Applying changes... (May take up to 20s)") puppetclasses = [] #If there is a gateway configured in /etc/sysconfig/network, unset it expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "") l3ifconfig = {'type': "resource", 'class': "l23network::l3::ifconfig", 'name': self.activeiface} if responses["onboot"].lower() == "no": params = {"ipaddr": "none", "gateway": ""} elif responses["bootproto"] == "dhcp": self.unset_gateway() if "dhcp_nowait" in responses.keys(): params = {"ipaddr": "dhcp", "dhcp_nowait": responses["dhcp_nowait"]} else: params = {"ipaddr": "dhcp"} else: cidr = network.netmaskToCidr(responses["netmask"]) params = {"ipaddr": "{0}/{1}".format(responses["ipaddr"], cidr), "check_by_ping": "none"} if len(responses["gateway"]) > 1: params["gateway"] = responses["gateway"] self.unset_gateway() l3ifconfig['params'] = params puppetclasses.append(l3ifconfig) self.log.info("Puppet data: %s" % (puppetclasses)) try: self.parent.refreshScreen() puppet.puppetApply(puppetclasses) ModuleHelper.getNetwork(self) gateway = self.get_default_gateway_linux() if gateway is None: gateway = "" self.fixEtcHosts() except Exception as e: self.log.error(e) self.parent.footer.set_text("Error applying changes. Check logs " "for details.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return False self.parent.footer.set_text("Changes successfully applied.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return True
def update_dhcp(self): settings = self.parent.settings.get("ADMIN_NETWORK") if not self._update_nailgun(settings): return False if os.path.exists(consts.HIERA_NET_SETTINGS): result, msg = self._update_hiera_dnsmasq(settings) else: result = self._update_dnsmasq(settings) if not result: ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False cobbler_sync = ["cobbler", "sync"] code, out, err = utils.execute(cobbler_sync) if code != 0: log.error(err) ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False return True
def _update_defaults(self, defaults, new_settings): for setting in defaults: try: new_value = ModuleHelper.get_setting(new_settings, setting) if BOOTSTRAP_REPOS_KEY == setting: defaults[setting]["value"] = \ self._parse_config_repo_list(new_value) continue defaults[setting]["value"] = new_value except KeyError: log.warning("no setting named {0} found.".format(setting)) except Exception as e: log.warning("unexpected error: {0}".format(e))
def save(self, responses): newsettings = ModuleHelper.make_settings_from_responses(responses) # Need to calculate and netmask newsettings['ADMIN_NETWORK']['netmask'] = \ self.netsettings[newsettings['ADMIN_NETWORK']['interface']][ "netmask"] # Update self.defaults for index, fieldname in enumerate(self.fields): if fieldname != "blank" and "label" not in fieldname: self.defaults[fieldname]['value'] = responses[fieldname] self.parent.settings.merge(newsettings) self.parent.footer.set_text("Changes saved successfully.")
def screenUI(self): return ModuleHelper.screenUI(self, self.header_content, self.fields, self.defaults, buttons_visible=False)
def apply(self, args): responses = self.check(args) if responses is False: self.log.error("Check failed. Not applying") self.parent.footer.set_text("Check failed. Not applying.") self.log.error("%s" % (responses)) return False self.parent.footer.set_text("Applying changes... (May take up to 20s)") puppetclasses = [] l3ifconfig = {'type': "resource", 'class': "l23network::l3::ifconfig", 'name': self.activeiface} if responses["onboot"].lower() == "no": params = {"ipaddr": "none"} elif responses["bootproto"] == "dhcp": if "dhcp_nowait" in responses.keys(): params = {"ipaddr": "dhcp", "dhcp_nowait": responses["dhcp_nowait"]} else: params = {"ipaddr": "dhcp"} else: params = {"ipaddr": responses["ipaddr"], "netmask": responses["netmask"], "check_by_ping": "none"} if len(responses["gateway"]) > 1: params["gateway"] = responses["gateway"] params["default_gateway"] = True elif network.inSameSubnet(self.get_default_gateway_linux(), responses["ipaddr"], responses["netmask"]): #If the current gateway is in the same subnet AND the user #sets the gateway to empty, unset gateway expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=") l3ifconfig['params'] = params puppetclasses.append(l3ifconfig) self.log.info("Puppet data: %s" % (puppetclasses)) try: #Gateway handling so DHCP will set gateway if responses["bootproto"] == "dhcp": expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=") self.parent.refreshScreen() puppet.puppetApply(puppetclasses) ModuleHelper.getNetwork(self) expr = '^GATEWAY=.*' gateway = self.get_default_gateway_linux() if gateway is None: gateway = "" replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=%s" % gateway) self.fixEtcHosts() except Exception as e: self.log.error(e) self.parent.footer.set_text("Error applying changes. Check logs " "for details.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return False self.parent.footer.set_text("Changes successfully applied.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return True
def cancel(self, button): ModuleHelper.cancel(self, button)
def save(self, responses): newsettings = ModuleHelper.make_settings_from_responses(responses) self.parent.settings.merge(newsettings) # Update self.defaults self._update_defaults(self.defaults, self.parent.settings)
def refresh(self): ModuleHelper.getNetwork(self) self.setNetworkDetails()
def apply(self, args): responses = self.check(args) if responses is False: self.log.error("Check failed. Not applying") self.parent.footer.set_text("Check failed. Not applying.") self.log.error("%s" % (responses)) return False self.parent.footer.set_text("Applying changes... (May take up to 20s)") # Build puppet resources to apply l23network puppet module to enable # network changes puppetclasses = [] # FIXME(mattymo): install_bondtool param does not work (LP#1541028) # The following 4 lines should be removed when fixed. disable_bond = { 'type': "literal", 'name': 'K_mod <| title == "bonding" |> {ensure => absent} '} puppetclasses.append(disable_bond) # If there is a gateway configured in /etc/sysconfig/network, unset it expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "") # Initialize l23network class for NetworkManager fixes l23network = {'type': "resource", 'class': "class", 'name': "l23network", 'params': {'install_bondtool': False}} puppetclasses.append(l23network) # Prepare l23network interface configuration l3ifconfig = {'type': "resource", 'class': "l23network::l3::ifconfig", 'name': self.activeiface} additionalclasses = [] if responses["onboot"].lower() == "no": params = {"ipaddr": "none", "gateway": ""} elif responses["bootproto"] == "dhcp": additionalclasses = self.clear_gateways_except(self.activeiface) params = {"ipaddr": "dhcp"} else: cidr = network.addr_in_cidr_notation(responses["ipaddr"], responses["netmask"]) params = {"ipaddr": cidr, "check_by_ping": "none"} if len(responses["gateway"]) > 1: params["gateway"] = responses["gateway"] additionalclasses = self.clear_gateways_except( self.activeiface) puppetclasses.extend(additionalclasses) l3ifconfig['params'] = params puppetclasses.append(l3ifconfig) self.log.info("Puppet data: %s" % (puppetclasses)) try: self.parent.refreshScreen() result = puppet.puppetApply(puppetclasses) if result is False: raise Exception("Puppet apply failed") ModuleHelper.getNetwork(self) gateway = self.get_default_gateway_linux() if gateway is None: gateway = "" self.fixEtcHosts() if responses['bootproto'] == 'dhcp': self.parent.dns_might_have_changed = True except Exception as e: self.log.error(e) self.parent.footer.set_text("Error applying changes. Check logs " "for details.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return False self.parent.footer.set_text("Changes successfully applied.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return True
def check(self, args): """Validate that all fields have valid values and sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() # Get field information responses = dict() for index, fieldname in enumerate(self.fields): if fieldname != "blank": responses[fieldname] = self.edits[index].get_edit_text() password = responses["FUEL_ACCESS/password"] # Validate each field errors = [] warnings = [] # Passwords must match if password != responses["CONFIRM_PASSWORD"] and \ password != self.defaults['FUEL_ACCESS/password']['value']: errors.append("Passwords do not match.") # Password must not be empty if len(password) == 0: errors.append("Password must not be empty.") # Password needs to be in ASCII character set try: if password.decode('ascii'): pass except UnicodeDecodeError: errors.append("Password contains non-ASCII characters.") # Passwords should be at least 8 symbols if len(password) < 8: warnings.append("8 symbols") # Passwords should contain at least one digit if re.search(r"\d", password) is None: warnings.append("one digit") if re.search(r"[A-Z]", password) is None: warnings.append("one uppercase letter") if re.search(r"[a-z]", password) is None: warnings.append("one lowercase letter") if re.search(r"[!#$%&'()*+,-./[\\\]^_`{|}~" + r'"]', password) is None: warnings.append("one special character") if len(errors) > 0: log.error("Errors: %s %s" % (len(errors), errors)) ModuleHelper.display_failed_check_dialog(self, errors) return False if len(warnings) > 0: self.parent.footer.set_text("Warning: Password should have " "at least %s." % (warnings[0])) else: self.parent.footer.set_text("No errors found.") # Remove confirm from responses so it isn't saved del responses["CONFIRM_PASSWORD"] return responses
def check(self, args): """Validate that all fields have valid values and sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() # Get field information responses = dict() for index, fieldname in enumerate(self.fields): if fieldname == "blank": pass elif fieldname == "ntpenabled": rb_group = self.edits[index].rb_group if rb_group[0].state: responses["ntpenabled"] = "Yes" else: responses["ntpenabled"] = "No" else: responses[fieldname] = self.edits[index].get_edit_text() # Validate each field errors = [] warnings = [] if responses['ntpenabled'] == "No": # Disabled NTP means passing no NTP servers to save method # Even though nodes will use Fuel Master, NTP[1,2,3] are empty so # Fuel Master can initialize itself as a time source. responses = { 'NTP1': "", 'NTP2': "", 'NTP3': ""} self.parent.footer.set_text("No errors found.") log.info("No errors found") return responses if all(map(lambda f: (len(responses[f]) == 0), self.fields)): pass # We will allow empty if user doesn't need external networking # and present a strongly worded warning # msg = "If you continue without NTP, you may have issues with "\ # + "deployment due to time synchronization issues. These "\ # + "problems are exacerbated in virtualized deployments." # dialog.display_dialog( # self, widget.TextLabel(msg), "Empty NTP Warning") del responses['ntpenabled'] for ntpfield, ntpvalue in responses.iteritems(): # NTP must be under 255 chars if len(ntpvalue) >= 255: errors.append("%s must be under 255 chars." % self.defaults[ntpfield]['label']) # NTP needs to have valid chars if re.search('[^a-zA-Z0-9-.]', ntpvalue): errors.append("%s contains illegal characters." % self.defaults[ntpfield]['label']) # ensure external NTP is valid if len(ntpvalue) > 0: # Validate first NTP address try: # Try to test NTP via ntpdate if not self.checkNTP(ntpvalue): warnings.append("%s unable to perform NTP." % self.defaults[ntpfield]['label']) except Exception: warnings.append("%s unable to sync time with server.: %s" % self.defaults[ntpfield]['label']) if len(errors) > 0: log.error("Errors: %s %s" % (len(errors), errors)) ModuleHelper.display_failed_check_dialog(self, errors) return False else: if len(warnings) > 0: msg = ["NTP configuration has the following warnings:"] msg.extend(warnings) msg.append("You may see errors during provisioning and " "in system logs. NTP errors are not fatal.") warning_msg = '\n'.join(str(line) for line in msg) dialog.display_dialog(self, widget.TextLabel(warning_msg), "NTP Warnings") log.warning(warning_msg) self.parent.footer.set_text("No errors found.") log.info("No errors found") return responses
def cancel(self, button): ModuleHelper.cancel(self, button) self.setNetworkDetails()
def get_default_gateway_linux(self): return ModuleHelper.get_default_gateway_linux()
def getNetwork(self): ModuleHelper.getNetwork(self)
def screenUI(self): screen = ModuleHelper.screenUI(self, self.header_content, self.fields, self.defaults) # set the radiobutton state (ModuleHelper handles only yes/no choice) self._ui_set_bootstrap_flavor() return screen
def _get_fresh_defaults(self): defaults = copy.copy(self.defaults) self._update_defaults( defaults, ModuleHelper.make_settings_from_responses(self.responses)) return defaults
def load(self): ModuleHelper.load_to_defaults( self.parent.settings, self.defaults, ignoredparams=['ntpenabled'])
def load(self): ModuleHelper.load_to_defaults( self.parent.settings, self.defaults, ignoredparams=['CONFIRM_PASSWORD'])
def check(self, args): """Validate that all fields have valid values and sanity checks.""" # Get field information responses = dict() self.parent.footer.set_text("Checking data...") for index, fieldname in enumerate(self.fields): if fieldname == "blank" or fieldname == "ifname": pass elif fieldname == "bootproto": rb_group = self.edits[index].rb_group if rb_group[0].state: responses["bootproto"] = "none" else: responses["bootproto"] = "dhcp" elif fieldname == "onboot": rb_group = self.edits[index].rb_group if rb_group[0].state: responses["onboot"] = "yes" else: responses["onboot"] = "no" else: responses[fieldname] = self.edits[index].get_edit_text() # Validate each field errors = [] # Check for the duplicate IP provided for k, v in six.iteritems(self.netsettings): if (k != self.activeiface and responses["ipaddr"] != '' and responses["ipaddr"] == v.get('addr')): errors.append("The same IP address {0} is assigned for " "interfaces '{1}' and '{2}'.".format( responses["ipaddr"], k, self.activeiface)) break if responses["onboot"] == "no": numactiveifaces = 0 for iface in self.netsettings: if self.netsettings[iface]['addr'] != "": numactiveifaces += 1 if numactiveifaces < 2 and \ self.netsettings[self.activeiface]['addr'] != "": # Block user because puppet l23network fails if all interfaces # are disabled. errors.append("Cannot disable all interfaces.") elif responses["bootproto"] == "dhcp": 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: self.log.warning("dhcp_checker failed to check on %s" % self.activeiface) dhcp_server_data = [] if len(dhcp_server_data) < 1: errors.append("No DHCP servers found. Cannot enable DHCP") # Check ipaddr, netmask, gateway only if static elif responses["bootproto"] == "none": try: if netaddr.valid_ipv4(responses["ipaddr"]): if not netaddr.IPAddress(responses["ipaddr"]): raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except (BadIPException, Exception): errors.append("Not a valid IP address: %s" % responses["ipaddr"]) try: if netaddr.valid_ipv4(responses["netmask"]): netmask = netaddr.IPAddress(responses["netmask"]) if netmask.is_netmask is False: raise BadIPException("Not a valid IP address") else: raise BadIPException("Not a valid IP address") except (BadIPException, Exception): errors.append("Not a valid netmask: %s" % responses["netmask"]) try: if len(responses["gateway"]) > 0: # Check if gateway is valid if netaddr.valid_ipv4(responses["gateway"]) is False: raise BadIPException("Gateway IP address is not valid") # Check if gateway is in same subnet if network.inSameSubnet(responses["ipaddr"], responses["gateway"], responses["netmask"]) is False: raise BadIPException("Gateway IP is not in same " "subnet as IP address") except (BadIPException, Exception) as e: errors.append(e) self.parent.footer.set_text("Scanning for duplicate IP address..") if len(responses["ipaddr"]) > 0: if self.netsettings[self.activeiface]['link'].upper() != "UP": try: network.upIface(self.activeiface) except NetworkException as e: errors.append("Cannot activate {0} to check for " "duplicate IP.".format(self.activeiface)) # Bind arping to requested IP if it's already assigned assigned_ips = [v.get('addr') for v in self.netsettings.itervalues()] arping_bind = responses["ipaddr"] in assigned_ips if network.duplicateIPExists(responses["ipaddr"], self.activeiface, arping_bind): errors.append("Duplicate host found with IP {0}.".format( responses["ipaddr"])) if len(errors) > 0: self.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 _generate_screen_by_defaults(self, defaults): screen = ModuleHelper.screenUI(self, self.header_content, self.fields, defaults) return screen
def screenUI(self): return ModuleHelper.screenUI(self, self.header_content, self.fields, self.defaults, showallbuttons=True)
def screenUI(self): return ModuleHelper.screenUI(self, self.header_content, self.fields, self.defaults, show_all_buttons=True)
def load(self): ModuleHelper.load_to_defaults(self.parent.settings, self.defaults)
def load(self): ModuleHelper.load_to_defaults(self.parent.settings, self.defaults, ignoredparams=['CONFIRM_PASSWORD'])
def apply(self, args): responses = self.check(args) if responses is False: self.log.error("Check failed. Not applying") self.parent.footer.set_text("Check failed. Not applying.") self.log.error("%s" % (responses)) return False self.parent.footer.set_text("Applying changes... (May take up to 20s)") puppetclasses = [] l3ifconfig = { 'type': "resource", 'class': "l23network::l3::ifconfig", 'name': self.activeiface } if responses["onboot"].lower() == "no": params = {"ipaddr": "none"} elif responses["bootproto"] == "dhcp": if "dhcp_nowait" in responses.keys(): params = { "ipaddr": "dhcp", "dhcp_nowait": responses["dhcp_nowait"] } else: params = {"ipaddr": "dhcp"} else: params = { "ipaddr": responses["ipaddr"], "netmask": responses["netmask"], "check_by_ping": "none" } if len(responses["gateway"]) > 1: params["gateway"] = responses["gateway"] params["default_gateway"] = True elif network.inSameSubnet(self.get_default_gateway_linux(), responses["ipaddr"], responses["netmask"]): #If the current gateway is in the same subnet AND the user #sets the gateway to empty, unset gateway expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=") l3ifconfig['params'] = params puppetclasses.append(l3ifconfig) self.log.info("Puppet data: %s" % (puppetclasses)) try: #Gateway handling so DHCP will set gateway if responses["bootproto"] == "dhcp": expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=") self.parent.refreshScreen() puppet.puppetApply(puppetclasses) ModuleHelper.getNetwork(self) expr = '^GATEWAY=.*' gateway = self.get_default_gateway_linux() if gateway is None: gateway = "" replace.replaceInFile("/etc/sysconfig/network", expr, "GATEWAY=%s" % gateway) self.fixEtcHosts() except Exception as e: self.log.error(e) self.parent.footer.set_text("Error applying changes. Check logs " "for details.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return False self.parent.footer.set_text("Changes successfully applied.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return True
def screenUI(self): return ModuleHelper.screenUI(self, self.header_content, self.fields, self.defaults)
def check(self, args): """Validate that all fields have valid values through sanity checks.""" self.parent.footer.set_text("Checking data...") self.parent.refreshScreen() # Get field information responses = dict() for index, fieldname in enumerate(self.fields): if fieldname == "blank": pass else: responses[fieldname] = self.edits[index].get_edit_text() # Validate each field errors = [] # hostname must be under 60 chars if len(responses["HOSTNAME"]) >= 60: errors.append("Hostname must be under 60 chars.") # hostname must not be empty if len(responses["HOSTNAME"]) == 0: errors.append("Hostname must not be empty.") # hostname needs to have valid chars if re.search('[^a-z0-9-]', responses["HOSTNAME"]): errors.append( "Hostname must contain only alphanumeric and hyphen.") # domain must be under 180 chars if len(responses["DNS_DOMAIN"]) >= 180: errors.append("Domain must be under 180 chars.") # domain must not be empty if len(responses["DNS_DOMAIN"]) == 0: errors.append("Domain must not be empty.") # domain needs to have valid chars if re.match('[^a-z0-9-.]', responses["DNS_DOMAIN"]): errors.append( "Domain must contain only alphanumeric, period and hyphen.") # ensure external DNS is valid if len(responses["DNS_UPSTREAM"]) == 0: # We will allow empty if user doesn't need external networking # and present a strongly worded warning msg = "If you continue without DNS, you may not be able to access"\ + " external data necessary for installation needed for " \ + "some OpenStack Releases." dialog.display_dialog(self, widget.TextLabel(msg), "Empty DNS Warning") else: upstream_nameservers = responses["DNS_UPSTREAM"].split(',') # external DNS must contain only numbers, periods, and commas # Needs more serious ip address checking if re.match('[^0-9.,]', responses["DNS_UPSTREAM"]): errors.append( "External DNS must contain only IP addresses and commas.") # Ensure local IPs are not in upstream list host_ips = network.list_host_ip_addresses() for nameserver in upstream_nameservers: if nameserver in host_ips: errors.append("Host IPs cannot be in upstream DNS.") break if len(upstream_nameservers) > 3: errors.append( "Unable to specify more than 3 External DNS addresses.") # ensure test DNS name isn't empty if len(responses["TEST_DNS"]) == 0: errors.append("Test DNS must not be empty.") # Validate first IP address for nameserver in upstream_nameservers: if not netaddr.valid_ipv4(nameserver): errors.append("Not a valid IP address for DNS server:" " {0}".format(nameserver)) # Try to resolve with first address if not self.checkDNS(upstream_nameservers[0]): # Warn user that DNS resolution failed, but continue msg = "Unable to resolve %s.\n\n" % responses['TEST_DNS']\ + "Possible causes for DNS failure include:\n"\ + "* Invalid DNS server\n"\ + "* Invalid gateway\n"\ + "* Other networking issue\n\n"\ + "Fuel Setup can save this configuration, but "\ + "you may want to correct your settings." dialog.display_dialog(self, widget.TextLabel(msg), "DNS Failure Warning") self.parent.refreshScreen() 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 getDHCP(self, iface): return ModuleHelper.getDHCP(iface)
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 apply(self, args): responses = self.check(args) if responses is False: self.log.error("Check failed. Not applying") self.parent.footer.set_text("Check failed. Not applying.") self.log.error("%s" % (responses)) return False self.parent.footer.set_text("Applying changes... (May take up to 20s)") puppetclasses = [] #If there is a gateway configured in /etc/sysconfig/network, unset it expr = '^GATEWAY=.*' replace.replaceInFile("/etc/sysconfig/network", expr, "") l3ifconfig = { 'type': "resource", 'class': "l23network::l3::ifconfig", 'name': self.activeiface } if responses["onboot"].lower() == "no": params = {"ipaddr": "none"} elif responses["bootproto"] == "dhcp": self.unset_gateway() if "dhcp_nowait" in responses.keys(): params = { "ipaddr": "dhcp", "dhcp_nowait": responses["dhcp_nowait"] } else: params = {"ipaddr": "dhcp"} else: cidr = network.netmaskToCidr(responses["netmask"]) params = { "ipaddr": "{0}/{1}".format(responses["ipaddr"], cidr), "check_by_ping": "none" } if len(responses["gateway"]) > 1: params["gateway"] = responses["gateway"] self.unset_gateway() l3ifconfig['params'] = params puppetclasses.append(l3ifconfig) self.log.info("Puppet data: %s" % (puppetclasses)) try: self.parent.refreshScreen() puppet.puppetApply(puppetclasses) ModuleHelper.getNetwork(self) gateway = self.get_default_gateway_linux() if gateway is None: gateway = "" self.fixEtcHosts() except Exception as e: self.log.error(e) self.parent.footer.set_text("Error applying changes. Check logs " "for details.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return False self.parent.footer.set_text("Changes successfully applied.") ModuleHelper.getNetwork(self) self.setNetworkDetails() return True