[PATCH conductor 1/3] BZ 717987 (1) - Added realms available flag

jprovazn at redhat.com jprovazn at redhat.com
Fri Feb 3 15:10:02 UTC 2012


From: Jan Provaznik <jprovazn at redhat.com>

TODO: status of current availability is not displayed anywhere in UI yet
---
 src/app/models/provider.rb                         |   23 +++++++++++++++++--
 src/app/models/provider_account.rb                 |    7 ++++-
 .../20120202121555_add_realm_available_column.rb   |   11 +++++++++
 src/spec/factories/provider.rb                     |    7 ++++++
 src/spec/factories/realm.rb                        |    1 -
 src/spec/models/instance_spec.rb                   |   19 ++++++++++++++++
 6 files changed, 62 insertions(+), 6 deletions(-)
 create mode 100644 src/db/migrate/20120202121555_add_realm_available_column.rb

diff --git a/src/app/models/provider.rb b/src/app/models/provider.rb
index 01c0d3e..498304d 100644
--- a/src/app/models/provider.rb
+++ b/src/app/models/provider.rb
@@ -134,6 +134,15 @@ class Provider < ActiveRecord::Base
 
   def populate_realms
     reload
+
+    # if the provider is not running, mark as unavailable and don't refresh its
+    # realms
+    unless valid_framework?
+      update_attribute(:available, false)
+      logger.warn "provider #{name} is not available"
+      return
+    end
+
     conductor_acct_realms = {}
     conductor_acct_realm_ids = {}
     deltacloud_realms = []
@@ -141,7 +150,12 @@ class Provider < ActiveRecord::Base
     dc_acct_realm_ids = {}
     self.transaction do
       provider_accounts.each do |acct|
-        client = acct.connect
+        # if account is not accessible (but provider is running)
+        # account's realms will be removed
+        unless client = acct.connect
+          logger.warn "provider account #{acct.name} is not available"
+          next
+        end
         dc_acct_realms[acct.label] = client.realms
         dc_acct_realm_ids[acct.label] = dc_acct_realms[acct.label].collect{|r| r.id}
         dc_acct_realms[acct.label].each do |dc_realm|
@@ -172,16 +186,19 @@ class Provider < ActiveRecord::Base
 
       # Add anything in Deltacloud to Conductor if it's not already there
       deltacloud_realms.each do |d_realm|
-        unless conductor_realm_ids.include?(d_realm.id)
+        if ar_realm = conductor_realms.detect {|r| r.external_key == d_realm.id}
+          ar_realm.available = d_realm.state == 'AVAILABLE'
+        else
           ar_realm = Realm.new(:external_key => d_realm.id,
                                  :name => d_realm.name ? d_realm.name : d_realm.id,
                                  :provider_id => id)
-          ar_realm.save!
         end
+        ar_realm.save!
       end
 
       # add any new provider account realm mappings
       provider_accounts.each do |acct|
+        next unless dc_acct_realms[acct.label]
         dc_acct_realms[acct.label].each do |d_realm|
           unless conductor_acct_realm_ids[acct.label].include?(d_realm.id)
             acct.realms << realms.where("external_key" => d_realm.id)
diff --git a/src/app/models/provider_account.rb b/src/app/models/provider_account.rb
index 89009aa..82b44c4 100644
--- a/src/app/models/provider_account.rb
+++ b/src/app/models/provider_account.rb
@@ -352,13 +352,16 @@ class ProviderAccount < ActiveRecord::Base
     else
       account_images.each do |pi|
         if not instance.frontend_realm.nil?
-          brealms = instance.frontend_realm.realm_backend_targets.select {|brealm_target| brealm_target.target_provider == provider}
+          brealms = instance.frontend_realm.realm_backend_targets.select {|brealm_target| brealm_target.target_provider == provider and brealm_target.target_provider.available}
           if brealms.empty?
             errors << I18n.t('instances.errors.realm_not_mapped', :frontend_realm_name => instance.frontend_realm.name)
             next
           end
           brealms.each do |brealm_target|
-            if (brealm_target.target_realm.nil? || realms.include?(brealm_target.target_realm))
+            # add match if realm is mapped to provider or if it's mapped to
+            # backend realm which is available and is accessible for this
+            # provider account
+            if (brealm_target.target_realm.nil? || (brealm_target.target_realm.available && realms.include?(brealm_target.target_realm)))
               matched << Instance::Match.new(instance.pool.pool_family, self, hwp, pi, brealm_target.target_realm)
             end
           end
diff --git a/src/db/migrate/20120202121555_add_realm_available_column.rb b/src/db/migrate/20120202121555_add_realm_available_column.rb
new file mode 100644
index 0000000..5f38c55
--- /dev/null
+++ b/src/db/migrate/20120202121555_add_realm_available_column.rb
@@ -0,0 +1,11 @@
+class AddRealmAvailableColumn < ActiveRecord::Migration
+  def self.up
+    add_column :realms, :available, :boolean, :null => false, :default => true
+    add_column :providers, :available, :boolean, :null => false, :default => true
+  end
+
+  def self.down
+    remove_column :realms, :available
+    remove_column :providers, :available
+  end
+end
diff --git a/src/spec/factories/provider.rb b/src/spec/factories/provider.rb
index af58065..e8a8889 100644
--- a/src/spec/factories/provider.rb
+++ b/src/spec/factories/provider.rb
@@ -37,6 +37,13 @@ FactoryGirl.define do
     after_create { |p| p.realms << FactoryGirl.create(:realm3, :provider => p) }
   end
 
+  factory :mock_provider_with_unavailable_realm, :parent => :provider do
+    provider_type {ProviderType.find_by_deltacloud_driver("mock")}
+    url 'http://localhost:3002/api'
+    hardware_profiles { |hp| [hp.association(:mock_hwp1), hp.association(:mock_hwp2)] }
+    after_create { |p| p.realms << FactoryGirl.create(:realm1, :provider => p, :available => false) }
+  end
+
   factory :ec2_provider, :parent => :provider do
     name 'amazon-ec2'
     provider_type { ProviderType.find_by_deltacloud_driver("ec2") }
diff --git a/src/spec/factories/realm.rb b/src/spec/factories/realm.rb
index 3ca53fb..4816235 100644
--- a/src/spec/factories/realm.rb
+++ b/src/spec/factories/realm.rb
@@ -38,5 +38,4 @@ FactoryGirl.define do
     name 'backend_name'
     external_key 'backend_key'
   end
-
 end
diff --git a/src/spec/models/instance_spec.rb b/src/spec/models/instance_spec.rb
index 9d3a096..7bcef6f 100644
--- a/src/spec/models/instance_spec.rb
+++ b/src/spec/models/instance_spec.rb
@@ -205,6 +205,25 @@ describe Instance do
     @instance.matches.last.should include(I18n.t('instances.errors.hw_profile_match_not_found', :account_name => 'testaccount'))
   end
 
+  it "shouldn't match frontend realms mapped to unavailable providers" do
+    build = @instance.image_build || @instance.image.latest_pushed_build
+    provider = FactoryGirl.create(:mock_provider, :name => build.provider_images.first.provider_name, :available => false)
+    realm_target = FactoryGirl.create(:realm_backend_target, :realm_or_provider => provider)
+    @instance.frontend_realm = realm_target.frontend_realm
+    @pool.pool_family.provider_accounts = [FactoryGirl.create(:mock_provider_account, :label => 'testaccount', :provider => provider)]
+    @instance.matches.last.should include(I18n.t('instances.errors.realm_not_mapped', :frontend_realm_name => @instance.frontend_realm.name))
+  end
+
+  it "shouldn't match frontend realms mapped to unavailable realms" do
+    build = @instance.image_build || @instance.image.latest_pushed_build
+    provider = FactoryGirl.create(:mock_provider_with_unavailable_realm, :name => build.provider_images.first.provider_name)
+    realm_target = FactoryGirl.create(:realm_backend_target, :realm_or_provider => provider.realms.first)
+    @instance.frontend_realm = realm_target.frontend_realm
+    @pool.pool_family.provider_accounts = [FactoryGirl.create(:mock_provider_account, :label => 'testaccount', :provider => provider)]
+    @instance.matches.last.should include(I18n.t('instances.errors.realm_not_mapped', :frontend_realm_name => @instance.frontend_realm.name))
+  end
+
+
   it "shouldn't return any matches if instance hwp architecture doesn't match image architecture" do
     @pool.pool_family.provider_accounts = [FactoryGirl.create(:mock_provider_account, :label => 'testaccount')]
     @instance.hardware_profile.architecture.value = 'i386'
-- 
1.7.7.5




More information about the aeolus-devel mailing list