Пример #1
0
    def save(self, password):
        if self.parent.save_only:
            # We shouldn't change root password in save_only mode
            return True

        hashed = crypt.crypt(password, utils.gensalt())
        log.info("Changing root password")
        # clear any locks first
        rm_command = ["rm", "-f", "/etc/passwd.lock", "/etc/shadow.lock"]
        utils.execute(rm_command)
        usermod_command = ["usermod", "-p", hashed, "root"]
        usermod_code, _, errout = utils.execute(usermod_command)

        if usermod_code == 0:
            self.parent.footer.set_text("Changes applied successfully.")
            log.info("Root password successfully changed.")
            # Reset fields
            self.cancel(None)
        else:
            log.error("Root password change failed with error:"
                      "\"{0}\"".format(errout))
            self.parent.footer.set_text("Unable to apply changes. Check logs "
                                        "for more details.")
            return False

        self.save_settings(hashed)
        return True
Пример #2
0
def search_external_dhcp(iface, timeout):
    """Checks for non-local DHCP servers discoverable on specified iface.

    :param iface: Interface for scanning.
    :type iface: string
    :param timeout: command timeout in seconds.
    :type timeout: int
    :returns: list of DHCP data
    :raises: errors.NetworkException
    """
    command = [
        "dhcpcheck", "discover", "--timeout",
        str(timeout), "-f", "json", "--ifaces", iface
    ]
    try:
        upIface(iface)  # ensure iface is up
        _, output, _ = execute(command)
        data = json.loads(output.strip())
        # FIXME(mattymo): Sometimes dhcpcheck prints json with keys, but no
        # values instead of empty array.
        if len(data) and not data[0]['mac']:
            return []
        return data
    except ValueError:
        # ValueError thrown if output is completely empty
        log.debug('Unable to parse JSON.')
        return []
    except OSError:
        raise NetworkException('Unable to check DHCP.')
Пример #3
0
def search_external_dhcp(iface, timeout):
    """Checks for non-local DHCP servers discoverable on specified iface.

    :param iface: Interface for scanning.
    :type iface: string
    :param timeout: command timeout in seconds.
    :type timeout: int
    :returns: list of DHCP data
    :raises: errors.NetworkException
    """
    command = ["dhcpcheck", "discover", "--timeout", str(timeout), "-f",
               "json", "--ifaces", iface]
    try:
        upIface(iface)  # ensure iface is up
        _, output, _ = execute(command)
        data = json.loads(output.strip())
        # FIXME(mattymo): Sometimes dhcpcheck prints json with keys, but no
        # values instead of empty array.
        if len(data) and not data[0]['mac']:
            return []
        return data
    except ValueError:
        # ValueError thrown if output is completely empty
        log.debug('Unable to parse JSON.')
        return []
    except OSError:
        raise NetworkException('Unable to check DHCP.')
Пример #4
0
    def checkDNS(self, server):
        # Note: Python's internal resolver caches negative answers.
        # Therefore, we should call dig externally to be sure.

        command = ["dig", "+short", "+time=3", "+retries=1",
                   self.defaults["TEST_DNS"]['value'], "@{0}".format(server)]
        code, _, _ = utils.execute(command)
        return code == 0
Пример #5
0
    def checkDNS(self, server):
        # Note: Python's internal resolver caches negative answers.
        # Therefore, we should call dig externally to be sure.

        command = [
            "dig", "+short", "+time=3", "+retries=1",
            self.defaults["TEST_DNS"]['value'], "@{0}".format(server)
        ]
        code, _, _ = utils.execute(command)
        return code == 0
Пример #6
0
 def unset_gateway(self):
     """Unset current gateway."""
     command = "ip route del default dev $(ip ro | grep default"\
               " | awk '{print $5}')"
     if self.get_default_gateway_linux() is None:
         return True
     code, output, errout = utils.execute(command, shell=True)
     if code != 0:
         self.log.error("Unable to unset gateway")
         self.log.info("Command was: {0}\nStderr: {1}\nStdout:".format(
             command, output, errout))
         self.parent.footer.set_text("Unable to unset gateway.")
         return False
Пример #7
0
def duplicateIPExists(ip, iface, arping_bind=False):
    """Checks for duplicate IP addresses using arping.

    Don't use arping_bind unless you know what you are doing.

    :param ip: IP to scan for
    :param iface: Interface on which to send requests
    :param arping_bind: Bind to IP when probing (IP must be already assigned.)
    :returns: boolean
    """
    if arping_bind:
        bind_ip = ip
    else:
        bind_ip = "0.0.0.0"
    command = ["arping", "-D", "-c3", "-w1", "-I", iface, "-s", bind_ip, ip]
    code, _, _ = execute(command)
    return (code != 0)
Пример #8
0
def puppetApply(classes):
    """Runs puppet apply

    :param classes: list of {'type': 'name': 'params':}. name must be a string
    :type classes: dict or list of dicts
    """
    log = logging
    log.info("Puppet start")

    command = [
        "puppet", "apply", "-d", "-v", "--logdest",
        "/var/log/puppet/fuelmenu-puppet.log"
    ]

    puppet_type_handlers = {
        consts.PUPPET_TYPE_LITERAL:
        lambda item: [item['name']],
        consts.PUPPET_TYPE_RESOURCE:
        lambda item: [item["class"], "{", '"{0}":'.format(item["name"])],
        consts.PUPPET_TYPE_CLASS:
        lambda item: ["class", "{", '"{0}":'.format(item["class"])]
    }

    cmd_input = list()
    for cls in classes:
        if cls['type'] not in puppet_type_handlers:
            log.error("Invalid type %s", cls['type'])
            return False

        cmd_input.extend(puppet_type_handlers[cls['type']](cls))
        if cls['type'] == consts.PUPPET_TYPE_LITERAL:
            continue

        # Build params
        for key, value in cls["params"].items():
            cmd_input.extend([key, "=>", _to_string(value)])
        cmd_input.append('}')

    stdin = ' '.join(cmd_input)
    log.debug(' '.join(command))
    log.debug(stdin)
    code, out, err = utils.execute(command, stdin=stdin)
    if code != 0:
        log.error("Exit code: %d. Error: %s Stdout: %s", code, err, out)
        return False
    return True
Пример #9
0
def duplicateIPExists(ip, iface, arping_bind=False):
    """Checks for duplicate IP addresses using arping.

    Don't use arping_bind unless you know what you are doing.

    :param ip: IP to scan for
    :param iface: Interface on which to send requests
    :param arping_bind: Bind to IP when probing (IP must be already assigned.)
    :returns: boolean
    """
    if arping_bind:
        bind_ip = ip
    else:
        bind_ip = "0.0.0.0"
    command = ["arping", "-D", "-c3", "-w1", "-I", iface, "-s", bind_ip, ip]
    code, _, _ = execute(command)
    return (code != 0)
Пример #10
0
def puppetApplyManifest(manifest):
    log = logging
    log.info("Start puppet apply with manifest {0}".format(manifest))

    cmd = ["puppet", "apply", "--debug", "--verbose", "--logdest",
           consts.PUPPET_LOGFILE, manifest]

    log.debug(' '.join(cmd))
    err_code, _, errout = utils.execute(cmd)

    if err_code != 0:
        msg = "Puppet apply failed. Check logs for more details."
        log.error(msg)
        return False, msg

    msg = "Puppet apply successfully executed."
    log.info(msg)
    return True, msg
Пример #11
0
def puppetApply(classes):
    """Runs puppet apply

    :param classes: list of {'type': 'name': 'params':}. name must be a string
    :type classes: dict or list of dicts
    """
    log = logging
    log.info("Puppet start")

    command = ["puppet", "apply", "-d", "-v", "--logdest",
               "/var/log/puppet/fuelmenu-puppet.log"]

    puppet_type_handlers = {
        consts.PUPPET_TYPE_LITERAL: lambda item: [item['name']],
        consts.PUPPET_TYPE_RESOURCE: lambda item: [
            item["class"], "{", '"{0}":'.format(item["name"])],
        consts.PUPPET_TYPE_CLASS: lambda item: [
            "class", "{", '"{0}":'.format(item["class"])]
    }

    cmd_input = list()
    for cls in classes:
        if cls['type'] not in puppet_type_handlers:
            log.error("Invalid type %s", cls['type'])
            return False

        cmd_input.extend(puppet_type_handlers[cls['type']](cls))
        if cls['type'] == consts.PUPPET_TYPE_LITERAL:
            continue

        # Build params
        for key, value in six.iteritems(cls["params"]):
            cmd_input.extend([key, "=>", _to_string(value)])
        cmd_input.append('}')

    stdin = ' '.join(cmd_input)
    log.debug(' '.join(command))
    log.debug(stdin)
    code, out, err = utils.execute(command, stdin=stdin)
    if code != 0:
        log.error("Exit code: %d. Error: %s Stdout: %s",
                  code, err, out)
        return False
    return True
Пример #12
0
def puppetApplyManifest(manifest):
    log = logging
    log.info("Start puppet apply with manifest {0}".format(manifest))

    cmd = [
        "puppet", "apply", "--debug", "--verbose", "--logdest",
        consts.PUPPET_LOGFILE, manifest
    ]

    log.debug(' '.join(cmd))
    err_code, _, errout = utils.execute(cmd)

    if err_code != 0:
        msg = "Puppet apply failed. Check logs for more details."
        log.error(msg)
        return False, msg

    msg = "Puppet apply successfully executed."
    log.info(msg)
    return True, msg
Пример #13
0
 def update_dhcp(self):
     settings = self.parent.settings.get("ADMIN_NETWORK")
     if not self._update_nailgun(settings):
         return False
     if os.path.exists(consts.HIERA_NET_SETTINGS):
         result, msg = self._update_hiera_dnsmasq(settings)
     else:
         result = self._update_dnsmasq(settings)
     if not result:
         ModuleHelper.display_dialog(
             self, error_msg=self.apply_dialog_message["message"],
             title=self.apply_dialog_message["title"])
         return False
     cobbler_sync = ["cobbler", "sync"]
     code, out, err = utils.execute(cobbler_sync)
     if code != 0:
         log.error(err)
         ModuleHelper.display_dialog(
             self, error_msg=self.apply_dialog_message["message"],
             title=self.apply_dialog_message["title"])
         return False
     return True
Пример #14
0
    def save(self, password):
        if self.parent.save_only:
            # We shouldn't change root password in save_only mode
            return True

        # there is no convinient way to create grub2 pbkdf password
        # grub2-mkpasswd-pbkdf2 can read input password only from stdin
        # FYI: grub2-setpassword is the bash script which can't be used
        # here because it blocks buffered input from stdin
        cmd = ["/usr/bin/grub2-mkpasswd-pbkdf2"]
        stdin = "{0}\n{0}".format(password)
        errcode, out, errout = utils.execute(cmd, stdin=stdin)

        # parse grub2-mkpasswd-pbkdf2 output
        pbkdf2 = re.findall('grub.pbkdf2.*', out, re.M)

        if errcode == 0 and pbkdf2 != []:
            grub2_password = "******".format(pbkdf2[0])
            log.info(grub2_password)

            log.info("Creating new /boot/grub2/user.cfg file")
            # overwrite /boot/grub2/user.cfg file if exists
            with open("/boot/grub2/user.cfg", "w") as usercfg:
                usercfg.write(grub2_password)
                usercfg.write("\n")
                usercfg.close()

            self.parent.footer.set_text("Changes applied successfully.")
            log.info("Grub password successfully set.")
            # Reset fields
            self.cancel(None)
        else:
            log.error("Command grub2-mkpasswd-pbkdf2 failed with an error:"
                      "\"{0}\"".format(errout))
            self.parent.footer.set_text("Unable to apply changes. Check logs "
                                        "for more details.")
            return False

        return True
Пример #15
0
    def save(self, password):
        if self.parent.save_only:
            # We shouldn't change root password in save_only mode
            return True

        # there is no convinient way to create grub2 pbkdf password
        # grub2-mkpasswd-pbkdf2 can read input password only from stdin
        # FYI: grub2-setpassword is the bash script which can't be used
        # here because it blocks buffered input from stdin
        cmd = ["/usr/bin/grub2-mkpasswd-pbkdf2"]
        stdin = "{0}\n{0}".format(password)
        errcode, out, errout = utils.execute(cmd, stdin=stdin)

        # parse grub2-mkpasswd-pbkdf2 output
        pbkdf2 = re.findall('grub.pbkdf2.*', out, re.M)

        if errcode == 0 and pbkdf2 != []:
            grub2_password = "******".format(pbkdf2[0])
            log.info(grub2_password)

            log.info("Creating new /boot/grub2/user.cfg file")
            # overwrite /boot/grub2/user.cfg file if exists
            with open("/boot/grub2/user.cfg", "w") as usercfg:
                usercfg.write(grub2_password)
                usercfg.write("\n")
                usercfg.close()

            self.parent.footer.set_text("Changes applied successfully.")
            log.info("Grub password successfully set.")
            # Reset fields
            self.cancel(None)
        else:
            log.error("Command grub2-mkpasswd-pbkdf2 failed with an error:"
                      "\"{0}\"".format(errout))
            self.parent.footer.set_text("Unable to apply changes. Check logs "
                                        "for more details.")
            return False

        return True
Пример #16
0
    def apply(self, args):
        responses = self.check(args)
        if responses is False:
            log.error("Check failed. Not applying")
            log.error("%s" % (responses))
            return False

        self.save(responses)
        # Apply NTP now, ignoring errors
        if len(responses["NTP1"]) > 0:
            # Stop ntpd, run ntpdate, start ntpd
            start_command = ["service", "ntpd", "start"]
            stop_command = ["service", "ntpd", "stop"]
            ntpdate_command = ["ntpdate", "-t5", responses["NTP1"]]
            utils.execute(stop_command)
            utils.execute(ntpdate_command)
            utils.execute(start_command)
        return True
Пример #17
0
    def apply(self, args):
        responses = self.check(args)
        if responses is False:
            log.error("Check failed. Not applying")
            log.error("%s" % (responses))
            return False

        self.save(responses)
        # Apply NTP now, ignoring errors
        if len(responses['NTP1']) > 0:
            # Stop ntpd, run ntpdate, start ntpd
            start_command = ["service", "ntpd", "start"]
            stop_command = ["service", "ntpd", "stop"]
            ntpdate_command = ["ntpdate", "-t5", responses['NTP1']]
            utils.execute(stop_command)
            utils.execute(ntpdate_command)
            utils.execute(start_command)
        return True
Пример #18
0
    def apply(self, args):
        self.fixEtcHosts()

        responses = self.check(args)
        if responses is False:
            log.error("Check failed. Not applying")
            log.error("%s" % (responses))
            return False

        self.save(responses)

        # Update network details so we write correct IP address
        self.getNetwork()

        # Apply hostname
        cmd = ["/usr/bin/hostnamectl", "set-hostname", responses["HOSTNAME"]]
        err_code, _, errout = utils.execute(cmd)
        if err_code != 0:
            log.error("Hostname change failed with an error: "
                      "\"{0}\"".format(errout))
            self.parent.footer.set_text("Unable to apply changes. Check logs "
                                        "for more details.")
            return False

        # remove old hostname from /etc/hosts
        f = open("/etc/hosts", "r")
        lines = f.readlines()
        f.close()
        with open("/etc/hosts", "w") as etchosts:
            for line in lines:
                if "localhost" in line:
                    etchosts.write(line)
                elif responses["HOSTNAME"] in line \
                        or self.parent.settings["HOSTNAME"] \
                        or self.netsettings[self.parent.managediface]['addr'] \
                        in line:
                    continue
                else:
                    etchosts.write(line)
            etchosts.close()

        # append hostname and ip address to /etc/hosts
        with open("/etc/hosts", "a") as etchosts:
            if self.netsettings[self.parent.managediface]["addr"] != "":
                managediface_ip = self.netsettings[
                    self.parent.managediface]["addr"]
            else:
                managediface_ip = "127.0.0.1"
            etchosts.write("%s   %s.%s %s\n" %
                           (managediface_ip, responses["HOSTNAME"],
                            responses['DNS_DOMAIN'], responses["HOSTNAME"]))
            etchosts.close()

        def make_resolv_conf(filename):
            if self.netsettings[self.parent.managediface]["addr"] != "":
                managediface_ip = self.netsettings[
                    self.parent.managediface]["addr"]
            else:
                managediface_ip = "127.0.0.1"
            with open(filename, 'w') as f:
                f.write("search {0}\n".format(responses['DNS_SEARCH']))
                f.write("domain {0}\n".format(responses['DNS_DOMAIN']))
                if utils.is_post_deployment():
                    f.write("nameserver {0}\n".format(managediface_ip))
                for upstream_dns in responses['DNS_UPSTREAM'].split(','):
                    f.write("nameserver {0}\n".format(upstream_dns))

        # Create a temporary resolv.conf so DNS works before the cobbler
        # container is up and running.
        # TODO(asheplyakov): puppet does a similar thing, perhaps we can
        # use the corresponding template instead of duplicating it here.
        make_resolv_conf('/etc/resolv.conf')

        # Reread resolv.conf
        res_init()

        return True
Пример #19
0
    def apply(self, args):
        self.fixEtcHosts()

        responses = self.check(args)
        if responses is False:
            log.error("Check failed. Not applying")
            log.error("%s" % (responses))
            return False

        self.save(responses)

        # Update network details so we write correct IP address
        self.getNetwork()

        # Apply hostname
        cmd = ["/usr/bin/hostnamectl", "set-hostname", responses["HOSTNAME"]]
        err_code, _, errout = utils.execute(cmd)
        if err_code != 0:
            log.error("Hostname change failed with an error: "
                      "\"{0}\"".format(errout))
            self.parent.footer.set_text("Unable to apply changes. Check logs "
                                        "for more details.")
            return False

        # remove old hostname from /etc/hosts
        f = open("/etc/hosts", "r")
        lines = f.readlines()
        f.close()
        with open("/etc/hosts", "w") as etchosts:
            for line in lines:
                if "localhost" in line:
                    etchosts.write(line)
                elif responses["HOSTNAME"] in line \
                        or self.parent.settings["HOSTNAME"] \
                        or self.netsettings[self.parent.managediface]['addr'] \
                        in line:
                    continue
                else:
                    etchosts.write(line)
            etchosts.close()

        # append hostname and ip address to /etc/hosts
        with open("/etc/hosts", "a") as etchosts:
            if self.netsettings[self.parent.managediface]["addr"] != "":
                managediface_ip = self.netsettings[
                    self.parent.managediface]["addr"]
            else:
                managediface_ip = "127.0.0.1"
            etchosts.write(
                "%s   %s.%s %s\n" % (managediface_ip, responses["HOSTNAME"],
                                     responses['DNS_DOMAIN'],
                                     responses["HOSTNAME"]))
            etchosts.close()

        def make_resolv_conf(filename):
            if self.netsettings[self.parent.managediface]["addr"] != "":
                managediface_ip = self.netsettings[
                    self.parent.managediface]["addr"]
            else:
                managediface_ip = "127.0.0.1"
            with open(filename, 'w') as f:
                f.write("search {0}\n".format(responses['DNS_SEARCH']))
                f.write("domain {0}\n".format(responses['DNS_DOMAIN']))
                if utils.is_post_deployment():
                    f.write("nameserver {0}\n".format(managediface_ip))
                for upstream_dns in responses['DNS_UPSTREAM'].split(','):
                    f.write("nameserver {0}\n".format(upstream_dns))

        # Create a temporary resolv.conf so DNS works before the cobbler
        # container is up and running.
        # TODO(asheplyakov): puppet does a similar thing, perhaps we can
        # use the corresponding template instead of duplicating it here.
        make_resolv_conf('/etc/resolv.conf')

        # Reread resolv.conf
        res_init()

        return True
Пример #20
0
 def checkNTP(self, server):
     # Use ntpdate to verify server answers NTP requests
     command = ["ntpdate", "-q", "-t2", server]
     code, _, _ = utils.execute(command)
     return code == 0
Пример #21
0
 def getDHCP(cls, iface):
     """Returns True if the interface has a dhclient process running."""
     command = ["pgrep", "-f", "dhclient.*{0}".format(iface)]
     code, output, errout = utils.execute(command)
     return code == 0
Пример #22
0
def upIface(iface):
    code, _, _ = execute(["ifconfig", iface, "up"])
    if code != 0:
        raise NetworkException("Failed to up interface {0}".format(iface))
Пример #23
0
 def getDHCP(cls, iface):
     """Returns True if the interface has a dhclient process running."""
     command = ["pgrep", "-f", "dhclient.*{0}".format(iface)]
     code, output, errout = utils.execute(command)
     return code == 0
Пример #24
0
 def checkNTP(self, server):
     # Use ntpdate to verify server answers NTP requests
     command = ["ntpdate", "-q", "-t2", server]
     code, _, _ = utils.execute(command)
     return (code == 0)
Пример #25
0
def upIface(iface):
    code, _, _ = execute(["ifconfig", iface, "up"])
    if code != 0:
        raise NetworkException("Failed to up interface {0}".format(iface))