274 lines
7.7 KiB
JavaScript
274 lines
7.7 KiB
JavaScript
|
/**
|
||
|
* Service which defines the various kinds of external notification and provides methods for
|
||
|
* easily looking up information about those kinds.
|
||
|
*/
|
||
|
angular.module('quay').factory('ExternalNotificationData', ['Config', 'Features','VulnerabilityService',
|
||
|
|
||
|
function(Config, Features, VulnerabilityService) {
|
||
|
var externalNotificationData = {};
|
||
|
|
||
|
var events = [
|
||
|
{
|
||
|
'id': 'repo_push',
|
||
|
'title': 'Push to Repository',
|
||
|
'icon': 'fa-upload'
|
||
|
}
|
||
|
];
|
||
|
|
||
|
if (Features.REPO_MIRROR) {
|
||
|
var repoMirrorEvents = [
|
||
|
{
|
||
|
'id': 'repo_mirror_sync_started',
|
||
|
'title': 'Repository Mirror Started',
|
||
|
'icon': 'fa-circle-o-notch'
|
||
|
},
|
||
|
{
|
||
|
'id': 'repo_mirror_sync_success',
|
||
|
'title': 'Repository Mirror Success',
|
||
|
'icon': 'fa-check-circle-o'
|
||
|
},
|
||
|
{
|
||
|
'id': 'repo_mirror_sync_failed',
|
||
|
'title': 'Repository Mirror Unsuccessful',
|
||
|
'icon': 'fa-times-circle-o'
|
||
|
}
|
||
|
];
|
||
|
|
||
|
for (var i = 0; i < repoMirrorEvents.length; ++i) {
|
||
|
events.push(repoMirrorEvents[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Features.BUILD_SUPPORT) {
|
||
|
var buildEvents = [
|
||
|
{
|
||
|
'id': 'build_queued',
|
||
|
'title': 'Dockerfile Build Queued',
|
||
|
'icon': 'fa-tasks',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'ref-regex',
|
||
|
'type': 'regex',
|
||
|
'title': 'matching ref(s)',
|
||
|
'help_text': 'An optional regular expression for matching the git branch or tag ' +
|
||
|
'git ref. If left blank, the notification will fire for all builds.',
|
||
|
'optional': true,
|
||
|
'placeholder': '(refs/heads/somebranch)|(refs/tags/sometag)'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'build_start',
|
||
|
'title': 'Dockerfile Build Started',
|
||
|
'icon': 'fa-circle-o-notch',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'ref-regex',
|
||
|
'type': 'regex',
|
||
|
'title': 'matching ref(s)',
|
||
|
'help_text': 'An optional regular expression for matching the git branch or tag ' +
|
||
|
'git ref. If left blank, the notification will fire for all builds.',
|
||
|
'optional': true,
|
||
|
'placeholder': '(refs/heads/somebranch)|(refs/tags/sometag)'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'build_success',
|
||
|
'title': 'Dockerfile Build Successfully Completed',
|
||
|
'icon': 'fa-check-circle-o',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'ref-regex',
|
||
|
'type': 'regex',
|
||
|
'title': 'matching ref(s)',
|
||
|
'help_text': 'An optional regular expression for matching the git branch or tag ' +
|
||
|
'git ref. If left blank, the notification will fire for all builds.',
|
||
|
'optional': true,
|
||
|
'placeholder': '(refs/heads/somebranch)|(refs/tags/sometag)'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'build_failure',
|
||
|
'title': 'Dockerfile Build Failed',
|
||
|
'icon': 'fa-times-circle-o',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'ref-regex',
|
||
|
'type': 'regex',
|
||
|
'title': 'matching ref(s)',
|
||
|
'help_text': 'An optional regular expression for matching the git branch or tag ' +
|
||
|
'git ref. If left blank, the notification will fire for all builds.',
|
||
|
'optional': true,
|
||
|
'placeholder': '(refs/heads/somebranch)|(refs/tags/sometag)'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'build_cancelled',
|
||
|
'title': 'Docker Build Cancelled',
|
||
|
'icon': 'fa-minus-circle',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'ref-regex',
|
||
|
'type': 'regex',
|
||
|
'title': 'matching ref(s)',
|
||
|
'help_text': 'An optional regular expression for matching the git branch or tag ' +
|
||
|
'git ref. If left blank, the notification will fire for all builds.',
|
||
|
'optional': true,
|
||
|
'placeholder': '(refs/heads/somebranch)|(refs/tags/sometag)'
|
||
|
}
|
||
|
]
|
||
|
}];
|
||
|
|
||
|
for (var i = 0; i < buildEvents.length; ++i) {
|
||
|
events.push(buildEvents[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Features.SECURITY_SCANNER) {
|
||
|
events.push({
|
||
|
'id': 'vulnerability_found',
|
||
|
'title': 'Package Vulnerability Found',
|
||
|
'icon': 'fa-bug',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'level',
|
||
|
'type': 'enum',
|
||
|
'title': 'minimum severity level',
|
||
|
'values': VulnerabilityService.LEVELS,
|
||
|
'help_text': 'A vulnerability must have a severity of the chosen level (or higher) ' +
|
||
|
'for this notification to fire. Defcon 1 is a special severity level ' +
|
||
|
'manually tagged by the ' + Config.REGISTRY_TITLE_SHORT + ' team for ' +
|
||
|
'above-critical issues',
|
||
|
}
|
||
|
]
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var methods = [
|
||
|
{
|
||
|
'id': 'quay_notification',
|
||
|
'title': Config.REGISTRY_TITLE_SHORT + ' Notification',
|
||
|
'icon': 'quay-icon',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'target',
|
||
|
'type': 'entity',
|
||
|
'title': 'Recipient',
|
||
|
'help_text': 'The ' + Config.REGISTRY_TITLE_SHORT + ' user to notify'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'email',
|
||
|
'title': 'E-mail',
|
||
|
'icon': 'fa-envelope',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'email',
|
||
|
'type': 'email',
|
||
|
'title': 'E-mail address'
|
||
|
}
|
||
|
],
|
||
|
'enabled': Features.MAILING
|
||
|
},
|
||
|
{
|
||
|
'id': 'webhook',
|
||
|
'title': 'Webhook POST',
|
||
|
'icon': 'fa-link',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'url',
|
||
|
'type': 'url',
|
||
|
'title': 'Webhook URL'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'flowdock',
|
||
|
'title': 'Flowdock Team Notification',
|
||
|
'icon': 'flowdock-icon',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'flow_api_token',
|
||
|
'type': 'string',
|
||
|
'title': 'Flow API Token',
|
||
|
'help_url': 'https://www.flowdock.com/account/tokens'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'hipchat',
|
||
|
'title': 'HipChat Room Notification',
|
||
|
'icon': 'hipchat-icon',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'room_id',
|
||
|
'type': 'pattern',
|
||
|
'title': 'Room ID #',
|
||
|
'pattern': '^[0-9]+$',
|
||
|
'help_url': 'https://hipchat.com/admin/rooms',
|
||
|
'pattern_fail_message': 'We require the HipChat room <b>number</b>, not name.'
|
||
|
},
|
||
|
{
|
||
|
'name': 'notification_token',
|
||
|
'type': 'string',
|
||
|
'title': 'Room Notification Token',
|
||
|
'help_url': 'https://hipchat.com/rooms/tokens/{room_id}'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
'id': 'slack',
|
||
|
'title': 'Slack Room Notification',
|
||
|
'icon': 'slack-icon',
|
||
|
'fields': [
|
||
|
{
|
||
|
'name': 'url',
|
||
|
'type': 'pattern',
|
||
|
'title': 'Webhook URL',
|
||
|
'pattern': '^https://hooks\\.slack\\.com/services/[A-Z0-9]+/[A-Z0-9]+/[a-zA-Z0-9]+$',
|
||
|
'help_url': 'https://slack.com/services/new/incoming-webhook',
|
||
|
'placeholder': 'https://hooks.slack.com/service/{some}/{token}/{here}'
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
];
|
||
|
|
||
|
var methodMap = {};
|
||
|
var eventMap = {};
|
||
|
|
||
|
for (var i = 0; i < methods.length; ++i) {
|
||
|
methodMap[methods[i].id] = methods[i];
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < events.length; ++i) {
|
||
|
eventMap[events[i].id] = events[i];
|
||
|
}
|
||
|
|
||
|
externalNotificationData.getSupportedEvents = function() {
|
||
|
return events;
|
||
|
};
|
||
|
|
||
|
externalNotificationData.getSupportedMethods = function() {
|
||
|
var filtered = [];
|
||
|
for (var i = 0; i < methods.length; ++i) {
|
||
|
if (methods[i].enabled !== false) {
|
||
|
filtered.push(methods[i]);
|
||
|
}
|
||
|
}
|
||
|
return filtered;
|
||
|
};
|
||
|
|
||
|
externalNotificationData.getEventInfo = function(event) {
|
||
|
return eventMap[event];
|
||
|
};
|
||
|
|
||
|
externalNotificationData.getMethodInfo = function(method) {
|
||
|
return methodMap[method];
|
||
|
};
|
||
|
|
||
|
return externalNotificationData;
|
||
|
}]);
|