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()
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():
presumed_dead_date = datetime.utcnow() - PRESUMED_DEAD_BUILD_AGE
return (RepositoryBuild.select()

View file

@ -52,6 +52,25 @@ def user_view(user):
'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/')
@internal_only
@show_if(features.SUPER_USERS)

View file

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

View file

@ -24,10 +24,11 @@
</div>
<!-- Chart -->
<div>
<div id="repository-usage-chart" class="usage-chart limit-{{limit}}"></div>
<span class="usage-caption" ng-show="chart">Repository Usage</span>
</div>
<div class="usage-chart" total="subscribedPlan.privateRepos || 0"
current="subscription.usedPrivateRepos || 0"
limit="limit"
usage-title="Repository Usage"
ng-show="!planLoading"></div>
<!-- Plans Table -->
<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 });
}
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.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 () {
var directiveDefinitionObject = {
priority: 0,

View file

@ -2788,6 +2788,15 @@ function SuperUserAdminCtrl($scope, ApiService, Features, UserService) {
$scope.logsCounter = 0;
$scope.newUser = {};
$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.logsCounter++;

View file

@ -13,6 +13,9 @@
<li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#create-user">Create User</a>
</li>
<li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#usage-counter" ng-click="getUsage()">System Usage</a>
</li>
<li>
<a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">System Logs</a>
</li>
@ -27,6 +30,13 @@
<div class="logsView" makevisible="logsCounter" all-logs="true"></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 -->
<div id="create-user" class="tab-pane">
<span class="quay-spinner" ng-show="creatingUser"></span>