From: Jan Provaznik <[email protected]>
Key per instance setup should work this way:
- create instance key for each provider account
- when creating an instance we use this cloud account key (it's passed to
condor)
- when instance is started, we generate unique instance key and update it in
instance (from instance observer)
---
src/app/models/cloud_account.rb | 13 +++--------
src/app/models/cloud_account_observer.rb | 9 ++++++++
src/app/models/instance.rb | 2 +
src/app/models/instance_key.rb | 3 +-
src/app/models/instance_observer.rb | 9 ++++++++
src/config/environment.rb | 2 +-
.../20090801045212_create_cloud_accounts.rb | 1 +
.../migrate/20100902081651_create_instance_keys.rb | 3 +-
src/spec/models/cloud_account_observer_spec.rb | 22 ++++++++++++++++++++
src/spec/models/instance_observer_spec.rb | 13 +++++++++++
10 files changed, 64 insertions(+), 13 deletions(-)
create mode 100644 src/app/models/cloud_account_observer.rb
create mode 100644 src/spec/models/cloud_account_observer_spec.rb
diff --git a/src/app/models/cloud_account.rb b/src/app/models/cloud_account.rb
index e4fe6c6..4371a1a 100644
--- a/src/app/models/cloud_account.rb
+++ b/src/app/models/cloud_account.rb
@@ -33,7 +33,7 @@ class CloudAccount < ActiveRecord::Base
:include => [:role],
:order => "permissions.id ASC"
- has_one :instance_key, :dependent => :destroy
+ has_one :instance_key, :as => :instance_key_owner, :dependent => :destroy
# Helpers
attr_accessor :x509_cert_priv_file, :x509_cert_pub_file
@@ -62,7 +62,6 @@ class CloudAccount < ActiveRecord::Base
end
# Hooks
- after_create :generate_cloud_account_key
before_destroy :destroyable?
before_validation :read_x509_files
@@ -170,13 +169,9 @@ EOT
return xml.to_s
end
- private
- def generate_cloud_account_key
+ def generate_auth_key
client = connect
- if client && client.feature?(:instances, :authentication_key)
- key = client.create_key(:name => "#{self.name}_#{Time.now.to_i}_key")
- InstanceKey.create(:cloud_account => self, :pem => key.pem, :name =>
key.id) if key
- end
+ return nil unless client && client.feature?(:instances,
:authentication_key)
+ client.create_key(:name =>
"#{self.name}_#{Time.now.to_i}_key_#{self.object_id}")
end
-
end
diff --git a/src/app/models/cloud_account_observer.rb
b/src/app/models/cloud_account_observer.rb
new file mode 100644
index 0000000..a0826ea
--- /dev/null
+++ b/src/app/models/cloud_account_observer.rb
@@ -0,0 +1,9 @@
+class CloudAccountObserver < ActiveRecord::Observer
+ def after_create(account)
+ if key = account.generate_auth_key
+ account.update_attribute(:instance_key, InstanceKey.create!(:pem =>
key.pem, :name => key.id, :instance_key_owner => account))
+ end
+ end
+end
+
+CloudAccountObserver.instance
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index 8573c5a..b22ce63 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -36,6 +36,8 @@ class Instance < ActiveRecord::Base
belongs_to :instance_key
belongs_to :instance_hwp
+ has_one :instance_key, :as => :instance_key_owner, :dependent => :destroy
+
validates_presence_of :pool_id
validates_presence_of :hardware_profile_id
validates_presence_of :template_id
diff --git a/src/app/models/instance_key.rb b/src/app/models/instance_key.rb
index b3b7513..9c941fe 100644
--- a/src/app/models/instance_key.rb
+++ b/src/app/models/instance_key.rb
@@ -21,7 +21,6 @@
#
class InstanceKey < ActiveRecord::Base
- belongs_to :cloud_account
- has_many :instances
+ belongs_to :instance_key_owner, :polymorphic => true
end
diff --git a/src/app/models/instance_observer.rb
b/src/app/models/instance_observer.rb
index 3b9af13..80b39c5 100644
--- a/src/app/models/instance_observer.rb
+++ b/src/app/models/instance_observer.rb
@@ -61,6 +61,15 @@ class InstanceObserver < ActiveRecord::Observer
end
end
+ def before_update(instance)
+ # we try to generate key only when instance is running
+ # and instance_key is not generated yet
+ return if instance.state != Instance::STATE_RUNNING or
instance.instance_key
+ if key = instance.cloud_account.generate_auth_key
+ instance.instance_key = InstanceKey.create!(:pem => key.pem, :name =>
key.id, :instance_key_owner => instance)
+ end
+ end
+
end
InstanceObserver.instance
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 09ec85b..d00ae2f 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -56,7 +56,7 @@ Rails::Initializer.run do |config|
config.middleware.swap Rack::MethodOverride, 'Rack::RestfulSubmit'
- config.active_record.observers = :instance_observer, :task_observer
+ config.active_record.observers = :instance_observer, :task_observer,
:cloud_account_observer
# Only load the plugins named here, in the order given. By default, all
plugins
# in vendor/plugins are loaded in alphabetical order.
# :all can be used as a placeholder for all plugins not explicitly named
diff --git a/src/db/migrate/20090801045212_create_cloud_accounts.rb
b/src/db/migrate/20090801045212_create_cloud_accounts.rb
index 042c406..991734e 100644
--- a/src/db/migrate/20090801045212_create_cloud_accounts.rb
+++ b/src/db/migrate/20090801045212_create_cloud_accounts.rb
@@ -27,6 +27,7 @@ class CreateCloudAccounts < ActiveRecord::Migration
t.string :password, :null => false
t.integer :provider_id, :null => false
t.integer :quota_id
+ t.integer :instance_key_id
t.integer :lock_version, :default => 0
t.string :account_number, :null => false
t.text :x509_cert_priv, :null => false
diff --git a/src/db/migrate/20100902081651_create_instance_keys.rb
b/src/db/migrate/20100902081651_create_instance_keys.rb
index 841d7ff..8ee23fb 100644
--- a/src/db/migrate/20100902081651_create_instance_keys.rb
+++ b/src/db/migrate/20100902081651_create_instance_keys.rb
@@ -1,7 +1,8 @@
class CreateInstanceKeys < ActiveRecord::Migration
def self.up
create_table :instance_keys do |t|
- t.integer :cloud_account_id, :null => false
+ t.integer :instance_key_owner_id, :null => false
+ t.string :instance_key_owner_type, :null => false
t.string :name, :null => false
t.text :pem
t.timestamps
diff --git a/src/spec/models/cloud_account_observer_spec.rb
b/src/spec/models/cloud_account_observer_spec.rb
new file mode 100644
index 0000000..48491c0
--- /dev/null
+++ b/src/spec/models/cloud_account_observer_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe CloudAccountObserver do
+ fixtures :all
+
+ it "should create an instance_key if provider is EC2" do
+ @client = mock('DeltaCloud', :null_object => true)
+ @provider = Factory.build :ec2_provider
+ @key = mock('Key', :null_object => true)
+ @key.stub!(:pem).and_return("PEM")
+ @key.stub!(:id).and_return("1_user")
+ @client.stub!(:"feature?").and_return(true)
+ @client.stub!(:"create_key").and_return(@key)
+
+ cloud_account = Factory.build :ec2_cloud_account
+ cloud_account.stub!(:connect).and_return(@client)
+ cloud_account.save
+ cloud_account.instance_key.should_not == nil
+ cloud_account.instance_key.pem == "PEM"
+ cloud_account.instance_key.id == "1_user"
+ end
+end
diff --git a/src/spec/models/instance_observer_spec.rb
b/src/spec/models/instance_observer_spec.rb
index a696319..96eac6d 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -154,4 +154,17 @@ describe InstanceObserver do
end
end
+ it "should generate instance key when instance is running" do
+ client = mock('DeltaCloud', :null_object => true)
+ key = mock('Key', :null_object => true)
+ key.stub!(:pem).and_return("PEM")
+ key.stub!(:id).and_return("1_user")
+ client.stub!(:"feature?").and_return(true)
+ client.stub!(:"create_key").and_return(key)
+ @cloud_account.stub!(:connect).and_return(client)
+
+ @instance.state = Instance::STATE_RUNNING
+ @instance.save!
+ @instance.instance_key.should_not == nil
+ end
end
--
1.7.3.4
_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel