This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/endpoints/api/logs.py

210 lines
8.5 KiB
Python
Raw Normal View History

""" Access usage logs for organizations or repositories. """
2015-05-14 20:47:38 +00:00
2014-03-14 20:02:13 +00:00
from datetime import datetime, timedelta
from endpoints.api import (resource, nickname, ApiResource, query_param, parse_args,
RepositoryParamResource, require_repo_admin, related_user_resource,
format_date, require_user_admin, path_param, require_scope, page_support)
from endpoints.api.logs_models_pre_oci import pre_oci_model as model
from endpoints.exception import Unauthorized, NotFound
2017-02-09 00:52:17 +00:00
from auth.permissions import AdministerOrganizationPermission
2014-03-14 20:02:13 +00:00
from auth.auth_context import get_authenticated_user
from auth import scopes
2014-03-14 20:02:13 +00:00
LOGS_PER_PAGE = 20
SERVICE_LEVEL_LOG_KINDS = set(['service_key_create', 'service_key_approve', 'service_key_delete',
'service_key_modify', 'service_key_extend', 'service_key_rotate'])
2014-03-14 20:02:13 +00:00
def _validate_logs_arguments(start_time, end_time):
2014-03-14 20:02:13 +00:00
if start_time:
try:
start_time = datetime.strptime(start_time + ' UTC', '%m/%d/%Y %Z')
except ValueError:
start_time = None
2014-11-24 21:07:38 +00:00
if not start_time:
start_time = datetime.today() - timedelta(7) # One week
2014-03-14 20:02:13 +00:00
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
2014-11-24 21:07:38 +00:00
if not end_time:
2014-03-14 20:02:13 +00:00
end_time = datetime.today()
return start_time, end_time
def get_logs(start_time, end_time, performer_name=None, repository_name=None, namespace_name=None,
page_token=None, ignore=None):
(start_time, end_time) = _validate_logs_arguments(start_time, end_time)
kinds = model.get_log_entry_kinds()
log_entry_page = model.get_logs_query(start_time, end_time, performer_name, repository_name,
namespace_name, ignore, page_token)
include_namespace = namespace_name is None and repository_name is None
2014-03-14 20:02:13 +00:00
return {
'start_time': format_date(start_time),
'end_time': format_date(end_time),
'logs': [log.to_dict(kinds, include_namespace) for log in log_entry_page.logs],
}, log_entry_page.next_page_token
def get_aggregate_logs(start_time, end_time, performer_name=None, repository=None, namespace=None,
ignore=None):
(start_time, end_time) = _validate_logs_arguments(start_time, end_time)
kinds = model.get_log_entry_kinds()
aggregated_logs = model.get_aggregated_logs(start_time, end_time, performer_name=performer_name,
repository_name=repository, namespace_name=namespace,
ignore=ignore)
return {
'aggregated': [log.to_dict(kinds, start_time) for log in aggregated_logs]
2014-03-14 20:02:13 +00:00
}
@resource('/v1/repository/<apirepopath:repository>/logs')
@path_param('repository', 'The full path of the repository. e.g. namespace/name')
2014-03-14 20:02:13 +00:00
class RepositoryLogs(RepositoryParamResource):
""" Resource for fetching logs for the specific repository. """
2014-03-14 20:02:13 +00:00
@require_repo_admin
@nickname('listRepoLogs')
@parse_args()
@query_param('starttime', 'Earliest time from which to get logs. The time should be formatted "%m/%d/%Y" in UTC.', type=str)
@query_param('endtime', 'Latest time to which to get logs. The time should be formatted "%m/%d/%Y" in UTC.', type=str)
@page_support()
def get(self, namespace, repository, page_token, parsed_args):
2014-03-14 20:02:13 +00:00
""" List the logs for the specified repository. """
if model.repo_exists(namespace, repository) is False:
raise NotFound()
2014-03-14 20:02:13 +00:00
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
return get_logs(start_time, end_time, repository_name=repository, page_token=page_token,
namespace_name=namespace)
2014-03-14 20:02:13 +00:00
@resource('/v1/user/logs')
class UserLogs(ApiResource):
""" Resource for fetching logs for the current user. """
@require_user_admin
@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)
@page_support()
def get(self, parsed_args, page_token):
""" List the logs for the current user. """
performer_name = parsed_args['performer']
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
user = get_authenticated_user()
return get_logs(start_time, end_time, performer_name=performer_name,
namespace_name=user.username, page_token=page_token,
ignore=SERVICE_LEVEL_LOG_KINDS)
2014-03-14 20:02:13 +00:00
@resource('/v1/organization/<orgname>/logs')
@path_param('orgname', 'The name of the organization')
@related_user_resource(UserLogs)
2014-03-14 20:02:13 +00:00
class OrgLogs(ApiResource):
""" Resource for fetching logs for the entire organization. """
2014-03-14 20:02:13 +00:00
@nickname('listOrgLogs')
@parse_args()
2014-03-14 20:02:13 +00:00
@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)
@page_support()
@require_scope(scopes.ORG_ADMIN)
def get(self, orgname, page_token, parsed_args):
2014-03-14 20:02:13 +00:00
""" List the logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
performer_name = parsed_args['performer']
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
2014-03-14 20:02:13 +00:00
return get_logs(start_time, end_time, namespace_name=orgname, performer_name=performer_name,
page_token=page_token, ignore=SERVICE_LEVEL_LOG_KINDS)
raise Unauthorized()
@resource('/v1/repository/<apirepopath:repository>/aggregatelogs')
@path_param('repository', 'The full path of the repository. e.g. namespace/name')
class RepositoryAggregateLogs(RepositoryParamResource):
""" Resource for fetching aggregated logs for the specific repository. """
@require_repo_admin
@nickname('getAggregateRepoLogs')
@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, namespace, repository, parsed_args):
""" Returns the aggregated logs for the specified repository. """
if model.repo_exists(namespace, repository) is False:
raise NotFound()
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
return get_aggregate_logs(start_time, end_time, repository=repository, namespace=namespace)
@resource('/v1/user/aggregatelogs')
class UserAggregateLogs(ApiResource):
""" Resource for fetching aggregated logs for the current user. """
@require_user_admin
@nickname('getAggregateUserLogs')
@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, parsed_args):
""" Returns the aggregated logs for the current user. """
performer_name = parsed_args['performer']
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
user = get_authenticated_user()
return get_aggregate_logs(start_time, end_time, performer_name=performer_name,
namespace=user.username, ignore=SERVICE_LEVEL_LOG_KINDS)
@resource('/v1/organization/<orgname>/aggregatelogs')
@path_param('orgname', 'The name of the organization')
@related_user_resource(UserLogs)
class OrgAggregateLogs(ApiResource):
""" Resource for fetching aggregate logs for the entire organization. """
@nickname('getAggregateOrgLogs')
@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)
@require_scope(scopes.ORG_ADMIN)
def get(self, orgname, parsed_args):
""" Gets the aggregated logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
performer_name = parsed_args['performer']
start_time = parsed_args['starttime']
end_time = parsed_args['endtime']
return get_aggregate_logs(start_time, end_time, namespace=orgname,
performer_name=performer_name, ignore=SERVICE_LEVEL_LOG_KINDS)
2014-03-14 20:02:13 +00:00
raise Unauthorized()