Skip to content

Commit

Permalink
Merge aa6ccd3 into 3e7e73b
Browse files Browse the repository at this point in the history
  • Loading branch information
audrium committed Oct 19, 2020
2 parents 3e7e73b + aa6ccd3 commit 1b923cd
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Authors
The list of contributors in alphabetical order:

- `Adelina Lintuluoto <https://orcid.org/0000-0002-0726-1452>`_
- `Audrius Mecionis <https://orcid.org/0000-0002-3759-1663>`_
- `Anton Khodak <https://orcid.org/0000-0003-3263-4553>`_
- `Daniel Prelipcean <https://orcid.org/0000-0002-4855-194X>`_
- `Diego Rodriguez <https://orcid.org/0000-0003-0649-2002>`_
Expand Down
3 changes: 3 additions & 0 deletions docs/cmd_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Options:
Sets log level
--help Show this message and exit.

Quota commands:
quota-show Show user quota.

Configuration commands:
ping Check connection to REANA server.
version Show version.
Expand Down
26 changes: 26 additions & 0 deletions reana_client/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,32 @@ def ping(access_token):
return {"status": "ERROR: INVALID SERVER", "error": True}


def get_user_quota(access_token):
"""Retrieve user quota usage and limits."""
try:
response, http_response = current_rs_api_client.api.get_you(
access_token=access_token
).result()
if http_response.status_code == 200:
return response["quota"]
raise Exception(
"Expected status code 200 but replied with "
"{status_code}".format(status_code=http_response.status_code)
)

except HTTPError as e:
logging.debug(
"User quotas could not be retrieved: "
"\nStatus: {}\nReason: {}\n"
"Message: {}".format(
e.response.status_code, e.response.reason, e.response.json()["message"]
)
)
raise Exception(e.response.json()["message"])
except Exception as e:
raise e


def get_workflows(
access_token,
type,
Expand Down
3 changes: 2 additions & 1 deletion reana_client/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import click
from urllib3 import disable_warnings

from reana_client.cli import workflow, files, ping, secrets
from reana_client.cli import workflow, files, ping, secrets, quotas

DEBUG_LOG_FORMAT = (
"[%(asctime)s] p%(process)s "
Expand All @@ -36,6 +36,7 @@ class ReanaCLI(click.Group):
"""REANA command line interface."""

cmd_groups = [
quotas.quota_group,
ping.configuration_group,
workflow.workflow_management_group,
workflow.workflow_execution_group,
Expand Down
128 changes: 128 additions & 0 deletions reana_client/cli/quotas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
#
# This file is part of REANA.
# Copyright (C) 2020 CERN.
#
# REANA is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""REANA client quotas related commands."""

import logging
import sys

import click
from reana_client.cli.utils import (
add_access_token_options,
check_connection,
NotRequiredIf,
)


def usage_percentage(usage, limit):
"""Usage percentage."""
if limit == 0:
return ""
return "({:.0%})".format(usage / limit)


@click.group(help="Quota commands")
def quota_group():
"""Quota commands."""
pass


@click.option(
"--resource",
"resource",
cls=NotRequiredIf,
not_required_if="resources",
help="Specify quota resource. e.g. cpu, disk.",
)
@click.option(
"--resources",
"resources",
is_flag=True,
cls=NotRequiredIf,
not_required_if="resource",
help="Print available resources",
)
@click.option(
"--report",
"report",
type=click.Choice(["limit", "usage"], case_sensitive=False),
help="Specify quota report type. e.g. limit, usage.",
)
@quota_group.command("quota-show")
@click.pass_context
@add_access_token_options
@check_connection
def quota_show(ctx, access_token, resource, resources, report): # noqa: D301
"""Show user quota.
The `quota-show` command displays quota usage for the user.
Examples: \n
\t $ reana-client quota-show --resource disk --report limit\n
\t $ reana-client quota-show --resource disk --report usage\n
\t $ reana-client quota-show --resource disk\n
\t $ reana-client quota-show --resources
"""
from reana_client.api.client import get_user_quota

from reana_commons.utils import resource_health_colors

logging.debug("command: {}".format(ctx.command_path.replace(" ", ".")))

for p in ctx.params:
logging.debug("{param}: {value}".format(param=p, value=ctx.params[p]))

try:
quota = get_user_quota(access_token)

if resources:
return click.echo("\n".join(quota.keys()))

if resource not in quota.keys():
click.echo(
click.style(
"Error: resource '{}' is not valid.\nAvailable resources are: '{}'.".format(
resource, "', '".join(sorted(quota.keys())),
),
fg="red",
),
err=True,
)
sys.exit(1)

if not report:
usage = quota[resource]["usage"]
limit = quota[resource]["limit"]
health = quota[resource]["health"]
percentage = usage_percentage(usage["raw"], limit["raw"])
limit_str = (
"out of {} used".format(limit["human_readable"])
if limit["raw"] > 0
else "used"
)
return click.echo(
click.style(
"{} {} {}".format(usage["human_readable"], limit_str, percentage),
fg=resource_health_colors.get(health),
)
)

result = (
quota[resource][report]["human_readable"]
if quota[resource]["limit"]["raw"] > 0
else "No limit set."
)
return click.echo(result)

except Exception as e:
logging.debug(str(e), exc_info=True)
click.echo(
click.style(
"Something went wrong while retreiving quota related data", fg="red"
),
err=True,
)

0 comments on commit 1b923cd

Please sign in to comment.