Ejemplo n.º 1
0
    def ask(self, status):
        if 'type' in status.info['needs_fixing']:
            if not status.info['path_info'].exists:
                return _("Doesn't exist.")
            else:
                return "{} {} → {}\n".format(
                    bold(_("type")),
                    status.info['path_info'].desc,
                    _("file"),
                )

        question = ""

        if 'owner' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("owner")),
                status.info['path_info'].owner,
                self.attributes['owner'],
            )

        if 'group' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("group")),
                status.info['path_info'].group,
                self.attributes['group'],
            )

        return question.rstrip("\n")
Ejemplo n.º 2
0
    def ask(self, status):
        if not status.info['exists']:
            return _("'{}' not found in /etc/passwd").format(self.name)
        elif self.attributes['delete']:
            return _("'{}' found in /etc/passwd. Will be deleted.").format(self.name)

        output = ""
        for key, should_value in self.attributes.iteritems():
            if key in ('delete', 'groups', 'hash_method', 'password', 'password_hash',
                       'salt', 'use_shadow'):
                continue
            is_value = status.info[key]
            if should_value != is_value:
                output += "{} {} → {}\n".format(
                    bold(_ATTRIBUTE_NAMES[key]),
                    is_value,
                    should_value,
                )

        if self.attributes['use_shadow']:
            filename = "/etc/shadow"
            found_hash = status.info['shadow_hash']
        else:
            filename = "/etc/passwd"
            found_hash = status.info['passwd_hash']

        if found_hash is None:
            output += bold(_ATTRIBUTE_NAMES['password_hash']) + " " + \
                      _("not found in {}").format(filename) + "\n"
        elif found_hash != self.attributes['password_hash']:
            output += bold(_ATTRIBUTE_NAMES['password_hash']) + " " + \
                      found_hash + "\n"
            output += " " * (len(_ATTRIBUTE_NAMES['password_hash']) - 1) + "→ " + \
                      self.attributes['password_hash'] + "\n"

        groups_should = set(self.attributes['groups'])
        groups_is = set(status.info['groups'])
        missing_groups = list(groups_should.difference(groups_is))
        missing_groups.sort()
        extra_groups = list(groups_is.difference(groups_should))
        extra_groups.sort()

        if missing_groups:
            output += bold(_("missing groups")) + " " + \
                      ", ".join(missing_groups) + "\n"

        if extra_groups:
            output += bold(_("extra groups")) + " " + \
                      ", ".join(extra_groups) + "\n"

        return output
Ejemplo n.º 3
0
 def ask(self, status):
     before = _("installed") if status.info['installed'] \
         else _("not installed")
     after = green(_("installed")) if self.attributes['installed'] \
         else red(_("not installed"))
     return "{} {} → {}\n".format(
         bold(_("status")),
         before,
         after,
     )
Ejemplo n.º 4
0
 def ask(self, status):
     if not status.info['exists']:
         return _("'{}' not found in /etc/group").format(self.name)
     elif self.attributes['delete']:
         return _("'{}' found in /etc/group. Will be deleted.").format(self.name)
     else:
         return "{} {} → {}\n".format(
             bold(_("GID")),
             status.info['gid'],
             self.attributes['gid'],
         )
Ejemplo n.º 5
0
    def ask(self, status):
        if 'type' in status.info['needs_fixing']:
            if not status.info['path_info'].exists:
                return _("Doesn't exist. Do you want to create it?")
            else:
                return _(
                    "Not a directory. "
                    "The `file` utility says it's a '{}'.\n"
                    "Do you want it removed and replaced?"
                ).format(
                    status.info['path_info'].desc,
                )

        question = ""

        if 'mode' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("mode")),
                status.info['path_info'].mode,
                self.attributes['mode'],
            )

        if 'owner' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("owner")),
                status.info['path_info'].owner,
                self.attributes['owner'],
            )

        if 'group' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("group")),
                status.info['path_info'].group,
                self.attributes['group'],
            )

        return question.rstrip("\n")
Ejemplo n.º 6
0
    def get_result(self, interactive=False, interactive_default=True):
        if interactive is False and self.attributes['interactive'] is True:
            return self.STATUS_ACTION_SKIPPED

        if self.triggered and not self.has_been_triggered:
            LOG.debug(_("skipping {} because it wasn't triggered").format(self.id))
            return self.STATUS_ACTION_SKIPPED

        if self.unless:
            unless_result = self.bundle.node.run(
                self.unless,
                may_fail=True,
            )
            if unless_result.return_code == 0:
                LOG.debug(_("{node}:action:{name}: failed 'unless', not running").format(
                    name=self.name,
                    node=self.bundle.node.name,
                ))
                return self.STATUS_ACTION_SKIPPED

        if (
            interactive and
            self.attributes['interactive'] is not False
            and not ask_interactively(
                wrap_question(
                    self.id,
                    self.attributes['command'],
                    _("Run action {}?").format(
                        bold(self.name),
                    ),
                ),
                interactive_default,
            )
        ):
            return self.STATUS_ACTION_SKIPPED
        try:
            self.run(interactive=interactive)
            return self.STATUS_ACTION_OK
        except ActionFailure:
            return self.STATUS_ACTION_FAILED
Ejemplo n.º 7
0
    def apply(self, interactive=False, interactive_default=True):
        self.node.repo.hooks.item_apply_start(
            self.node.repo,
            self.node,
            self,
        )
        status_code = None
        status_before = None
        status_after = None
        start_time = datetime.now()

        if self.triggered and not self.has_been_triggered:
            LOG.debug(_("skipping {} because it wasn't triggered").format(self.id))
            status_code = self.STATUS_SKIPPED

        if status_code is None:
            status_before = self.get_status()
            if self.unless and not status_before.correct:
                unless_result = self.node.run(self.unless, may_fail=True)
                if unless_result.return_code == 0:
                    LOG.debug(_("'unless' for {} succeeded, not fixing").format(self.id))
                    status_code = self.STATUS_SKIPPED

        if status_code is None:
            if status_before.correct:
                status_code = self.STATUS_OK

        if status_code is None:
            if not interactive:
                self.fix(status_before)
                status_after = self.get_status()
            else:
                question = wrap_question(
                    self.id,
                    self.ask(status_before),
                    _("Fix {}?").format(bold(self.id)),
                )
                if ask_interactively(question,
                                     interactive_default):
                    self.fix(status_before)
                    status_after = self.get_status()
                else:
                    status_code = self.STATUS_SKIPPED

        if status_code is None:
            if status_after.correct:
                status_code = self.STATUS_FIXED
            else:
                status_code = self.STATUS_FAILED

        self.node.repo.hooks.item_apply_end(
            self.node.repo,
            self.node,
            self,
            duration=datetime.now() - start_time,
            status_code=status_code,
            status_before=status_before,
            status_after=status_after,
        )

        return status_code
Ejemplo n.º 8
0
    def ask(self, status):
        if 'type' in status.info['needs_fixing']:
            if not status.info['path_info'].exists:
                return _("Doesn't exist.")
            elif self.attributes['delete']:
                if status.info['path_info'].is_directory:
                    return _("Directory and its contents will be deleted.")
                else:
                    return _("File will be deleted.")
            else:
                return "{} {} → {}\n".format(
                    bold(_("type")),
                    status.info['path_info'].desc,
                    _("file"),
                )

        question = ""

        if 'content' in status.info['needs_fixing']:
            question += bold(_("content "))
            if (
                status.info['path_info'].is_text_file and
                not self.attributes['content_type'] == 'binary'
            ):
                if status.info['path_info'].size > DIFF_MAX_FILE_SIZE:
                    question += _("(remote file larger than {} bytes, skipping diff)\n").format(
                        DIFF_MAX_FILE_SIZE,
                    )
                elif len(self.content) > DIFF_MAX_FILE_SIZE:
                    question += _("(new content larger than {} bytes, skipping diff)\n").format(
                        DIFF_MAX_FILE_SIZE,
                    )
                else:
                    content_is = get_remote_file_contents(self.node, self.name)
                    content_should = self.content
                    question += "\n" + diff(
                        content_is,
                        content_should,
                        self.name,
                        encoding_hint=self.attributes['encoding'],
                    ) + "\n"
            else:
                question += "'{}' → {}\n".format(
                    status.info['path_info'].desc,
                    _("<blockwart content>"),
                )

        if 'mode' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("mode")),
                status.info['path_info'].mode,
                self.attributes['mode'],
            )

        if 'owner' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("owner")),
                status.info['path_info'].owner,
                self.attributes['owner'],
            )

        if 'group' in status.info['needs_fixing']:
            question += "{} {} → {}\n".format(
                bold(_("group")),
                status.info['path_info'].group,
                self.attributes['group'],
            )

        return question.rstrip("\n")