modules/mu/clouds/aws.rb in cloud-mu-2.0.1 vs modules/mu/clouds/aws.rb in cloud-mu-2.0.2

- old
+ new

@@ -140,25 +140,26 @@ # @return [Array<Symbol>] def self.required_instance_methods [:arn] end + # Given an AWS region, check the API to make sure it's a valid one + # @param r [String] + # @return [String] + def self.validate_region(r) + MU::Cloud::AWS.ec2(region: r).describe_availability_zones.availability_zones.first.region_name + end + # If we've configured AWS as a provider, or are simply hosted in AWS, # decide what our default region is. def self.myRegion return @@myRegion_var if @@myRegion_var if credConfig.nil? and !hosted? and !ENV['EC2_REGION'] return nil end - # Given an AWS region, check the API to make sure it's a valid one - # @param r [String] - # @return [String] - def self.validate_region(r) - MU::Cloud::AWS.ec2(region: r).describe_availability_zones.availability_zones.first.region_name - end if $MU_CFG and $MU_CFG['aws'] $MU_CFG['aws'].each_pair { |credset, cfg| next if !cfg['region'] if (cfg['default'] or !@@myRegion_var) and validate_region(cfg['region']) @@ -535,27 +536,35 @@ @@my_acct_num ||= acct_num acct_num end @@regions = {} + @@regions_semaphore = Mutex.new # List the Amazon Web Services region names available to this account. The # region that is local to this Mu server will be listed first. # @param us_only [Boolean]: Restrict results to United States only # @return [Array<String>] def self.listRegions(us_only = false, credentials: nil) if @@regions.size == 0 return [] if credConfig.nil? result = MU::Cloud::AWS.ec2(region: myRegion, credentials: credentials).describe_regions.regions regions = [] - result.each { |r| - @@regions[r.region_name] = Proc.new { - listAZs(region: r.region_name, credentials: credentials) - } + @@regions_semaphore.synchronize { + begin + result.each { |r| + @@regions[r.region_name] = Proc.new { + listAZs(region: r.region_name, credentials: credentials) + } + } + rescue ::Aws::EC2::Errors::AuthFailure => e + MU.log "Region #{r.region_name} throws #{e.message}, ignoring it", MU::ERR + end } end + regions = if us_only @@regions.keys.delete_if { |r| !r.match(/^us\-/) }.uniq else @@regions.keys.uniq end @@ -587,13 +596,20 @@ def self.createEc2SSHKey(keyname, public_key, credentials: nil) # We replicate this key in all regions if !MU::Cloud::CloudFormation.emitCloudFormation MU::Cloud::AWS.listRegions.each { |region| MU.log "Replicating #{keyname} to EC2 in #{region}", MU::DEBUG, details: @ssh_public_key - MU::Cloud::AWS.ec2(region: region, credentials: credentials).import_key_pair( - key_name: keyname, - public_key_material: public_key - ) + begin + MU::Cloud::AWS.ec2(region: region, credentials: credentials).import_key_pair( + key_name: keyname, + public_key_material: public_key + ) + rescue ::Aws::EC2::Errors::AuthFailure => e + @@regions_semaphore.synchronize { + @@regions.delete(region) + } + MU.log "#{region} threw #{e.message}, skipping", MU::ERR + end } end end @@instance_types = nil