From: Tomas Sedovic <[email protected]>

Adding a new cloud account imports all the backend realms from the given
provider. Additionaly, we add frontend realms that map to the backend.

Only one frontend realm is created for every actual realm that the cloud
provider serves, but each cloud account imports its own set of backend realms.
---
 src/app/models/cloud_account.rb                |   20 ++++++++--
 src/app/models/instance.rb                     |   19 ---------
 src/app/models/pool.rb                         |   13 +------
 src/app/models/realm.rb                        |   42 +++++++++++++++++++-
 src/app/views/instance/new.haml                |    2 +-
 src/db/migrate/20090804141600_create_realms.rb |    8 +++-
 src/spec/factories/realm.rb                    |    8 ++++
 src/spec/models/instance_spec.rb               |   25 ------------
 src/spec/models/realm_spec.rb                  |   50 ++++++++++++++++++++++++
 9 files changed, 124 insertions(+), 63 deletions(-)
 create mode 100644 src/spec/models/realm_spec.rb

diff --git a/src/app/models/cloud_account.rb b/src/app/models/cloud_account.rb
index 7cc056f..1a9e7dc 100644
--- a/src/app/models/cloud_account.rb
+++ b/src/app/models/cloud_account.rb
@@ -62,10 +62,6 @@ class CloudAccount < ActiveRecord::Base
     return a.nil? ? CloudAccount.new(account) : a
   end
 
-  def account_prefix_for_realm
-    provider.name + Realm::AGGREGATOR_REALM_PROVIDER_DELIMITER + username
-  end
-
   def pools
     pools = []
     instances.each do |instance|
@@ -99,6 +95,22 @@ class CloudAccount < ActiveRecord::Base
                                :name => realm.name ? realm.name : realm.id,
                                :provider_id => provider.id)
           ar_realm.save!
+
+          frontend_realm = Realm.new(:external_key => ar_realm.external_key,
+                                     :name => ar_realm.name,
+                                     :provider_id => nil)
+
+          available_realms = Realm.frontend.find(:all, :conditions => {
+            :external_key => frontend_realm.external_key })
+
+          if available_realms.empty?
+            frontend_realm.backend_realms << ar_realm
+            frontend_realm.save!
+          else
+            available_realms.each do |r|
+              r.backend_realms << ar_realm
+            end
+          end
         end
       end
     end
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index b6dd78e..5f0c5f2 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -90,25 +90,6 @@ class Instance < ActiveRecord::Base
     return task
   end
 
-  def front_end_realm
-    unless cloud_account.nil?
-      cloud_account.provider.name + Realm::AGGREGATOR_REALM_PROVIDER_DELIMITER 
+
-        cloud_account.username + (realm.nil? ? "" :
-                                  (Realm::AGGREGATOR_REALM_ACCOUNT_DELIMITER +
-                                   realm.name))
-    end
-  end
-
-  def front_end_realm=(realm_name)
-    unless realm_name.nil? or realm_name.empty?
-      provider_name, tmpstr = 
realm_name.split(Realm::AGGREGATOR_REALM_PROVIDER_DELIMITER,2)
-      account_name, realm_name = 
tmpstr.split(Realm::AGGREGATOR_REALM_ACCOUNT_DELIMITER,2)
-      provider = Provider.find_by_name(provider_name)
-      self.cloud_account = 
provider.cloud_accounts.find_by_username(account_name)
-      self.realm = provider.realms.find_by_name(realm_name) unless 
realm_name.nil?
-    end
-  end
-
   # Returns the total time that this instance has been in the state
   def total_state_time(state)
 
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index d186b20..6ffd6cf 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -58,19 +58,8 @@ class Pool < ActiveRecord::Base
     HardwareProfile.find(:all, :conditions => {:provider_id => nil})
   end
 
-  #FIXME: do we still allow explicit cloud/account choice via realm selection?
-  #FIXME: How is account list for realm defined without explicit pool-account 
relationship?
   def realms
-    realm_list = []
-    CloudAccount.all.each do |cloud_account|
-      prefix = cloud_account.account_prefix_for_realm
-      realm_list << prefix
-      cloud_account.provider.realms.each do |realm|
-        realm_list << prefix + Realm::AGGREGATOR_REALM_ACCOUNT_DELIMITER +
-                      realm.name
-      end
-    end
-    realm_list
+    Realm.find(:all, :conditions => { :provider_id => nil })
   end
 
 end
diff --git a/src/app/models/realm.rb b/src/app/models/realm.rb
index 07bb306..5c92297 100644
--- a/src/app/models/realm.rb
+++ b/src/app/models/realm.rb
@@ -22,14 +22,54 @@
 class Realm < ActiveRecord::Base
   has_many :instances
   belongs_to :provider
+  named_scope :frontend, :conditions => { :provider_id => nil }
 
-  validates_presence_of :provider_id
+  has_and_belongs_to_many :frontend_realms,
+                          :class_name => "Realm",
+                          :join_table => "realm_map",
+                          :foreign_key => "backend_realm_id",
+                          :association_foreign_key => "frontend_realm_id"
+
+  has_and_belongs_to_many :backend_realms,
+                          :class_name => "Realm",
+                          :join_table => "realm_map",
+                          :foreign_key => "frontend_realm_id",
+                          :association_foreign_key => "backend_realm_id"
 
   validates_presence_of :external_key
   validates_uniqueness_of :external_key, :scope => :provider_id
 
   validates_presence_of :name
 
+
+  protected
+  def validate
+    if provider.nil? and !frontend_realms.empty?
+      errors.add(:frontend_realms, "Frontend realms are allowed for backend 
realms only.")
+    end
+
+    if !provider.nil? and !backend_realms.empty?
+      errors.add(:backend_realms, "Backend realms are allowed for frontend 
realms only.")
+    end
+
+    frontend_realms.each do |frealm|
+      if name != frealm.name
+        errors.add(:realms, "Frontend realm must have the same name as the 
appropriate backend realm.")
+      end
+      if external_key != frealm.external_key
+        errors.add(:realms, "Frontend realm must have the same external key as 
the appropriate backend realm.")
+      end
+    end
+    backend_realms.each do |brealm|
+      if name != brealm.name
+        errors.add(:realms, "Frontend realm must have the same name as the 
appropriate backend realm.")
+      end
+      if external_key != brealm.external_key
+        errors.add(:realms, "Frontend realm must have the same external key as 
the appropriate backend realm.")
+      end
+    end
+  end
+
   AGGREGATOR_REALM_PROVIDER_DELIMITER = ":"
   AGGREGATOR_REALM_ACCOUNT_DELIMITER = "/"
 end
diff --git a/src/app/views/instance/new.haml b/src/app/views/instance/new.haml
index 7942036..74eeaa1 100644
--- a/src/app/views/instance/new.haml
+++ b/src/app/views/instance/new.haml
@@ -74,5 +74,5 @@
         %label
           Realm
           %span Choose a realm
-        = select("instance", "front_end_realm", @instance.pool.realms, { 
:include_blank => true })
+        = select("instance", "realm_id", @instance.pool.realms.map {|r| 
[r.name, r.id ]}, { :include_blank => true })
     = submit_tag "Save", :class => "submit"
diff --git a/src/db/migrate/20090804141600_create_realms.rb 
b/src/db/migrate/20090804141600_create_realms.rb
index 3d557d8..054721f 100644
--- a/src/db/migrate/20090804141600_create_realms.rb
+++ b/src/db/migrate/20090804141600_create_realms.rb
@@ -24,13 +24,19 @@ class CreateRealms < ActiveRecord::Migration
     create_table :realms do |t|
       t.string  :external_key, :null => false
       t.string  :name, :null => false, :limit => 1024
-      t.integer :provider_id, :null => false
+      t.integer :provider_id
       t.integer :lock_version, :default => 0
       t.timestamps
     end
+
+    create_table "realm_map", :force => true, :id => false do |t|
+      t.column "frontend_realm_id", :integer
+      t.column "backend_realm_id", :integer
+    end
   end
 
   def self.down
+    drop_table :realm_map
     drop_table :realms
   end
 end
diff --git a/src/spec/factories/realm.rb b/src/spec/factories/realm.rb
index 5da284f..a13f09d 100644
--- a/src/spec/factories/realm.rb
+++ b/src/spec/factories/realm.rb
@@ -15,3 +15,11 @@ end
 
 Factory.define :realm4, :parent => :realm do |r|
 end
+
+Factory.define :backend_realm, :parent => :realm do |r|
+  r.name 'backend_name'
+  r.external_key 'backend_key'
+end
+
+Factory.define :frontend_realm, :parent => :backend_realm do |r|
+end
diff --git a/src/spec/models/instance_spec.rb b/src/spec/models/instance_spec.rb
index 49bf625..21c2fd8 100644
--- a/src/spec/models/instance_spec.rb
+++ b/src/spec/models/instance_spec.rb
@@ -84,31 +84,6 @@ describe Instance do
     valid_task.should_not == false
   end
 
-  it "should be able to query and set up frontend realm" do
-    provider = Factory.build(:mock_provider2)
-    provider.stub!(:connect).and_return(mock('DeltaCloud'))
-    provider.save!
-
-    cloud_account = Factory.build(:cloud_account, :provider => provider,
-                                                  :username => 'john doe',
-                                                  :password => 'asdf')
-    cloud_account.stub!(:valid_credentials?).and_return(true)
-    cloud_account.save!
-
-    @instance = Factory.create(:instance, :cloud_account => cloud_account)
-    @instance.front_end_realm.should eql('mock2:john doe')
-
-    realm = Factory.create(:realm, :name => 'a realm',
-                           :provider_id => provider.id)
-    @instance.realm = realm
-    @instance.front_end_realm.should eql('mock2:john doe/a realm')
-
-    Factory.create(:realm, :name => 'different realm',
-                   :provider_id => provider.id)
-    @instance.front_end_realm = 'mock2:john doe/different realm'
-    @instance.front_end_realm.should eql('mock2:john doe/different realm')
-  end
-
   it "should properly calculate the total time that the instance has been in a 
monitored state" do
     instance = Factory :new_instance
 
diff --git a/src/spec/models/realm_spec.rb b/src/spec/models/realm_spec.rb
new file mode 100644
index 0000000..6f8ce19
--- /dev/null
+++ b/src/spec/models/realm_spec.rb
@@ -0,0 +1,50 @@
+require 'spec_helper'
+
+describe Realm do
+
+  before(:each) do
+    @provider = Factory :mock_provider
+    @backend_realm = Factory :backend_realm, :provider => @provider
+
+    @frontend_realm = Factory :frontend_realm, :provider => nil
+    @backend_realm.frontend_realms << @frontend_realm
+    @frontend_realm.backend_realms << @backend_realm
+  end
+
+  it "should validate backend" do
+    @backend_realm.provider_id.should_not be_nil
+    @backend_realm.backend_realms.should be_empty
+
+    @backend_realm.frontend_realms.should_not be_empty
+    @backend_realm.frontend_realms.first.id.should == @frontend_realm.id
+  end
+
+  it "should validate frontend" do
+    @frontend_realm.provider_id.should be_nil
+    @frontend_realm.frontend_realms.should be_empty
+
+    @frontend_realm.backend_realms.should_not be_empty
+    @frontend_realm.backend_realms.first.id.should == @backend_realm.id
+  end
+
+  it "should map the frontend and backend names" do
+    @frontend_realm.name = 'different_from' + @backend_realm.name
+    @frontend_realm.should_not be_valid
+    @backend_realm.should_not be_valid
+
+    @frontend_realm.name = @backend_realm.name
+    @frontend_realm.should be_valid
+    @backend_realm.should be_valid
+  end
+
+  it "should map the frontend and backend keys" do
+    @frontend_realm.external_key = 'different_from' + 
@backend_realm.external_key
+    @frontend_realm.should_not be_valid
+    @backend_realm.should_not be_valid
+
+    @frontend_realm.external_key = @backend_realm.external_key
+    @frontend_realm.should be_valid
+    @backend_realm.should be_valid
+  end
+
+end
-- 
1.7.2.3

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to