Module: OCI::Regions

Defined in:
lib/oci/regions.rb

Overview

Module defining available regions and helper methods to get value service endpoints

Constant Summary collapse

REGION_ENUM =
[
  REGION_AP_CHIYODA_1 = 'ap-chiyoda-1'.freeze,
  REGION_AP_CHUNCHEON_1 = 'ap-chuncheon-1'.freeze,
  REGION_AP_HYDERABAD_1 = 'ap-hyderabad-1'.freeze,
  REGION_AP_MUMBAI_1 = 'ap-mumbai-1'.freeze,
  REGION_AP_MELBOURNE_1 = 'ap-melbourne-1'.freeze,
  REGION_AP_OSAKA_1 = 'ap-osaka-1'.freeze,
  REGION_AP_SEOUL_1 = 'ap-seoul-1'.freeze,
  REGION_AP_SYDNEY_1 = 'ap-sydney-1'.freeze,
  REGION_AP_TOKYO_1 = 'ap-tokyo-1'.freeze,

  REGION_CA_MONTREAL_1 = 'ca-montreal-1'.freeze,
  REGION_CA_TORONTO_1 = 'ca-toronto-1'.freeze,

  REGION_EU_AMSTERDAM_1 = 'eu-amsterdam-1'.freeze,
  REGION_EU_FRANKFURT_1 = 'eu-frankfurt-1'.freeze,
  REGION_EU_ZURICH_1 = 'eu-zurich-1'.freeze,

  REGION_ME_DUBAI_1 = 'me-dubai-1'.freeze,
  REGION_ME_JEDDAH_1 = 'me-jeddah-1'.freeze,

  REGION_SA_SAOPAULO_1 = 'sa-saopaulo-1'.freeze,

  REGION_UK_GOV_LONDON_1 = 'uk-gov-london-1'.freeze,
  REGION_UK_LONDON_1 = 'uk-london-1'.freeze,
  REGION_UK_GOV_CARDIFF_1 = 'uk-gov-cardiff-1'.freeze,

  REGION_US_PHOENIX_1 = 'us-phoenix-1'.freeze,
  REGION_US_ASHBURN_1 = 'us-ashburn-1'.freeze,
  REGION_US_LANGLEY_1 = 'us-langley-1'.freeze,
  REGION_US_LUKE_1 = 'us-luke-1'.freeze,
  REGION_US_SANJOSE_1 = 'us-sanjose-1'.freeze,

  REGION_US_GOV_ASHBURN_1 = 'us-gov-ashburn-1'.freeze,
  REGION_US_GOV_CHICAGO_1 = 'us-gov-chicago-1'.freeze,
  REGION_US_GOV_PHOENIX_1 = 'us-gov-phoenix-1'.freeze
]
REGION_SHORT_NAMES_TO_LONG_NAMES =
{
  'ams': REGION_EU_AMSTERDAM_1,
  'bom': REGION_AP_MUMBAI_1,
  'brs': REGION_UK_GOV_CARDIFF_1,
  'dxb': REGION_ME_DUBAI_1,
  'fra': REGION_EU_FRANKFURT_1,
  'gru': REGION_SA_SAOPAULO_1,
  'hyd': REGION_AP_HYDERABAD_1,
  'iad': REGION_US_ASHBURN_1,
  'icn': REGION_AP_SEOUL_1,
  'jed': REGION_ME_JEDDAH_1,
  'kix': REGION_AP_OSAKA_1,
  'lhr': REGION_UK_LONDON_1,
  'ltn': REGION_UK_GOV_LONDON_1,
  'mel': REGION_AP_MELBOURNE_1,
  'nja': REGION_AP_CHIYODA_1,
  'nrt': REGION_AP_TOKYO_1,
  'phx': REGION_US_PHOENIX_1,
  'sjc': REGION_US_SANJOSE_1,
  'syd': REGION_AP_SYDNEY_1,
  'yny': REGION_AP_CHUNCHEON_1,
  'yul': REGION_CA_MONTREAL_1,
  'yyz': REGION_CA_TORONTO_1,
  'zrh': REGION_EU_ZURICH_1
}
REGION_REALM_MAPPING =

— Start of region realm mapping —

{
  'ap-chiyoda-1': 'oc8'.freeze,
  'ap-chuncheon-1': 'oc1'.freeze,
  'ap-hyderabad-1': 'oc1'.freeze,
  'ap-mumbai-1': 'oc1'.freeze,
  'ap-melbourne-1': 'oc1'.freeze,
  'ap-osaka-1': 'oc1'.freeze,
  'ap-seoul-1': 'oc1'.freeze,
  'ap-sydney-1': 'oc1'.freeze,
  'ap-tokyo-1': 'oc1'.freeze,

  'ca-montreal-1': 'oc1'.freeze,
  'ca-toronto-1': 'oc1'.freeze,

  'eu-amsterdam-1': 'oc1'.freeze,
  'eu-frankfurt-1': 'oc1'.freeze,
  'eu-zurich-1': 'oc1'.freeze,

  'me-dubai-1': 'oc1'.freeze,
  'me-jeddah-1': 'oc1'.freeze,

  'sa-saopaulo-1': 'oc1'.freeze,

  'uk-london-1': 'oc1'.freeze,

  'uk-gov-london-1': 'oc4'.freeze,
  'uk-gov-cardiff-1': 'oc4'.freeze,

  'us-phoenix-1': 'oc1'.freeze,
  'us-ashburn-1': 'oc1'.freeze,
  'us-langley-1': 'oc2'.freeze,
  'us-luke-1': 'oc2'.freeze,
  'us-sanjose-1': 'oc1'.freeze,

  'us-gov-ashburn-1': 'oc3'.freeze,
  'us-gov-phoenix-1': 'oc3'.freeze,
  'us-gov-chicago-1': 'oc3'.freeze
}
REALM_DOMAIN_MAPPING =

— Start of realm domain mapping —

{
  'oc1': 'oraclecloud.com'.freeze,
  'oc2': 'oraclegovcloud.com'.freeze,
  'oc3': 'oraclegovcloud.com'.freeze,
  'oc4': 'oraclegovcloud.uk'.freeze,
  'oc8': 'oraclecloud8.com'.freeze
}
SERVICE_ENDPOINT_PREFIX_MAPPING =

— Start of service prefixes —

{
  AnnouncementClient: 'announcements',
  AuditClient: 'audit',
  Auth: 'auth',
  AutoScalingClient: 'autoscaling',
  BlockstorageClient: 'iaas',
  BudgetClient: 'usage',
  ComputeClient: 'iaas',
  ComputeManagementClient: 'iaas',
  ContainerEngineClient: 'containerengine',
  DatabaseClient: 'database',
  DnsClient: 'dns',
  EmailClient: 'email',
  FileStorageClient: 'filestorage',
  HealthChecksClient: 'healthchecks',
  IdentityClient: 'identity',
  KmsVaultClient: 'kms',
  LoadBalancerClient: 'iaas',
  MonitoringClient: 'telemetry',
  NotificationControlPlaneClient: 'notification',
  NotificationDataPlaneClient: 'notification',
  ObjectStorageClient: 'objectstorage',
  ResourceManagerClient: 'resourcemanager',
  ResourceSearchClient: 'query',
  StreamAdminClient: 'streams',
  StreamClient: 'streams',
  VirtualNetworkClient: 'iaas',
  WaasClient: 'waas'
}.freeze
REGION_METADATA_KEYS =

Region Metadata schema keys

%w[realmKey realmDomainComponent regionKey regionIdentifier].freeze
OCI_REGION_METADATA_VAR_NAME =

Region metadata environment variable name

'OCI_REGION_METADATA'.freeze
REGION_METADATA_CFG_FILE_LOCATION =

Region Metadata Configuration File location

"#{Dir.home}/.oci/regions-config.json".freeze

Class Method Summary collapse

Class Method Details

.check_and_add_region_metadata(region) ⇒ Object

If the region information is not available in the existing maps, following sources are checked in order:

1. Regions Configuration File at ~/.oci/regions-config.json
2. Region Metadata Environment variable
3. Instance Metadata Service

The region metadata schema is:
{
    "realmKey" : string,
    "realmDomainComponent" : string,
    "regionKey" : string,
    "regionIdentifier" : string
}

If the region still cannot be resolved, we fall back to OC1 realm


264
265
266
267
268
269
270
# File 'lib/oci/regions.rb', line 264

def self.(region)
  # Follow the hierarchy of sources
  return if valid_region?(region)
  return if !@has_read_cfg_file && (region)
  return if !@has_read_env_var && (region)
  return if @opt_in_for_imds && !@has_read_imds && (region)
end

.check_valid_schema(region_metadata) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/oci/regions.rb', line 359

def self.check_valid_schema()
  REGION_METADATA_KEYS.each do |key|
    unless .key? key
      OCI.logger.debug("Key #{key} not found in region metadata") if OCI.logger
      return false
    end

    if [key].nil? || [key].empty?
      OCI.logger.debug("Value for key #{key} in region metadata is empty") if OCI.logger
      return false
    end
  end
  true
end

.enable_instance_metadata_serviceObject



389
390
391
# File 'lib/oci/regions.rb', line 389

def self.
  @opt_in_for_imds = true
end

.format_endpoint(prefix, region) ⇒ Object



221
222
223
224
# File 'lib/oci/regions.rb', line 221

def self.format_endpoint(prefix, region)
  second_level_domain = get_second_level_domain(region)
  "https://#{prefix}.#{region}.#{second_level_domain}"
end

.get_second_level_domain(region) ⇒ String

Returns a second level domain for the given region.

Parameters:

  • region (String)

    A region used to get the second level domain. This will usually correspond to a value in REGION_ENUM, but may be an arbitrary string.

Returns:

  • (String)

    A second level domain for given region, default to oraclecloud.com



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/oci/regions.rb', line 232

def self.get_second_level_domain(region)
  symbolised_region = region.to_sym

  # get realm from region, default to oc1
  realm = if REGION_REALM_MAPPING.key?(symbolised_region)
            REGION_REALM_MAPPING[symbolised_region]
          else
            'oc1'
          end

  # return second level domain if exists
  symbolised_realm = realm.to_sym

  return REALM_DOMAIN_MAPPING[symbolised_realm] if REALM_DOMAIN_MAPPING.key?(symbolised_realm)

  REALM_DOMAIN_MAPPING[:oc1]
end

.get_service_endpoint(region, service) ⇒ String

Returns an endpoint for the given region and service.

Parameters:

  • region (String)

    A region used to determine the service endpoint. This will usually correspond to a value in REGION_ENUM, but may be an arbitrary string.

  • service (Symbol)

    A symbol representing a service client class (e.g. :IdentityClient)

Returns:

  • (String)

    A fully qualified endpoint



184
185
186
187
188
189
190
191
192
# File 'lib/oci/regions.rb', line 184

def self.get_service_endpoint(region, service)
  # check if the region exists in config file, environment variable or region meta_data_service
  # and add it to the existing map of regions.
  (region)
  prefix = SERVICE_ENDPOINT_PREFIX_MAPPING[service]
  raise "Service '#{service}' is not supported." unless prefix

  format_endpoint(prefix, region)
end

.get_service_endpoint_for_template(region, endpoint_template) ⇒ String

Returns an endpoint for the given region and service endpoint template.

Parameters:

  • region (String)

    A region used to determine the service endpoint. This will usually correspond to a value in REGION_ENUM, but may be an arbitrary string.

  • endpoint_template (String)

    A service endpoint template defined by service team in spec.

Returns:

  • (String)

    A fully qualified endpoint



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/oci/regions.rb', line 201

def self.get_service_endpoint_for_template(region, endpoint_template)
  # check if the region exists in config file, environment variable or region meta_data_service
  # and add it to the existing map of regions.
  (region)
  endpoint = endpoint_template.clone

  # replace the token inside service_endpoint_template if exists
  [
    ['{region}', region],
    ['{secondLevelDomain}', get_second_level_domain(region).to_s]
  ].each { |k, v| endpoint.sub!(k, v) }
  endpoint
end

.read_metadata(metadata_env) ⇒ Object



355
356
357
# File 'lib/oci/regions.rb', line 355

def self.()
  JSON.parse()
end

.region_from_instance_metadata_service(region) ⇒ Object

Read region from instance metadata service



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/oci/regions.rb', line 302

def self.(region)
  @has_read_imds = true

  region_info = {}
  begin
    url = OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner::GET_REGION_INFO_URL
    uri_region_info = URI(url)
    region_info_client = Net::HTTP.new(uri_region_info.hostname, uri_region_info.port)
    # region_info_client.max_retries = 0
    region_info_client.open_timeout = 10
    region_info_client.read_timeout = 60
    region_info_client.request(OCI::Auth::Util.(url, 'get')) do |response|
      return false unless response.is_a? Net::HTTPSuccess

      region_info = (response.body)
    end
  rescue JSON::ParserError
    OCI.logger.debug('Failed to parse json from regionInfo endpoint') if OCI.logger
    return false
  end

  if check_valid_schema(region_info)
    region_info.each { |_k, v| v.downcase! }
    return update_regions_map(region_info, region)
  end

  false
end

.region_metadata_from_cfg_file(region) ⇒ Object

Read region from metadata config file



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/oci/regions.rb', line 273

def self.(region)
  @has_read_cfg_file = true
  config_file_location = File.expand_path(REGION_METADATA_CFG_FILE_LOCATION)
  unless File.file?(config_file_location)
    OCI.logger.debug('Config file does not exist.') if OCI.logger
    return false
  end

  begin
    file_hash = File.read(config_file_location)
     = (file_hash)
  rescue JSON::ParserError
    OCI.logger.debug('Failed to parse json file ' + config_file_location) if OCI.logger
    return false
  end

  # boolean flag to confirm if the region is found in the metadata array
  has_found_region = false
  .each do ||
    next unless check_valid_schema()

    .each { |_k, v| v.downcase! }
    has_region = update_regions_map(, region)
    has_found_region ||= has_region
  end
  has_found_region
end

.region_metadata_from_env_var(region) ⇒ Object

This method adds Region metadata info from OCI_REGION_METADATA environment variable to list of existing regions if the region does not exists already.



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/oci/regions.rb', line 333

def self.(region)
  begin
    @has_read_env_var = true
     = ENV[OCI_REGION_METADATA_VAR_NAME]

    # Empty value for environment variable OCI_REGION_METADATA
    return false if .nil? || .empty?

     = ()
  rescue JSON::ParserError
    OCI.logger.debug('Failed to parse json from environment variable ' + OCI_REGION_METADATA_VAR_NAME) if OCI.logger
    return false
  end

  if check_valid_schema()
    .each { |_k, v| v.downcase! }
    return update_regions_map(, region)
  end

  false
end

.reset_imds_settingsObject



393
394
395
396
# File 'lib/oci/regions.rb', line 393

def self.reset_imds_settings
  @opt_in_for_imds = false
  @has_read_imds = false
end

.update_regions_map(metadata, region) ⇒ Object



374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/oci/regions.rb', line 374

def self.update_regions_map(, region)
  region_identifier = ['regionIdentifier']
  realm_key = ['realmKey']
  region_key = ['regionKey']
  realm_domain_component = ['realmDomainComponent']

  # Add region
  REGION_ENUM.push(region_identifier) unless REGION_ENUM.include?(region_identifier)
  REGION_SHORT_NAMES_TO_LONG_NAMES[region_key.to_sym] ||= region_identifier
  REALM_DOMAIN_MAPPING[realm_key.to_sym] ||= realm_domain_component
  REGION_REALM_MAPPING[region_identifier.to_sym] ||= realm_key

  REGION_ENUM.include? region
end

.valid_region?(region) ⇒ Boolean

Returns:

  • (Boolean)

    Returns true if the given string corresponds to a known region, as defined in



217
218
219
# File 'lib/oci/regions.rb', line 217

def self.valid_region?(region)
  REGION_ENUM.include? region
end