module GoogleCloudEnvSecrets

Constants

VERSION

Attributes

configuration[RW]

Public Class Methods

all() click to toggle source
# File lib/google_cloud_env_secrets/secrets.rb, line 2
def self.all
  @secrets = nil unless self.configuration.cache_secrets
  @secrets ||= begin
      # Skip if not running on Google Cloud and credentials are not set explicitly
      if self.configuration.credentials.nil? && Google::Cloud.env.project_id.nil?
        return {}
      end

      # Configure and initialize
      # https://googleapis.dev/ruby/google-cloud-secret_manager/latest/Google/Cloud/SecretManager.html
      Google::Cloud::SecretManager.configure do |config|
        if self.configuration.credentials
          if File.exist?(self.configuration.credentials)
            config.credentials = self.configuration.credentials # load by file
          else
            config.credentials = JSON.parse(self.configuration.credentials) # load data
          end
        end
      end

      client = Google::Cloud::SecretManager.secret_manager_service

      # create worker pool to read secrets in parallel
      pool = Concurrent::FixedThreadPool.new(Concurrent.processor_count * 4)
      secrets = Concurrent::Hash.new

      # read all secrets ...
      client.list_secrets(parent: "projects/" + self.configuration.project).each do |secret|
        pool.post(secret) do |secret|
          name = secret.name.split("/").last

          # only consider prefixed secrets?
          if self.configuration.prefix
            next unless name.start_with? self.configuration.prefix

            # clean up name
            name.delete_prefix! self.configuration.prefix
            name.sub! /^[^a-z0-9]+/i, ""
          end

          secrets[name] = client.access_secret_version(name: secret.name + "/versions/latest").payload.data
        end
      end

      # shutdown worker pool
      pool.shutdown
      pool.wait_for_termination

      secrets
    end

  @secrets || {}
end
configure() { |configuration| ... } click to toggle source
# File lib/google_cloud_env_secrets/config.rb, line 21
def self.configure
  self.configuration ||= Configuration.new
  yield(configuration)
end
exist?(name) click to toggle source
# File lib/google_cloud_env_secrets/secrets.rb, line 60
def self.exist?(name)
  self.all.has_key?(name.to_s)
end
find(name) click to toggle source
# File lib/google_cloud_env_secrets/secrets.rb, line 56
def self.find(name)
  self.all[name.to_s]
end
inject_env!(secrets = {}, overload = true, env = ENV) click to toggle source
# File lib/google_cloud_env_secrets/secrets.rb, line 64
def self.inject_env!(secrets = {}, overload = true, env = ENV)
  secrets.each do |name, value|
    name = name.to_s
    if overload
      env[name] = value
    else
      env[name] ||= value
    end
  end
end
load() click to toggle source

load Google Secrets into ENV

# File lib/google_cloud_env_secrets/railtie.rb, line 15
def self.load
  GoogleCloudEnvSecrets.configure do |config|
    config.credentials = ENV["GOOGLE_APPLICATION_CREDENTIALS"] || nil
    config.project = ENV["GOOGLE_PROJECT"] || GoogleCloudEnvSecrets.parse_project_from_credentials(config.credentials) || Google::Cloud.env.project_id
    config.prefix = ENV["GOOGLE_SECRETS_PREFIX"] || nil

    if ENV.has_key?("GOOGLE_SECRETS_OVERLOAD")
      config.overload = ENV["GOOGLE_SECRETS_OVERLOAD"]&.to_s&.downcase == "true"
    end
  end

  secrets = GoogleCloudEnvSecrets.all
  GoogleCloudEnvSecrets.inject_env!(secrets, GoogleCloudEnvSecrets.configuration.overload)
end
parse_project_from_credentials(credentials) click to toggle source
# File lib/google_cloud_env_secrets/config.rb, line 26
def self.parse_project_from_credentials(credentials)
  if File.exist?(credentials)
    j = JSON.parse(File.read(credentials))
    return j["project_id"]
  else
    j = JSON.parse(credentials)
    return j["project_id"]
  end
rescue
  nil
end