[PATCH conductor] bug 786220 - Scope images to Pool Family
Scott Seago
sseago at redhat.com
Wed Feb 15 18:51:38 UTC 2012
https://bugzilla.redhat.com/show_bug.cgi?id=786220
---
src/app/controllers/api/environments_controller.rb | 39 ++++++++
src/app/controllers/api/images_controller.rb | 58 ++++++++++--
.../controllers/api/provider_images_controller.rb | 4 +
src/app/controllers/deployables_controller.rb | 30 ++----
src/app/controllers/deployments_controller.rb | 86 ++++++++++--------
src/app/controllers/images_controller.rb | 35 ++++---
src/app/controllers/pool_families_controller.rb | 2 +-
src/app/models/deployable.rb | 61 +++++++------
src/app/models/pool_family.rb | 7 ++
src/app/models/provider_account.rb | 10 ++-
.../views/api/environments/_environment.xml.haml | 9 ++
src/app/views/api/environments/index.xml.haml | 4 +
src/app/views/api/environments/show.xml.haml | 2 +
src/app/views/api/images/_image.xml.haml | 1 +
src/app/views/deployables/_image_uuids.html.haml | 8 +-
src/app/views/deployables/show.html.haml | 8 +-
.../deployments/launch_from_catalog.html.haml | 2 +-
src/app/views/images/_list.html.haml | 47 ++++++----
src/app/views/images/import.html.haml | 3 +
src/app/views/images/show.html.haml | 23 +++--
src/config/locales/en.yml | 8 ++
src/config/routes.rb | 4 +
src/features/deployables.feature | 1 +
src/features/deployment.feature | 3 +-
src/lib/image.rb | 6 +-
src/spec/controllers/api/images_controller_spec.rb | 26 +++++-
.../api/provider_images_controller_spec.rb | 5 +-
.../controllers/deployables_controller_spec.rb | 12 ++--
.../controllers/deployments_controller_spec.rb | 5 +-
src/spec/vcr/cassettes/iwhd_connection.yml | 96 ++++++++++++++++++++
30 files changed, 439 insertions(+), 166 deletions(-)
create mode 100644 src/app/controllers/api/environments_controller.rb
create mode 100644 src/app/views/api/environments/_environment.xml.haml
create mode 100644 src/app/views/api/environments/index.xml.haml
create mode 100644 src/app/views/api/environments/show.xml.haml
diff --git a/src/app/controllers/api/environments_controller.rb b/src/app/controllers/api/environments_controller.rb
new file mode 100644
index 0000000..9260caa
--- /dev/null
+++ b/src/app/controllers/api/environments_controller.rb
@@ -0,0 +1,39 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+module Api
+ class EnvironmentsController < ApplicationController
+ before_filter :require_user
+
+ respond_to :xml
+ layout :false
+
+ def index
+ @environments = PoolFamily.all
+ end
+
+ def show
+ begin
+ @environment = PoolFamily.find(params[:id])
+ rescue ActiveRecord::RecordNotFound
+ @environment = PoolFamily.find_by_name(params[:id])
+ end
+ end
+ end
+end
diff --git a/src/app/controllers/api/images_controller.rb b/src/app/controllers/api/images_controller.rb
index 18870f2..465a20b 100644
--- a/src/app/controllers/api/images_controller.rb
+++ b/src/app/controllers/api/images_controller.rb
@@ -20,13 +20,16 @@
module Api
class ImagesController < ApplicationController
before_filter :require_user_api
- before_filter :check_permissions, :only => [:create, :destroy]
respond_to :xml
layout :false
def index
- @images = Aeolus::Image::Warehouse::Image.all
+ if (@environment = params[:environment_id])
+ @images = Aeolus::Image::Warehouse::Image.by_environment(@environment)
+ else
+ @images = Aeolus::Image::Warehouse::Image.all
+ end
respond_with(@images)
end
@@ -47,9 +50,16 @@ module Api
begin
if req[:type] == :failed
raise(Aeolus::Conductor::API::InsufficientParametersSupplied.new(400, t("api.error_messages.specify_a_type_build_or_import")))
+ elsif req[:type] == :failed_env
+ raise(Aeolus::Conductor::API::InsufficientParametersSupplied.new(400, t("api.error_messages.specify_environment")))
elsif req[:type] == :build
errors = TemplateXML.validate(req[:params][:template])
raise Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.invalid_template", :errors => errors.join(", "))) if errors.any?
+ raise Aeolus::Conductor::API::InsufficientParametersSupplied.new(400, t("api.error_messages.environment_required")) if req[:params][:environment].nil?
+ @pool_family = PoolFamily.find_by_name(req[:params][:environment])
+ raise Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.environment_not_found", :environment => req[:params][:environment])) if @pool_family.nil?
+ check_permissions
+ environment_targets = @pool_family.build_targets
@targetnotfound=false
@badtarget=""
@@ -58,20 +68,46 @@ module Api
if !target
@targetnotfound=true
@badtarget=t
+ elsif !environment_targets.include?(t)
+ raise(Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.target_not_found_in_environment", :target => t, :targets => environment_targets.join(", "))))
end
end
if @targetnotfound
raise(Aeolus::Conductor::API::TargetNotFound.new(404, t("api.error_messages.target_not_found", :target => @badtarget)))
end
- @image = Aeolus::Image::Factory::Image.new(req[:params])
+
+ uuid = UUIDTools::UUID.timestamp_create.to_s
+ @tpl = Aeolus::Image::Warehouse::Template.create!(uuid, req[:params][:template], {
+ :object_type => 'template',
+ :uuid => uuid
+ })
+ uuid = UUIDTools::UUID.timestamp_create.to_s
+ body = "<image><name>#{@tpl.name}</name></image>"
+ iwhd_image = Aeolus::Image::Warehouse::Image.create!(uuid, body, {
+ :uuid => uuid,
+ :object_type => 'image',
+ :template => @tpl.uuid,
+ :environment => @pool_family.name
+ })
+ @image = Aeolus::Image::Factory::Image.new(:id => iwhd_image.id)
+ @image.targets = req[:params][:targets]
+ @image.template = req[:params][:template]
@image.save!
respond_with(@image)
elsif req[:type] == :import
account = ProviderAccount.find_by_label(req[:params][:provider_account_name])
raise(Aeolus::Conductor::API::ProviderAccountNotFound.new(404, t("api.error_messages.provider_account_not_found",
:name => req[:params][:provider_account_name]))) unless account.present?
+ raise Aeolus::Conductor::API::InsufficientParametersSupplied.new(400, t("api.error_messages.environment_required")) if req[:params][:environment].nil?
+ @pool_family = PoolFamily.find_by_name(req[:params][:environment])
+ raise Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.environment_not_found", :environment => req[:params][:environment])) if @pool_family.nil?
+ check_permissions
+ environment_accounts = @pool_family.provider_accounts
+ if !environment_accounts.include?(account)
+ raise(Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.account_not_found_in_environment", :account => account.label, :accounts => environment_accounts.collect{|a|a.label}.join(", "))))
+ end
begin
- @image = Image.import(account, req[:params][:target_identifier], req[:params][:image_descriptor])
+ @image = Image.import(account, req[:params][:target_identifier], @pool_family, req[:params][:image_descriptor])
rescue Aeolus::Conductor::Base::ImageNotFound
raise(Aeolus::Conductor::API::ImageNotFound.new(404, t("api.error_messages.image_not_found_on_provider",
:image => req[:params][:target_identifier])))
@@ -86,6 +122,8 @@ module Api
def destroy
begin
if @image = Aeolus::Image::Warehouse::Image.find(params[:id])
+ @pool_family = PoolFamily.find_by_name(@image.environment)
+ check_permissions
@provider_images = @image.provider_images
if @image.delete!
respond_with(@image, @provider_images)
@@ -103,17 +141,21 @@ module Api
private
def process_post(body)
doc = Nokogiri::XML CGI.unescapeHTML(body)
- if !doc.xpath("/image/targets").empty? && !doc.xpath("/image/tdl/template").empty?
+ if !doc.xpath("/image/targets").empty? && !doc.xpath("/image/tdl/template").empty? && !doc.xpath("/image/environment").empty?
{ :type => :build, :params => { :template => doc.xpath("/image/tdl/template").to_s,
- :targets => doc.xpath("/image/targets").text }
+ :targets => doc.xpath("/image/targets").text,
+ :environment => doc.xpath("/image/environment").text}
}
elsif !doc.xpath("/image/provider_account_name").empty? && !doc.xpath("/image/target_identifier").empty? &&
- !doc.xpath("/image/image_descriptor").empty?
+ !doc.xpath("/image/image_descriptor").empty? && !doc.xpath("/image/environment").empty?
{ :type => :import, :params => { :target_identifier => doc.xpath("/image/target_identifier").text,
:image_descriptor => doc.xpath("/image/image_descriptor").children.first.to_s,
- :provider_account_name => doc.xpath("/image/provider_account_name").text }
+ :provider_account_name => doc.xpath("/image/provider_account_name").text,
+ :environment => doc.xpath("/image/environment").text }
}
+ elsif !doc.xpath("/image").empty? && doc.xpath("/image/environment").empty?
+ { :type => :failed_env }
else
{ :type => :failed }
end
diff --git a/src/app/controllers/api/provider_images_controller.rb b/src/app/controllers/api/provider_images_controller.rb
index 7055cb4..ec98813 100644
--- a/src/app/controllers/api/provider_images_controller.rb
+++ b/src/app/controllers/api/provider_images_controller.rb
@@ -64,12 +64,16 @@ module Api
return
end
+ @pool_family = PoolFamily.find_by_name(target_images.first.build.image.environment)
+ environment_accounts = @pool_family.provider_accounts
@provider_images = []
@errors = []
doc.xpath("/provider_image/provider_account").text.split(",").each do |account_name|
account = ProviderAccount.find_by_label(account_name)
if !account
raise(Aeolus::Conductor::API::ProviderAccountNotFound.new(404, t("api.error_messages.provider_account_not_found", :name => account_name)))
+ elsif !environment_accounts.include?(account)
+ raise(Aeolus::Conductor::API::ParameterDataIncorrect.new(400, t("api.error_messages.account_not_found_in_environment", :account => account.label, :accounts => environment_accounts.collect{|a|a.label}.join(", "))))
end
target_image = find_target_image_for_account(target_images, account)
diff --git a/src/app/controllers/deployables_controller.rb b/src/app/controllers/deployables_controller.rb
index 4e4404f..e37bc4a 100644
--- a/src/app/controllers/deployables_controller.rb
+++ b/src/app/controllers/deployables_controller.rb
@@ -63,7 +63,10 @@ class DeployablesController < ApplicationController
require_privilege(Privilege::VIEW, @deployable)
save_breadcrumb(polymorphic_path([@catalog, @deployable]), @deployable.name)
@providers = Provider.all
- @catalogs_options = Catalog.list_for_user(current_user, Privilege::VIEW).select {|c| !@deployable.catalogs.include?(c)}
+ @catalogs_options = Catalog.list_for_user(current_user, Privilege::VIEW).select do |c|
+ !@deployable.catalogs.include?(c) and
+ @deployable.catalogs.first.pool.pool_family == c.pool.pool_family
+ end
if @catalog.present?
add_permissions_inline(@deployable, '', {:catalog_id => @catalog.id})
@@ -71,28 +74,14 @@ class DeployablesController < ApplicationController
add_permissions_inline(@deployable)
end
- @images_details = @deployable.get_image_details
- images = @deployable.fetch_images
- uuids = @deployable.fetch_image_uuids
- @missing_images = images.zip(uuids).select{|p| p.first.nil?}.map{|p| p.second}
- @images_hash_details = images != [nil] ? @deployable.get_uuids_hash(images) : nil
-
- @images_details.each do |assembly|
- assembly.keys.each do |key|
- @deployable_errors ||= []
- @deployable_errors << "#{assembly[:name]}: #{assembly[key]}" if key.to_s =~ /^error\w+/
- end
- if @missing_images.include?(assembly[:image_uuid])
- @deployable_errors << "#{assembly[:name]}: Image (UUID: #{assembly[:image_uuid]}) doesn't exist."
- end
- flash.now[:error] = @deployable_errors unless @deployable_errors.empty?
- end
+ @images_details, images, @missing_images, @deployable_errors = @deployable.get_image_details
+ flash.now[:error] = @deployable_errors unless @deployable_errors.empty?
return unless @missing_images.empty?
@build_results = {}
@pushed_count = 0
- ProviderAccount.includes(:provider).where('providers.enabled' => true).each do |account|
+ ProviderAccount.includes(:provider, :pool_families).where('providers.enabled' => true, 'pool_families.id' => @deployable.catalogs.first.pool.pool_family.id).each do |account|
type = account.provider.provider_type.deltacloud_driver
@build_results[type] ||= []
status = @deployable.build_status(images, account)
@@ -163,8 +152,8 @@ class DeployablesController < ApplicationController
rescue => e
flash.now[:warning]= t('deployables.flash.warning.failed', :message => e.message) if @deployable.errors.empty?
if params[:create_from_image].present?
- load_catalogs
@image = Aeolus::Image::Warehouse::Image.find(params[:create_from_image])
+ load_catalogs
@hw_profiles = HardwareProfile.frontend.list_for_user(current_user, Privilege::VIEW)
else
@catalog = @selected_catalogs.first
@@ -267,7 +256,8 @@ class DeployablesController < ApplicationController
end
def load_catalogs
- @catalogs = Catalog.list_for_user(current_user, Privilege::MODIFY)
+ @pool_family = PoolFamily.where(:name => @image.environment).first
+ @catalogs = Catalog.includes(:pool).list_for_user(current_user, Privilege::MODIFY).where('pools.pool_family_id' => @pool_family.id)
end
def import_xml_from_url(url)
diff --git a/src/app/controllers/deployments_controller.rb b/src/app/controllers/deployments_controller.rb
index b858723..e36c483 100644
--- a/src/app/controllers/deployments_controller.rb
+++ b/src/app/controllers/deployments_controller.rb
@@ -61,14 +61,15 @@ class DeploymentsController < ApplicationController
redirect_to launch_new_deployments_path(:pool_id => params[:deployment][:pool_id]) and return
end
- @deployable = Deployable.find(params[:deployable_id])
@deployment = Deployment.new(params[:deployment])
@pool = @deployment.pool
+ init_new_deployment_attrs
require_privilege(Privilege::CREATE, Deployment, @pool)
require_privilege(Privilege::USE, @deployable)
- init_new_deployment_attrs
+ img, img2, missing, d_errors = @deployable.get_image_details
+ flash[:error] = d_errors unless d_errors.empty?
- unless @deployable_xml && @deployment.valid_deployable_xml?(@deployable_xml)
+ unless @deployable && @deployable.xml && @deployment.valid_deployable_xml?(@deployable.xml) && d_errors.empty?
render 'launch_new' and return
end
@@ -84,16 +85,17 @@ class DeploymentsController < ApplicationController
end
def overview
- @deployable = Deployable.find(params[:deployable_id])
@deployment = Deployment.new(params[:deployment])
@pool = @deployment.pool
+ init_new_deployment_attrs
require_privilege(Privilege::CREATE, Deployment, @pool)
require_privilege(Privilege::USE, @deployable)
- init_new_deployment_attrs
@launch_parameters_encoded = Base64.encode64(ActiveSupport::JSON.encode(@deployment.launch_parameters))
+ img, img2, missing, d_errors = @deployable.get_image_details
+ flash[:error] = d_errors unless d_errors.empty?
respond_to do |format|
- if @deployable_xml && @deployment.valid_deployable_xml?(@deployable_xml)
+ if @deployable.xml && @deployment.valid_deployable_xml?(@deployable.xml) && d_errors.empty?
@errors = @deployment.check_assemblies_matches(current_user)
set_errors_flash(@errors)
@additional_quota = count_additional_quota(@deployment)
@@ -119,44 +121,54 @@ class DeploymentsController < ApplicationController
@pool = @deployment.pool
require_privilege(Privilege::CREATE, Deployment, @pool)
init_new_deployment_attrs
- @deployment.deployable_xml = @deployable_xml if @deployable_xml
+ @deployment.deployable_xml = @deployable.xml if @deployable && @deployable.xml
if params.has_key?(:deployable_id)
- @deployable = Deployable.find(params[:deployable_id])
require_privilege(Privilege::USE, @deployable)
end
- @deployment.owner = current_user
- load_assemblies_services
- if params.delete(:commit) == 'back'
- view = launch_parameters_encoded.blank? ? 'launch_new' : 'launch_time_params'
- render view and return
- end
-
+ img, img2, missing, d_errors = @deployable.get_image_details
respond_to do |format|
- if @deployment.save
- status = @deployment.launch(current_user)
- if status[:errors].empty?
- flash[:notice] = t "deployments.flash.notice.launched"
- else
- flash[:error] = {
- :summary => t("deployments.flash.error.failed_to_launch_assemblies"),
- :failures => status[:errors],
- :successes => status[:successes]
- }
- end
- format.html { redirect_to deployment_path(@deployment) }
- format.js do
- @deployment_properties = @deployment.properties
- render :partial => 'properties'
- end
- format.json { render :json => @deployment, :status => :created }
- else
- # We need @pool to re-display the form
+ unless d_errors.empty?
@pool = @deployment.pool
flash.now[:warning] = t "deployments.flash.warning.failed_to_launch"
- init_new_deployment_attrs
+ flash[:error] = d_errors
format.html { render :action => 'overview' }
format.js { launch_new }
- format.json { render :json => @deployment.errors, :status => :unprocessable_entity }
+ format.json { render :json => d_errors, :status => :unprocessable_entity }
+ else
+
+ @deployment.owner = current_user
+ load_assemblies_services
+ if params.delete(:commit) == 'back'
+ view = launch_parameters_encoded.blank? ? 'launch_new' : 'launch_time_params'
+ render view and return
+ end
+
+ if @deployment.save
+ status = @deployment.launch(current_user)
+ if status[:errors].empty?
+ flash[:notice] = t "deployments.flash.notice.launched"
+ else
+ flash[:error] = {
+ :summary => t("deployments.flash.error.failed_to_launch_assemblies"),
+ :failures => status[:errors],
+ :successes => status[:successes]
+ }
+ end
+ format.html { redirect_to deployment_path(@deployment) }
+ format.js do
+ @deployment_properties = @deployment.properties
+ render :partial => 'properties'
+ end
+ format.json { render :json => @deployment, :status => :created }
+ else
+ # We need @pool to re-display the form
+ @pool = @deployment.pool
+ flash.now[:warning] = t "deployments.flash.warning.failed_to_launch"
+ init_new_deployment_attrs
+ format.html { render :action => 'overview' }
+ format.js { launch_new }
+ format.json { render :json => @deployment.errors, :status => :unprocessable_entity }
+ end
end
end
end
@@ -372,7 +384,7 @@ class DeploymentsController < ApplicationController
def init_new_deployment_attrs
@deployables = Deployable.list_for_user(current_user, Privilege::USE).select{|d| d.catalogs.collect {|c| c.pool}.include?(@pool)}
@pools = Pool.list_for_user(current_user, Privilege::CREATE, Deployment)
- @deployable_xml = params[:deployable_id] ? Deployable.find(params[:deployable_id]).xml : nil
+ @deployable = params[:deployable_id] ? Deployable.find(params[:deployable_id]) : nil
@realms = FrontendRealm.all
@hardware_profiles = HardwareProfile.all(
:include => :architecture,
diff --git a/src/app/controllers/images_controller.rb b/src/app/controllers/images_controller.rb
index 41108c5..cc2231e 100644
--- a/src/app/controllers/images_controller.rb
+++ b/src/app/controllers/images_controller.rb
@@ -21,8 +21,8 @@ class ImagesController < ApplicationController
def index
set_admin_environments_tabs 'images'
@header = [
- { :name => 'checkbox', :class => 'checkbox', :sortable => false },
{ :name => t('images.index.name'), :sort_attr => :name },
+ { :name => t('images.environment_header'), :sort_attr => :name },
{ :name => t('images.index.os'), :sort_attr => :name },
{ :name => t('images.index.os_version'), :sort_attr => :name },
{ :name => t('images.index.architecture'), :sort_attr => :name },
@@ -37,6 +37,7 @@ class ImagesController < ApplicationController
def show
@image = Aeolus::Image::Warehouse::Image.find(params[:id])
+ @environment = PoolFamily.where('name' => @image.environment).first
if @image.imported?
begin
# For an imported image, we only want to show the actual provider account
@@ -46,12 +47,12 @@ class ImagesController < ApplicationController
type = provider.provider_type
acct = ProviderAccount.enabled.find_by_provider_name_and_login(provider.name, pimg.provider_account_identifier)
raise unless acct
- @account_groups = {type.deltacloud_driver => {:type => type, :accounts => [acct]}}
+ @account_groups = {type.deltacloud_driver => {:type => type, :accounts => [[acct, at environment.provider_accounts.include?(acct)]]}}
rescue Exception => e
- @account_groups = ProviderAccount.enabled.group_by_type(current_user)
+ @account_groups = ProviderAccount.enabled.group_by_type(@environment)
end
else
- @account_groups = ProviderAccount.enabled.group_by_type(current_user)
+ @account_groups = ProviderAccount.enabled.group_by_type(@environment)
end
# according to imagefactory Builder.first shouldn't be implemented yet
# but it does what we need - returns builder object which contains
@@ -74,8 +75,8 @@ class ImagesController < ApplicationController
active_pushes = @account_groups.inject({}) do |result, (driver, group)|
timg = @target_images_by_target[driver]
group[:accounts].each do |account|
- result[account.id] = @builder.find_active_push(timg.id, account.provider.name, account.credentials_hash['username'])
- result[account.id].attributes['status'].capitalize! if result[account.id]
+ result[account[0].id] = @builder.find_active_push(timg.id, account[0].provider.name, account.credentials_hash['username'])
+ result[account[0].id].attributes['status'].capitalize! if result[account[0].id]
end if timg.present?
result
@@ -84,7 +85,7 @@ class ImagesController < ApplicationController
provider_images = @account_groups.inject({}) do |result, (driver, group)|
timg = @target_images_by_target[driver]
group[:accounts].each do |account|
- result[account.id] = timg.find_provider_image_by_provider_and_account(account.provider.name, account.credentials_hash['username']).first
+ result[account[0].id] = timg.find_provider_image_by_provider_and_account(account[0].provider.name, account[0].credentials_hash['username']).first
end if timg.present?
result
@@ -98,7 +99,7 @@ class ImagesController < ApplicationController
failed_push_counts = @account_groups.inject({}) do |result, (driver, group)|
timg = @target_images_by_target[driver]
group[:accounts].each do |account|
- result[account.id] = @builder.failed_push_count(timg.id, account.provider.name, account.credentials_hash['username'])
+ result[account[0].id] = @builder.failed_push_count(timg.id, account[0].provider.name, account[0].credentials_hash['username'])
end if timg.present?
result
@@ -120,7 +121,8 @@ class ImagesController < ApplicationController
def rebuild_all
@image = Aeolus::Image::Warehouse::Image.find(params[:id])
- targets = Provider.enabled.list_for_user(current_user, Privilege::VIEW).map {|p| p.provider_type.deltacloud_driver}.uniq
+ @environment = PoolFamily.where('name' => @image.environment).first
+ targets = @environment.build_targets
unless targets.empty?
factory_image = Aeolus::Image::Factory::Image.new(:id => @image.id)
factory_image.targets = targets.join(',')
@@ -132,13 +134,14 @@ class ImagesController < ApplicationController
def push_all
@image = Aeolus::Image::Warehouse::Image.find(params[:id])
+ @environment = PoolFamily.where('name' => @image.environment).first
@build = Aeolus::Image::Warehouse::ImageBuild.find(params[:build_id])
# only latest builds can be pushed
unless latest_build?(@build)
redirect_to image_path(@image.id)
return
end
- accounts = ProviderAccount.list_for_user(current_user, Privilege::VIEW)
+ accounts = @environment.provider_accounts
target_images = @build.target_images
accounts.each do |account|
if account.image_status(@image) == :not_pushed
@@ -169,20 +172,21 @@ class ImagesController < ApplicationController
end
def new
+ @environment = PoolFamily.find(params[:environment])
if 'import' == params[:tab]
- @accounts = ProviderAccount.enabled.list_for_user(current_user, Privilege::USE)
+ @accounts = @environment.provider_accounts.enabled.list_for_user(current_user, Privilege::USE)
render :import and return
- else
- @environment = PoolFamily.find(params[:environment])
end
end
def import
account = ProviderAccount.find(params[:provider_account])
+ @environment = PoolFamily.find(params[:environment])
+
xml = "<image><name>#{params[:name]}</name></image>" unless params[:name].blank?
begin
- image = Image.import(account, params[:image_id], xml)
+ image = Image.import(account, params[:image_id], @environment, xml)
flash[:success] = t("images.import.image_imported")
redirect_to image_url(image.id) and return
rescue Exception => e
@@ -283,7 +287,8 @@ class ImagesController < ApplicationController
@image = Aeolus::Image::Warehouse::Image.create!(uuid, body, {
:uuid => uuid,
:object_type => 'image',
- :template => @tpl.uuid
+ :template => @tpl.uuid,
+ :environment => @environment.name
})
flash.now[:error] = t('images.flash.notice.created')
redirect_to image_path(@image.id)
diff --git a/src/app/controllers/pool_families_controller.rb b/src/app/controllers/pool_families_controller.rb
index 98322eb..d9398ed 100644
--- a/src/app/controllers/pool_families_controller.rb
+++ b/src/app/controllers/pool_families_controller.rb
@@ -74,7 +74,7 @@ class PoolFamiliesController < ApplicationController
@pool_family = PoolFamily.find(params[:id])
save_breadcrumb(pool_family_path(@pool_family), @pool_family.name)
require_privilege(Privilege::VIEW, @pool_family)
- @images = Aeolus::Image::Warehouse::Image.all
+ @images = Aeolus::Image::Warehouse::Image.by_environment(@pool_family.name)
load_pool_family_tabs
respond_to do |format|
diff --git a/src/app/models/deployable.rb b/src/app/models/deployable.rb
index c9df4c5..6d33eef 100644
--- a/src/app/models/deployable.rb
+++ b/src/app/models/deployable.rb
@@ -117,28 +117,49 @@ class Deployable < ActiveRecord::Base
#get details of image for deployable#show
def get_image_details
deployable_xml = DeployableXML.new(xml)
+ uuids = deployable_xml.image_uuids
+ images = []
+ missing_images = []
assemblies_array ||= []
+ deployable_errors ||= []
deployable_xml.assemblies.each do |assembly|
- assembly_hash ||= {:name => assembly.name}
+ assembly_hash = {}
+ image = Aeolus::Image::Warehouse::Image.find(assembly.image_id)
+ if image.nil?
+ missing_images << assembly.image_id
+ deployable_errors << I18n.t("deployables.flash.error.missing_image",
+ :assembly => assembly.name,
+ :uuid => assembly.image_id)
+ else
+ if image.environment != catalogs.first.pool.pool_family.name
+ deployable_errors << I18n.t("deployables.flash.error.wrong_environment",
+ :assembly => assembly.name,
+ :uuid => assembly.image_id,
+ :wrong_env => image.environment,
+ :environment => catalogs.first.pool.pool_family.name)
+ end
+ images << image
+ assembly_hash[:build_and_target_uuids] = get_build_and_target_uuids(image)
+ end
+ assembly_hash[:name] = assembly.name
assembly_hash[:image_uuid] = assembly.image_id
assembly_hash[:images_count] = assembly.images_count
if assembly.hwp
- hwp_name = assembly.hwp
- hwp = HardwareProfile.find_by_name(hwp_name)
+ hwp = HardwareProfile.find_by_name(assembly.hwp)
if hwp
assembly_hash[:hwp_name] = hwp.name
assembly_hash[:hwp_hdd] = hwp.storage.value
assembly_hash[:hwp_ram] = hwp.memory.value
assembly_hash[:hwp_arch] = hwp.architecture.value
else
- assembly_hash[:error_hwp] = I18n.t('deployables.error.hwp_not_exists', :name => hwp_name)
+ deployable_errors << "#{assembly_hash[:name]}: " + I18n.t('deployables.error.hwp_not_exists', :name => assembly.hwp)
end
else
- assembly_hash[:error_hwp] = I18n.t('deployables.error.attribute_not_exist')
+ deployable_errors << "#{assembly_hash[:name]}: " + I18n.t('deployables.error.attribute_not_exist')
end
assemblies_array << assembly_hash
end
- assemblies_array
+ [assemblies_array, images, missing_images, deployable_errors]
end
def build_status(images, account)
@@ -156,29 +177,11 @@ class Deployable < ActiveRecord::Base
[catalog, self]
end
- def get_uuids_hash(images)
- image_uuids = []
- target_image_uuids = []
- latest_build_uuid = []
-
- images.each do |i|
- image_uuids << (i.respond_to?(:uuid) ? i.uuid : nil)
- latest_build = i.latest_pushed_build if i.respond_to?(:latest_pushed_build)
- latest_build_uuid << (latest_build ? latest_build.uuid : nil)
- if latest_build
- target_images = latest_build.target_images
- target_image_uuids_for_build = []
- target_images.each do |ti|
- target_image_uuids_for_build << ti.uuid
- end
- target_image_uuids << target_image_uuids_for_build
- else
- target_image_uuids << nil
- end
- end
-
- #return array [[image_uuid, latest_build_uuid, [target_image_uuids]], [..]]
- image_uuids.zip(latest_build_uuid, target_image_uuids)
+ def get_build_and_target_uuids(image)
+ latest_build = image.respond_to?(:latest_pushed_build) ? image.latest_pushed_build : nil
+ [(image.respond_to?(:uuid) ? image.uuid : nil),
+ (latest_build ? latest_build.uuid : nil),
+ (latest_build ? latest_build.target_images.collect { |ti| ti.uuid} : nil)]
end
private
diff --git a/src/app/models/pool_family.rb b/src/app/models/pool_family.rb
index 9bb54b7..3e834a0 100644
--- a/src/app/models/pool_family.rb
+++ b/src/app/models/pool_family.rb
@@ -83,4 +83,11 @@ class PoolFamily < ActiveRecord::Base
:available_quota => avail,
}
end
+ def build_targets
+ targets = []
+ ProviderAccount.enabled.group_by_type(self).each do |driver, group|
+ targets << driver if group[:included]
+ end
+ targets
+ end
end
diff --git a/src/app/models/provider_account.rb b/src/app/models/provider_account.rb
index 251a1e8..aa450eb 100644
--- a/src/app/models/provider_account.rb
+++ b/src/app/models/provider_account.rb
@@ -316,12 +316,16 @@ class ProviderAccount < ActiveRecord::Base
PRESET_FILTERS_OPTIONS = []
- def self.group_by_type(user)
+ def self.group_by_type(pool_family)
res = {}
- ProviderAccount.list_for_user(user, Privilege::VIEW).each do |account|
+ family_accounts = pool_family.nil? ? [] : pool_family.provider_accounts
+ ProviderAccount.enabled.each do |account|
ptype = account.provider.provider_type
res[ptype.deltacloud_driver] ||= {:type => ptype, :accounts => []}
- res[ptype.deltacloud_driver][:accounts] << account
+ res[ptype.deltacloud_driver][:accounts] << [account, family_accounts.include?(account)]
+ end
+ res.each do |driver, group|
+ group[:included] = (group[:accounts].count{|a| a[1]} > 0)
end
res
end
diff --git a/src/app/views/api/environments/_environment.xml.haml b/src/app/views/api/environments/_environment.xml.haml
new file mode 100644
index 0000000..5fd425f
--- /dev/null
+++ b/src/app/views/api/environments/_environment.xml.haml
@@ -0,0 +1,9 @@
+!!!XML
+%environment{:id => environment.id, :href => api_image_url(environment.id) }
+ %name= environment.name
+ %description= environment.description
+ %targets{:type => 'xs:list'}
+ - ProviderAccount.enabled.group_by_type(environment).select{|driver,group| group[:included]}.each do |driver, group|
+ %target{:name => driver}
+ - group[:accounts].select{|account| account[1]==true}.each do |account|
+ %account{:name => account[0].name}
diff --git a/src/app/views/api/environments/index.xml.haml b/src/app/views/api/environments/index.xml.haml
new file mode 100644
index 0000000..a3ff564
--- /dev/null
+++ b/src/app/views/api/environments/index.xml.haml
@@ -0,0 +1,4 @@
+!!!XML
+%environments
+ - @environments.each do |env|
+ = render :partial => 'environment', :locals => {:environment => env}
diff --git a/src/app/views/api/environments/show.xml.haml b/src/app/views/api/environments/show.xml.haml
new file mode 100644
index 0000000..21e5fac
--- /dev/null
+++ b/src/app/views/api/environments/show.xml.haml
@@ -0,0 +1,2 @@
+!!! XML
+= render :partial => "environment", :locals => {:environment => @environment}
diff --git a/src/app/views/api/images/_image.xml.haml b/src/app/views/api/images/_image.xml.haml
index f19b1e6..bfabbde 100644
--- a/src/app/views/api/images/_image.xml.haml
+++ b/src/app/views/api/images/_image.xml.haml
@@ -1,6 +1,7 @@
!!!XML
%image{:id => image.id, :href => api_image_url(image.id) }
%name= image.name
+ %environment= image.environment
%description= image.description
%os= image.os.name
%os_version= image.os.version
diff --git a/src/app/views/deployables/_image_uuids.html.haml b/src/app/views/deployables/_image_uuids.html.haml
index 91902a2..9445641 100644
--- a/src/app/views/deployables/_image_uuids.html.haml
+++ b/src/app/views/deployables/_image_uuids.html.haml
@@ -4,20 +4,20 @@
%td
%strong="#{t("deployables.show.image_uuid")}"
%td
- ="#{(@images_hash_details[index][0].nil? ? t('deployables.show.n_a') : @images_hash_details[index][0])}"
+ ="#{(uuid_arr[0].nil? ? t('deployables.show.n_a') : uuid_arr[0])}"
%tr
%td
%strong="#{t("deployables.show.latest_build_uuid")}"
%td
- ="#{(@images_hash_details[index][1].nil? ? t("deployables.show.n_a") : @images_hash_details[index][1])}"
+ ="#{(uuid_arr[1].nil? ? t("deployables.show.n_a") : uuid_arr[1])}"
%tr
%td
%strong="#{t("deployables.show.target_images_uuids")}"
%td
- - if @images_hash_details[index][2].nil?
+ - if uuid_arr[2].nil?
=t'deployables.show.n_a'
- else
%ul
- - @images_hash_details[index][2].each do |image_uuid|
+ - uuid_arr[2].each do |image_uuid|
%li
=image_uuid
diff --git a/src/app/views/deployables/show.html.haml b/src/app/views/deployables/show.html.haml
index 772536f..504016e 100644
--- a/src/app/views/deployables/show.html.haml
+++ b/src/app/views/deployables/show.html.haml
@@ -31,7 +31,7 @@
%th.align-center=t'.arch'
%th=t(".uuids")
%tbody
- - @images_details.each_with_index do |assembly, index|
+ - @images_details.each do |assembly|
%tr
%td.status= image_valid?(assembly)
%td
@@ -42,16 +42,16 @@
%td.align-center=assembly[:hwp_ram]
%td.align-center=assembly[:hwp_arch]
%td.align-center
- - if @images_hash_details.nil?
+ - if assembly[:build_and_target_uuids].nil?
= t(".n_a")
- else
%a.control{:href => '#'}=t(".show_hide_uuids")
- - unless @images_hash_details.nil?
+ - unless assembly[:build_and_target_uuids].nil?
%tr.collapsed
%td
%td{:colspan => 7}
%ul
- = render :partial => "image_uuids", :locals => {:index => index}
+ = render :partial => "image_uuids", :locals => {:uuid_arr => assembly[:build_and_target_uuids]}
%section.admin-content-section
- if @missing_images.empty?
diff --git a/src/app/views/deployments/launch_from_catalog.html.haml b/src/app/views/deployments/launch_from_catalog.html.haml
index 8b37b1b..923ba64 100644
--- a/src/app/views/deployments/launch_from_catalog.html.haml
+++ b/src/app/views/deployments/launch_from_catalog.html.haml
@@ -30,7 +30,7 @@
%th=t'.arch'
%th
%strong=t'.deployable_xml'
- -deployable.get_image_details.each do |assembly|
+ -deployable.get_image_details.first.each do |assembly|
%tr
%td
%strong= assembly[:image_uuid]
diff --git a/src/app/views/images/_list.html.haml b/src/app/views/images/_list.html.haml
index d75ea59..635297f 100644
--- a/src/app/views/images/_list.html.haml
+++ b/src/app/views/images/_list.html.haml
@@ -1,22 +1,33 @@
- content_for :form_header do
- - if check_privilege(Privilege::USE, PoolFamily)
+ - if @pool_family and check_privilege(Privilege::USE, @pool_family)
%li= restful_submit_tag t("delete"), "destroy", multi_destroy_images_path, 'DELETE', :id => 'delete_button', :class => 'button danger'
- %li= link_to t('images.import.import_image'), new_image_path(:tab => 'import'), { :class => 'button primary', :id => 'import_image_button'}
- - if @pool_family
- %li= link_to t('images.index.new'), new_image_path(:environment => @pool_family), { :class => 'button primary', :id => 'import_image_button'}
+ %li= link_to t('images.import.import_image'), new_image_path(:tab => 'import', :environment => @pool_family), { :class => 'button primary', :id => 'import_image_button'}
+ %li= link_to t('images.index.new'), new_image_path(:environment => @pool_family), { :class => 'button primary', :id => 'import_image_button'}
= filter_table(@header, @images) do |image|
- %tr{:class => cycle('nostripe','stripe')}
- %td{:class => 'checkbox'}
- - selected = params[:select] == 'all'
- = check_box_tag "images_selected[]", image.id, selected, :id => "image_checkbox_#{image.id}"
- %td
- = link_to (image.imported? ? image.name + " (Imported)" : image.name), image_path(image.id)
- %td
- = image.os.name.empty? ? "N/A" : image.os.name
- %td
- = image.os.version.empty? ? "N/A" : image.os.version
- %td
- = image.os.arch.empty? ? "N/A" : image.os.arch
- %td
- = Time.at(image.latest_pushed_or_unpushed_build.timestamp.to_f) rescue ''
+ - if @pool_family.nil? and image.environment
+ - environment = PoolFamily.find_by_name(image.environment)
+ - else
+ - environment = nil
+ - if environment.nil? or check_privilege(Privilege::USE, PoolFamily, environment)
+ %tr{:class => cycle('nostripe','stripe')}
+ - if @pool_family
+ %td{:class => 'checkbox'}
+ - selected = params[:select] == 'all'
+ = check_box_tag "images_selected[]", image.id, selected, :id => "image_checkbox_#{image.id}"
+ %td
+ = link_to (image.imported? ? image.name + " (Imported)" : image.name), image_path(image.id)
+ - unless @pool_family
+ %td
+ - if environment
+ = link_to environment.name, pool_family_path(environment, :details_tab => 'images')
+ - else
+ N/A
+ %td
+ = image.os.name.empty? ? "N/A" : image.os.name
+ %td
+ = image.os.version.empty? ? "N/A" : image.os.version
+ %td
+ = image.os.arch.empty? ? "N/A" : image.os.arch
+ %td
+ = Time.at(image.latest_pushed_or_unpushed_build.timestamp.to_f) rescue ''
diff --git a/src/app/views/images/import.html.haml b/src/app/views/images/import.html.haml
index e1c759b..f725b74 100644
--- a/src/app/views/images/import.html.haml
+++ b/src/app/views/images/import.html.haml
@@ -2,11 +2,14 @@
%header.admin-page-header
%h1.images= t('.import_image')
#obj_actions.button-container
+ = t :return_to
+ = link_to t('images.environment', :environment => @environment.name), pool_family_path(@environment), :class => 'rounded-link'
%section.admin-content-section.image-import
%section#image-file-form
= form_tag(import_images_path, { :multipart => true, :method => :post, :class => :generic }) do
+ = hidden_field_tag :environment, @environment.id
%fieldset
%p
= label_tag :provider_account, t('.provider_account')
diff --git a/src/app/views/images/show.html.haml b/src/app/views/images/show.html.haml
index e26a720..5abb90e 100644
--- a/src/app/views/images/show.html.haml
+++ b/src/app/views/images/show.html.haml
@@ -6,20 +6,23 @@
= link_to t('images.index.images'), images_path, :class => 'rounded-link'
- if check_privilege(Privilege::USE, PoolFamily)
.button-group
- = link_to t('.new_deployable_from_image'), new_deployable_path(:create_from_image => @image.id), :class => 'button pill'
+ - if @environment
+ = link_to t('.new_deployable_from_image'), new_deployable_path(:create_from_image => @image.id), :class => 'button pill'
- unless @image.imported?
= link_to t('.template_xml'), template_image_path(@image.uuid), :class => 'button'
= button_to t("delete"), image_path(@image.id), :method => 'delete', :confirm => "Are you sure you want to delete?", :class => 'button pill danger', :id => 'delete'
%section.admin-content-section
%header
+ %h2=t'properties'
+ %h3= t('images.environment', :environment => @image.environment)
%h2= t('.provider_images')
.section-controls
= t'.view_build'
= form_tag image_path(@image.id), :method => :get do
= select_tag :build, options_for_build_select(@builds, @build, @latest_build)
= submit_tag t('.select_build'), :id => 'seletect_build_button'
- - if check_privilege(Privilege::USE, PoolFamily)
+ - if check_privilege(Privilege::USE, PoolFamily) and @environment
- if @image.imported?
= t('.can_not_build_imported_image')
-else
@@ -28,7 +31,7 @@
= button_to t('.push_all'), push_all_image_path(@image.id, :build_id => @build.id), :class => 'button pill'
.content
%ul.image_builds
- - @account_groups.each do |driver, group|
+ - @account_groups.select{|driver,group| group[:included] || @target_images_by_target[driver] || (@build and @builder.find_active_build(@build.id, driver))}.each do |driver, group|
- timg = @target_images_by_target[driver]
%li
%dl
@@ -62,23 +65,23 @@
= t'.image_uri'
%th.image_controls
%tbody
- - group[:accounts].each do |account|
- - pimg = timg ? timg.find_provider_image_by_provider_and_account(account.provider.name, account.credentials_hash['username']).first : nil
+ - group[:accounts].select{|account| account[1]==true || (timg and !timg.find_provider_image_by_provider_and_account(account[0].provider.name, account[0].credentials_hash['username']).empty?)}.each do |account|
+ - pimg = timg ? timg.find_provider_image_by_provider_and_account(account[0].provider.name, account[0].credentials_hash['username']).first : nil
%tr
%td
- %strong= account.name
+ %strong= account[0].name
%td.light
- = account.provider.name
+ = account[0].provider.name
%td.light
= pimg ? pimg.target_identifier : ''
%td.light
= pimg ? pimg.id : ''
%td.image_controls.light
- - if timg and b = @builder.find_active_push(timg.id, account.provider.name, account.credentials_hash['username'])
+ - if timg and b = @builder.find_active_push(timg.id, account[0].provider.name, account[0].credentials_hash['username'])
= label_tag b.status
- elsif timg and not pimg and @build and @build.id == @latest_build
- = button_to t('.upload'), image_provider_images_path(@image.id, :build_id => @build.id, :target_image_id => timg.id, :account_id => account.id), :method => :post, :class => 'upload_image'
- - failed_push_count = @builder.failed_push_count(timg.id, account.provider.name, account.credentials_hash['username'])
+ = button_to t('.upload'), image_provider_images_path(@image.id, :build_id => @build.id, :target_image_id => timg.id, :account_id => account[0].id), :method => :post, :class => 'upload_image'
+ - failed_push_count = @builder.failed_push_count(timg.id, account[0].provider.name, account[0].credentials_hash['username'])
- if failed_push_count > 0
= t('images.show.failed_push_attempts', :count => failed_push_count )
- elsif pimg
diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
index 505be04..117861f 100644
--- a/src/config/locales/en.yml
+++ b/src/config/locales/en.yml
@@ -716,6 +716,7 @@ en:
not_found: Target Image not found
images:
environment: %{environment} Environment
+ environment_header: Environment
import:
import_image: Import Image
provider_account: Provider Account
@@ -903,6 +904,8 @@ en:
not_selected: "No deployable was not selected!"
no_catalog_exists: "No catalog exists! Please create one."
no_hwp_exists: "No hardware profile exists! Please create one."
+ missing_image: "%{assembly}: Image (UUID: %{uuid}) doesn't exist"
+ wrong_environment: "%{assembly}: Image (UUID: %{uuid}) belongs to the wrong environment (%{wrong_env}) instead of %{environment}"
warning:
failed: "Deployable was not created: %{message}"
notice:
@@ -1283,7 +1286,10 @@ en:
create_new: Create a new Realm Mapping
api:
error_messages:
+ account_not_found_in_environment: "Provider Account %{account} is not in this environment. Valid accounts include %{accounts}."
build_not_found: Could not find Build %{build}
+ environment_required: "Environment parameter is required."
+ environment_not_found: "Environment %{environment} was not found."
image_not_found: Could not find Image %{image}
image_not_found_on_provider: "Could not find Image %{image} on provider"
in_grabbing_target_images: "In grabbing list of target images: %{error}"
@@ -1298,10 +1304,12 @@ en:
provider_image_status_not_found: Could not find status for ProviderImage %{providerimage}
push_error: "Could not push TargetImage %{targetimage} to %{account} and error %{error}"
specify_a_type_build_or_import: Please specify a type, build or import
+ specify_environment: Please specify an environment
target_image_status_not_found: Could not find status for TargetImage %{targetimage}
target_image_not_found: Could not find TargetImage %{targetimage}
target_image_not_found_for_account: Could not find an appropriate target image for account %{account}
target_not_found: Could not find Target %{target}
+ target_not_found_in_environment: Target %{target} has no provider accounts in this environment. Valid targets include %{targets}."
support:
array:
words_connector: ', '
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 3d440a8..d24f039 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -262,6 +262,10 @@ Conductor::Application.routes.draw do
# :except => [:new, :edit]
resources :hooks
+
+ resources :environments do
+ resources :images
+ end
end
scope "/api" do
diff --git a/src/features/deployables.feature b/src/features/deployables.feature
index a3290cf..f63670c 100644
--- a/src/features/deployables.feature
+++ b/src/features/deployables.feature
@@ -7,6 +7,7 @@ Feature: Manage Catalog Entries
Given I am an authorised user
And I am logged in
And there is mock provider account "mock_account"
+ And there is a provider account "mock_account" related to pool family "default"
Scenario: Create new catalog entry
Given there is a "default" catalog
diff --git a/src/features/deployment.feature b/src/features/deployment.feature
index 0ef9119..a4e80e8 100644
--- a/src/features/deployment.feature
+++ b/src/features/deployment.feature
@@ -185,9 +185,8 @@ Feature: Manage Deployments
When I select "test_catalog_entry" from "deployable_id"
When I fill in "deployment_name" with "mynewdeployment"
When I press "next_button"
- Then I should see "Are you sure you wish to deploy"
And I should see an error message
- And I should see "front_hwp2 not found."
+ And I should see "Hardware profile front_hwp2 specified in XML doesn't exist."
Scenario: Verify that the launch parameters are displayed
Given a pool "mockpool" exists
diff --git a/src/lib/image.rb b/src/lib/image.rb
index 02bfdba..b9ce9b7 100644
--- a/src/lib/image.rb
+++ b/src/lib/image.rb
@@ -17,7 +17,7 @@
class Image
# Given a ProviderAccount and an AMI/image ID on a provider, plus an optional XML string, use aeolus-image
# to import the image. Returns an Aeolus::Image::Factory::Image or allows exceptions to bubble up
- def self.import(provider_account, image_id, xml=nil)
+ def self.import(provider_account, image_id, environment, xml=nil)
raise Aeolus::Conductor::Base::BlankImageId unless image_id.present?
# Verify that the image exists prior to import
conn = provider_account.connect
@@ -27,6 +27,8 @@ class Image
xml ||= "<image><name>#{img.name}</name></image>" if img.name.present?
provider = provider_account.provider
account_id = provider_account.credentials_hash['username']
- Aeolus::Image.import(provider.name, provider.provider_type.deltacloud_driver, image_id, account_id, xml)
+ image = Aeolus::Image.import(provider.name, provider.provider_type.deltacloud_driver, image_id, account_id, xml)
+ image.set_attr("environment", environment.name)
+ image
end
end
diff --git a/src/spec/controllers/api/images_controller_spec.rb b/src/spec/controllers/api/images_controller_spec.rb
index ccce985..718ae9f 100644
--- a/src/spec/controllers/api/images_controller_spec.rb
+++ b/src/spec/controllers/api/images_controller_spec.rb
@@ -33,6 +33,7 @@ describe Api::ImagesController do
:provider => "provider")
@image = mock(Aeolus::Image::Warehouse::Image,
:id => '5',
+ :environment => 'default',
:os => @os,
:name => 'test',
:description => 'test image',
@@ -40,15 +41,24 @@ describe Api::ImagesController do
:build => @build,
:provider_images => [@provider_image, @provider_image.clone]
)
- @provider_account = mock(ProviderAccount,
- :label => 'mock',
- :credentials_hash => {'username' => 'foo', 'password' => 'bar'})
@provider_type = mock(ProviderType,
:name => 'mock',
:deltacloud_driver => 'mock')
@provider = mock(Provider,
:name => 'mock',
+ :enabled => true,
:provider_type => @provider_type)
+ @provider_account = mock(ProviderAccount,
+ :label => 'mock',
+ :provider => @provider,
+ :credentials_hash => {'username' => 'foo', 'password' => 'bar'})
+ @environment = mock(PoolFamily, :name => 'default')
+ ProviderAccount.any_instance.stub(:pool_families).and_return([@environment])
+ ProviderAccount.stub(:group_by_type).and_return(
+ "mock" => {:type => @provider_type,
+ :included => true,
+ :accounts => [@provider_account, true]})
+ PoolFamily.any_instance.stub(:provider_accounts).and_return([@provider_account])
Aeolus::Image::Warehouse::ImageBuild.stub(:where).and_return([@build])
end
@@ -82,6 +92,7 @@ describe Api::ImagesController do
@image_collection.each_with_index do |image, index|
resp['images']['image'][index]['name'].should == image.name
resp['images']['image'][index]['id'].should == image.id
+ resp['images']['image'][index]['environment'].should == image.environment
resp['images']['image'][index]['os'].should == image.os.name
resp['images']['image'][index]['arch'].should == image.os.arch
resp['images']['image'][index]['os_version'].should == image.os.version
@@ -105,6 +116,7 @@ describe Api::ImagesController do
resp = Hash.from_xml(response.body)
resp['images']['image']['name'].should == @image.name
resp['images']['image']['id'].should == @image.id
+ resp['images']['image']['environment'].should == @image.environment
resp['images']['image']['os'].should == @image.os.name
resp['images']['image']['arch'].should == @image.os.arch
resp['images']['image']['os_version'].should == @image.os.version
@@ -146,6 +158,7 @@ describe Api::ImagesController do
resp = Hash.from_xml(response.body)
resp['image']['name'].should == @image.name
resp['image']['id'].should == @image.id
+ resp['image']['environment'].should == @image.environment
resp['image']['os'].should == @image.os.name
resp['image']['arch'].should == @image.os.arch
resp['image']['os_version'].should == @image.os.version
@@ -231,9 +244,12 @@ describe Api::ImagesController do
parent.add_child(Nokogiri::XML(tpl).root)
target "mock"
}
+ environment "default"
}
end
Aeolus::Image::Factory::Image.stub(:new).and_return(@image)
+ @image.stub(:targets=).and_return(@image)
+ @image.stub(:template=).and_return(@image)
@image.stub(:save!)
Aeolus::Image::Factory::TargetImage.stub(:status).and_return(nil)
@@ -261,12 +277,14 @@ describe Api::ImagesController do
child "c2"
}
provider_account_name "mock"
+ environment "default"
}
end
Aeolus::Image::Factory::Image.stub(:new).and_return(@image)
ProviderAccount.stub(:find_by_label).and_return(@provider_account)
@provider_account.stub(:provider).and_return(@provider)
@image.stub(:save!)
+ @image.stub(:set_attr)
# We previously stubbed this out to return nil... That's inappropriate here:
Aeolus::Image::Warehouse::Image.stub(:find).and_return(@image)
@provider_image.stub(:set_attr)
@@ -300,12 +318,14 @@ describe Api::ImagesController do
child "c4"
}
provider_account_name "mock2"
+ environment "default"
}
end
Aeolus::Image::Factory::Image.stub(:new).and_return(@image)
ProviderAccount.stub(:find_by_label).and_return(@provider_account)
@provider_account.stub(:provider).and_return(@provider)
@image.stub(:save!)
+ @image.stub(:set_attr)
# We previously stubbed this out to return nil... That's inappropriate here:
Aeolus::Image::Warehouse::Image.stub(:find).and_return(@image)
@provider_image.stub(:set_attr)
diff --git a/src/spec/controllers/api/provider_images_controller_spec.rb b/src/spec/controllers/api/provider_images_controller_spec.rb
index 162f9ee..51a2e9a 100644
--- a/src/spec/controllers/api/provider_images_controller_spec.rb
+++ b/src/spec/controllers/api/provider_images_controller_spec.rb
@@ -56,7 +56,7 @@ describe Api::ProviderImagesController do
:build => @build)
@build1 = mock(Aeolus::Image::Warehouse::ImageBuild, :target_images => [@target_image, @target_image])
@build2 = mock(Aeolus::Image::Warehouse::ImageBuild, :target_images => [@target_image, @target_image])
- @image = mock(Aeolus::Image::Warehouse::Image, :image_builds => [@build1, @build2])
+ @image = mock(Aeolus::Image::Warehouse::Image, :image_builds => [@build1, @build2], :environment => 'default')
end
it "should raise bad request when no provider account is given" do
@@ -347,6 +347,7 @@ describe Api::ProviderImagesController do
context "when trying to build image" do
before(:each) do
@provider_account = FactoryGirl.create :mock_provider_account
+ @provider_account.pool_families << PoolFamily.find_by_name('default')
xml = Nokogiri::XML::Builder.new do |x|
x.provider_image {
x.image_id "17"
@@ -362,7 +363,7 @@ describe Api::ProviderImagesController do
:target => 'mock')
@build1 = mock(Aeolus::Image::Warehouse::ImageBuild, :id=>'3', :target_images => [@target_image, @target_image])
@build2 = mock(Aeolus::Image::Warehouse::ImageBuild, :id=>'2', :target_images => [@target_image, @target_image])
- @image = mock(Aeolus::Image::Warehouse::Image, :id=>'1', :image_builds => [@build1, @build2])
+ @image = mock(Aeolus::Image::Warehouse::Image, :id=>'1', :image_builds => [@build1, @build2], :environment => 'default')
@build1.stub(:image).and_return(@image)
@build2.stub(:image).and_return(@image)
diff --git a/src/spec/controllers/deployables_controller_spec.rb b/src/spec/controllers/deployables_controller_spec.rb
index 65583cb..72d89f4 100644
--- a/src/spec/controllers/deployables_controller_spec.rb
+++ b/src/spec/controllers/deployables_controller_spec.rb
@@ -23,13 +23,14 @@ describe DeployablesController do
@admin_permission = FactoryGirl.create :admin_permission
@admin = @admin_permission.user
mock_warden(@admin)
+ @catalog = FactoryGirl.create(:catalog)
end
describe "#new" do
context "with params[:create_from_image]" do
before do
@deployable = stub_model(Deployable, :name => "test_new", :id => 1)
- @image = mock(Aeolus::Image::Warehouse::Image, :id => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :name => 'image1', :uuid => '3c58e0d6-d11a-4e68-8b12-233783e56d35')
+ @image = mock(Aeolus::Image::Warehouse::Image, :id => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :name => 'image1', :uuid => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :environment => "default")
Aeolus::Image::Warehouse::Image.stub(:find).and_return(@image)
end
@@ -39,13 +40,13 @@ describe DeployablesController do
end
it "returns flash[:error] when no catalog and hardware profile exists" do
- Catalog.stub(:list_for_user).and_return([])
+ Catalog.stub(:list_for_user).and_return(Catalog.includes(:pool).where("1=0"))
get :new, :create_from_image => @image.id
flash[:error].should_not be_empty
end
it "returns flash[:error] when no catalog exists" do
- Catalog.stub(:list_for_user).and_return([])
+ Catalog.stub(:list_for_user).and_return(Catalog.includes(:pool).where("1=0"))
HardwareProfile.stub(:list_for_user).and_return([mock(HardwareProfile)])
get :new, :create_from_image => @image.id
flash[:error].should eql(["No catalog exists! Please create one."])
@@ -55,7 +56,7 @@ describe DeployablesController do
describe "#create" do
before(:each) do
- @image = mock(Aeolus::Image::Warehouse::Image, :id => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :name => 'image1', :uuid => '3c58e0d6-d11a-4e68-8b12-233783e56d35')
+ @image = mock(Aeolus::Image::Warehouse::Image, :id => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :name => 'image1', :uuid => '3c58e0d6-d11a-4e68-8b12-233783e56d35', :environment => "default")
Aeolus::Image::Warehouse::Image.stub(:find).and_return(@image)
end
@@ -67,8 +68,7 @@ describe DeployablesController do
it "creates new deployable from image via POST" do
hw_profile = FactoryGirl.create(:front_hwp1)
- catalog = FactoryGirl.create(:catalog)
- post(:create, :create_from_image => @image.id, :deployable => {:name => @image.name}, :hardware_profile => hw_profile.id, :catalog_id => catalog.id)
+ post(:create, :create_from_image => @image.id, :deployable => {:name => @image.name}, :hardware_profile => hw_profile.id, :catalog_id => @catalog.id)
response.should be_redirect
end
end
diff --git a/src/spec/controllers/deployments_controller_spec.rb b/src/spec/controllers/deployments_controller_spec.rb
index 278cb9d..6986ef8 100644
--- a/src/spec/controllers/deployments_controller_spec.rb
+++ b/src/spec/controllers/deployments_controller_spec.rb
@@ -62,8 +62,11 @@ describe DeploymentsController do
Factory.create(:front_hwp1)
Factory.create(:front_hwp2)
@deployment = Factory.build(:deployment)
+ catalog_entry = Factory.create(:catalog_entry)
+ @deployable = catalog_entry.deployable
+ @catalog = catalog_entry.catalog
Deployment.stub!(:new).and_return(@deployment)
- post :create
+ post :create, :deployable_id => @deployable.id
end
it { response.should be_success }
diff --git a/src/spec/vcr/cassettes/iwhd_connection.yml b/src/spec/vcr/cassettes/iwhd_connection.yml
index fc26a1a..0f2e6b7 100644
--- a/src/spec/vcr/cassettes/iwhd_connection.yml
+++ b/src/spec/vcr/cassettes/iwhd_connection.yml
@@ -75,6 +75,7 @@
<object_attr name="object_type" path="http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/object_type"/>
<object_attr name="uuid" path="http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/uuid"/>
<object_attr name="template" path="http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/template"/>
+ <object_attr name="environment" path="http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/environment"/>
</object>
http_version: "1.1"
@@ -104,6 +105,29 @@
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :get
+ uri: http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/environment
+ body:
+ headers:
+ accept:
+ - "*/*; q=0.5, application/xml"
+ accept-encoding:
+ - gzip, deflate
+ content-length:
+ - "0"
+ response: !ruby/struct:VCR::Response
+ status: !ruby/struct:VCR::ResponseStatus
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Mon, 13 Jun 2011 14:11:30 GMT
+ content-length:
+ - "7"
+ body: default
+ http_version: "1.1"
+- !ruby/struct:VCR::HTTPInteraction
+ request: !ruby/struct:VCR::Request
+ method: :get
uri: http://localhost:9090/images/53d2a281-448b-4872-b1b0-680edaad5922/latest_unpushed
body:
headers:
@@ -384,6 +408,7 @@
<object_attr name="target" path="http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/target"/>
<object_attr name="target_parameters" path="http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/target_parameters"/>
<object_attr name="template" path="http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/template"/>
+ <object_attr name="environment" path="http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/environment"/>
<object_attr name="uuid" path="http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/uuid"/>
</object>
@@ -506,6 +531,29 @@
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :get
+ uri: http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/environment
+ body:
+ headers:
+ accept:
+ - "*/*; q=0.5, application/xml"
+ accept-encoding:
+ - gzip, deflate
+ content-length:
+ - "0"
+ response: !ruby/struct:VCR::Response
+ status: !ruby/struct:VCR::ResponseStatus
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Mon, 13 Jun 2011 14:11:46 GMT
+ content-length:
+ - "7"
+ body: default
+ http_version: "1.1"
+- !ruby/struct:VCR::HTTPInteraction
+ request: !ruby/struct:VCR::Request
+ method: :get
uri: http://localhost:9090/images/34c87aa0-3405-42f8-820e-309054029295/uuid
body:
headers:
@@ -557,6 +605,7 @@
<object_attr name="target_parameters" path="http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/target_parameters"/>
<object_attr name="template" path="http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/template"/>
<object_attr name="uuid" path="http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/uuid"/>
+ <object_attr name="environment" path="http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/environment"/>
</object>
http_version: "1.1"
@@ -678,6 +727,29 @@
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :get
+ uri: http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/environment
+ body:
+ headers:
+ accept:
+ - "*/*; q=0.5, application/xml"
+ accept-encoding:
+ - gzip, deflate
+ content-length:
+ - "0"
+ response: !ruby/struct:VCR::Response
+ status: !ruby/struct:VCR::ResponseStatus
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Mon, 13 Jun 2011 14:11:48 GMT
+ content-length:
+ - "7"
+ body: default
+ http_version: "1.1"
+- !ruby/struct:VCR::HTTPInteraction
+ request: !ruby/struct:VCR::Request
+ method: :get
uri: http://localhost:9090/images/ef6fd2bb-50d4-4f53-ae92-a68b01f82cf1/uuid
body:
headers:
@@ -727,6 +799,7 @@
<object_attr name="latest_unpushed" path="http://localhost:9090/images/85653387-88b2-46b0-b7b2-c779d2af06c7/latest_unpushed"/>
<object_attr name="object_type" path="http://localhost:9090/images/85653387-88b2-46b0-b7b2-c779d2af06c7/object_type"/>
<object_attr name="uuid" path="http://localhost:9090/images/85653387-88b2-46b0-b7b2-c779d2af06c7/uuid"/>
+ <object_attr name="environment" path="http://localhost:9090/images/85653387-88b2-46b0-b7b2-c779d2af06c7/environment"/>
</object>
http_version: "1.1"
@@ -824,6 +897,29 @@
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
+ method: :get
+ uri: http://localhost:9090/images/85653387-88b2-46b0-b7b2-c779d2af06c7/environment
+ body:
+ headers:
+ accept:
+ - "*/*; q=0.5, application/xml"
+ accept-encoding:
+ - gzip, deflate
+ content-length:
+ - "0"
+ response: !ruby/struct:VCR::Response
+ status: !ruby/struct:VCR::ResponseStatus
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Mon, 13 Jun 2011 14:11:51 GMT
+ content-length:
+ - "7"
+ body: default
+ http_version: "1.1"
+- !ruby/struct:VCR::HTTPInteraction
+ request: !ruby/struct:VCR::Request
method: :post
uri: http://localhost:9090/images/images_testing_uuid
body: op=parts
--
1.7.6.4
More information about the aeolus-devel
mailing list