[email protected] wrote:
> 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
>
>
ACK and pushed.
I made a few changes before pushing to get this all working, as follows:
1) removed extraneous newline from realm.rb section of patch
2) removed new.haml and made the equivalent change to configure.haml, as
that form has been redesigned on next as a two-step form
3) made necessary update to condormatic.rb to include the new realm
mapping in the classads sync
Scott
> 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
>
_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel