Esempio n. 1
0
    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
            else:
                responses[fieldname] = self.edits[index].get_edit_text()

        ###Validate each field
        errors = []

        if all(map(lambda f: (len(responses[f]) == 0), self.fields)):
            #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")

        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):
                        errors.append("%s unable to perform NTP."
                                      % self.defaults[ntpfield]['label'])
                except Exception as e:
                    errors.append(e)
                    errors.append("%s unable to perform NTP: %s"
                                  % self.defaults[ntpfield]['label'])

        if len(errors) > 0:
            self.parent.footer.set_text(
                "Errors: %s First error: %s" % (len(errors), errors[0]))
            log.warning("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            log.info("No errors found")
            return responses
Esempio n. 2
0
    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
            else:
                responses[fieldname] = self.edits[index].get_edit_text()

        ###Validate each field
        errors = []

        if all(map(lambda f: (len(responses[f]) == 0), self.fields)):
            #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")

        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):
                        errors.append("%s unable to perform NTP." %
                                      self.defaults[ntpfield]['label'])
                except Exception as e:
                    errors.append(e)
                    errors.append("%s unable to perform NTP: %s" %
                                  self.defaults[ntpfield]['label'])

        if len(errors) > 0:
            self.parent.footer.set_text("Errors: %s First error: %s" %
                                        (len(errors), errors[0]))
            log.warning("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            log.info("No errors found")
            return responses
Esempio n. 3
0
 def save(self):
     results, modulename = self.parent.global_save()
     if results:
         self.parent.footer.set_text("All changes saved successfully!")
         return True
     else:
         #show pop up with more details
         msg = "ERROR: Module %s failed to save. Go back" % (modulename)\
               + " and fix any mistakes or choose Quit without Saving."
         dialog.display_dialog(self, widget.TextLabel(msg),
                               "Error saving changes!")
         return False
Esempio n. 4
0
    def test_display_dialog(self, m_pile, m_dialog):
        original_widget = self.object.parent.mainloop.widget
        self.assertEqual(
            m_dialog.return_value, dialog.display_dialog(self.object, self.body, self.title, self.escape_key)
        )

        m_pile.assert_called_once_with([self.body])
        m_dialog.assert_called_once_with(
            self.title, m_pile.return_value, self.escape_key, original_widget, self.object.parent.mainloop
        )
        self.assertEqual(self.object.parent.mainloop.widget, m_dialog.return_value)
Esempio n. 5
0
    def check(self, args):
        self.parent.footer.set_text("Checking data...")
        self.parent.refreshScreen()

        responses = dict()
        for index, fieldname in enumerate(self.fields):
            if fieldname != helper.BLANK_KEY:
                responses[fieldname] = self.edits[index].get_edit_text()

        ssh_network = responses[SSH_NETWORK]
        errors = []

        if len(ssh_network) == 0:
            self.parent.footer.set_text("Address is empty, "
                                        "will be changed to 0.0.0.0/0")
            log.warning("Empty address, changed to 0.0.0.0/0")
            responses[SSH_NETWORK] = "0.0.0.0/0"

            msg = "If you continue without the address, you may able to"\
                  + " access the Fuel through SSH from any network. The"\
                  + " address will be changed to 0.0.0.0/0. This can lead"\
                  + " to the security issues."

            dialog.display_dialog(
                self, widget.TextLabel(msg), "Empty Address Warning")

        else:
            if not network.getCidrSize(ssh_network):
                errors.append("Incorrect network address format: {0}."
                              .format(ssh_network))

        if len(errors) > 0:
            log.error("Errors: %s %s", len(errors), errors)
            helper.ModuleHelper.display_failed_check_dialog(self, errors)
            return False

        self.parent.footer.set_text("No errors found.")
        return responses
Esempio n. 6
0
    def check(self, args):
        self.parent.footer.set_text("Checking data...")
        self.parent.refreshScreen()

        responses = dict()
        for index, fieldname in enumerate(self.fields):
            if fieldname != helper.BLANK_KEY:
                responses[fieldname] = self.edits[index].get_edit_text()

        ssh_network = responses[SSH_NETWORK]
        errors = []

        if len(ssh_network) == 0:
            self.parent.footer.set_text("Address is empty, "
                                        "will be changed to 0.0.0.0/0")
            log.warning("Empty address, changed to 0.0.0.0/0")
            responses[SSH_NETWORK] = "0.0.0.0/0"

            msg = "If you continue without the address, you may able to"\
                  + " access the Fuel through SSH from any network. The"\
                  + " address will be changed to 0.0.0.0/0. This can lead"\
                  + " to the security issues."

            dialog.display_dialog(self, widget.TextLabel(msg),
                                  "Empty Address Warning")

        else:
            if not network.getCidrSize(ssh_network):
                errors.append("Incorrect network address format: {0}.".format(
                    ssh_network))

        if len(errors) > 0:
            log.error("Errors: %s %s", len(errors), errors)
            helper.ModuleHelper.display_failed_check_dialog(self, errors)
            return False

        self.parent.footer.set_text("No errors found.")
        return responses
    def test_display_dialog(self, m_pile, m_dialog):
        original_widget = self.object.parent.mainloop.widget
        self.assertEqual(
            m_dialog.return_value,
            dialog.display_dialog(
                self.object, self.body, self.title, self.escape_key)
        )

        m_pile.assert_called_once_with([self.body])
        m_dialog.assert_called_once_with(
            self.title, m_pile.return_value, self.escape_key,
            original_widget, self.object.parent.mainloop)
        self.assertEqual(
            self.object.parent.mainloop.widget, m_dialog.return_value)
Esempio n. 8
0
    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()
        ntp_enabled = False

        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:
                    ntp_enabled = True
            else:
                responses[fieldname] = self.edits[index].get_edit_text()

        if self.parent.save_only:
            return responses

        # Validate each field
        errors = []
        warnings = []
        if not ntp_enabled:
            # 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

        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.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
Esempio n. 9
0
 def display_dialog(cls, modobj, error_msg, title):
     body = widget.TextLabel(error_msg)
     dialog.display_dialog(modobj, body, title)
Esempio n. 10
0
    def check(self, args):
        """Validate that all fields have valid values and some sanity checks"""
        self.parent.footer.set_text("Checking data...")
        self.parent.refreshScreen()
        #Get field information
        responses = dict()

        for index, fieldname in enumerate(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."

            diag = dialog.display_dialog(
                self, TextLabel(msg), "Empty DNS Warning")

        else:
            #external DNS must contain only numbers, periods, and commas
            #TODO: 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 test DNS name isn't empty
            if len(responses["TEST_DNS"]) == 0:
                errors.append("Test DNS must not be empty.")
            #Validate first IP address
            try:
                if netaddr.valid_ipv4(responses["DNS_UPSTREAM"].split(",")[0]):
                    DNS_UPSTREAM = responses["DNS_UPSTREAM"].split(",")[0]
                else:
                    errors.append("Not a valid IP address for External DNS: %s"
                                  % responses["DNS_UPSTREAM"])

                #Try to resolve with first address
                if not self.checkDNS(DNS_UPSTREAM):
                    errors.append("IP %s unable to resolve host."
                                  % DNS_UPSTREAM)
            except Exception, e:

                errors.append(e)
                errors.append("Not a valid IP address for External DNS: %s"
                              % responses["DNS_UPSTREAM"])
Esempio n. 11
0
    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"] = "dhcp"
                else:
                    responses["bootproto"] = "none"
            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 = []
        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 intefaces
                #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
                with timeout.run_with_timeout(dhcp_checker.utils.IfaceState,
                                              [self.activeiface],
                                              timeout=dhcptimeout) as iface:
                    dhcp_server_data = timeout.run_with_timeout(
                        dhcp_checker.api.check_dhcp_on_eth,
                        [iface, dhcptimeout],
                        timeout=dhcptimeout)
            except (KeyboardInterrupt, timeout.TimeoutError):
                self.log.debug("DHCP scan timed out")
                self.log.warning(traceback.format_exc())
                dhcp_server_data = []
            except Exception:
                self.log.warning("dhcp_checker failed to check on %s" %
                                 self.activeiface)
                dhcp_server_data = []
                responses["dhcp_nowait"] = False

            if len(dhcp_server_data) < 1:
                self.log.debug("No DHCP servers found. Warning user about "
                               "dhcp_nowait.")
                #Build dialog elements
                dhcp_info = []
                dhcp_info.append(
                    urwid.Padding(urwid.Text(("header", "!!! WARNING !!!")),
                                  "center"))
                dhcp_info.append(
                    widget.TextLabel(
                        "Unable to detect DHCP server" + "on interface %s." %
                        (self.activeiface) +
                        "\nDHCP will be set up in the background, " +
                        "but may not receive an IP address. You may " +
                        "want to check your DHCP connection manually " +
                        "using the Shell Login menu to the left."))
                dialog.display_dialog(
                    self, urwid.Pile(dhcp_info),
                    "DHCP Servers Found on %s" % self.activeiface)
                self.parent.refreshScreen()
                responses["dhcp_nowait"] = True
        #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))
                if network.duplicateIPExists(responses["ipaddr"],
                                             self.activeiface):
                    errors.append("Duplicate host found with IP {0}.".format(
                        responses["ipaddr"]))
        if len(errors) > 0:
            self.parent.footer.set_text("Error: %s" % (errors[0]))
            self.log.error("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
Esempio n. 12
0
    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
Esempio n. 13
0
    def main(self):
        text_header = (u"Fuel %s setup "
                       u"Use Up/Down/Left/Right to navigate.  F8 exits. "
                       u"Remember to save your changes."
                       % self.version)
        text_footer = (u"Status messages go here.")

        # Top and bottom lines of frame
        self.header = urwid.AttrWrap(urwid.Text(text_header), 'header')
        self.footer = urwid.AttrWrap(urwid.Text(text_footer), 'footer')

        self.children = []
        for clsobj in modules.__all__:
            modobj = clsobj(self)
            self.children.append(modobj)

        self.choices = [m.name for m in self.children]

        if len(self.children) == 0:
            sys.exit(1)

        # Build list of choices excluding visible
        self.visiblechoices = []
        for child, choice in zip(self.children, self.choices):
            if child.visible:
                self.visiblechoices.append(choice)

        self.menuitems = self.menu(u'Menu', self.visiblechoices)
        menufill = urwid.Filler(self.menuitems, 'top', 40)
        self.menubox = urwid.BoxAdapter(menufill, 40)

        self.child = self.children[0]
        self.childpage = self.child.screenUI()
        self.childfill = urwid.Filler(self.childpage, 'top', 22)
        self.childbox = urwid.BoxAdapter(self.childfill, 22)
        self.cols = urwid.Columns(
            [
                ('fixed', 20, urwid.Pile([
                    urwid.AttrMap(self.menubox, 'body'),
                    urwid.Divider(" ")])),
                ('weight', 3, urwid.Pile([
                    urwid.Divider(" "),
                    self.childbox,
                    urwid.Divider(" ")]))
            ], 1)
        self.listwalker = urwid.SimpleListWalker([self.cols])
        # self.listwalker = urwid.TreeWalker([self.cols])
        self.listbox = urwid.ListBox(self.listwalker)
        # listbox = urwid.ListBox(urwid.SimpleListWalker(listbox_content))

        self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'),
                                 header=self.header, footer=self.footer)

        palette = \
            [
                ('body', 'black', 'light gray', 'standout'),
                ('header', 'light red', 'light gray', 'bold'),
                ('footer', 'light red', 'light gray', 'bold'),
                ('menu', 'black', 'light gray', 'bold'),
                ('menuf', 'white', 'dark red', 'bold'),
                ('important', 'light red', 'light gray',
                    ('standout', 'underline')),
                ('editlbl', 'black', 'light gray'),
                ('editfc', 'light gray', 'black', 'bold'),
                ('editbx', 'light gray', 'dark gray'),
                ('buttn', 'white', 'dark green', 'bold'),
                ('buttnf', 'light gray', 'dark green', 'bold'),
            ]

        # use appropriate Screen class
        if urwid.web_display.is_web_request():
            self.screen = urwid.web_display.Screen()
        else:
            self.screen = urwid.raw_display.Screen()

        def unhandled(key):
            if key == 'f8':
                raise urwid.ExitMainLoop()
            if key == 'shift tab':
                self.child.walker.tab_prev()
            if key == 'tab':
                self.child.walker.tab_next()

        self.mainloop = urwid.MainLoop(self.frame, palette, self.screen,
                                       unhandled_input=unhandled)
        # Initialize each module completely before any events are handled
        for child in reversed(self.children):
            self.setChildScreen(name=child.name)

        signal.signal(signal.SIGUSR1, self.sigusr1_handler)
        msg = "It is recommended to change default administrator password."

        dialog.display_dialog(self.child, widget.TextLabel(msg), "WARNING!")

        run_delegate = self._save_only if self.save_only else self.mainloop.run
        run_delegate()
Esempio n. 14
0
    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(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:
            #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 test DNS name isn't empty
            if len(responses["TEST_DNS"]) == 0:
                errors.append("Test DNS must not be empty.")
            #Validate first IP address
            try:
                if netaddr.valid_ipv4(responses["DNS_UPSTREAM"].split(",")[0]):
                    DNS_UPSTREAM = responses["DNS_UPSTREAM"].split(",")[0]
                else:
                    errors.append("Not a valid IP address for External DNS: %s"
                                  % responses["DNS_UPSTREAM"])

                #Try to resolve with first address
                if not self.checkDNS(DNS_UPSTREAM):
                    #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()
            except Exception:
                errors.append("Not a valid IP address for External DNS: %s"
                              % responses["DNS_UPSTREAM"])

        if len(errors) > 0:
            self.parent.footer.set_text("Error: %s" % (errors[0]))
            log.error("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
Esempio n. 15
0
    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()

            ###Start DHCP check on this interface
            #dhcp_server_data=[{'server_id': '192.168.200.2', 'iface': 'eth2',
            #                   'yiaddr': '192.168.200.15', 'mac':
            #                '52:54:00:12:35:02', 'server_ip': '192.168.200.2',
            #                   'dport': 67, 'message': 'offer',
            #                   'gateway': '0.0.0.0'}]
            try:
                dhcptimeout = 5
                default = []
                with timeout.run_with_timeout(dhcp_checker.utils.IfaceState,
                                              [self.activeiface],
                                              timeout=dhcptimeout) as iface:
                    dhcp_server_data = timeout.run_with_timeout(
                        dhcp_checker.api.check_dhcp_on_eth,
                        [iface, dhcptimeout], timeout=dhcptimeout,
                        default=default)
            except (KeyboardInterrupt, timeout.TimeoutError):
                log.debug("DHCP scan timed out")
                log.warning(traceback.format_exc())
                dhcp_server_data = default

            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...")
                if network.duplicateIPExists(mgmt_if_ipaddr, self.activeiface):
                    errors.append("Duplicate host found with IP {0}.".format(
                        mgmt_if_ipaddr))

        if len(errors) > 0:
            self.parent.footer.set_text("Error: %s" % (errors[0]))
            log.error("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
Esempio n. 16
0
    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
Esempio n. 17
0
    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()

        if self.parent.save_only:
            return responses

        # 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.ModuleHelper.display_failed_check_dialog(self, errors)
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
Esempio n. 18
0
    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
Esempio n. 19
0
    def main(self):
        text_header = (u"Fuel %s setup "
                       u"Use Up/Down/Left/Right to navigate.  F8 exits. "
                       u"Remember to save your changes."
                       % self.version)
        text_footer = (u"Status messages go here.")

        # Top and bottom lines of frame
        self.header = urwid.AttrWrap(urwid.Text(text_header), 'header')
        self.footer = urwid.AttrWrap(urwid.Text(text_footer), 'footer')

        self.children = []
        for clsobj in modules.__all__:
            modobj = clsobj(self)
            self.children.append(modobj)

        self.choices = [m.name for m in self.children]

        if len(self.children) == 0:
            sys.exit(1)

        # Build list of choices excluding visible
        self.visiblechoices = []
        for child, choice in zip(self.children, self.choices):
            if child.visible:
                self.visiblechoices.append(choice)

        self.menuitems = self.menu(u'Menu', self.visiblechoices)
        menufill = urwid.Filler(self.menuitems, 'top', 40)
        self.menubox = urwid.BoxAdapter(menufill, 40)

        self.child = self.children[0]
        self.childpage = self.child.screenUI()
        self.childfill = urwid.Filler(self.childpage, 'top', 22)
        self.childbox = urwid.BoxAdapter(self.childfill, 22)
        self.cols = urwid.Columns(
            [
                ('fixed', 20, urwid.Pile([
                    urwid.AttrMap(self.menubox, 'body'),
                    urwid.Divider(" ")])),
                ('weight', 3, urwid.Pile([
                    urwid.Divider(" "),
                    self.childbox,
                    urwid.Divider(" ")]))
            ], 1)
        self.listwalker = urwid.SimpleListWalker([self.cols])
        # self.listwalker = urwid.TreeWalker([self.cols])
        self.listbox = urwid.ListBox(self.listwalker)
        # listbox = urwid.ListBox(urwid.SimpleListWalker(listbox_content))

        self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'),
                                 header=self.header, footer=self.footer)

        palette = \
            [
                ('body', 'black', 'light gray', 'standout'),
                ('header', 'light red', 'light gray', 'bold'),
                ('footer', 'light red', 'light gray', 'bold'),
                ('menu', 'black', 'light gray', 'bold'),
                ('menuf', 'white', 'dark red', 'bold'),
                ('important', 'light red', 'light gray',
                    ('standout', 'underline')),
                ('editlbl', 'black', 'light gray'),
                ('editfc', 'light gray', 'black', 'bold'),
                ('editbx', 'light gray', 'dark gray'),
                ('buttn', 'white', 'dark green', 'bold'),
                ('buttnf', 'light gray', 'dark green', 'bold'),
            ]

        # use appropriate Screen class
        if urwid.web_display.is_web_request():
            self.screen = urwid.web_display.Screen()
        else:
            self.screen = urwid.raw_display.Screen()

        def unhandled(key):
            if key == 'f8':
                raise urwid.ExitMainLoop()
            if key == 'shift tab':
                self.child.walker.tab_prev()
            if key == 'tab':
                self.child.walker.tab_next()

        self.mainloop = urwid.MainLoop(self.frame, palette, self.screen,
                                       unhandled_input=unhandled)
        # Initialize each module completely before any events are handled
        for child in reversed(self.children):
            self.setChildScreen(name=child.name)

        signal.signal(signal.SIGUSR1, self.handle_sigusr1)

        dialog.display_dialog(
            self.child,
            widget.TextLabel("It is highly recommended to change default "
                             "admin password."),
            "WARNING!")
        if not self.save_only:
            self.mainloop.run()
        else:
            self._save_only()
Esempio n. 20
0
 def display_dialog(cls, modobj, error_msg, title):
     body = widget.TextLabel(error_msg)
     dialog.display_dialog(modobj, body, title)
Esempio n. 21
0
    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
            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:
            self.parent.footer.set_text(
                "Errors: %s First error: %s" % (len(errors), errors[0]))
            log.error("Errors: %s %s" % (len(errors), 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
Esempio n. 22
0
    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()
        ntp_enabled = False

        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:
                    ntp_enabled = True
            else:
                responses[fieldname] = self.edits[index].get_edit_text()

        if self.parent.save_only:
            return responses

        # Validate each field
        errors = []
        warnings = []
        if not ntp_enabled:
            # 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

        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.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
Esempio n. 23
0
    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(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"] = "dhcp"
                else:
                    responses["bootproto"] = "none"
            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 = []
        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 intefaces
                #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
                with timeout.run_with_timeout(dhcp_checker.utils.IfaceState,
                                              [self.activeiface],
                                              timeout=dhcptimeout) as iface:
                    dhcp_server_data = timeout.run_with_timeout(
                        dhcp_checker.api.check_dhcp_on_eth,
                        [iface, dhcptimeout], timeout=dhcptimeout)
            except (KeyboardInterrupt, timeout.TimeoutError):
                self.log.debug("DHCP scan timed out")
                self.log.warning(traceback.format_exc())
                dhcp_server_data = []
            except Exception:
                self.log.warning("dhcp_checker failed to check on %s"
                                 % self.activeiface)
                dhcp_server_data = []
                responses["dhcp_nowait"] = False

            if len(dhcp_server_data) < 1:
                self.log.debug("No DHCP servers found. Warning user about "
                               "dhcp_nowait.")
                #Build dialog elements
                dhcp_info = []
                dhcp_info.append(urwid.Padding(
                                 urwid.Text(("header", "!!! WARNING !!!")),
                                 "center"))
                dhcp_info.append(
                    widget.TextLabel(
                        "Unable to detect DHCP server" +
                        "on interface %s." % (self.activeiface) +
                        "\nDHCP will be set up in the background, " +
                        "but may not receive an IP address. You may " +
                        "want to check your DHCP connection manually " +
                        "using the Shell Login menu to the left."))
                dialog.display_dialog(self, urwid.Pile(dhcp_info),
                                      "DHCP Servers Found on %s"
                                      % self.activeiface)
                self.parent.refreshScreen()
                responses["dhcp_nowait"] = True
        #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)
        if len(errors) > 0:
            self.parent.footer.set_text("Error: %s" % (errors[0]))
            self.log.error("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
    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()

            ###Start DHCP check on this interface
            #dhcp_server_data=[{'server_id': '192.168.200.2', 'iface': 'eth2',
            #                   'yiaddr': '192.168.200.15', 'mac':
            #                '52:54:00:12:35:02', 'server_ip': '192.168.200.2',
            #                   'dport': 67, 'message': 'offer',
            #                   'gateway': '0.0.0.0'}]
            try:
                dhcptimeout = 5
                default = []
                with timeout.run_with_timeout(dhcp_checker.utils.IfaceState,
                                              [self.activeiface],
                                              timeout=dhcptimeout) as iface:
                    dhcp_server_data = timeout.run_with_timeout(
                        dhcp_checker.api.check_dhcp_on_eth,
                        [iface, dhcptimeout], timeout=dhcptimeout,
                        default=default)
            except (KeyboardInterrupt, timeout.TimeoutError):
                log.debug("DHCP scan timed out")
                log.warning(traceback.format_exc())
                dhcp_server_data = default

            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))

        if len(errors) > 0:
            self.parent.footer.set_text("Error: %s" % (errors[0]))
            log.error("Errors: %s %s" % (len(errors), errors))
            return False
        else:
            self.parent.footer.set_text("No errors found.")
            return responses
Esempio n. 25
0
    def check(self, args):
        """Validate that all fields have valid values and some sanity checks"""
        self.parent.footer.set_text("Checking data...")
        self.parent.refreshScreen()
        #Get field information
        responses = dict()

        for index, fieldname in enumerate(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."

            diag = dialog.display_dialog(self, TextLabel(msg),
                                         "Empty DNS Warning")

        else:
            #external DNS must contain only numbers, periods, and commas
            #TODO: 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 test DNS name isn't empty
            if len(responses["TEST_DNS"]) == 0:
                errors.append("Test DNS must not be empty.")
            #Validate first IP address
            try:
                if netaddr.valid_ipv4(responses["DNS_UPSTREAM"].split(",")[0]):
                    DNS_UPSTREAM = responses["DNS_UPSTREAM"].split(",")[0]
                else:
                    errors.append(
                        "Not a valid IP address for External DNS: %s" %
                        responses["DNS_UPSTREAM"])

                #Try to resolve with first address
                if not self.checkDNS(DNS_UPSTREAM):
                    #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."
                    diag = dialog.display_dialog(self, TextLabel(msg),
                                                 "DNS Failure Warning")
                    self.parent.refreshScreen()
            except Exception, e:
                errors.append("Not a valid IP address for External DNS: %s" %
                              responses["DNS_UPSTREAM"])