diff --git a/endpoints/api/repositorynotification.py b/endpoints/api/repositorynotification.py index cecff5d2e..c34cbc553 100644 --- a/endpoints/api/repositorynotification.py +++ b/endpoints/api/repositorynotification.py @@ -3,14 +3,14 @@ import logging from flask import request -from endpoints.api import (RepositoryParamResource, nickname, resource, require_repo_admin, - log_action, validate_json_request, request_error, - path_param, disallow_for_app_repositories, InvalidRequest) +from endpoints.api import ( + RepositoryParamResource, nickname, resource, require_repo_admin, log_action, + validate_json_request, request_error, path_param, disallow_for_app_repositories, InvalidRequest) from endpoints.exception import NotFound from notifications.models_interface import Repository from notifications.notificationevent import NotificationEvent -from notifications.notificationmethod import (NotificationMethod, - CannotValidateNotificationMethodException) +from notifications.notificationmethod import ( + NotificationMethod, CannotValidateNotificationMethodException) from endpoints.api.repositorynotification_models_pre_oci import pre_oci_model as model logger = logging.getLogger(__name__) @@ -69,17 +69,16 @@ class RepositoryNotificationList(RepositoryParamResource): raise request_error(message=ex.message) new_notification = model.create_repo_notification(namespace_name, repository_name, - parsed['event'], - parsed['method'], - parsed['config'], - parsed['eventConfig'], + parsed['event'], parsed['method'], + parsed['config'], parsed['eventConfig'], parsed.get('title')) - log_action('add_repo_notification', namespace_name, - {'repo': repository_name, 'namespace': namespace_name, - 'notification_id': new_notification.uuid, - 'event': new_notification.event_name, 'method': new_notification.method_name}, - repo_name=repository_name) + log_action('add_repo_notification', namespace_name, { + 'repo': repository_name, + 'namespace': namespace_name, + 'notification_id': new_notification.uuid, + 'event': new_notification.event_name, + 'method': new_notification.method_name}, repo_name=repository_name) return new_notification.to_dict(), 201 @require_repo_admin @@ -88,9 +87,7 @@ class RepositoryNotificationList(RepositoryParamResource): def get(self, namespace_name, repository_name): """ List the notifications for the specified repository. """ notifications = model.list_repo_notifications(namespace_name, repository_name) - return { - 'notifications': [n.to_dict() for n in notifications] - } + return {'notifications': [n.to_dict() for n in notifications]} @resource('/v1/repository//notification/') @@ -98,6 +95,7 @@ class RepositoryNotificationList(RepositoryParamResource): @path_param('uuid', 'The UUID of the notification') class RepositoryNotification(RepositoryParamResource): """ Resource for dealing with specific notifications. """ + @require_repo_admin @nickname('getRepoNotification') @disallow_for_app_repositories @@ -115,12 +113,15 @@ class RepositoryNotification(RepositoryParamResource): """ Deletes the specified notification. """ deleted = model.delete_repo_notification(namespace_name, repository_name, uuid) if not deleted: - raise InvalidRequest("No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid)) + raise InvalidRequest("No repository notification found for: %s, %s, %s" % + (namespace_name, repository_name, uuid)) - log_action('delete_repo_notification', namespace_name, - {'repo': repository_name, 'namespace': namespace_name, 'notification_id': uuid, - 'event': deleted.event_name, 'method': deleted.method_name}, - repo_name=repository_name) + log_action('delete_repo_notification', namespace_name, { + 'repo': repository_name, + 'namespace': namespace_name, + 'notification_id': uuid, + 'event': deleted.event_name, + 'method': deleted.method_name}, repo_name=repository_name) return 'No Content', 204 @@ -131,12 +132,15 @@ class RepositoryNotification(RepositoryParamResource): """ Resets repository notification to 0 failures. """ reset = model.reset_notification_number_of_failures(namespace_name, repository_name, uuid) if not reset: - raise InvalidRequest("No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid)) + raise InvalidRequest("No repository notification found for: %s, %s, %s" % + (namespace_name, repository_name, uuid)) - log_action('reset_repo_notification', namespace_name, - {'repo': repository_name, 'namespace': namespace_name, 'notification_id': uuid, - 'event': reset.event_name, 'method': reset.method_name}, - repo_name=repository_name) + log_action('reset_repo_notification', namespace_name, { + 'repo': repository_name, + 'namespace': namespace_name, + 'notification_id': uuid, + 'event': reset.event_name, + 'method': reset.method_name}, repo_name=repository_name) return 'No Content', 204 @@ -146,6 +150,7 @@ class RepositoryNotification(RepositoryParamResource): @path_param('uuid', 'The UUID of the notification') class TestRepositoryNotification(RepositoryParamResource): """ Resource for queuing a test of a notification. """ + @require_repo_admin @nickname('testRepoNotification') @disallow_for_app_repositories @@ -153,6 +158,7 @@ class TestRepositoryNotification(RepositoryParamResource): """ Queues a test notification for this repository. """ test_note = model.queue_test_notification(uuid) if not test_note: - raise InvalidRequest("No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid)) + raise InvalidRequest("No repository notification found for: %s, %s, %s" % + (namespace_name, repository_name, uuid)) return {}, 200 diff --git a/endpoints/api/repositorynotification_models_interface.py b/endpoints/api/repositorynotification_models_interface.py index 52c1214ff..ed0ebd2f7 100644 --- a/endpoints/api/repositorynotification_models_interface.py +++ b/endpoints/api/repositorynotification_models_interface.py @@ -26,6 +26,7 @@ class RepositoryNotification( :type event_config: string :type number_of_failures: int """ + def to_dict(self): try: config = json.loads(self.config_json) @@ -55,7 +56,8 @@ class RepoNotificationInterface(object): """ @abstractmethod - def create_repo_notification(self, namespace_name, repository_name, event_name, method_name, method_config, event_config, title=None): + def create_repo_notification(self, namespace_name, repository_name, event_name, method_name, + method_config, event_config, title=None): """ Args: diff --git a/endpoints/api/repositorynotification_models_pre_oci.py b/endpoints/api/repositorynotification_models_pre_oci.py index 8f1a1a4d8..b3edf43ae 100644 --- a/endpoints/api/repositorynotification_models_pre_oci.py +++ b/endpoints/api/repositorynotification_models_pre_oci.py @@ -3,25 +3,25 @@ import json from app import notification_queue from data import model from data.model import InvalidNotificationException -from endpoints.api.repositorynotification_models_interface import RepoNotificationInterface, RepositoryNotification +from endpoints.api.repositorynotification_models_interface import (RepoNotificationInterface, + RepositoryNotification) from notifications import build_notification_data from notifications.notificationevent import NotificationEvent class RepoNotificationPreOCIModel(RepoNotificationInterface): - - def create_repo_notification(self, namespace_name, repository_name, event_name, method_name, method_config, event_config, title=None): + def create_repo_notification(self, namespace_name, repository_name, event_name, method_name, + method_config, event_config, title=None): repository = model.repository.get_repository(namespace_name, repository_name) - return self._notification(model.notification.create_repo_notification(repository, - event_name, - method_name, - method_config, - event_config, - title)) + return self._notification( + model.notification.create_repo_notification(repository, event_name, method_name, + method_config, event_config, title)) def list_repo_notifications(self, namespace_name, repository_name, event_name=None): - return [self._notification(n) - for n in model.notification.list_repo_notifications(namespace_name, repository_name, event_name)] + return [ + self._notification(n) + for n in model.notification.list_repo_notifications(namespace_name, repository_name, + event_name)] def get_repo_notification(self, uuid): try: @@ -39,7 +39,8 @@ class RepoNotificationPreOCIModel(RepoNotificationInterface): def reset_notification_number_of_failures(self, namespace_name, repository_name, uuid): return self._notification( - model.notification.reset_notification_number_of_failures(namespace_name, repository_name, uuid)) + model.notification.reset_notification_number_of_failures(namespace_name, repository_name, + uuid)) def queue_test_notification(self, uuid): try: @@ -52,23 +53,20 @@ class RepoNotificationPreOCIModel(RepoNotificationInterface): sample_data = event_info.get_sample_data(notification.repository.namespace_user.username, notification.repository.name, event_config) notification_data = build_notification_data(notification, sample_data) - notification_queue.put([notification.repository.namespace_user.username, notification.uuid, - notification.event.name], json.dumps(notification_data)) + notification_queue.put([ + notification.repository.namespace_user.username, notification.uuid, notification.event.name], + json.dumps(notification_data)) return self._notification(notification) - def _notification(self, notification): if not notification: return None - return RepositoryNotification(uuid=notification.uuid, - title=notification.title, - event_name=notification.event.name, - method_name=notification.method.name, - config_json=notification.config_json, - event_config_json=notification.event_config_json, - number_of_failures=notification.number_of_failures) + return RepositoryNotification( + uuid=notification.uuid, title=notification.title, event_name=notification.event.name, + method_name=notification.method.name, config_json=notification.config_json, + event_config_json=notification.event_config_json, + number_of_failures=notification.number_of_failures) - -pre_oci_model = RepoNotificationPreOCIModel() \ No newline at end of file +pre_oci_model = RepoNotificationPreOCIModel() diff --git a/endpoints/v1/index.py b/endpoints/v1/index.py index 3e34498f4..07aa00e67 100644 --- a/endpoints/v1/index.py +++ b/endpoints/v1/index.py @@ -14,7 +14,6 @@ from auth.permissions import ( CreateRepositoryPermission, repository_read_grant, repository_write_grant) from auth.signedgrant import generate_signed_token from endpoints.decorators import anon_protect, anon_allowed, parse_repository_name -from endpoints.notificationhelper import spawn_notification from endpoints.v1 import v1_bp from endpoints.v1.models_pre_oci import pre_oci_model as model from notifications import spawn_notification diff --git a/endpoints/v2/manifest.py b/endpoints/v2/manifest.py index 1ef0646f5..c5e33662b 100644 --- a/endpoints/v2/manifest.py +++ b/endpoints/v2/manifest.py @@ -10,7 +10,6 @@ from app import docker_v2_signing_key, app, metric_queue from auth.registry_jwt_auth import process_registry_jwt_auth from digest import digest_tools from endpoints.decorators import anon_protect, parse_repository_name -from endpoints.notificationhelper import spawn_notification from endpoints.v2 import v2_bp, require_repo_read, require_repo_write from endpoints.v2.models_interface import Label from endpoints.v2.models_pre_oci import data_model as model diff --git a/notifications/__init__.py b/notifications/__init__.py index 6264958e9..04903167d 100644 --- a/notifications/__init__.py +++ b/notifications/__init__.py @@ -6,7 +6,6 @@ from app import app, notification_queue from data import model from auth.auth_context import get_authenticated_user, get_validated_oauth_token - DEFAULT_BATCH_SIZE = 1000 @@ -17,8 +16,7 @@ def build_repository_event_data(namespace_name, repo_name, extra_data=None, subp """ repo_string = '%s/%s' % (namespace_name, repo_name) homepage = '%s://%s/repository/%s' % (app.config['PREFERRED_URL_SCHEME'], - app.config['SERVER_HOSTNAME'], - repo_string) + app.config['SERVER_HOSTNAME'], repo_string) if subpage: if not subpage.startswith('/'): @@ -37,6 +35,7 @@ def build_repository_event_data(namespace_name, repo_name, extra_data=None, subp event_data.update(extra_data or {}) return event_data + def build_notification_data(notification, event_data, performer_data=None): if not performer_data: performer_data = {} @@ -67,13 +66,13 @@ def notification_batch(batch_size=DEFAULT_BATCH_SIZE): the callable will be bulk inserted into the queue with the specified batch size. """ with notification_queue.batch_insert(batch_size) as queue_put: + def spawn_notification_batch(repo, event_name, extra_data=None, subpage=None, pathargs=None, performer_data=None): event_data = build_repository_event_data(repo.namespace_name, repo.name, extra_data=extra_data, subpage=subpage) - notifications = model.notification.list_repo_notifications(repo.namespace_name, - repo.name, + notifications = model.notification.list_repo_notifications(repo.namespace_name, repo.name, event_name=event_name) path = [repo.namespace_name, repo.name, event_name] + (pathargs or []) for notification in list(notifications): diff --git a/notifications/models_interface.py b/notifications/models_interface.py index 4c5dac3bd..734977c81 100644 --- a/notifications/models_interface.py +++ b/notifications/models_interface.py @@ -1,5 +1,6 @@ from collections import namedtuple + class Repository(namedtuple('Repository', ['namespace_name', 'name'])): """ Repository represents a repository.