CLI: Add "ara expire" to expire old running objects

This new command will allow to change the status of objects that have
been running for more than 24 hours (by default) without being updated
and so we are expecting these to never finish.

Change-Id: Iedbac84188fc4202f51e405d2fae0a35d34b3a1d
Related: https://github.com/ansible-community/ara/issues/26
This commit is contained in:
David Moreau Simard 2020-09-17 10:22:12 -04:00
parent c3874e54f3
commit c639f438de
No known key found for this signature in database
GPG Key ID: 7D4729EC4E64E8B7
3 changed files with 122 additions and 0 deletions

101
ara/cli/expire.py Normal file
View File

@ -0,0 +1,101 @@
# Copyright (c) 2020 The ARA Records Ansible authors
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# See https://github.com/ansible-community/ara/issues/26 for rationale on expiring
import logging
import os
import sys
from datetime import datetime, timedelta
from cliff.command import Command
from ara.cli.base import global_arguments
from ara.clients.utils import get_client
class ExpireObjects(Command):
""" Expires objects that have been in the running state for too long """
log = logging.getLogger(__name__)
expired = 0
def get_parser(self, prog_name):
parser = super(ExpireObjects, self).get_parser(prog_name)
parser = global_arguments(parser)
# fmt: off
parser.add_argument(
"--hours",
type=int,
default=24,
help="Expires objects that have been running state for this many hours (default: 24)"
)
parser.add_argument(
"--order",
metavar="<order>",
default="started",
help=(
"Orders objects by a field ('id', 'created', 'updated', 'started', 'ended')\n"
"Defaults to 'started' descending so the oldest objects would be expired first.\n"
"The order can be reversed by using '-': ara expire --order=-started"
),
)
parser.add_argument(
"--limit",
metavar="<limit>",
default=os.environ.get("ARA_CLI_LIMIT", 200),
help=("Only expire the first <limit> determined by the ordering. Defaults to ARA_CLI_LIMIT or 200.")
)
parser.add_argument(
"--confirm",
action="store_true",
help="Confirm expiration of objects, otherwise runs without expiring any objects",
)
# fmt: on
return parser
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)

View File

@ -9,6 +9,26 @@ ara
.. command-output:: ara --help
ara expire
----------
.. note::
This command requires write privileges.
You can read more about read and write permissions :ref:`here <api-security:user management>`.
.. command-output:: ara expire --help
Examples:
.. code-block:: bash
# Return which objects would be expired by ommitting --confirm
ara expire
# Expire running objects without updates faster than the default
ara expire --hours 4 --confirm
ara playbook list
-----------------

View File

@ -35,6 +35,7 @@ console_scripts =
ara-manage = ara.server.__main__:main
ara.cli =
expire = ara.cli.expire:ExpireObjects
playbook list = ara.cli.playbook:PlaybookList
playbook show = ara.cli.playbook:PlaybookShow
playbook delete = ara.cli.playbook:PlaybookDelete