コード例 #1
0
    def handle(self, *args, **options):
        write = self.stderr.write
        userid = options['userid']
        project = options["project"]

        # Get holdings from Cyclades DB
        db_holdings = util.get_db_holdings(user=userid, project=project)
        db_project_holdings = util.get_db_holdings(project=project,
                                                   for_users=False)

        # Get holdings from QuotaHolder
        try:
            qh_holdings = util.get_qh_users_holdings(
                [userid] if userid is not None else None,
                [project] if project is not None else None)
            qh_project_holdings = util.get_qh_project_holdings(
                [project] if project is not None else None)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        unsynced_users, users_pending, users_unknown =\
            reconcile.check_users(self.stderr, quotas.RESOURCES,
                                  db_holdings, qh_holdings)

        unsynced_projects, projects_pending, projects_unknown =\
            reconcile.check_projects(self.stderr, quotas.RESOURCES,
                                     db_project_holdings, qh_project_holdings)
        pending_exists = users_pending or projects_pending
        unknown_exists = users_unknown or projects_unknown

        headers = ("Type", "Holder", "Source", "Resource",
                   "Database", "Quotaholder")
        unsynced = unsynced_users + unsynced_projects
        if unsynced:
            pprint_table(self.stdout, unsynced, headers)
            if options["fix"]:
                qh = quotas.Quotaholder.get()
                force = options["force"]
                name = ("client: reconcile-resources-cyclades, time: %s"
                        % datetime.now())
                user_provisions = reconcile.create_user_provisions(
                    unsynced_users)
                project_provisions = reconcile.create_project_provisions(
                    unsynced_projects)
                try:
                    qh.issue_commission_generic(
                        user_provisions, project_provisions,
                        name=name, force=force,
                        auto_accept=True)
                except quotas.errors.QuotaLimit:
                    write("Reconciling failed because a limit has been "
                          "reached. Use --force to ignore the check.\n")
                    return
                write("Fixed unsynced resources\n")

        if pending_exists:
            write("Found pending commissions. Run 'snf-manage"
                  " reconcile-commissions-cyclades'\n")
        elif not (unsynced or unknown_exists):
            write("Everything in sync.\n")
コード例 #2
0
    def handle(self, *args, **options):
        write = self.stderr.write
        fix = options["fix"]
        force = options["force"]
        handlers = self.get_handlers(options["resources"])
        maxops = options["max_operations"]
        if maxops is not None:
            try:
                maxops = int(maxops)
            except ValueError:
                m = "Expected integer max operations."
                raise CommandError(m)

        shutdown_timeout = options["shutdown_timeout"]
        if shutdown_timeout is not None:
            try:
                shutdown_timeout = int(shutdown_timeout)
            except ValueError:
                m = "Expected integer shutdown timeout."
                raise CommandError(m)

        remove_system_volumes = options["remove_system_volumes"]
        cascade_remove = options["cascade_remove"]

        excluded_users = options['exclude_users']
        excluded_users = set(excluded_users.split(',')
                             if excluded_users is not None else [])

        users_to_check = options['users']
        if users_to_check is not None:
            users_to_check = list(set(users_to_check.split(',')) -
                                  excluded_users)

        try:
            qh_holdings = util.get_qh_users_holdings(users_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        excluded_projects = options["exclude_projects"]
        excluded_projects = set(excluded_projects.split(',')
                                if excluded_projects is not None else [])

        projects_to_check = options["projects"]
        if projects_to_check is not None:
            projects_to_check = list(set(projects_to_check.split(',')) -
                                     excluded_projects)

        try:
            qh_project_holdings = util.get_qh_project_holdings(
                projects_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        qh_project_holdings = sorted(qh_project_holdings.items())
        qh_holdings = sorted(qh_holdings.items())
        resources = set(h[0] for h in handlers)
        dangerous = bool(resources.difference(DEFAULT_RESOURCES))

        self.stderr.write("Checking resources %s...\n" %
                          ",".join(list(resources)))

        hopts = {"cascade_remove": cascade_remove,
                 "remove_system_volumes": remove_system_volumes,
                 }
        opts = {"shutdown_timeout": shutdown_timeout}
        actions = {}
        overlimit = []
        viol_id = 0
        remains = defaultdict(list)

        if users_to_check is None:
            for resource, handle_resource, resource_type in handlers:
                if resource_type not in actions:
                    actions[resource_type] = OrderedDict()
                actual_resources = enforce.get_actual_resources(
                    resource_type, projects=projects_to_check)
                for project, project_quota in qh_project_holdings:
                    if enforce.skip_check(project, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_project_quotas(project_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for project '%s'!\n" %
                              (resource, project))
                        continue
                    if qh_pending:
                        write("Pending commission for project '%s', "
                              "resource '%s'. Skipping\n" %
                              (project, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "project", project, "",
                                          resource, qh_limit, qh_value))
                        relevant_resources = enforce.pick_project_resources(
                            actual_resources[project], users=users_to_check,
                            excluded_users=excluded_users)
                        handle_resource(viol_id, resource, relevant_resources,
                                        diff, actions, remains, options=hopts)

        for resource, handle_resource, resource_type in handlers:
            if resource_type not in actions:
                actions[resource_type] = OrderedDict()
            actual_resources = enforce.get_actual_resources(resource_type,
                                                            users_to_check)
            for user, user_quota in qh_holdings:
                if enforce.skip_check(user, users_to_check, excluded_users):
                    continue
                for source, source_quota in user_quota.iteritems():
                    if enforce.skip_check(source, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_quotas(source_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for user '%s' and source '%s'!\n" %
                              (resource, user, source))
                        continue
                    if qh_pending:
                        write("Pending commission for user '%s', source '%s', "
                              "resource '%s'. Skipping\n" %
                              (user, source, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "user", user, source,
                                          resource, qh_limit, qh_value))
                        relevant_resources = actual_resources[source][user]
                        handle_resource(viol_id, resource, relevant_resources,
                                        diff, actions, remains, options=hopts)

        if not overlimit:
            write("No violations.\n")
            return

        headers = ("#", "Type", "Holder", "Source", "Resource", "Limit",
                   "Usage")
        pprint_table(self.stdout, overlimit, headers,
                     options["output_format"], title="Violations")

        if any(actions.values()):
            self.stdout.write("\n")
            if fix:
                if dangerous and not force:
                    write("You are enforcing resources that may permanently "
                          "remove a vm or volume.\n")
                    self.confirm()
                write("Applying actions. Please wait...\n")
            title = "Applied Actions" if fix else "Suggested Actions"
            log = enforce.perform_actions(actions, maxops=maxops, fix=fix,
                                          options=opts)
            headers = ("Type", "ID", "State", "Backend", "Action", "Violation")
            if fix:
                headers += ("Result",)
            pprint_table(self.stdout, log, headers,
                         options["output_format"], title=title)

        def explain(resource):
            if resource == "cyclades.disk":
                if not remove_system_volumes:
                    return (", because this would need to remove system "
                            "volumes; if you want to do so, use the "
                            "--remove-system-volumes option:")
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            elif resource in DESTROY_RESOURCES:
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            return ":"

        if remains:
            self.stderr.write("\n")
            for resource, viols in remains.iteritems():
                self.stderr.write(
                    "The following violations for resource '%s' "
                    "could not be resolved%s\n"
                    % (resource, explain(resource)))
                self.stderr.write("  %s\n" % ",".join(map(str, viols)))
コード例 #3
0
    def handle(self, *args, **options):
        write = self.stderr.write
        userid = options['userid']
        project = options["project"]

        # Get holdings from Cyclades DB
        db_holdings = util.get_db_holdings(user=userid, project=project)
        db_project_holdings = util.get_db_holdings(project=project,
                                                   for_users=False)

        # Get holdings from QuotaHolder
        try:
            qh_holdings = util.get_qh_users_holdings(
                [userid] if userid is not None else None,
                [project] if project is not None else None)
            qh_project_holdings = util.get_qh_project_holdings(
                [project] if project is not None else None)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        unsynced_users, users_pending, users_unknown =\
            reconcile.check_users(self.stderr, quotas.RESOURCES,
                                  db_holdings, qh_holdings)

        unsynced_projects, projects_pending, projects_unknown =\
            reconcile.check_projects(self.stderr, quotas.RESOURCES,
                                     db_project_holdings, qh_project_holdings)
        pending_exists = users_pending or projects_pending
        unknown_exists = users_unknown or projects_unknown

        headers = ("Type", "Holder", "Source", "Resource", "Database",
                   "Quotaholder")
        unsynced = unsynced_users + unsynced_projects
        if unsynced:
            pprint_table(self.stdout, unsynced, headers)
            if options["fix"]:
                qh = quotas.Quotaholder.get()
                force = options["force"]
                name = ("client: reconcile-resources-cyclades, time: %s" %
                        datetime.now())
                user_provisions = reconcile.create_user_provisions(
                    unsynced_users)
                project_provisions = reconcile.create_project_provisions(
                    unsynced_projects)
                try:
                    qh.issue_commission_generic(user_provisions,
                                                project_provisions,
                                                name=name,
                                                force=force,
                                                auto_accept=True)
                except quotas.errors.QuotaLimit:
                    write("Reconciling failed because a limit has been "
                          "reached. Use --force to ignore the check.\n")
                    return
                write("Fixed unsynced resources\n")

        if pending_exists:
            write("Found pending commissions. Run 'snf-manage"
                  " reconcile-commissions-cyclades'\n")
        elif not (unsynced or unknown_exists):
            write("Everything in sync.\n")
コード例 #4
0
    def handle(self, *args, **options):
        write = self.stderr.write
        if options["list_resources"]:
            self.help_resources(options)
            exit()

        fix = options["fix"]
        force = options["force"]
        handlers = self.get_handlers(options["resources"],
                                     options["soft_resources"])
        maxops = options["max_operations"]
        if maxops is not None:
            try:
                maxops = int(maxops)
            except ValueError:
                m = "Expected integer max operations."
                raise CommandError(m)

        shutdown_timeout = options["shutdown_timeout"]
        if shutdown_timeout is not None:
            try:
                shutdown_timeout = int(shutdown_timeout)
            except ValueError:
                m = "Expected integer shutdown timeout."
                raise CommandError(m)

        remove_system_volumes = options["remove_system_volumes"]
        cascade_remove = options["cascade_remove"]

        excluded_users = options['exclude_users']
        excluded_users = set(
            excluded_users.split(',') if excluded_users is not None else [])

        users_to_check = options['users']
        if users_to_check is not None:
            users_to_check = list(
                set(users_to_check.split(',')) - excluded_users)

        try:
            qh_holdings = util.get_qh_users_holdings(users_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        excluded_projects = options["exclude_projects"]
        excluded_projects = set(
            excluded_projects.split(','
                                    ) if excluded_projects is not None else [])

        projects_to_check = options["projects"]
        if projects_to_check is not None:
            projects_to_check = list(
                set(projects_to_check.split(',')) - excluded_projects)

        try:
            qh_project_holdings = util.get_qh_project_holdings(
                projects_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        qh_project_holdings = sorted(qh_project_holdings.items())
        qh_holdings = sorted(qh_holdings.items())
        resources = set(h[0] for h in handlers if not h[1])
        dangerous = bool(resources.intersection(DESTROY_RESOURCES))
        if resources:
            self.stderr.write("Checking resources %s...\n" %
                              ",".join(list(resources)))
        resources_soft = set(h[0] for h in handlers if h[1])
        if resources_soft:
            self.stderr.write("Checking resources for soft enforce %s...\n" %
                              ",".join(list(resources_soft)))
        if not resources and not resources_soft:
            self.stderr.write("No resources specified; use '--list-resources' "
                              "to list available resources.\n")
            exit()

        hopts = {
            "cascade_remove": cascade_remove,
            "remove_system_volumes": remove_system_volumes,
        }
        opts = {"shutdown_timeout": shutdown_timeout}
        actions = {}
        overlimit = []
        viol_id = 0
        remains = defaultdict(list)

        if users_to_check is None:
            for resource, is_soft, handle_resource, resource_type in handlers:
                if resource_type not in actions:
                    actions[resource_type] = OrderedDict()
                actual_resources = enforce.get_actual_resources(
                    resource_type, projects=projects_to_check)
                for project, project_quota in qh_project_holdings:
                    if enforce.skip_check(project, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_project_quotas(project_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for project '%s'!\n" % (resource, project))
                        continue
                    if qh_pending:
                        write("Pending commission for project '%s', "
                              "resource '%s'. Skipping\n" %
                              (project, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "project", project, "",
                                          resource, qh_limit, qh_value))
                        relevant_resources = enforce.pick_project_resources(
                            actual_resources[project],
                            users=users_to_check,
                            excluded_users=excluded_users)
                        handle_resource(viol_id,
                                        resource,
                                        relevant_resources,
                                        diff,
                                        actions,
                                        remains,
                                        options=hopts)

        for resource, is_soft, handle_resource, resource_type in handlers:
            if resource_type not in actions:
                actions[resource_type] = OrderedDict()
            actual_resources = enforce.get_actual_resources(
                resource_type, users_to_check)
            for user, user_quota in qh_holdings:
                if enforce.skip_check(user, users_to_check, excluded_users):
                    continue
                for source, source_quota in user_quota.iteritems():
                    if enforce.skip_check(source, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_quotas(source_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for user '%s' and source '%s'!\n" %
                              (resource, user, source))
                        continue
                    if qh_pending:
                        write("Pending commission for user '%s', source '%s', "
                              "resource '%s'. Skipping\n" %
                              (user, source, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "user", user, source,
                                          resource, qh_limit, qh_value))
                        relevant_resources = actual_resources[source][user]
                        handle_resource(viol_id,
                                        resource,
                                        relevant_resources,
                                        diff,
                                        actions,
                                        remains,
                                        options=hopts)

        if not overlimit:
            write("No violations.\n")
            return

        headers = ("#", "Type", "Holder", "Source", "Resource", "Limit",
                   "Usage")
        pprint_table(self.stdout,
                     overlimit,
                     headers,
                     options["output_format"],
                     title="Violations")

        if any(actions.values()):
            self.stdout.write("\n")
            if fix:
                if dangerous and not force:
                    write("You are enforcing resources that may permanently "
                          "remove a VM, volume, or IP.\n")
                    self.confirm()
                write("Applying actions. Please wait...\n")
            title = "Applied Actions" if fix else "Suggested Actions"
            log = enforce.perform_actions(actions,
                                          maxops=maxops,
                                          fix=fix,
                                          options=opts)
            headers = ("Type", "ID", "State", "Backend", "Action", "Violation")
            if fix:
                headers += ("Result", )
            pprint_table(self.stdout,
                         log,
                         headers,
                         options["output_format"],
                         title=title)

        def explain(resource):
            if resource == "cyclades.disk":
                if not remove_system_volumes:
                    return (", because this would need to remove system "
                            "volumes; if you want to do so, use the "
                            "--remove-system-volumes option:")
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            elif resource in DESTROY_RESOURCES:
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            return ":"

        if remains:
            self.stderr.write("\n")
            for resource, viols in remains.iteritems():
                self.stderr.write("The following violations for resource '%s' "
                                  "could not be resolved%s\n" %
                                  (resource, explain(resource)))
                self.stderr.write("  %s\n" % ",".join(map(str, viols)))