From: Jan Provaznik <jprovazn(a)redhat.com>
---
src/app/models/pool.rb | 15 +++++++++++++++
src/app/models/pool_family.rb | 20 ++++++++++++++++++++
src/app/models/quota.rb | 1 +
.../20110417180833_add_pool_family_quota.rb | 9 +++++++++
src/spec/models/pool_family_spec.rb | 6 ++++++
src/spec/models/pool_spec.rb | 8 ++++++++
6 files changed, 59 insertions(+), 0 deletions(-)
create mode 100644 src/db/migrate/20110417180833_add_pool_family_quota.rb
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index c158403..edf13ee 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -55,11 +55,26 @@ class Pool < ActiveRecord::Base
validates_length_of :name, :maximum => 255
validates_format_of :name, :with => /^[\w -]*$/n, :message => "must only
contain: numbers, letters, spaces, '_' and '-'"
+ validate :quota, :validate_pool_family_quota
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+
+ def validate_pool_family_quota
+ if pool_family and pool_family.quota
+ # TODO: what to do if pool doesn't have quota?
+ return unless quota
+ return if Quota.no_limit(pool_family.quota.maximum_running_instances)
+ if Quota.no_limit(quota.maximum_running_instances)
+ errors.add(:quota, "must be set because pool family quota is set to
#{pool_family.quota.maximum_running_instances}")
+ elsif usage = pool_family.quota_usage and usage + quota.maximum_running_instances
> pool_family.quota.maximum_running_instances
+ errors.add(:quota, "exceeds pool family quota")
+ end
+ end
+ end
+
def cloud_accounts
accounts = []
instances.each do |instance|
diff --git a/src/app/models/pool_family.rb b/src/app/models/pool_family.rb
index 2eee939..4671f22 100644
--- a/src/app/models/pool_family.rb
+++ b/src/app/models/pool_family.rb
@@ -42,6 +42,7 @@ class PoolFamily < ActiveRecord::Base
end
has_many :pools, :dependent => :destroy
+ belongs_to :quota, :dependent => :destroy
has_and_belongs_to_many :provider_accounts
validates_length_of :name, :maximum => 255
@@ -49,6 +50,7 @@ class PoolFamily < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
+ validate :quota, :validate_quota
before_destroy :destroyable?
@@ -64,4 +66,22 @@ class PoolFamily < ActiveRecord::Base
# A PoolFamily is destroyable unless it is the default PoolFamily
self != PoolFamily.default
end
+
+ def validate_quota
+ usage = quota_usage
+ errors.add(:quota, "exceeded") if quota and quota.maximum_running_instances
and (not usage or quota.maximum_running_instances < usage)
+ end
+
+ def quota_usage
+ sum = 0
+ pools.each do |p|
+ # TODO: what to do if pool doesn't have quota?
+ next unless p.quota
+ # if any of existing pools has unlimited quota (=nil)
+ # we return nil
+ return nil if Quota.no_limit(p.quota.maximum_running_instances)
+ sum += p.quota.maximum_running_instances
+ end
+ sum
+ end
end
diff --git a/src/app/models/quota.rb b/src/app/models/quota.rb
index 7d67088..b33560c 100644
--- a/src/app/models/quota.rb
+++ b/src/app/models/quota.rb
@@ -37,6 +37,7 @@
class Quota < ActiveRecord::Base
has_one :pool
+ has_one :pool_family
has_one :provider_account
has_one :user
diff --git a/src/db/migrate/20110417180833_add_pool_family_quota.rb
b/src/db/migrate/20110417180833_add_pool_family_quota.rb
new file mode 100644
index 0000000..76197da
--- /dev/null
+++ b/src/db/migrate/20110417180833_add_pool_family_quota.rb
@@ -0,0 +1,9 @@
+class AddPoolFamilyQuota < ActiveRecord::Migration
+ def self.up
+ add_column :pool_families, :quota_id, :integer
+ end
+
+ def self.down
+ remove_column :pool_families, :quota_id
+ end
+end
diff --git a/src/spec/models/pool_family_spec.rb b/src/spec/models/pool_family_spec.rb
index ff9a342..509b34d 100644
--- a/src/spec/models/pool_family_spec.rb
+++ b/src/spec/models/pool_family_spec.rb
@@ -45,4 +45,10 @@ describe PoolFamily do
@pool_family.errors[:name].should =~ /^must only contain.*/
end
+ it "should not be valid if pool family quota is lower than sum of pool
quotas" do
+ pool_family = Factory :pool_family
+ pool_family.pools << Factory(:pool, :pool_family => pool_family, :quota
=> Quota.new(:maximum_running_instances => 2))
+ pool_family.quota = Quota.new(:maximum_running_instances => 1)
+ pool_family.should_not be_valid
+ end
end
diff --git a/src/spec/models/pool_spec.rb b/src/spec/models/pool_spec.rb
index ca754fa..5103c6d 100644
--- a/src/spec/models/pool_spec.rb
+++ b/src/spec/models/pool_spec.rb
@@ -22,4 +22,12 @@ describe Pool do
u.errors[:name].should =~ /^is too long.*/
end
+ it "should not be valid if pool quota exceeds pool family quota" do
+ pool_family = Factory(:pool_family, :quota => Quota.new(:maximum_running_instances
=> 1))
+ pool = Factory(:pool, :pool_family => pool_family, :quota =>
Quota.new(:maximum_running_instances => 1))
+ pool.quota = Quota.new(:maximum_running_instances => 2)
+ pool.should_not be_valid
+ pool.quota = Quota.new(:maximum_running_instances => nil)
+ pool.should_not be_valid
+ end
end
--
1.7.4