def deployed_storage_policies(request): if request.method == "GET": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) keys = r.keys("storage-policy:*") swift_file = os.path.join(settings.SWIFT_CFG_DEPLOY_DIR, 'swift.conf') config_parser = ConfigParser.RawConfigParser() config_parser.read(swift_file) deployed_storage_policy_list = [sp for sp in keys if config_parser.has_section(sp)] storage_policy_list = [] for key in deployed_storage_policy_list: storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['id'] = str(key).split(':')[-1] storage_policy['devices'] = json.loads(storage_policy['devices']) storage_policy_list.append(storage_policy) return JSONResponse(storage_policy_list, status=status.HTTP_200_OK) return JSONResponse('Only HTTP POST requests allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def deployed_storage_policies(request): if request.method == "GET": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) keys = r.keys("storage-policy:*") swift_file = os.path.join(settings.SWIFT_CFG_DEPLOY_DIR, 'swift.conf') config_parser = ConfigParser.RawConfigParser() config_parser.read(swift_file) deployed_storage_policy_list = [ sp for sp in keys if config_parser.has_section(sp) ] storage_policy_list = [] for key in deployed_storage_policy_list: storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['id'] = str(key).split(':')[-1] storage_policy['devices'] = json.loads(storage_policy['devices']) storage_policy_list.append(storage_policy) return JSONResponse(storage_policy_list, status=status.HTTP_200_OK) return JSONResponse('Only HTTP POST requests allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def static_policy_detail(request, policy_id): """ Retrieve, update or delete a static policy. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) target = str(policy_id).split(':')[:-1] target = ':'.join(target) policy = str(policy_id).split(':')[-1] if request.method == 'GET': project_list = get_project_list() project_list['global'] = 'Global' policy_redis = r.hget("pipeline:" + str(target), policy) data = json.loads(policy_redis) filter_data = r.hgetall('filter:' + str(data['dsl_name'])) to_json_bools(filter_data, 'get', 'put', 'post', 'head', 'delete') data['get'] = filter_data['get'] data['put'] = filter_data['put'] if 'post' in filter_data: data['post'] = filter_data['post'] if 'head' in filter_data: data['head'] = filter_data['head'] if 'delete' in filter_data: data['delete'] = filter_data['delete'] data["id"] = policy data["target_id"] = target data["target_name"] = project_list[target.split(':')[0]] return JSONResponse(data, status=200) elif request.method == 'PUT': data = JSONParser().parse(request) try: policy_redis = r.hget("pipeline:" + str(target), policy) json_data = json.loads(policy_redis) json_data.update(data) json_data['object_name'] = ', '.join(r.lrange('object_type:' + json_data['object_type'], 0, -1)) json_data['execution_order'] = int(json_data['execution_order']) r.hset("pipeline:" + str(target), policy, json.dumps(json_data)) return JSONResponse("Data updated", status=201) except DataError: return JSONResponse("Error updating data", status=400) elif request.method == 'DELETE': r.hdel('pipeline:' + target, policy) policies_ids = r.keys('policy:*') pipelines_ids = r.keys('pipeline:*') if len(policies_ids) == 0 and len(pipelines_ids) == 0: r.set('policies:id', 0) # token = get_token_connection(request) # unset_filter(r, target, filter_data, token) return JSONResponse('Policy has been deleted', status=status.HTTP_204_NO_CONTENT) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def storage_policies(request): """ Creates a storage policy to swift with an specific ring. Allows create replication storage policies and erasure code storage policies """ if request.method == "GET": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) keys = r.keys("storage-policy:*") storage_policy_list = [] for key in keys: storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['id'] = str(key).split(':')[-1] storage_policy['devices'] = json.loads(storage_policy['devices']) storage_policy_list.append(storage_policy) return JSONResponse(storage_policy_list, status=status.HTTP_200_OK) if request.method == "POST": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) data = JSONParser().parse(request) if data['policy_type'] == 'EC': data['replicas'] = int(data['ec_num_data_fragments']) + int( data['ec_num_parity_fragments']) try: sp_id = str(r.incr('storage-policies:id')) key = 'storage-policy:' + sp_id ring = RingBuilder(int(data['partition_power']), int(data['replicas']), int(data['time'])) ring.save(get_policy_file_path(settings.SWIFT_CFG_TMP_DIR, sp_id)) r.hmset(key, data) except: return JSONResponse('Error creating the Storage Policy', status=status.HTTP_500_INTERNAL_SERVER_ERROR) return JSONResponse('Account created successfully', status=status.HTTP_201_CREATED) return JSONResponse('Only HTTP POST requests allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def filter_detail(request, filter_id): """ Retrieve, update or delete a Filter. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) if not r.exists("filter:" + str(filter_id)): return JSONResponse('Object does not exist!', status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': my_filter = r.hgetall("filter:" + str(filter_id)) to_json_bools(my_filter, 'put', 'get', 'post', 'head', 'delete') return JSONResponse(my_filter, status=status.HTTP_200_OK) elif request.method == 'PUT': try: data = JSONParser().parse(request) except ParseError: return JSONResponse("Invalid format or empty request", status=status.HTTP_400_BAD_REQUEST) try: if 'dsl_name' in data and str(filter_id) != data['dsl_name']: # Check for possible activated policies policies = r.keys('policy:*') for policy_key in policies: policy = r.hgetall(policy_key) dsl_filter = policy['filter'] if dsl_filter == str(filter_id): return JSONResponse("It is not possible to change the DSL Name, "+str(filter_id)+ " is associated with some Dynamic Policy", status=status.HTTP_400_BAD_REQUEST) filter_data = r.hgetall("filter:" + str(filter_id)) r.hmset('filter:' + str(data['dsl_name']), filter_data) r.delete("filter:" + str(filter_id)) r.hmset('filter:' + str(data['dsl_name']), data) else: r.hmset('filter:' + str(filter_id), data) return JSONResponse("Data updated", status=status.HTTP_200_OK) except DataError: return JSONResponse("Error updating data", status=status.HTTP_408_REQUEST_TIMEOUT) elif request.method == 'DELETE': try: r.delete("filter:" + str(filter_id)) return JSONResponse('Filter has been deleted', status=status.HTTP_204_NO_CONTENT) except DataError: return JSONResponse("Error deleting filter", status=status.HTTP_408_REQUEST_TIMEOUT) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def start_dynamic_policy_actor(policy_data, http_host): to_json_bools(policy_data, 'transient') host = create_local_host() transient = policy_data["transient"] policy_id = int(policy_data["id"]) rule_id = 'policy:' + str(policy_id) if transient: rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_TRANSIENT_MODULE, policy_data, http_host) else: rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_MODULE, policy_data, http_host) try: rule_actors[policy_id].start_rule() except Exception as e: rule_actors[policy_id].stop_actor() del rule_actors[policy_id] raise ValueError("An error occurred starting the policy actor: "+str(e))
def storage_policies(request): """ Creates a storage policy to swift with an specific ring. Allows create replication storage policies and erasure code storage policies """ if request.method == "GET": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) keys = r.keys("storage-policy:*") storage_policy_list = [] for key in keys: storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['id'] = str(key).split(':')[-1] storage_policy['devices'] = json.loads(storage_policy['devices']) storage_policy_list.append(storage_policy) return JSONResponse(storage_policy_list, status=status.HTTP_200_OK) if request.method == "POST": try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) data = JSONParser().parse(request) if data['policy_type'] == 'EC': data['replicas'] = int(data['ec_num_data_fragments']) + int(data['ec_num_parity_fragments']) try: sp_id = str(r.incr('storage-policies:id')) key = 'storage-policy:' + sp_id ring = RingBuilder(int(data['partition_power']), int(data['replicas']), int(data['time'])) ring.save(get_policy_file_path(settings.SWIFT_CFG_TMP_DIR, sp_id)) r.hmset(key, data) except: return JSONResponse('Error creating the Storage Policy', status=status.HTTP_500_INTERNAL_SERVER_ERROR) return JSONResponse('Account created successfully', status=status.HTTP_201_CREATED) return JSONResponse('Only HTTP POST requests allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def metric_module_list(request): """ List all metric modules """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) if request.method == 'GET': keys = r.keys("workload_metric:*") workload_metrics = [] for key in keys: metric = r.hgetall(key) to_json_bools(metric, 'put', 'get', 'replicate') workload_metrics.append(metric) sorted_workload_metrics = sorted(workload_metrics, key=lambda x: int(itemgetter('id')(x))) return JSONResponse(sorted_workload_metrics, status=status.HTTP_200_OK) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def filter_list(request): """ List all filters, or create a new one. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) if request.method == 'GET': keys = r.keys("filter:*") filters = [] for key in keys: filter = r.hgetall(key) to_json_bools(filter, 'get', 'put', 'post', 'head', 'delete') filters.append(filter) sorted_list = sorted(filters, key=lambda x: int(itemgetter('id')(x))) return JSONResponse(sorted_list, status=status.HTTP_200_OK) if request.method == 'POST': try: data = JSONParser().parse(request) except ParseError: return JSONResponse("Invalid format or empty request", status=status.HTTP_400_BAD_REQUEST) if (('filter_type' not in data) or (data['filter_type'] == 'native' and not check_keys(data.keys(), settings.NATIVE_FILTER_KEYS[2:-1])) or (data['filter_type'] == 'storlet' and not check_keys(data.keys(), settings.STORLET_FILTER_KEYS[2:-1]))): return JSONResponse("Invalid parameters in request", status=status.HTTP_400_BAD_REQUEST) try: filter_id = r.incr("filters:id") data['id'] = filter_id r.hmset('filter:' + str(data['dsl_name']), data) return JSONResponse(data, status=status.HTTP_201_CREATED) except DataError: return JSONResponse("Error to save the object", status=status.HTTP_400_BAD_REQUEST) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def storage_policy_detail(request, storage_policy_id): try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) key = "storage-policy:" + storage_policy_id if request.method == 'GET': if r.exists(key): storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['storage_policy_id'] = storage_policy_id storage_policy['devices'] = json.loads(storage_policy['devices']) devices = [] for device in storage_policy['devices']: object_node_id, device_id = device[0].split(':') object_node = r.hgetall('object_node:' + object_node_id) object_node_devices = json.loads(object_node['devices']) device_detail = object_node_devices[device_id] device_detail['id'] = device[0] device_detail['region'] = r.hgetall( 'region:' + object_node['region_id'])['name'] device_detail['zone'] = r.hgetall( 'zone:' + object_node['zone_id'])['name'] devices.append(device_detail) storage_policy['devices'] = devices return JSONResponse(storage_policy, status=status.HTTP_200_OK) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) if request.method == 'PUT': if r.exists(key): data = JSONParser().parse(request) try: data['deployed'] = False r.hmset(key, data) return JSONResponse("Storage Policy updated", status=status.HTTP_204_NO_CONTENT) except RedisError: return JSONResponse("Error updating storage policy", status=status.HTTP_400_BAD_REQUEST) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) if request.method == 'DELETE': if r.exists(key): try: policy_file_path_dep = get_policy_file_path( settings.SWIFT_CFG_DEPLOY_DIR, storage_policy_id) if os.path.isfile(policy_file_path_dep): os.remove(policy_file_path_dep) gzip_policy_file_dep = policy_file_path_dep.replace( 'builder', 'ring.gz') if os.path.isfile(gzip_policy_file_dep): os.remove(gzip_policy_file_dep) policy_file_path_tmp = get_policy_file_path( settings.SWIFT_CFG_TMP_DIR, storage_policy_id) if os.path.isfile(policy_file_path_tmp): os.remove(policy_file_path_tmp) gzip_policy_file_tmp = policy_file_path_tmp.replace( 'builder', 'ring.gz') if os.path.isfile(gzip_policy_file_tmp): os.remove(gzip_policy_file_tmp) deploy_swift_file = get_swift_cfg_path( settings.SWIFT_CFG_DEPLOY_DIR) config_parser = ConfigParser.RawConfigParser() config_parser.read(deploy_swift_file) config_parser.remove_section(key) with open(deploy_swift_file, 'wb') as configfile: config_parser.write(configfile) r.delete(key) rsync_dir_with_nodes(settings.SWIFT_CFG_DEPLOY_DIR, '/etc/swift') if not r.keys('storage-policy:*'): r.delete('storage-policies:id') return JSONResponse("Storage Policy deleted", status=status.HTTP_204_NO_CONTENT) except RedisError: return JSONResponse("Error deleting storage policy", status=status.HTTP_400_BAD_REQUEST) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) return JSONResponse('Method not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def metric_module_detail(request, metric_module_id): """ Retrieve, update or delete a metric module. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) metric_id = int(metric_module_id) if not r.exists("workload_metric:" + str(metric_id)): return JSONResponse('Object does not exist!', status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': metric = r.hgetall("workload_metric:" + str(metric_id)) to_json_bools(metric, 'put', 'get', 'replicate') return JSONResponse(metric, status=status.HTTP_200_OK) elif request.method == 'POST': try: data = JSONParser().parse(request) except ParseError: return JSONResponse("Invalid format or empty request", status=status.HTTP_400_BAD_REQUEST) redis_data = r.hgetall('workload_metric:' + str(metric_id)) redis_data.update(data) data = redis_data to_json_bools(data, 'put', 'get', 'replicate') if 'metric_name' not in data: metric_name = r.hget('workload_metric:' + str(metric_id), 'metric_name').split('.')[0] else: metric_name = data['metric_name'].split('.')[0] if data['status'] == 'Running': try: if data['put'] == True: start_metric('put_'+metric_name) else: stop_metric('put_'+metric_name) if data['get'] == True: start_metric('get_'+metric_name) else: stop_metric('get_'+metric_name) except Exception: data['status'] = 'Stopped' else: if data['put'] == True: stop_metric('put_'+metric_name) if data['get'] == True: stop_metric('get_'+metric_name) try: r.hmset('workload_metric:' + str(metric_id), data) return JSONResponse("Data updated", status=status.HTTP_200_OK) except DataError: return JSONResponse("Error updating data", status=status.HTTP_408_REQUEST_TIMEOUT) elif request.method == 'DELETE': try: wm_data = r.hgetall('workload_metric:' + str(metric_id)) metric_name = wm_data['metric_name'].split('.')[0] if wm_data['put'] == 'True': actor_id = 'put_'+metric_name if actor_id in metric_actors: stop_metric(actor_id) if wm_data['get'] == 'True': actor_id = 'get_'+metric_name if actor_id in metric_actors: stop_metric(actor_id) r.delete('workload_metric:' + str(metric_id)) wm_ids = r.keys('workload_metric:*') if len(wm_ids) == 0: r.set('workload_metrics:id', 0) return JSONResponse('Workload metric has been deleted', status=status.HTTP_204_NO_CONTENT) except DataError: return JSONResponse("Error deleting workload metric", status=status.HTTP_408_REQUEST_TIMEOUT) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def storage_policy_detail(request, storage_policy_id): try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) key = "storage-policy:" + storage_policy_id if request.method == 'GET': if r.exists(key): storage_policy = r.hgetall(key) to_json_bools(storage_policy, 'deprecated', 'default', 'deployed') storage_policy['storage_policy_id'] = storage_policy_id storage_policy['devices'] = json.loads(storage_policy['devices']) devices = [] for device in storage_policy['devices']: object_node_id, device_id = device[0].split(':') object_node = r.hgetall('object_node:' + object_node_id) object_node_devices = json.loads(object_node['devices']) device_detail = object_node_devices[device_id] device_detail['id'] = device[0] device_detail['region'] = r.hgetall('region:' + object_node['region_id'])['name'] device_detail['zone'] = r.hgetall('zone:' + object_node['zone_id'])['name'] devices.append(device_detail) storage_policy['devices'] = devices return JSONResponse(storage_policy, status=status.HTTP_200_OK) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) if request.method == 'PUT': if r.exists(key): data = JSONParser().parse(request) try: data['deployed'] = False r.hmset(key, data) return JSONResponse("Storage Policy updated", status=status.HTTP_204_NO_CONTENT) except RedisError: return JSONResponse("Error updating storage policy", status=status.HTTP_400_BAD_REQUEST) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) if request.method == 'DELETE': if r.exists(key): try: policy_file_path_dep = get_policy_file_path(settings.SWIFT_CFG_DEPLOY_DIR, storage_policy_id) if os.path.isfile(policy_file_path_dep): os.remove(policy_file_path_dep) gzip_policy_file_dep = policy_file_path_dep.replace('builder', 'ring.gz') if os.path.isfile(gzip_policy_file_dep): os.remove(gzip_policy_file_dep) policy_file_path_tmp = get_policy_file_path(settings.SWIFT_CFG_TMP_DIR, storage_policy_id) if os.path.isfile(policy_file_path_tmp): os.remove(policy_file_path_tmp) gzip_policy_file_tmp = policy_file_path_tmp.replace('builder', 'ring.gz') if os.path.isfile(gzip_policy_file_tmp): os.remove(gzip_policy_file_tmp) deploy_swift_file = get_swift_cfg_path(settings.SWIFT_CFG_DEPLOY_DIR) config_parser = ConfigParser.RawConfigParser() config_parser.read(deploy_swift_file) config_parser.remove_section(key) with open(deploy_swift_file, 'wb') as configfile: config_parser.write(configfile) r.delete(key) rsync_dir_with_nodes(settings.SWIFT_CFG_DEPLOY_DIR, '/etc/swift') if not r.keys('storage-policy:*'): r.delete('storage-policies:id') return JSONResponse("Storage Policy deleted", status=status.HTTP_204_NO_CONTENT) except RedisError: return JSONResponse("Error deleting storage policy", status=status.HTTP_400_BAD_REQUEST) else: return JSONResponse('Storage policy not found.', status=status.HTTP_404_NOT_FOUND) return JSONResponse('Method not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)
def access_control_detail(request, policy_id): """ Get or delete an access control. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=500) target_id = str(policy_id).split(':')[:-1] target_id = ':'.join(target_id) acl_id = str(policy_id).split(':')[-1] if request.method == 'GET': try: project_list = get_project_list() policy_redis = r.hget("acl:" + str(target_id), acl_id) policy = json.loads(policy_redis) to_json_bools(policy, 'list', 'write', 'read') target_split = target_id.split(':') if len(target_split) > 1: target_name = project_list[target_id.split(':')[0]]+'/'+target_id.split(':')[1] else: target_name = project_list[target_id.split(':')[0]] p = {'id': acl_id, 'target_id': target_id, 'target_name': target_name} p.update(policy) return JSONResponse(p, status=status.HTTP_200_OK) except DataError: return JSONResponse("Error retrieving policy", status=400) if request.method == 'DELETE': try: r.hdel("acl:" + str(target_id), acl_id) except DataError: return JSONResponse("Error retrieving policy", status=400) return JSONResponse("Access policy correctly removed", status=status.HTTP_200_OK) if request.method == 'PUT': data = JSONParser().parse(request) try: policy_redis = r.hget("acl:" + str(target_id), acl_id) policy = json.loads(policy_redis) access = data.pop('access') if access == 'list': data['list'] = True data['read'] = False data['write'] = False elif access == 'read': data['list'] = False data['read'] = True data['write'] = False elif access == 'read-write': data['list'] = False data['read'] = True data['write'] = True policy.update(data) policy['object_name'] = ', '.join(r.lrange('object_type:' + policy['object_type'], 0, -1)) r.hset("acl:" + str(target_id), acl_id, json.dumps(policy)) return JSONResponse('Data updated', status=status.HTTP_201_CREATED) except DataError: return JSONResponse("Error creating policy", status=400) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=405)
def access_control(request): try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=500) if request.method == 'GET': acl = [] project_list = get_project_list() try: keys = r.keys('acl:*') for it in keys: for key, value in r.hgetall(it).items(): policy = json.loads(value) to_json_bools(policy, 'list', 'write', 'read') target_id = it.replace('acl:', '') target_split = target_id.split(':') if len(target_split) > 1: target_name = project_list[target_id.split(':')[0]]+'/'+target_id.split(':')[1] else: target_name = project_list[target_id.split(':')[0]] p = {'id': key, 'target_id': target_id, 'target_name': target_name} p.update(policy) acl.append(p) except DataError: return JSONResponse("Error retrieving policy", status=400) return JSONResponse(acl, status=status.HTTP_200_OK) if request.method == 'POST': data = JSONParser().parse(request) try: if data['container_id']: key = 'acl:' + data['project_id'] + ':' + data['container_id'] else: key = 'acl:' + data['project_id'] acl_id = str(r.incr('acls:id')) data.pop('container_id') data.pop('project_id') data['object_name'] = ', '.join(r.lrange('object_type:' + data['object_type'], 0, -1)) identity = data.pop('identity') access = data.pop('access') if access == 'list': data['list'] = True data['read'] = False data['write'] = False elif access == 'read': data['list'] = False data['read'] = True data['write'] = False elif access == 'read-write': data['list'] = False data['read'] = True data['write'] = True if 'user_id' in identity: data['user_id'] = identity.replace('user_id:', '') data['group_id'] = '' elif 'group_id' in identity: data['group_id'] = identity.replace('group_id:', '') data['user_id'] = '' r.hset(key, acl_id, json.dumps(data)) return JSONResponse("Access control policy created", status=201) except DataError: return JSONResponse("Error creating policy", status=400) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=405)
def policy_list(request): """ List all policies (sorted by execution_order). Deploy new policies via DSL. """ try: r = get_redis_connection() except RedisError: return JSONResponse('Error connecting with DB', status=status.HTTP_500_INTERNAL_SERVER_ERROR) if request.method == 'GET': if 'static' in str(request.path): project_list = get_project_list() project_list['global'] = 'Global' keys = r.keys("pipeline:*") policies = [] for it in keys: for key, value in r.hgetall(it).items(): policy = json.loads(value) filter_data = r.hgetall('filter:' + str(policy['dsl_name'])) to_json_bools(filter_data, 'get', 'put', 'post', 'head', 'delete') target_id = it.replace('pipeline:', '') policy = {'id': key, 'target_id': target_id, 'target_name': project_list[target_id.split(':')[0]], 'filter_name': policy['filter_name'], 'object_type': policy['object_type'], 'object_size': policy['object_size'], 'object_tag': policy['object_tag'], 'object_name': ', '.join(r.lrange('object_type:' + policy['object_type'], 0, -1)), 'execution_server': policy['execution_server'], 'reverse': policy['reverse'], 'execution_order': policy['execution_order'], 'params': policy['params'], 'put': filter_data['put'], 'get': filter_data['get']} if 'post' in filter_data: policy['post'] = filter_data['post'] if 'head' in filter_data: policy['head'] = filter_data['head'] if 'delete' in filter_data: policy['delete'] = filter_data['delete'] policies.append(policy) sorted_policies = sorted(policies, key=lambda x: int(itemgetter('execution_order')(x))) return JSONResponse(sorted_policies, status=status.HTTP_200_OK) elif 'dynamic' in str(request.path): keys = r.keys("policy:*") policies = [] for key in keys: policy = r.hgetall(key) policies.append(policy) return JSONResponse(policies, status=status.HTTP_200_OK) else: return JSONResponse("Invalid request", status=status.HTTP_400_BAD_REQUEST) if request.method == 'POST': # New Policy rules_string = request.body.splitlines() for rule_string in rules_string: # # Rules improved: # TODO: Handle the new parameters of the rule # Add containers and object in rules # Add execution server in rules # Add object type in rules # try: condition_list, rule_parsed = dsl_parser.parse(rule_string) if condition_list: # Dynamic Rule http_host = request.META['HTTP_HOST'] deploy_dynamic_policy(r, rule_string, rule_parsed, http_host) else: # Static Rule deploy_static_policy(request, r, rule_parsed) except SwiftClientError: return JSONResponse('Error accessing Swift.', status=status.HTTP_500_INTERNAL_SERVER_ERROR) except StorletNotFoundException: return JSONResponse('Storlet not found.', status=status.HTTP_404_NOT_FOUND) except ProjectNotFound: return JSONResponse('Invalid Project Name/ID. The Project does not exist.', status=status.HTTP_404_NOT_FOUND) except ProjectNotCrystalEnabled: return JSONResponse('The project is not Crystal Enabled. Verify it in the Projects panel.', status=status.HTTP_404_NOT_FOUND) except Exception as e: logger.info('Unexpected exception: ' + e.message) return JSONResponse('Please, review the rule, and start the related workload ' 'metric before creating a new policy', status=status.HTTP_401_UNAUTHORIZED) return JSONResponse('Policies added successfully!', status=status.HTTP_201_CREATED) if request.method == 'PUT': # Dynamic Policy From form http_host = request.META['HTTP_HOST'] data = JSONParser().parse(request) policy_id = r.incr("policies:id") rule_id = 'policy:' + str(policy_id) action = data['action'] project_id = data['project_id'] container = data['container_id'] if project_id == 'global': project_name = 'Global' else: project_list = get_project_list() project_name = project_list[project_id] if container: target_id = os.path.join(project_id, container) target_name = os.path.join(project_name, container) else: target_id = project_id target_name = project_name if data['transient']: location = settings.RULE_TRANSIENT_MODULE else: location = settings.RULE_MODULE policy_location = os.path.join(settings.PYACTOR_URL, location, str(rule_id)) policy_data = {"id": policy_id, "target_id": target_id, "target_name": target_name, "filter": data['filter_id'], "parameters": data['params'], "action": action, "condition": data['workload_metric']+' '+data['condition'], "object_type": data['object_type'], "object_size": data['object_size'], "object_tag": data['object_tag'], "object_name": ', '.join(r.lrange('object_type:' + data['object_type'], 0, -1)), "transient": data['transient'], "policy_location": policy_location, "status": 'Alive'} start_dynamic_policy_actor(policy_data, http_host) try: r.hmset(rule_id, policy_data) return JSONResponse("Policy inserted correctly", status=status.HTTP_201_CREATED) except RedisError: return JSONResponse("Error inserting policy", status=status.HTTP_400_BAD_REQUEST) return JSONResponse('Method ' + str(request.method) + ' not allowed.', status=status.HTTP_405_METHOD_NOT_ALLOWED)