Пример #1
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        if not args.confirm:
            self.log.info("--confirm was not specified, no playbooks will be deleted")

        query = {}
        if args.label is not None:
            query["label"] = args.label

        if args.ansible_version is not None:
            query["ansible_version"] = args.ansible_version

        if args.controller is not None:
            query["controller"] = args.controller

        if args.name is not None:
            query["name"] = args.name

        if args.path is not None:
            query["path"] = args.path

        if args.status is not None:
            query["status"] = args.status

        # generate a timestamp from n days ago in a format we can query the API with
        # ex: 2019-11-21T00:57:41.702229
        query["started_before"] = (datetime.now() - timedelta(days=args.days)).isoformat()
        query["order"] = args.order
        query["limit"] = args.limit

        playbooks = client.get("/api/v1/playbooks", **query)

        # TODO: Improve client validation and exception handling
        if "count" not in playbooks:
            # If we didn't get an answer we can parse, it's probably due to an error 500, 403, 401, etc.
            # The client would have logged the error.
            self.log.error("Client failed to retrieve results, see logs for ara.clients.offline or ara.clients.http.")
            sys.exit(1)

        self.log.info("Found %s playbooks matching query" % playbooks["count"])
        for playbook in playbooks["results"]:
            if not args.confirm:
                msg = "Dry-run: playbook {id} ({path}) would have been deleted, start date: {started}"
                self.log.info(msg.format(id=playbook["id"], path=playbook["path"], started=playbook["started"]))
            else:
                msg = "Deleting playbook {id} ({path}), start date: {started}"
                self.log.info(msg.format(id=playbook["id"], path=playbook["path"], started=playbook["started"]))
                client.delete("/api/v1/playbooks/%s" % playbook["id"])
                self.deleted += 1

        self.log.info("%s playbooks deleted" % self.deleted)
Пример #2
0
    def set_options(self, task_keys=None, var_options=None, direct=None):
        super(CallbackModule, self).set_options(task_keys=task_keys,
                                                var_options=var_options,
                                                direct=direct)

        self.argument_labels = self.get_option("argument_labels")
        self.default_labels = self.get_option("default_labels")
        self.ignored_facts = self.get_option("ignored_facts")
        self.ignored_arguments = self.get_option("ignored_arguments")
        self.ignored_files = self.get_option("ignored_files")

        client = self.get_option("api_client")
        endpoint = self.get_option("api_server")
        timeout = self.get_option("api_timeout")
        username = self.get_option("api_username")
        password = self.get_option("api_password")
        insecure = self.get_option("api_insecure")
        self.client = client_utils.get_client(
            client=client,
            endpoint=endpoint,
            timeout=timeout,
            username=username,
            password=password,
            verify=False if insecure else True,
        )
Пример #3
0
    def set_options(self, task_keys=None, var_options=None, direct=None):
        super(CallbackModule, self).set_options(task_keys=task_keys,
                                                var_options=var_options,
                                                direct=direct)

        self.argument_labels = self.get_option("argument_labels")
        self.default_labels = self.get_option("default_labels")
        self.ignored_facts = self.get_option("ignored_facts")
        self.ignored_arguments = self.get_option("ignored_arguments")
        self.ignored_files = self.get_option("ignored_files")

        client = self.get_option("api_client")
        endpoint = self.get_option("api_server")
        timeout = self.get_option("api_timeout")
        username = self.get_option("api_username")
        password = self.get_option("api_password")
        insecure = self.get_option("api_insecure")
        self.client = client_utils.get_client(
            client=client,
            endpoint=endpoint,
            timeout=timeout,
            username=username,
            password=password,
            verify=False if insecure else True,
        )

        # TODO: Consider un-hardcoding this and plumbing pool_maxsize to requests.adapters.HTTPAdapter.
        #       In the meantime default to 4 so we don't go above requests.adapters.DEFAULT_POOLSIZE.
        #       Otherwise we can hit "urllib3.connectionpool: Connection pool is full"
        # TODO: Using >= 2 threads with the offline client can result in execution getting locked up
        self.thread_count = 1 if client == "offline" else 4
        self.global_threads = ThreadPoolExecutor(max_workers=self.thread_count)
        self.log.debug("working with %s thread(s)" % self.thread_count)
Пример #4
0
    def set_options(self, task_keys=None, var_options=None, direct=None):
        super(CallbackModule, self).set_options(task_keys=task_keys,
                                                var_options=var_options,
                                                direct=direct)

        self.argument_labels = self.get_option("argument_labels")
        self.default_labels = self.get_option("default_labels")
        self.ignored_facts = self.get_option("ignored_facts")
        self.ignored_arguments = self.get_option("ignored_arguments")
        self.ignored_files = self.get_option("ignored_files")

        client = self.get_option("api_client")
        endpoint = self.get_option("api_server")
        timeout = self.get_option("api_timeout")
        username = self.get_option("api_username")
        password = self.get_option("api_password")
        insecure = self.get_option("api_insecure")
        self.client = client_utils.get_client(
            client=client,
            endpoint=endpoint,
            timeout=timeout,
            username=username,
            password=password,
            verify=False if insecure else True,
        )

        # TODO: Consider un-hardcoding this and plumbing pool_maxsize to requests.adapters.HTTPAdapter.
        #       In the meantime default to 4 so we don't go above requests.adapters.DEFAULT_POOLSIZE.
        #       Otherwise we can hit "urllib3.connectionpool: Connection pool is full"
        self.callback_threads = self.get_option("callback_threads")
        if self.callback_threads > 4:
            self.callback_threads = 4
Пример #5
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        task = client.get("/api/v1/tasks/%s" % args.task_id)
        if "detail" in task and task["detail"] == "Not found.":
            self.log.error("Task not found: %s" % args.task_id)
            sys.exit(1)

        task["report"] = "%s/playbooks/%s.html" % (args.server,
                                                   task["playbook"]["id"])
        columns = (
            "id",
            "report",
            "name",
            "action",
            "status",
            "path",
            "lineno",
            "started",
            "ended",
            "duration",
            "tags",
            "handler",
        )
        return (columns, ([task[column] for column in columns]))
Пример #6
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        play = client.get("/api/v1/plays/%s" % args.play_id)
        if "detail" in play and play["detail"] == "Not found.":
            self.log.error("Play not found: %s" % args.play_id)
            sys.exit(1)

        playbook = "(%s) %s" % (play["playbook"]["id"], play["playbook"]["name"] or play["playbook"]["path"])
        play["report"] = "%s/playbooks/%s.html" % (args.server, play["playbook"]["id"])
        play["playbook"] = playbook

        # fmt: off
        columns = (
            "id",
            "report",
            "status",
            "name",
            "playbook",
            "started",
            "ended",
            "duration",
            "items",
        )
        # fmt: on
        return (columns, ([play[column] for column in columns]))
Пример #7
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.status is not None:
            query["status"] = args.status

        if args.name is not None:
            query["name"] = args.name

        if args.path is not None:
            query["path"] = args.path

        if args.action is not None:
            query["action"] = args.action

        query["order"] = args.order
        query["limit"] = args.limit

        tasks = client.get("/api/v1/tasks", **query)

        for task in tasks["results"]:
            task["results"] = task["items"]["results"]
            if args.resolve:
                playbook = cli_utils.get_playbook(client, task["playbook"])
                # Paths can easily take up too much width real estate
                if not args.long:
                    task["playbook"] = "(%s) %s" % (playbook["id"],
                                                    cli_utils.truncatepath(
                                                        playbook["path"], 50))
                else:
                    task["playbook"] = "(%s) %s" % (playbook["id"],
                                                    playbook["path"])

                if args.long:
                    play = cli_utils.get_play(client, task["play"])
                    task["play"] = "(%s) %s" % (play["id"], play["name"])

        # fmt: off
        if args.long:
            columns = ("id", "status", "results", "action", "name", "tags",
                       "path", "lineno", "handler", "playbook", "play",
                       "started", "duration")
        else:
            columns = ("id", "status", "results", "action", "name", "playbook",
                       "started", "duration")
        # fmt: off
        return (columns, ([task[column] for column in columns]
                          for task in tasks["results"]))
Пример #8
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.label is not None:
            query["label"] = args.label

        if args.controller is not None:
            query["controller"] = args.controller

        if args.name is not None:
            query["name"] = args.name

        if args.path is not None:
            query["path"] = args.path

        if args.status is not None:
            query["status"] = args.status

        query["order"] = args.order
        query["limit"] = args.limit

        playbooks = client.get("/api/v1/playbooks", **query)
        for playbook in playbooks["results"]:
            # Send items to columns
            playbook["plays"] = playbook["items"]["plays"]
            playbook["tasks"] = playbook["items"]["tasks"]
            playbook["results"] = playbook["items"]["results"]
            playbook["hosts"] = playbook["items"]["hosts"]
            playbook["files"] = playbook["items"]["files"]
            playbook["records"] = playbook["items"]["records"]
            # Paths can easily take up too much width real estate
            if not args.long:
                playbook["path"] = cli_utils.truncatepath(playbook["path"], 50)

        # fmt: off
        if args.long:
            columns = ("id", "status", "controller", "name", "path", "plays",
                       "tasks", "results", "hosts", "files", "records",
                       "started", "duration")
        else:
            columns = ("id", "status", "controller", "path", "tasks",
                       "results", "hosts", "started", "duration")
        return (columns, ([playbook[column] for column in columns]
                          for playbook in playbooks["results"]))
Пример #9
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.name is not None:
            query["name"] = args.name

        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.with_changed:
            query["changed__gt"] = 0
        if args.without_changed:
            query["changed__lt"] = 1
        if args.with_failed:
            query["failed__gt"] = 0
        if args.without_failed:
            query["failed__lt"] = 1
        if args.with_unreachable:
            query["unreachable__gt"] = 0
        if args.without_unreachable:
            query["unreachable__lt"] = 1

        query["order"] = args.order
        query["limit"] = args.limit

        hosts = client.get("/api/v1/hosts", **query)

        if args.resolve:
            for host in hosts["results"]:
                playbook = cli_utils.get_playbook(client, host["playbook"])
                # Paths can easily take up too much width real estate
                if not args.long:
                    host["playbook"] = "(%s) %s" % (playbook["id"],
                                                    cli_utils.truncatepath(
                                                        playbook["path"], 50))
                else:
                    host["playbook"] = "(%s) %s" % (playbook["id"],
                                                    playbook["path"])

        columns = ("id", "name", "playbook", "changed", "failed", "ok",
                   "skipped", "unreachable", "updated")
        # fmt: off
        return (columns, ([host[column] for column in columns]
                          for host in hosts["results"]))
Пример #10
0
Файл: prune.py Проект: zdtsw/ara
    def handle(self, *args, **options):
        client = options.get("client")
        endpoint = options.get("endpoint")
        username = options.get("username")
        password = options.get("password")
        insecure = options.get("insecure")
        timeout = options.get("timeout")
        days = options.get("days")
        confirm = options.get("confirm")

        # Get an instance of either an offline or http client with the specified parameters.
        # When using the offline client, don't run SQL migrations.
        api_client = get_client(
            client=client,
            endpoint=endpoint,
            username=username,
            password=password,
            verify=False if insecure else True,
            timeout=timeout,
            run_sql_migrations=False,
        )

        if not confirm:
            logger.info("--confirm was not specified, no playbooks will be deleted")

        # generate a timestamp from n days ago in a format we can query the API with
        # ex: 2019-11-21T00:57:41.702229
        limit_date = (datetime.now() - timedelta(days=days)).isoformat()

        logger.info("Querying %s/api/v1/playbooks/?started_before=%s" % (endpoint, limit_date))
        playbooks = api_client.get("/api/v1/playbooks", started_before=limit_date)

        # TODO: Improve client validation and exception handling
        if "count" not in playbooks:
            # If we didn't get an answer we can parse, it's probably due to an error 500, 403, 401, etc.
            # The client would have logged the error.
            logger.error("Client failed to retrieve results, see logs for ara.clients.offline or ara.clients.http.")
            sys.exit(1)

        logger.info("Found %s playbooks matching query" % playbooks["count"])

        for playbook in playbooks["results"]:
            if not confirm:
                msg = "Dry-run: playbook {id} ({path}) would have been deleted, start date: {started}"
                logger.info(msg.format(id=playbook["id"], path=playbook["path"], started=playbook["started"]))
            else:
                msg = "Deleting playbook {id} ({path}), start date: {started}"
                logger.info(msg.format(id=playbook["id"], path=playbook["path"], started=playbook["started"]))
                api_client.delete("/api/v1/playbooks/%s" % playbook["id"])
                self.deleted += 1

        logger.info("%s playbooks deleted" % self.deleted)
Пример #11
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        client.delete("/api/v1/tasks/%s" % args.task_id)
Пример #12
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.name is not None:
            query["name"] = args.name

        if args.uuid is not None:
            query["uuid"] = args.uuid

        if args.status is not None:
            query["status"] = args.status

        query["order"] = args.order
        query["limit"] = args.limit

        plays = client.get("/api/v1/plays", **query)
        for play in plays["results"]:
            # Send items to columns
            play["tasks"] = play["items"]["tasks"]
            play["results"] = play["items"]["results"]

            if args.resolve:
                playbook = cli_utils.get_playbook(client, play["playbook"])
                # Paths can easily take up too much width real estate
                if not args.long:
                    play["playbook"] = "(%s) %s" % (playbook["id"], cli_utils.truncatepath(playbook["path"], 50))
                else:
                    play["playbook"] = "(%s) %s" % (playbook["id"], playbook["path"])

        columns = ("id", "status", "name", "playbook", "tasks", "results", "started", "duration")
        # fmt: off
        return (
            columns, (
                [play[column] for column in columns]
                for play in plays["results"]
            )
        )
Пример #13
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        if not args.confirm:
            self.log.info("--confirm was not specified, no objects will be expired")

        query = dict(status="running")
        # generate a timestamp from n days ago in a format we can query the API with
        # ex: 2019-11-21T00:57:41.702229
        query["updated_before"] = (datetime.now() - timedelta(hours=args.hours)).isoformat()
        query["order"] = args.order
        query["limit"] = args.limit

        endpoints = ["/api/v1/playbooks", "/api/v1/plays", "/api/v1/tasks"]
        for endpoint in endpoints:
            objects = client.get(endpoint, **query)
            self.log.info("Found %s objects matching query on %s" % (objects["count"], endpoint))
            # TODO: Improve client validation and exception handling
            if "count" not in objects:
                # If we didn't get an answer we can parse, it's probably due to an error 500, 403, 401, etc.
                # The client would have logged the error.
                self.log.error(
                    "Client failed to retrieve results, see logs for ara.clients.offline or ara.clients.http."
                )
                sys.exit(1)

            for obj in objects["results"]:
                link = "%s/%s" % (endpoint, obj["id"])
                if not args.confirm:
                    self.log.info(
                        "Dry-run: %s would have been expired, status is running since %s" % (link, obj["updated"])
                    )
                else:
                    self.log.info("Expiring %s, status is running since %s" % (link, obj["updated"]))
                    client.patch(link, status="expired")
                    self.expired += 1

        self.log.info("%s objects expired" % self.expired)
Пример #14
0
    def set_options(self, task_keys=None, var_options=None, direct=None):
        super(CallbackModule, self).set_options(task_keys=task_keys,
                                                var_options=var_options,
                                                direct=direct)

        self.ignored_facts = self.get_option("ignored_facts")
        self.ignored_arguments = self.get_option("ignored_arguments")

        client = self.get_option("api_client")
        endpoint = self.get_option("api_server")
        timeout = self.get_option("api_timeout")
        username = self.get_option("api_username")
        password = self.get_option("api_password")
        self.client = client_utils.get_client(client=client,
                                              endpoint=endpoint,
                                              timeout=timeout,
                                              username=username,
                                              password=password)
Пример #15
0
    def take_action(self, args):
        # TODO: Render json properly in pretty tables
        if args.formatter == "table":
            self.log.warn(
                "Rendering using default table formatter, use '-f yaml' or '-f json' for improved display."
            )

        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        record = client.get("/api/v1/records/%s" % args.record_id)
        if "detail" in record and record["detail"] == "Not found.":
            self.log.error("Record not found: %s" % args.record_id)
            sys.exit(1)

        playbook = "(%s) %s" % (record["playbook"]["id"],
                                record["playbook"]["name"]
                                or record["playbook"]["path"])
        record["report"] = "%s/playbooks/%s.html" % (args.server,
                                                     record["playbook"]["id"])
        record["playbook"] = playbook

        # fmt: off
        columns = (
            "id",
            "report",
            "playbook",
            "key",
            "value",
            "created",
            "updated",
        )
        # fmt: on
        return (columns, ([record[column] for column in columns]))
Пример #16
0
    def take_action(self, args):
        # TODO: Render json properly in pretty tables
        if args.formatter == "table":
            self.log.warn(
                "Rendering using default table formatter, use '-f yaml' or '-f json' for improved display."
            )

        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        playbook = client.get("/api/v1/playbooks/%s" % args.playbook_id)
        if "detail" in playbook and playbook["detail"] == "Not found.":
            self.log.error("Playbook not found: %s" % args.playbook_id)
            sys.exit(1)

        playbook["report"] = "%s/playbooks/%s.html" % (args.server,
                                                       args.playbook_id)
        columns = (
            "id",
            "report",
            "controller",
            "status",
            "path",
            "started",
            "ended",
            "duration",
            "ansible_version",
            "items",
            "labels",
            "arguments",
        )
        return (columns, ([playbook[column] for column in columns]))
Пример #17
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.key is not None:
            query["key"] = args.key

        query["order"] = args.order
        query["limit"] = args.limit

        records = client.get("/api/v1/records", **query)
        if args.resolve:
            for record in records["results"]:
                playbook = cli_utils.get_playbook(client, record["playbook"])
                # Paths can easily take up too much width real estate
                if not args.long:
                    record["playbook"] = "(%s) %s" % (
                        playbook["id"],
                        cli_utils.truncatepath(playbook["path"], 50))
                else:
                    record["playbook"] = "(%s) %s" % (playbook["id"],
                                                      playbook["path"])

        columns = ("id", "key", "type", "playbook", "updated")
        # fmt: off
        return (columns, ([record[column] for column in columns]
                          for record in records["results"]))
Пример #18
0
    def take_action(self, args):
        # TODO: Render json properly in pretty tables
        if args.with_facts and args.formatter == "table":
            self.log.warn(
                "Rendering using default table formatter, use '-f yaml' or '-f json' for improved display."
            )

        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        host = client.get("/api/v1/hosts/%s" % args.host_id)
        if "detail" in host and host["detail"] == "Not found.":
            self.log.error("Host not found: %s" % args.host_id)
            sys.exit(1)

        host["report"] = "%s/playbooks/%s.html" % (args.server,
                                                   host["playbook"]["id"])
        if args.with_facts:
            # fmt: off
            columns = ("id", "report", "name", "changed", "failed", "ok",
                       "skipped", "unreachable", "facts", "updated")
            # fmt: on
        else:
            # fmt: off
            columns = ("id", "report", "name", "changed", "failed", "ok",
                       "skipped", "unreachable", "updated")
            # fmt: on
        return (columns, ([host[column] for column in columns]))
Пример #19
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.status is not None:
            query["status"] = args.status

        if args.name is not None:
            query["name"] = args.name

        if args.path is not None:
            query["path"] = args.path

        if args.action is not None:
            query["action"] = args.action

        query["order"] = args.order
        query["limit"] = args.limit

        tasks = client.get("/api/v1/tasks", **query)

        # TODO: This could probably be made more efficient without needing to iterate a second time
        # Group tasks by aggregate
        aggregate = {}
        for task in tasks["results"]:
            item = task[args.aggregate]
            if item not in aggregate:
                aggregate[item] = []
            aggregate[item].append(task)

        data = {}
        for item, tasks in aggregate.items():
            data[item] = {
                "count": len(tasks),
                "results": 0,
                "expired": 0,
                "running": 0,
                "completed": 0,
                "unknown": 0,
                "duration_total": "00:00:00.000000",
            }

            if args.aggregate == "path" and not args.long:
                data[item]["aggregate"] = cli_utils.truncatepath(item, 50)
            else:
                data[item]["aggregate"] = item

            for task in tasks:
                for status in ["running", "completed", "expired", "unknown"]:
                    if task["status"] == status:
                        data[item][status] += 1

                data[item]["results"] += task["items"]["results"]

                if task["duration"] is not None:
                    data[item]["duration_total"] = cli_utils.sum_timedelta(
                        task["duration"], data[item]["duration_total"])

            data[item]["duration_avg"] = cli_utils.avg_timedelta(
                data[item]["duration_total"], data[item]["count"])

        # fmt: off
        if args.long:
            columns = (
                "aggregate",
                "count",
                "results",
                "duration_total",
                "duration_avg",
                "completed",
                "running",
                "expired",
                "unknown",
            )
        else:
            columns = (
                "aggregate",
                "count",
                "results",
                "duration_total",
                "duration_avg",
            )

        return (columns, ([data[action][column] for column in columns]
                          for action in sorted(data.keys())))
Пример #20
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.name is not None:
            query["name"] = args.name

        if args.playbook is not None:
            query["playbook"] = args.playbook

        if args.with_changed:
            query["changed__gt"] = 0
        if args.without_changed:
            query["changed__lt"] = 1
        if args.with_failed:
            query["failed__gt"] = 0
        if args.without_failed:
            query["failed__lt"] = 1
        if args.with_unreachable:
            query["unreachable__gt"] = 0
        if args.without_unreachable:
            query["unreachable__lt"] = 1

        query["order"] = args.order
        query["limit"] = args.limit

        resp = client.get("/api/v1/hosts", **query)

        # Group hosts by name
        hosts = {}
        for host in resp["results"]:
            name = host["name"]
            if name not in hosts:
                hosts[name] = []
            hosts[name].append(host)

        data = {}
        for name, host_results in hosts.items():
            data[name] = {
                "name": name,
                "count": len(host_results),
                "changed": 0,
                "failed": 0,
                "ok": 0,
                "skipped": 0,
                "unreachable": 0,
            }

            for host in host_results:
                for status in [
                        "changed", "failed", "ok", "skipped", "unreachable"
                ]:
                    data[name][status] += host[status]

        columns = ("name", "count", "changed", "failed", "ok", "skipped",
                   "unreachable")
        # fmt: off
        return (columns, ([data[host][column] for column in columns]
                          for host in sorted(data.keys())))
Пример #21
0
    def take_action(self, args):
        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )
        query = {}
        if args.playbook is not None:
            query["playbook"] = args.playbook
        if args.play is not None:
            query["play"] = args.play
        if args.task is not None:
            query["task"] = args.task
        if args.host is not None:
            query["host"] = args.host

        if args.status is not None:
            query["status"] = args.status

        if args.changed:
            query["changed"] = args.changed

        query["ignore_errors"] = args.ignore_errors
        query["order"] = args.order
        query["limit"] = args.limit

        results = client.get("/api/v1/results", **query)

        if args.resolve:
            for result in results["results"]:
                playbook = cli_utils.get_playbook(client, result["playbook"])
                # Paths can easily take up too much width real estate
                if not args.long:
                    result["playbook"] = "(%s) %s" % (
                        playbook["id"],
                        cli_utils.truncatepath(playbook["path"], 50))
                else:
                    result["playbook"] = "(%s) %s" % (playbook["id"],
                                                      playbook["path"])

                task = cli_utils.get_task(client, result["task"])
                result["task"] = "(%s) %s" % (task["id"], task["name"])

                host = cli_utils.get_host(client, result["host"])
                result["host"] = "(%s) %s" % (host["id"], host["name"])

                if args.long:
                    play = cli_utils.get_play(client, result["play"])
                    result["play"] = "(%s) %s" % (play["id"], play["name"])

        # fmt: off
        if args.long:
            columns = (
                "id",
                "status",
                "changed",
                "ignore_errors",
                "playbook",
                "play",
                "task",
                "host",
                "started",
                "duration",
            )
        else:
            columns = (
                "id",
                "status",
                "playbook",
                "task",
                "host",
                "started",
                "duration",
            )

        return (columns, ([result[column] for column in columns]
                          for result in results["results"]))
Пример #22
0
    def take_action(self, args):
        # TODO: Render json properly in pretty tables
        if args.with_content and args.formatter == "table":
            self.log.warn(
                "Rendering using default table formatter, use '-f yaml' or '-f json' for improved display."
            )

        client = get_client(
            client=args.client,
            endpoint=args.server,
            timeout=args.timeout,
            username=args.username,
            password=args.password,
            verify=False if args.insecure else True,
            run_sql_migrations=False,
        )

        # TODO: Improve client to be better at handling exceptions
        result = client.get("/api/v1/results/%s" % args.result_id)
        if "detail" in result and result["detail"] == "Not found.":
            self.log.error("Result not found: %s" % args.result_id)
            sys.exit(1)

        # Parse data from playbook and format it for display
        result["ansible_version"] = result["playbook"]["ansible_version"]
        playbook = "(%s) %s" % (result["playbook"]["id"],
                                result["playbook"]["name"]
                                or result["playbook"]["path"])
        result["report"] = "%s/playbooks/%s.html" % (args.server,
                                                     result["playbook"]["id"])
        result["playbook"] = playbook

        # Parse data from play and format it for display
        play = "(%s) %s" % (result["play"]["id"], result["play"]["name"])
        result["play"] = play

        # Parse data from task and format it for display
        task = "(%s) %s" % (result["task"]["id"], result["task"]["name"])
        path = "(%s) %s:%s" % (result["task"]["file"], result["task"]["path"],
                               result["task"]["lineno"])
        result["task"] = task
        result["path"] = path

        if args.with_content:
            columns = (
                "id",
                "report",
                "status",
                "playbook",
                "play",
                "task",
                "path",
                "started",
                "ended",
                "duration",
                "ansible_version",
                "content",
            )
        else:
            columns = (
                "id",
                "report",
                "status",
                "playbook",
                "play",
                "task",
                "path",
                "started",
                "ended",
                "duration",
                "ansible_version",
            )
        return (columns, ([result[column] for column in columns]))