Port logs and robots.
This commit is contained in:
parent
3c268de025
commit
1bbe2283dc
4 changed files with 229 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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
121
endpoints/api/logs.py
Normal 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
97
endpoints/api/robot.py
Normal 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)
|
Reference in a new issue