Add a basic usage counter for enterprise

This commit is contained in:
Joseph Schorr 2014-10-28 16:33:13 -04:00
parent 93cd7de0e0
commit 109850b428
8 changed files with 109 additions and 29 deletions

View file

@ -2210,6 +2210,14 @@ def confirm_team_invite(code, user):
found.delete_instance() found.delete_instance()
return (team, inviter) return (team, inviter)
def get_repository_usage():
repo_pull = LogEntryKind.get(name = 'pull_repo')
return (LogEntry.select().where(LogEntry.kind == repo_pull, ~(LogEntry.repository >> None))
.group_by(LogEntry.ip)
.group_by(LogEntry.repository)
.count())
def archivable_buildlogs_query(): def archivable_buildlogs_query():
presumed_dead_date = datetime.utcnow() - PRESUMED_DEAD_BUILD_AGE presumed_dead_date = datetime.utcnow() - PRESUMED_DEAD_BUILD_AGE
return (RepositoryBuild.select() return (RepositoryBuild.select()

View file

@ -52,6 +52,25 @@ def user_view(user):
'super_user': user.username in app.config['SUPER_USERS'] 'super_user': user.username in app.config['SUPER_USERS']
} }
@resource('/v1/superuser/usage/')
@internal_only
@show_if(features.SUPER_USERS)
class UsageInformation(ApiResource):
""" Resource for returning the usage information for enterprise customers. """
@require_fresh_login
@nickname('getSystemUsage')
def get(self):
""" Returns the number of repository handles currently held. """
if SuperUserPermission().can():
return {
'usage': model.get_repository_usage(),
'allowed': 0
}
abort(403)
@resource('/v1/superuser/users/') @resource('/v1/superuser/users/')
@internal_only @internal_only
@show_if(features.SUPER_USERS) @show_if(features.SUPER_USERS)

View file

@ -3131,38 +3131,38 @@ p.editable:hover i {
stroke-width: 1.5px; stroke-width: 1.5px;
} }
.usage-chart { .usage-chart-element {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
width: 200px; width: 200px;
height: 200px; height: 200px;
} }
.usage-chart .count-text { .usage-chart-element .count-text {
font-size: 22px; font-size: 22px;
} }
.usage-chart.limit-at path.arc-0 { .usage-chart-element.limit-at path.arc-0 {
fill: #c09853; fill: #c09853;
} }
.usage-chart.limit-over path.arc-0 { .usage-chart-element.limit-over path.arc-0 {
fill: #b94a48; fill: #b94a48;
} }
.usage-chart.limit-near path.arc-0 { .usage-chart-element.limit-near path.arc-0 {
fill: #468847; fill: #468847;
} }
.usage-chart.limit-over path.arc-1 { .usage-chart-element.limit-over path.arc-1 {
fill: #fcf8e3; fill: #fcf8e3;
} }
.usage-chart.limit-at path.arc-1 { .usage-chart-element.limit-at path.arc-1 {
fill: #f2dede; fill: #f2dede;
} }
.usage-chart.limit-near path.arc-1 { .usage-chart-element.limit-near path.arc-1 {
fill: #dff0d8; fill: #dff0d8;
} }

View file

@ -24,10 +24,11 @@
</div> </div>
<!-- Chart --> <!-- Chart -->
<div> <div class="usage-chart" total="subscribedPlan.privateRepos || 0"
<div id="repository-usage-chart" class="usage-chart limit-{{limit}}"></div> current="subscription.usedPrivateRepos || 0"
<span class="usage-caption" ng-show="chart">Repository Usage</span> limit="limit"
</div> usage-title="Repository Usage"
ng-show="!planLoading"></div>
<!-- Plans Table --> <!-- Plans Table -->
<table class="table table-hover plans-list-table" ng-show="!planLoading"> <table class="table table-hover plans-list-table" ng-show="!planLoading">

View file

@ -0,0 +1,2 @@
<span id="usage-chart-element" class="usage-chart-element" ng-class="'limit-' + limit" ng-show="total != null"></span>
<span class="usage-caption" ng-show="total != null && usageTitle">{{ usageTitle }}</span>

View file

@ -4540,23 +4540,6 @@ quayApp.directive('planManager', function () {
$scope.planChanged({ 'plan': subscribedPlan }); $scope.planChanged({ 'plan': subscribedPlan });
} }
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
$scope.limit = 'over';
} else if (sub.usedPrivateRepos == $scope.subscribedPlan.privateRepos) {
$scope.limit = 'at';
} else if (sub.usedPrivateRepos >= $scope.subscribedPlan.privateRepos * 0.7) {
$scope.limit = 'near';
} else {
$scope.limit = 'none';
}
if (!$scope.chart) {
$scope.chart = new UsageChart();
$scope.chart.draw('repository-usage-chart');
}
$scope.chart.update(sub.usedPrivateRepos || 0, $scope.subscribedPlan.privateRepos || 0);
$scope.planChanging = false; $scope.planChanging = false;
$scope.planLoading = false; $scope.planLoading = false;
}); });
@ -5929,6 +5912,54 @@ quayApp.directive('notificationsBubble', function () {
}); });
quayApp.directive('usageChart', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/usage-chart.html',
replace: false,
transclude: false,
restrict: 'C',
scope: {
'current': '=current',
'total': '=total',
'limit': '=limit',
'usageTitle': '@usageTitle'
},
controller: function($scope, $element) {
$scope.limit = "";
var chart = null;
var update = function() {
if ($scope.current == null || $scope.total == null) { return; }
if (!chart) {
chart = new UsageChart();
chart.draw('usage-chart-element');
}
var current = $scope.current || 0;
var total = $scope.total || 0;
if (current > total) {
$scope.limit = 'over';
} else if (current == total) {
$scope.limit = 'at';
} else if (current >= total * 0.7) {
$scope.limit = 'near';
} else {
$scope.limit = 'none';
}
chart.update($scope.current, $scope.total);
};
$scope.$watch('current', update);
$scope.$watch('total', update);
}
};
return directiveDefinitionObject;
});
quayApp.directive('notificationView', function () { quayApp.directive('notificationView', function () {
var directiveDefinitionObject = { var directiveDefinitionObject = {
priority: 0, priority: 0,

View file

@ -2788,6 +2788,15 @@ function SuperUserAdminCtrl($scope, ApiService, Features, UserService) {
$scope.logsCounter = 0; $scope.logsCounter = 0;
$scope.newUser = {}; $scope.newUser = {};
$scope.createdUsers = []; $scope.createdUsers = [];
$scope.systemUsage = null;
$scope.getUsage = function() {
if ($scope.systemUsage) { return; }
ApiService.getSystemUsage().then(function(resp) {
$scope.systemUsage = resp;
}, ApiService.errorDisplay('Cannot load system usage. Please contact support.'))
}
$scope.loadLogs = function() { $scope.loadLogs = function() {
$scope.logsCounter++; $scope.logsCounter++;

View file

@ -13,6 +13,9 @@
<li> <li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#create-user">Create User</a> <a href="javascript:void(0)" data-toggle="tab" data-target="#create-user">Create User</a>
</li> </li>
<li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#usage-counter" ng-click="getUsage()">System Usage</a>
</li>
<li> <li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">System Logs</a> <a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">System Logs</a>
</li> </li>
@ -27,6 +30,13 @@
<div class="logsView" makevisible="logsCounter" all-logs="true"></div> <div class="logsView" makevisible="logsCounter" all-logs="true"></div>
</div> </div>
<!-- Usage tab -->
<div id="usage-counter" class="tab-pane">
<div class="quay-spinner" ng-show="systemUsage == null"></div>
<div class="usage-chart" total="systemUsage.allowed" limit="systemUsageLimit"
current="systemUsage.usage" usage-title="Container Usage"></div>
</div>
<!-- Create user tab --> <!-- Create user tab -->
<div id="create-user" class="tab-pane"> <div id="create-user" class="tab-pane">
<span class="quay-spinner" ng-show="creatingUser"></span> <span class="quay-spinner" ng-show="creatingUser"></span>