Instance authentification features
by Michal Fojtik
Hi,
I added two new features for instances. Both features handle authentification.
'authentification_key':
This is used in EC2 driver, where you can now supply a 'keyname' when you are creating a new instance.
Keyname is then reported back in 'show' action. Keyname is associated with generated private key, which you can use to login into instance.
'authentification_password':
This feature wraps authentification for GoGrid driver, where you just get list of your passwords for running servers/instances. So when you apply this patch you will see a 'username' and 'password' XML tags in show action.
Let me know if these patches are working for you.
- Michal
14 years, 1 month
Git config/patch standards for developers
by jason.guiditta
Hello all,
We have had some issues with inconsistency in the setup of people's git
configuration (whitespace sneaking in, for example), so I thought I would
try to put together a page with examples of how things should be set up, as
well as some guidelines for patch submittal. I don't expect I have covered
everything, so feel free to add points that did not cross my mind for this
first pass, or make a correction if you see a mistake. If any new developer
has questions on how to start submitting patches, I would like to be able to
direct them to this as our canonical guideline doc. Patches that apply
cleanly, are clearly for one repo or another, and have useful descriptions
are much more pleasant to review. This also increases the likelihood of
said review happening. Thank you for your time.
</soapbox>
-j
14 years, 1 month
[PATCH] fix populate realms, images, hw prof on pool
by Martyn Taylor
From: martyntaylor <mtaylor(a)redhat.com>
---
src/app/controllers/pool_controller.rb | 2 +-
src/app/models/hardware_profile.rb | 2 +-
src/app/models/pool.rb | 127 ++++++++++++++++++++------------
src/app/views/pool/accounts.html.erb | 2 +-
src/config/routes.rb | 3 +-
5 files changed, 84 insertions(+), 52 deletions(-)
diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb
index cf751e0..17691bb 100644
--- a/src/app/controllers/pool_controller.rb
+++ b/src/app/controllers/pool_controller.rb
@@ -90,7 +90,7 @@ class PoolController < ApplicationController
end
def accounts_for_pool
- @pool = Pool.find(params[:pool_id])
+ @pool = Pool.find(params[:id])
require_privilege(Privilege::ACCOUNT_VIEW,@pool)
@cloud_accounts = []
all_accounts = CloudAccount.list_for_user(@current_user, Privilege::ACCOUNT_ADD)
diff --git a/src/app/models/hardware_profile.rb b/src/app/models/hardware_profile.rb
index 8330388..5125694 100644
--- a/src/app/models/hardware_profile.rb
+++ b/src/app/models/hardware_profile.rb
@@ -42,7 +42,7 @@ class HardwareProfile < ActiveRecord::Base
validates_uniqueness_of :external_key, :scope => [:provider_id, :pool_id]
validates_presence_of :name
- validates_uniqueness_of :name
+ #validates_uniqueness_of :name
validates_presence_of :storage
validates_numericality_of :storage, :greater_than => 0
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index c97e03f..f3cb10c 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -56,65 +56,96 @@ class Pool < ActiveRecord::Base
# FIXME: for already-mapped accounts, update rather than add new
def populate_realms_and_images(accounts=cloud_accounts)
accounts.each do |cloud_account|
+
client = cloud_account.connect
+
realms = client.realms
+ hardware_profiles = client.flavors
+
if client.driver_name == "ec2"
images = client.images(:owner_id=>:self)
else
images = client.images
end
+
+
# FIXME: this should probably be in the same transaction as pool.save
self.transaction do
- realms.each do |realm|
- #ignore if it exists
- #FIXME: we need to handle keeping in sync forupdates as well as
- # account permissions
- unless Realm.find_by_external_key_and_provider_id(realm.id,
- cloud_account.provider.id)
- ar_realm = Realm.new(:external_key => realm.id,
- :name => realm.name ? realm.name : realm.id,
- :provider_id => cloud_account.provider.id)
- ar_realm.save!
- end
- end
- images.each do |image|
- #ignore if it exists
- #FIXME: we need to handle keeping in sync for updates as well as
- # account permissions
- ar_image = Image.find_by_external_key_and_provider_id(image.id,
- cloud_account.provider.id)
- unless ar_image
- ar_image = Image.new(:external_key => image.id,
- :name => image.name ? image.name :
- (image.description ? image.description :
- image.id),
- :architecture => image.architecture,
- :provider_id => cloud_account.provider.id)
- ar_image.save!
- end
- front_end_image = Image.new(:external_key =>
- cloud_account.account_prefix_for_realm +
- Realm::AGGREGATOR_REALM_ACCOUNT_DELIMITER +
- ar_image.external_key,
- :name => ar_image.name,
- :architecture => ar_image.architecture,
- :pool_id => id)
- front_end_image.save!
- end
- cloud_account.provider.hardware_profiles.each do |hardware_profile|
- front_hardware_profile = HardwareProfile.new(:external_key =>
- cloud_account.account_prefix_for_realm +
- hardware_profile.external_key,
- :name => hardware_profile.name,
- :memory => hardware_profile.memory,
- :storage => hardware_profile.storage,
- :architecture => hardware_profile.architecture,
- :pool_id => id)
- front_hardware_profile.save!
- end
+ populate_realms(cloud_account, realms)
+ populate_images(cloud_account, images)
+ populate_hardware_profiles(cloud_account, hardware_profiles)
+ end
+ end
+
+ end
+
+ private
+ def populate_realms(cloud_account, realms)
+ provider = Provider.find(cloud_account.provider_id)
+
+ realms.each do |realm|
+ #ignore if it exists
+ #FIXME: we need to handle keeping in sync for updates as well as
+ # account permissions
+ #unless Realm.find_by_external_key_and_provider_id(realm.id, cloud_account.provider.id)
+ matching_realms = Realm.find(:all, :conditions => {:provider_id => provider.id, :external_key => realm.id})
+ if matching_realms.length == 0
+ ar_realm = Realm.new(:external_key => realm.id,
+ :name => realm.name ? realm.name : realm.id,
+ :provider_id => cloud_account.provider.id)
+ ar_realm.save!
+ end
+ end
+ end
+
+ def populate_hardware_profiles(cloud_account, hardware_profiles)
+
+ hardware_profiles.each do |hardware_profile|
+ external_key = cloud_account.account_prefix_for_realm + hardware_profile.id
+ profiles = HardwareProfile.find(:all, :conditions => {:pool_id => id, :external_key => external_key})
+
+ if profiles.length == 0
+ front_hardware_profile = HardwareProfile.new( :external_key => external_key,
+ :name => hardware_profile.id,
+ :memory => hardware_profile.memory,
+ :storage => hardware_profile.storage,
+ :architecture => hardware_profile.architecture,
+ :pool_id => id)
+ front_hardware_profile.save!
end
end
end
-
+ def populate_images(cloud_account, images)
+ provider = Provider.find(cloud_account.provider_id)
+
+ images.each do |image|
+
+ ar_images = Image.find(:all, :conditions => {:provider_id => provider.id, :external_key => image.id})
+ if ar_images.length == 0
+ ar_image = Image.new(:external_key => image.id,
+ :name => image.name ? image.name :
+ (image.description ? image.description :
+ image.id),
+ :architecture => image.architecture,
+ :provider_id => cloud_account.provider.id)
+ ar_image.save!
+ end
+
+ fr_images = Image.find(:all, :conditions => {:pool_id => id, :external_key => image.id})
+ if fr_images.length == 0
+
+
+ front_end_image = Image.new(:external_key =>
+ cloud_account.account_prefix_for_realm +
+ Realm::AGGREGATOR_REALM_ACCOUNT_DELIMITER +
+ ar_image.external_key,
+ :name => ar_image.name,
+ :architecture => ar_image.architecture,
+ :pool_id => id)
+ front_end_image.save!
+ end
+
+ end
+ end
end
diff --git a/src/app/views/pool/accounts.html.erb b/src/app/views/pool/accounts.html.erb
index 96c4e2d..d63fe13 100644
--- a/src/app/views/pool/accounts.html.erb
+++ b/src/app/views/pool/accounts.html.erb
@@ -26,5 +26,5 @@
</tbody>
</table>
<% end %>
-<%= link_to "View/Add Existing Cloud Accounts", {:controller => "pool",:action => "accounts_for_pool", :pool_id => @pool}, :class=>"actionlink" %>
+<%= link_to "View/Add Existing Cloud Accounts", {:controller => "pool",:action => "accounts_for_pool", :id => @pool}, :class=>"actionlink" %>
<%= link_to "Add a New Cloud Account", {:controller => "cloud_accounts",:action => "new_from_pool", :pool_id => @pool}, :class=>"actionlink" %><br/>
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 4a304ca..bc11307 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -34,8 +34,9 @@ ActionController::Routing::Routes.draw do |map|
map.resources :pool
-
+
map.connect '', :controller => 'provider'
+ map.connect ':controller/:action:/:pool/:cloud_account', :controller => 'pool', :action => 'add_account'
map.login 'login', :controller => "user_sessions", :action => "new"
map.logout 'logout', :controller => "user_sessions", :action => "destroy"
--
1.6.6.1
14 years, 1 month
Blocked with b0rken aggregator
by steve linabery
Hi all,
I'm hitting a bug with aggregator. Here's how I get it:
1) wipe database and create new user, slinabery, via web ui
2) rake dc:site_admin[slinabery]
3) create a new provider, mocc, using mock provider
4) there is a default pool created named slinabery. click it.
5) follow link "Back End Accounts". follow link "Add a New Cloud Account".
6) get error "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"
at URL http://localhost:3000/cloud_accounts/new_from_pool?pool_id=1
7) Click entry in left-hand list for Provider "mocc"
8) Follow link "Accounts", then link "Add an account"
9) complete form using "mockuser" and "mockpassword"
10) click pool 'slinabery', follow link "Back End Accounts"
11) click "view/add existing cloud accounts"
12) click "Add this account" link next to 'mocc' provider entry
13) get error "Validation failed: Name has already been taken"
at URL http://localhost:3000/pool/add_account?cloud_account=1&pool=1
Here's the trace from the aggregator server stdout:
ActiveRecord::RecordInvalid (Validation failed: Name has already been taken):
app/models/pool.rb:113:in `populate_realms_and_images'
app/models/pool.rb:104:in `populate_realms_and_images'
app/models/pool.rb:67:in `populate_realms_and_images'
app/models/pool.rb:58:in `each'
app/models/pool.rb:58:in `populate_realms_and_images'
app/controllers/pool_controller.rb:110:in `add_account'
app/controllers/pool_controller.rb:107:in `add_account'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
Thank you,
Steve.
14 years, 1 month
Terremark vcloud express driver [the one that works]
by marios@redhat.com
This patch implements the terremark driver for deltacloud core. I've been using this for a few days to create and manage instances and seems to be fine (deltacloudd -i terremark). Besides this patch you also need the gems 'fog', 'nokogiri', 'excon' (gem install [name]).
Known issues:
- getting list of images is slow and sometimes you need to refresh browser manually
- still dont get full details about an instance (e.g. os, memory, cpu) - this is an issue with the underlying fog library which I'm looking at
If you would like to play with the driver I have a limited account (20 something days left) that terremark gave me for testing - ping me and I can give you login details. You can use terremark's web management console to confirm what you've done etc: https://my.vcloudexpress.terremark.com/Signin.aspx
--marios
14 years, 1 month
[PATCH] Added Validation for Cloud Account Provider Credentials
by Martyn Taylor
From: martyntaylor <mtaylor(a)redhat.com>
---
src/app/controllers/cloud_accounts_controller.rb | 2 +-
src/app/controllers/provider_controller.rb | 11 ++++++++---
src/app/models/cloud_account.rb | 16 ++++++++++++++++
src/app/views/cloud_accounts/new.html.erb | 1 +
src/features/support/env.rb | 6 ++++++
.../controllers/cloud_accounts_controller_spec.rb | 7 +++++++
src/spec/spec_helper.rb | 7 +++++++
7 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/src/app/controllers/cloud_accounts_controller.rb b/src/app/controllers/cloud_accounts_controller.rb
index 05e024e..23b3113 100644
--- a/src/app/controllers/cloud_accounts_controller.rb
+++ b/src/app/controllers/cloud_accounts_controller.rb
@@ -95,4 +95,4 @@ class CloudAccountsController < ApplicationController
end
redirect_to :controller => 'provider', :action => 'accounts', :id => provider.id
end
-end
+end
\ No newline at end of file
diff --git a/src/app/controllers/provider_controller.rb b/src/app/controllers/provider_controller.rb
index 23b5ba0..092054c 100644
--- a/src/app/controllers/provider_controller.rb
+++ b/src/app/controllers/provider_controller.rb
@@ -76,8 +76,13 @@ class ProviderController < ApplicationController
require_privilege(Privilege::ACCOUNT_MODIFY)
@acct = CloudAccount.find_or_create(params[:cloud_account])
@provider = Provider.find(params[:cloud_account][:provider_id])
- @provider.cloud_accounts << @acct
- redirect_to :action => 'accounts', :id => @provider.id
+ if @acct.save
+ @provider.cloud_accounts << @acct
+ redirect_to :action => 'accounts', :id => @provider.id
+ else
+ flash[:notice] = @acct.errors.full_messages[0]
+ redirect_to :action => 'new_account', :id => @provider.id
+ end
end
-end
+end
\ No newline at end of file
diff --git a/src/app/models/cloud_account.rb b/src/app/models/cloud_account.rb
index 1d6b3e9..f04187d 100644
--- a/src/app/models/cloud_account.rb
+++ b/src/app/models/cloud_account.rb
@@ -67,4 +67,20 @@ class CloudAccount < ActiveRecord::Base
def name
username
end
+
+ protected
+ def validate
+ errors.add_to_base("Login Credentials are Invalid for this Provider") unless valid_credentials?
+ end
+
+ private
+ def valid_credentials?
+ begin
+ deltacloud = DeltaCloud.new(username, password, provider.url)
+ deltacloud.instances
+ rescue Exception => e
+ return false
+ end
+ return true
+ end
end
diff --git a/src/app/views/cloud_accounts/new.html.erb b/src/app/views/cloud_accounts/new.html.erb
index 40f32cb..8d4fcc8 100644
--- a/src/app/views/cloud_accounts/new.html.erb
+++ b/src/app/views/cloud_accounts/new.html.erb
@@ -4,6 +4,7 @@
<h2 class="greeting">New Cloud Account</h2>
<div class="dcloud_form">
+ <%= error_messages_for 'cloud_account' %>
<% form_for @cloud_account, :url => { :action => "create" } do |f| %>
<%= f.error_messages %>
<%= render :partial => "form", :object => f %>
diff --git a/src/features/support/env.rb b/src/features/support/env.rb
index 2d6e9a1..91327a8 100644
--- a/src/features/support/env.rb
+++ b/src/features/support/env.rb
@@ -30,6 +30,12 @@ Provider.class_eval do
end
end
+CloudAccount.class_eval do
+ alias_method :original_validate, :validate
+ def validate
+ end
+end
+
# If you set this to false, any error raised from within your app will bubble
# up to your step definition and out to cucumber unless you catch it somewhere
# on the way. You can make Rails rescue errors and render error pages on a
diff --git a/src/spec/controllers/cloud_accounts_controller_spec.rb b/src/spec/controllers/cloud_accounts_controller_spec.rb
index f1d4a0d..4dbac78 100644
--- a/src/spec/controllers/cloud_accounts_controller_spec.rb
+++ b/src/spec/controllers/cloud_accounts_controller_spec.rb
@@ -48,4 +48,11 @@ describe CloudAccountsController do
response.should_not be_success
end
+ it "should fail to create a cloud account if the provider credentials are invalid" do
+ cloud_account = Factory.build(:mock_cloud_account)
+ cloud_account.stub!(:valid_credentials?).and_return(false)
+ cloud_account.save.should == false
+ end
+
+
end
diff --git a/src/spec/spec_helper.rb b/src/spec/spec_helper.rb
index 5181389..b880a52 100644
--- a/src/spec/spec_helper.rb
+++ b/src/spec/spec_helper.rb
@@ -21,6 +21,13 @@ Spec::Runner.configure do |config|
config.use_instantiated_fixtures = false
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
+CloudAccount.class_eval do
+ alias_method :original_valid_credentials?, :valid_credentials?
+ def valid_credentials?
+ return true
+ end
+end
+
# == Fixtures
#
# You can declare fixtures for each example_group like this:
--
1.6.6.1
14 years, 1 month
Recent versions of test-unit / ZenTest break deltacloud aggregator
by Mo Morsi
I ran into this when I updated my gems locally via 'gem update' and
attempted to run 'rake spec' against the next branch of the aggregator
http://stackoverflow.com/questions/1145318/getting-uninitialized-constant...
A workaround for the time being is to install an older version of
test-unit via
gem install test-unit -v 1.2.3
and forcing rails to use it, by adding the following to
config/environment.rb
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 4277fe7..395ad7a 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -73,4 +73,7 @@ Rails::Initializer.run do |config|
# The default locale is :en and all translations from
config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales',
'*.{rb,yml}')]
# config.i18n.default_locale = :de
+
+ config.gem 'test-unit', :lib => 'test/unit', :version => '1.2.3'
+
end
-Mo
14 years, 1 month
[PATCH] Fix return value from ec2 *_instance methods.
by Chris Lalancette
The *_instance methods are expected to return an instance
object from the individual drivers. The ec2 driver was
failing to do this, leading to stacktraces in the server.
Fix this up by fetching the instance after an action.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
server/lib/deltacloud/drivers/ec2/ec2_driver.rb | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 69356e2..e1e5bf2 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -171,6 +171,9 @@ class EC2Driver < Deltacloud::BaseDriver
safely do
ec2.reboot_instances( :instance_id => id )
end
+
+ this_instance = ec2.describe_instances( :instance_id => id).reservationSet.item.first.instancesSet.item.first
+ convert_instance(this_instance, this_instance.ownerId)
end
def stop_instance(credentials, id)
@@ -178,6 +181,8 @@ class EC2Driver < Deltacloud::BaseDriver
safely do
ec2.terminate_instances( :instance_id => id )
end
+ this_instance = ec2.describe_instances( :instance_id => id).reservationSet.item.first.instancesSet.item.first
+ convert_instance(this_instance, this_instance.ownerId)
end
def destroy_instance(credentials, id)
@@ -185,6 +190,8 @@ class EC2Driver < Deltacloud::BaseDriver
safely do
ec2.terminate_instances( :instance_id => id )
end
+ this_instance = ec2.describe_instances( :instance_id => id).reservationSet.item.first.instancesSet.item.first
+ convert_instance(this_instance, this_instance.ownerId)
end
#
--
1.6.6.1
14 years, 1 month
Towards declaring the Deltacloud API stable
by David Lutterkort
Hi,
I would like to get quickly to a point where we can declare the current
Deltacloud API stable, and be reasonably confident that we can evolve
the API in a way that will maintain backwards compatibility.
Unfortunately, there are a few goofups in the current Deltacloud API
that we need to fix before we can declare the API stable, since fixing
them will break API compatibility. In no specific order, the issues I am
aware of are
* returning full objects when listing a collection: this is a
pretty serious issue. For example, for Terremark, returning a
list of full image details requires first calling to Terremark
to get a list of images without details, then retrieving the
detail of each image. That can be a long and slow process,
leading to timeout issues for clients. The best way to fix this
is to return full image details on GET /api/images from drivers
where that is cheap, and only an abbreviated list of images,
i.e. with only a URL and id for the image, from drivers like
Terremark. We'll probably have to deal with other lists in a
similar manner.
* returning the representation of a new instance from a
POST /api/instances: again, in some drivers, like Terremark,
that requires making two calls to the backend cloud, which is
too fragile for this operation. Instead, the result from
POST /api/instances should contain the URL of the new instance
in a Location: header, and optionally the instance
representation for drivers where that is cheap to do.
* the list of actions for an instance is misleading: we report
<link rel='ACTION' href='URL'/> - that is not enough, since it
gives no indication what HTTP method should be used to perform
the action. It's generally POST, but for destroying an instance,
you are supposed to do a DELETE on the instance URL. We
therefore need to include a method in the <link/> tag
* inconsistent indication of relations to other objects, e.g. the
image and the hardware profile for an instance. For the image,
we just include a <image href="..."/> tag, whereas for hardware
profile we give the URL for hte HWP and its id. There's actually
some discussion on rest-practices[1] pertaining to that, though
we haven't reached any conclusion.
* inconsistent usage of '-' and '_' in XML tag names (e.g.,
<hardware-profile> vs. <owner_id>) This one is mostly cosmetic,
but if we are breaking API, we might as well fix this one, too.
I am sure there are other issues, and I'd appreciate if people could
help collect them, so we can address them with one last big API breakage
before we declare the API stable going forward.
David
[1] https://www.redhat.com/archives/rest-practices/2010-April/msg00024.html
14 years, 1 month