1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
# encoding: utf-8
require "train/plugins"
require "google/apis"
require "google/apis/cloudresourcemanager_v1"
require "google/apis/compute_v1"
require "google/apis/storage_v1"
require "google/apis/iam_v1"
require "google/apis/admin_directory_v1"
require "googleauth"
module Train::Transports
class Gcp < Train.plugin(1)
name "gcp"
# GCP will look automatically for the below env var for service accounts etc. :
option :google_application_credentials, required: false do
ENV["GOOGLE_APPLICATION_CREDENTIALS"]
end
# see https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
# In the absence of this, the client is expected to have already set up local credentials via:
# $ gcloud auth application-default login
# $ gcloud config set project <project-name>
# GCP projects can have default regions / zones set, see:
# https://cloud.google.com/compute/docs/regions-zones/changing-default-zone-region
# can also specify project via env var:
option :google_cloud_project, required: false do
ENV["GOOGLE_CLOUD_PROJECT"]
end
option :google_super_admin_email, required: false do
ENV["GOOGLE_SUPER_ADMIN_EMAIL"]
end
def connection(_ = nil)
@connection ||= Connection.new(@options)
end
class Connection < BaseConnection
def initialize(options)
super(options)
# additional GCP platform metadata
release = Gem.loaded_specs["google-api-client"].version
@platform_details = { release: "google-api-client-v#{release}" }
# Initialize the client object cache
@cache_enabled[:api_call] = true
@cache[:api_call] = {}
connect
end
def platform
force_platform!("gcp", @platform_details)
end
# Instantiate some named classes for ease of use
def gcp_compute_client
gcp_client(Google::Apis::ComputeV1::ComputeService)
end
def gcp_iam_client
gcp_client(Google::Apis::IamV1::IamService)
end
def gcp_project_client
gcp_client(Google::Apis::CloudresourcemanagerV1::CloudResourceManagerService)
end
def gcp_storage_client
gcp_client(Google::Apis::StorageV1::StorageService)
end
def gcp_admin_client
scopes = ["https://www.googleapis.com/auth/admin.directory.user.readonly"]
authorization = Google::Auth.get_application_default(scopes).dup
# Use of the Admin API requires delegation (impersonation). An email address of a Super Admin in
# the G Suite account may be required.
authorization.sub = @options[:google_super_admin_email] if @options[:google_super_admin_email]
Google::Apis::RequestOptions.default.authorization = authorization
gcp_client(Google::Apis::AdminDirectoryV1::DirectoryService)
end
# Let's allow for other clients too
def gcp_client(klass)
return klass.new unless cache_enabled?(:api_call)
@cache[:api_call][klass.to_s.to_sym] ||= klass.new
end
def connect
ENV["GOOGLE_APPLICATION_CREDENTIALS"] = @options[:google_application_credentials] if @options[:google_application_credentials]
ENV["GOOGLE_CLOUD_PROJECT"] = @options[:google_cloud_project] if @options[:google_cloud_project]
# GCP initialization
scopes = ["https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/compute"]
authorization = Google::Auth.get_application_default(scopes)
Google::Apis::ClientOptions.default.application_name = "chef-inspec-train"
Google::Apis::ClientOptions.default.application_version = Train::VERSION
Google::Apis::RequestOptions.default.authorization = authorization
end
def uri
"gcp://#{unique_identifier}"
end
def unique_identifier
unique_id = "default"
# use auth client_id for users (issuer is nil)
unique_id = gcp_iam_client.request_options.authorization.client_id unless gcp_iam_client.request_options.authorization.client_id.nil?
# for service account credentials (client_id is nil)
unique_id = gcp_iam_client.request_options.authorization.issuer unless gcp_iam_client.request_options.authorization.issuer.nil?
unique_id
end
end
end
end
|