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))
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])
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])
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])
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])
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))
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])
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])
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))
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))
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))
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])
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))
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])
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])
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])
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])
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
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])
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])
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])
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')
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])
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])
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])
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])
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()
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])
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])
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])
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])
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])
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)
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])
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])
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])
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))
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])
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])
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()
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()
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)
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()
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()
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))
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])
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])
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])
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])
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])
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])
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])
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()
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()
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])
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])
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])
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])
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()
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()