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
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.')
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.')
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
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
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
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)
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
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
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
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
def update_dhcp(self): settings = self.parent.settings.get("ADMIN_NETWORK") if not self._update_nailgun(settings): return False if os.path.exists(consts.HIERA_NET_SETTINGS): result, msg = self._update_hiera_dnsmasq(settings) else: result = self._update_dnsmasq(settings) if not result: ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False cobbler_sync = ["cobbler", "sync"] code, out, err = utils.execute(cobbler_sync) if code != 0: log.error(err) ModuleHelper.display_dialog( self, error_msg=self.apply_dialog_message["message"], title=self.apply_dialog_message["title"]) return False return True
def 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
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
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
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
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
def checkNTP(self, server): # Use ntpdate to verify server answers NTP requests command = ["ntpdate", "-q", "-t2", server] code, _, _ = utils.execute(command) return code == 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
def upIface(iface): code, _, _ = execute(["ifconfig", iface, "up"]) if code != 0: raise NetworkException("Failed to up interface {0}".format(iface))
def checkNTP(self, server): # Use ntpdate to verify server answers NTP requests command = ["ntpdate", "-q", "-t2", server] code, _, _ = utils.execute(command) return (code == 0)