From e687b4d2d4653b3ba9d072c8641e458cd2981adf Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Tue, 25 Feb 2014 18:22:55 -0500 Subject: [PATCH] Add logging descriptions for the new trigger logs --- endpoints/api.py | 21 ++++++--- endpoints/webhooks.py | 23 ++++++--- initdb.py | 7 ++- static/js/app.js | 106 ++++++++++++++++++++++++++++++------------ 4 files changed, 113 insertions(+), 44 deletions(-) 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) {