Repository: rucio/rucio

Issue:
Expose the RSE limits through rucio-admin
Motivation
----------

The RSE limits are quite hidden and should be exposed in `rse info`. It should also be possible to manipulate them.

Modification
------------

Add the limits at the bottom of the `rse info` report. Add two new subcommands, `set-limit` and `delete-limit`.



Discussion:
Depends on #4074.

Resolving patch:
diff --git a/lib/rucio/web/rest/flaskapi/v1/rses.py b/lib/rucio/web/rest/flaskapi/v1/rses.py
--- a/lib/rucio/web/rest/flaskapi/v1/rses.py
+++ b/lib/rucio/web/rest/flaskapi/v1/rses.py
@@ -21,6 +21,7 @@
 # - Hannes Hansen <hannes.jakob.hansen@cern.ch>, 2018-2019
 # - Andrew Lister <andrew.lister@stfc.ac.uk>, 2019
 # - Benedikt Ziemons <benedikt.ziemons@cern.ch>, 2020-2021
+# - David Población Criado <david.poblacion.criado@cern.ch>, 2021
 
 from json import dumps
 
@@ -875,7 +876,7 @@ def blueprint():
     usage_history_view = UsageHistory.as_view('usage_history')
     bp.add_url_rule('/<rse>/usage/history', view_func=usage_history_view, methods=['get', ])
     limits_view = Limits.as_view('limits')
-    bp.add_url_rule('/<rse>/limits', view_func=limits_view, methods=['get', 'put'])
+    bp.add_url_rule('/<rse>/limits', view_func=limits_view, methods=['get', 'put', 'delete'])
     qos_policy_view = QoSPolicy.as_view('qos_policy')
     bp.add_url_rule('/<rse>/qos_policy', view_func=qos_policy_view, methods=['get', ])
     bp.add_url_rule('/<rse>/qos_policy/<policy>', view_func=qos_policy_view, methods=['post', 'delete'])


Test patch:
diff --git a/lib/rucio/tests/test_bin_rucio.py b/lib/rucio/tests/test_bin_rucio.py
--- a/lib/rucio/tests/test_bin_rucio.py
+++ b/lib/rucio/tests/test_bin_rucio.py
@@ -33,10 +33,12 @@
 # - Radu Carpa <radu.carpa@cern.ch>, 2021
 # - Rahul Chauhan <omrahulchauhan@gmail.com>, 2021
 # - Simon Fayer <simon.fayer05@imperial.ac.uk>, 2021
+# - David Población Criado <david.poblacion.criado@cern.ch>, 2021
 
 from __future__ import print_function
 
 import os
+import random
 import re
 import unittest
 from datetime import datetime, timedelta
@@ -1532,3 +1534,44 @@ def test_list_account_usage(self):
         assert re.search('.*{0}.*{1}.*{2}.*{3}'.format(rse_exp, usage, global_limit, global_left), out) is not None
         self.account_client.set_local_account_limit(account, rse, -1)
         self.account_client.set_global_account_limit(account, rse_exp, -1)
+
+    def test_get_set_delete_limits_rse(self):
+        """CLIENT(ADMIN): Get, set and delete RSE limits"""
+        name = generate_uuid()
+        value = random.randint(0, 100000)
+        name2 = generate_uuid()
+        value2 = random.randint(0, 100000)
+        name3 = generate_uuid()
+        value3 = account_name_generator()
+        cmd = 'rucio-admin rse set-limit %s %s %s' % (self.def_rse, name, value)
+        execute(cmd)
+        cmd = 'rucio-admin rse set-limit %s %s %s' % (self.def_rse, name2, value2)
+        execute(cmd)
+        cmd = 'rucio-admin rse info %s' % self.def_rse
+        exitcode, out, err = execute(cmd)
+        assert re.search("{0}: {1}".format(name, value), out) is not None
+        assert re.search("{0}: {1}".format(name2, value2), out) is not None
+        new_value = random.randint(100001, 999999999)
+        cmd = 'rucio-admin rse set-limit %s %s %s' % (self.def_rse, name, new_value)
+        execute(cmd)
+        cmd = 'rucio-admin rse info %s' % self.def_rse
+        exitcode, out, err = execute(cmd)
+        assert re.search("{0}: {1}".format(name, new_value), out) is not None
+        assert re.search("{0}: {1}".format(name, value), out) is None
+        assert re.search("{0}: {1}".format(name2, value2), out) is not None
+        cmd = 'rucio-admin rse delete-limit %s %s' % (self.def_rse, name)
+        execute(cmd)
+        cmd = 'rucio-admin rse info %s' % self.def_rse
+        exitcode, out, err = execute(cmd)
+        assert re.search("{0}: {1}".format(name, new_value), out) is None
+        assert re.search("{0}: {1}".format(name2, value2), out) is not None
+        cmd = 'rucio-admin rse delete-limit %s %s' % (self.def_rse, name)
+        exitcode, out, err = execute(cmd)
+        assert re.search('Limit {0} not defined in RSE {1}'.format(name, self.def_rse), err) is not None
+        cmd = 'rucio-admin rse set-limit %s %s %s' % (self.def_rse, name3, value3)
+        exitcode, out, err = execute(cmd)
+        assert re.search('The RSE limit value must be an integer', err) is not None
+        cmd = 'rucio-admin rse info %s' % self.def_rse
+        exitcode, out, err = execute(cmd)
+        assert re.search("{0}: {1}".format(name3, value3), out) is None
+        assert re.search("{0}: {1}".format(name2, value2), out) is not None