Commit e9af4c71 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'historical-data' into 'master'

Validate historical active user count when uploading license.

Addresses #274.

![Screen_Shot_2015-05-12_at_10.21.15](https://dev.gitlab.org/gitlab/gitlab-ee/uploads/3ee062badc186190c2443dc89b2977e1/Screen_Shot_2015-05-12_at_10.21.15.png)

![Screen_Shot_2015-05-12_at_10.21.28](https://dev.gitlab.org/gitlab/gitlab-ee/uploads/80854d83427413fc028c388dfb42ea96/Screen_Shot_2015-05-12_at_10.21.28.png)

![Screen_Shot_2015-05-12_at_10.24.28](https://dev.gitlab.org/gitlab/gitlab-ee/uploads/8c376267c65ffcacceff0587765bde5c/Screen_Shot_2015-05-12_at_10.24.28.png)

See merge request !390
parents bf1b6994 87996ece
class HistoricalData < ActiveRecord::Base
validate :date, presence: true
# HistoricalData.during((Date.today - 1.year)..Date.today).average(:active_user_count)
scope :during, ->(range) { where(date: range) }
class << self
def track!
create!(
date: Date.today,
active_user_count: User.active.count
)
end
# HistoricalData.at(Date.new(2014, 1, 1)).active_user_count
def at(date)
find_by(date: date)
end
end
end
class License < ActiveRecord::Base
include ActionView::Helpers::NumberHelper
validate :valid_license
validate :active_user_count, unless: :persisted?
validate :not_expired, unless: :persisted?
......@@ -87,7 +89,7 @@ class License < ActiveRecord::Base
def valid_license
return if license?
self.errors.add(:base, "The license file is invalid. Make sure it is exactly as you received it from GitLab B.V.")
self.errors.add(:base, "The license file is invalid. Make sure it is exactly as you received it from GitLab B.V..")
end
def active_user_count
......@@ -95,12 +97,27 @@ class License < ActiveRecord::Base
restricted_user_count = self.restrictions[:active_user_count]
active_user_count = User.active.count
historical_active_user_count = HistoricalData.maximum(:active_user_count) || 0
max_active_user_count = [active_user_count, historical_active_user_count].max
return if max_active_user_count < restricted_user_count
return if active_user_count <= restricted_user_count
overage = max_active_user_count - restricted_user_count
message = ""
message <<
if historical_active_user_count > active_user_count
"At one point, this GitLab installation had "
else
"This GitLab installation has "
end
message << "#{number_with_delimiter max_active_user_count} active #{"user".pluralize(max_active_user_count)}, "
message << "exceeding this license's limit of #{number_with_delimiter restricted_user_count} by "
message << "#{number_with_delimiter overage} #{"user".pluralize(overage)}. "
message << "Please upload a license for at least "
message << "#{number_with_delimiter max_active_user_count} #{"user".pluralize(max_active_user_count)}."
message = "This license allows #{restricted_user_count} active users. "
message << "This GitLab installation currently has #{active_user_count}, "
message << "i.e. #{active_user_count - restricted_user_count} too many."
self.errors.add(:base, message)
end
......
......@@ -35,36 +35,47 @@
%strong
- if @license.will_expire?
= time_ago_with_tooltip @license.expires_at
- if @license.expired?
%span.label.label-danger.pull-right
%strong Expired
- else
Never
- if @license.expired?
%span.label.label-danger.pull-right
%strong Expired
.panel.panel-default
.panel-heading
Restrictions
Users
%ul.well-list
%li
%span.light Active users:
%span.light License limit:
%strong
- if @license.restricted?(:active_user_count)
- restricted_user_count = @license.restrictions[:active_user_count]
- active_user_count = User.active.count
#{restricted_user_count} users
- if active_user_count > restricted_user_count
%span.label.label-danger.pull-right
%strong Exceeded by #{active_user_count - restricted_user_count} users
- elsif restricted_user_count > active_user_count
%span.label.label-success.pull-right
%strong #{restricted_user_count - active_user_count} more allowed
- else
%span.label.label-info.pull-right
%strong Right at the limit
- restricted = @license.restrictions[:active_user_count]
#{number_with_delimiter restricted} #{"users".pluralize(restricted)}
- else
Unlimited
%li
%span.light Current active users:
%strong
- current = User.active.count
#{number_with_delimiter current} #{"users".pluralize(current)}
- if restricted && current > restricted
%span.label.label-danger.pull-right
%strong
Exceeds license limit
- historical = HistoricalData.maximum(:active_user_count)
- if historical
%li
%span.light Maximum active users:
%strong
#{number_with_delimiter historical} #{"users".pluralize(historical)}
- if restricted && historical > restricted
%span.label.label-danger.pull-right
%strong
Exceeds license limit
.col-md-6
.panel.panel-info
......
class HistoricalDataWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { daily.hour_of_day(12) }
def perform
HistoricalData.track!
end
end
......@@ -2,9 +2,7 @@ class LdapSyncWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
# We check if we are in a Sidekiq server process because of a bug in Sidetiq
# 0.6.1 which was giving Unicorn trouble (throwing a Redis::InheritedError).
if Gitlab.config.ldap.enabled && Sidekiq.server?
if Gitlab.config.ldap.enabled
HOUR = Gitlab.config.ldap.schedule_sync_hour
MINUTE = Gitlab.config.ldap.schedule_sync_minute
......
class CreateHistoricalData < ActiveRecord::Migration
def change
create_table :historical_data do |t|
t.date :date, null: false
t.integer :active_user_count
t.timestamps
end
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150502064022) do
ActiveRecord::Schema.define(version: 20150507194350) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -132,6 +132,13 @@ ActiveRecord::Schema.define(version: 20150502064022) do
t.boolean "is_sample", default: false
end
create_table "historical_data", force: true do |t|
t.date "date", null: false
t.integer "active_user_count"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "identities", force: true do |t|
t.string "extern_uid"
t.string "provider"
......
......@@ -204,7 +204,7 @@ FactoryGirl.define do
end
factory :gitlab_license, class: "Gitlab::License" do
issued_at { Date.today }
issued_at { Date.today - 1.month }
licensee do
{ "Name" => Faker::Name.name }
end
......
require 'spec_helper'
describe HistoricalData do
before do
(1..12).each do |i|
HistoricalData.create!(date: Date.new(2014, i, 1), active_user_count: i * 100)
end
end
describe ".during" do
it "returns the historical data during the given period" do
expect(HistoricalData.during(Date.new(2014, 1, 1)..Date.new(2014, 12, 31)).average(:active_user_count)).to eq(650)
end
end
describe ".at" do
it "returns the historical data at the given date" do
expect(HistoricalData.at(Date.new(2014, 8, 1)).active_user_count).to eq(800)
end
end
describe ".track!" do
before do
allow(User).to receive(:active).and_return([1,2,3,4,5])
end
it "creates a new historical data record" do
HistoricalData.track!
data = HistoricalData.last
expect(data.date).to eq(Date.today)
expect(data.active_user_count).to eq(5)
end
end
end
......@@ -24,6 +24,39 @@ describe License do
end
describe "Active user count" do
let(:active_user_count) { User.active.count }
context "when there is no active user count restriction" do
it "is valid" do
expect(license).to be_valid
end
end
context "when the active user count restriction is exceeded" do
before do
gl_license.restrictions = { active_user_count: active_user_count - 1 }
end
it "is invalid" do
expect(license).to_not be_valid
end
end
context "when the active user count restriction is not exceeded" do
before do
gl_license.restrictions = { active_user_count: active_user_count + 1 }
end
it "is valid" do
expect(license).to be_valid
end
end
end
describe "Historical active user count" do
let(:active_user_count) { User.active.count + 10 }
let!(:historical_data) { HistoricalData.create!(date: License.current.issued_at, active_user_count: active_user_count) }
context "when there is no active user count restriction" do
it "is valid" do
expect(license).to be_valid
......@@ -32,7 +65,7 @@ describe License do
context "when the active user count restriction is exceeded" do
before do
gl_license.restrictions = { active_user_count: User.active.count - 1 }
gl_license.restrictions = { active_user_count: active_user_count - 1 }
end
it "is invalid" do
......@@ -42,7 +75,7 @@ describe License do
context "when the active user count restriction is not exceeded" do
before do
gl_license.restrictions = { active_user_count: User.active.count + 1 }
gl_license.restrictions = { active_user_count: active_user_count + 1 }
end
it "is valid" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment