Skip to content

Commit

Permalink
Provide readable error when id/name could not be found server-side
Browse files Browse the repository at this point in the history
Introduce better exception handling
  • Loading branch information
bheuvel committed Mar 29, 2017
1 parent debfb02 commit 258d1a3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
18 changes: 12 additions & 6 deletions lib/vagrant-cloudstack/action/run_instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,19 @@ def call(env)
@template = CloudstackResource.new(@domain_config.template_id, @domain_config.template_name || @env[:machine].config.vm.box, 'template')
@pf_ip_address = CloudstackResource.new(@domain_config.pf_ip_address_id, @domain_config.pf_ip_address, 'public_ip_address')

@resource_service.sync_resource(@zone, { available: true })
cs_zone = @env[:cloudstack_compute].zones.find{ |f| f.id == @zone.id }
@resource_service.sync_resource(@service_offering, {listall: true})
@resource_service.sync_resource(@disk_offering, {listall: true})
@resource_service.sync_resource(@template, {zoneid: @zone.id, templatefilter: 'executable', listall: true})
@resource_service.sync_resource(@pf_ip_address)
begin
@resource_service.sync_resource(@zone, { available: true })
@resource_service.sync_resource(@service_offering, {listall: true})
@resource_service.sync_resource(@disk_offering, {listall: true})
@resource_service.sync_resource(@template, {zoneid: @zone.id, templatefilter: 'executable', listall: true})
@resource_service.sync_resource(@pf_ip_address)
rescue CloudstackResourceNotFound => e
@env[:ui].error(e.message)
terminate
exit(false)
end

cs_zone = @env[:cloudstack_compute].zones.find{ |f| f.id == @zone.id }
if cs_zone.network_type.downcase == 'basic'
# No network specification in basic zone
@env[:ui].warn(I18n.t('vagrant_cloudstack.basic_network', :zone_name => @zone.name)) if !@networks.empty? && (@networks[0].id || @networks[0].name)
Expand Down
9 changes: 7 additions & 2 deletions lib/vagrant-cloudstack/exceptions/exceptions.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
module VagrantPlugins
module Cloudstack
module Exceptions
class IpNotFoundException < Exception
class IpNotFoundException < StandardError
end
class DuplicatePFRule < Exception
class DuplicatePFRule < StandardError
end
class CloudstackResourceNotFound < StandardError
def initialize(msg='Resource not found in cloudstack')
super
end
end
end
end
Expand Down
20 changes: 16 additions & 4 deletions lib/vagrant-cloudstack/service/cloudstack_resource_service.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
require 'vagrant-cloudstack/exceptions/exceptions'

module VagrantPlugins
module Cloudstack
module Service
class CloudstackResourceService
include VagrantPlugins::Cloudstack::Exceptions

def initialize(cloudstack_compute, ui)
@cloudstack_compute = cloudstack_compute
@ui = ui
end

def sync_resource(resource, api_parameters = {})
@resource_details = nil
if resource.id.nil? and resource.name
if resource.id.nil? and !(resource.name.nil? || resource.name.empty? )
resource.id = name_to_id(resource.name, resource.kind, api_parameters)
elsif resource.id
resource.name = id_to_name(resource.id, resource.kind, api_parameters)
end

unless resource.is_undefined?
unless resource.is_id_undefined? || resource.is_name_undefined?
resource.details = @resource_details
@ui.detail("Syncronized resource: #{resource}")
end
Expand All @@ -38,13 +42,21 @@ def resourcefield_to_id(resource_type, resource_field, resource_field_value, opt
@ui.info("Fetching UUID for #{resource_type} with #{resource_field} '#{resource_field_value}'")
full_response = translate_from_to(resource_type, options)
@resource_details = full_response.find {|type| type[resource_field] == resource_field_value }
@resource_details['id']
if @resource_details
@resource_details['id']
else
raise CloudstackResourceNotFound.new("No UUID found for #{resource_type} with #{resource_field} '#{resource_field_value}'")
end
end

def id_to_resourcefield(resource_id, resource_type, resource_field, options={})
@ui.info("Fetching #{resource_field} for #{resource_type} with UUID '#{resource_id}'")
options = options.merge({'id' => resource_id})
full_response = translate_from_to(resource_type, options)
begin
full_response = translate_from_to(resource_type, options)
rescue Fog::Compute::Cloudstack::BadRequest => e
raise CloudstackResourceNotFound.new("No Name found for #{resource_type} with UUID '#{resource_id}', #{e.class.to_s} reports:\n #{e.message}")
end
@resource_details = full_response[0]
@resource_details[resource_field]
end
Expand Down

0 comments on commit 258d1a3

Please sign in to comment.