class Google::Cloud::Env

# Google Cloud hosting environment

This library provides access to information about the application's hosting environment if it is running on Google Cloud Platform. You may use this library to determine which Google Cloud product is hosting your application (e.g. App Engine, Kubernetes Engine), information about the Google Cloud project hosting the application, information about the virtual machine instance, authentication information, and so forth.

## Usage

Obtain an instance of the environment info with:

“`ruby require “google/cloud/env” env = Google::Cloud.env “`

Then you can interrogate any fields using methods on the object.

“`ruby if env.app_engine?

# App engine specific logic

end “`

Any item that does not apply to the current environment will return nil. For example:

“`ruby unless env.app_engine?

service = env.app_engine_service_id  # => nil

end “`

Constants

METADATA_FAILURE_EXCEPTIONS

@private

METADATA_HOST

@private Base (host) URL for the metadata server.

METADATA_PATH_BASE

@private URL path for v1 of the metadata service.

METADATA_ROOT_PATH

@private URL path for metadata server root.

VERSION

Attributes

connection[R]
env[R]
metadata_cache[R]

Public Class Methods

get() click to toggle source

Returns the global instance of {Google::Cloud::Env}.

@return [Google::Cloud::Env]

# File lib/google/cloud/env.rb, line 450
def self.get
  ::Google::Cloud.env
end
new(env: nil, connection: nil, metadata_cache: nil, open_timeout: 0.1, request_timeout: 1.0, retry_count: 2, retry_interval: 0.1, retry_backoff_factor: 1.5, retry_max_interval: 0.5) click to toggle source

Create a new instance of the environment information. Most client should not need to call this directly. Obtain a singleton instance of the information from `Google::Cloud.env`. This constructor is provided to allow customization of the timeout/retry settings, as well as mocking for testing.

@param [Hash] env Mock environment variables. @param [Hash,false] #metadata_cache The metadata cache. You may pass

a prepopuated cache, an empty cache (the default) or `false` to
disable the cache completely.

@param [Numeric] open_timeout Timeout for opening http connections.

Defaults to 0.1.

@param [Numeric] request_timeout Timeout for entire http requests.

Defaults to 1.0.

@param [Integer] retry_count Number of times to retry http requests.

Defaults to 1. Note that retry remains in effect even if a custom
`connection` is provided.

@param [Numeric] retry_interval Time between retries in seconds.

Defaults to 0.1.

@param [Numeric] retry_backoff_factor Multiplier applied to the retry

interval on each retry. Defaults to 1.5.

@param [Numeric] retry_max_interval Maximum time between retries in

seconds. Defaults to 0.5.

@param [Faraday::Connection] connection Faraday connection to use.

If specified, overrides the `request_timeout` and `open_timeout`
settings.
# File lib/google/cloud/env.rb, line 105
def initialize env: nil, connection: nil, metadata_cache: nil,
               open_timeout: 0.1, request_timeout: 1.0,
               retry_count: 2, retry_interval: 0.1,
               retry_backoff_factor: 1.5, retry_max_interval: 0.5
  @disable_metadata_cache = metadata_cache == false
  @metadata_cache = metadata_cache || {}
  @env = env || ::ENV
  @retry_count = retry_count
  @retry_interval = retry_interval
  @retry_backoff_factor = retry_backoff_factor
  @retry_max_interval = retry_max_interval
  request_opts = { timeout: request_timeout, open_timeout: open_timeout }
  @connection = connection || ::Faraday.new(url: METADATA_HOST, request: request_opts)
end

Public Instance Methods

app_engine?() click to toggle source

Determine whether the application is running on Google App Engine.

@return [Boolean]

# File lib/google/cloud/env.rb, line 135
def app_engine?
  env["GAE_INSTANCE"] ? true : false
end
app_engine_flexible?() click to toggle source

Determine whether the application is running on Google App Engine Flexible Environment.

@return [Boolean]

# File lib/google/cloud/env.rb, line 145
def app_engine_flexible?
  app_engine? && env["GAE_ENV"] != "standard"
end
app_engine_memory_mb() click to toggle source

Returns the amount of memory reserved for the current App Engine instance, or `nil` if the current code is not running in App Engine.

@return [Integer,nil]

# File lib/google/cloud/env.rb, line 366
def app_engine_memory_mb
  result = env["GAE_MEMORY_MB"]
  result.nil? ? nil : result.to_i
end
app_engine_service_id() click to toggle source

Returns the name of the running App Engine service, or `nil` if the current code is not running in App Engine.

@return [String,nil]

# File lib/google/cloud/env.rb, line 345
def app_engine_service_id
  env["GAE_SERVICE"]
end
Also aliased as: app_engine_service_name
app_engine_service_name()
app_engine_service_version() click to toggle source

Returns the version of the running App Engine service, or `nil` if the current code is not running in App Engine.

@return [String,nil]

# File lib/google/cloud/env.rb, line 356
def app_engine_service_version
  env["GAE_VERSION"]
end
app_engine_standard?() click to toggle source

Determine whether the application is running on Google App Engine Standard Environment.

@return [Boolean]

# File lib/google/cloud/env.rb, line 155
def app_engine_standard?
  app_engine? && env["GAE_ENV"] == "standard"
end
cloud_shell?() click to toggle source

Determine whether the application is running on Google Cloud Shell.

@return [Boolean]

# File lib/google/cloud/env.rb, line 175
def cloud_shell?
  env["DEVSHELL_GCLOUD_CONFIG"] ? true : false
end
compute_engine?() click to toggle source

Determine whether the application is running on Google Compute Engine.

Note that most other products (e.g. App Engine, Kubernetes Engine, Cloud Shell) themselves use Compute Engine under the hood, so this method will return true for all the above products. If you want to determine whether the application is running on a “raw” Compute Engine VM without using a higher level hosting product, use {Env#raw_compute_engine?}.

@return [Boolean]

# File lib/google/cloud/env.rb, line 191
def compute_engine?
  metadata?
end
container_engine?()
Alias for: kubernetes_engine?
container_engine_cluster_name()
container_engine_namespace_id()
instance_attribute(key) click to toggle source

Returns the value of the given instance attribute for the VM instance hosting the application, or `nil` if the given key does not exist or application is not running on Google Cloud.

@param [String] key Attribute key to look up. @return [String,nil]

# File lib/google/cloud/env.rb, line 314
def instance_attribute key
  lookup_metadata "instance", "attributes/#{key}"
end
instance_attribute_keys() click to toggle source

Returns an array (which may be empty) of all attribute keys present for the VM instance hosting the application, or `nil` if the application is not running on Google Cloud.

@return [Array<String>,nil]

# File lib/google/cloud/env.rb, line 301
def instance_attribute_keys
  result = lookup_metadata "instance", "attributes/"
  result.nil? ? nil : result.split
end
instance_description() click to toggle source

Returns the description field (which may be the empty string) of the VM instance hosting the application, or `nil` if the application is not running on Google Cloud.

@return [String,nil]

# File lib/google/cloud/env.rb, line 255
def instance_description
  lookup_metadata "instance", "description"
end
instance_machine_type() click to toggle source

Returns the machine type of the VM instance hosting the application, or `nil` if the application is not running on Google Cloud.

@return [String,nil]

# File lib/google/cloud/env.rb, line 277
def instance_machine_type
  result = lookup_metadata "instance", "machine-type"
  result.nil? ? nil : result.split("/").last
end
instance_name() click to toggle source

Returns the name of the VM instance hosting the application, or `nil` if the application is not running on Google Cloud.

@return [String,nil]

# File lib/google/cloud/env.rb, line 244
def instance_name
  env["GAE_INSTANCE"] || lookup_metadata("instance", "name")
end
instance_tags() click to toggle source

Returns an array (which may be empty) of all tags set on the VM instance hosting the application, or `nil` if the application is not running on Google Cloud.

@return [Array<String>,nil]

# File lib/google/cloud/env.rb, line 289
def instance_tags
  result = lookup_metadata "instance", "tags"
  result.nil? ? nil : JSON.parse(result)
end
instance_zone() click to toggle source

Returns the zone (for example “`us-central1-c`”) in which the instance hosting the application lives. Returns `nil` if the application is not running on Google Cloud.

@return [String,nil]

# File lib/google/cloud/env.rb, line 266
def instance_zone
  result = lookup_metadata "instance", "zone"
  result.nil? ? nil : result.split("/").last
end
knative?() click to toggle source

Determine whether the application is running on a Knative-based hosting platform, such as Cloud Run or Cloud Functions.

@return [Boolean]

# File lib/google/cloud/env.rb, line 126
def knative?
  env["K_SERVICE"] ? true : false
end
knative_service_id() click to toggle source

Returns the name of the running Knative service, or `nil` if the current code is not running on Knative.

@return [String,nil]

# File lib/google/cloud/env.rb, line 324
def knative_service_id
  env["K_SERVICE"]
end
Also aliased as: knative_service_name
knative_service_name()
Alias for: knative_service_id
knative_service_revision() click to toggle source

Returns the revision of the running Knative service, or `nil` if the current code is not running on Knative.

@return [String,nil]

# File lib/google/cloud/env.rb, line 335
def knative_service_revision
  env["K_REVISION"]
end
kubernetes_engine?() click to toggle source

Determine whether the application is running on Google Kubernetes Engine (GKE).

@return [Boolean]

# File lib/google/cloud/env.rb, line 165
def kubernetes_engine?
  kubernetes_engine_cluster_name ? true : false
end
Also aliased as: container_engine?
kubernetes_engine_cluster_name() click to toggle source

Returns the name of the Kubernetes Engine cluster hosting the application, or `nil` if the current code is not running in Kubernetes Engine.

@return [String,nil]

# File lib/google/cloud/env.rb, line 378
def kubernetes_engine_cluster_name
  instance_attribute "cluster-name"
end
kubernetes_engine_namespace_id() click to toggle source

Returns the name of the Kubernetes Engine namespace hosting the application, or `nil` if the current code is not running in Kubernetes Engine.

@return [String,nil]

# File lib/google/cloud/env.rb, line 390
def kubernetes_engine_namespace_id
  # The Kubernetes namespace is difficult to obtain without help from
  # the application using the Downward API. The environment variable
  # below is set in some older versions of GKE, and the file below is
  # present in Kubernetes as of version 1.9, but it is possible that
  # alternatives will need to be found in the future.
  env["GKE_NAMESPACE_ID"] || ::IO.read("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
rescue SystemCallError
  nil
end
lookup_metadata(type, entry) click to toggle source

Retrieve info from the Google Compute Engine Metadata Service. Returns `nil` if the Metadata Service is not running or the given data is not present.

@param [String] type Type of metadata to look up. Currently supported

values are "project" and "instance".

@param [String] entry Metadata entry path to look up. @return [String,nil]

# File lib/google/cloud/env.rb, line 430
def lookup_metadata type, entry
  return nil unless metadata?

  path = "#{METADATA_PATH_BASE}/#{type}/#{entry}"
  if @disable_metadata_cache || !metadata_cache.include?(path)
    metadata_cache[path] = retry_or_fail_with nil do
      resp = connection.get path do |req|
        req.headers = { "Metadata-Flavor" => "Google" }
      end
      resp.status == 200 ? resp.body.strip : nil
    end
  end
  metadata_cache[path]
end
metadata?() click to toggle source

Determine whether the Google Compute Engine Metadata Service is running.

@return [Boolean]

# File lib/google/cloud/env.rb, line 407
def metadata?
  path = METADATA_ROOT_PATH
  if @disable_metadata_cache || !metadata_cache.include?(path)
    metadata_cache[path] = retry_or_fail_with false do
      resp = connection.get path do |req|
        req.headers = { "Metadata-Flavor" => "Google" }
      end
      resp.status == 200 && resp.headers["Metadata-Flavor"] == "Google"
    end
  end
  metadata_cache[path]
end
numeric_project_id() click to toggle source

Returns the unique numeric ID of the project hosting the application, or `nil` if the application is not running on Google Cloud.

Caveat: this method does not work and returns `nil` on CloudShell.

@return [Integer,nil]

# File lib/google/cloud/env.rb, line 227
def numeric_project_id
  # CloudShell's metadata server seems to run in a dummy project.
  # We can get the user's normal project ID via environment variables,
  # but the numeric ID from the metadata service is not correct. So
  # disable this for CloudShell to avoid confusion.
  return nil if cloud_shell?

  result = lookup_metadata "project", "numeric-project-id"
  result.nil? ? nil : result.to_i
end
project_id() click to toggle source

Returns the unique string ID of the project hosting the application, or `nil` if the application is not running on Google Cloud.

@return [String,nil]

# File lib/google/cloud/env.rb, line 212
def project_id
  env["GOOGLE_CLOUD_PROJECT"] ||
    env["GCLOUD_PROJECT"] ||
    env["DEVSHELL_PROJECT_ID"] ||
    lookup_metadata("project", "project-id")
end
raw_compute_engine?() click to toggle source

Determine whether the application is running on “raw” Google Compute Engine without using a higher level hosting product such as App Engine or Kubernetes Engine.

@return [Boolean]

# File lib/google/cloud/env.rb, line 202
def raw_compute_engine?
  !knative? && !app_engine? && !cloud_shell? && metadata? && !kubernetes_engine?
end

Private Instance Methods

retry_or_fail_with(error_result) { || ... } click to toggle source
# File lib/google/cloud/env.rb, line 460
def retry_or_fail_with error_result
  retries_remaining = @retry_count
  retry_interval = @retry_interval
  begin
    yield
  rescue *METADATA_FAILURE_EXCEPTIONS
    retries_remaining -= 1
    if retries_remaining >= 0
      sleep retry_interval
      retry_interval *= @retry_backoff_factor
      retry_interval = @retry_max_interval if retry_interval > @retry_max_interval
      retry
    end
    error_result
  end
end