Beispiel #1
0
    def POST(self, rse, key):
        """ create rse with given RSE name.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            500 Internal Error

        :param rse: RSE name.
        :param key: Key attribute.

        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')

        try:
            value = parameter['value']
        except KeyError, e:
            raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #2
0
    def PUT(self, rse, scheme, hostname=None, port=None):
        """
        Updates attributes of an existing protocol entry. Because protocol identifier, hostname,
        and port are used as unique identifier they are immutable.

        HTTP Success:
            200 OK

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            404 Resource not Found
            409 Conflict
            500 InternalError
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')

        try:
            update_protocols(rse, issuer=ctx.env.get('issuer'), scheme=scheme, hostname=hostname, port=port, data=parameter)
        except InvalidObject, e:
            raise generate_http_error(400, 'InvalidObject', e[0][0])
Beispiel #3
0
    def POST(self, rse, scheme):
        """
        Create a protocol for a given RSE.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            404 Resource not Found
            409 Conflict
            500 Internal Error

        """
        json_data = data()
        try:
            parameters = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')

        # Fill defaults and check mandatory parameters
        parameters['scheme'] = scheme

        try:
            add_protocol(rse, issuer=ctx.env.get('issuer'), data=parameters)
        except RSENotFound, e:
            raise generate_http_error(404, 'RSENotFound', e[0][0])
Beispiel #4
0
    def POST(self, rse):
        """ Create RSE with given name.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            500 Internal Error

        """
        json_data = data()
        kwargs = {'deterministic': True,
                  'volatile': False, 'city': None, 'staging_area': False,
                  'region_code': None, 'country_name': None,
                  'continent': None, 'time_zone': None, 'ISP': None}
        try:
            parameters = json_data and loads(json_data)
            if parameters:
                for param in kwargs:
                    if param in parameters:
                        kwargs[param] = parameters[param]
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')
        kwargs['issuer'] = ctx.env.get('issuer')
        try:
            add_rse(rse, **kwargs)
        except AccessDenied, e:
            raise generate_http_error(401, 'AccessDenied', e.args[0][0])
Beispiel #5
0
    def GET(self):
        """ List all RSEs.

        HTTP Success:
            200 OK

        HTTP Error:
            400 Bad request
            401 Unauthorized
            404 Resource not Found
            500 InternalError

        :returns: A list containing all RSEs.
        """
        header('Content-Type', 'application/x-json-stream')
        params = input()
        if 'expression' in params:
            try:
                for rse in parse_rse_expression(params['expression']):
                    item = {'rse': rse}
                    yield render_json(**item) + '\n'
            except InvalidRSEExpression, e:
                raise generate_http_error(400, 'InvalidRSEExpression', e)
            except InvalidObject, e:
                raise generate_http_error(400, 'InvalidObject', e[0][0])
Beispiel #6
0
    def POST(self, account):
        """ create account with given account name.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            409 Conflict
            500 Internal Error

        :param Rucio-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        :params Rucio-Type: the type of the new account.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'cannot decode json parameter dictionary')

        type = None
        try:
            type = parameter['type']
        except KeyError, e:
            if e.args[0] == 'type':
                raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #7
0
    def POST(self, key):
        """
        Create a new value for a key.

        HTTP Success:
            201 Created

        HTTP Error:
            401 Unauthorized
            404 Not Found
            409 Conflict
            500 Internal Error

        :param Rucio-Auth-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        :params Rucio-Account: account belonging to the new scope.
        """
        json_data = data()
        try:
            params = loads(json_data)
            value = params['value']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            add_value(key=key, value=value, issuer=ctx.env.get('issuer'))
        except Duplicate, e:
            raise generate_http_error(409, 'Duplicate', e[0][0])
Beispiel #8
0
    def POST(self):
        """
        List the DIDs associated to a list of replicas.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        :returns: A list of dictionaries containing the mapping PFNs to DIDs.
        """
        json_data = data()
        rse, pfns = None, []
        header('Content-Type', 'application/x-json-stream')
        try:
            params = parse_response(json_data)
            if 'pfns' in params:
                pfns = params['pfns']
            if 'rse' in params:
                rse = params['rse']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            for pfn in get_did_from_pfns(pfns, rse):
                yield dumps(pfn) + '\n'
        except RucioException, e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Beispiel #9
0
    def POST(self, account, rse):
        """ Create or update an account limit.
        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            404 Not Found
            500 Internal Error

        :param X-Rucio-Auth-Account: Account identifier.
        :param X-Rucio-Auth-Token:   As an 32 character hex string.
        :param account:              Account name.
        :param rse:                  RSE name.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'cannot decode json parameter dictionary')
        try:
            bytes = parameter['bytes']
        except KeyError, e:
            if e.args[0] == 'type':
                raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #10
0
    def DELETE(self, account):

        """ Delete an account's identity mapping.

        HTTP Success:
            200 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            404 Not Found
            500 Internal Error
        :param account: Account identifier.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'cannot decode json parameter dictionary')
        try:
            identity = parameter['identity']
            authtype = parameter['authtype']
        except KeyError, e:
            if e.args[0] == 'authtype' or e.args[0] == 'identity':
                raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #11
0
    def POST(self, account, key):
        """ Add attributes to an account.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            409 Conflict
            500 Internal Error

        :param account: Account identifier.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'cannot decode json parameter dictionary')

        try:
            key = parameter['key']
            value = parameter['value']
        except KeyError, e:
            if e.args[0] == 'key' or e.args[0] == 'value':
                raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #12
0
    def POST(self):
        """
        Declare a list of bad replicas.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        """
        json_data = data()
        rse, pfns = None, []
        header('Content-Type', 'application/x-json-stream')
        try:
            params = parse_response(json_data)
            if 'pfns' in params:
                pfns = params['pfns']
            if 'rse' in params:
                rse = params['rse']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            declare_bad_file_replicas(rse=rse, pfns=pfns, issuer=ctx.env.get('issuer'))
        except ReplicaNotFound, e:
            raise generate_http_error(404, 'ReplicaNotFound', e.args[0][0])
Beispiel #13
0
    def POST(self, account):
        """ Grant an identity access to an account.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            409 Conflict
            500 Internal Error

        :param account: Account identifier.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'cannot decode json parameter dictionary')

        try:
            identity = parameter['identity']
            authtype = parameter['authtype']
            email = parameter['email']
        except KeyError, e:
            if e.args[0] == 'authtype' or e.args[0] == 'identity' or e.args[0] == 'email':
                raise generate_http_error(400, 'KeyError', '%s not defined' % str(e))
Beispiel #14
0
    def POST(self, account, name):
        """
        Create a new subscription.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            409 Conflict
            500 Internal Error
        """
        dry_run = 0
        json_data = data()
        try:
            params = loads(json_data)
            filter = params['filter']
            replication_rules = params['replication_rules']
            comments = params['comments']
            lifetime = params['lifetime']
            retroactive = params['retroactive']
            dry_run = params['dry_run']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            subscription_id = add_subscription(name=name, account=account, filter=filter, replication_rules=replication_rules, comments=comments, lifetime=lifetime, retroactive=retroactive, dry_run=dry_run)
        except SubscriptionDuplicate as e:
            raise generate_http_error(409, 'SubscriptionDuplicate', e.args[0][0])
        except RucioException, e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Beispiel #15
0
    def PUT(self, rse):
        """ Update RSE properties (e.g. name, availability).

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            500 Internal Error

        """
        json_data = data()
        kwargs = {}

        try:
            parameters = json_data and loads(json_data)
            kwargs['parameters'] = parameters
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')
        kwargs['issuer'] = ctx.env.get('issuer')
        try:
            update_rse(rse, **kwargs)
        except AccessDenied, e:
            raise generate_http_error(401, 'AccessDenied', e.args[0][0])
Beispiel #16
0
    def POST(self, key):
        """
        Create a new allowed key (value is NULL).

        HTTP Success:
            201 Created

        HTTP Error:
            401 Unauthorized
            404 Not Found
            409 Conflict
            500 Internal Error

        :param Rucio-Auth-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        :params Rucio-Account: account belonging to the new scope.
        """
        json_data = data()
        try:
            params = json_data and loads(json_data)
            if params and 'value_type' in params:
                value_type = params['value_type']
            if params and 'value_regexp' in params:
                value_regexp = params['value_regexp']
            if params and 'key_type' in params:
                key_type = params['key_type']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            add_key(key=key, key_type=key_type, value_type=value_type, value_regexp=value_regexp, issuer=ctx.env.get('issuer'))
        except Duplicate, e:
            raise generate_http_error(409, 'Duplicate', e[0][0])
Beispiel #17
0
    def PUT(self, account, name):
        """
        Update an existing subscription.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            404 Not Found
            500 Internal Error
        """
        json_data = data()
        try:
            params = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            filter = params['filter']
        except KeyError:
            filter = None
        try:
            replication_rules = params['replication_rules']
        except KeyError:
            replication_rules = None
        try:
            comments = params['comments']
        except KeyError:
            comments = None
        try:
            lifetime = params['lifetime']
        except KeyError:
            lifetime = None
        try:
            retroactive = params['retroactive']
        except KeyError:
            retroactive = None
        try:
            dry_run = params['dry_run']
        except KeyError:
            dry_run = None

        try:
            update_subscription(name=name, account=account, filter=filter, replication_rules=replication_rules, comments=comments, lifetime=lifetime, retroactive=retroactive, dry_run=dry_run)
        except SubscriptionNotFound, e:
            raise generate_http_error(404, 'SubscriptionNotFound', e[0][0])
Beispiel #18
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized

        :param Rucio-Auth-Token: as a variable-length string.
        :returns: Tuple(account name, token lifetime).
        """

        header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
        header('Access-Control-Allow-Headers', ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        header('Access-Control-Allow-Methods', '*')
        header('Access-Control-Allow-Credentials', 'true')
        header('Access-Control-Expose-Headers', 'X-Rucio-Auth-Token')

        header('Content-Type', 'application/octet-stream')
        header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')

        token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')

        result = validate_auth_token(token)
        if not result:
            raise generate_http_error(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())

        return result
Beispiel #19
0
 def decorated(*args, **kwargs):
     try:
         return f(*args, **kwargs)
     except (Created, HTTPError, OK, seeother):
         raise
     except RucioException, e:
         raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Beispiel #20
0
    def GET(self, scope, name):
        """ get locks for a given scope, name.

        HTTP Success:
            200 OK

        HTTP Error:
            404 Not Found
            500 InternalError

        :returns: JSON dict containing informations about the requested user.
        """
        header('Content-Type', 'application/x-json-stream')
        did_type = None
        if ctx.query:
            params = parse_qs(ctx.query[1:])
            if 'did_type' in params:
                did_type = params['did_type'][0]
        try:
            if did_type == 'dataset':
                for lock in get_dataset_locks(scope, name):
                    yield render_json(**lock) + '\n'
            else:
                raise InternalError('Wrong did_type specified')
        except RucioException, e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0])
Beispiel #21
0
 def GET(self, account):
     header('Content-Type', 'application/x-json-stream')
     try:
         for identity in list_identities(account):
             yield render_json(**identity) + "\n"
     except AccountNotFound, e:
         raise generate_http_error(404, 'AccountNotFound', e.args[0][0])
Beispiel #22
0
def load_json_data():
    """ Hook to load json data. """
    json_data = data()
    try:
        ctx.env['parameters'] = json_data and loads(json_data)
    except ValueError:
        raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary/list')
Beispiel #23
0
    def GET(self, account, rse=None):
        """ get the current limits for an account on a specific RSE

        HTTP Success:
            200 OK

        HTTP Error:
            404 Not Found
            500 InternalError

        :param X-Rucio-Account: Account identifier.
        :param X-Rucio-Auth-Token: as an 32 character hex string.

        :param account:   The account name.
        :param rse:       The rse name.

        :returns: JSON dict containing informations about the requested user.
        """
        header('Content-Type', 'application/json')
        try:
            if rse:
                limits = get_account_limit(account=account, rse=rse)
            else:
                limits = get_account_limits(account=account)
        except RSENotFound, e:
            raise generate_http_error(404, 'RSENotFound', e.args[0][0])
Beispiel #24
0
    def GET(self, account, name):
        """
        Return all rules of a given subscription id.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found

        :param scope: The scope name.
        """
        header('Content-Type', 'application/x-json-stream')
        state = None
        if ctx.query:
            params = parse_qs(ctx.query[1:])
            if 'state' in params:
                state = params['state'][0]
        try:
            subscriptions = [subscription['id'] for subscription in list_subscriptions(name=name, account=account)]
            if len(subscriptions) > 0:
                if state == 'OK':
                    state = RuleState.OK
                if state == 'Replicating':
                    state = RuleState.REPLICATING
                if state == 'Stuck':
                    state = RuleState.STUCK
                for rule in list_replication_rules({'subscription_id': subscriptions[0], 'state': state}):
                    yield dumps(rule, cls=APIEncoder) + '\n'
        except RuleNotFound, e:
            raise generate_http_error(404, 'RuleNotFound', e.args[0][0])
Beispiel #25
0
def rucio_loadhook():
    """ Rucio load Hook to authenticate, timing, etc. """

    # Allow cross-site scripting
    header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
    header('Access-Control-Allow-Headers',
           ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
    header('Access-Control-Allow-Methods', '*')
    header('Access-Control-Allow-Credentials', 'true')

    if ctx.env.get('REQUEST_METHOD') == 'OPTIONS':
        raise OK

    if ctx.env.get('REQUEST_METHOD') == 'GET':
        header('Cache-Control',
               'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')
    else:
        header('Content-Type', 'application/octet-stream')

    auth_token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')
    try:
        auth = validate_auth_token(auth_token)
    except RucioException, e:
        raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Beispiel #26
0
    def GET(self, account):
        """ get account information for given account name.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found
            500 InternalError

        :param Rucio-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.

        :returns: JSON dict containing informations about the requested user.
        """
        header('Content-Type', 'application/json')
        if account == 'whoami':
            # Redirect to the account uri
            frontend = ctx.env.get('HTTP_X_REQUESTED_HOST')
            if frontend:
                raise redirect(frontend + "/accounts/%s" % (ctx.env.get('issuer')))
            raise seeother(ctx.env.get('issuer'))

        acc = None
        try:
            acc = get_account_info(account)
        except AccountNotFound, e:
            raise generate_http_error(404, 'AccountNotFound', e.args[0][0])
Beispiel #27
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized

        :param Rucio-Account: Account identifier as a string.
        :param Rucio-AppID: Application identifier as a string.
        :param SavedCredentials: Apache mod_auth_kerb SavedCredentials.
        :returns: "Rucio-Auth-Token" as a variable-length string header.
        """

        header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
        header('Access-Control-Allow-Headers', ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        header('Access-Control-Allow-Methods', '*')
        header('Access-Control-Allow-Credentials', 'true')
        header('Access-Control-Expose-Headers', 'X-Rucio-Auth-Token')

        header('Content-Type', 'application/octet-stream')
        header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')

        account = ctx.env.get('HTTP_X_RUCIO_ACCOUNT')
        gsscred = ctx.env.get('REMOTE_USER')
        appid = ctx.env.get('HTTP_X_RUCIO_APPID')
        if appid is None:
            appid = 'unknown'
        ip = ctx.env.get('HTTP_X_FORWARDED_FOR')
        if ip is None:
            ip = ctx.ip

        try:
            result = get_auth_token_gss(account, gsscred, appid, ip)
        except AccessDenied:
            raise generate_http_error(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())

        if result is None:
            raise generate_http_error(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())
        else:
            header('X-Rucio-Auth-Token', result)
            return str()

        raise BadRequest()
Beispiel #28
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized

        :param Rucio-Account: Account identifier as a string.
        :param Rucio-Username: Username as a string.
        :param Rucio-Password: SHA1 hash of the password as a string.
        :param Rucio-AppID: Application identifier as a string.
        :returns: "Rucio-Auth-Token" as a variable-length string header.
        """

        header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
        header('Access-Control-Allow-Headers', ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        header('Access-Control-Allow-Methods', '*')
        header('Access-Control-Allow-Credentials', 'true')
        header('Access-Control-Expose-Headers', 'X-Rucio-Auth-Token')

        header('Content-Type', 'application/octet-stream')
        header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')

        account = ctx.env.get('HTTP_X_RUCIO_ACCOUNT')
        username = ctx.env.get('HTTP_X_RUCIO_USERNAME')
        password = ctx.env.get('HTTP_X_RUCIO_PASSWORD')
        appid = ctx.env.get('HTTP_X_RUCIO_APPID')
        if appid is None:
            appid = 'unknown'
        ip = ctx.env.get('HTTP_X_FORWARDED_FOR')
        if ip is None:
            ip = ctx.ip

        try:
            result = get_auth_token_user_pass(account, username, password, appid, ip)
        except AccessDenied:
            raise generate_http_error(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())
        except RucioException, e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0])
Beispiel #29
0
    def PUT(self):
        """
        Update a file replicas state at a given RSE.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 Internal Error
        """
        json_data = data()
        try:
            parameters = parse_response(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            update_replicas_states(rse=parameters['rse'], files=parameters['files'], issuer=ctx.env.get('issuer'))
        except AccessDenied, e:
            raise generate_http_error(401, 'AccessDenied', e.args[0][0])
Beispiel #30
0
    def GET(self, rse):
        """
        Get RSE limits.

        :param rse: the RSE name.
        """
        header('Content-Type', 'application/json')
        try:
            limits = get_rse_limits(rse=rse, issuer=ctx.env.get('issuer'))
            return render_json(**limits)
        except RSENotFound, e:
            raise generate_http_error(404, 'RSENotFound', e[0][0])
Beispiel #31
0
    def GET(self, rse):
        """ List all supported protocols of the given RSE.

        HTTP Success:
            200 OK

        HTTP Error:
            404 Resource not Found
            500 InternalError

        :returns: A list containing all supported protocols and all their attributes.
        """
        header('Content-Type', 'application/json')
        p_list = None
        try:
            p_list = get_rse_protocols(rse, issuer=ctx.env.get('issuer'))
        except RSEOperationNotSupported, error:
            raise generate_http_error(404, 'RSEOperationNotSupported', error[0][0])
Beispiel #32
0
    def GET(self, rse):
        """
        Get RSE usage information.

        :param rse: the RSE name.
        """
        header('Content-Type', 'application/x-json-stream')
        source = None
        if ctx.query:
            params = parse_qs(ctx.query[1:])
            if 'source' in params:
                source = params['source'][0]

        try:
            for usage in list_rse_usage_history(rse=rse, issuer=ctx.env.get('issuer'), source=source):
                yield render_json(**usage) + '\n'
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
Beispiel #33
0
        def decorated(*args, **kwargs):
            requested_content_type = ctx.env.get('HTTP_ACCEPT')
            request_type_allowed = True
            if requested_content_type:
                if ',' in requested_content_type:
                    for content_type in requested_content_type.replace(' ', '').split(','):
                        if content_type in supported_content_types or '*/*' in content_type:
                            request_type_allowed = True
                            break
                        else:
                            request_type_allowed = False
                else:
                    if requested_content_type not in supported_content_types and '*/*' not in requested_content_type:
                        request_type_allowed = False

            if not request_type_allowed:
                raise generate_http_error(406, 'UnsupportedRequestedContentType', 'The requested content type %s is not supported. Use %s.' % (requested_content_type, ','.join(supported_content_types)))
            return f(*args, **kwargs)
Beispiel #34
0
    def GET(self):
        """ Export data from Rucio.

        HTTP Success:
            200 OK

        HTTP Error:
            400 Bad request
            401 Unauthorized
            404 Resource not Found
            500 InternalError
        """
        header('Content-Type', 'application/json')
        try:
            return render_json(**export_data(issuer=ctx.env.get('issuer')))
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__,
                                      error.args[0])
Beispiel #35
0
    def GET(self, account, name=None):
        """
        Return a summary of the states of all rules of a given subscription id.

        HTTP Success:
            200 OK

        HTTP Error:
            404 Not Found
            500 Internal Error

        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for row in list_subscription_rule_states(account=account):
                yield dumps(row, cls=APIEncoder) + '\n'
        except RucioException, error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
Beispiel #36
0
    def GET(self, rse, scheme):
        """ List all references of the provided RSE for the given protocol.

        HTTP Success:
            200 OK

        HTTP Error:
            404 Resource not Found
            500 InternalError

        :returns: A list with detailed protocol information.
        """
        header('Content-Type', 'application/json')
        p_list = None
        try:
            p_list = get_rse_protocols(rse, issuer=ctx.env.get('issuer'))
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
Beispiel #37
0
 def GET(self):
     try:
         data = param_input()
         response = get(str(data.file_location),
                        cert=config_get('webui', 'usercert'),
                        verify=False)
         if not response.ok:
             response.raise_for_status()
         cont = response.content
         file_like_object = BytesIO(cont)
         tar = open(mode='r:gz', fileobj=file_like_object)
         jsonResponse = {}
         for member in tar.getmembers():
             jsonResponse[member.name] = member.size
         header('Content-Type', 'application/json')
         return dumps(jsonResponse)
     except ConnectionError, err:
         raise generate_http_error(503, str(type(err)), str(err))
Beispiel #38
0
class RSEAccountUsageLimit(RucioController):
    """ Read and delete RSE limits for accounts. """

    def GET(self, rse):
        """
        Get account usage and limit for one RSE.

        :param rse: the RSE name.
        """
        header('Content-Type', 'application/json')
        try:
            usage = get_rse_account_usage(rse=rse)
            for row in usage:
                yield dumps(row, cls=APIEncoder) + '\n'
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
        except RucioException, error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0][0])
Beispiel #39
0
class RSE(RucioController):
    """ Create, update, get and disable RSE. """
    def POST(self, rse):
        """ Create RSE with given name.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            404 Resource not Found
            409 Conflict
            500 Internal Error

        """
        json_data = data()
        kwargs = {
            'deterministic': True,
            'volatile': False,
            'city': None,
            'staging_area': False,
            'region_code': None,
            'country_name': None,
            'continent': None,
            'time_zone': None,
            'ISP': None
        }
        try:
            parameters = json_data and loads(json_data)
            if parameters:
                for param in kwargs:
                    if param in parameters:
                        kwargs[param] = parameters[param]
        except ValueError:
            raise generate_http_error(
                400, 'ValueError', 'Cannot decode json parameter dictionary')
        kwargs['issuer'] = ctx.env.get('issuer')
        try:
            add_rse(rse, **kwargs)
        except InvalidObject, error:
            raise generate_http_error(400, 'InvalidObject', error[0][0])
        except AccessDenied, error:
            raise generate_http_error(401, 'AccessDenied', error.args[0][0])
Beispiel #40
0
    def POST(self, scope, name, key):
        """
        Add metadata to a data identifier.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            404 Not Found
            409 Conflict
            500 Internal Error

        :param scope: The scope name.
        :param name: The data identifier name.
        :param key: the key.

        """
        json_data = data()
        try:
            params = loads(json_data)
            value = params['value']
            recursive = params.get('recursive', False)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')
        try:
            set_metadata(scope=scope, name=name, key=key, value=value,
                         issuer=ctx.env.get('issuer'), recursive=recursive)
        except DataIdentifierNotFound as error:
            raise generate_http_error(404, 'DataIdentifierNotFound', error.args[0])
        except Duplicate as error:
            raise generate_http_error(409, 'Duplicate', error.args[0])
        except KeyNotFound as error:
            raise generate_http_error(400, 'KeyNotFound', error.args[0])
        except InvalidMetadata as error:
            raise generate_http_error(400, 'InvalidMetadata', error.args[0])
        except InvalidValueForKey as error:
            raise generate_http_error(400, 'InvalidValueForKey', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)

        raise Created()
Beispiel #41
0
    def POST(self, scope, name):
        """
        Append data identifiers to data identifiers.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        :param scope: Create the data identifier within this scope.
        :param name: Create the data identifier with this name.
        """
        try:
            json_data = loads(data())
        except ValueError:
            raise generate_http_error(400, 'ValueError',
                                      'Cannot decode json parameter list')

        try:
            attach_dids(scope=scope,
                        name=name,
                        attachment=json_data,
                        issuer=ctx.env.get('issuer'),
                        vo=ctx.env.get('vo'))
        except DataIdentifierNotFound as error:
            raise generate_http_error(404, 'DataIdentifierNotFound',
                                      error.args[0])
        except DuplicateContent as error:
            raise generate_http_error(409, 'DuplicateContent', error.args[0])
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except UnsupportedOperation as error:
            raise generate_http_error(409, 'UnsupportedOperation',
                                      error.args[0])
        except RSENotFound as error:
            raise generate_http_error(404, 'RSENotFound', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__,
                                      error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)

        raise Created()
Beispiel #42
0
    def POST(self):
        """
        List dataset replicas for multiple DIDs.

        HTTP Success:
            200 OK

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            406 Not Acceptable
            500 InternalError

        :returns: A dictionary containing all replicas information.
        """
        header('Content-Type', 'application/x-json-stream')
        json_data = data()
        try:
            params = parse_response(json_data)
            dids = params['dids']
            didslength = len(dids)
        except KeyError as error:
            raise generate_http_error(
                400, 'KeyError',
                'Cannot find mandatory parameter : %s' % str(error))
        except ValueError:
            raise generate_http_error(400, 'ValueError',
                                      'Cannot decode json parameter list')
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__,
                                      error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)
        if didslength == 0:
            raise generate_http_error(400, 'ValueError',
                                      'List of DIDs is empty')
        try:
            for row in list_dataset_replicas_bulk(dids=dids,
                                                  vo=ctx.env.get('vo')):
                yield dumps(row, cls=APIEncoder) + '\n'
        except InvalidObject as error:
            raise generate_http_error(
                400, 'InvalidObject',
                'Cannot validate DIDs: %s' % (str(error)))
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__,
                                      error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)
Beispiel #43
0
    def POST(self):
        """
        Resurrect DIDs.

        HTTP Success:
            201 Created


        HTTP Error:
            401 Unauthorized
            404 Not Found
            409 Conflict
            500 Internal Error

        """
        json_data = data()
        try:
            dids = loads(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            resurrect(dids=dids, issuer=ctx.env.get('issuer'))
        except DataIdentifierNotFound as error:
            raise generate_http_error(404, 'DataIdentifierNotFound', error.args[0])
        except DuplicateContent as error:
            raise generate_http_error(409, 'DuplicateContent', error.args[0])
        except DataIdentifierAlreadyExists as error:
            raise generate_http_error(409, 'DataIdentifierAlreadyExists', error.args[0])
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except UnsupportedOperation as error:
            raise generate_http_error(409, 'UnsupportedOperation', error.args[0])
        except DatabaseException as error:
            raise generate_http_error(500, 'DatabaseException', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)
        raise Created()
Beispiel #44
0
    def POST(self, account):
        """ Grant an identity access to an account.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            409 Conflict
            500 Internal Error

        :param account: Account identifier.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(
                400, 'ValueError', 'cannot decode json parameter dictionary')

        try:
            identity = parameter['identity']
            authtype = parameter['authtype']
            email = parameter['email']
        except KeyError as error:
            if error.args[0] == 'authtype' or error.args[
                    0] == 'identity' or error.args[0] == 'email':
                raise generate_http_error(400, 'KeyError',
                                          '%s not defined' % str(error))
        except TypeError:
            raise generate_http_error(400, 'TypeError',
                                      'body must be a json dictionary')

        try:
            add_account_identity(identity_key=identity,
                                 id_type=authtype,
                                 account=account,
                                 email=email,
                                 issuer=ctx.env.get('issuer'))
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except Duplicate as error:
            raise generate_http_error(409, 'Duplicate', error.args[0])
        except AccountNotFound as error:
            raise generate_http_error(404, 'AccountNotFound', error.args[0])
        except Exception as error:
            print(str(format_exc()))
            raise InternalError(error)

        raise Created()
Beispiel #45
0
    def GET(self, section, option):
        """
        Retrieve the value of an option.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found

        :param Rucio-Auth-Account: Account identifier.
        :param Rucio-Auth-Token: 32 character hex string.
        """

        try:
            return json.dumps(config.get(section=section, option=option, issuer=ctx.env.get('issuer')))
        except:
            raise generate_http_error(404, 'ConfigNotFound', 'No configuration found for section \'%s\' option \'%s\'' % (section, option))
Beispiel #46
0
    def GET(self, scope, name):
        """ List all parents of a data identifier.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        :returns: A list of dictionary containing all dataset information.
        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for dataset in list_parent_dids(scope=scope, name=name):
                yield render_json(**dataset) + "\n"
        except DataIdentifierNotFound, error:
            raise generate_http_error(404, 'DataIdentifierNotFound',
                                      error.args[0][0])
Beispiel #47
0
    def GET(self, rse):
        """
        List dataset replicas replicas.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        :returns: A dictionary containing all replicas on the RSE.
        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for row in list_datasets_per_rse(rse=rse):
                yield dumps(row, cls=APIEncoder) + '\n'
        except RucioException, e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Beispiel #48
0
    def GET(self, scope, name):
        """
        Return all rules of a given DID.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found

        :param scope: The scope name.
        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for rule in list_replication_rules({'scope': scope, 'name': name}):
                yield dumps(rule, cls=APIEncoder) + '\n'
        except RuleNotFound, error:
            raise generate_http_error(404, 'RuleNotFound', error.args[0][0])
Beispiel #49
0
class Distance(RucioController):
    """ Create/Update and read distances between RSEs. """

    def GET(self, source, destination):
        """
        Get RSE distance between source and destination.

        :param rse: the RSE name.
        """
        header('Content-Type', 'application/json')
        try:
            distance = get_distance(source=source,
                                    destination=destination,
                                    issuer=ctx.env.get('issuer'))
            return dumps(distance, cls=APIEncoder)
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
        except RucioException, error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0][0])
Beispiel #50
0
class Values(RucioController):
    """ REST APIs for data identifier attribute values. """

    def GET(self, key):
        """
        List all values for a key.

        HTTP Success:
            200 Success
        """
        header('Content-Type', 'application/json')
        return dumps(list_values(key=key))

    def POST(self, key):
        """
        Create a new value for a key.

        HTTP Success:
            201 Created

        HTTP Error:
            401 Unauthorized
            404 Not Found
            409 Conflict
            500 Internal Error

        :param Rucio-Auth-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        :params Rucio-Account: account belonging to the new scope.
        """
        json_data = data()
        try:
            params = loads(json_data)
            value = params['value']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            add_value(key=key, value=value, issuer=ctx.env.get('issuer'))
        except Duplicate, e:
            raise generate_http_error(409, 'Duplicate', e[0][0])
        except InvalidValueForKey, e:
            raise generate_http_error(400, 'InvalidValueForKey', e[0][0])
Beispiel #51
0
    def GET(self, rse):
        """ Details about a specific RSE.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Resource not Found
            500 InternalError

        :returns: A list containing all RSEs.
        """
        header('Content-Type', 'application/json')
        try:
            rse_prop = get_rse(rse=rse)
            return render_json(**rse_prop)
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
Beispiel #52
0
    def DELETE(self, account):
        """ disable account with given account name.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found
            500 InternalError

        :param Rucio-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        """

        try:
            del_account(account, issuer=ctx.env.get('issuer'))
        except AccessDenied, e:
            raise generate_http_error(401, 'AccessDenied', e.args[0][0])
Beispiel #53
0
    def POST(self):
        """
        Create file replicas at a given RSE.

        HTTP Success:
            201 Created

        HTTP Error:
            401 Unauthorized
            409 Conflict
            500 Internal Error
        """
        json_data = data()
        try:
            parameters = parse_response(json_data)
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')

        try:
            add_replicas(rse=parameters['rse'], files=parameters['files'],
                         issuer=ctx.env.get('issuer'), vo=ctx.env.get('vo'),
                         ignore_availability=parameters.get('ignore_availability', False))
        except InvalidPath as error:
            raise generate_http_error(400, 'InvalidPath', error.args[0])
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except Duplicate as error:
            raise generate_http_error(409, 'Duplicate', error.args[0])
        except DataIdentifierAlreadyExists as error:
            raise generate_http_error(409, 'DataIdentifierAlreadyExists', error.args[0])
        except RSENotFound as error:
            raise generate_http_error(404, 'RSENotFound', error.args[0])
        except ResourceTemporaryUnavailable as error:
            raise generate_http_error(503, 'ResourceTemporaryUnavailable', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)
        raise Created()
Beispiel #54
0
    def POST(self, account, rse):
        """ Create or update an account limit.
        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            404 Not Found
            500 Internal Error

        :param X-Rucio-Auth-Account: Account identifier.
        :param X-Rucio-Auth-Token:   As an 32 character hex string.
        :param account:              Account name.
        :param rse:                  RSE name.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(
                400, 'ValueError', 'cannot decode json parameter dictionary')
        try:
            bytes = parameter['bytes']
        except KeyError as exception:
            if exception.args[0] == 'type':
                raise generate_http_error(400, 'KeyError',
                                          '%s not defined' % str(exception))
        except TypeError:
            raise generate_http_error(400, 'TypeError',
                                      'body must be a json dictionary')

        try:
            set_local_account_limit(account=account,
                                    rse=rse,
                                    bytes=bytes,
                                    issuer=ctx.env.get('issuer'),
                                    vo=ctx.env.get('vo'))
        except AccessDenied as exception:
            raise generate_http_error(401, 'AccessDenied', exception.args[0])
        except RSENotFound as exception:
            raise generate_http_error(404, 'RSENotFound', exception.args[0])
        except AccountNotFound as exception:
            raise generate_http_error(404, 'AccountNotFound',
                                      exception.args[0])
        except Exception as exception:
            print(format_exc())
            raise InternalError(exception)

        raise Created()
Beispiel #55
0
    def GET(self, guid):
        """
        Return the file associated to a GUID.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found

        :param scope: The scope name.
        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for dataset in get_dataset_by_guid(guid):
                yield dumps(dataset, cls=APIEncoder) + '\n'
        except DataIdentifierNotFound, error:
            raise generate_http_error(404, 'DataIdentifierNotFound',
                                      error.args[0][0])
Beispiel #56
0
    def GET(self, account):
        """ list all attributes for an account.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            404 Not Found
            500 InternalError

        :param Rucio-Account: Account identifier.
        :param Rucio-Auth-Token: as an 32 character hex string.
        :returns: JSON dict containing informations about the requested account.
        """
        header('Content-Type', 'application/json')
        try:
            attribs = list_account_attributes(account)
        except AccountNotFound, e:
            raise generate_http_error(404, 'AccountNotFound', e.args[0][0])
Beispiel #57
0
class Limits:
    def POST(self, rse):
        """ Not supported. """
        raise BadRequest()

    def GET(self, rse):
        """
        Get RSE limits.

        :param rse: the RSE name.
        """
        header('Content-Type', 'application/json')
        try:
            limits = get_rse_limits(rse=rse, issuer=ctx.env.get('issuer'))
            return render_json(**limits)
        except RSENotFound, error:
            raise generate_http_error(404, 'RSENotFound', error[0][0])
        except RucioException, error:
            raise generate_http_error(500, error.__class__.__name__,
                                      error.args[0][0])
Beispiel #58
0
    def GET(self, account=None, name=None):
        """
        Retrieve a subscription.

        HTTP Success:
            200 OK

        HTTP Error:
            404 Not Found
            500 Internal Error

        :param account: The account name.
        :param name: The subscription name.
        """
        header('Content-Type', 'application/x-json-stream')
        try:
            for subscription in list_subscriptions(name=name, account=account):
                yield dumps(subscription, cls=APIEncoder) + '\n'
        except SubscriptionNotFound, error:
            raise generate_http_error(404, 'SubscriptionNotFound', error[0][0])
Beispiel #59
0
    def POST(self, account, key):
        """ Add attributes to an account.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad Reqeust
            401 Unauthorized
            409 Conflict
            500 Internal Error

        :param account: Account identifier.
        """
        json_data = data()
        try:
            parameter = loads(json_data)
        except ValueError:
            raise generate_http_error(
                400, 'ValueError', 'cannot decode json parameter dictionary')

        try:
            key = parameter['key']
            value = parameter['value']
        except KeyError as error:
            if error.args[0] == 'key' or error.args[0] == 'value':
                raise generate_http_error(400, 'KeyError',
                                          '%s not defined' % str(error))
        except TypeError:
            raise generate_http_error(400, 'TypeError',
                                      'body must be a json dictionary')

        try:
            add_account_attribute(key=key,
                                  value=value,
                                  account=account,
                                  issuer=ctx.env.get('issuer'),
                                  vo=ctx.env.get('vo'))
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except Duplicate as error:
            raise generate_http_error(409, 'Duplicate', error.args[0])
        except AccountNotFound as error:
            raise generate_http_error(404, 'AccountNotFound', error.args[0])
        except Exception as error:
            print(str(format_exc()))
            raise InternalError(error)

        raise Created()
Beispiel #60
0
    def POST(self, rse):
        """ Create RSE with given name.

        HTTP Success:
            201 Created

        HTTP Error:
            400 Bad request
            401 Unauthorized
            404 Resource not Found
            409 Conflict
            500 Internal Error

        """
        json_data = data().decode()
        kwargs = {'deterministic': True,
                  'volatile': False, 'city': None, 'staging_area': False,
                  'region_code': None, 'country_name': None,
                  'continent': None, 'time_zone': None, 'ISP': None,
                  'rse_type': None, 'latitude': None, 'longitude': None,
                  'ASN': None, 'availability': None}
        try:
            parameters = json_data and loads(json_data)
            if parameters:
                for param in kwargs:
                    if param in parameters:
                        kwargs[param] = parameters[param]
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary')
        kwargs['issuer'] = ctx.env.get('issuer')
        kwargs['vo'] = ctx.env.get('vo')
        try:
            add_rse(rse, **kwargs)
        except InvalidObject as error:
            raise generate_http_error(400, 'InvalidObject', error.args[0])
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except RSENotFound as error:
            raise generate_http_error(404, 'RSENotFound', error.args[0])
        except Duplicate as error:
            raise generate_http_error(409, 'Duplicate', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
        except Exception as error:
            print(error)
            print(format_exc())
            raise InternalError(error)

        raise Created()