def org_add_user(user, org_id_slug, user_email): if not user.admin: raise AuthError('You must be an admin to add a user to an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to edit this Org.') # localize localize(org) # get this new user by id / email new_org_user = fetch_by_id_or_field(User, 'email', user_email) if not new_org_user: raise RequestError('User "{}" does not exist'.format(user_email)) # ensure that user is not already a part of this Org. if new_org_user.id in org.user_ids: raise RequestError('User "{}" is already a part of Org "{}"'.format( new_org_user.email, org.name)) org.users.append(new_org_user) db.session.commit() return jsonify(new_org_user)
def org_user(user, org_id_slug, user_email): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') # localize localize(org) # get this new user by id / email org_user = fetch_by_id_or_field(User, 'email', user_email) if not org_user: raise RequestError( 'This user does not yet exist') # check whether this user can view this other user: if not len(list(set(org_user.org_ids).intersection(set(user.org_ids)))): raise ForbiddenError( 'You are not allowed to view this user.' .format(user.email)) return jsonify(org_user)
def org_user(user, org_id_slug, user_email): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) # get this new user by id / email org_user = fetch_by_id_or_field(User, 'email', user_email) if not org_user: raise RequestError('This user does not yet exist') # check whether this user can view this other user: if not len(list(set(org_user.org_ids).intersection(set(user.org_ids)))): raise ForbiddenError('You are not allowed to view this user.'.format( user.email)) return jsonify(org_user)
def merge_authors(user, org, from_author_id, to_author_id): """ Merge two authors. """ from_a = fetch_by_id_or_field(Author, 'name', from_author_id, org_id=org.id, transform='upper') if not from_a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(from_author_id)) to_a = fetch_by_id_or_field(Author, 'name', to_author_id, org_id=org.id, transform='upper') if not to_a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(to_author_id)) # re associate content stmt = update(content_items_authors)\ .where(and_( content_items_authors.c.author_id == from_author_id, ~content_items_authors.c.content_item_id.in_(to_a.content_item_ids)))\ .values(author_id=to_author_id) db.session.execute(stmt) # remove from author id db.session.delete(from_a) db.session.commit() return jsonify(to_a.to_dict(incl_content=True))
def org_remove_user(user, org_id_slug, user_email): if not user.admin: raise AuthError( 'You must be an admin to remove a user from an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( "You are not allowed to access this Org.") # get this existing user by id / email existing_user = fetch_by_id_or_field(User, 'email', user_email) if not existing_user: raise RequestError( 'User "{}" does not yet exist' .format(user_email)) # ensure that user is not already a part of this Org. if existing_user.id not in org.user_ids: raise RequestError( 'User "{}" is not a part of Org "{}"' .format(existing_user.email, org.name)) # remove the user from the org org.users.remove(existing_user) # if we're force-deleting the user, do so # but make sure their recipes are re-assigned # to the super-user if arg_bool('force', False): cmd = "UPDATE recipes set user_id={} WHERE user_id={}"\ .format(org.super_user.id, existing_user.id) db.session.execute(cmd) db.session.delete(user) db.session.commit() return delete_response()
def delete_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) force = arg_bool('force', default=False) if force: db.session.delete(r) else: # just delete recipes with no approved events. event_cnt = r.events.filter_by(status='approved').count() if event_cnt > 0: r.status = 'inactive' db.session.add(r) else: db.session.delete(r) # set the status of associated events to 'deleted' cmd = """ UPDATE events SET status='deleted' WHERE recipe_id = {} AND status='pending'; """.format(r.id) db.session.execute(cmd) db.session.commit() return delete_response()
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) db.session.add(r) db.session.commit() return jsonify(r)
def create_recipe(user, org): req_data = request_data() sous_chef = req_data.pop('sous_chef', arg_str('sous_chef', None)) if not sous_chef: raise RequestError( 'You must pass in a SousChef ID or slug to create a recipe.') sc = fetch_by_id_or_field(SousChef, 'slug', sous_chef) if not sc: raise RequestError( 'A SousChef does not exist with ID/slug {}'.format(sous_chef)) # validate the recipe and add it to the database. recipe = recipe_schema.validate(req_data, sc.to_dict()) r = Recipe(sc, user_id=user.id, org_id=org.id, **recipe) db.session.add(r) db.session.commit() # if the recipe creates metrics create them in here. if 'metrics' in sc.creates: for name, params in sc.metrics.items(): m = Metric(name=name, recipe_id=r.id, org_id=org.id, **params) db.session.add(m) try: db.session.commit() except Exception as e: raise ConflictError( "You tried to create a metric that already exists. " "Here's the exact error:\n{}".format(e.message)) return jsonify(r)
def update_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, 'slug', sous_chef) if not sc: raise NotFoundError( 'A SousChef does not exist with ID/slug {}' .format(sous_chef)) req_data = request_data() # validate the schema new_sous_chef = sous_chef_schema.update(sc, req_data) # udpate for name, value in new_sous_chef.items(): setattr(sc, name, value) db.session.add(sc) try: db.session.commit() except Exception as e: raise RequestError( "An error occurred while updating SousChef '{}'. " "Here's the error message: {}" .format(sc.slug, e.message)) return jsonify(sc)
def update_metric(user, org, name_id): m = fetch_by_id_or_field(Metric, 'name', name_id, org_id=org.id) if not m: raise NotFoundError( 'Metric "{}" does not yet exist for Org "{}"' .format(name_id, org.name)) # get the request data req_data = request_data() # filter out any non-columns columns = get_table_columns(Metric) for k in req_data.keys(): if k not in columns: req_data.pop(k) # don't ever overwrite these: for k in ['id', 'recipe_id', 'name', 'org_id', 'created', 'updated']: if k in req_data: req_data.pop(k, None) # update fields for k, v in req_data.items(): setattr(m, k, v) try: db.session.add(m) db.session.commit() except Exception as e: raise RequestError("Error updating Metric: {}".format(e.message)) return jsonify(m)
def author_remove_content(user, org, author_id, content_item_id): """ Remove an author from a content item. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(author_id)) c = ContentItem.query\ .filter_by(id=content_item_id, org_id=org.id)\ .first() if not c: raise RequestError( 'ContentItem with ID {} does not exist.' .format(content_item_id)) if a.id in c.author_ids: a.content_items.remove(c) db.session.add(a) db.session.commit() return delete_response()
def author_add_content(user, org, author_id, content_item_id): """ Add an author to a content item. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(author_id)) c = ContentItem.query\ .filter_by(id=content_item_id, org_id=org.id)\ .first() if not c: raise RequestError( 'ContentItem with ID {} does not exist.' .format(content_item_id)) if a.id not in c.author_ids: c.authors.append(a) db.session.add(c) db.session.commit() # return modified author return jsonify(a.to_dict(incl_content=True))
def delete_metric(user, org, name_id): m = fetch_by_id_or_field(Metric, 'name', name_id, org_id=org.id) if not m: raise NotFoundError( 'Metric "{}" does not yet exist.' .format(name_id)) # format for deleting metrics from metric store. cmd_fmt = "UPDATE {table} " + \ "SET metrics=json_del_keys(metrics, '{name}'::text);"\ .format(name=m.name) # delete metric from metric stores. if 'timeseries' in m.content_levels: db.session.execute(cmd_fmt.format(table="content_metric_timeseries")) if 'summary' in m.content_levels: db.session.execute(cmd_fmt.format(table="content_metric_summary")) if 'timeseries' in m.org_levels: db.session.execute(cmd_fmt.format(table="org_metric_timeseries")) if 'summary' in m.org_levels: db.session.execute(cmd_fmt.format(table="org_metric_summary")) db.session.delete(m) db.session.commit() return delete_response()
def update_author(user, org, author_id): """ Update an author. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."'.format(author_id)) req_data = request_data() cols = get_table_columns(Author) for k in req_data.keys(): if k not in cols or k in ['id', 'org_id']: req_data.pop(k, None) for k, v in req_data.items(): if k == 'name': if v: v = v.upper() setattr(a, k, v) db.session.add(a) db.session.commit() return jsonify(a)
def cook_a_recipe(user, org, recipe_id): """ Run recipes via the API. """ r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # setup kwargs for merlynne kw = dict(org=org.to_dict(incl_auths=True, auths_as_dict=True, settings_as_dict=True, incl_domains=True, incl_users=True), apikey=user.apikey, recipe=r.to_dict(), recipe_obj=r, sous_chef_path=r.sous_chef.runs) # cook recipe merlynne = Merlynne(**kw) try: job_id = merlynne.cook_recipe() except Exception as e: raise RequestError( 'There was a problem initializing the SousChef: {}'.format( e.message)) # # return job status url ret = url_for_job_status(apikey=user.apikey, job_id=job_id, queue='recipe') return jsonify(ret, status=202)
def decorated_function(*args, **kw): # get the org org_id = arg_str('org', default=None) if not org_id: raise AuthError( 'An org is required for this request.') # get the user object. user = kw.get('user') org = fetch_by_id_or_field(Org, 'slug', org_id) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'An Org with ID/Slug {} does exist.' .format(org_id)) # otherwise ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".' .format(user.name, org.name)) # check if we should localize this request localize(org) kw['org'] = org return f(*args, **kw)
def update_author(user, org, author_id): """ Update an author. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(author_id)) req_data = request_data() cols = get_table_columns(Author) for k in req_data.keys(): if k not in cols or k in ['id', 'org_id']: req_data.pop(k, None) for k, v in req_data.items(): if k == 'name': if v: v = v.upper() setattr(a, k, v) db.session.add(a) db.session.commit() return jsonify(a)
def update_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, 'slug', sous_chef) if not sc: raise NotFoundError( 'A SousChef does not exist with ID/slug {}'.format(sous_chef)) req_data = request_data() # validate the schema new_sous_chef = sous_chef_schema.update(sc, req_data) # udpate for name, value in new_sous_chef.items(): setattr(sc, name, value) db.session.add(sc) try: db.session.commit() except Exception as e: raise RequestError("An error occurred while updating SousChef '{}'. " "Here's the error message: {}".format( sc.slug, e.message)) return jsonify(sc)
def org_delete(user, org_id_slug): if not user.admin: raise AuthError('You must be an admin to delete an Org') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".'.format( user.name, org.name)) db.session.delete(org) db.session.commit() return delete_response()
def delete_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError('Recipe with id/slug {} does not exist.' .format(recipe_id)) force = arg_bool('force', default=False) if force: db.session.delete(r) else: # just delete recipes with no approved events. event_cnt = r.events.filter_by(status='approved').count() if event_cnt > 0: r.status = 'inactive' db.session.add(r) else: db.session.delete(r) # set the status of associated pending events to 'deleted' cmd = """ UPDATE events SET status='deleted' WHERE recipe_id = {} AND status='pending'; """.format(r.id) db.session.execute(cmd) db.session.commit() return delete_response()
def author_add_content(user, org, author_id, content_item_id): """ Add an author to a content item. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."'.format(author_id)) c = ContentItem.query\ .filter_by(id=content_item_id, org_id=org.id)\ .first() if not c: raise RequestError( 'ContentItem with ID {} does not exist.'.format(content_item_id)) if a.id not in c.author_ids: c.authors.append(a) db.session.add(c) db.session.commit() # return modified author return jsonify(a.to_dict(incl_content=True))
def decorated_function(*args, **kw): # get the org org_id = arg_str('org', default=None) if not org_id: raise AuthError('An org is required for this request.') # get the user object. user = kw.get('user') org = fetch_by_id_or_field(Org, 'slug', org_id) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'An Org with ID/Slug {} does exist.'.format(org_id)) # otherwise ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".'.format( user.name, org.name)) # check if we should localize this request localize(org) kw['org'] = org return f(*args, **kw)
def get_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, "slug", sous_chef) if not sc: raise NotFoundError("A SousChef does not exist with ID/slug {}".format(sous_chef)) return jsonify(sc)
def org_delete(user, org_id_slug): if not user.admin: raise AuthError( 'You must be an admin to delete an Org') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".' .format(user.name, org.name)) db.session.delete(org) db.session.commit() return delete_response()
def bulk_create_org_timeseries(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') req_data = request_data() job_id = ingest_bulk.org_timeseries( req_data, org_id=org.id, metrics_lookup=org.timeseries_metrics, commit=False ) ret = url_for_job_status(apikey=user.apikey, job_id=job_id, queue='bulk') return jsonify(ret)
def author_remove_content(user, org, author_id, content_item_id): """ Remove an author from a content item. """ a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."'.format(author_id)) c = ContentItem.query\ .filter_by(id=content_item_id, org_id=org.id)\ .first() if not c: raise RequestError( 'ContentItem with ID {} does not exist.'.format(content_item_id)) if a.id in c.author_ids: a.content_items.remove(c) db.session.add(a) db.session.commit() return delete_response()
def org_metrics_summary(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') # localize localize(org) req_data = request_data() ret = ingest_metric.org_summary( req_data, org_id=org.id, valid_metrics=org.org_summary_metric_names, commit=True ) return jsonify(ret)
def get_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError('Recipe with id/slug {} does not exist.' .format(recipe_id)) # add in event counts. return jsonify(r)
def get_template(user, org, slug_id): t = fetch_by_id_or_field(Template, 'slug', slug_id, org_id=org.id) if not t: raise NotFoundError( 'Template "{}" does not yet exist for Org "{}"' .format(slug_id, org.name)) return jsonify(t)
def get_template(user, org, slug_id): t = fetch_by_id_or_field(Template, 'slug', slug_id, org_id=org.id) if not t: raise NotFoundError( 'Template "{}" does not yet exist for Org "{}"'.format( slug_id, org.name)) return jsonify(t)
def get_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # add in event counts. return jsonify(r)
def get_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, 'slug', sous_chef) if not sc: raise NotFoundError( 'A SousChef does not exist with ID/slug {}'.format(sous_chef)) return jsonify(sc)
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError('Recipe with id/slug {} does not exist.' .format(recipe_id)) # keep track of current coptions hash. current_option_hash = copy.copy(r.options_hash) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) # if the new options hash is different than the old one, we should # override the last_job column to be null if current_option_hash != r.options_hash: r.last_job = {} db.session.add(r) # now install metrics + reports if new_recipe.get('status', 'uninitialized') and r.status == 'stable': for name, params in r.sous_chef.metrics.items(): m = Metric.query\ .filter_by(org_id=org.id, recipe_id=r.id, name=name, type=params['type'])\ .first() if not m: m = Metric( name=name, recipe_id=r.id, org_id=org.id, **params) else: for k, v in params.items(): setattr(m, k, v) db.session.add(m) db.session.commit() return jsonify(r)
def get_setting(user, org, level, name_id): if level not in ['me', 'orgs']: raise NotFoundError( 'You cannot store settings for \'{}\'' .format(level)) if level == 'me': s = fetch_by_id_or_field( Setting, 'name', name_id, org_id=org.id, user_id=user.id, level=level) else: s = fetch_by_id_or_field( Setting, 'name', name_id, org_id=org.id, level=level) if not s: raise NotFoundError( 'Setting "{}" does not yet exist for Org "{}"' .format(name_id, org.name)) return jsonify(s)
def update_tag(user, org, tag_id): """ Update an individual tag. """ # fetch the tag object tag = fetch_by_id_or_field(Tag, 'slug', tag_id, org_id=org.id) if not tag: raise NotFoundError( 'A Tag with ID {} does not exist' .format(tag_id)) # fetch the request data. req_data = request_data() # check hex code if 'color' in req_data: validate_hex_code(req_data['color']) # check tag type if 'type' in req_data: validate_tag_types(req_data['type']) # if tag type is "impact" ensure a proper category and # level are included if req_data['type'] == 'impact': validate_tag_categories(req_data['category']) validate_tag_levels(req_data['level']) # check if levels + categories are being assigned to # subject tags if tag.type == 'subject': if req_data.get('category') or req_data.get('level'): raise RequestError( 'Categories and Levels can only be set for Impact Tags') # set org id req_data['org_id'] = org.id # filter out non-table columns columns = get_table_columns(Tag) for k in req_data.keys(): if k not in columns: req_data.pop(k) # update attributes for k, v in req_data.items(): setattr(tag, k, v) db.session.add(tag) # check for dupes try: db.session.commit() except Exception as err: raise RequestError(err.message) return jsonify(tag)
def get_metric(user, org, name_id): m = fetch_by_id_or_field(Metric, 'name', name_id, org_id=org.id) if not m: raise NotFoundError( 'Metric "{}" does not yet exist for Org "{}"' .format(name_id, org.name)) return jsonify(m)
def get_setting(user, org, name_id): s = fetch_by_id_or_field(Setting, 'name', name_id, org_id=org.id) if not s: raise NotFoundError( 'Setting "{}" does not yet exist for Org "{}"' .format(name_id, org.name)) return jsonify(s)
def org_remove_user(user, org_id_slug, user_email): if not user.admin: raise AuthError('You must be an admin to remove a user from an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError("You are not allowed to access this Org.") # get this existing user by id / email existing_user = fetch_by_id_or_field(User, 'email', user_email) if not existing_user: raise RequestError('User "{}" does not yet exist'.format(user_email)) # ensure that user is not already a part of this Org. if existing_user.id not in org.user_ids: raise RequestError('User "{}" is not a part of Org "{}"'.format( existing_user.email, org.name)) # remove the user from the org org.users.remove(existing_user) # if we're force-deleting the user, do so # but make sure their recipes are re-assigned # to the super-user if arg_bool('force', False): cmd = "UPDATE recipes set user_id={} WHERE user_id={}"\ .format(org.super_user.id, existing_user.id) db.session.execute(cmd) db.session.delete(user) db.session.commit() return delete_response()
def delete_template(user, org, slug_id): t = fetch_by_id_or_field(Template, 'slug', slug_id, org_id=org.id) if not t: raise NotFoundError( 'Template "{}" does not yet exist for Org "{}"'.format( slug_id, org.name)) db.session.delete(t) db.session.commit() return delete_response()
def delete_template(user, org, slug_id): t = fetch_by_id_or_field(Template, 'slug', slug_id, org_id=org.id) if not t: raise NotFoundError( 'Template "{}" does not yet exist for Org "{}"' .format(slug_id, org.name)) db.session.delete(t) db.session.commit() return delete_response()
def delete_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, "slug", sous_chef) if not sc: raise NotFoundError("A SousChef does not exist with ID/slug {}".format(sous_chef)) db.session.delete(sc) db.session.commit() return delete_response()
def get_tag(user, org, tag_id): """ GET an individual tag. """ # fetch the tag object tag = fetch_by_id_or_field(Tag, 'slug', tag_id, org_id=org.id) if not tag: raise NotFoundError('A Tag with ID {} does not exist'.format(tag_id)) return jsonify(tag)
def delete_sous_chef(user, sous_chef): sc = fetch_by_id_or_field(SousChef, 'slug', sous_chef) if not sc: raise NotFoundError( 'A SousChef does not exist with ID/slug {}'.format(sous_chef)) db.session.delete(sc) db.session.commit() return delete_response()
def cook_a_recipe(user, org, recipe_id): """ Run recipes via the API. """ r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError('Recipe with id/slug {} does not exist.' .format(recipe_id)) # setup kwargs for merlynne kw = dict( org=org.to_dict( incl_auths=True, auths_as_dict=True, settings_as_dict=True, incl_domains=True, incl_users=True), apikey=user.apikey, recipe=r.to_dict(), recipe_obj=r, passthrough=arg_bool('passthrough', default=False), sous_chef_path=r.sous_chef.runs ) # initialize merlynne merlynne = Merlynne(**kw) try: resp = merlynne.cook_recipe() except Exception as e: raise RequestError( 'There was a problem initializing the SousChef: {}' .format(e.message)) # queued job if not kw['passthrough']: # set its status as 'queued' r.status = 'queued' db.session.add(r) db.session.commit() # # return job status url ret = url_for_job_status(apikey=user.apikey, job_id=resp, queue='recipe') return jsonify(ret, status=202) # format non-iterables. if isinstance(resp, dict): resp = [resp] # stream results def generate(): for item in resp: yield obj_to_json(item) + "\n" return Response(stream_with_context(generate()))
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # keep track of current coptions hash. current_option_hash = copy.copy(r.options_hash) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) # if the new options hash is different than the old one, we should # override the last_job column to be null if current_option_hash != r.options_hash: r.last_job = {} db.session.add(r) # now install metrics + reports if new_recipe.get('status', 'uninitialized') and r.status == 'stable': for name, params in r.sous_chef.metrics.items(): m = Metric.query\ .filter_by(org_id=org.id, recipe_id=r.id, name=name, type=params['type'])\ .first() if not m: m = Metric(name=name, recipe_id=r.id, org_id=org.id, **params) else: for k, v in params.items(): setattr(m, k, v) db.session.add(m) db.session.commit() return jsonify(r)
def delete_tag(user, org, tag_id): """ Delete an individual tag. """ # fetch the tag object tag = fetch_by_id_or_field(Tag, 'slug', tag_id, org_id=org.id) if not tag: raise NotFoundError('A Tag with ID {} does not exist'.format(tag_id)) db.session.delete(tag) db.session.commit() return delete_response()
def update_setting(user, org, level, name_id): if level not in ['me', 'orgs']: raise NotFoundError( 'You cannot store settings for \'{}\''.format(level)) s = fetch_by_id_or_field(Setting, 'name', name_id, org_id=org.id, user_id=user.id, level=level) if not s: raise NotFoundError('Setting "{}" does not yet exist.'.format( name_id, org.name)) # get the request data req_data = request_data() name = req_data.get('name') value = req_data.get('value') json_value = req_data.get('json_value') # if it's a json_value check whether we can parse it as such if json_value: if isinstance(value, basestring): try: obj_to_json(value) except: raise RequestError( "Setting '{}' with value '{}' was declared as a " "'json_value' but could not be parsed as such.".format( name_id, value)) # upsert / patch values. if name: s.name = name if json_value: if not isinstance(json_value, bool): if str(json_value).lower() in TRUE_VALUES: json_value = True else: json_value = False s.json_value = json_value s.value = obj_to_json(value) else: s.value = value db.session.add(s) db.session.commit() return jsonify(s)
def get_tag(user, org, tag_id): """ GET an individual tag. """ # fetch the tag object tag = fetch_by_id_or_field(Tag, 'slug', tag_id, org_id=org.id) if not tag: raise NotFoundError( 'A Tag with ID {} does not exist' .format(tag_id)) return jsonify(tag)
def get_author(user, org, author_id): """ Get an author. """ incl_content = arg_bool('incl_content', default=False) a = fetch_by_id_or_field(Author, 'name', author_id, org_id=org.id, transform='upper') if not a: raise NotFoundError( 'Author with ID/Name "{}" does not exist."' .format(author_id)) return jsonify(a.to_dict(incl_content=incl_content))
def org_create_user(user, org_id_slug): if not user.admin: raise AuthError( 'You must be an admin to create a user for an Org.') # get the form. req_data = request_data() email = req_data.get('email') password = req_data.get('password') name = req_data.get('name') admin = req_data.get('admin', False) if not all([email, password, name]): raise RequestError( 'An email, password, and name are required to create a User.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( "You are not allowed to access this Org.") if User.query.filter_by(email=email).first(): raise RequestError( 'A User with email "{}" already exists' .format(email)) if not mail.validate(email): raise RequestError( '{} is an invalid email address.' .format(email)) new_org_user = User( email=email, password=password, name=name, admin=admin) org.users.append(new_org_user) db.session.commit() return jsonify(new_org_user)
def delete_setting(user, org, name_id): s = fetch_by_id_or_field(Setting, 'name', name_id, org_id=org.id) if not s: raise NotFoundError( 'Setting "{}" does not yet exist for Org "{}"' .format(name_id, org.name)) db.session.delete(s) db.session.commit() return delete_response()
def update_setting(user, org, level, name_id): if level not in ['me', 'orgs']: raise NotFoundError( 'You cannot store settings for \'{}\'' .format(level)) s = fetch_by_id_or_field( Setting, 'name', name_id, org_id=org.id, user_id=user.id, level=level) if not s: raise NotFoundError( 'Setting "{}" does not yet exist.' .format(name_id, org.name)) # get the request data req_data = request_data() name = req_data.get('name') value = req_data.get('value') json_value = req_data.get('json_value') # if it's a json_value check whether we can parse it as such if json_value: if isinstance(value, basestring): try: obj_to_json(value) except: raise RequestError( "Setting '{}' with value '{}' was declared as a " "'json_value' but could not be parsed as such." .format(name_id, value)) # upsert / patch values. if name: s.name = name if json_value: if not isinstance(json_value, bool): if str(json_value).lower() in TRUE_VALUES: json_value = True else: json_value = False s.json_value = json_value s.value = obj_to_json(value) else: s.value = value db.session.add(s) db.session.commit() return jsonify(s)