Skip to content

Commit

Permalink
cli: add retention-rules-list command
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonadoni committed Nov 25, 2022
1 parent c4e39fd commit ad61368
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Version 0.9.0 (UNRELEASED)
- Adds support for Python 3.11.
- Adds support for ``.reanaignore`` during file upload. Files that match ``.reanaignore`` will not be uploaded.
- Adds support for ``.gitignore`` during file upload. Files that match ``.gitignore`` will not be uploaded.
- Adds ``retention-rules-list`` command to list the retention rules of a workflow.
- Changes ``delete`` CLI command to always delete workspace.
- Changes ``delete_workflow`` API method to always delete workspace.
- Changes ``list`` to hide deleted workflows by default.
Expand Down
3 changes: 3 additions & 0 deletions docs/cmd_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Workspace file management commands:
rm Delete files from workspace.
upload Upload files and directories to workspace.

Workspace file retention commands:
retention-rules-list List the retention rules for a workflow.

Secret management commands:
secrets-add Add secrets from literal string or from file.
secrets-delete Delete user secrets by name.
Expand Down
29 changes: 29 additions & 0 deletions reana_client/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,3 +1062,32 @@ def info(access_token):
raise Exception(e.response.json()["message"])
except Exception as e:
raise e


def get_workflow_retention_rules(workflow, access_token):
"""Get the retention rules of a workflow."""
try:
(
response,
http_response,
) = current_rs_api_client.api.get_workflow_retention_rules(
workflow_id_or_name=workflow,
access_token=access_token,
).result()
if http_response.status_code == 200:
return response
else:
raise Exception(
"Expected status code 200 but replied with "
"{status_code}".format(status_code=http_response.status_code)
)

except HTTPError as e:
logging.debug(
"Workflow retention rules 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"])
5 changes: 3 additions & 2 deletions reana_client/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of REANA.
# Copyright (C) 2017, 2018, 2019, 2020, 2021 CERN.
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2022 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.
Expand All @@ -13,7 +13,7 @@
import click
from urllib3 import disable_warnings

from reana_client.cli import workflow, files, ping, secrets, quotas
from reana_client.cli import workflow, files, ping, secrets, quotas, retention_rules
from reana_client.utils import get_api_url

DEBUG_LOG_FORMAT = (
Expand Down Expand Up @@ -43,6 +43,7 @@ class ReanaCLI(click.Group):
workflow.workflow_execution_group,
workflow.interactive_group,
files.files_group,
retention_rules.retention_rules_group,
secrets.secrets_group,
]

Expand Down
73 changes: 73 additions & 0 deletions reana_client/cli/retention_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
#
# This file is part of REANA.
# Copyright (C) 2022 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 retention-rules related commands."""

import logging
import sys
from typing import Optional, Tuple

import click

from reana_client.api.client import get_workflow_retention_rules
from reana_client.cli.utils import (
add_access_token_options,
add_workflow_option,
check_connection,
display_formatted_output,
)
from reana_client.printer import display_message


@click.group(help="Workspace file retention commands")
def retention_rules_group():
"""Workspace file retention commands."""
pass


@retention_rules_group.command()
@add_workflow_option
@add_access_token_options
@check_connection
@click.option(
"--format",
"_format",
multiple=True,
help="Format output according to column titles or column values. "
"Use `<columm_name>=<column_value>` format. "
"E.g. display pattern and status of active retention rules "
"`--format workspace_files,status=active`.",
)
@click.option(
"--json",
"output_format",
flag_value="json",
default=None,
help="Get output in JSON format.",
)
def retention_rules_list(
access_token: str, workflow: str, _format: Tuple[str], output_format: Optional[str]
) -> None: # noqa: D301
"""List the retention rules for a workflow.
Example:\n
\t $ reana-client retention-rules-list -w myanalysis.42
"""
try:
rules = get_workflow_retention_rules(workflow, access_token).get(
"retention_rules", []
)
except Exception as e:
logging.debug(e, exc_info=True)
display_message(str(e), msg_type="error")
sys.exit(1)

sorted_rules = sorted(rules, key=lambda rule: rule["retention_days"])

headers = ["workspace_files", "retention_days", "apply_on", "status"]
rows = [[rule[h] or "-" for h in headers] for rule in sorted_rules]
display_formatted_output(rows, headers, _format, output_format)
46 changes: 46 additions & 0 deletions tests/test_cli_retention_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#
# This file is part of REANA.
# Copyright (C) 2022 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 retention rules tests."""

from unittest.mock import MagicMock, patch

from click.testing import CliRunner

from reana_client.cli import cli


@patch("reana_client.cli.retention_rules.get_workflow_retention_rules")
def test_retention_rules_list(mock_get_workflow_retention_rules: MagicMock):
"""Test retention-rules-list command."""
workflow_id = "123456"
workflow_name = "workflow"
access_token = "secret"
pattern = "*.tmp"
mock_get_workflow_retention_rules.return_value = {
"workflow_id": workflow_id,
"workflow_name": workflow_name,
"retention_rules": [
{
"workspace_files": pattern,
"status": "created",
"apply_on": None,
"retention_days": 42,
},
],
}

runner = CliRunner(env={"REANA_SERVER_URL": "localhost"})
result = runner.invoke(
cli, ["retention-rules-list", "-w", workflow_name, "-t", access_token]
)

assert result.exit_code == 0
assert pattern in result.output
mock_get_workflow_retention_rules.assert_called_once_with(
workflow_name, access_token
)

0 comments on commit ad61368

Please sign in to comment.