Repository: rucio/rucio

Issue:
Error when re-adding the same rule `IndexError: tuple index out of range`
Motivation
----------

With rucio 1.16.1.

When adding a rule which already exists. Client side: 
```
# rucio add-rule data10_hi:NTUP_HI.289208._000500.root.1 1 NDGF-T1-MWTEST_DATADISK 

2018-05-15 09:13:27,815	ERROR	An unknown exception occurred.
Details: no error information passed (http status code: 500 ('internal_server_error', 'server_error', '/o\\', '\xe2\x9c\x97'))
```

Server side: 
```
[Tue May 15 09:13:27.806133 2018] [:error] [pid 9] [client 127.0.0.1:45386]     return self._delegate(fn, self.fvars, args)
[Tue May 15 09:13:27.806139 2018] [:error] [pid 9] [client 127.0.0.1:45386]   File "/usr/lib/python2.7/site-packages/web/application.py", line 462, in _delegate
[Tue May 15 09:13:27.806146 2018] [:error] [pid 9] [client 127.0.0.1:45386]     return handle_class(cls)
[Tue May 15 09:13:27.806153 2018] [:error] [pid 9] [client 127.0.0.1:45386]   File "/usr/lib/python2.7/site-packages/web/application.py", line 438, in handle_class
[Tue May 15 09:13:27.806160 2018] [:error] [pid 9] [client 127.0.0.1:45386]     return tocall(*args)
[Tue May 15 09:13:27.806167 2018] [:error] [pid 9] [client 127.0.0.1:45386]   File "/usr/lib/python2.7/site-packages/rucio/web/rest/rule.py", line 281, in POST
[Tue May 15 09:13:27.806174 2018] [:error] [pid 9] [client 127.0.0.1:45386]     raise generate_http_error(409, 'DuplicateRule', error.args[0])
[Tue May 15 09:13:27.806181 2018] [:error] [pid 9] [client 127.0.0.1:45386] IndexError: tuple index out of range
```

Modification
------------

`error.args[0]` ->  `error.args`


Permission : Fix update_replicas_states permission for ATLAS
Motivation
----------
The permission for update_replicas_states is too restrictive and should be extended to TEST endpoints




Discussion:
Can't reproduce?

```
$ rucio add-rule data10_hi:NTUP_HI.289208._000500.root.1 1 NDGF-T1-MWTEST_DATADISK
2018-05-15 11:46:41,885 ERROR   RSE excluded due to write blacklisting.
Details: RSE excluded due to write blacklisting.
```


and against 1.16.1:

```
$ rucio -H https://rucio-lb-int.cern.ch add-rule data10_hi:NTUP_HI.289208._000500.root.1 1 NDGF-T1-MWTEST_DATADISK
2018-05-15 11:47:56,291 ERROR   RSE excluded due to write blacklisting.
Details: RSE excluded due to write blacklisting.
```
Identified.

when raising DuplicateRule the error is not passed to the exception


Resolving patch:
diff --git a/lib/rucio/core/permission/atlas.py b/lib/rucio/core/permission/atlas.py
--- a/lib/rucio/core/permission/atlas.py
+++ b/lib/rucio/core/permission/atlas.py
@@ -15,7 +15,7 @@
 # Authors:
 # - Vincent Garonne <vgaronne@gmail.com>, 2016
 # - Martin Barisits <martin.barisits@cern.ch>, 2016-2018
-# - Cedric Serfon <cedric.serfon@cern.ch>, 2016-2017
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2016-2018
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2018
 
 import rucio.core.authentication
@@ -767,18 +767,15 @@ def perm_update_replicas_states(issuer, kwargs):
     for kv in list_account_attributes(account=issuer):
         if kv['key'].startswith('group-') and kv['value'] in ['admin', 'user']:
             phys_group.append(kv['key'].partition('-')[2])
+    rse_attr = list_rse_attributes(rse=rse)
     if phys_group:
-        rse_attr = list_rse_attributes(rse=rse)
         if rse_attr.get('type', '') == 'GROUPDISK':
             if rse_attr.get('physgroup', '') in phys_group:
                 return True
-
-    return rse.endswith('SCRATCHDISK')\
-        or rse.endswith('USERDISK')\
-        or rse.endswith('MOCK')\
-        or rse.endswith('LOCALGROUPDISK')\
-        or issuer == 'root'\
-        or has_account_attribute(account=issuer, key='admin')
+    else:
+        return rse_attr.get('type', '') in ['SCRATCHDISK', 'MOCK', 'LOCALGROUPDISK', 'TEST']\
+            or issuer == 'root'\
+            or has_account_attribute(account=issuer, key='admin')
 
 
 def perm_queue_requests(issuer, kwargs):
diff --git a/lib/rucio/core/rule.py b/lib/rucio/core/rule.py
--- a/lib/rucio/core/rule.py
+++ b/lib/rucio/core/rule.py
@@ -1,17 +1,25 @@
-'''
-  Copyright European Organization for Nuclear Research (CERN)
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  You may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Authors:
-  - Vincent Garonne, <vincent.garonne@cern.ch>, 2012-2018
-  - Martin Barisits, <martin.barisits@cern.ch>, 2013-2018
-  - Mario Lassnig, <mario.lassnig@cern.ch>, 2013-2015, 2017
-  - Cedric Serfon, <cedric.serfon@cern.ch>, 2014-2017
-'''
+# Copyright 2012-2018 CERN for the benefit of the ATLAS collaboration.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Authors:
+# - Vincent Garonne <vgaronne@gmail.com>, 2012-2018
+# - Mario Lassnig <mario.lassnig@cern.ch>, 2013-2018
+# - Martin Barisits <martin.barisits@cern.ch>, 2013-2018
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2014-2017
+# - David Cameron <d.g.cameron@gmail.com>, 2014
+# - Joaquin Bogado <jbogado@linti.unlp.edu.ar>, 2014-2018
+# - Thomas Beermann <thomas.beermann@cern.ch>, 2014-2015
 
 import json
 import logging
@@ -198,7 +206,7 @@ def add_rule(dids, account, copies, rse_expression, grouping, weight, lifetime,
                        or match('.*1062.*Duplicate entry.*for key.*', str(error.args[0]))\
                        or match('.*IntegrityError.*duplicate key value violates unique constraint.*', error.args[0]) \
                        or match('.*sqlite3.IntegrityError.*are not unique.*', error.args[0]):
-                        raise DuplicateRule()
+                        raise DuplicateRule(error.args[0])
                     raise InvalidReplicationRule(error.args[0])
                 rule_ids.append(new_rule.id)
 
@@ -432,9 +440,9 @@ def add_rules(dids, rules, session=None):
                             new_rule.save(session=session)
                         except IntegrityError as error:
                             if match('.*ORA-00001.*', str(error.args[0])):
-                                raise DuplicateRule()
+                                raise DuplicateRule(error.args[0])
                             elif str(error.args[0]) == '(IntegrityError) UNIQUE constraint failed: rules.scope, rules.name, rules.account, rules.rse_expression, rules.copies':
-                                raise DuplicateRule()
+                                raise DuplicateRule(error.args[0])
                             raise InvalidReplicationRule(error.args[0])
 
                         rule_ids[(did.scope, did.name)].append(new_rule.id)
@@ -1221,7 +1229,7 @@ def update_rule(rule_id, options, session=None):
            or match('.*IntegrityError.*UNIQUE constraint failed.*', str(error.args[0]))\
            or match('.*1062.*Duplicate entry.*for key.*', str(error.args[0]))\
            or match('.*sqlite3.IntegrityError.*are not unique.*', error.args[0]):
-            raise DuplicateRule()
+            raise DuplicateRule(error.args[0])
         else:
             raise error
     except NoResultFound:
diff --git a/lib/rucio/vcsversion.py b/lib/rucio/vcsversion.py
--- a/lib/rucio/vcsversion.py
+++ b/lib/rucio/vcsversion.py
@@ -4,8 +4,8 @@
 '''
 VERSION_INFO = {
     'final': True,
-    'version': '1.16.1',
-    'branch_nick': 'patch-0-1_16_1_preparation',
-    'revision_id': '61f649d73cdb5c263c23559fd8e18fb368d2e5f0',
-    'revno': 6601
+    'version': '1.16.2',
+    'branch_nick': 'patch-0-1_16_2_preparation',
+    'revision_id': '84967b6a13c7e10cbf2b842997dc0bccd81d4f69',
+    'revno': 6615
 }


Test patch: