diff --git a/endpoints/api.py b/endpoints/api.py
index 3a522c65a..0da04bc3b 100644
--- a/endpoints/api.py
+++ b/endpoints/api.py
@@ -1440,9 +1440,9 @@ def activate_build_trigger(namespace, repository, trigger_uuid):
'write')
try:
- repository = '%s/%s' % (trigger.repository.namespace,
- trigger.repository.name)
- path = url_for('webhooks.build_trigger_webhook', repository=repository,
+ repository_path = '%s/%s' % (trigger.repository.namespace,
+ trigger.repository.name)
+ path = url_for('webhooks.build_trigger_webhook', repository=repository_path,
trigger_uuid=trigger.uuid)
authed_url = _prepare_webhook_url(app.config['URL_SCHEME'], '$token',
token.code, app.config['URL_HOST'],
@@ -1460,6 +1460,13 @@ def activate_build_trigger(namespace, repository, trigger_uuid):
trigger.write_token = token
trigger.save()
+ # Log the trigger setup.
+ repo = model.get_repository(namespace, repository)
+ log_action('setup_repo_trigger', namespace,
+ {'repo': repository, 'namespace': namespace,
+ 'trigger_id': trigger.uuid, 'service': trigger.service.name,
+ 'config': final_config}, repo=repo)
+
return jsonify(trigger_view(trigger))
abort(403) # Permission denied
@@ -1542,10 +1549,12 @@ def delete_build_trigger(namespace, repository, trigger_uuid):
# We are just going to eat this error
logger.warning('Trigger deactivation problem.', ex)
+ log_action('delete_repo_trigger', namespace,
+ {'repo': repository, 'trigger_id': trigger_uuid,
+ 'service': trigger.service.name, 'config': config_dict},
+ repo=model.get_repository(namespace, repository))
+
trigger.delete_instance()
- log_action('delete_repo_trigger', namespace,
- {'repo': repository, 'trigger_id': trigger_uuid},
- repo=model.get_repository(namespace, repository))
return make_response('No Content', 204)
abort(403) # Permission denied
diff --git a/endpoints/webhooks.py b/endpoints/webhooks.py
index 65a2ec403..e82eea700 100644
--- a/endpoints/webhooks.py
+++ b/endpoints/webhooks.py
@@ -63,9 +63,9 @@ def build_trigger_webhook(namespace, repository, trigger_uuid):
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
logger.debug('Passing webhook request to handler %s', handler)
+ config_dict = json.loads(trigger.config)
try:
- specs = handler.handle_trigger_request(request, trigger.auth_token,
- json.loads(trigger.config))
+ specs = handler.handle_trigger_request(request, trigger.auth_token, config_dict)
dockerfile_id, tags, name, subdir = specs
except ValidationRequestException:
@@ -73,12 +73,12 @@ def build_trigger_webhook(namespace, repository, trigger_uuid):
return make_response('Okay')
host = urlparse.urlparse(request.url).netloc
- repo = '%s/%s/%s' % (host, trigger.repository.namespace,
- trigger.repository.name)
+ repo_path = '%s/%s/%s' % (host, trigger.repository.namespace,
+ trigger.repository.name)
token = model.create_access_token(trigger.repository, 'write')
logger.debug('Creating build %s with repo %s tags %s and dockerfile_id %s',
- name, repo, tags, dockerfile_id)
+ name, repo_path, tags, dockerfile_id)
job_config = {
'docker_tags': tags,
@@ -95,6 +95,17 @@ def build_trigger_webhook(namespace, repository, trigger_uuid):
'repository': repository,
}), retries_remaining=1)
+ metadata = {
+ 'repo': repository,
+ 'namespace': namespace,
+ 'trigger_id': trigger_uuid,
+ 'fileid': dockerfile_id,
+ 'config': config_dict,
+ 'service': trigger.service.name
+ }
+ repo = model.get_repository(namespace, repository)
+ model.log_action('build_dockerfile', namespace, ip=request.remote_addr, metadata=metadata, repository=repo)
+
return make_response('Okay')
- abort(403)
\ No newline at end of file
+ abort(403)
diff --git a/initdb.py b/initdb.py
index c6e9bbc29..9b4776d8b 100644
--- a/initdb.py
+++ b/initdb.py
@@ -220,7 +220,6 @@ def initialize_database():
LogEntryKind.create(name='modify_prototype_permission')
LogEntryKind.create(name='delete_prototype_permission')
- LogEntryKind.create(name='add_repo_trigger')
LogEntryKind.create(name='setup_repo_trigger')
LogEntryKind.create(name='delete_repo_trigger')
@@ -442,6 +441,12 @@ def populate_database():
timestamp=today,
metadata={'token_code': 'somecode', 'repo': 'orgrepo'})
+ model.log_action('build_dockerfile', new_user_1.username, repository=building,
+ timestamp=today,
+ metadata={'repo': 'building', 'namespace': new_user_1.username,
+ 'trigger_id': trigger.uuid, 'config': json.loads(trigger.config),
+ 'service': trigger.service.name})
+
if __name__ == '__main__':
app.config['LOGGING_CONFIG']()
initialize_database()
diff --git a/static/js/app.js b/static/js/app.js
index 7ec770f13..f66d39b96 100644
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -105,6 +105,7 @@ function getMarkedDown(string) {
quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angular-tour', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', '$strap.directives', 'ngCookies', 'ngSanitize', 'angular-md5', 'pasvaz.bindonce', 'ansiToHtml', 'ngAnimate'], function($provide, cfpLoadingBarProvider) {
cfpLoadingBarProvider.includeSpinner = false;
+
$provide.factory('UtilService', ['$sanitize', function($sanitize) {
var utilService = {};
@@ -121,6 +122,30 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
return utilService;
}]);
+
+ $provide.factory('TriggerDescriptionBuilder', ['UtilService', '$sanitize', function(UtilService, $sanitize) {
+ var builderService = {};
+
+ builderService.getDescription = function(name, config) {
+ switch (name) {
+ case 'github':
+ var source = $sanitize(UtilService.textToSafeHtml(config['build_source']));
+ var desc = ' Push to Github Repository ';
+ desc += '' + source + '';
+ if (config['subdir']) {
+ desc += '
Dockerfile folder: ' + UtilService.textToSafeHtml(config['subdir']);
+ }
+ return desc;
+
+ default:
+ return 'Unknown';
+ }
+ };
+
+ return builderService;
+ }]);
+
+
$provide.factory('ImageMetadataService', ['UtilService', function(UtilService) {
var metadataService = {};
metadataService.getFormattedCommand = function(image) {
@@ -1241,7 +1266,7 @@ quayApp.directive('logsView', function () {
'repository': '=repository',
'performer': '=performer'
},
- controller: function($scope, $element, $sce, Restangular, ApiService) {
+ controller: function($scope, $element, $sce, Restangular, ApiService, TriggerDescriptionBuilder) {
$scope.loading = true;
$scope.logs = null;
$scope.kindsAllowed = null;
@@ -1303,7 +1328,14 @@ quayApp.directive('logsView', function () {
'add_repo_webhook': 'Add webhook in repository {repo}',
'delete_repo_webhook': 'Delete webhook in repository {repo}',
'set_repo_description': 'Change description for repository {repo}: {description}',
- 'build_dockerfile': 'Build image from Dockerfile for repository {repo}',
+ 'build_dockerfile': function(metadata) {
+ if (metadata.trigger_id) {
+ var triggerDescription = TriggerDescriptionBuilder.getDescription(
+ metadata['service'], metadata['config']);
+ return 'Build image from Dockerfile for repository {repo} triggered by ' + triggerDescription;
+ }
+ return 'Build image from Dockerfile for repository {repo}';
+ },
'org_create_team': 'Create team: {team}',
'org_delete_team': 'Delete team: {team}',
'org_add_team_member': 'Add member {member} to team {team}',
@@ -1330,39 +1362,51 @@ quayApp.directive('logsView', function () {
} else if (metadata.delegate_team) {
return 'Delete default permission: {role} for {delegate_team}' + defaultPermSuffix(metadata);
}
+ },
+ 'setup_repo_trigger': function(metadata) {
+ var triggerDescription = TriggerDescriptionBuilder.getDescription(
+ metadata['service'], metadata['config']);
+ return 'Setup build trigger - ' + triggerDescription;
+ },
+ 'delete_repo_trigger': function(metadata) {
+ var triggerDescription = TriggerDescriptionBuilder.getDescription(
+ metadata['service'], metadata['config']);
+ return 'Delete build trigger - ' + triggerDescription;
}
};
var logKinds = {
- 'account_change_plan': 'Change plan',
- 'account_change_cc': 'Update credit card',
- 'account_change_password': 'Change password',
- 'account_convert': 'Convert account to organization',
- 'create_robot': 'Create Robot Account',
- 'delete_robot': 'Delete Robot Account',
- 'create_repo': 'Create Repository',
- 'push_repo': 'Push to repository',
- 'pull_repo': 'Pull repository',
- 'delete_repo': 'Delete repository',
- 'change_repo_permission': 'Change repository permission',
- 'delete_repo_permission': 'Remove user permission from repository',
- 'change_repo_visibility': 'Change repository visibility',
- 'add_repo_accesstoken': 'Create access token',
- 'delete_repo_accesstoken': 'Delete access token',
- 'add_repo_webhook': 'Add webhook',
- 'delete_repo_webhook': 'Delete webhook',
- 'set_repo_description': 'Change repository description',
- 'build_dockerfile': 'Build image from Dockerfile',
- 'delete_tag': 'Delete Tag',
- 'org_create_team': 'Create team',
- 'org_delete_team': 'Delete team',
- 'org_add_team_member': 'Add team member',
- 'org_remove_team_member': 'Remove team member',
- 'org_set_team_description': 'Change team description',
- 'org_set_team_role': 'Change team permission',
- 'create_prototype_permission': 'Create default permission',
- 'modify_prototype_permission': 'Modify default permission',
- 'delete_prototype_permission': 'Delete default permission'
+ 'account_change_plan': 'Change plan',
+ 'account_change_cc': 'Update credit card',
+ 'account_change_password': 'Change password',
+ 'account_convert': 'Convert account to organization',
+ 'create_robot': 'Create Robot Account',
+ 'delete_robot': 'Delete Robot Account',
+ 'create_repo': 'Create Repository',
+ 'push_repo': 'Push to repository',
+ 'pull_repo': 'Pull repository',
+ 'delete_repo': 'Delete repository',
+ 'change_repo_permission': 'Change repository permission',
+ 'delete_repo_permission': 'Remove user permission from repository',
+ 'change_repo_visibility': 'Change repository visibility',
+ 'add_repo_accesstoken': 'Create access token',
+ 'delete_repo_accesstoken': 'Delete access token',
+ 'add_repo_webhook': 'Add webhook',
+ 'delete_repo_webhook': 'Delete webhook',
+ 'set_repo_description': 'Change repository description',
+ 'build_dockerfile': 'Build image from Dockerfile',
+ 'delete_tag': 'Delete Tag',
+ 'org_create_team': 'Create team',
+ 'org_delete_team': 'Delete team',
+ 'org_add_team_member': 'Add team member',
+ 'org_remove_team_member': 'Remove team member',
+ 'org_set_team_description': 'Change team description',
+ 'org_set_team_role': 'Change team permission',
+ 'create_prototype_permission': 'Create default permission',
+ 'modify_prototype_permission': 'Modify default permission',
+ 'delete_prototype_permission': 'Delete default permission',
+ 'setup_repo_trigger': 'Setup build trigger',
+ 'delete_repo_trigger': 'Delete build trigger'
};
var getDateString = function(date) {