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/static/js/directives/ui/logs-view.js

337 lines
15 KiB
JavaScript
Raw Normal View History

/**
* Element which displays usage logs for the given entity.
*/
angular.module('quay').directive('logsView', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/logs-view.html',
replace: false,
transclude: false,
restrict: 'C',
scope: {
'organization': '=organization',
'user': '=user',
'makevisible': '=makevisible',
'repository': '=repository',
'performer': '=performer',
'allLogs': '@allLogs'
},
controller: function($scope, $element, $sce, Restangular, ApiService, TriggerService,
StringBuilderService, ExternalNotificationData, UtilService) {
$scope.loading = true;
$scope.logs = null;
$scope.kindsAllowed = null;
$scope.chartVisible = true;
$scope.logsPath = '';
var datetime = new Date();
$scope.logStartDate = new Date(datetime.getUTCFullYear(), datetime.getUTCMonth(), datetime.getUTCDate() - 7);
$scope.logEndDate = new Date(datetime.getUTCFullYear(), datetime.getUTCMonth(), datetime.getUTCDate());
var defaultPermSuffix = function(metadata) {
if (metadata.activating_username) {
return ', when creating user is {activating_username}';
}
return '';
};
var logDescriptions = {
'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: {robot}',
'delete_robot': 'Delete Robot Account: {robot}',
'create_repo': 'Create Repository: {repo}',
'push_repo': 'Push to repository: {repo}',
'repo_verb': function(metadata) {
var prefix = '';
if (metadata.verb == 'squash') {
prefix = 'Pull of squashed tag {tag}'
}
if (metadata.token) {
if (metadata.token_type == 'build-worker') {
prefix += ' by <b>build worker</b>';
} else {
prefix += ' via token';
}
} else if (metadata.username) {
prefix += ' by {username}';
} else {
prefix += ' by {_ip}';
}
return prefix;
},
'pull_repo': function(metadata) {
if (metadata.token) {
var prefix = 'Pull of repository'
if (metadata.token_type == 'build-worker') {
prefix += ' by <b>build worker</b>';
} else {
prefix += ' via token';
}
return prefix;
} else if (metadata.username) {
return 'Pull repository {repo} by {username}';
} else {
return 'Public pull of repository {repo} by {_ip}';
}
},
'delete_repo': 'Delete repository: {repo}',
'change_repo_permission': function(metadata) {
if (metadata.username) {
return 'Change permission for user {username} in repository {repo} to {role}';
} else if (metadata.team) {
return 'Change permission for team {team} in repository {repo} to {role}';
} else if (metadata.token) {
return 'Change permission for token {token} in repository {repo} to {role}';
}
},
'delete_repo_permission': function(metadata) {
if (metadata.username) {
return 'Remove permission for user {username} from repository {repo}';
} else if (metadata.team) {
return 'Remove permission for team {team} from repository {repo}';
} else if (metadata.token) {
return 'Remove permission for token {token} from repository {repo}';
}
},
'delete_tag': 'Tag {tag} deleted in repository {repo} by user {username}',
'create_tag': 'Tag {tag} created in repository {repo} on image {image} by user {username}',
'move_tag': 'Tag {tag} moved from image {original_image} to image {image} in repository {repo} by user {username}',
'change_repo_visibility': 'Change visibility for repository {repo} to {visibility}',
'add_repo_accesstoken': 'Create access token {token} in repository {repo}',
'delete_repo_accesstoken': 'Delete access token {token} in repository {repo}',
'set_repo_description': 'Change description for repository {repo}: {description}',
'build_dockerfile': function(metadata) {
if (metadata.trigger_id) {
var triggerDescription = TriggerService.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}',
'org_remove_team_member': 'Remove member {member} from team {team}',
'org_invite_team_member': function(metadata) {
if (metadata.user) {
return 'Invite {user} to team {team}';
} else {
return 'Invite {email} to team {team}';
}
},
'org_delete_team_member_invite': function(metadata) {
if (metadata.user) {
return 'Rescind invite of {user} to team {team}';
} else {
return 'Rescind invite of {email} to team {team}';
}
},
'org_team_member_invite_accepted': 'User {member}, invited by {inviter}, joined team {team}',
'org_team_member_invite_declined': 'User {member}, invited by {inviter}, declined to join team {team}',
'org_set_team_description': 'Change description of team {team}: {description}',
'org_set_team_role': 'Change permission of team {team} to {role}',
'create_prototype_permission': function(metadata) {
if (metadata.delegate_user) {
return 'Create default permission: {role} for {delegate_user}' + defaultPermSuffix(metadata);
} else if (metadata.delegate_team) {
return 'Create default permission: {role} for {delegate_team}' + defaultPermSuffix(metadata);
}
},
'modify_prototype_permission': function(metadata) {
if (metadata.delegate_user) {
return 'Modify default permission: {role} (from {original_role}) for {delegate_user}' + defaultPermSuffix(metadata);
} else if (metadata.delegate_team) {
return 'Modify default permission: {role} (from {original_role}) for {delegate_team}' + defaultPermSuffix(metadata);
}
},
'delete_prototype_permission': function(metadata) {
if (metadata.delegate_user) {
return 'Delete default permission: {role} for {delegate_user}' + defaultPermSuffix(metadata);
} else if (metadata.delegate_team) {
return 'Delete default permission: {role} for {delegate_team}' + defaultPermSuffix(metadata);
}
},
'setup_repo_trigger': function(metadata) {
var triggerDescription = TriggerService.getDescription(
metadata['service'], metadata['config']);
return 'Setup build trigger - ' + triggerDescription;
},
'delete_repo_trigger': function(metadata) {
var triggerDescription = TriggerService.getDescription(
metadata['service'], metadata['config']);
return 'Delete build trigger - ' + triggerDescription;
},
'create_application': 'Create application {application_name} with client ID {client_id}',
'update_application': 'Update application to {application_name} for client ID {client_id}',
'delete_application': 'Delete application {application_name} with client ID {client_id}',
'reset_application_client_secret': 'Reset the Client Secret of application {application_name} ' +
'with client ID {client_id}',
'add_repo_notification': function(metadata) {
var eventData = ExternalNotificationData.getEventInfo(metadata.event);
return 'Add notification of event "' + eventData['title'] + '" for repository {repo}';
},
'delete_repo_notification': function(metadata) {
var eventData = ExternalNotificationData.getEventInfo(metadata.event);
return 'Delete notification of event "' + eventData['title'] + '" for repository {repo}';
},
'regenerate_robot_token': 'Regenerated token for robot {robot}',
// Note: These are deprecated.
'add_repo_webhook': 'Add webhook in repository {repo}',
'delete_repo_webhook': 'Delete webhook in repository {repo}'
};
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',
'repo_verb': 'Pull Repo Verb',
'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',
'set_repo_description': 'Change repository description',
'build_dockerfile': 'Build image from Dockerfile',
'delete_tag': 'Delete Tag',
'create_tag': 'Create Tag',
'move_tag': 'Move Tag',
'org_create_team': 'Create team',
'org_delete_team': 'Delete team',
'org_add_team_member': 'Add team member',
'org_invite_team_member': 'Invite team member',
'org_delete_team_member_invite': 'Rescind team member invitation',
'org_remove_team_member': 'Remove team member',
'org_team_member_invite_accepted': 'Team invite accepted',
'org_team_member_invite_declined': 'Team invite declined',
'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',
'create_application': 'Create Application',
'update_application': 'Update Application',
'delete_application': 'Delete Application',
'reset_application_client_secret': 'Reset Client Secret',
'add_repo_notification': 'Add repository notification',
'delete_repo_notification': 'Delete repository notification',
'regenerate_robot_token': 'Regenerate Robot Token',
// Note: these are deprecated.
'add_repo_webhook': 'Add webhook',
'delete_repo_webhook': 'Delete webhook'
};
var getDateString = function(date) {
return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
};
var getOffsetDate = function(date, days) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
};
var update = function() {
var hasValidUser = !!$scope.user;
var hasValidOrg = !!$scope.organization;
var hasValidRepo = $scope.repository && $scope.repository.namespace;
var isValid = hasValidUser || hasValidOrg || hasValidRepo || $scope.allLogs;
if (!$scope.makevisible || !isValid) {
return;
}
var twoWeeksAgo = getOffsetDate($scope.logEndDate, -14);
if ($scope.logStartDate > $scope.logEndDate || $scope.logStartDate < twoWeeksAgo) {
$scope.logStartDate = twoWeeksAgo;
}
$scope.loading = true;
// Note: We construct the URLs here manually because we also use it for the download
// path.
var url = UtilService.getRestUrl('user/logs');
if ($scope.organization) {
url = UtilService.getRestUrl('organization', $scope.organization.name, 'logs');
}
if ($scope.repository) {
url = UtilService.getRestUrl('repository', $scope.repository.namespace, $scope.repository.name, 'logs');
}
if ($scope.allLogs) {
url = UtilService.getRestUrl('superuser', 'logs')
}
url += '?starttime=' + encodeURIComponent(getDateString($scope.logStartDate));
url += '&endtime=' + encodeURIComponent(getDateString($scope.logEndDate));
if ($scope.performer) {
url += '&performer=' + encodeURIComponent($scope.performer.name);
}
var loadLogs = Restangular.one(url);
loadLogs.customGET().then(function(resp) {
$scope.logsPath = '/api/v1/' + url;
if (!$scope.chart) {
$scope.chart = new LogUsageChart(logKinds);
$($scope.chart).bind('filteringChanged', function(e) {
$scope.$apply(function() { $scope.kindsAllowed = e.allowed; });
});
}
$scope.chart.draw('bar-chart', resp.logs, $scope.logStartDate, $scope.logEndDate);
$scope.kindsAllowed = null;
$scope.logs = resp.logs;
$scope.loading = false;
});
};
$scope.toggleChart = function() {
$scope.chartVisible = !$scope.chartVisible;
};
$scope.isVisible = function(allowed, kind) {
return allowed == null || allowed.hasOwnProperty(kind);
};
$scope.getColor = function(kind) {
return $scope.chart.getColor(kind);
};
$scope.getDescription = function(log) {
log.metadata['_ip'] = log.ip ? log.ip : null;
return StringBuilderService.buildString(logDescriptions[log.kind] || log.kind, log.metadata);
};
$scope.$watch('organization', update);
$scope.$watch('user', update);
$scope.$watch('repository', update);
$scope.$watch('makevisible', update);
$scope.$watch('performer', update);
$scope.$watch('logStartDate', update);
$scope.$watch('logEndDate', update);
}
};
return directiveDefinitionObject;
});