Port logs and robots.

This commit is contained in:
jakedt 2014-03-14 16:02:13 -04:00
parent 3c268de025
commit 1bbe2283dc
4 changed files with 229 additions and 1 deletions

View file

@ -177,10 +177,12 @@ import endpoints.api.billing
import endpoints.api.build
import endpoints.api.discovery
import endpoints.api.image
import endpoints.api.logs
import endpoints.api.permission
import endpoints.api.prototype
import endpoints.api.repository
import endpoints.api.repotoken
import endpoints.api.robot
import endpoints.api.search
import endpoints.api.tag
import endpoints.api.team

View file

@ -2394,6 +2394,7 @@ def robot_view(name, token):
}
# Ported
@api_bp.route('/user/robots', methods=['GET'])
@api_login_required
def get_user_robots():
@ -2404,6 +2405,7 @@ def get_user_robots():
})
# Ported
@api_bp.route('/organization/<orgname>/robots', methods=['GET'])
@api_login_required
@org_api_call('get_user_robots')
@ -2418,6 +2420,7 @@ def get_org_robots(orgname):
abort(403)
# Ported
@api_bp.route('/user/robots/<robot_shortname>', methods=['PUT'])
@api_login_required
def create_user_robot(robot_shortname):
@ -2429,6 +2432,7 @@ def create_user_robot(robot_shortname):
return resp
# Ported
@api_bp.route('/organization/<orgname>/robots/<robot_shortname>',
methods=['PUT'])
@api_login_required
@ -2446,6 +2450,7 @@ def create_org_robot(orgname, robot_shortname):
abort(403)
# Ported
@api_bp.route('/user/robots/<robot_shortname>', methods=['DELETE'])
@api_login_required
def delete_user_robot(robot_shortname):
@ -2455,6 +2460,7 @@ def delete_user_robot(robot_shortname):
return make_response('Deleted', 204)
# Ported
@api_bp.route('/organization/<orgname>/robots/<robot_shortname>',
methods=['DELETE'])
@api_login_required
@ -2487,7 +2493,7 @@ def log_view(log):
return view
# Ported
@api_bp.route('/repository/<path:repository>/logs', methods=['GET'])
@api_login_required
@parse_repository_name
@ -2505,6 +2511,7 @@ def list_repo_logs(namespace, repository):
abort(403)
# Ported
@api_bp.route('/organization/<orgname>/logs', methods=['GET'])
@api_login_required
@org_api_call('list_user_logs')
@ -2521,6 +2528,7 @@ def list_org_logs(orgname):
abort(403)
# Ported
@api_bp.route('/user/logs', methods=['GET'])
@api_login_required
def list_user_logs():

121
endpoints/api/logs.py Normal file
View file

@ -0,0 +1,121 @@
import json
from datetime import datetime, timedelta
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, query_param, parse_args,
RepositoryParamResource, require_repo_admin)
from auth.permissions import AdministerOrganizationPermission, AdministerOrganizationPermission
from auth.auth_context import get_authenticated_user
from data import model
def log_view(log):
view = {
'kind': log.kind.name,
'metadata': json.loads(log.metadata_json),
'ip': log.ip,
'datetime': log.datetime,
}
if log.performer:
view['performer'] = {
'kind': 'user',
'name': log.performer.username,
'is_robot': log.performer.robot,
}
return view
def get_logs(namespace, start_time, end_time, performer_name=None,
repository=None):
performer = None
if performer_name:
performer = model.get_user(performer_name)
if start_time:
try:
start_time = datetime.strptime(start_time + ' UTC', '%m/%d/%Y %Z')
except ValueError:
start_time = None
if not start_time:
start_time = datetime.today() - timedelta(7) # One week
if end_time:
try:
end_time = datetime.strptime(end_time + ' UTC', '%m/%d/%Y %Z')
end_time = end_time + timedelta(days=1)
except ValueError:
end_time = None
if not end_time:
end_time = datetime.today()
logs = model.list_logs(namespace, start_time, end_time, performer=performer,
repository=repository)
return {
'start_time': start_time,
'end_time': end_time,
'logs': [log_view(log) for log in logs]
}
@resource('/v1/repository/<path:repository>/logs')
class RepositoryLogs(RepositoryParamResource):
""" Resource for fetching logs for the specific repository. """
@require_repo_admin
@nickname('listRepoLogs')
@parse_args
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
def get(self, args, namespace, repository):
""" List the logs for the specified repository. """
repo = model.get_repository(namespace, repository)
if not repo:
abort(404)
start_time = args['starttime']
end_time = args['endtime']
return get_logs(namespace, start_time, end_time, repository=repo)
@resource('/v1/organization/<orgname>/logs')
class OrgLogs(ApiResource):
""" Resource for fetching logs for the entire organization. """
@nickname('listOrgLogs')
@parse_args
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str)
# @org_api_call('list_user_logs')
def get(self, args, orgname):
""" List the logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
performer_name = args['performer']
start_time = args['starttime']
end_time = args['endtime']
return get_logs(orgname, start_time, end_time, performer_name=performer_name)
abort(403)
@resource('/v1/user/logs')
class UserLogs(ApiResource):
""" Resource for fetching logs for the current user. """
@nickname('listUserLogs')
@parse_args
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str)
def get(self, args):
""" List the logs for the current user. """
performer_name = args['performer']
start_time = args['starttime']
end_time = args['endtime']
return get_logs(get_authenticated_user().username, start_time, end_time,
performer_name=performer_name)

97
endpoints/api/robot.py Normal file
View file

@ -0,0 +1,97 @@
from flask.ext.restful import abort
from endpoints.api import resource, nickname, ApiResource, log_action
from auth.permissions import AdministerOrganizationPermission, OrganizationMemberPermission
from auth.auth_context import get_authenticated_user
from data import model
from util.names import format_robot_username
def robot_view(name, token):
return {
'name': name,
'token': token,
}
@resource('/user/robots')
class UserRobotList(ApiResource):
""" Resource for listing user robots. """
@nickname('getUserRobots')
def get(self):
""" List the available robots for the user. """
user = get_authenticated_user()
robots = model.list_entity_robots(user.username)
return {
'robots': [robot_view(name, password) for name, password in robots]
}
@resource('/user/robots/<robot_shortname>')
class UserRobot(ApiResource):
""" Resource for managing a user's robots. """
@nickname('createUserRobot')
def put(self, robot_shortname):
""" Create a new user robot with the specified name. """
parent = get_authenticated_user()
robot, password = model.create_robot(robot_shortname, parent)
resp = robot_view(robot.username, password)
log_action('create_robot', parent.username, {'robot': robot_shortname})
resp.status_code = 201
return resp
@nickname('deleteUserRobot')
def delete(self, robot_shortname):
""" Delete an existing robot. """
parent = get_authenticated_user()
model.delete_robot(format_robot_username(parent.username, robot_shortname))
log_action('delete_robot', parent.username, {'robot': robot_shortname})
return 'Deleted', 204
@resource('/organization/<orgname>/robots')
class OrgRobotList(ApiResource):
""" Resource for listing an organization's robots. """
@nickname('getOrgRobots')
#@org_api_call('get_user_robots')
def get(self, orgname):
""" List the organization's robots. """
permission = OrganizationMemberPermission(orgname)
if permission.can():
robots = model.list_entity_robots(orgname)
return {
'robots': [robot_view(name, password) for name, password in robots]
}
abort(403)
@resource('/organization/<orgname>/robots/<robot_shortname>')
class OrgRobot(ApiResource):
""" Resource for managing an organization's robots. """
@nickname('createOrgRobot')
#@org_api_call('create_user_robot')
def put(self, orgname, robot_shortname):
""" Create a new robot in the organization. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
parent = model.get_organization(orgname)
robot, password = model.create_robot(robot_shortname, parent)
resp = robot_view(robot.username, password)
log_action('create_robot', orgname, {'robot': robot_shortname})
resp.status_code = 201
return resp
abort(403)
@nickname('deleteOrgRobot')
#@org_api_call('delete_user_robot')
def delete(self, orgname, robot_shortname):
""" Delete an existing organization robot. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
model.delete_robot(format_robot_username(orgname, robot_shortname))
log_action('delete_robot', orgname, {'robot': robot_shortname})
return 'Deleted', 204
abort(403)