예제 #1
0
def _pprint_key_entries(user, key_fn, key_entries, hash_meth='md5',
                        prefix='ci-info: '):
    if not key_entries:
        message = ("%sno authorized ssh keys fingerprints found for user %s.\n"
                   % (prefix, user))
        util.multi_log(message)
        return
    tbl_fields = ['Keytype', 'Fingerprint (%s)' % (hash_meth), 'Options',
                  'Comment']
    tbl = PrettyTable(tbl_fields)
    for entry in key_entries:
        if _is_printable_key(entry):
            row = []
            row.append(entry.keytype or '-')
            row.append(_gen_fingerprint(entry.base64, hash_meth) or '-')
            row.append(entry.options or '-')
            row.append(entry.comment or '-')
            tbl.add_row(row)
    authtbl_s = tbl.get_string()
    authtbl_lines = authtbl_s.splitlines()
    max_len = len(max(authtbl_lines, key=len))
    lines = [
        util.center("Authorized keys from %s for user %s" %
                    (key_fn, user), "+", max_len),
    ]
    lines.extend(authtbl_lines)
    for line in lines:
        util.multi_log(text="%s%s\n" % (prefix, line),
                       stderr=False, console=True)
예제 #2
0
def _pprint_key_entries(user, key_fn, key_entries, hash_meth='md5',
                        prefix='ci-info: '):
    if not key_entries:
        message = ("%sno authorized ssh keys fingerprints found for user %s.\n"
                   % (prefix, user))
        util.multi_log(message)
        return
    tbl_fields = ['Keytype', 'Fingerprint (%s)' % (hash_meth), 'Options',
                  'Comment']
    tbl = SimpleTable(tbl_fields)
    for entry in key_entries:
        if _is_printable_key(entry):
            row = []
            row.append(entry.keytype or '-')
            row.append(_gen_fingerprint(entry.base64, hash_meth) or '-')
            row.append(entry.options or '-')
            row.append(entry.comment or '-')
            tbl.add_row(row)
    authtbl_s = tbl.get_string()
    authtbl_lines = authtbl_s.splitlines()
    max_len = len(max(authtbl_lines, key=len))
    lines = [
        util.center("Authorized keys from %s for user %s" %
                    (key_fn, user), "+", max_len),
    ]
    lines.extend(authtbl_lines)
    for line in lines:
        util.multi_log(text="%s%s\n" % (prefix, line),
                       stderr=False, console=True)
def handle(name, cfg, cloud, log, _args):
    if util.is_false(cfg.get("ssh", {}).get("emit_keys_to_console", True)):
        log.debug(
            "Skipping module named %s, logging of SSH host keys disabled",
            name)
        return

    helper_path = _get_helper_tool_path(cloud.distro)
    if not os.path.exists(helper_path):
        log.warning(
            "Unable to activate module %s, helper tool not found at %s",
            name,
            helper_path,
        )
        return

    fp_blacklist = util.get_cfg_option_list(cfg, "ssh_fp_console_blacklist",
                                            [])
    key_blacklist = util.get_cfg_option_list(cfg, "ssh_key_console_blacklist",
                                             ["ssh-dss"])

    try:
        cmd = [helper_path, ",".join(fp_blacklist), ",".join(key_blacklist)]
        (stdout, _stderr) = subp.subp(cmd)
        util.multi_log("%s\n" % (stdout.strip()), stderr=False, console=True)
    except Exception:
        log.warning("Writing keys to the system console failed!")
        raise
def _handle_exit(signum, frame):
    (msg, rc) = EXIT_FOR[signum]
    msg = msg % ({"version": vr.version_string()})
    contents = StringIO()
    contents.write("%s\n" % (msg))
    _pprint_frame(frame, 1, BACK_FRAME_TRACE_DEPTH, contents)
    util.multi_log(contents.getvalue(), console=True, stderr=False, log=LOG)
    sys.exit(rc)
예제 #5
0
def _handle_exit(signum, frame):
    (msg, rc) = EXIT_FOR[signum]
    msg = msg % ({'version': vr.version()})
    contents = StringIO()
    contents.write("%s\n" % (msg))
    _pprint_frame(frame, 1, BACK_FRAME_TRACE_DEPTH, contents)
    util.multi_log(contents.getvalue(),
                   console=True, stderr=False, log=LOG)
    sys.exit(rc)
예제 #6
0
def handle(name, cfg, cloud, log, args):
    """Handler method activated by cloud-init."""

    verbose = util.get_cfg_by_path(cfg, ('debug', 'verbose'), default=True)
    if args:
        # if args are provided (from cmdline) then explicitly set verbose
        out_file = args[0]
        verbose = True
    else:
        out_file = util.get_cfg_by_path(cfg, ('debug', 'output'))

    if not verbose:
        log.debug(("Skipping module named %s,"
                   " verbose printing disabled"), name)
        return
    # Clean out some keys that we just don't care about showing...
    dump_cfg = copy.deepcopy(cfg)
    for k in SKIP_KEYS:
        dump_cfg.pop(k, None)
    all_keys = list(dump_cfg.keys())
    for k in all_keys:
        if k.startswith("_"):
            dump_cfg.pop(k, None)
    # Now dump it...
    to_print = StringIO()
    to_print.write(_make_header("Config"))
    to_print.write(_dumps(dump_cfg))
    to_print.write("\n")
    to_print.write(_make_header("MetaData"))
    to_print.write(_dumps(cloud.datasource.metadata))
    to_print.write("\n")
    to_print.write(_make_header("Misc"))
    to_print.write("Datasource: %s\n" %
                   (type_utils.obj_name(cloud.datasource)))
    to_print.write("Distro: %s\n" % (type_utils.obj_name(cloud.distro)))
    to_print.write("Hostname: %s\n" % (cloud.get_hostname(True)))
    to_print.write("Instance ID: %s\n" % (cloud.get_instance_id()))
    to_print.write("Locale: %s\n" % (cloud.get_locale()))
    to_print.write("Launch IDX: %s\n" % (cloud.launch_index))
    contents = to_print.getvalue()
    content_to_file = []
    for line in contents.splitlines():
        line = "ci-info: %s\n" % (line)
        content_to_file.append(line)
    if out_file:
        util.write_file(out_file, "".join(content_to_file), 0644, "w")
    else:
        util.multi_log("".join(content_to_file), console=True, stderr=False)
예제 #7
0
def handle(name, cfg, cloud, log, args):
    """Handler method activated by cloud-init."""

    verbose = util.get_cfg_by_path(cfg, ('debug', 'verbose'), default=True)
    if args:
        # if args are provided (from cmdline) then explicitly set verbose
        out_file = args[0]
        verbose = True
    else:
        out_file = util.get_cfg_by_path(cfg, ('debug', 'output'))

    if not verbose:
        log.debug(("Skipping module named %s,"
                   " verbose printing disabled"), name)
        return
    # Clean out some keys that we just don't care about showing...
    dump_cfg = copy.deepcopy(cfg)
    for k in SKIP_KEYS:
        dump_cfg.pop(k, None)
    all_keys = list(dump_cfg)
    for k in all_keys:
        if k.startswith("_"):
            dump_cfg.pop(k, None)
    # Now dump it...
    to_print = StringIO()
    to_print.write(_make_header("Config"))
    to_print.write(_dumps(dump_cfg))
    to_print.write("\n")
    to_print.write(_make_header("MetaData"))
    to_print.write(_dumps(cloud.datasource.metadata))
    to_print.write("\n")
    to_print.write(_make_header("Misc"))
    to_print.write("Datasource: %s\n" %
                   (type_utils.obj_name(cloud.datasource)))
    to_print.write("Distro: %s\n" % (type_utils.obj_name(cloud.distro)))
    to_print.write("Hostname: %s\n" % (cloud.get_hostname(True)))
    to_print.write("Instance ID: %s\n" % (cloud.get_instance_id()))
    to_print.write("Locale: %s\n" % (cloud.get_locale()))
    to_print.write("Launch IDX: %s\n" % (cloud.launch_index))
    contents = to_print.getvalue()
    content_to_file = []
    for line in contents.splitlines():
        line = "ci-info: %s\n" % (line)
        content_to_file.append(line)
    if out_file:
        util.write_file(out_file, "".join(content_to_file), 0o644, "w")
    else:
        util.multi_log("".join(content_to_file), console=True, stderr=False)
예제 #8
0
def handle(name, cfg, cloud, log, _args):
    helper_path = _get_helper_tool_path(cloud.distro)
    if not os.path.exists(helper_path):
        log.warning(("Unable to activate module %s,"
                     " helper tool not found at %s"), name, helper_path)
        return

    fp_blacklist = util.get_cfg_option_list(cfg, "ssh_fp_console_blacklist",
                                            [])
    key_blacklist = util.get_cfg_option_list(cfg, "ssh_key_console_blacklist",
                                             ["ssh-dss"])

    try:
        cmd = [helper_path, ','.join(fp_blacklist), ','.join(key_blacklist)]
        (stdout, _stderr) = subp.subp(cmd)
        util.multi_log("%s\n" % (stdout.strip()), stderr=False, console=True)
    except Exception:
        log.warning("Writing keys to the system console failed!")
        raise
예제 #9
0
def _pprint_key_entries(user,
                        key_fn,
                        key_entries,
                        hash_meth="sha256",
                        prefix="ci-info: "):
    if not key_entries:
        message = (
            "%sno authorized SSH keys fingerprints found for user %s.\n" %
            (prefix, user))
        util.multi_log(message, console=True, stderr=False)
        return
    tbl_fields = [
        "Keytype",
        "Fingerprint (%s)" % (hash_meth),
        "Options",
        "Comment",
    ]
    tbl = SimpleTable(tbl_fields)
    for entry in key_entries:
        if _is_printable_key(entry):
            row = [
                entry.keytype or "-",
                _gen_fingerprint(entry.base64, hash_meth) or "-",
                entry.options or "-",
                entry.comment or "-",
            ]
            tbl.add_row(row)
    authtbl_s = tbl.get_string()
    authtbl_lines = authtbl_s.splitlines()
    max_len = len(max(authtbl_lines, key=len))
    lines = [
        util.center(
            "Authorized keys from %s for user %s" % (key_fn, user),
            "+",
            max_len,
        ),
    ]
    lines.extend(authtbl_lines)
    for line in lines:
        util.multi_log(text="%s%s\n" % (prefix, line),
                       stderr=False,
                       console=True)
def handle(name, cfg, _cloud, log, _args):
    if not os.path.exists(HELPER_TOOL):
        log.warn(("Unable to activate module %s,"
                  " helper tool not found at %s"), name, HELPER_TOOL)
        return

    fp_blacklist = util.get_cfg_option_list(cfg, "ssh_fp_console_blacklist",
                                            [])
    key_blacklist = util.get_cfg_option_list(cfg, "ssh_key_console_blacklist",
                                             ["ssh-dss"])

    try:
        cmd = [HELPER_TOOL]
        cmd.append(','.join(fp_blacklist))
        cmd.append(','.join(key_blacklist))
        (stdout, _stderr) = util.subp(cmd)
        util.multi_log("%s\n" % (stdout.strip()), stderr=False, console=True)
    except:
        log.warn("Writing keys to the system console failed!")
        raise
예제 #11
0
def handle(_name, cfg, cloud, log, args):

    msg_in = ""
    if len(args) != 0:
        msg_in = str(args[0])
    else:
        msg_in = util.get_cfg_option_str(cfg, "final_message", "")

    msg_in = msg_in.strip()
    if not msg_in:
        msg_in = FINAL_MESSAGE_DEF

    uptime = util.uptime()
    ts = util.time_rfc2822()
    cver = version.version_string()
    try:
        subs = {
            "uptime": uptime,
            "timestamp": ts,
            "version": cver,
            "datasource": str(cloud.datasource),
        }
        subs.update(dict([(k.upper(), v) for k, v in subs.items()]))
        util.multi_log(
            "%s\n" % (templater.render_string(msg_in, subs)),
            console=False,
            stderr=True,
            log=log,
        )
    except Exception:
        util.logexc(log, "Failed to render final message template")

    boot_fin_fn = cloud.paths.boot_finished
    try:
        contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
        util.write_file(boot_fin_fn, contents, ensure_dir_exists=False)
    except Exception:
        util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)

    if cloud.datasource.is_disconnected:
        log.warning("Used fallback datasource")
예제 #12
0
def handle(name, cfg, cloud, log, _args):
    helper_path = _get_helper_tool_path(cloud.distro)
    if not os.path.exists(helper_path):
        log.warn(("Unable to activate module %s,"
                  " helper tool not found at %s"), name, helper_path)
        return

    fp_blacklist = util.get_cfg_option_list(cfg,
                                            "ssh_fp_console_blacklist", [])
    key_blacklist = util.get_cfg_option_list(cfg,
                                             "ssh_key_console_blacklist",
                                             ["ssh-dss"])

    try:
        cmd = [helper_path, ','.join(fp_blacklist), ','.join(key_blacklist)]
        (stdout, _stderr) = util.subp(cmd)
        util.multi_log("%s\n" % (stdout.strip()),
                       stderr=False, console=True)
    except Exception:
        log.warn("Writing keys to the system console failed!")
        raise
예제 #13
0
def handle(name, cfg, _cloud, log, _args):
    if not os.path.exists(HELPER_TOOL):
        log.warn(("Unable to activate module %s,"
                  " helper tool not found at %s"), name, HELPER_TOOL)
        return

    fp_blacklist = util.get_cfg_option_list(cfg,
                                            "ssh_fp_console_blacklist", [])
    key_blacklist = util.get_cfg_option_list(cfg,
                                             "ssh_key_console_blacklist",
                                              ["ssh-dss"])

    try:
        cmd = [HELPER_TOOL]
        cmd.append(','.join(fp_blacklist))
        cmd.append(','.join(key_blacklist))
        (stdout, _stderr) = util.subp(cmd)
        util.multi_log("%s\n" % (stdout.strip()),
                       stderr=False, console=True)
    except:
        log.warn("Writing keys to the system console failed!")
        raise
예제 #14
0
def handle(_name, cfg, cloud, log, args):

    msg_in = ''
    if len(args) != 0:
        msg_in = str(args[0])
    else:
        msg_in = util.get_cfg_option_str(cfg, "final_message", "")

    msg_in = msg_in.strip()
    if not msg_in:
        msg_in = FINAL_MESSAGE_DEF

    uptime = util.uptime()
    ts = util.time_rfc2822()
    cver = version.version_string()
    try:
        subs = {
            'uptime': uptime,
            'timestamp': ts,
            'version': cver,
            'datasource': str(cloud.datasource),
        }
        util.multi_log("%s\n" % (templater.render_string(msg_in, subs)),
                       console=False,
                       stderr=True,
                       log=log)
    except Exception:
        util.logexc(log, "Failed to render final message template")

    boot_fin_fn = cloud.paths.boot_finished
    try:
        contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
        util.write_file(boot_fin_fn, contents)
    except:
        util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)

    if cloud.datasource.is_disconnected:
        log.warn("Used fallback datasource")
예제 #15
0
def handle(_name, cfg, cloud, log, args):

    msg_in = ''
    if len(args) != 0:
        msg_in = str(args[0])
    else:
        msg_in = util.get_cfg_option_str(cfg, "final_message", "")

    msg_in = msg_in.strip()
    if not msg_in:
        msg_in = FINAL_MESSAGE_DEF

    uptime = util.uptime()
    ts = util.time_rfc2822()
    cver = version.version_string()
    try:
        subs = {
            'uptime': uptime,
            'timestamp': ts,
            'version': cver,
            'datasource': str(cloud.datasource),
        }
        subs.update(dict([(k.upper(), v) for k, v in subs.items()]))
        util.multi_log("%s\n" % (templater.render_string(msg_in, subs)),
                       console=False, stderr=True, log=log)
    except Exception:
        util.logexc(log, "Failed to render final message template")

    boot_fin_fn = cloud.paths.boot_finished
    try:
        contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
        util.write_file(boot_fin_fn, contents)
    except Exception:
        util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)

    if cloud.datasource.is_disconnected:
        log.warn("Used fallback datasource")
예제 #16
0
def welcome(action, msg=None):
    if not msg:
        msg = welcome_format(action)
    util.multi_log("%s\n" % (msg), console=False, stderr=True, log=LOG)
    return msg
예제 #17
0
 def test_logs_go_to_console_by_default(self):
     self._createConsole(self.root)
     logged_string = 'something very important'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, open('/dev/console').read())
예제 #18
0
 def test_given_log_level_used(self):
     log = mock.MagicMock()
     log_level = mock.Mock()
     util.multi_log('message', log=log, log_level=log_level)
     self.assertEqual((log_level, mock.ANY), log.log.call_args[0])
예제 #19
0
 def test_newlines_stripped_from_log_call(self):
     log = mock.MagicMock()
     expected_string = 'something very important'
     util.multi_log('{0}\n'.format(expected_string), log=log)
     self.assertEqual((mock.ANY, expected_string), log.log.call_args[0])
예제 #20
0
 def test_logs_go_to_stdout_if_console_does_not_exist(self):
     logged_string = 'something very important'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, self.stdout.getvalue())
예제 #21
0
 def test_logs_go_to_console_by_default(self):
     self._createConsole(self.root)
     logged_string = 'something very important'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, open('/dev/console').read())
예제 #22
0
 def test_given_log_level_used(self):
     log = mock.MagicMock()
     log_level = mock.Mock()
     util.multi_log('message', log=log, log_level=log_level)
     self.assertEqual((log_level, mock.ANY), log.log.call_args[0])
예제 #23
0
 def test_log_level_defaults_to_debug(self):
     log = mock.MagicMock()
     util.multi_log('message', log=log)
     self.assertEqual((logging.DEBUG, mock.ANY), log.log.call_args[0])
예제 #24
0
 def test_newlines_stripped_from_log_call(self):
     log = mock.MagicMock()
     expected_string = 'something very important'
     util.multi_log('{0}\n'.format(expected_string), log=log)
     self.assertEqual((mock.ANY, expected_string), log.log.call_args[0])
예제 #25
0
 def test_logs_go_to_log_if_given(self):
     log = mock.MagicMock()
     logged_string = 'something very important'
     util.multi_log(logged_string, log=log)
     self.assertEqual([((mock.ANY, logged_string), {})],
                      log.log.call_args_list)
예제 #26
0
 def test_stderr_used_by_default(self):
     logged_string = 'test stderr output'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, self.stderr.getvalue())
예제 #27
0
 def test_logs_go_to_stdout_if_console_does_not_exist(self):
     logged_string = 'something very important'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, self.stdout.getvalue())
예제 #28
0
 def test_stderr_not_used_if_false(self):
     util.multi_log('should not see this', stderr=False)
     self.assertEqual('', self.stderr.getvalue())
예제 #29
0
 def test_logs_dont_go_to_stdout_if_console_exists(self):
     self._createConsole(self.root)
     util.multi_log('something')
     self.assertEqual('', self.stdout.getvalue())
예제 #30
0
 def test_logs_dont_go_to_stdout_if_console_exists(self):
     self._createConsole(self.root)
     util.multi_log('something')
     self.assertEqual('', self.stdout.getvalue())
예제 #31
0
 def test_logs_dont_go_to_stdout_if_fallback_to_stdout_is_false(self):
     util.multi_log('something', fallback_to_stdout=False)
     self.assertEqual('', self.stdout.getvalue())
예제 #32
0
 def test_logs_go_to_log_if_given(self):
     log = mock.MagicMock()
     logged_string = 'something very important'
     util.multi_log(logged_string, log=log)
     self.assertEqual([((mock.ANY, logged_string), {})],
                      log.log.call_args_list)
def handle(_name, cfg, cloud, log, args):
    if args:
        # if run from command line, and give args, wipe the chpasswd['list']
        password = args[0]
        if "chpasswd" in cfg and "list" in cfg["chpasswd"]:
            del cfg["chpasswd"]["list"]
    else:
        password = util.get_cfg_option_str(cfg, "password", None)

    expire = True
    plist = None

    if "chpasswd" in cfg:
        chfg = cfg["chpasswd"]
        if "list" in chfg and chfg["list"]:
            if isinstance(chfg["list"], list):
                log.debug("Handling input for chpasswd as list.")
                plist = util.get_cfg_option_list(chfg, "list", plist)
            else:
                log.debug("Handling input for chpasswd as multiline string.")
                plist = util.get_cfg_option_str(chfg, "list", plist)
                if plist:
                    plist = plist.splitlines()

        expire = util.get_cfg_option_bool(chfg, "expire", expire)

    if not plist and password:
        (users, _groups) = ug_util.normalize_users_groups(cfg, cloud.distro)
        (user, _user_config) = ug_util.extract_default(users)
        if user:
            plist = ["%s:%s" % (user, password)]
        else:
            log.warning("No default or defined user to change password for.")

    errors = []
    if plist:
        plist_in = []
        hashed_plist_in = []
        hashed_users = []
        randlist = []
        users = []
        # N.B. This regex is included in the documentation (i.e. the module
        # docstring), so any changes to it should be reflected there.
        prog = re.compile(r"\$(1|2a|2y|5|6)(\$.+){2}")
        for line in plist:
            u, p = line.split(":", 1)
            if prog.match(p) is not None and ":" not in p:
                hashed_plist_in.append(line)
                hashed_users.append(u)
            else:
                # in this else branch, we potentially change the password
                # hence, a deviation from .append(line)
                if p == "R" or p == "RANDOM":
                    p = rand_user_password()
                    randlist.append("%s:%s" % (u, p))
                plist_in.append("%s:%s" % (u, p))
                users.append(u)
        ch_in = "\n".join(plist_in) + "\n"
        if users:
            try:
                log.debug("Changing password for %s:", users)
                chpasswd(cloud.distro, ch_in)
            except Exception as e:
                errors.append(e)
                util.logexc(
                    log, "Failed to set passwords with chpasswd for %s", users
                )

        hashed_ch_in = "\n".join(hashed_plist_in) + "\n"
        if hashed_users:
            try:
                log.debug("Setting hashed password for %s:", hashed_users)
                chpasswd(cloud.distro, hashed_ch_in, hashed=True)
            except Exception as e:
                errors.append(e)
                util.logexc(
                    log,
                    "Failed to set hashed passwords with chpasswd for %s",
                    hashed_users,
                )

        if len(randlist):
            blurb = (
                "Set the following 'random' passwords\n",
                "\n".join(randlist),
            )
            util.multi_log(
                "%s\n%s\n" % blurb, stderr=False, fallback_to_stdout=False
            )

        if expire:
            expired_users = []
            for u in users:
                try:
                    cloud.distro.expire_passwd(u)
                    expired_users.append(u)
                except Exception as e:
                    errors.append(e)
                    util.logexc(log, "Failed to set 'expire' for %s", u)
            if expired_users:
                log.debug("Expired passwords for: %s users", expired_users)

    handle_ssh_pwauth(cfg.get("ssh_pwauth"), cloud.distro)

    if len(errors):
        log.debug("%s errors occured, re-raising the last one", len(errors))
        raise errors[-1]
예제 #34
0
 def test_log_level_defaults_to_debug(self):
     log = mock.MagicMock()
     util.multi_log('message', log=log)
     self.assertEqual((logging.DEBUG, mock.ANY), log.log.call_args[0])
예제 #35
0
def welcome(action, msg=None):
    if not msg:
        msg = welcome_format(action)
    util.multi_log("%s\n" % (msg),
                   console=False, stderr=True, log=LOG)
    return msg
예제 #36
0
 def test_stderr_used_by_default(self):
     logged_string = 'test stderr output'
     util.multi_log(logged_string)
     self.assertEqual(logged_string, self.stderr.getvalue())
예제 #37
0
 def test_stderr_not_used_if_false(self):
     util.multi_log('should not see this', stderr=False)
     self.assertEqual('', self.stderr.getvalue())