From: Ladislav Martincik lmartinc@redhat.com
--- src/app/controllers/cloud_accounts_controller.rb | 179 -------------------- src/app/controllers/dashboard_controller.rb | 6 +- src/app/controllers/permissions_controller.rb | 4 +- src/app/controllers/pools_controller.rb | 14 +- .../controllers/provider_accounts_controller.rb | 179 ++++++++++++++++++++ src/app/controllers/quotas_controller.rb | 6 +- src/app/controllers/templates_controller.rb | 2 +- src/app/models/cloud_account.rb | 176 ------------------- src/app/models/instance.rb | 2 +- src/app/models/instance_key.rb | 2 +- src/app/models/instance_observer.rb | 4 +- src/app/models/instance_task.rb | 6 +- src/app/models/permission.rb | 2 +- src/app/models/pool.rb | 6 +- src/app/models/provider.rb | 8 +- src/app/models/provider_account.rb | 176 +++++++++++++++++++ src/app/models/quota.rb | 10 +- src/app/models/zone.rb | 2 +- src/app/services/data_service_active_record.rb | 16 +- src/app/services/graph_service.rb | 22 ++-- src/app/util/condormatic.rb | 6 +- src/app/views/cloud_accounts/_form.haml | 52 ------ src/app/views/cloud_accounts/edit.haml | 17 -- src/app/views/cloud_accounts/index.haml | 25 --- src/app/views/cloud_accounts/new.haml | 17 -- src/app/views/dashboard/summary.haml | 6 +- src/app/views/instances/index.haml | 2 +- src/app/views/instances/show.haml | 2 +- src/app/views/provider_accounts/_form.haml | 52 ++++++ src/app/views/provider_accounts/edit.haml | 17 ++ src/app/views/provider_accounts/index.haml | 25 +++ src/app/views/provider_accounts/new.haml | 17 ++ src/app/views/providers/accounts.haml | 42 +++--- src/classad_plugin/classad_plugin.rb | 10 +- src/config/environment.rb | 2 +- src/config/locales/en.yml | 2 +- src/config/navigation.rb | 2 +- src/config/routes.rb | 4 +- src/db/development_structure.sql | 79 +++++++++ ...706_rename_cloud_account_to_provider_account.rb | 17 ++ src/dbomatic/dbomatic | 8 +- src/features/provider.feature | 16 +- src/features/step_definitions/pool_steps.rb | 6 +- src/features/support/custom.rb | 8 +- src/image_builder_service/image_builder_service | 2 +- src/lib/tasks/demo_data.rake | 12 +- .../controllers/cloud_accounts_controller_spec.rb | 91 ---------- .../provider_accounts_controller_spec.rb | 91 ++++++++++ src/spec/controllers/templates_controller_spec.rb | 2 +- src/spec/factories/cloud_account.rb | 21 --- src/spec/factories/instance.rb | 4 +- src/spec/factories/instance_key.rb | 6 +- src/spec/factories/provider_account.rb | 21 +++ src/spec/models/cloud_account_spec.rb | 80 --------- src/spec/models/instance_observer_spec.rb | 16 +- src/spec/models/instance_spec.rb | 6 +- src/spec/models/provider_account_spec.rb | 80 +++++++++ src/spec/models/provider_spec.rb | 2 +- src/spec/models/quota_spec.rb | 48 +++--- src/spec/models/zone_spec.rb | 10 +- .../services/data_service_active_record_spec.rb | 58 +++--- src/test/fixtures/cloud_accounts.yml | 6 - src/test/fixtures/instances.yml | 2 +- src/test/fixtures/pool_accounts.yml | 2 +- src/test/fixtures/pools.yml | 2 +- src/test/fixtures/provider_accounts.yml | 6 + src/test/unit/cloud_account_test.rb | 8 - src/test/unit/provider_account_test.rb | 8 + 68 files changed, 968 insertions(+), 872 deletions(-) delete mode 100644 src/app/controllers/cloud_accounts_controller.rb create mode 100644 src/app/controllers/provider_accounts_controller.rb delete mode 100644 src/app/models/cloud_account.rb create mode 100644 src/app/models/provider_account.rb delete mode 100644 src/app/views/cloud_accounts/_form.haml delete mode 100644 src/app/views/cloud_accounts/edit.haml delete mode 100644 src/app/views/cloud_accounts/index.haml delete mode 100644 src/app/views/cloud_accounts/new.haml create mode 100644 src/app/views/provider_accounts/_form.haml create mode 100644 src/app/views/provider_accounts/edit.haml create mode 100644 src/app/views/provider_accounts/index.haml create mode 100644 src/app/views/provider_accounts/new.haml create mode 100644 src/db/development_structure.sql create mode 100644 src/db/migrate/20101126125706_rename_cloud_account_to_provider_account.rb delete mode 100644 src/spec/controllers/cloud_accounts_controller_spec.rb create mode 100644 src/spec/controllers/provider_accounts_controller_spec.rb delete mode 100644 src/spec/factories/cloud_account.rb create mode 100644 src/spec/factories/provider_account.rb delete mode 100644 src/spec/models/cloud_account_spec.rb create mode 100644 src/spec/models/provider_account_spec.rb delete mode 100644 src/test/fixtures/cloud_accounts.yml create mode 100644 src/test/fixtures/provider_accounts.yml delete mode 100644 src/test/unit/cloud_account_test.rb create mode 100644 src/test/unit/provider_account_test.rb
diff --git a/src/app/controllers/cloud_accounts_controller.rb b/src/app/controllers/cloud_accounts_controller.rb deleted file mode 100644 index 6a2a072..0000000 --- a/src/app/controllers/cloud_accounts_controller.rb +++ /dev/null @@ -1,179 +0,0 @@ -# -# Copyright (C) 2010 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. A copy of the GNU General Public License is -# also available at http://www.gnu.org/copyleft/gpl.html. - -# Filters added to this controller apply to all controllers in the application. -# Likewise, all the methods added will be available for all controllers. - -class CloudAccountsController < ApplicationController - before_filter :require_user - before_filter :load_providers - - helper :providers - - def index - @provider = Provider.find(params[:provider_id]) - require_privilege(Privilege::ACCOUNT_VIEW, @provider) - end - - def new - @provider = Provider.find(params[:provider_id]) - @cloud_account = CloudAccount.new - require_privilege(Privilege::ACCOUNT_MODIFY, @provider) - end - - def create - @provider = Provider.find(params[:provider_id]) - require_privilege(Privilege::ACCOUNT_MODIFY,@provider) - @cloud_account = CloudAccount.new(params[:cloud_account]) - @cloud_account.provider = @provider - - if params[:test_account] - test_account(@cloud_account) - render :action => 'new' and return - end - - if @cloud_account.invalid? - if not @cloud_account.valid_credentials? - flash.now[:error] = "The entered credential information is incorrect" - elsif @cloud_account.errors.on(:username) - flash.now[:error] = "The access key '#{params[:cloud_account][:username]}' has already been taken." - else - flash.now[:error] = "You must fill in all the required fields" - end - render :action => 'new' and return - end - - quota = Quota.new - quota.maximum_running_instances = quota_from_string(params[:quota][:maximum_running_instances]) - quota.save! - @cloud_account.quota = quota - @cloud_account.zones << Zone.default - @cloud_account.save! - if @cloud_account.populate_realms - flash[:notice] = "Provider account added." - end - redirect_to provider_accounts_path(@provider) - kick_condor - end - - def edit - @cloud_account = CloudAccount.find(params[:id]) - @provider = @cloud_account.provider - require_privilege(Privilege::ACCOUNT_MODIFY,@provider) - end - - def update_accounts - @provider = Provider.find(params[:provider][:id]) - require_privilege(Privilege::ACCOUNT_MODIFY, @provider) - @providers = Provider.list_for_user(@current_user, Privilege::PROVIDER_VIEW) - - success = true - @provider.cloud_accounts.each do |cloud_account| - attributes = params[:cloud_accounts][cloud_account.id.to_s] - - password = attributes[:password] - # blank password means the user didn't change it -- don't update it then - if password.blank? - attributes.delete :password - end - cloud_account.quota.maximum_running_instances = quota_from_string(params[:quota][cloud_account.id.to_s][:maximum_running_instances]) - - private_cert = attributes[:x509_cert_priv_file] - unless private_cert.blank? - attributes[:x509_cert_priv] = private_cert.read - end - attributes.delete :x509_cert_priv_file - - public_cert = attributes[:x509_cert_pub_file] - unless public_cert.blank? - attributes[:x509_cert_pub] = public_cert.read - end - attributes.delete :x509_cert_pub_file - - begin - cloud_account.update_attributes!(attributes) - cloud_account.quota.save! - rescue - success = false - end - end - if success - flash[:notice] = "Account updated." - redirect_to :controller => 'providers', :action => 'accounts', :id => @provider - else - flash.now[:notice] = "Error updating the cloud account." - render :template => 'provider/accounts' - end - end - - def update - @cloud_account = CloudAccount.find(params[:id]) - @provider = @cloud_account.provider - require_privilege(Privilege::ACCOUNT_MODIFY, @provider) - if @cloud_account.update_attributes(params[:cloud_account]) - flash[:notice] = "Cloud Account updated!" - redirect_to provider_accounts_path(@provider) - else - render :action => :edit - end - end - - def key - @cloud_account = CloudAccount.find(params[:id]) - require_privilege(Privilege::ACCOUNT_MODIFY,@cloud_account.provider) - unless @cloud_account.instance_key.nil? - render :text => @cloud_account.instance_key.pem - end - end - - def destroy - account = CloudAccount.find(params[:id]) - provider = account.provider - require_privilege(Privilege::ACCOUNT_MODIFY, provider) - if account.destroy - flash[:notice] = "Cloud Account destroyed" - else - flash[:error] = "Cloud Account could not be destroyed" - end - redirect_to provider_accounts_path(provider) - end - - def test_account(account) - if account.valid_credentials? - flash.now[:notice] = "Test Connection Success: Valid Account Details" - else - flash.now[:error] = "Test Connection Failed: Invalid Account Details" - end - rescue - flash.now[:error] = "Test Connection Failed: Could not connect to provider" - end - - private - - def quota_from_string(quota_raw) - if quota_raw.nil? or quota_raw.empty? or quota_raw.downcase == 'unlimited' - return nil - else - return Integer(quota_raw) - end - end - - def load_providers - @providers = Provider.list_for_user(@current_user, Privilege::PROVIDER_VIEW) - end -end diff --git a/src/app/controllers/dashboard_controller.rb b/src/app/controllers/dashboard_controller.rb index 8d37a12..e5b0c5f 100644 --- a/src/app/controllers/dashboard_controller.rb +++ b/src/app/controllers/dashboard_controller.rb @@ -40,8 +40,8 @@ class DashboardController < ApplicationController end
def quota_usage_graph - if params[:cloud_account_id] - params[:parent] = CloudAccount.find(params[:cloud_account_id]) + if params[:provider_account_id] + params[:parent] = ProviderAccount.find(params[:provider_account_id]) elsif params[:pool_id] params[:parent] = Pool.find(params[:pool_id]) else @@ -67,7 +67,7 @@ class DashboardController < ApplicationController
def index # FIXME filter to just those that the user has access to - @cloud_accounts = CloudAccount.find(:all) + @provider_accounts = ProviderAccount.find(:all)
# Now need to check any permissions are set since default permission and pool diff --git a/src/app/controllers/permissions_controller.rb b/src/app/controllers/permissions_controller.rb index c326e14..adc8d45 100644 --- a/src/app/controllers/permissions_controller.rb +++ b/src/app/controllers/permissions_controller.rb @@ -73,8 +73,8 @@ class PermissionsController < ApplicationController @permission_object = Pool.find params[:pool_id] elsif !params[:provider_id].nil? @permission_object = Provider.find params[:provider_id] - elsif !params[:cloud_account_id].nil? - @permission_object = CloudAccount.find params[:cloud_account_id] + elsif !params[:provider_account_id].nil? + @permission_object = ProviderAccount.find params[:provider_account_id] elsif !params[:base_permission_object_id].nil? @permission_object = BasePermissionObject.find params[:base_permission_object_id] else diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb index 2ba6940..bcc3d31 100644 --- a/src/app/controllers/pools_controller.rb +++ b/src/app/controllers/pools_controller.rb @@ -133,22 +133,22 @@ class PoolsController < ApplicationController def accounts_for_pool @pool = Pool.find(params[:pool_id]) require_privilege(Privilege::ACCOUNT_VIEW,@pool) - @cloud_accounts = [] - all_accounts = CloudAccount.list_for_user(@current_user, Privilege::ACCOUNT_ADD) + @provider_accounts = [] + all_accounts = ProviderAccount.list_for_user(@current_user, Privilege::ACCOUNT_ADD) all_accounts.each {|account| - @cloud_accounts << account unless @pool.cloud_accounts.map{|x| x.id}.include?(account.id) + @provider_accounts << account unless @pool.provider_accounts.map{|x| x.id}.include?(account.id) } end
def add_account @pool = Pool.find(params[:pool]) - @cloud_account = CloudAccount.find(params[:cloud_account]) + @provider_account = ProviderAccount.find(params[:provider_account]) require_privilege(Privilege::ACCOUNT_ADD,@pool) - require_privilege(Privilege::ACCOUNT_ADD,@cloud_account) + require_privilege(Privilege::ACCOUNT_ADD,@provider_account) Pool.transaction do - @pool.cloud_accounts << @cloud_account unless @pool.cloud_accounts.map{|x| x.id}.include?(@cloud_account.id) + @pool.provider_accounts << @provider_account unless @pool.provider_accounts.map{|x| x.id}.include?(@provider_account.id) @pool.save! - @pool.populate_realms([@cloud_account]) + @pool.populate_realms([@provider_account]) end redirect_to :action => 'show', :id => @pool.id end diff --git a/src/app/controllers/provider_accounts_controller.rb b/src/app/controllers/provider_accounts_controller.rb new file mode 100644 index 0000000..a3efea7 --- /dev/null +++ b/src/app/controllers/provider_accounts_controller.rb @@ -0,0 +1,179 @@ +# +# Copyright (C) 2010 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +class ProviderAccountsController < ApplicationController + before_filter :require_user + before_filter :load_providers + + helper :providers + + def index + @provider = Provider.find(params[:provider_id]) + require_privilege(Privilege::ACCOUNT_VIEW, @provider) + end + + def new + @provider = Provider.find(params[:provider_id]) + @provider_account = ProviderAccount.new + require_privilege(Privilege::ACCOUNT_MODIFY, @provider) + end + + def create + @provider = Provider.find(params[:provider_id]) + require_privilege(Privilege::ACCOUNT_MODIFY,@provider) + @provider_account = ProviderAccount.new(params[:provider_account]) + @provider_account.provider = @provider + + if params[:test_account] + test_account(@provider_account) + render :action => 'new' and return + end + + if @provider_account.invalid? + if not @provider_account.valid_credentials? + flash.now[:error] = "The entered credential information is incorrect" + elsif @provider_account.errors.on(:username) + flash.now[:error] = "The access key '#{params[:provider_account][:username]}' has already been taken." + else + flash.now[:error] = "You must fill in all the required fields" + end + render :action => 'new' and return + end + + quota = Quota.new + quota.maximum_running_instances = quota_from_string(params[:quota][:maximum_running_instances]) + quota.save! + @provider_account.quota = quota + @provider_account.zones << Zone.default + @provider_account.save! + if @provider_account.populate_realms + flash[:notice] = "Provider account added." + end + redirect_to provider_accounts_path(@provider) + kick_condor + end + + def edit + @provider_account = ProviderAccount.find(params[:id]) + @provider = @provider_account.provider + require_privilege(Privilege::ACCOUNT_MODIFY,@provider) + end + + def update_accounts + @provider = Provider.find(params[:provider][:id]) + require_privilege(Privilege::ACCOUNT_MODIFY, @provider) + @providers = Provider.list_for_user(@current_user, Privilege::PROVIDER_VIEW) + + success = true + @provider.provider_accounts.each do |provider_account| + attributes = params[:provider_accounts][provider_account.id.to_s] + + password = attributes[:password] + # blank password means the user didn't change it -- don't update it then + if password.blank? + attributes.delete :password + end + provider_account.quota.maximum_running_instances = quota_from_string(params[:quota][provider_account.id.to_s][:maximum_running_instances]) + + private_cert = attributes[:x509_cert_priv_file] + unless private_cert.blank? + attributes[:x509_cert_priv] = private_cert.read + end + attributes.delete :x509_cert_priv_file + + public_cert = attributes[:x509_cert_pub_file] + unless public_cert.blank? + attributes[:x509_cert_pub] = public_cert.read + end + attributes.delete :x509_cert_pub_file + + begin + provider_account.update_attributes!(attributes) + provider_account.quota.save! + rescue + success = false + end + end + if success + flash[:notice] = "Account updated." + redirect_to :controller => 'providers', :action => 'accounts', :id => @provider + else + flash.now[:notice] = "Error updating the cloud account." + render :template => 'provider/accounts' + end + end + + def update + @provider_account = ProviderAccount.find(params[:id]) + @provider = @provider_account.provider + require_privilege(Privilege::ACCOUNT_MODIFY, @provider) + if @provider_account.update_attributes(params[:provider_account]) + flash[:notice] = "Cloud Account updated!" + redirect_to provider_accounts_path(@provider) + else + render :action => :edit + end + end + + def key + @provider_account = ProviderAccount.find(params[:id]) + require_privilege(Privilege::ACCOUNT_MODIFY,@provider_account.provider) + unless @provider_account.instance_key.nil? + render :text => @provider_account.instance_key.pem + end + end + + def destroy + account = ProviderAccount.find(params[:id]) + provider = account.provider + require_privilege(Privilege::ACCOUNT_MODIFY, provider) + if account.destroy + flash[:notice] = "Cloud Account destroyed" + else + flash[:error] = "Cloud Account could not be destroyed" + end + redirect_to provider_accounts_path(provider) + end + + def test_account(account) + if account.valid_credentials? + flash.now[:notice] = "Test Connection Success: Valid Account Details" + else + flash.now[:error] = "Test Connection Failed: Invalid Account Details" + end + rescue + flash.now[:error] = "Test Connection Failed: Could not connect to provider" + end + + private + + def quota_from_string(quota_raw) + if quota_raw.nil? or quota_raw.empty? or quota_raw.downcase == 'unlimited' + return nil + else + return Integer(quota_raw) + end + end + + def load_providers + @providers = Provider.list_for_user(@current_user, Privilege::PROVIDER_VIEW) + end +end diff --git a/src/app/controllers/quotas_controller.rb b/src/app/controllers/quotas_controller.rb index e9937fb..9396a35 100644 --- a/src/app/controllers/quotas_controller.rb +++ b/src/app/controllers/quotas_controller.rb @@ -76,8 +76,8 @@ class QuotasController < ApplicationController def get_parent_object(params) if params[:parent_type] == "pool" return Pool.find(params[:id]) - elsif params[:parent_type] == "cloud_account" - return CloudAccount.find(params[:id]) + elsif params[:parent_type] == "provider_account" + return ProviderAccount.find(params[:id]) end #TODO Throw no match to pool or cloud account exception end @@ -85,7 +85,7 @@ class QuotasController < ApplicationController def get_parent_name(parent, parent_type) if parent_type == "pool" return parent.name - elsif parent_type == "cloud_account" + elsif parent_type == "provider_account" return parent.username end #TODO Throw no match to pool or cloud account exception diff --git a/src/app/controllers/templates_controller.rb b/src/app/controllers/templates_controller.rb index 12df295..2607ef6 100644 --- a/src/app/controllers/templates_controller.rb +++ b/src/app/controllers/templates_controller.rb @@ -197,7 +197,7 @@ class TemplatesController < ApplicationController on <a href="#{url_for :controller => 'providers'}">the providers page.</a>") render :action => 'build_form' and return end - if provider.cloud_accounts.empty? + if provider.provider_accounts.empty? flash_error("There is no provider account for '#{target}' provider, you can \ add account on <a href="#{url_for :controller => 'providers', \ :action => 'accounts', :id => provider.id}">the provider accounts page</a>") diff --git a/src/app/models/cloud_account.rb b/src/app/models/cloud_account.rb deleted file mode 100644 index 37365a0..0000000 --- a/src/app/models/cloud_account.rb +++ /dev/null @@ -1,176 +0,0 @@ - # -# Copyright (C) 2009 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. A copy of the GNU General Public License is -# also available at http://www.gnu.org/copyleft/gpl.html. - -# Filters added to this controller apply to all controllers in the application. -# Likewise, all the methods added will be available for all controllers. - -require 'nokogiri' - -class CloudAccount < ActiveRecord::Base - include PermissionedObject - - # Relations - belongs_to :provider - belongs_to :quota - has_many :instances - has_and_belongs_to_many :zones - has_many :permissions, :as => :permission_object, :dependent => :destroy, - :include => [:role], - :order => "permissions.id ASC" - - has_one :instance_key, :dependent => :destroy - - # Helpers - attr_accessor :x509_cert_priv_file, :x509_cert_pub_file - - # Validations - validates_presence_of :provider_id - validates_presence_of :label - validates_presence_of :username - validates_uniqueness_of :username, :scope => :provider_id - validates_presence_of :password - validates_presence_of :account_number - validate :validate_presence_of_x509_certs - validate :validate_credentials - - # We're using this instead of <tt>validates_presence_of</tt> helper because - # we want to show errors on different attributes ending with '_file'. - def validate_presence_of_x509_certs - errors.add(:x509_cert_pub_file, "can't be blank") if x509_cert_pub.blank? - errors.add(:x509_cert_priv_file, "can't be blank") if x509_cert_priv.blank? - end - - def validate_credentials - unless valid_credentials? - errors.add(:base, "Login Credentials are Invalid for this Provider") - end - end - - # Hooks - after_create :generate_cloud_account_key - before_destroy :destroyable? - before_validation :read_x509_files - - def destroyable? - instances.empty? - end - - def read_x509_files - self.x509_cert_pub = x509_cert_pub_file.read if x509_cert_pub_file.respond_to?(:read) - self.x509_cert_priv = x509_cert_priv_file.read if x509_cert_priv_file.respond_to?(:read) - end - - def connect - begin - return DeltaCloud.new(username, password, provider.url) - rescue Exception => e - logger.error("Error connecting to framework: #{e.message}") - logger.error("Backtrace: #{e.backtrace.join("\n")}") - return nil - end - end - - def self.find_or_create(account) - a = CloudAccount.find_by_username_and_provider_id(account["username"], account["provider_id"]) - return a.nil? ? CloudAccount.new(account) : a - end - - def pools - pools = [] - instances.each do |instance| - pools << instance.pool - end - end - - def name - label.blank? ? username : label - end - - # FIXME: for already-mapped accounts, update rather than add new - def populate_realms - client = connect - realms = client.realms - # FIXME: this should probably be in the same transaction as cloud_account.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, - provider.id) - ar_realm = Realm.new(:external_key => realm.id, - :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 - end - - def valid_credentials? - DeltaCloud::valid_credentials?(username, password, provider.url) - end - - def build_credentials - xml = Nokogiri::XML <<EOT -<?xml version="1.0"?> -<provider_credentials> - <ec2_credentials> - <account_number></account_number> - <access_key></access_key> - <secret_access_key></secret_access_key> - <certificate></certificate> - <key></key> - </ec2_credentials> -</provider_credentials> -EOT - node = xml.at_xpath('/provider_credentials/ec2_credentials') - node.at_xpath('./account_number').content = account_number - node.at_xpath('./access_key').content = username - node.at_xpath('./secret_access_key').content = password - node.at_xpath('./certificate').content = x509_cert_pub - node.at_xpath('./key').content = x509_cert_priv - return xml.to_s - end - - private - def generate_cloud_account_key - client = connect - if 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 - end - -end diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb index 22069e2..27d5e29 100644 --- a/src/app/models/instance.rb +++ b/src/app/models/instance.rb @@ -27,7 +27,7 @@ class Instance < ActiveRecord::Base @@per_page = 15
belongs_to :pool - belongs_to :cloud_account + belongs_to :provider_account
belongs_to :hardware_profile belongs_to :template diff --git a/src/app/models/instance_key.rb b/src/app/models/instance_key.rb index b3b7513..761499a 100644 --- a/src/app/models/instance_key.rb +++ b/src/app/models/instance_key.rb @@ -21,7 +21,7 @@ # class InstanceKey < ActiveRecord::Base
- belongs_to :cloud_account + belongs_to :provider_account has_many :instances
end diff --git a/src/app/models/instance_observer.rb b/src/app/models/instance_observer.rb index 3b9af13..7a5600b 100644 --- a/src/app/models/instance_observer.rb +++ b/src/app/models/instance_observer.rb @@ -36,9 +36,9 @@ class InstanceObserver < ActiveRecord::Observer hwp = an_instance.hardware_profile pool = an_instance.pool user = an_instance.owner - cloud_account = an_instance.cloud_account + provider_account = an_instance.provider_account
- [cloud_account, pool, user].each do |parent| + [provider_account, pool, user].each do |parent| if parent quota = parent.quota if quota diff --git a/src/app/models/instance_task.rb b/src/app/models/instance_task.rb index 6c78c0f..aba1e9a 100644 --- a/src/app/models/instance_task.rb +++ b/src/app/models/instance_task.rb @@ -44,10 +44,10 @@ class InstanceTask < Task # automatic transitions from transient states. def self.valid_actions_for_instance_state(state, instance, user=nil) actions = [] - # FIXME: cloud_account won't always be set here, but we're requiring + # FIXME: provider_account won't always be set here, but we're requiring # front end realm for now. - if cloud_account = instance.cloud_account and - conn = cloud_account.connect and c_state = conn.instance_state(state) + if provider_account = instance.provider_account and + conn = provider_account.connect and c_state = conn.instance_state(state) transitions = c_state.transitions transitions.each do |transition| # FIXME if we allow actions based on the expected state after diff --git a/src/app/models/permission.rb b/src/app/models/permission.rb index 349b6a7..09b5d09 100644 --- a/src/app/models/permission.rb +++ b/src/app/models/permission.rb @@ -33,7 +33,7 @@ class Permission < ActiveRecord::Base :foreign_key => "permission_object_id" belongs_to :provider, :class_name => "Provider", :foreign_key => "permission_object_id" - belongs_to :cloud_account, :class_name => "CloudAccount", + belongs_to :provider_account, :class_name => "ProviderAccount", :foreign_key => "permission_object_id" belongs_to :base_permission_object, :class_name => "BasePermissionObject", :foreign_key => "permission_object_id" diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb index 597128b..fc2747a 100644 --- a/src/app/models/pool.rb +++ b/src/app/models/pool.rb @@ -40,11 +40,11 @@ class Pool < ActiveRecord::Base :include => [:role], :order => "permissions.id ASC"
- def cloud_accounts + def provider_accounts accounts = [] instances.each do |instance| - if instance.cloud_account and !accounts.include?(instance.cloud_account) - accounts << instance.cloud_account + if instance.provider_account and !accounts.include?(instance.provider_account) + accounts << instance.provider_account end end end diff --git a/src/app/models/provider.rb b/src/app/models/provider.rb index cff34c2..e83c2b7 100644 --- a/src/app/models/provider.rb +++ b/src/app/models/provider.rb @@ -23,7 +23,7 @@ class Provider < ActiveRecord::Base require 'util/deltacloud' include PermissionedObject
- has_many :cloud_accounts, :dependent => :destroy + has_many :provider_accounts, :dependent => :destroy has_many :hardware_profiles, :dependent => :destroy has_many :replicated_images, :dependent => :destroy has_many :realms, :dependent => :destroy @@ -47,8 +47,8 @@ class Provider < ActiveRecord::Base # but a cloud account is silently not destroyed when there is # an instance for the cloud account def destroyable? - unless self.cloud_accounts.empty? - self.cloud_accounts.each do |c| + unless self.provider_accounts.empty? + self.provider_accounts.each do |c| unless c.instances.empty? inst_list = c.instances.map {|i| i.name}.join(', ') self.errors.add_to_base "there are instances for cloud account '#{c.name}': #{inst_list}" @@ -108,7 +108,7 @@ class Provider < ActiveRecord::Base end
def pools - cloud_accounts.collect {|account| account.pools}.flatten.uniq + provider_accounts.collect {|account| account.pools}.flatten.uniq end
# TODO: implement or remove - this is meant to contain a hash of diff --git a/src/app/models/provider_account.rb b/src/app/models/provider_account.rb new file mode 100644 index 0000000..8e10214 --- /dev/null +++ b/src/app/models/provider_account.rb @@ -0,0 +1,176 @@ + # +# Copyright (C) 2009 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +require 'nokogiri' + +class ProviderAccount < ActiveRecord::Base + include PermissionedObject + + # Relations + belongs_to :provider + belongs_to :quota + has_many :instances + has_and_belongs_to_many :zones + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + has_one :instance_key, :dependent => :destroy + + # Helpers + attr_accessor :x509_cert_priv_file, :x509_cert_pub_file + + # Validations + validates_presence_of :provider_id + validates_presence_of :label + validates_presence_of :username + validates_uniqueness_of :username, :scope => :provider_id + validates_presence_of :password + validates_presence_of :account_number + validate :validate_presence_of_x509_certs + validate :validate_credentials + + # We're using this instead of <tt>validates_presence_of</tt> helper because + # we want to show errors on different attributes ending with '_file'. + def validate_presence_of_x509_certs + errors.add(:x509_cert_pub_file, "can't be blank") if x509_cert_pub.blank? + errors.add(:x509_cert_priv_file, "can't be blank") if x509_cert_priv.blank? + end + + def validate_credentials + unless valid_credentials? + errors.add(:base, "Login Credentials are Invalid for this Provider") + end + end + + # Hooks + after_create :generate_provider_account_key + before_destroy :destroyable? + before_validation :read_x509_files + + def destroyable? + instances.empty? + end + + def read_x509_files + self.x509_cert_pub = x509_cert_pub_file.read if x509_cert_pub_file.respond_to?(:read) + self.x509_cert_priv = x509_cert_priv_file.read if x509_cert_priv_file.respond_to?(:read) + end + + def connect + begin + return DeltaCloud.new(username, password, provider.url) + rescue Exception => e + logger.error("Error connecting to framework: #{e.message}") + logger.error("Backtrace: #{e.backtrace.join("\n")}") + return nil + end + end + + def self.find_or_create(account) + a = ProviderAccount.find_by_username_and_provider_id(account["username"], account["provider_id"]) + return a.nil? ? ProviderAccount.new(account) : a + end + + def pools + pools = [] + instances.each do |instance| + pools << instance.pool + end + end + + def name + label.blank? ? username : label + end + + # FIXME: for already-mapped accounts, update rather than add new + def populate_realms + client = connect + realms = client.realms + # FIXME: this should probably be in the same transaction as provider_account.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, + provider.id) + ar_realm = Realm.new(:external_key => realm.id, + :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 + end + + def valid_credentials? + DeltaCloud::valid_credentials?(username, password, provider.url) + end + + def build_credentials + xml = Nokogiri::XML <<EOT +<?xml version="1.0"?> +<provider_credentials> + <ec2_credentials> + <account_number></account_number> + <access_key></access_key> + <secret_access_key></secret_access_key> + <certificate></certificate> + <key></key> + </ec2_credentials> +</provider_credentials> +EOT + node = xml.at_xpath('/provider_credentials/ec2_credentials') + node.at_xpath('./account_number').content = account_number + node.at_xpath('./access_key').content = username + node.at_xpath('./secret_access_key').content = password + node.at_xpath('./certificate').content = x509_cert_pub + node.at_xpath('./key').content = x509_cert_priv + return xml.to_s + end + + private + def generate_provider_account_key + client = connect + if client.feature?(:instances, :authentication_key) + key = client.create_key(:name => "#{self.name}_#{Time.now.to_i}_key") + InstanceKey.create(:provider_account => self, :pem => key.pem, :name => key.id) if key + end + end + +end diff --git a/src/app/models/quota.rb b/src/app/models/quota.rb index 7081869..0a1000f 100644 --- a/src/app/models/quota.rb +++ b/src/app/models/quota.rb @@ -22,7 +22,7 @@ class Quota < ActiveRecord::Base
has_one :pool - has_one :cloud_account + has_one :provider_account has_one :user
validates_numericality_of :maximum_total_instances, @@ -49,8 +49,8 @@ class Quota < ActiveRecord::Base
RESOURCE_NAMES = [ RESOURCE_RUNNING_INSTANCES, RESOURCE_TOTAL_INSTANCES ]
- def self.can_create_instance?(instance, cloud_account) - [instance.owner, instance.pool, cloud_account].each do |parent| + def self.can_create_instance?(instance, provider_account) + [instance.owner, instance.pool, provider_account].each do |parent| if parent quota = Quota.find(parent.quota_id) potential_total_instances = quota.total_instances + 1 @@ -62,8 +62,8 @@ class Quota < ActiveRecord::Base return true end
- def self.can_start_instance?(instance, cloud_account) - [instance.owner, instance.pool, cloud_account].each do |parent| + def self.can_start_instance?(instance, provider_account) + [instance.owner, instance.pool, provider_account].each do |parent| if parent quota = Quota.find(parent.quota_id) potential_running_instances = quota.running_instances + 1 diff --git a/src/app/models/zone.rb b/src/app/models/zone.rb index bc823a6..cd49a90 100644 --- a/src/app/models/zone.rb +++ b/src/app/models/zone.rb @@ -24,7 +24,7 @@ class Zone < ActiveRecord::Base DEFAULT_ZONE_KEY = "default_zone"
has_many :pools, :dependent => :destroy - has_and_belongs_to_many :cloud_accounts + has_and_belongs_to_many :provider_accounts
validates_presence_of :name def self.default diff --git a/src/app/services/data_service_active_record.rb b/src/app/services/data_service_active_record.rb index 66da011..cb6072d 100644 --- a/src/app/services/data_service_active_record.rb +++ b/src/app/services/data_service_active_record.rb @@ -65,11 +65,11 @@ class DataServiceActiveRecord data_points = [] free_instances = 0
- cloud_accounts = CloudAccount.find(:all, :conditions => {:provider_id => provider.id}) - cloud_accounts.each do |cloud_account| - quota = cloud_account.quota + provider_accounts = ProviderAccount.find(:all, :conditions => {:provider_id => provider.id}) + provider_accounts.each do |provider_account| + quota = provider_account.quota if quota - data_points << TotalQuotaUsagePoint.new(cloud_account.username, quota.total_instances) + data_points << TotalQuotaUsagePoint.new(provider_account.username, quota.total_instances) free_instances += (quota.maximum_total_instances - quota.total_instances) end end @@ -175,11 +175,11 @@ class DataServiceActiveRecord instances = []
if parent.class == Provider - cloud_accounts = CloudAccount.find(:all, :conditions => {:provider_id => parent.id}) - cloud_accounts.each do |cloud_account| - instances.concat(cloud_account.instances) + provider_accounts = ProviderAccount.find(:all, :conditions => {:provider_id => parent.id}) + provider_accounts.each do |provider_account| + instances.concat(provider_account.instances) end - elsif parent.class == Pool || parent.class == CloudAccount + elsif parent.class == Pool || parent.class == ProviderAccount instances = parent.instances else return nil diff --git a/src/app/services/graph_service.rb b/src/app/services/graph_service.rb index 7266434..109455c 100644 --- a/src/app/services/graph_service.rb +++ b/src/app/services/graph_service.rb @@ -10,16 +10,16 @@ class GraphService
#if a specific cloud account is given, just return that cloud account's graph. #otherwise return all graphs user has permission to see. - if opts[:cloud_account] - cloud_account = opts[:cloud_account] - cloud_account_graphs = Hash.new - cloud_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = qos_failure_rate_graph(parent, opts = {}) - graphs[cloud_account] = cloud_account_graphs + if opts[:provider_account] + provider_account = opts[:provider_account] + provider_account_graphs = Hash.new + provider_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = qos_failure_rate_graph(parent, opts = {}) + graphs[provider_account] = provider_account_graphs else - CloudAccount.all.each do |cloud_account| - cloud_account_graphs = Hash.new - cloud_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = quota_instances_in_use_graph(cloud_account,opts) - graphs[cloud_account] = cloud_account_graphs + ProviderAccount.all.each do |provider_account| + provider_account_graphs = Hash.new + provider_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = quota_instances_in_use_graph(provider_account,opts) + graphs[provider_account] = provider_account_graphs end end graphs @@ -67,7 +67,7 @@ class GraphService def self.quota_usage_graph (parent, opts = {}) x = [1,2]
- #we'll just have zero values for the unexpected case where cloud_account has no quota + #we'll just have zero values for the unexpected case where provider_account has no quota y = x.collect { |v| 0 } if parent.quota quota = parent.quota @@ -126,7 +126,7 @@ class GraphService providers = Provider.all providers.each do |provider| running_instances = 0 - provider.cloud_accounts.each do |account| + provider.provider_accounts.each do |account| running_instances = running_instances + account.quota.running_instances if account.quota end if running_instances > 0 diff --git a/src/app/util/condormatic.rb b/src/app/util/condormatic.rb index 74c5a80..20aee78 100644 --- a/src/app/util/condormatic.rb +++ b/src/app/util/condormatic.rb @@ -59,7 +59,7 @@ def condormatic_instance_create(task) requirements += " && realm == "#{realm.id}"" if realm != nil # We may need to add some stuff to the provider classads like pool id, provider id etc. This is mostly just # to test and make sure this works for now. - requirements += " && deltacloud_quota_check("#{job_name}", other.cloud_account_id)" + requirements += " && deltacloud_quota_check("#{job_name}", other.provider_account_id)" requirements += "\n"
pipe.puts requirements @@ -205,7 +205,7 @@ def condormatic_classads_sync
Rails.logger.info "Syncing classads.." providers.each do |provider| - provider.cloud_accounts.each do |account| + provider.provider_accounts.each do |account| provider.replicated_images.each do |replicated_image| # The replicated image entry gets put in the database as soon as we ask # to have the image built, so we only want to generate classads for it if @@ -230,7 +230,7 @@ def condormatic_classads_sync pipe.puts "provider_url="#{account.provider.url}"" pipe.puts "username="#{account.username}"" pipe.puts "password="#{account.password}"" - pipe.puts "cloud_account_id="#{account.id}"" + pipe.puts "provider_account_id="#{account.id}"" pipe.puts "keypair="#{escape(account.instance_key.name)}"" pipe.close_write
diff --git a/src/app/views/cloud_accounts/_form.haml b/src/app/views/cloud_accounts/_form.haml deleted file mode 100644 index 192ce05..0000000 --- a/src/app/views/cloud_accounts/_form.haml +++ /dev/null @@ -1,52 +0,0 @@ -= error_messages_for 'cloud_account' -%fieldset.clearfix.nomargin - %label.grid_4.la.alpha - = t('.account_name') - %span.required * - %label.grid_3.la - = t('.user_name') - %span.required * - %label.grid_3.la - = t('.password') - %span.required * - %label.grid_3.la.omega - = t('.quota_instances') - %span.required * -%fieldset.nomargin.clearfix - = f.text_field :label, :title => t('.account_name'), :class => "grid_4 alpha" - = f.text_field :username, :title => t('.user_name'), :class => "grid_3" - = f.password_field :password, :title => t('.password'), :class => "grid_3" - = text_field "quota", :maximum_running_instances, :title => t('.quota_instances'), :value => "unlimited",:id => "quota_instances", :class => "grid_3 omega" -%fieldset.nomargin.clearfix - .grid_3.prefix_10.alpha.omega - ( - %button.linkbutton.nospace{ :type => 'button', :onclick => "set_unlimited_quota("quota_instances");" }<> - = t('.unlimited_quota') - ) -%fieldset.clearfix.nomargin - %label.grid_4.la.alpha - = t('.account_number') - %span.required * - %label.grid_3.la - = t('.account_private_cert') - %span.required * - %label.grid_3.la - = t('.account_public_cert') - %span.required * - .grid_3.omega -%fieldset.clearfix.nomargin - = f.text_field :account_number, :title => t('.account_number'), :class => "grid_4 alpha" - .grid_3 - = f.file_field :x509_cert_priv_file, :title => t('.account_private_cert') - .grid_3 - = f.file_field :x509_cert_pub_file, :title => t('.account_public_cert') - .grid_3.omega - ( - %button.linkbutton.nospace{ :type => 'submit', :value => t('.test_account'), :name => 'test_account', :id => 'test_account' }<> - = t('.test_account') - ) - -:javascript - function set_unlimited_quota(elem_id) { - $("#" + elem_id)[0].value = "unlimited"; - } diff --git a/src/app/views/cloud_accounts/edit.haml b/src/app/views/cloud_accounts/edit.haml deleted file mode 100644 index c97faac..0000000 --- a/src/app/views/cloud_accounts/edit.haml +++ /dev/null @@ -1,17 +0,0 @@ -= render :partial => 'providers/providers' -#details.grid_13 - %nav.subsubnav - = render_navigation(:level => 4) - - %h2 - = t('.edit_provider_account') - - form_for @cloud_account, :url => provider_account_path(@provider, @cloud_account), :html => { :method => :put, :multipart => true } do |f| - = render :partial => 'form', :locals => { :f => f } - %fieldset.clearfix - .grid_13.alpha.omega - = submit_tag t(:edit), :class => "ra nomargin dialogbutton" - %section - %p.requirement - %span.required * - - - = t('.required_field') diff --git a/src/app/views/cloud_accounts/index.haml b/src/app/views/cloud_accounts/index.haml deleted file mode 100644 index ab2d475..0000000 --- a/src/app/views/cloud_accounts/index.haml +++ /dev/null @@ -1,25 +0,0 @@ -= render :partial => 'providers/providers' -#details.grid_13 - %nav.subsubnav - = render_navigation(:level => 4) - %h2 - = t('.provider_accounts') - - unless @provider.cloud_accounts.empty? - %table - %thead - %tr - %th{:scope => "col"} Label - %th{:scope => "col"} Username - %th{:scope => "col"} Account Number - %th{:scope => "col", :colspan => "2"} Actions - %tbody - - @provider.cloud_accounts.each do |cloud_account| - %tr - %td= cloud_account.label - %td= cloud_account.username - %td= cloud_account.account_number - %td= link_to 'Edit', edit_provider_account_path(@provider, cloud_account) - %td= link_to 'Delete', destroy_providers_account_path(@provider, cloud_account), :confirm => 'Are you sure?' - - - if @provider.cloud_accounts.empty? - = link_to 'Add', new_provider_account_path(@provider.id), :class => 'button' diff --git a/src/app/views/cloud_accounts/new.haml b/src/app/views/cloud_accounts/new.haml deleted file mode 100644 index 96d08df..0000000 --- a/src/app/views/cloud_accounts/new.haml +++ /dev/null @@ -1,17 +0,0 @@ -= render :partial => 'providers/providers' -#details.grid_13 - %nav.subsubnav - = render_navigation(:level => 4) - - %h2 - = t('.new_provider_account') - - form_for @cloud_account, :url => provider_accounts_path(@provider), :html => { :multipart => true } do |f| - = render :partial => 'form', :locals => { :f => f } - %fieldset.clearfix - .grid_13.alpha.omega - = submit_tag t(:add), :class => "ra nomargin dialogbutton" - %section - %p.requirement - %span.required * - - - = t('.required_field') diff --git a/src/app/views/dashboard/summary.haml b/src/app/views/dashboard/summary.haml index e6ba2dd..03e2843 100644 --- a/src/app/views/dashboard/summary.haml +++ b/src/app/views/dashboard/summary.haml @@ -80,7 +80,7 @@ .count= @providers.size %li Accounts - .count= @cloud_accounts.size + .count= @provider_accounts.size %li Pools .count= @pools.size @@ -107,11 +107,11 @@ Running %img{:src => "images/quota_usage_key_instances_limit.png", :width => 10, :heigth => 10} Limit - - @cloud_accounts.each do |account| + - @provider_accounts.each do |account| .account_quota_usage_graph_summary = account.provider.name + ": " + account.name .account_quota_usage_current_graph - %object{ :data => url_for(:action => :quota_usage_graph, :cloud_account_id => account.id, :resource_name => Quota::RESOURCE_RUNNING_INSTANCES, :width => 100, :height => 50), :type => 'image/svg+xml'} + %object{ :data => url_for(:action => :quota_usage_graph, :provider_account_id => account.id, :resource_name => Quota::RESOURCE_RUNNING_INSTANCES, :width => 100, :height => 50), :type => 'image/svg+xml'} <div style="clear: both;" />
:javascript diff --git a/src/app/views/instances/index.haml b/src/app/views/instances/index.haml index 9c2efb8..e36ba75 100644 --- a/src/app/views/instances/index.haml +++ b/src/app/views/instances/index.haml @@ -123,5 +123,5 @@ %td= inst.hardware_profile.name %td= inst.template.name %td= inst.public_addresses - %td= inst.cloud_account ? inst.cloud_account.provider.name : '' + %td= inst.provider_account ? inst.provider_account.provider.name : '' %td= owner_name(inst) diff --git a/src/app/views/instances/show.haml b/src/app/views/instances/show.haml index 33b2897..7eab76e 100644 --- a/src/app/views/instances/show.haml +++ b/src/app/views/instances/show.haml @@ -18,7 +18,7 @@ %span= "#{@instance.template.xml.platform} #{@instance.template.xml.platform_version}" %li = label_tag :provider, 'Provider' - %span= @instance.cloud_account.provider.name if @instance.cloud_account + %span= @instance.provider_account.provider.name if @instance.provider_account %li = label_tag :base_template, 'Base Template' %span= @instance.template.name diff --git a/src/app/views/provider_accounts/_form.haml b/src/app/views/provider_accounts/_form.haml new file mode 100644 index 0000000..ad6e777 --- /dev/null +++ b/src/app/views/provider_accounts/_form.haml @@ -0,0 +1,52 @@ += error_messages_for 'provider_account' +%fieldset.clearfix.nomargin + %label.grid_4.la.alpha + = t('.account_name') + %span.required * + %label.grid_3.la + = t('.user_name') + %span.required * + %label.grid_3.la + = t('.password') + %span.required * + %label.grid_3.la.omega + = t('.quota_instances') + %span.required * +%fieldset.nomargin.clearfix + = f.text_field :label, :title => t('.account_name'), :class => "grid_4 alpha" + = f.text_field :username, :title => t('.user_name'), :class => "grid_3" + = f.password_field :password, :title => t('.password'), :class => "grid_3" + = text_field "quota", :maximum_running_instances, :title => t('.quota_instances'), :value => "unlimited",:id => "quota_instances", :class => "grid_3 omega" +%fieldset.nomargin.clearfix + .grid_3.prefix_10.alpha.omega + ( + %button.linkbutton.nospace{ :type => 'button', :onclick => "set_unlimited_quota("quota_instances");" }<> + = t('.unlimited_quota') + ) +%fieldset.clearfix.nomargin + %label.grid_4.la.alpha + = t('.account_number') + %span.required * + %label.grid_3.la + = t('.account_private_cert') + %span.required * + %label.grid_3.la + = t('.account_public_cert') + %span.required * + .grid_3.omega +%fieldset.clearfix.nomargin + = f.text_field :account_number, :title => t('.account_number'), :class => "grid_4 alpha" + .grid_3 + = f.file_field :x509_cert_priv_file, :title => t('.account_private_cert') + .grid_3 + = f.file_field :x509_cert_pub_file, :title => t('.account_public_cert') + .grid_3.omega + ( + %button.linkbutton.nospace{ :type => 'submit', :value => t('.test_account'), :name => 'test_account', :id => 'test_account' }<> + = t('.test_account') + ) + +:javascript + function set_unlimited_quota(elem_id) { + $("#" + elem_id)[0].value = "unlimited"; + } diff --git a/src/app/views/provider_accounts/edit.haml b/src/app/views/provider_accounts/edit.haml new file mode 100644 index 0000000..fc91383 --- /dev/null +++ b/src/app/views/provider_accounts/edit.haml @@ -0,0 +1,17 @@ += render :partial => 'providers/providers' +#details.grid_13 + %nav.subsubnav + = render_navigation(:level => 4) + + %h2 + = t('.edit_provider_account') + - form_for @provider_account, :url => provider_account_path(@provider, @provider_account), :html => { :method => :put, :multipart => true } do |f| + = render :partial => 'form', :locals => { :f => f } + %fieldset.clearfix + .grid_13.alpha.omega + = submit_tag t(:edit), :class => "ra nomargin dialogbutton" + %section + %p.requirement + %span.required * + - + = t('.required_field') diff --git a/src/app/views/provider_accounts/index.haml b/src/app/views/provider_accounts/index.haml new file mode 100644 index 0000000..7610666 --- /dev/null +++ b/src/app/views/provider_accounts/index.haml @@ -0,0 +1,25 @@ += render :partial => 'providers/providers' +#details.grid_13 + %nav.subsubnav + = render_navigation(:level => 4) + %h2 + = t('.provider_accounts') + - unless @provider.provider_accounts.empty? + %table + %thead + %tr + %th{:scope => "col"} Label + %th{:scope => "col"} Username + %th{:scope => "col"} Account Number + %th{:scope => "col", :colspan => "2"} Actions + %tbody + - @provider.provider_accounts.each do |provider_account| + %tr + %td= provider_account.label + %td= provider_account.username + %td= provider_account.account_number + %td= link_to 'Edit', edit_provider_account_path(@provider, provider_account) + %td= link_to 'Delete', destroy_providers_account_path(@provider, provider_account), :confirm => 'Are you sure?' + + - if @provider.provider_accounts.empty? + = link_to 'Add', new_provider_account_path(@provider.id), :class => 'button' diff --git a/src/app/views/provider_accounts/new.haml b/src/app/views/provider_accounts/new.haml new file mode 100644 index 0000000..5cd151f --- /dev/null +++ b/src/app/views/provider_accounts/new.haml @@ -0,0 +1,17 @@ += render :partial => 'providers/providers' +#details.grid_13 + %nav.subsubnav + = render_navigation(:level => 4) + + %h2 + = t('.new_provider_account') + - form_for @provider_account, :url => provider_accounts_path(@provider), :html => { :multipart => true } do |f| + = render :partial => 'form', :locals => { :f => f } + %fieldset.clearfix + .grid_13.alpha.omega + = submit_tag t(:add), :class => "ra nomargin dialogbutton" + %section + %p.requirement + %span.required * + - + = t('.required_field') diff --git a/src/app/views/providers/accounts.haml b/src/app/views/providers/accounts.haml index f6f9c84..f1edca6 100644 --- a/src/app/views/providers/accounts.haml +++ b/src/app/views/providers/accounts.haml @@ -9,9 +9,9 @@
%h1 = t('.provider_accounts') - - form_tag ({:controller => 'cloud_accounts', :action => 'update_accounts'}), :multipart => true do + - form_tag ({:controller => 'provider_accounts', :action => 'update_accounts'}), :multipart => true do = hidden_field :provider, :id, :value => @provider.id - - @provider.cloud_accounts.each do |acct| + - @provider.provider_accounts.each do |acct| %fieldset.clearfix.nomargin %label.grid_4.la.alpha = t('.account_name') @@ -27,10 +27,10 @@ %span.required * %fieldset.nomargin.clearfix - disabled = 'disabled' unless has_account_modify?(@provider) - - cloud_account_id = "cloud_accounts[#{acct.id}]" - = text_field cloud_account_id, :label, :title => t('.account_name'), :value => acct.label, :disabled => disabled, :class => "grid_4 alpha" - = text_field cloud_account_id, :username, :title => t('.user_name'), :value => acct.username, :disabled => disabled, :class => "grid_3" - = password_field cloud_account_id, :password, :title => t('.password'), :disabled => disabled, :class => "grid_3" + - provider_account_id = "provider_accounts[#{acct.id}]" + = text_field provider_account_id, :label, :title => t('.account_name'), :value => acct.label, :disabled => disabled, :class => "grid_4 alpha" + = text_field provider_account_id, :username, :title => t('.user_name'), :value => acct.username, :disabled => disabled, :class => "grid_3" + = password_field provider_account_id, :password, :title => t('.password'), :disabled => disabled, :class => "grid_3" = error_message_on :maximum_running_instances, 'Maximum Running Instances ' = text_field "quota[#{acct.id}]", :maximum_running_instances, :title => t('.quota_instances'), :value => (acct.quota.maximum_running_instances.nil? ? "unlimited" : acct.quota.maximum_running_instances), :disabled => disabled, :id => "quota_instances#{acct.id}", :class => "grid_3 omega" %fieldset.nomargin.clearfix @@ -51,23 +51,23 @@ %span.required * .grid_3.omega %fieldset.clearfix - = text_field cloud_account_id, :account_number, :title => t('.account_number'), :value => acct.account_number, :disabled => disabled, :class => "grid_4 alpha" + = text_field provider_account_id, :account_number, :title => t('.account_number'), :value => acct.account_number, :disabled => disabled, :class => "grid_4 alpha" .grid_3 - = file_field cloud_account_id, :x509_cert_priv_file, :title => t('.account_private_cert'), :disabled => disabled + = file_field provider_account_id, :x509_cert_priv_file, :title => t('.account_private_cert'), :disabled => disabled .grid_3 - = file_field cloud_account_id, :x509_cert_pub_file, :title => t('.account_public_cert'), :disabled => disabled - - remove_path = url_for :controller => 'cloud_accounts', :action => 'destroy', :id => acct.id if has_account_modify?(@provider) && acct.destroyable? + = file_field provider_account_id, :x509_cert_pub_file, :title => t('.account_public_cert'), :disabled => disabled + - remove_path = url_for :controller => 'provider_accounts', :action => 'destroy', :id => acct.id if has_account_modify?(@provider) && acct.destroyable? .grid_3.omega %a.button{ :href => remove_path, :name => "remove_acc_#{acct.id}", :class => "tiny #{'disabled' unless remove_path}" } = t(:remove) %fieldset.clearfix.gap - = link_to t(:reset), {:controller => 'provider', :action => 'accounts', :id => @provider.id}, :class => "button dialogbutton" unless @provider.cloud_accounts.empty? - = submit_tag t(:save), :name => 'update_cloud_accounts', :class => "dialogbutton" unless @provider.cloud_accounts.empty? + = link_to t(:reset), {:controller => 'provider', :action => 'accounts', :id => @provider.id}, :class => "button dialogbutton" unless @provider.provider_accounts.empty? + = submit_tag t(:save), :name => 'update_provider_accounts', :class => "dialogbutton" unless @provider.provider_accounts.empty?
%h2 = t('.new_provider_account') - - form_tag({:controller => 'cloud_accounts', :action => 'create'}, :multipart => true) do - = hidden_field :cloud_account, :provider_id, :value => @provider.id + - form_tag({:controller => 'provider_accounts', :action => 'create'}, :multipart => true) do + = hidden_field :provider_account, :provider_id, :value => @provider.id %fieldset.clearfix.nomargin %label.grid_4.la.alpha = t('.account_name') @@ -82,9 +82,9 @@ = t('.quota_instances') %span.required * %fieldset.nomargin.clearfix - = text_field :cloud_account, :label, :title => t('.account_name'), :class => "grid_4 alpha" - = text_field :cloud_account, :username, :title => t('.user_name'), :class => "grid_3" - = password_field :cloud_account, :password, :title => t('.password'), :class => "grid_3" + = text_field :provider_account, :label, :title => t('.account_name'), :class => "grid_4 alpha" + = text_field :provider_account, :username, :title => t('.user_name'), :class => "grid_3" + = password_field :provider_account, :password, :title => t('.password'), :class => "grid_3" = text_field "quota", :maximum_running_instances, :title => t('.quota_instances'), :value => "unlimited",:id => "quota_instances", :class => "grid_3 omega" %fieldset.nomargin.clearfix .grid_3.prefix_10.alpha.omega @@ -104,12 +104,12 @@ %span.required * .grid_3.omega %fieldset.clearfix.nomargin - = text_field :cloud_account, :account_number, :title => t('.account_number'), :class => "grid_4 alpha" + = text_field :provider_account, :account_number, :title => t('.account_number'), :class => "grid_4 alpha" .grid_3 - = file_field :cloud_account, :x509_cert_priv_file, :title => t('.account_private_cert') + = file_field :provider_account, :x509_cert_priv_file, :title => t('.account_private_cert') .grid_3 - = file_field :cloud_account, :x509_cert_pub_file, :title => t('.account_public_cert') - - remove_path = url_for :controller => 'cloud_accounts', :action => 'destroy' + = file_field :provider_account, :x509_cert_pub_file, :title => t('.account_public_cert') + - remove_path = url_for :controller => 'provider_accounts', :action => 'destroy' .grid_3.omega ( %button.linkbutton.nospace{ :type => 'submit', :value => t('.test_account'), :name => 'test_account', :id => 'test_account' }<> diff --git a/src/classad_plugin/classad_plugin.rb b/src/classad_plugin/classad_plugin.rb index 2aabfb9..b6297b3 100644 --- a/src/classad_plugin/classad_plugin.rb +++ b/src/classad_plugin/classad_plugin.rb @@ -5,7 +5,7 @@ require 'permissioned_object' require 'authlogic' require 'user' require 'instance' -require 'cloud_account' +require 'provider_account' require 'pool' require 'quota'
@@ -60,16 +60,16 @@ def classad_plugin(logf, conf_path, instance_key, account_id) instance = Instance.find(:first, :conditions => [ "condor_job_id = ?", instance_key ]) logf.puts "getting cloud account from id #{account_id}" - cloud_account = CloudAccount.find(:first, + provider_account = ProviderAccount.find(:first, :conditions => [ "id = ?", account_id ])
- logf.puts "instance is: #{instance}, cloud account is #{cloud_account}" + logf.puts "instance is: #{instance}, cloud account is #{provider_account}"
return false if instance.nil? - return false if cloud_account.nil? + return false if provider_account.nil?
logf.puts "checking quota.." - ret = Quota.can_start_instance?(instance, cloud_account) + ret = Quota.can_start_instance?(instance, provider_account) logf.puts "After checking quota, ret is #{ret}"
logf.puts "Disconnecting from the database" diff --git a/src/config/environment.rb b/src/config/environment.rb index 7d8ba2c..c3cad8b 100644 --- a/src/config/environment.rb +++ b/src/config/environment.rb @@ -51,7 +51,7 @@ Rails::Initializer.run do |config| config.gem "compass-960-plugin", :lib => "ninesixty" config.gem "simple-navigation" config.gem "typhoeus" - config.gem "rb-inotify" +# config.gem "rb-inotify"
config.active_record.observers = :instance_observer, :task_observer # Only load the plugins named here, in the order given. By default, all plugins diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml index 1be36b6..6d71fd3 100644 --- a/src/config/locales/en.yml +++ b/src/config/locales/en.yml @@ -97,7 +97,7 @@ en: test_connection: Test Connection required_field: Required field. caution_image: Caution - cloud_accounts: + provider_accounts: index: provider_accounts: Provider Accounts new: diff --git a/src/config/navigation.rb b/src/config/navigation.rb index 95d5e05..82ad1cb 100644 --- a/src/config/navigation.rb +++ b/src/config/navigation.rb @@ -9,7 +9,7 @@ SimpleNavigation::Configuration.run do |navigation| second_level.item :system_settings, t(:system_settings), :controller => 'settings' do |third_level| third_level.item :manage_providers, t(:manage_providers), providers_path do |fourth_level| fourth_level.item :provider_summary, t(:provider_summary), { :controller => 'providers', :action => 'show', :id => (@provider.id if @provider) }, :highlights_on => //providers/\d+(/edit)?$/ - fourth_level.item :provider_accounts, t(:provider_accounts), { :controller => 'cloud_accounts', :action => 'index', :provider_id => (@provider.id if @provider) }, :highlights_on => //providers/\d+/accounts(/(\d+|new))?/ + fourth_level.item :provider_accounts, t(:provider_accounts), { :controller => 'provider_accounts', :action => 'index', :provider_id => (@provider.id if @provider) }, :highlights_on => //providers/\d+/accounts(/(\d+|new))?/ fourth_level.item :scheduling_policies, t(:scheduling_policies), '#' fourth_level.item :services_provided, t(:services_provided), '#' fourth_level.item :map_profiles, t(:map_profiles), '#' diff --git a/src/config/routes.rb b/src/config/routes.rb index 931c97f..17afc4b 100644 --- a/src/config/routes.rb +++ b/src/config/routes.rb @@ -53,9 +53,9 @@ ActionController::Routing::Routes.draw do |map| # Temporarily disable this route, provider stuff is not restful yet. # Will be re-enabled in upcoming patch map.resources :providers do |provider| - provider.resources :accounts, :controller => 'cloud_accounts' + provider.resources :accounts, :controller => 'provider_accounts' end - map.destroy_providers_account '/providers/:provider_id/accounts/:id/destroy', :controller => 'cloud_accounts', :action => 'destroy', :conditions => { :method => :get } + map.destroy_providers_account '/providers/:provider_id/accounts/:id/destroy', :controller => 'provider_accounts', :action => 'destroy', :conditions => { :method => :get }
# Allow downloading Web Service WSDL as a file with an extension # instead of a file named 'wsdl' diff --git a/src/db/development_structure.sql b/src/db/development_structure.sql new file mode 100644 index 0000000..ebdbb85 --- /dev/null +++ b/src/db/development_structure.sql @@ -0,0 +1,79 @@ +CREATE TABLE "base_permission_objects" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "hardware_profile_map" ("aggregator_hardware_profile_id" integer, "provider_hardware_profile_id" integer); +CREATE TABLE "hardware_profile_properties" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "kind" varchar(255) NOT NULL, "unit" varchar(255) NOT NULL, "value" varchar(255) NOT NULL, "range_first" varchar(255), "range_last" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "hardware_profiles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "external_key" varchar(255) NOT NULL, "name" varchar(1024) NOT NULL, "memory_id" integer, "storage_id" integer, "cpu_id" integer, "architecture_id" integer, "provider_id" integer, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "images" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "uuid" varchar(255), "name" varchar(255) NOT NULL, "build_id" varchar(255), "uri" varchar(255), "status" varchar(255), "target" varchar(255), "template_id" integer, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "instance_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "instance_id" integer NOT NULL, "event_type" varchar(255) NOT NULL, "event_time" datetime, "status" varchar(255), "message" varchar(255), "created_at" datetime, "updated_at" datetime); +CREATE TABLE "instance_keys" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "provider_account_id" integer NOT NULL, "name" varchar(255) NOT NULL, "pem" text, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "instances" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "external_key" varchar(255), "name" varchar(1024) NOT NULL, "hardware_profile_id" integer NOT NULL, "template_id" integer NOT NULL, "realm_id" integer, "owner_id" integer, "pool_id" integer NOT NULL, "provider_account_id" integer, "public_addresses" varchar(255), "private_addresses" varchar(255), "state" varchar(255), "condor_job_id" varchar(255), "last_error" text(255), "instance_key_id" integer, "lock_version" integer DEFAULT 0, "acc_pending_time" integer DEFAULT 0, "acc_running_time" integer DEFAULT 0, "acc_shutting_down_time" integer DEFAULT 0, "acc_stopped_time" integer DEFAULT 0, "time_last_pending" datetime, "time_last_running" datetime, "time_last_shutting_down" datetime, "time_last_stopped" datetime, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "metadata_objects" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "key" varchar(255) NOT NULL, "value" varchar(255) NOT NULL, "object_type" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "permissions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "role_id" integer NOT NULL, "user_id" integer NOT NULL, "permission_object_id" integer, "permission_object_type" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "pools" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "exported_as" varchar(255), "quota_id" integer, "zone_id" integer NOT NULL, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "privileges" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "privileges_roles" ("privilege_id" integer NOT NULL, "role_id" integer NOT NULL); +CREATE TABLE "property_enum_entries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "hardware_profile_property_id" integer NOT NULL, "value" varchar(255) NOT NULL, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "provider_accounts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "label" varchar(255) NOT NULL, "username" varchar(255) NOT NULL, "password" varchar(255) NOT NULL, "provider_id" integer NOT NULL, "quota_id" integer, "lock_version" integer DEFAULT 0, "account_number" varchar(255) NOT NULL, "x509_cert_priv" text NOT NULL, "x509_cert_pub" text NOT NULL, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "provider_accounts_zones" ("provider_account_id" integer NOT NULL, "zone_id" integer NOT NULL); +CREATE TABLE "providers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "cloud_type" varchar(255) NOT NULL, "url" varchar(255) NOT NULL, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "quotas" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "running_instances" integer DEFAULT 0, "total_instances" integer DEFAULT 0, "maximum_running_instances" integer, "maximum_total_instances" integer, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "realm_map" ("frontend_realm_id" integer, "backend_realm_id" integer); +CREATE TABLE "realms" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "external_key" varchar(255) NOT NULL, "name" varchar(1024) NOT NULL, "provider_id" integer, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "replicated_images" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "image_id" integer NOT NULL, "provider_id" integer NOT NULL, "provider_image_key" varchar(255), "uploaded" boolean DEFAULT 'f', "registered" boolean DEFAULT 'f'); +CREATE TABLE "roles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "scope" varchar(255) NOT NULL, "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); +CREATE TABLE "sessions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "session_id" varchar(255) NOT NULL, "data" text, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user" varchar(255), "type" varchar(255), "action" varchar(255), "state" varchar(255), "task_target_id" integer, "task_target_type" varchar(255), "args" varchar(255), "created_at" datetime, "time_submitted" datetime, "time_started" datetime, "time_ended" datetime, "message" text, "failure_code" varchar(255), "lock_version" integer DEFAULT 0); +CREATE TABLE "templates" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "uuid" varchar(255) NOT NULL, "xml" blob NOT NULL, "uri" varchar(255), "name" varchar(255), "platform" varchar(255), "platform_version" varchar(255), "architecture" varchar(255), "summary" text, "complete" boolean DEFAULT 'f', "uploaded" boolean DEFAULT 'f', "images_count" integer, "created_at" datetime, "updated_at" datetime); +CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "login" varchar(255) NOT NULL, "email" varchar(255) NOT NULL, "crypted_password" varchar(255) NOT NULL, "password_salt" varchar(255) NOT NULL, "persistence_token" varchar(255) NOT NULL, "single_access_token" varchar(255) NOT NULL, "perishable_token" varchar(255) NOT NULL, "first_name" varchar(255), "last_name" varchar(255), "quota_id" integer, "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "created_at" datetime, "updated_at" datetime); +CREATE TABLE "zones" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "description" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime); +CREATE INDEX "index_sessions_on_session_id" ON "sessions" ("session_id"); +CREATE INDEX "index_sessions_on_updated_at" ON "sessions" ("updated_at"); +CREATE INDEX "index_users_on_last_request_at" ON "users" ("last_request_at"); +CREATE INDEX "index_users_on_login" ON "users" ("login"); +CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token"); +CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); +INSERT INTO schema_migrations (version) VALUES ('200909011700'); + +INSERT INTO schema_migrations (version) VALUES ('20090731200741'); + +INSERT INTO schema_migrations (version) VALUES ('20090801045212'); + +INSERT INTO schema_migrations (version) VALUES ('20090802000000'); + +INSERT INTO schema_migrations (version) VALUES ('20090803000000'); + +INSERT INTO schema_migrations (version) VALUES ('20090803141507'); + +INSERT INTO schema_migrations (version) VALUES ('20090804135630'); + +INSERT INTO schema_migrations (version) VALUES ('20090804140143'); + +INSERT INTO schema_migrations (version) VALUES ('20090804141600'); + +INSERT INTO schema_migrations (version) VALUES ('20090804142049'); + +INSERT INTO schema_migrations (version) VALUES ('20090831140000'); + +INSERT INTO schema_migrations (version) VALUES ('20090917192602'); + +INSERT INTO schema_migrations (version) VALUES ('20091008153046'); + +INSERT INTO schema_migrations (version) VALUES ('20091008153058'); + +INSERT INTO schema_migrations (version) VALUES ('20091008153106'); + +INSERT INTO schema_migrations (version) VALUES ('20091019215838'); + +INSERT INTO schema_migrations (version) VALUES ('20100707000000'); + +INSERT INTO schema_migrations (version) VALUES ('20100810221250'); + +INSERT INTO schema_migrations (version) VALUES ('20100830150014'); + +INSERT INTO schema_migrations (version) VALUES ('20100902081651'); + +INSERT INTO schema_migrations (version) VALUES ('20101018174458'); + +INSERT INTO schema_migrations (version) VALUES ('20101021172441'); + +INSERT INTO schema_migrations (version) VALUES ('20101126125706'); \ No newline at end of file diff --git a/src/db/migrate/20101126125706_rename_cloud_account_to_provider_account.rb b/src/db/migrate/20101126125706_rename_cloud_account_to_provider_account.rb new file mode 100644 index 0000000..e551350 --- /dev/null +++ b/src/db/migrate/20101126125706_rename_cloud_account_to_provider_account.rb @@ -0,0 +1,17 @@ +class RenameCloudAccountToProviderAccount < ActiveRecord::Migration + def self.up + rename_table :cloud_accounts, :provider_accounts + rename_column :cloud_accounts_zones, :cloud_account_id, :provider_account_id + rename_table :cloud_accounts_zones, :provider_accounts_zones + rename_column :instances, :cloud_account_id, :provider_account_id + rename_column :instance_keys, :cloud_account_id, :provider_account_id + end + + def self.down + rename_table :provider_accounts, :cloud_accounts + rename_column :provider_accounts_zones, :provider_account_id, :cloud_account_id + rename_table :provider_accounts_zones, :cloud_accounts_zones + rename_column :instances, :provider_account_id, :cloud_account_id + rename_column :instance_keys, :provider_account_id, :cloud_account_id + end +end diff --git a/src/dbomatic/dbomatic b/src/dbomatic/dbomatic index 8a3e968..406388d 100755 --- a/src/dbomatic/dbomatic +++ b/src/dbomatic/dbomatic @@ -203,18 +203,18 @@ class CondorEventLog < Nokogiri::XML::SAX::Document return end
- cloud_account = CloudAccount.find(:first, :conditions => ['provider_id = ? AND username = ? AND password = ?', provider.id, username, password]) - if cloud_account.nil? + provider_account = ProviderAccount.find(:first, :conditions => ['provider_id = ? AND username = ? AND password = ?', provider.id, username, password]) + if provider_account.nil? @logger.error "Could not find the cloud account corresponding to #{link}, skipping cloud id update" return end
- inst.cloud_account_id = cloud_account.id + inst.provider_account_id = provider_account.id
# FIXME: we are updating the instance_key_id here, but this is really not # the right way or place to do this. This will have to be revisited when # we come up with a real key management architecture - inst.instance_key_id = cloud_account.instance_key.id + inst.instance_key_id = provider_account.instance_key.id
inst.save! end diff --git a/src/features/provider.feature b/src/features/provider.feature index 8cf2ccd..8f5ae57 100644 --- a/src/features/provider.feature +++ b/src/features/provider.feature @@ -66,10 +66,10 @@ Feature: Manage Providers And I follow "provider1" And I follow "Provider Accounts" And I follow "Add" within "#details" - And I fill in "cloud_account[label]" with "MockAccount" - And I fill in "cloud_account[username]" with "mockuser" - And I fill in "cloud_account[password]" with "mockpassword" - And I fill in "cloud_account[account_number]" with "12345678" + And I fill in "provider_account[label]" with "MockAccount" + And I fill in "provider_account[username]" with "mockuser" + And I fill in "provider_account[password]" with "mockpassword" + And I fill in "provider_account[account_number]" with "12345678" And I press "test_account" Then I should see "Test Connection Success: Valid Account Details"
@@ -82,10 +82,10 @@ Feature: Manage Providers And I follow "provider1" And I follow "Provider Accounts" And I follow "Add" within "#details" - And I fill in "cloud_account[label]" with "IncorrectAccount" - And I fill in "cloud_account[username]" with "incorrect_user" - And I fill in "cloud_account[password]" with "incorrect_password" - And I fill in "cloud_account[account_number]" with "12345678" + And I fill in "provider_account[label]" with "IncorrectAccount" + And I fill in "provider_account[username]" with "incorrect_user" + And I fill in "provider_account[password]" with "incorrect_password" + And I fill in "provider_account[account_number]" with "12345678" And I press "test_account" Then I should see "Test Connection Failed: Invalid Account Details"
diff --git a/src/features/step_definitions/pool_steps.rb b/src/features/step_definitions/pool_steps.rb index 5643f48..0aaa4bc 100644 --- a/src/features/step_definitions/pool_steps.rb +++ b/src/features/step_definitions/pool_steps.rb @@ -24,13 +24,13 @@ Given /^the Pool has the following Hardware Profiles:$/ do |table| end
Given /^the Pool has the following Realms named "([^"]*)"$/ do |names| - @cloud_account = Factory :mock_cloud_account - @provider = @cloud_account.provider + @provider_account = Factory :mock_provider_account + @provider = @provider_account.provider
names.split(", ").each do |name| @pool.realms << Factory(:realm, :name => name, :provider => @provider) end - @pool.cloud_accounts << @cloud_account + @pool.provider_accounts << @provider_account
end
diff --git a/src/features/support/custom.rb b/src/features/support/custom.rb index b5440ae..4136e49 100644 --- a/src/features/support/custom.rb +++ b/src/features/support/custom.rb @@ -27,11 +27,11 @@ Provider.class_eval do
end
-CloudAccount.class_eval do - - alias :generate_cloud_account_key_original :generate_cloud_account_key +ProviderAccount.class_eval do
- def generate_cloud_account_key + alias :generate_provider_account_key_original :generate_provider_account_key + + def generate_provider_account_key end
# def instance_key diff --git a/src/image_builder_service/image_builder_service b/src/image_builder_service/image_builder_service index 0ffb74d..35099b0 100755 --- a/src/image_builder_service/image_builder_service +++ b/src/image_builder_service/image_builder_service @@ -121,7 +121,7 @@ class ImageBuilderService # FIXME: this should be contained elsewhere (probably Image model) so we # can keep logic out of here. Also, this currently only handles one # account, we will need to be able to specify at some point. - creds = image.replicated_images.first.provider.cloud_accounts.first.build_credentials + creds = image.replicated_images.first.provider.provider_accounts.first.build_credentials #TODO: switch this back to uri once ActiveBuild retrieves it properly ab = @console.build_image(image.template.xml.to_xml, image.target, image.uuid, creds) if ab diff --git a/src/lib/tasks/demo_data.rake b/src/lib/tasks/demo_data.rake index f38ebbd..2f6fc35 100644 --- a/src/lib/tasks/demo_data.rake +++ b/src/lib/tasks/demo_data.rake @@ -25,17 +25,17 @@ namespace :db do SHORT_ACC = PROB_SHORT_REPONSE + PROB_FAILURE MEDIUM_ACC = PROB_MEDIUM_RESPONSE + PROB_SHORT_REPONSE + PROB_FAILURE
- task :demo_data, :cloud_account_id, :user_id, :time_period, :number_of_tasks, :needs => :environment do |t, args| + task :demo_data, :provider_account_id, :user_id, :time_period, :number_of_tasks, :needs => :environment do |t, args|
@time_scale = args[:time_period].to_f * 60 * 60 @number_of_tasks = args[:number_of_tasks]
puts @number_of_tasks
- cloud_account = CloudAccount.find(args[:cloud_account_id]) + provider_account = ProviderAccount.find(args[:provider_account_id]) user = User.find(args[:user_id])
- instance = create_instance(cloud_account) + instance = create_instance(provider_account)
started_at = Time.now create_tasks(instance, user) @@ -44,13 +44,13 @@ namespace :db do print_stats(started_at, ended_at) end
- def create_instance(cloud_account) + def create_instance(provider_account) instance = Instance.new({:name => "instance" + Time.now.to_s, :hardware_profile_id => HardwareProfile.find(:first), :image_id => Image.find(:first), :state => Instance::STATE_NEW, :pool_id => 1, - :cloud_account_id => cloud_account.id + :provider_account_id => provider_account.id }) instance.save! return instance @@ -116,4 +116,4 @@ namespace :db do return time_started end
-end \ No newline at end of file +end diff --git a/src/spec/controllers/cloud_accounts_controller_spec.rb b/src/spec/controllers/cloud_accounts_controller_spec.rb deleted file mode 100644 index 072126e..0000000 --- a/src/spec/controllers/cloud_accounts_controller_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'spec_helper' - -describe CloudAccountsController do - - fixtures :all - before(:each) do - @cloud_account = Factory :mock_cloud_account - @provider = @cloud_account.provider - - @admin_permission = Permission.create :role => Role.find(:first, :conditions => ['name = ?', 'Provider Administrator']), - :permission_object => @provider, - :user => Factory(:provider_admin_user) - @admin = @admin_permission.user - activate_authlogic - end - - it "shows provider accounts as list" do - UserSession.create(@admin) - get :index, :provider_id => @provider.id - response.should be_success - response.should render_template("index") - end - - it "allows test account validity on create when passing test_account param" do - UserSession.create(@admin) - post :create, :provider_id => @provider.id, :cloud_account => {}, :test_account => true - response.should be_success - response.should render_template("new") - response.flash[:error].should == "Test Connection Failed: Invalid Account Details" - end - - it "doesn't allow to save provider's account if not valid credentials" do - UserSession.create(@admin) - post :create, :provider_id => @provider.id, :cloud_account => {} - response.should be_success - response.should render_template("new") - response.flash[:error].should == "The entered credential information is incorrect" - end - - it "should permit users with account modify permission to access edit cloud account interface" do - UserSession.create(@admin) - get :edit, :id => @cloud_account.id - response.should be_success - response.should render_template("edit") - end - - it "should allow users with account modify permission to update a cloud account" do - UserSession.create(@admin) - - @cloud_account.password = "foobar" - @cloud_account.stub!(:valid_credentials?).and_return(true) - @cloud_account.save.should be_true - - post :update, :id => @cloud_account.id, :cloud_account => { :password => 'mockpassword' } - response.should redirect_to provider_accounts_path(@provider) - CloudAccount.find(@cloud_account.id).password.should == "mockpassword" - end - - it "should allow users with account modify permission to delete a cloud account" do - UserSession.create(@admin) - lambda do - get :destroy, :id => @cloud_account.id - end.should change(CloudAccount, :count).by(-1) - response.should redirect_to provider_accounts_path(@provider) - CloudAccount.find_by_id(@cloud_account.id).should be_nil - end - - it "should deny access to users without account modify permission" do - get :edit, :id => @cloud_account.id - response.should_not be_success - - post :update, :id => @cloud_account.id, :cloud_account => { :password => 'foobar' } - response.should_not be_success - - post :destroy, :id => @cloud_account.id - response.should_not be_success - end - - it "should provide ui to create new account" do - UserSession.create(@admin) - get :new, :provider_id => @provider.id - response.should be_success - response.should render_template("new") - end - - it "should fail to grant access to account UIs for unauthenticated user" do - get :new - response.should_not be_success - end - -end diff --git a/src/spec/controllers/provider_accounts_controller_spec.rb b/src/spec/controllers/provider_accounts_controller_spec.rb new file mode 100644 index 0000000..c8d6b32 --- /dev/null +++ b/src/spec/controllers/provider_accounts_controller_spec.rb @@ -0,0 +1,91 @@ +require 'spec_helper' + +describe ProviderAccountsController do + + fixtures :all + before(:each) do + @provider_account = Factory :mock_provider_account + @provider = @provider_account.provider + + @admin_permission = Permission.create :role => Role.find(:first, :conditions => ['name = ?', 'Provider Administrator']), + :permission_object => @provider, + :user => Factory(:provider_admin_user) + @admin = @admin_permission.user + activate_authlogic + end + + it "shows provider accounts as list" do + UserSession.create(@admin) + get :index, :provider_id => @provider.id + response.should be_success + response.should render_template("index") + end + + it "allows test account validity on create when passing test_account param" do + UserSession.create(@admin) + post :create, :provider_id => @provider.id, :provider_account => {}, :test_account => true + response.should be_success + response.should render_template("new") + response.flash[:error].should == "Test Connection Failed: Invalid Account Details" + end + + it "doesn't allow to save provider's account if not valid credentials" do + UserSession.create(@admin) + post :create, :provider_id => @provider.id, :provider_account => {} + response.should be_success + response.should render_template("new") + response.flash[:error].should == "The entered credential information is incorrect" + end + + it "should permit users with account modify permission to access edit cloud account interface" do + UserSession.create(@admin) + get :edit, :id => @provider_account.id + response.should be_success + response.should render_template("edit") + end + + it "should allow users with account modify permission to update a cloud account" do + UserSession.create(@admin) + + @provider_account.password = "foobar" + @provider_account.stub!(:valid_credentials?).and_return(true) + @provider_account.save.should be_true + + post :update, :id => @provider_account.id, :provider_account => { :password => 'mockpassword' } + response.should redirect_to provider_accounts_path(@provider) + ProviderAccount.find(@provider_account.id).password.should == "mockpassword" + end + + it "should allow users with account modify permission to delete a cloud account" do + UserSession.create(@admin) + lambda do + get :destroy, :id => @provider_account.id + end.should change(ProviderAccount, :count).by(-1) + response.should redirect_to provider_accounts_path(@provider) + ProviderAccount.find_by_id(@provider_account.id).should be_nil + end + + it "should deny access to users without account modify permission" do + get :edit, :id => @provider_account.id + response.should_not be_success + + post :update, :id => @provider_account.id, :provider_account => { :password => 'foobar' } + response.should_not be_success + + post :destroy, :id => @provider_account.id + response.should_not be_success + end + + it "should provide ui to create new account" do + UserSession.create(@admin) + get :new, :provider_id => @provider.id + response.should be_success + response.should render_template("new") + end + + it "should fail to grant access to account UIs for unauthenticated user" do + get :new + response.should_not be_success + end + +end diff --git a/src/spec/controllers/templates_controller_spec.rb b/src/spec/controllers/templates_controller_spec.rb index 6e23609..bb14f1f 100644 --- a/src/spec/controllers/templates_controller_spec.rb +++ b/src/spec/controllers/templates_controller_spec.rb @@ -33,7 +33,7 @@ describe TemplatesController do hydra = Typhoeus::Hydra.hydra hydra.stub(:put, %r{http://localhost:9090/templates/.*%7D).and_return( Typhoeus::Response.new(:code => 200)) - Factory.create(:mock_cloud_account) + Factory.create(:mock_provider_account) end
it "should create a new Image" do diff --git a/src/spec/factories/cloud_account.rb b/src/spec/factories/cloud_account.rb deleted file mode 100644 index 797fa47..0000000 --- a/src/spec/factories/cloud_account.rb +++ /dev/null @@ -1,21 +0,0 @@ -Factory.define :cloud_account do |f| - f.sequence(:username) { |n| "testUser#(n)" } - f.password "testPassword" - f.sequence(:label) { |n| "test label#(n)" } - f.account_number "3141" - f.x509_cert_priv "x509 private key" - f.x509_cert_pub "x509 public key" - f.association :provider -end - -Factory.define :mock_cloud_account, :parent => :cloud_account do |f| - f.username "mockuser" - f.password "mockpassword" - f.provider { |p| p.association(:mock_provider) } -end - -Factory.define :ec2_cloud_account, :parent => :cloud_account do |f| - f.username "mockuser" - f.password "mockpassword" - f.provider { |p| p.association(:ec2_provider) } -end diff --git a/src/spec/factories/instance.rb b/src/spec/factories/instance.rb index 7533ba9..87938bd 100644 --- a/src/spec/factories/instance.rb +++ b/src/spec/factories/instance.rb @@ -2,7 +2,7 @@ Factory.define :instance do |i| i.sequence(:name) { |n| "instance#{n}" } i.sequence(:external_key) { |n| "key#{n}" } i.association :hardware_profile, :factory => :mock_hwp1 - i.association :cloud_account, :factory => :mock_cloud_account + i.association :provider_account, :factory => :mock_provider_account i.association :template, :factory => :template i.association :pool, :factory => :pool i.association :owner, :factory => :user @@ -23,6 +23,6 @@ end
Factory.define :ec2_instance, :parent => :instance do |i| i.association :hardware_profile, :factory => :ec2_hwp1 - i.association :cloud_account, :factory => :ec2_cloud_account + i.association :provider_account, :factory => :ec2_provider_account i.association :instance_key, :factory => :ec2_instance_key1 end diff --git a/src/spec/factories/instance_key.rb b/src/spec/factories/instance_key.rb index d5bc69a..a7fe812 100644 --- a/src/spec/factories/instance_key.rb +++ b/src/spec/factories/instance_key.rb @@ -28,10 +28,10 @@ uH9ebPTGZc5cTpOEV9SupUez4cAedBGeHVDHy06sATrgIwKBgQCdqFhrse+uhRacK1LAymvBsou5 end
Factory.define :ec2_instance_key1, :parent => :instance_key do |p| - p.cloud_account { |p| p.association(:ec2_cloud_account) } + p.provider_account { |p| p.association(:ec2_provider_account) } p.name "1_user" end
Factory.define :mock_instance_key, :parent => :instance_key do |m| - m.cloud_account { |c| c.association(:mock_cloud_account) } -end \ No newline at end of file + m.provider_account { |c| c.association(:mock_provider_account) } +end diff --git a/src/spec/factories/provider_account.rb b/src/spec/factories/provider_account.rb new file mode 100644 index 0000000..a06ea48 --- /dev/null +++ b/src/spec/factories/provider_account.rb @@ -0,0 +1,21 @@ +Factory.define :provider_account do |f| + f.sequence(:username) { |n| "testUser#(n)" } + f.password "testPassword" + f.sequence(:label) { |n| "test label#(n)" } + f.account_number "3141" + f.x509_cert_priv "x509 private key" + f.x509_cert_pub "x509 public key" + f.association :provider +end + +Factory.define :mock_provider_account, :parent => :provider_account do |f| + f.username "mockuser" + f.password "mockpassword" + f.provider { |p| p.association(:mock_provider) } +end + +Factory.define :ec2_provider_account, :parent => :provider_account do |f| + f.username "mockuser" + f.password "mockpassword" + f.provider { |p| p.association(:ec2_provider) } +end diff --git a/src/spec/models/cloud_account_spec.rb b/src/spec/models/cloud_account_spec.rb deleted file mode 100644 index fb04e40..0000000 --- a/src/spec/models/cloud_account_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'spec_helper' - -describe CloudAccount do - fixtures :all - before(:each) do - @cloud_account = Factory :mock_cloud_account - end - - it "should not be destroyable if it has instances" do - @cloud_account.instances << Instance.new - @cloud_account.destroyable?.should be_false - @cloud_account.destroy.should be_false - - @cloud_account.instances.clear - @cloud_account.destroyable?.should be_true - @cloud_account.destroy.equal?(@cloud_account).should be_true - @cloud_account.should be_frozen - end - - it "should check the validitiy of the cloud account login credentials" do - mock_provider = Factory :mock_provider - - invalid_cloud_account = Factory.build(:cloud_account, :username => "wrong_username", :password => "wrong_password", :provider => mock_provider) - invalid_cloud_account.should_not be_valid - - valid_cloud_account = Factory.build(:mock_cloud_account, :provider => mock_provider) - valid_cloud_account.should be_valid - end - - it "should fail to create a cloud account if the provider credentials are invalid" do - cloud_account = Factory.build(:mock_cloud_account, :password => "wrong_password") - cloud_account.save.should == false - end - - 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 - - it "when calling connect and it fails with exception it will return nil" do - DeltaCloud.should_receive(:new).and_raise(Exception.new) - - @cloud_account.connect.should be_nil - end - - it "should generate credentials xml" do - expected_xml = <<EOT -<?xml version="1.0"?> -<provider_credentials> - <ec2_credentials> - <account_number>1234</account_number> - <access_key>user</access_key> - <secret_access_key>pass</secret_access_key> - <certificate>cert</certificate> - <key>priv_key</key> - </ec2_credentials> -</provider_credentials> -EOT - cloud_account = Factory.build(:mock_cloud_account, - :username => 'user', - :password => 'pass', - :account_number => '1234', - :x509_cert_priv => 'priv_key', - :x509_cert_pub => 'cert' - ) - cloud_account.build_credentials.should eql(expected_xml) - end -end diff --git a/src/spec/models/instance_observer_spec.rb b/src/spec/models/instance_observer_spec.rb index a696319..de707ab 100644 --- a/src/spec/models/instance_observer_spec.rb +++ b/src/spec/models/instance_observer_spec.rb @@ -5,8 +5,8 @@ describe InstanceObserver do before(:each) do Timecop.travel(Time.local(2008, 9, 1, 10, 5, 0, 0, 0))
- @cloud_account_quota = Factory :quota - @cloud_account = Factory(:mock_cloud_account, :quota_id => @cloud_account_quota.id) + @provider_account_quota = Factory :quota + @provider_account = Factory(:mock_provider_account, :quota_id => @provider_account_quota.id)
@pool_quota = Factory :quota @pool = Factory(:pool, :quota_id => @pool_quota.id) @@ -15,7 +15,7 @@ describe InstanceObserver do @user = Factory(:user, :quota_id => @user_quota.id)
@hwp = Factory :mock_hwp1 - @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => @hwp, :cloud_account_id => @cloud_account.id, :owner => @user) + @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => @hwp, :provider_account_id => @provider_account.id, :owner => @user) end
after(:each) do @@ -102,14 +102,14 @@ describe InstanceObserver do end
it "should not update quota on pool, user and cloud account when an instance is state new" do - [@cloud_account_quota, @pool_quota, @user_quota].each do |quota| + [@provider_account_quota, @pool_quota, @user_quota].each do |quota| quota = Quota.find(quota) quota.total_instances.should == 0 end end
it "should update quota on pool, user and cloud account when an instance goes to state pending" do - [@cloud_account_quota, @pool_quota, @user_quota].each do |quota| + [@provider_account_quota, @pool_quota, @user_quota].each do |quota| @instance.state = Instance::STATE_PENDING @instance.save!
@@ -122,7 +122,7 @@ describe InstanceObserver do @instance.state = Instance::STATE_CREATE_FAILED @instance.save!
- [@cloud_account_quota, @pool_quota, @user_quota].each do |quota| + [@provider_account_quota, @pool_quota, @user_quota].each do |quota| quota = Quota.find(quota) quota.total_instances.should == 0 end @@ -132,7 +132,7 @@ describe InstanceObserver do @instance.state = Instance::STATE_RUNNING @instance.save!
- [@cloud_account_quota, @pool_quota, @user_quota].each do |quota| + [@provider_account_quota, @pool_quota, @user_quota].each do |quota| quota = Quota.find(quota.id) quota.running_instances.should == 1 quota.total_instances.should == 1 @@ -146,7 +146,7 @@ describe InstanceObserver do @instance.state = Instance::STATE_SHUTTING_DOWN @instance.save!
- [@cloud_account_quota, @pool_quota, @user_quota].each do |quota| + [@provider_account_quota, @pool_quota, @user_quota].each do |quota| quota = Quota.find(quota.id)
quota.running_instances.should == 0 diff --git a/src/spec/models/instance_spec.rb b/src/spec/models/instance_spec.rb index ee9cbaf..36df141 100644 --- a/src/spec/models/instance_spec.rb +++ b/src/spec/models/instance_spec.rb @@ -127,11 +127,11 @@ describe Instance do
it "should return empty list of instance actions when connect to provider fails" do provider = Factory.build(:mock_provider2) - cloud_account = Factory.build(:cloud_account, :provider => provider, + provider_account = Factory.build(:provider_account, :provider => provider, :username => 'john doe', :password => 'asdf') - cloud_account.stub!(:connect).and_return(nil) - instance = Factory.create(:instance, :cloud_account => cloud_account) + provider_account.stub!(:connect).and_return(nil) + instance = Factory.create(:instance, :provider_account => provider_account) instance.get_action_list.should be_empty end
diff --git a/src/spec/models/provider_account_spec.rb b/src/spec/models/provider_account_spec.rb new file mode 100644 index 0000000..48678e8 --- /dev/null +++ b/src/spec/models/provider_account_spec.rb @@ -0,0 +1,80 @@ +require 'spec_helper' + +describe ProviderAccount do + fixtures :all + before(:each) do + @provider_account = Factory :mock_provider_account + end + + it "should not be destroyable if it has instances" do + @provider_account.instances << Instance.new + @provider_account.destroyable?.should be_false + @provider_account.destroy.should be_false + + @provider_account.instances.clear + @provider_account.destroyable?.should be_true + @provider_account.destroy.equal?(@provider_account).should be_true + @provider_account.should be_frozen + end + + it "should check the validitiy of the cloud account login credentials" do + mock_provider = Factory :mock_provider + + invalid_provider_account = Factory.build(:provider_account, :username => "wrong_username", :password => "wrong_password", :provider => mock_provider) + invalid_provider_account.should_not be_valid + + valid_provider_account = Factory.build(:mock_provider_account, :provider => mock_provider) + valid_provider_account.should be_valid + end + + it "should fail to create a cloud account if the provider credentials are invalid" do + provider_account = Factory.build(:mock_provider_account, :password => "wrong_password") + provider_account.save.should == false + end + + 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) + + provider_account = Factory.build :ec2_provider_account + provider_account.stub!(:connect).and_return(@client) + provider_account.save + provider_account.instance_key.should_not == nil + provider_account.instance_key.pem == "PEM" + provider_account.instance_key.id == "1_user" + end + + it "when calling connect and it fails with exception it will return nil" do + DeltaCloud.should_receive(:new).and_raise(Exception.new) + + @provider_account.connect.should be_nil + end + + it "should generate credentials xml" do + expected_xml = <<EOT +<?xml version="1.0"?> +<provider_credentials> + <ec2_credentials> + <account_number>1234</account_number> + <access_key>user</access_key> + <secret_access_key>pass</secret_access_key> + <certificate>cert</certificate> + <key>priv_key</key> + </ec2_credentials> +</provider_credentials> +EOT + provider_account = Factory.build(:mock_provider_account, + :username => 'user', + :password => 'pass', + :account_number => '1234', + :x509_cert_priv => 'priv_key', + :x509_cert_pub => 'cert' + ) + provider_account.build_credentials.should eql(expected_xml) + end +end diff --git a/src/spec/models/provider_spec.rb b/src/spec/models/provider_spec.rb index 1b86f92..e3af313 100644 --- a/src/spec/models/provider_spec.rb +++ b/src/spec/models/provider_spec.rb @@ -79,7 +79,7 @@ describe Provider do HardwareProfile.destroy_all
instance = Factory(:instance) - provider = instance.cloud_account.provider + provider = instance.provider_account.provider provider.destroy provider.destroyed?.should be_false end diff --git a/src/spec/models/quota_spec.rb b/src/spec/models/quota_spec.rb index 9620e83..960b417 100644 --- a/src/spec/models/quota_spec.rb +++ b/src/spec/models/quota_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe Quota do
before(:each) do - @cloud_account_quota = Factory :quota - @cloud_account = Factory(:mock_cloud_account, :quota_id => @cloud_account_quota.id) + @provider_account_quota = Factory :quota + @provider_account = Factory(:mock_provider_account, :quota_id => @provider_account_quota.id)
@pool_quota = Factory :quota @pool = Factory(:pool, :quota_id => @pool_quota.id) @@ -13,12 +13,12 @@ describe Quota do @user = Factory(:user, :quota_id => @user_quota.id)
@hwp = Factory :mock_hwp1 - @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => @hwp, :cloud_account_id => @cloud_account.id, :owner => @user) + @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => @hwp, :provider_account_id => @provider_account.id, :owner => @user) end
it "should return true when asking if an instance can be created/started when there is sufficient quota space" do - Quota.can_create_instance?(@instance, @cloud_account).should == true - Quota.can_start_instance?(@instance, @cloud_account).should == true + Quota.can_create_instance?(@instance, @provider_account).should == true + Quota.can_start_instance?(@instance, @provider_account).should == true end
it "should return true when asking if an instance can be created/started when using unlimited Quotas" do @@ -28,11 +28,11 @@ describe Quota do @pool.quota = Factory :unlimited_quota @pool.save!
- @cloud_account.quota = Factory :unlimited_quota - @cloud_account.save! + @provider_account.quota = Factory :unlimited_quota + @provider_account.save!
- Quota.can_create_instance?(@instance, @cloud_account).should == true - Quota.can_start_instance?(@instance, @cloud_account).should == true + Quota.can_create_instance?(@instance, @provider_account).should == true + Quota.can_start_instance?(@instance, @provider_account).should == true end
it "should return false when asking if an instance can be created/started when the user quota is reached" do @@ -40,8 +40,8 @@ describe Quota do @user_quota.running_instances = @user_quota.maximum_running_instances @user_quota.save!
- Quota.can_create_instance?(@instance, @cloud_account).should == false - Quota.can_start_instance?(@instance, @cloud_account).should == false + Quota.can_create_instance?(@instance, @provider_account).should == false + Quota.can_start_instance?(@instance, @provider_account).should == false end
it "should return false when asking if an instance can be created/started when the pool quota is reached" do @@ -49,17 +49,17 @@ describe Quota do @pool_quota.running_instances = @pool_quota.maximum_running_instances @pool_quota.save!
- Quota.can_create_instance?(@instance, @cloud_account).should == false - Quota.can_start_instance?(@instance, @cloud_account).should == false + Quota.can_create_instance?(@instance, @provider_account).should == false + Quota.can_start_instance?(@instance, @provider_account).should == false end
it "should return false when asking if an instance can be created/started when the cloud account quota is reached" do - @cloud_account_quota.total_instances = @cloud_account_quota.maximum_total_instances - @cloud_account_quota.running_instances = @cloud_account_quota.maximum_running_instances - @cloud_account_quota.save! + @provider_account_quota.total_instances = @provider_account_quota.maximum_total_instances + @provider_account_quota.running_instances = @provider_account_quota.maximum_running_instances + @provider_account_quota.save!
- Quota.can_create_instance?(@instance, @cloud_account).should == false - Quota.can_start_instance?(@instance, @cloud_account).should == false + Quota.can_create_instance?(@instance, @provider_account).should == false + Quota.can_start_instance?(@instance, @provider_account).should == false end
it "should return false when asking if an instance can be created/started when the all quotas are reached" do @@ -71,12 +71,12 @@ describe Quota do @pool_quota.running_instances = @pool_quota.maximum_running_instances @pool_quota.save!
- @cloud_account_quota.total_instances = @cloud_account_quota.maximum_total_instances - @cloud_account_quota.running_instances = @cloud_account_quota.maximum_running_instances - @cloud_account_quota.save! + @provider_account_quota.total_instances = @provider_account_quota.maximum_total_instances + @provider_account_quota.running_instances = @provider_account_quota.maximum_running_instances + @provider_account_quota.save!
- Quota.can_create_instance?(@instance, @cloud_account).should == false - Quota.can_start_instance?(@instance, @cloud_account).should == false + Quota.can_create_instance?(@instance, @provider_account).should == false + Quota.can_start_instance?(@instance, @provider_account).should == false end
-end \ No newline at end of file +end diff --git a/src/spec/models/zone_spec.rb b/src/spec/models/zone_spec.rb index 2ede895..450a314 100644 --- a/src/spec/models/zone_spec.rb +++ b/src/spec/models/zone_spec.rb @@ -5,9 +5,9 @@ describe Zone do before(:each) do @pool = Factory :pool @zone = @pool.zone - @cloud_account = Factory :mock_cloud_account - @cloud_account.zones << @zone - @cloud_account.save! + @provider_account = Factory :mock_provider_account + @provider_account.zones << @zone + @provider_account.save! end
it "should validate default zone" do @@ -27,8 +27,8 @@ describe Zone do end
it "should have account" do - @zone.cloud_accounts.size.should == 1 - @zone.cloud_accounts[0].id.should == @cloud_account.id + @zone.provider_accounts.size.should == 1 + @zone.provider_accounts[0].id.should == @provider_account.id end
end diff --git a/src/spec/services/data_service_active_record_spec.rb b/src/spec/services/data_service_active_record_spec.rb index b443fa9..45b07bf 100644 --- a/src/spec/services/data_service_active_record_spec.rb +++ b/src/spec/services/data_service_active_record_spec.rb @@ -11,13 +11,13 @@ describe DataServiceActiveRecord do data = [[25, 10], [40, 20], [20, 20]] free = 0 for i in 0..2 - cloud_account = Factory.build(:cloud_account, :provider => provider, :username => "username" + i.to_s) - cloud_account.stub!(:valid_credentials?).and_return(true) - cloud_account.save! + provider_account = Factory.build(:provider_account, :provider => provider, :username => "username" + i.to_s) + provider_account.stub!(:valid_credentials?).and_return(true) + provider_account.save!
quota = Factory(:quota, :maximum_total_instances => data[i][0], :total_instances => data[i][1]) - cloud_account.quota_id = quota.id - cloud_account.save! + provider_account.quota_id = quota.id + provider_account.save!
free += (data[i][0] - data[i][1]) end @@ -36,24 +36,24 @@ describe DataServiceActiveRecord do provider.stub!(:connect).and_return(client) provider.save!
- cloud_account = Factory.build(:cloud_account, :provider => provider) - cloud_account.stub!(:valid_credentials?).and_return(true) - cloud_account.save! + provider_account = Factory.build(:provider_account, :provider => provider) + provider_account.stub!(:valid_credentials?).and_return(true) + provider_account.save!
quota = Factory(:quota, :maximum_running_instances => 40, :maximum_total_instances => 50, :running_instances => 20, :total_instances => 20) - cloud_account.quota_id = quota.id + provider_account.quota_id = quota.id
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_RUNNING_INSTANCES) + data_point = DataServiceActiveRecord.quota_usage(provider_account, Quota::RESOURCE_RUNNING_INSTANCES) data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 40)
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_TOTAL_INSTANCES) + data_point = DataServiceActiveRecord.quota_usage(provider_account, Quota::RESOURCE_TOTAL_INSTANCES) data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 50)
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_OVERALL) + data_point = DataServiceActiveRecord.quota_usage(provider_account, Quota::RESOURCE_OVERALL) data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 40) end
@@ -127,13 +127,13 @@ describe DataServiceActiveRecord do provider.stub!(:connect).and_return(client) provider.save!
- cloud_accounts = [] + provider_accounts = [] expected_averages.each do |expected_average| - cloud_account = Factory.build(:cloud_account, :provider => provider, :username => "username" + expected_average[0].to_s) - cloud_account.stub!(:valid_credentials?).and_return(true) - cloud_account.save! + provider_account = Factory.build(:provider_account, :provider => provider, :username => "username" + expected_average[0].to_s) + provider_account.stub!(:valid_credentials?).and_return(true) + provider_account.save!
- instance = Factory(:instance, :cloud_account_id => cloud_account.id, :pool_id => pool.id) + instance = Factory(:instance, :provider_account_id => provider_account.id, :pool_id => pool.id) generate_tasks(start_time, interval_length, instance, expected_average) end
@@ -163,11 +163,11 @@ describe DataServiceActiveRecord do runtimes = [runtime1, runtime2, runtime3]
pool = Factory(:pool) - cloud_account = Factory :mock_cloud_account + provider_account = Factory :mock_provider_account
for i in 0..2 do runtimes[i].each do |runtime| - instance = Factory(:instance, :pool => pool, :cloud_account => cloud_account, :state => Instance::STATE_STOPPED) + instance = Factory(:instance, :pool => pool, :provider_account => provider_account, :state => Instance::STATE_STOPPED) instance.save!
instance.time_last_pending = start_times[i] + (interval_length / 2) @@ -177,7 +177,7 @@ describe DataServiceActiveRecord do end end
- stats = DataServiceActiveRecord.qos_instance_runtime_stats(cloud_account, start_time, end_time, interval_length) + stats = DataServiceActiveRecord.qos_instance_runtime_stats(provider_account, start_time, end_time, interval_length) stats[0].should == DataServiceActiveRecord::QoSDataPoint.new(start_times[0], 15, 25, 5) stats[1].should == DataServiceActiveRecord::QoSDataPoint.new(start_times[1], 30, 50, 10) stats[2].should == DataServiceActiveRecord::QoSDataPoint.new(start_times[2], 300, 500, 100) @@ -187,11 +187,11 @@ describe DataServiceActiveRecord do it "should generate the mean max and min instance runtimes of instances for a given cloud account or pool" do pool = Factory(:pool)
- cloud_account = Factory :mock_cloud_account + provider_account = Factory :mock_provider_account
start_time = Time.utc(2010,"jan",1,20,15,1) [50, 100, 150, 200, 250].each do |runtime| - instance = Factory(:new_instance, :pool => pool, :cloud_account => cloud_account) + instance = Factory(:new_instance, :pool => pool, :provider_account => provider_account) instance.time_last_pending = start_time instance.time_last_running = start_time instance.acc_running_time = runtime @@ -205,8 +205,8 @@ describe DataServiceActiveRecord do
it "should calculate the average time it takes a provider to complete a task between two times" do pool = Factory(:pool) - cloud_account = Factory(:mock_cloud_account) - instance = Factory(:instance, :pool => pool, :cloud_account => cloud_account) + provider_account = Factory(:mock_provider_account) + instance = Factory(:instance, :pool => pool, :provider_account => provider_account)
start_time = Time.utc(2010,"jan",1,20,15,1) task_completion_times = [10, 20, 30, 40, 50] @@ -230,7 +230,7 @@ describe DataServiceActiveRecord do end
expected_average_time = total_time / task_completion_times.length - average_time = DataServiceActiveRecord.qos_task_completion_mean_max_min(cloud_account.provider, start_time, Time.now, InstanceTask::ACTION_CREATE) + average_time = DataServiceActiveRecord.qos_task_completion_mean_max_min(provider_account.provider, start_time, Time.now, InstanceTask::ACTION_CREATE)
average_time[:average].should == expected_average_time average_time[:min].should == 10 @@ -243,8 +243,8 @@ describe DataServiceActiveRecord do end_time = create_time + 1
pool = Factory(:pool) - cloud_account = Factory :mock_cloud_account - instance = Factory(:instance, :pool => pool, :cloud_account => cloud_account) + provider_account = Factory :mock_provider_account + instance = Factory(:instance, :pool => pool, :provider_account => provider_account)
failures = 5 non_failures = 20 @@ -289,8 +289,8 @@ describe DataServiceActiveRecord do number_of_instances = 20
pool = Factory(:pool) - cloud_account = Factory :mock_cloud_account - instance = Factory(:instance, :pool => pool, :cloud_account => cloud_account) + provider_account = Factory :mock_provider_account + instance = Factory(:instance, :pool => pool, :provider_account => provider_account)
for i in 0..2 for j in 1..failures[i] diff --git a/src/test/fixtures/cloud_accounts.yml b/src/test/fixtures/cloud_accounts.yml deleted file mode 100644 index 5099be1..0000000 --- a/src/test/fixtures/cloud_accounts.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html - -mock_account: - username: mockuser - password: mockpassword - provider: mock_provider diff --git a/src/test/fixtures/instances.yml b/src/test/fixtures/instances.yml index 951258d..4ec5c7d 100644 --- a/src/test/fixtures/instances.yml +++ b/src/test/fixtures/instances.yml @@ -7,7 +7,7 @@ test_instance: image: fedora_13_image_frontend realm: us_realm pool: test_pool - cloud_account: mock_account + provider_account: mock_account public_address: private_address: state: stopped diff --git a/src/test/fixtures/pool_accounts.yml b/src/test/fixtures/pool_accounts.yml index c5db498..083d254 100644 --- a/src/test/fixtures/pool_accounts.yml +++ b/src/test/fixtures/pool_accounts.yml @@ -1,5 +1,5 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
test_pool_mock_account: - cloud_account: mock_account + provider_account: mock_account pool: test_pool diff --git a/src/test/fixtures/pools.yml b/src/test/fixtures/pools.yml index da63a52..a5d96bb 100644 --- a/src/test/fixtures/pools.yml +++ b/src/test/fixtures/pools.yml @@ -3,4 +3,4 @@ test_pool name: test_pool owner: test_user - cloud_accounts: mock_account + provider_accounts: mock_account diff --git a/src/test/fixtures/provider_accounts.yml b/src/test/fixtures/provider_accounts.yml new file mode 100644 index 0000000..5099be1 --- /dev/null +++ b/src/test/fixtures/provider_accounts.yml @@ -0,0 +1,6 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +mock_account: + username: mockuser + password: mockpassword + provider: mock_provider diff --git a/src/test/unit/cloud_account_test.rb b/src/test/unit/cloud_account_test.rb deleted file mode 100644 index addf6af..0000000 --- a/src/test/unit/cloud_account_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'test_helper' - -class CloudAccountTest < ActiveSupport::TestCase - # Replace this with your real tests. - test "the truth" do - assert true - end -end diff --git a/src/test/unit/provider_account_test.rb b/src/test/unit/provider_account_test.rb new file mode 100644 index 0000000..cafbb76 --- /dev/null +++ b/src/test/unit/provider_account_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class ProviderAccountTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end