def post(self, actor_id): """Ensure a certain number of workers are running for an actor""" logger.debug("top of POST /actors/{}/workers.".format(actor_id)) id = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[id]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError("No actor found with id: {}.".format(actor_id), 404) args = self.validate_post() logger.debug( "workers POST params validated. actor: {}.".format(actor_id)) num = args.get('num') if not num or num == 0: logger.debug("did not get a num: {}.".format(actor_id)) num = 1 logger.debug("ensuring at least {} workers. actor: {}.".format( num, actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: workers = Worker.get_workers(dbid) except WorkerException as e: logger.debug( "did not find workers for actor: {}.".format(actor_id)) raise ResourceError(e.msg, 404) current_number_workers = len(workers.items()) if current_number_workers < num: logger.debug( "There were only {} workers for actor: {} so we're adding more." .format(current_number_workers, actor_id)) worker_ids = [] num_to_add = int(num) - len(workers.items()) logger.info("adding {} more workers for actor {}".format( num_to_add, actor_id)) for idx in range(num_to_add): worker_ids.append( Worker.request_worker(tenant=g.tenant, actor_id=actor_id)) logger.info("New worker ids: {}".format(worker_ids)) ch = CommandChannel() ch.put_cmd(actor_id=actor.db_id, worker_ids=worker_ids, image=actor.image, tenant=g.tenant, num=num_to_add, stop_existing=False) ch.close() logger.info( "Message put on command channel for new worker ids: {}".format( worker_ids)) return ok( result=None, msg="Scheduled {} new worker(s) to start. There were only". format(num_to_add)) else: return ok(result=None, msg="Actor {} already had {} worker(s).".format( actor_id, num))
def post(self, api_id): """Update an API.""" json_data = request.get_json() if not json_data: raise ResourceError( msg="Content type JSON required for creating APIs.") # first, find the API try: api = models.get_api_model(api_id=api_id) except DAOError: raise ResourceError(msg="API not found.") except TypeError as e: raise ResourceError(msg="Problem looking up API: {}.".format(e)) admin = ApiAdmin() try: rsp = admin.update_api(json_data) except DAOError as e: raise ResourceError(msg='Error trying to update API: {}'.format(e)) if not rsp.status_code == 200 or rsp.json().get('error'): raise ResourceError( msg='Error trying to update API: {}'.format(rsp.content)) a = {} a['name'] = json_data.get('name') a['version'] = json_data.get('version') or 'v2' a['provider'] = 'admin' return ok(result=models.api_details(models.get_api_id(a)), msg="API created successfully.")
def get(self, actor_id): logger.debug("top of GET /actors/{}/workers for tenant {}.".format( actor_id, g.tenant)) dbid = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError("No actor found with id: {}.".format(actor_id), 404) try: workers = Worker.get_workers(dbid) except WorkerException as e: logger.debug( "did not find workers for actor: {}.".format(actor_id)) raise ResourceError(e.msg, 404) result = [] for id, worker in workers.items(): worker.update({'id': id}) try: w = Worker(**worker) result.append(w.display()) except Exception as e: logger.error( "Unable to instantiate worker in workers endpoint from description: {}. " .format(worker)) return ok(result=result, msg="Workers retrieved successfully.")
def get(self, role_id): """Get details about a role.""" if role_id in models.all_roles(): return ok(result=models.role_details(role_id), msg="Role retrieved successfully.") else: raise ResourceError(msg="Role not found.", code=404)
def delete(self, actor_id): logger.debug("top of DELETE /actors/{}".format(actor_id)) id = Actor.get_dbid(g.tenant, actor_id) logger.info("calling shutdown_workers() for actor: {}".format(id)) shutdown_workers(id) logger.debug("shutdown_workers() done") try: actor = Actor.from_db(actors_store[id]) executions = actor.get('executions') or {} for ex_id, val in executions.items(): del logs_store[ex_id] except KeyError as e: logger.info("got KeyError {} trying to retrieve actor or executions with id {}".format( e, id)) # delete the actor's message channel # TODO - needs work; each worker is subscribed to the ActorMsgChannel. If the workers are not # closed before the ch.delete() below, the ActorMsgChannel will survive. try: ch = ActorMsgChannel(actor_id=id) ch.delete() logger.info("Deleted actor message channel for actor: {}".format(id)) except Exception as e: # if we get an error trying to remove the inbox, log it but keep going logger.error("Unable to delete the actor's message channel for actor: {}, exception: {}".format(id, e)) del actors_store[id] logger.info("actor {} deleted from store.".format(id)) del permissions_store[id] logger.info("actor {} permissions deleted from store.".format(id)) del nonce_store[id] logger.info("actor {} nonnces delete from nonce store.".format(id)) return ok(result=None, msg='Actor deleted successfully.')
def get(self, account_id, role_id): """Get details about a service account's occupation of a role.""" if models.has_role(account_id, role_id): return ok(result=models.role_details(role_id), msg="Role retrieved successfully.") raise ResourceError( msg="{} does not occupy role {}".format(account_id, role_id))
def get(self): result = { 'headerName': g.jwt_header_name, 'jwtRaw': g.jwt, 'jwtDecoded': g.jwt_decoded } return ok(result=result, msg="JWT generated successfully.")
def put(self, actor_id): logger.debug("top of PUT /actors/{}".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor {} in store.".format(dbid)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) previous_image = actor.image args = self.validate_put(actor) logger.debug("PUT args validated successfully.") args['tenant'] = g.tenant update_image = False if args['image'] == previous_image: logger.debug("new image is the same. not updating actor.") args['status'] = actor.status else: update_image = True args['status'] = SUBMITTED logger.debug("new image is different. updating actor.") args['api_server'] = g.api_server args['owner'] = g.user actor = Actor(**args) actors_store[actor.db_id] = actor.to_db() logger.info("updated actor {} stored in db.".format(actor_id)) worker_ids = Worker.request_worker(actor.db_id) if update_image: ch = CommandChannel() ch.put_cmd(actor_id=actor.db_id, worker_ids=worker_ids, image=actor.image, tenant=args['tenant']) logger.debug("put new command on command channel to update actor.") return ok(result=actor.display(), msg="Actor updated successfully.")
def post(self, actor_id): """Create a new nonce for an actor.""" logger.debug("top of POST /actors/{}/nonces".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) args = self.validate_post() logger.debug("nonce post args validated: {}.".format(actor_id)) # supply "provided" fields: args['tenant'] = g.tenant args['api_server'] = g.api_server args['db_id'] = dbid args['owner'] = g.user args['roles'] = g.roles # create and store the nonce: nonce = Nonce(**args) Nonce.add_nonce(dbid, nonce) logger.info("nonce added for actor: {}.".format(actor_id)) return ok(result=nonce.display(), msg="Actor nonce created successfully.")
def get(self, actor_id, execution_id): def get_hypermedia(actor, exc): return {'_links': {'self': '{}/actors/v2/{}/executions/{}/logs'.format(actor.api_server, actor.id, exc.id), 'owner': '{}/profiles/v2/{}'.format(actor.api_server, actor.owner), 'execution': '{}/actors/v2/{}/executions/{}'.format(actor.api_server, actor.id, exc.id)}, } logger.debug("top of GET /actors/{}/executions/{}/logs.".format(actor_id, execution_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) try: excs = executions_store[dbid] except KeyError: logger.debug("did not find executions. actor: {}.".format(actor_id)) raise ResourceError("No executions found for actor {}.".format(actor_id)) try: exc = Execution.from_db(excs[execution_id]) except KeyError: logger.debug("did not find execution: {}. actor: {}.".format(execution_id, actor_id)) raise ResourceError("Execution {} not found.".format(execution_id)) try: logs = logs_store[execution_id] except KeyError: logger.debug("did not find logs. execution: {}. actor: {}.".format(execution_id, actor_id)) logs = "" result={'logs': logs} result.update(get_hypermedia(actor, exc)) return ok(result, msg="Logs retrieved successfully.")
def put(self, api_id): """ Update an api status. :param api_id: :return: """ # first, find the API try: api = models.get_api_model(api_id=api_id) except DAOError: raise ResourceError(msg="API not found.") except TypeError as e: raise ResourceError(msg="Problem looking up API: {}.".format(e)) args = self.validate_put() status = args['status'] API_STATUSES = ('CREATED', 'PUBLISHED', 'RETIRED') if status not in API_STATUSES: raise ResourceError(msg='Invalid API status: must be one of {}'. format(API_STATUSES)) admin = ApiAdmin() try: admin.update_api_status(api_name=api['name'], api_version=api['version'], api_provider=api['owner'], status=status) except DAOError as e: raise ResourceError(msg="Error updating API status: {}".format(e)) except TypeError as e: raise ResourceError(msg="Problem updating API: {}.".format(e)) return ok(result=models.api_details(api_id), msg="API status updated successfully.")
def get(self, actor_id): def get_hypermedia(actor): return { '_links': { 'self': '{}/actors/v2/{}/messages'.format(actor.api_server, actor.id), 'owner': '{}/profiles/v2/{}'.format(actor.api_server, actor.owner), }, } logger.debug("top of GET /actors/{}/messages".format(actor_id)) # check that actor exists id = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[id]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError("No actor found with id: {}.".format(actor_id), 404) ch = ActorMsgChannel(actor_id=id) result = {'messages': len(ch._queue._queue)} ch.close() logger.debug("messages found for actor: {}.".format(actor_id)) result.update(get_hypermedia(actor)) return ok(result)
def get(self, role_id, account_id): """List details about a service account's occupation of a role.""" if models.has_role(account_id, role_id): return ok(result=models.account_details(account_id), msg="Service account retrieved successfully.") raise ResourceError( msg="{} is not occupied by service account {}".format( role_id, account_id))
def get(self, role_id): """List service accounts occupying a role.""" try: return ok(result=models.role_details(role_id), msg="Service accounts retrieved successfully.") except WebFault as e: admin = UserAdmin() raise ResourceError(msg=admin.error_msg(e))
def get(self, account_id): """List all roles occupied by a service account.""" try: return ok(result=models.account_details(account_id), msg="Roles retrieved successfully.") except WebFault as e: admin = UserAdmin() raise ResourceError(msg=admin.error_msg(e))
def get(self, actor_id): logger.debug("top of GET /actors/{}/state".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[dbid]) except KeyError: raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) return ok(result={'state': actor.get('state') }, msg="Actor state retrieved successfully.")
def get(self): logger.debug("top of GET /actors") actors = [] for k, v in actors_store.items(): if v['tenant'] == g.tenant: actor = Actor.from_db(v) if check_permissions(g.user, actor.db_id, READ): actors.append(actor.display()) logger.info("actors retrieved.") return ok(result=actors, msg="Actors retrieved successfully.")
def get(self, actor_id): logger.debug("top of GET /actors/{}/nonces".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) nonces = Nonce.get_nonces(actor_id=dbid) return ok(result=[n.display() for n in nonces], msg="Actor nonces retrieved successfully.")
def post(self): """Create a new role.""" args = self.validate_post() role_id = args['roleId'] admin = UserAdmin() try: admin.addInternalRole(roleName=models.role_in(role_id)) except WebFault as e: raise ResourceError(admin.error_msg(e)) return ok(result=models.role_details(role_id), msg="Role {} created successfully.".format(args['roleId']))
def get(self, actor_id): logger.debug("top of GET /actors/{}".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor with id: {}".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) logger.debug("found actor {}".format(actor_id)) return ok(result=actor.display(), msg="Actor retrieved successfully.")
def post(self, account_id): """Add a role to the list of roles occupied by a service account.""" args = self.validate_post() admin = UserAdmin() try: admin.updateRolesOfUser(userName=account_id, newUserList=models.role_in(args['roleId'])) except WebFault as e: raise ResourceError(msg=admin.error_msg(e)) return ok(result=models.account_details(account_id), msg="Role {} added successfully.".format(args['roleId']))
def delete(self, actor_id, worker_id): logger.debug("top of DELETE /actors/{}/workers/{}.".format(actor_id, worker_id)) id = Actor.get_dbid(g.tenant, actor_id) try: worker = Worker.get_worker(id, worker_id) except WorkerException as e: logger.debug("Did not find worker: {}. actor: {}.".format(worker_id, actor_id)) raise ResourceError(e.msg, 404) logger.info("calling shutdown_worker(). worker: {}. actor: {}.".format(worker_id, actor_id)) shutdown_worker(worker['id']) logger.info("shutdown_worker() called for worker: {}. actor: {}.".format(worker_id, actor_id)) return ok(result=None, msg="Worker scheduled to be stopped.")
def delete(self, actor_id, nonce_id): """Delete a nonce.""" logger.debug("top of DELETE /actors/{}/nonces/{}".format(actor_id, nonce_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) Nonce.delete_nonce(dbid, nonce_id) return ok(result=None, msg="Actor nonce deleted successfully.")
def get(self, actor_id, nonce_id): """Lookup details about a nonce.""" logger.debug("top of GET /actors/{}/nonces/{}".format(actor_id, nonce_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) nonce = Nonce.get_nonce(actor_id=dbid, nonce_id=nonce_id) return ok(result=nonce.display(), msg="Actor nonce retrieved successfully.")
def post(self, role_id): """Add a service account to the list of accounts occupying a role.""" args = self.validate_post() admin = UserAdmin() try: admin.addRemoveUsersOfRole(roleName=models.role_in(role_id), newUsers=args['accountId']) except WebFault as e: raise ResourceError(admin.error_msg(e)) return ok(result=models.role_details(role_id), msg="Service account {} added to role.".format( args['accountId']))
def get(self, actor_id): logger.debug("top of GET /actors/{}/permissions.".format(actor_id)) id = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[id]) except KeyError: logger.debug("Did not find actor: {}.".format(actor_id)) raise ResourceError("No actor found with id: {}.".format(actor_id), 404) try: permissions = get_permissions(id) except PermissionsException as e: logger.debug("Did not find permissions. actor: {}.".format(actor_id)) raise ResourceError(e.msg, 404) return ok(result=permissions, msg="Permissions retrieved successfully.")
def get(self, actor_id, worker_id): logger.debug("top of GET /actors/{}/workers/{}.".format(actor_id, worker_id)) id = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[id]) except KeyError: logger.debug("Did not find actor: {}.".format(actor_id)) raise ResourceError("No actor found with id: {}.".format(actor_id), 404) try: worker = Worker.get_worker(id, worker_id) except WorkerException as e: logger.debug("Did not find worker: {}. actor: {}.".format(worker_id, actor_id)) raise ResourceError(e.msg, 404) return ok(result=worker, msg="Worker retrieved successfully.")
def post(self, actor_id): logger.debug("top of POST /actors/{}/executions".format(actor_id)) id = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[id]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) args = self.validate_post() logger.debug("execution post args validated: {}.".format(actor_id)) Execution.add_execution(id, args) logger.info("execution added: {}.".format(actor_id)) return ok(result=actor.display(), msg="Actor execution added successfully.")
def post(self, actor_id): """Add new permissions for an actor""" logger.debug("top of POST /actors/{}/permissions.".format(actor_id)) id = Actor.get_dbid(g.tenant, actor_id) try: Actor.from_db(actors_store[id]) except KeyError: logger.debug("Did not find actor: {}.".format(actor_id)) raise ResourceError( "actor not found: {}'".format(actor_id), 404) args = self.validate_post() logger.debug("POST permissions body validated for actor: {}.".format(actor_id)) set_permission(args['user'], id, PermissionLevel(args['level'])) logger.info("Permission added for user: {} actor: {} level: {}".format(args['user'], id, args['level'])) permissions = get_permissions(id) return ok(result=permissions, msg="Permission added successfully.")
def get(self, actor_id): logger.debug("top of GET /actors/{}/executions".format(actor_id)) dbid = Actor.get_dbid(g.tenant, actor_id) try: actor = Actor.from_db(actors_store[dbid]) except KeyError: logger.debug("did not find actor: {}.".format(actor_id)) raise ResourceError( "No actor found with id: {}.".format(actor_id), 404) try: summary = ExecutionsSummary(db_id=dbid) except DAOError as e: logger.debug("did not find executions summary: {}".format(actor_id)) raise ResourceError("Could not retrieve executions summary for actor: {}. " "Details: {}".format(actor_id, e), 404) return ok(result=summary.display(), msg="Actor executions retrieved successfully.")