def create_workflow(): data = request.get_json() workflow_id = request.args.get("source") workflow_name = data['name'] try: new_permissions = data['permissions'] except: new_permissions = [] if request.files and 'file' in request.files: data = json.loads(request.files['file'].read().decode('utf-8')) if workflow_id: wf = current_app.running_context.execution_db.session.query(Workflow)\ .filter(Workflow.id_ == workflow_id).first() if wf.name == workflow_name: return unique_constraint_problem('workflow', 'create', workflow_name) copy_permissions = wf.permissions return copy_workflow(workflow=wf, workflow_name=workflow_name, permissions=copy_permissions) wf2 = current_app.running_context.execution_db.session.query(Workflow) \ .filter(Workflow.id_ == data['id_']).first() if wf2: return import_workflow(data) else: if new_permissions: update_permissions("workflows", workflow_name, new_permissions=new_permissions) else: default_permissions("workflows", workflow_name) try: workflow = workflow_schema.load(data) current_app.running_context.execution_db.session.add(workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f" Created Workflow {workflow.name} ({workflow.id_})") return workflow_schema.dump(workflow), HTTPStatus.CREATED except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem('workflow', 'create', workflow_name, e.messages) except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'create', workflow_name)
def import_workflow(workflow_json): new_permissions = workflow_json['permissions'] regenerate_workflow_ids(workflow_json) workflow_json['name'] = workflow_json.get("name") if new_permissions: update_permissions("workflows", workflow_json['name'], new_permissions=new_permissions) else: default_permissions("workflows", workflow_json['name']) try: new_workflow = workflow_schema.load(workflow_json) current_app.running_context.execution_db.session.add(new_workflow) current_app.running_context.execution_db.session.commit() return workflow_schema.dump(new_workflow), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() current_app.logger.error( f" Could not import workflow {workflow_json['name']}. Unique constraint failed" ) return unique_constraint_problem('workflow', 'import', workflow_json['name'])
def update_global(global_var): data = request.get_json() global_id = data["id_"] new_permissions = data['permissions'] to_update = auth_check(global_id, "update", "global_variables") if to_update: if new_permissions: auth_check(global_id, "update", "global_variables", updated_roles=new_permissions) else: default_permissions("global_variables", global_id) try: with open(config.ENCRYPTION_KEY_PATH, 'rb') as f: data['value'] = fernet_encrypt(f.read(), data['value']) global_variable_schema.load(data, instance=global_var) current_app.running_context.execution_db.session.commit() return global_variable_schema.dump(global_var), HTTPStatus.OK except (IntegrityError, StatementError): current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable", "update", data["name"]) else: return None, HTTPStatus.FORBIDDEN
def copy_workflow(workflow, permissions, workflow_name=None): old_json = workflow_schema.dump(workflow) workflow_json = deepcopy(old_json) update_check = auth_check(workflow_json["name"], "update", "workflows") if not update_check: return None, HTTPStatus.FORBIDDEN regenerate_workflow_ids(workflow_json) if workflow_name: workflow_json['name'] = workflow_name else: workflow_json['name'] = old_json.get("name") update_permissions("workflows", workflow_json['name'], permissions) try: new_workflow = workflow_schema.load(workflow_json) current_app.running_context.execution_db.session.add(new_workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f" Workflow {workflow.id_} copied to {new_workflow.id_}") return workflow_schema.dump(new_workflow), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() current_app.logger.error( f" Could not copy workflow {workflow_json['name']}. Unique constraint failed" ) return unique_constraint_problem('workflow', 'copy', workflow_json['name'])
def update_workflow(workflow): data = request.get_json() old_name = workflow.name new_name = data['name'] new_permissions = data['permissions'] to_update = auth_check(old_name, "update", "workflows") if to_update: auth_check(old_name, "update", "workflows", new_name=new_name, updated_roles=new_permissions) try: workflow_schema.load(data, instance=workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f"Updated workflow {workflow.name} ({workflow.id_})") return workflow_schema.dump(workflow), HTTPStatus.OK except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem('workflow', 'update', workflow.id_, e.messages) except IntegrityError: # ToDo: Make sure this fires on duplicate current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'update', workflow.id_) else: return None, HTTPStatus.FORBIDDEN
def update_global(global_var): username = get_jwt_claims().get('username', None) curr_user_id = (db.session.query(User).filter(User.username == username).first()).id data = request.get_json() global_id = data["id_"] new_permissions = data['permissions'] access_level = data['access_level'] to_update = auth_check(global_id, "update", "global_variables") if (global_var.creator == curr_user_id) or to_update: if access_level == 0: auth_check(global_id, "update", "global_variables", updated_roles=[{"role": 1, "permissions": ["delete", "execute", "read", "update"]}]) if access_level == 1: default_permissions("global_variables", global_id, data=data) elif access_level == 2: auth_check(global_id, "update", "global_variables", updated_roles=new_permissions) # if new_permissions: # auth_check(global_id, "update", "global_variables", updated_roles=new_permissions) # else: # default_permissions("global_variables", global_id, data=data) try: key = config.get_from_file(config.ENCRYPTION_KEY_PATH)#, 'rb') data['value'] = fernet_encrypt(key, data['value']) global_variable_schema.load(data, instance=global_var) current_app.running_context.execution_db.session.commit() return global_variable_schema.dump(global_var), HTTPStatus.OK except (IntegrityError, StatementError): current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable", "update", data["name"]) else: return None, HTTPStatus.FORBIDDEN
def update_global_templates(global_template): data = request.get_json() try: global_variable_template_schema.load(data, instance=global_template) current_app.running_context.execution_db.session.commit() return global_variable_template_schema.dump(global_template), HTTPStatus.OK except (IntegrityError, StatementError): current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable_template", "update", data["name"])
def copy_workflow(workflow, permissions, workflow_name=None, creator=None): old_json = workflow_schema.dump(workflow) workflow_json = deepcopy(old_json) update_check = auth_check(workflow_json["id_"], "update", "workflows") if (not update_check) and (workflow_json['creator'] != creator): return None, HTTPStatus.FORBIDDEN regenerate_workflow_ids(workflow_json) if workflow_name: workflow_json['name'] = workflow_name else: workflow_json['name'] = old_json.get("name") workflow_json['creator'] = creator access_level = workflow_json['access_level'] if access_level == 0: update_permissions("workflows", workflow_json['id_'], new_permissions=[{ "role": 1, "permissions": ["delete", "execute", "read", "update"] }], creator=creator) if access_level == 1: default_permissions("workflows", workflow_json['id_'], data=workflow_json, creator=creator) elif access_level == 2: update_permissions("workflows", workflow_json['id_'], new_permissions=permissions, creator=creator) # if permissions: # update_permissions("workflows", workflow_json['id_'], new_permissions=permissions, creator=creator) # else: # default_permissions("workflows", workflow_json['id_'], data=workflow_json, creator=creator) try: new_workflow = workflow_schema.load(workflow_json) current_app.running_context.execution_db.session.add(new_workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f" Workflow {workflow.id_} copied to {new_workflow.id_}") return workflow_schema.dump(new_workflow), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() current_app.logger.error( f" Could not copy workflow {workflow_json['name']}. Unique constraint failed" ) return unique_constraint_problem('workflow', 'copy', workflow_json['name'])
def create_global(): data = request.get_json() try: global_variable = global_variable_schema.load(data) current_app.running_context.execution_db.session.add(global_variable) current_app.running_context.execution_db.session.commit() return global_variable_schema.dump(global_variable), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable", "create", data["name"])
def update_workflow_status(execution_id): old_workflow_status = workflow_status_schema.dump(execution_id) data = request.get_json() # TODO: change these on the db model to be keyed by ID if "node_statuses" in old_workflow_status: old_workflow_status["node_statuses"] = { astat['node_id']: astat for astat in old_workflow_status["node_statuses"] } else: old_workflow_status["node_statuses"] = {} patch = jsonpatch.JsonPatch.from_string(json.dumps(data)) logger.debug(f"Patch: {patch}") logger.debug(f"Old Workflow Status: {old_workflow_status}") new_workflow_status = patch.apply(old_workflow_status) new_workflow_status["node_statuses"] = list( new_workflow_status["node_statuses"].values()) event = request.args.get("event") try: execution_id = workflow_status_schema.load(new_workflow_status, instance=execution_id) current_app.running_context.execution_db.session.commit() node_statuses = [] for patch in data: if "node_statuses" in patch["path"]: node_statuses.append( node_status_getter(patch["value"]["combined_id"])) # TODo: Replace this when moving to sanic current_app.logger.info( f"Workflow Status update: {new_workflow_status}") gevent.spawn(push_to_workflow_stream_queue, new_workflow_status, event) if node_statuses: current_app.logger.info(f"Action Status update:{node_statuses}") gevent.spawn(push_to_action_stream_queue, node_statuses, event) current_app.logger.info( f"Updated workflow status {execution_id.execution_id} ({execution_id.name})" ) return workflow_status_schema.dump(execution_id), HTTPStatus.OK except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow status', 'update', execution_id.id_)
def update_dashboard(dashboard): data = request.get_json() try: dashboard_schema.load(data, instance=dashboard) # return invalid_input_problem("dashboard", "update", data["name"], errors) # ToDo: validation current_app.running_context.execution_db.session.commit() current_app.logger.info(f"Updated dashboard {dashboard}") return dashboard_schema.dump(dashboard), HTTPStatus.OK except (IntegrityError, StatementError): current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("dashboard", "update", data["name"])
def create_global(): data = request.get_json() global_id = data['id_'] username = get_jwt_claims().get('username', None) curr_user = db.session.query(User).filter( User.username == username).first() data.update({'creator': curr_user.id}) new_permissions = data['permissions'] access_level = data['access_level'] # creator only if access_level == 0: update_permissions("global_variables", global_id, new_permissions=[{ "role": 1, "permissions": ["delete", "execute", "read", "update"] }], creator=curr_user.id) # default permissions elif access_level == 1: default_permissions("global_variables", global_id, data=data, creator=curr_user.id) # user-specified permissions elif access_level == 2: update_permissions("global_variables", global_id, new_permissions=new_permissions, creator=curr_user.id) # if new_permissions: # update_permissions("global_variables", global_id, new_permissions=new_permissions, creator=curr_user.id) # else: # default_permissions("global_variables", global_id, data=data, creator=curr_user.id) try: key = config.get_from_file(config.ENCRYPTION_KEY_PATH, 'rb') data['value'] = fernet_encrypt(key, data['value']) global_variable = global_variable_schema.load(data) current_app.running_context.execution_db.session.add(global_variable) current_app.running_context.execution_db.session.commit() return global_variable_schema.dump(global_variable), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable", "create", data["name"])
def update_workflow(workflow): username = get_jwt_claims().get('username', None) curr_user_id = (db.session.query(User).filter( User.username == username).first()).id data = request.get_json() new_permissions = data['permissions'] access_level = data['access_level'] to_update = auth_check(str(workflow.id_), "update", "workflows") if (workflow.creator == curr_user_id) or to_update: if access_level == 0: auth_check(str(workflow.id_), "update", "workflows", updated_roles=[{ "role": 1, "permissions": ["delete", "execute", "read", "update"] }]) elif access_level == 1: default_permissions("workflows", str(workflow.id_), data=data) elif access_level == 2: auth_check(str(workflow.id_), "update", "workflows", updated_roles=new_permissions) # if new_permissions: # auth_check(str(workflow.id_), "update", "workflows", updated_roles=new_permissions) # else: # default_permissions("workflows", str(workflow.id_), data=data) try: workflow_schema.load(data, instance=workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f"Updated workflow {workflow.name} ({workflow.id_})") return workflow_schema.dump(workflow), HTTPStatus.OK except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem('workflow', 'update', workflow.id_, e.messages) except IntegrityError: # ToDo: Make sure this fires on duplicate current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'update', workflow.id_) else: return None, HTTPStatus.FORBIDDEN
def create_dashboard(): data = request.get_json() dashboard_name = data["name"] try: dashboard = dashboard_schema.load(data) current_app.running_context.execution_db.session.add(dashboard) current_app.running_context.execution_db.session.commit() return dashboard_schema.dump(dashboard), HTTPStatus.CREATED except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem("dashboard", "create", dashboard_name, e.messages) except (IntegrityError, StatementError): current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("dashboard", "create", dashboard_name)
def update_workflow(workflow_id): data = request.get_json() errors = workflow_schema.load(data, instance=workflow_id).errors if errors: return invalid_input_problem("global_variable", "update", data["name"], errors) try: current_app.running_context.execution_db.session.commit() current_app.logger.info( f"Updated workflow {workflow_id.name} ({workflow_id.id_})") return workflow_schema.dump(workflow_id), HTTPStatus.OK except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'update', workflow_id.id_)
def import_workflow_and_regenerate_ids(workflow_json, creator): new_permissions = workflow_json['permissions'] access_level = workflow_json['access_level'] regenerate_workflow_ids(workflow_json) workflow_json['name'] = workflow_json.get("name") if access_level == 0: update_permissions("workflows", workflow_json['id_'], new_permissions=[{ "role": 1, "permissions": ["delete", "execute", "read", "update"] }], creator=creator) if access_level == 1: default_permissions("workflows", workflow_json['id_'], data=workflow_json, creator=creator) elif access_level == 2: update_permissions("workflows", workflow_json['id_'], new_permissions=new_permissions, creator=creator) # if new_permissions: # update_permissions("workflows", workflow_json['id_'], new_permissions=new_permissions, creator=creator) # else: # default_permissions("workflows", workflow_json['id_'], data=workflow_json, creator=creator) try: new_workflow = workflow_schema.load(workflow_json) current_app.running_context.execution_db.session.add(new_workflow) current_app.running_context.execution_db.session.commit() return workflow_schema.dump(new_workflow), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() current_app.logger.error( f" Could not import workflow {workflow_json['name']}. Unique constraint failed" ) return unique_constraint_problem('workflow', 'import', workflow_json['name'])
def create_workflow(): data = request.get_json() workflow_id = request.args.get("source") workflow_name = data['name'] if workflow_id: return copy_workflow(workflow_id=workflow_id) try: workflow = workflow_schema.load(data) current_app.running_context.execution_db.session.add(workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f"Created Workflow {workflow.name} ({workflow.id_})") return workflow_schema.dump(workflow), HTTPStatus.CREATED except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem('workflow', 'create', workflow_name, e.messages) except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'create', workflow_name)
def copy_workflow(workflow_id): data = request.get_json() workflow_json = workflow_schema.dump(workflow_id) workflow_json['name'] = data.get("name", f"{workflow_id.name}_copy") regenerate_workflow_ids(workflow_json) try: new_workflow = workflow_schema.load(workflow_json) current_app.running_context.execution_db.session.add(new_workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f"Workflow {workflow_id.id_} copied to {new_workflow.id_}") return workflow_schema.dump(new_workflow), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() current_app.logger.error( f"Could not copy workflow {workflow_json['name']}. Unique constraint failed" ) return unique_constraint_problem('workflow', 'copy', workflow_json['name'])
def create_global(): data = request.get_json() global_id = data['id_'] new_permissions = data['permissions'] if new_permissions: update_permissions("global_variables", global_id, new_permissions=new_permissions) else: default_permissions("global_variables", global_id) try: with open(config.ENCRYPTION_KEY_PATH, 'rb') as f: data['value'] = fernet_encrypt(f.read(), data['value']) global_variable = global_variable_schema.load(data) current_app.running_context.execution_db.session.add(global_variable) current_app.running_context.execution_db.session.commit() return global_variable_schema.dump(global_variable), HTTPStatus.CREATED except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem("global_variable", "create", data["name"])
def create_workflow(): data = request.get_json() workflow_id = request.args.get("source") workflow_name = data['name'] username = get_jwt_claims().get('username', None) curr_user = db.session.query(User).filter( User.username == username).first() data.update({'creator': curr_user.id}) # handling old WALKOFF workflow data try: new_permissions = data['permissions'] access_level = data['access_level'] except: new_permissions = [] data['permissions'] = [] access_level = 0 data['access_level'] = 0 if request.files and 'file' in request.files: data = json.loads(request.files['file'].read().decode('utf-8')) if workflow_id: wf = current_app.running_context.execution_db.session.query(Workflow)\ .filter(Workflow.id_ == workflow_id).first() if wf.name == workflow_name: return unique_constraint_problem('workflow', 'create', workflow_name) copy_permissions = wf.permissions return copy_workflow(workflow=wf, permissions=copy_permissions, workflow_name=workflow_name, creator=curr_user.id) wf2 = current_app.running_context.execution_db.session.query(Workflow) \ .filter(Workflow.id_ == data['id_']).first() if wf2: return import_workflow_and_regenerate_ids(data, curr_user.id) try: workflow = workflow_schema.load(data) # creator only if access_level == 0: update_permissions("workflows", str(workflow.id_), new_permissions=[{ "role": 1, "permissions": ["delete", "execute", "read", "update"] }], creator=curr_user.id) # default permissions elif access_level == 1: default_permissions("workflows", str(workflow.id_), data, creator=curr_user.id) # user-specified permissions elif access_level == 2: update_permissions("workflows", str(workflow.id_), new_permissions=new_permissions, creator=curr_user.id) # if new_permissions: # update_permissions("workflows", str(workflow.id_), new_permissions=new_permissions, creator=curr_user.id) # else: # default_permissions("workflows", str(workflow.id_), data, creator=curr_user.id) current_app.running_context.execution_db.session.add(workflow) current_app.running_context.execution_db.session.commit() current_app.logger.info( f" Created Workflow {workflow.name} ({workflow.id_})") return workflow_schema.dump(workflow), HTTPStatus.CREATED except ValidationError as e: current_app.running_context.execution_db.session.rollback() return improper_json_problem('workflow', 'create', workflow_name, e.messages) except IntegrityError: current_app.running_context.execution_db.session.rollback() return unique_constraint_problem('workflow', 'create', workflow_name)