Repository: rucio/rucio

Issue:
rucio-admin rse update removes default RSE-Tag
Motivation
----------
```
# rucio-admin rse info KEK-TMP-SE
...
Attributes:
===========
  fts: https://fts.usatlas.bnl.gov:8446
  naming_convention: BelleII
  ANY: True
  TMP-SE: True
  KEK-TMP-SE: True
Protocols:
==========
...
# rucio-admin rse update --setting availability_write --value False --rse KEK-TMP-SE
Updated RSE KEK-TMP-SE settings availability_write to False
# rucio-admin rse info KEK-TMP-SE
...
Attributes:
===========
  fts: https://fts.usatlas.bnl.gov:8446
  naming_convention: BelleII
  ANY: True
  TMP-SE: True
Protocols:
==========
```
Thus this command actually removes the default RSE Tag `KEK-TMP-SE: True`.

Modification
------------
The issue is that the branch in `update_rse`
https://github.com/rucio/rucio/blob/066294e11bd163f076479369946d2192cd23fcbd/lib/rucio/core/rse.py#L1205
allows the RSE name to be changed. However, the client
https://github.com/rucio/rucio/blob/066294e11bd163f076479369946d2192cd23fcbd/bin/rucio-admin#L529
sets `name` per default to the `rse`. Instead it should just set the `rse` field.

Additionally we need to consider of removing the name change entirely. I am not sure if we should support this feature, since it does not correctly change replication rules down the line.



Discussion:

Resolving patch:
diff --git a/lib/rucio/core/rse.py b/lib/rucio/core/rse.py
--- a/lib/rucio/core/rse.py
+++ b/lib/rucio/core/rse.py
@@ -16,7 +16,7 @@
 # - Vincent Garonne <vgaronne@gmail.com>, 2012-2018
 # - Ralph Vigne <ralph.vigne@cern.ch>, 2012-2015
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2012-2019
-# - Martin Barisits <martin.barisits@cern.ch>, 2013-2018
+# - Martin Barisits <martin.barisits@cern.ch>, 2013-2020
 # - Cedric Serfon <cedric.serfon@cern.ch>, 2013-2018
 # - Thomas Beermann <thomas.beermann@cern.ch>, 2014-2017
 # - Wen Guan <wguan.icedew@gmail.com>, 2015-2016
@@ -1191,7 +1191,7 @@ def update_rse(rse_id, parameters, session=None):
     param = {}
     availability_mapping = {'availability_read': 4, 'availability_write': 2, 'availability_delete': 1}
     for key in parameters:
-        if key == 'name':
+        if key == 'name' and parameters['name'] != rse:  # Needed due to wrongly setting name in pre1.22.7 clients
             param['rse'] = parameters['name']
         elif key in ['availability_read', 'availability_write', 'availability_delete']:
             if parameters[key] is True:
@@ -1202,8 +1202,8 @@ def update_rse(rse_id, parameters, session=None):
             param[key] = parameters[key]
     param['availability'] = availability
     query.update(param)
-    if 'name' in parameters:
-        add_rse_attribute(rse_id=rse_id, key=parameters['name'], value=1, session=session)
+    if 'rse' in param:
+        add_rse_attribute(rse_id=rse_id, key=parameters['name'], value=True, session=session)
         query = session.query(models.RSEAttrAssociation).filter_by(rse_id=rse_id).filter(models.RSEAttrAssociation.key == rse)
         rse_attr = query.one()
         rse_attr.delete(session=session)
diff --git a/lib/rucio/web/rest/webpy/v1/rse.py b/lib/rucio/web/rest/webpy/v1/rse.py
--- a/lib/rucio/web/rest/webpy/v1/rse.py
+++ b/lib/rucio/web/rest/webpy/v1/rse.py
@@ -18,7 +18,7 @@
 # - Thomas Beermann <thomas.beermann@cern.ch>, 2012, 2014
 # - Ralph Vigne <ralph.vigne@cern.ch>, 2013-2014
 # - Cedric Serfon <cedric.serfon@cern.ch>, 2014-2018
-# - Martin Barisits <martin.barisits@cern.ch>, 2017
+# - Martin Barisits <martin.barisits@cern.ch>, 2017-2020
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2018
 # - Hannes Hansen <hannes.jakob.hansen@cern.ch>, 2018-2019
 #


Test patch:
diff --git a/lib/rucio/tests/test_rse.py b/lib/rucio/tests/test_rse.py
--- a/lib/rucio/tests/test_rse.py
+++ b/lib/rucio/tests/test_rse.py
@@ -429,6 +429,13 @@ def test_add_rse(self):
 
     def test_update_rse(self):
         """ RSE (CLIENTS): update rse."""
+        # Check if updating RSE does not remove RSE tag
+        rse = rse_name_generator()
+        ret = self.client.add_rse(rse)
+        assert_equal(get_rse_attribute(key=rse, rse_id=get_rse_id(rse)), [True])
+        self.client.update_rse(rse, {'availability_write': False, 'availability_delete': False})
+        assert_equal(get_rse_attribute(key=rse, rse_id=get_rse_id(rse)), [True])
+
         rse = rse_name_generator()
         renamed_rse = 'renamed_rse%s' % rse
         ret = self.client.add_rse(rse)