示例#1
0
        def fmt_field(name, value='', key=None, level=0):
            hl = False

            # resolve values
            if isinstance(value, Script):
                hl = True
                value = value.script
            elif cls.is_secret(name, key):
                reveal = "reveal with: {}".format(
                    HighlightColor(
                        join('avendesora', 'value', cls.get_name(),
                             cls.combine_field(name, key))))
                value = ', '.join(cull([value.get_description(), reveal]))
            elif isinstance(value, (GeneratedSecret, ObscuredSecret)):
                v = cls.get_scalar(name, key)
                value = ', '.join(cull([value.get_description(), str(v)]))
            else:
                value = str(value)

            # format values
            if '\n' in value:
                value = indent(dedent(value),
                               get_setting('indent')).strip('\n')
                sep = '\n'
            elif value:
                sep = ' '
            else:
                sep = ''
            if hl:
                value = HighlightColor(value)
            name = str(name).replace('_', ' ')
            leader = level * get_setting('indent')
            return indent(
                LabelColor((name if key is None else str(key)) + ':') + sep +
                value, leader)
示例#2
0
    def run_borg_raw(self, args):

        # prepare the command
        os.environ.update(self.publish_passcode())
        os.environ["BORG_DISPLAY_PASSPHRASE"] = "no"
        executable = self.value("borg_executable", BORG)
        remote_path = self.value("remote_path")
        remote_path = ["--remote-path", remote_path] if remote_path else []
        repository = str(self.repository)
        command = ([executable] + remote_path +
                   [a.replace('@repo', repository) for a in args])

        # run the command
        narrate("running:\n{}".format(
            indent(render_command(command, borg_options_arg_count))))
        with cd(self.working_dir):
            narrate("running in:", cwd())
            starts_at = arrow.now()
            log("starts at: {!s}".format(starts_at))
            borg = Run(command, modes="soeW", env=os.environ, log=False)
            ends_at = arrow.now()
            log("ends at: {!s}".format(ends_at))
            log("elapsed = {!s}".format(ends_at - starts_at))
        if borg.stdout:
            narrate("Borg stdout:")
            narrate(indent(borg.stdout))
        if borg.stderr:
            narrate("Borg stderr:")
            narrate(indent(borg.stderr))
        if borg.status:
            narrate("Borg exit status:", borg.status)

        return borg
示例#3
0
    def conceal(cls,
                plaintext,
                decorate=False,
                encoding=None,
                symmetric=False,
                gpg_ids=None):
        encoding = encoding if encoding else get_setting('encoding')
        plaintext = str(plaintext).encode(encoding)
        if not gpg_ids:
            gpg_ids = get_setting('gpg_ids', [])
        if is_str(gpg_ids):
            gpg_ids = gpg_ids.split()

        encrypted = cls.gpg.encrypt(plaintext,
                                    gpg_ids,
                                    armor=True,
                                    symmetric=bool(symmetric))
        if not encrypted.ok:
            msg = ' '.join(
                cull(
                    ['unable to encrypt.',
                     getattr(encrypted, 'stderr', None)]))
            raise PasswordError(msg)
        ciphertext = str(encrypted)
        if decorate:
            return 'GPG("""\n%s""")' % indent(ciphertext)
        else:
            return ciphertext
示例#4
0
def to_python(obj, _level=0):
    """Recursively convert object to string with reasonable formatting"""
    def leader(relative_level=0):
        return (_level + relative_level) * '    '

    code = []
    if type(obj) == dict:
        code += ['{']
        for key in sorted(obj.keys()):
            value = obj[key]
            code += [
                '%s%r: %s,' % (leader(1), key, to_python(value, _level + 1))
            ]
        code += ['%s}' % (leader(0))]
    elif type(obj) == list:
        code += ['[']
        for each in obj:
            code += ['%s%s,' % (leader(1), to_python(each, _level + 1))]
        code += ['%s]' % (leader(0))]
    elif type(obj) == tuple:
        code += ['(']
        for each in obj:
            code += ['%s%s,' % (leader(1), to_python(each, _level + 1))]
        code += ['%s)' % (leader(0))]
    elif type(obj) == set:
        code += ['set([']
        for each in sorted(obj):
            code += ['%s%s,' % (leader(1), to_python(each, _level + 1))]
        code += ['%s])' % (leader(0))]
    elif is_str(obj) and '\n' in obj:
        code += ['"""' + indent(dedent(obj), leader(1)) + leader(0) + '"""']
    else:
        code += [repr(obj)]
    return '\n'.join(code)
示例#5
0
    def run_borg(self, cmd, args='', borg_opts=None, emborg_opts=()):

        # prepare the command
        os.environ.update(self.publish_passcode())
        os.environ['BORG_DISPLAY_PASSPHRASE'] = 'no'
        if self.ssh_command:
            os.environ['BORG_RSH'] = self.ssh_command
        executable = self.value('borg_executable', BORG)
        if borg_opts is None:
            borg_opts = self.borg_options(cmd, emborg_opts)
        command = ([executable] + cmd.split() + borg_opts +
                   (args.split() if is_str(args) else args))
        environ = {
            k: v
            for k, v in os.environ.items() if k.startswith('BORG_')
        }
        if 'BORG_PASSPHRASE' in environ:
            environ['BORG_PASSPHRASE'] = '<redacted>'
        narrate('setting environment variables:', render(environ))

        # check if ssh agent is present
        if self.needs_ssh_agent:
            for ssh_var in 'SSH_AGENT_PID SSH_AUTH_SOCK'.split():
                if ssh_var not in os.environ:
                    warn(
                        'environment variable not found, is ssh-agent running?',
                        culprit=ssh_var)

        # run the command
        narrate('running:\n{}'.format(
            indent(render_command(command, borg_options_arg_count))))
        narrating = 'verbose' in emborg_opts or 'narrate' in emborg_opts
        modes = 'soeW' if narrating else 'sOEW'
        return Run(command, modes=modes, stdin='', env=os.environ, log=False)
示例#6
0
def format(text):
    try:
        if '\n' in text:
            return '\n' + indent(text, '        ')
        else:
            return text
    except:
        return text
示例#7
0
def format(text):
    try:
        if '\n' in text:
            return '\n' + indent(text, '        ')
        else:
            return text
    except:
        return text
示例#8
0
def run_duplicity(cmd, settings, narrating):
    os.environ.update(publish_passcode(settings))
    for ssh_var in 'SSH_AGENT_PID SSH_AUTH_SOCK'.split():
        if ssh_var not in os.environ:
            warn('environment variable not found, is ssh-agent running?',
                 culprit=ssh_var)
    narrate('running:\n{}'.format(indent(render_command(cmd))))
    modes = 'soeW' if narrating else 'sOEW'
    Run(cmd, modes=modes, env=os.environ)
示例#9
0
    def run_borg_raw(self, args):

        # run the run_before_borg commands
        self.run_user_commands('run_before_borg')

        # prepare the command
        self.publish_passcode()
        os.environ["BORG_DISPLAY_PASSPHRASE"] = "no"
        executable = self.value("borg_executable", BORG)
        remote_path = self.value("remote_path")
        remote_path = ["--remote-path", remote_path] if remote_path else []
        repository = str(self.repository)
        command = ([executable] + remote_path +
                   [a.replace('@repo', repository) for a in args])

        # run the command
        narrate("running:\n{}".format(
            indent(render_command(command, borg_options_arg_count))))
        with cd(self.working_dir):
            narrate("running in:", cwd())
            starts_at = arrow.now()
            log("starts at: {!s}".format(starts_at))
            try:
                borg = Run(command, modes="soeW1", env=os.environ, log=False)
            except Error as e:
                self.report_borg_error(e, executable)
            ends_at = arrow.now()
            log("ends at: {!s}".format(ends_at))
            log("elapsed = {!s}".format(ends_at - starts_at))
        if borg.status == 1:
            warn('Warning emitted by Borg, see logfile for details.')
        if borg.stdout:
            narrate("Borg stdout:")
            narrate(indent(borg.stdout))
        if borg.stderr:
            narrate("Borg stderr:")
            narrate(indent(borg.stderr))
        if borg.status:
            narrate("Borg exit status:", borg.status)

        return borg
示例#10
0
    def run_borg_raw(self, args):

        # prepare the command
        os.environ.update(self.publish_passcode())
        os.environ['BORG_DISPLAY_PASSPHRASE'] = 'no'
        executable = self.value('borg_executable', BORG)
        repository = str(self.repository)
        command = ([executable] + [(repository if a == '@repo' else a)
                                   for a in args])

        # run the command
        narrate('running:\n{}'.format(
            indent(render_command(command, borg_options_arg_count))))
        return Run(command, modes='soeW', env=os.environ, log=False)
示例#11
0
    def display_field(self, account, field):
        # get string to display
        value, is_secret, name, desc = tuple(account.get_value(field))
        label = '%s (%s)' % (name, desc) if desc else name
        value = dedent(str(value)).strip()
        label_color = get_setting('_label_color')

        # indent multiline outputs
        sep = ' '
        if '\n' in value:
            if is_secret:
                warn('secret contains newlines, will not be fully concealed.')
            value = indent(value, get_setting('indent')).strip('\n')
            sep = '\n'

        if label:
            if label[0] == '_':
                # hidden field
                label = '!' + label[1:]
            text = label_color(label.replace('_', ' ') + ':') + sep + value
        else:
            text = value
            label = field
        log('Writing to TTY:', label)

        if is_secret:
            if Color.isTTY():
                # Write only if output is a TTY. This is a security feature.
                # The ideas is that when the TTY writer is called it is because
                # the user is expecting the output to go to the tty. This
                # eliminates the chance that the output can be intercepted and
                # recorded by replacing Avendesora with an alias or shell
                # script. If the user really want the output to go to something
                # other than the TTY, the user should use the --stdout option.
                try:
                    cursor.write(text)
                    cursor.conceal()
                    sleep(get_setting('display_time'))
                except KeyboardInterrupt:
                    pass
                cursor.reveal()
                cursor.clear()
            else:
                error('output is not a TTY.')
                codicil(
                    'Use --stdout option if you want to send secret',
                    'to a file or a pipe.'
                )
        else:
            output(text)
示例#12
0
    def command_briefs(self):
        """
        Return a nicely formatted list of all the subcommands installed on this 
        system, to incorporate into the usage text.
        """
        from stepwise import tabulate
        from inform import indent

        rows = [
                [f'{name}:', getattr(app, 'brief', 'No summary.')]
                for name, app in self.commands.items()
        ]
        table = tabulate(rows, truncate='-x', max_width=-4)
        return indent(table, leader='    ', first=-1)
示例#13
0
    def fail(self, *msg, cmd='<unknown>'):
        msg = join(*msg)
        try:
            msg = msg.decode('ascii', errors='replace')
        except AttributeError:
            pass
        try:
            if self.notify and not Color.isTTY():
                Run(
                    [
                        "mail", "-s",
                        f"{PROGRAM_NAME} failed on {username}@{hostname}"
                    ] + self.notify.split(),
                    stdin=dedent(f"""\
                        {PROGRAM_NAME} fails.

                        command: {cmd}
                        config: {self.config_name}
                        source: {username}@{fullhostname}:{', '.join(str(d) for d in self.src_dirs)}
                        destination: {self.repository!s}
                        error message:
                        """) + indent(msg) + "\n",
                    modes="soeW",
                    encoding="ascii",
                )
        except Error:
            pass
        try:
            notifier = self.settings.get("notifier")
            # don't use self.value as we don't want arguments expanded yet
            if notifier and not Color.isTTY():
                Run(self.notifier.format(
                    cmd=cmd,
                    msg=msg,
                    hostname=hostname,
                    user_name=username,
                    prog_name=PROGRAM_NAME,
                ),
                    modes="SoeW"
                    # need to use the shell as user will generally quote msg
                    )
        except Error:
            pass
        except KeyError as e:
            warn("unknown key.", culprit=(self.settings_file, "notifier", e))
示例#14
0
    def render(self, fmts=('{f} ({d}): {v}', '{f}: {v}')):
        """Return value formatted as a string.

        Args:
            fmts (collection of strings):
                *fmts* contains a sequence of format strings that are tried in
                sequence.  The first one for which all keys are known is used.
                The possible keys are:

                | n -- name (identifier for the first level of a field)
                | k -- key (identifier for the second level of a field)
                | f -- field (name.key)
                | d -- description
                | v -- value

                If none work, the value alone is returned.
        Returns:
            The value rendered as a string.
        """
        value = str(self.value)
        if '\n' in value:
            value = '\n' + indent(dedent(value),
                                  get_setting('indent')).strip('\n')
        if is_str(fmts):
            fmts = fmts,

        # build list of arguments, deleting any that is not set
        args = {
            k: v
            for k, v in [('f', self.field), ('k', self.key), (
                'n', self.name), ('d', self.desc), ('v', value)] if v
        }

        # format the arguments, use first format sting that works
        for fmt in fmts:
            try:
                return fmt.format(**args)
            except KeyError:
                pass

        # nothing worked, just return the value
        return value
示例#15
0
    def conceal(cls, plaintext, decorate=False, encoding=None, symmetric=False):
        encoding = encoding if encoding else get_setting('encoding')
        plaintext = str(plaintext).encode(encoding)
        gpg_ids = get_setting('gpg_ids', [])
        if is_str(gpg_ids):
            gpg_ids = gpg_ids.split()

        encrypted = cls.gpg.encrypt(
            plaintext, gpg_ids, armor=True, symmetric=bool(symmetric)
        )
        if not encrypted.ok:
            msg = ' '.join(cull([
                'unable to encrypt.',
                getattr(encrypted, 'stderr', None)
            ]))
            raise Error(msg)
        ciphertext = str(encrypted)
        if decorate:
            return 'GPG("""\n%s""")' % indent(ciphertext)
        else:
            return ciphertext
示例#16
0
    def run_borg_raw(self, args):

        # prepare the command
        os.environ.update(self.publish_passcode())
        os.environ['BORG_DISPLAY_PASSPHRASE'] = 'no'
        executable = self.value('borg_executable', BORG)
        remote_path = self.value('remote_path')
        remote_path = ['--remote-path', remote_path] if remote_path else []
        repository = str(self.repository)
        command = ([executable] + remote_path +
                   [(repository if a == '@repo' else a) for a in args])

        # run the command
        narrate('running:\n{}'.format(
            indent(render_command(command, borg_options_arg_count))))
        starts_at = arrow.now()
        narrate('starts at: {!s}'.format(starts_at))
        borg = Run(command, modes='soeW', env=os.environ, log=False)
        ends_at = arrow.now()
        narrate('ends at: {!s}'.format(ends_at))
        narrate('elapsed = {!s}'.format(ends_at - starts_at))
        return borg
示例#17
0
    def run_borg(
        self,
        cmd,
        args=(),
        borg_opts=None,
        emborg_opts=(),
        strip_prefix=False,
        show_borg_output=False,
        use_working_dir=False,
    ):
        # prepare the command
        os.environ.update(self.publish_passcode())
        os.environ["BORG_DISPLAY_PASSPHRASE"] = "no"
        if self.ssh_command:
            os.environ["BORG_RSH"] = self.ssh_command
        executable = self.value("borg_executable", BORG)
        borg_opts = self.borg_options(cmd, borg_opts, emborg_opts,
                                      strip_prefix)
        command = [executable] + cmd.split() + borg_opts + args
        environ = {
            k: v
            for k, v in os.environ.items() if k.startswith("BORG_")
        }
        if "BORG_PASSPHRASE" in environ:
            environ["BORG_PASSPHRASE"] = "<redacted>"
        narrate("Borg-related environment variables:", render(environ))

        # check if ssh agent is present
        if self.needs_ssh_agent:
            if "SSH_AUTH_SOCK" not in os.environ:
                warn(
                    "SSH_AUTH_SOCK environment variable not found.",
                    "Is ssh-agent running?",
                )

        # run the command
        narrate("running:\n{}".format(
            indent(render_command(command, borg_options_arg_count))))
        with cd(self.working_dir if use_working_dir else "."):
            narrate("running in:", cwd())
            starts_at = arrow.now()
            log("starts at: {!s}".format(starts_at))
            narrating = (show_borg_output or "--verbose" in borg_opts
                         or "verbose" in emborg_opts or "narrate"
                         in emborg_opts) and "--json" not in command
            if narrating:
                modes = "soeW"
                display("\nRunning Borg {} command ...".format(cmd))
            else:
                modes = "sOEW"
            try:
                borg = Run(command,
                           modes=modes,
                           stdin="",
                           env=os.environ,
                           log=False)
            except Error as e:
                e.reraise(culprit=f"borg {cmd}")
            ends_at = arrow.now()
            log("ends at: {!s}".format(ends_at))
            log("elapsed = {!s}".format(ends_at - starts_at))
        if borg.stdout:
            narrate("Borg stdout:")
            narrate(indent(borg.stdout))
        if borg.stderr:
            narrate("Borg stderr:")
            narrate(indent(borg.stderr))
        if borg.status:
            narrate("Borg exit status:", borg.status)
        return borg
示例#18
0
    def run_borg(
        self,
        cmd,
        args=(),
        borg_opts=None,
        emborg_opts=(),
        strip_prefix=False,
        show_borg_output=False,
        use_working_dir=False,
    ):

        # run the run_before_borg commands
        self.run_user_commands('run_before_borg')

        # prepare the command
        self.publish_passcode()
        if "BORG_PASSPHRASE" in os.environ:
            os.environ["BORG_DISPLAY_PASSPHRASE"] = "no"
        if self.ssh_command:
            os.environ["BORG_RSH"] = self.ssh_command
        environ = {
            k: v
            for k, v in os.environ.items() if k.startswith("BORG_")
        }
        if "BORG_PASSPHRASE" in environ:
            environ["BORG_PASSPHRASE"] = "<redacted>"
        executable = self.value("borg_executable", BORG)
        borg_opts = self.borg_options(cmd, borg_opts, emborg_opts,
                                      strip_prefix)
        command = [executable] + cmd.split() + borg_opts + args
        narrate("Borg-related environment variables:", render(environ))

        # check if ssh agent is present
        if self.needs_ssh_agent:
            if "SSH_AUTH_SOCK" not in os.environ:
                warn(
                    "SSH_AUTH_SOCK environment variable not found.",
                    "Is ssh-agent running?",
                )

        # run the command
        narrate("running:\n{}".format(
            indent(render_command(command, borg_options_arg_count))))
        with cd(self.working_dir if use_working_dir else "."):
            narrate("running in:", cwd())
            if "--json" in command or "--json-lines" in command:
                narrating = False
            else:
                narrating = (show_borg_output or "--verbose" in borg_opts
                             or "--progress" in borg_opts
                             or "verbose" in emborg_opts
                             or "narrate" in emborg_opts)
            if narrating:
                modes = "soeW1"
                display("\nRunning Borg {} command ...".format(cmd))
            else:
                modes = "sOEW1"
            starts_at = arrow.now()
            log("starts at: {!s}".format(starts_at))
            try:
                borg = Run(command,
                           modes=modes,
                           stdin="",
                           env=os.environ,
                           log=False)
            except Error as e:
                self.report_borg_error(e, cmd)
            finally:
                # remove passcode env variables created by emborg
                if self.borg_passcode_env_var_set_by_emborg:
                    narrate(
                        f"Unsetting {self.borg_passcode_env_var_set_by_emborg}."
                    )
                    del os.environ[self.borg_passcode_env_var_set_by_emborg]
            ends_at = arrow.now()
            log("ends at: {!s}".format(ends_at))
            log("elapsed = {!s}".format(ends_at - starts_at))
        if borg.status:
            narrate("Borg exit status:", borg.status)
        if borg.status == 1 and borg.stderr:
            warnings = borg.stderr.partition(72 * '-')[0]
            warn('Warning emitted by Borg:', codicil=warnings)
        if borg.stdout:
            narrate("Borg stdout:")
            narrate(indent(borg.stdout))
        if borg.stderr:
            narrate("Borg stderr:")
            narrate(indent(borg.stderr))

        return borg
示例#19
0
 def get_expected(self):
     if "\n" in self.expected:
         expected = "\n" + indent(self.expected, stops=2)
     else:
         expected = self.expected
     return dict(exit_status=self.expected_exit_status, output=expected)
示例#20
0
 def get_result(self):
     if "\n" in self.result:
         result = "\n" + indent(self.result, stops=2)
     else:
         result = self.result
     return dict(exit_status=self.exit_status, output=result)