bcome 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/bcome.rb +7 -0
- data/lib/objects/bcome/version.rb +3 -3
- data/lib/objects/bootup.rb +4 -3
- data/lib/objects/driver/base.rb +16 -2
- data/lib/objects/driver/ec2.rb +11 -2
- data/lib/objects/driver/gcp.rb +49 -5
- data/lib/objects/driver/gcp/authentication/base.rb +36 -0
- data/lib/objects/driver/gcp/authentication/oauth.rb +24 -29
- data/lib/objects/driver/gcp/authentication/oauth_client_config.rb +22 -0
- data/lib/objects/driver/gcp/authentication/oauth_session_store.rb +22 -0
- data/lib/objects/driver/gcp/authentication/service_account.rb +57 -2
- data/lib/objects/driver/gcp/authentication/signet/service_account.rb +27 -0
- data/lib/objects/driver/gcp/authentication/utilities.rb +42 -0
- data/lib/objects/encryptor.rb +83 -0
- data/lib/objects/exception/base.rb +10 -3
- data/lib/objects/exception/ec2_driver_missing_authorization_keys.rb +11 -0
- data/lib/objects/exception/empty_namespace_tree.rb +11 -0
- data/lib/objects/exception/gcp_auth_service_account_missing_credentials.rb +11 -0
- data/lib/objects/exception/invalid_metadata_encryption_key.rb +1 -1
- data/lib/objects/exception/missing_gcp_service_account_credentials_filename.rb +11 -0
- data/lib/objects/exception/user_orchestration_error.rb +11 -0
- data/lib/objects/initialization/factory.rb +36 -0
- data/lib/objects/initialization/structure.rb +18 -0
- data/lib/objects/initialization/utils.rb +20 -0
- data/lib/objects/loading_bar/handler.rb +1 -1
- data/lib/objects/loading_bar/indicator/base.rb +1 -0
- data/lib/objects/modules/draw.rb +49 -0
- data/lib/objects/modules/tree.rb +157 -0
- data/lib/objects/modules/workspace_commands.rb +2 -32
- data/lib/objects/modules/workspace_menu.rb +113 -48
- data/lib/objects/node/attributes.rb +6 -0
- data/lib/objects/node/base.rb +27 -7
- data/lib/objects/node/cache_handler.rb +1 -1
- data/lib/objects/node/factory.rb +15 -11
- data/lib/objects/node/inventory/base.rb +9 -3
- data/lib/objects/node/inventory/defined.rb +18 -15
- data/lib/objects/node/inventory/merge.rb +9 -1
- data/lib/objects/node/inventory/subselect.rb +6 -4
- data/lib/objects/node/meta_data_factory.rb +1 -1
- data/lib/objects/node/meta_data_loader.rb +2 -2
- data/lib/objects/node/resources/inventory.rb +19 -0
- data/lib/objects/node/resources/merged.rb +23 -14
- data/lib/objects/node/resources/sub_inventory.rb +6 -5
- data/lib/objects/node/server/base.rb +35 -22
- data/lib/objects/node/server/dynamic/ec2.rb +0 -1
- data/lib/objects/node/server/dynamic/gcp.rb +0 -1
- data/lib/objects/node/server/static.rb +22 -9
- data/lib/objects/orchestration/base.rb +7 -1
- data/lib/objects/orchestration/interactive_terraform.rb +10 -16
- data/lib/objects/registry/command/external.rb +6 -2
- data/lib/objects/registry/command/group.rb +5 -1
- data/lib/objects/registry/loader.rb +3 -0
- data/lib/objects/ssh/command.rb +4 -8
- data/lib/objects/ssh/command_exec.rb +3 -1
- data/lib/objects/ssh/connection_wrangler.rb +34 -17
- data/lib/objects/ssh/connector.rb +17 -9
- data/lib/objects/ssh/driver.rb +7 -18
- data/lib/objects/ssh/driver_concerns/connection.rb +3 -11
- data/lib/objects/ssh/driver_concerns/functions.rb +7 -7
- data/lib/objects/ssh/proxy_chain.rb +19 -0
- data/lib/objects/ssh/proxy_chain_link.rb +26 -0
- data/lib/objects/ssh/proxy_hop.rb +47 -18
- data/lib/objects/ssh/script_exec.rb +9 -11
- data/lib/objects/startup.rb +7 -1
- data/lib/objects/terraform/output.rb +5 -1
- data/lib/objects/workspace.rb +10 -0
- data/patches/irb.rb +35 -1
- data/patches/string.rb +13 -0
- metadata +71 -25
- data/lib/objects/driver/static.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6487e49ca4d5c08aa0ffa0debb3fa7451db2a2e5cafa03c4962e40bf8790f3dc
|
4
|
+
data.tar.gz: 8a0878e1514dd2207939474d30998e4ac777de4ef68da8eff0570fe776d54602
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fccfbb6428abfc99e58865369574f04860833015d7dbe4062f93533dcf3b8362e051603371db25b396012ee94c51e565d0666c8766bd139b52577897da18e3ff
|
7
|
+
data.tar.gz: 920284c1ba38dfeb1c688fb78d262f7d5762a3350aa61fa6145045cde303599e391fe60076f2207bf2d90ccabafc38c7c0e38cda9a99dcc65bfad309ab37ebe1
|
data/lib/bcome.rb
CHANGED
@@ -7,6 +7,7 @@ require 'pmap'
|
|
7
7
|
require 'singleton'
|
8
8
|
require 'require_all'
|
9
9
|
require 'tty-cursor'
|
10
|
+
require 'strings-ansi'
|
10
11
|
require 'pry'
|
11
12
|
|
12
13
|
require_all "#{File.dirname(__FILE__)}/../patches"
|
@@ -15,3 +16,9 @@ require_all "#{File.dirname(__FILE__)}/../lib/objects"
|
|
15
16
|
# Load in any user defined orchestration
|
16
17
|
path_to_bcome_orchestration_configs = "#{Dir.getwd}/bcome/orchestration"
|
17
18
|
require_all path_to_bcome_orchestration_configs if File.directory?(path_to_bcome_orchestration_configs)
|
19
|
+
|
20
|
+
# Load in any patches
|
21
|
+
# Note: previously patches could have (and were placed) anywhere in the orchestration directory above. This just makes it more explicit, and keeps
|
22
|
+
# things tidier.
|
23
|
+
path_to_user_monkey_patches = "#{Dir.getwd}/bcome/patches"
|
24
|
+
require_all path_to_user_monkey_patches if File.directory?(path_to_user_monkey_patches)
|
@@ -7,15 +7,15 @@ module Bcome
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.release
|
10
|
-
'
|
10
|
+
'2.0.0'
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.release_name
|
14
|
-
'
|
14
|
+
'Multicloud & Hybrid'
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.display
|
18
|
-
"#{name} #{release} #{release_name}"
|
18
|
+
"#{name} v#{release} - #{release_name}"
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/objects/bootup.rb
CHANGED
@@ -29,8 +29,7 @@ module Bcome
|
|
29
29
|
|
30
30
|
def init_context(context)
|
31
31
|
if @spawn_into_console
|
32
|
-
|
33
|
-
::Bcome::Workspace.instance.set(context: context)
|
32
|
+
::Bcome::Workspace.instance.set(context: context, show_welcome: true)
|
34
33
|
else
|
35
34
|
context
|
36
35
|
end
|
@@ -44,11 +43,13 @@ module Bcome
|
|
44
43
|
starting_context.load_nodes if starting_context.inventory? && !starting_context.nodes_loaded?
|
45
44
|
|
46
45
|
# Attempt to load our next context resource
|
47
|
-
next_context = starting_context.
|
46
|
+
next_context = starting_context.resources.active.first if crumb == 'first'
|
47
|
+
next_context ||= starting_context.resource_for_identifier(crumb)
|
48
48
|
|
49
49
|
# Our current breadcrumb is not a node, and so we'll attempt to invoke a method call on the previous
|
50
50
|
# e.g. given resource:foo, then invoke 'foo' on 'resource'
|
51
51
|
unless next_context
|
52
|
+
puts "\n" # clean any trailing loading bars
|
52
53
|
starting_context.invoke(crumb, @arguments)
|
53
54
|
return
|
54
55
|
end
|
data/lib/objects/driver/base.rb
CHANGED
@@ -5,7 +5,7 @@ module Bcome::Driver
|
|
5
5
|
class << self
|
6
6
|
def create_from_config(config, node)
|
7
7
|
raise Bcome::Exception::InvalidNetworkDriverType, 'Your network configurtion is invalid' unless config.is_a?(Hash)
|
8
|
-
raise Bcome::Exception::InvalidNetworkDriverType, "Missing config parameter 'type'" unless config[:type]
|
8
|
+
raise Bcome::Exception::InvalidNetworkDriverType, "Missing config parameter 'type' for namespace '#{config.inspect}'" unless config[:type]
|
9
9
|
|
10
10
|
config_klass_key = config[:type].to_sym
|
11
11
|
driver_klass = klass_for_type[config_klass_key]
|
@@ -17,7 +17,6 @@ module Bcome::Driver
|
|
17
17
|
|
18
18
|
def klass_for_type
|
19
19
|
{
|
20
|
-
static: ::Bcome::Driver::Static,
|
21
20
|
ec2: ::Bcome::Driver::Ec2,
|
22
21
|
gcp: ::Bcome::Driver::Gcp
|
23
22
|
}
|
@@ -58,5 +57,20 @@ module Bcome::Driver
|
|
58
57
|
def config
|
59
58
|
@params
|
60
59
|
end
|
60
|
+
|
61
|
+
## Spoof-fetch. Used with the network-socket linkup POC.
|
62
|
+
def spoof_fetch_server_list(monkey_patched_inventory)
|
63
|
+
if @node.nodes_loaded?
|
64
|
+
monkey_patched_inventory.set_static_servers
|
65
|
+
else
|
66
|
+
wrap_indicator type: :basic, title: loader_title, completed_title: loader_completed_title do
|
67
|
+
fake_delay_milliseconds = rand(1..400).to_f / 1000
|
68
|
+
sleep fake_delay_milliseconds
|
69
|
+
monkey_patched_inventory.set_static_servers
|
70
|
+
signal_success
|
71
|
+
end
|
72
|
+
@node.nodes_loaded!
|
73
|
+
end
|
74
|
+
end
|
61
75
|
end
|
62
76
|
end
|
data/lib/objects/driver/ec2.rb
CHANGED
@@ -4,11 +4,14 @@ require 'fog/aws'
|
|
4
4
|
|
5
5
|
module Bcome::Driver
|
6
6
|
class Ec2 < Bcome::Driver::Base
|
7
|
-
PATH_TO_FOG_CREDENTIALS =
|
7
|
+
PATH_TO_FOG_CREDENTIALS = '.aws/keys'
|
8
8
|
|
9
9
|
def initialize(*params)
|
10
10
|
super
|
11
11
|
raise Bcome::Exception::Ec2DriverMissingProvisioningRegion, params.inspect unless provisioning_region
|
12
|
+
raise ::Bcome::Exception::Ec2DriverMissingAuthorizationKeys, PATH_TO_FOG_CREDENTIALS unless File.exist?(PATH_TO_FOG_CREDENTIALS)
|
13
|
+
|
14
|
+
ENV['FOG_RC'] = PATH_TO_FOG_CREDENTIALS
|
12
15
|
end
|
13
16
|
|
14
17
|
def pretty_provider_name
|
@@ -23,7 +26,12 @@ module Bcome::Driver
|
|
23
26
|
@fog_client ||= get_fog_client
|
24
27
|
end
|
25
28
|
|
26
|
-
def fetch_server_list(
|
29
|
+
def fetch_server_list(legacy_ec2_filters)
|
30
|
+
# Filters should be defined within a namespace's :network element. Pre 2.0 the expection for AWS was
|
31
|
+
# to define filters at the root level of the namespace. Here we move :filters into :network, yet retain
|
32
|
+
# ec2_filters at the root level for backwards compaibility with pre 2.0 versions.
|
33
|
+
filters = config.key?(:filters) ? config[:filters] : legacy_ec2_filters
|
34
|
+
|
27
35
|
wrap_indicator type: :basic, title: loader_title, completed_title: loader_completed_title do
|
28
36
|
begin
|
29
37
|
@servers = unfiltered_server_list.all(filters)
|
@@ -72,6 +80,7 @@ module Bcome::Driver
|
|
72
80
|
|
73
81
|
def get_fog_client
|
74
82
|
::Fog.credential = credentials_key
|
83
|
+
|
75
84
|
client = ::Fog::Compute.new(
|
76
85
|
provider: 'AWS',
|
77
86
|
region: provisioning_region
|
data/lib/objects/driver/gcp.rb
CHANGED
@@ -39,8 +39,16 @@ module Bcome::Driver
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def do_fetch_server_list(_filters)
|
42
|
-
|
43
|
-
|
42
|
+
# Network filter key now called :filter. retained :list_filter for backwards compatibility.
|
43
|
+
# Fallback is ""
|
44
|
+
filters = (
|
45
|
+
@params[:filters] || (
|
46
|
+
@params[:list_filter] || ''
|
47
|
+
)
|
48
|
+
)
|
49
|
+
|
50
|
+
gcp_service.list_instances(@params[:project], @params[:zone], filter: filters)
|
51
|
+
rescue Google::Apis::AuthorizationError => e
|
44
52
|
raise ::Bcome::Exception::CannotAuthenticateToGcp
|
45
53
|
rescue Google::Apis::ClientError => e
|
46
54
|
raise ::Bcome::Exception::Generic, "Namespace #{@node.namespace} / #{e.message}"
|
@@ -77,8 +85,8 @@ module Bcome::Driver
|
|
77
85
|
def auth_schemes
|
78
86
|
{
|
79
87
|
oauth: ::Bcome::Driver::Gcp::Authentication::Oauth,
|
80
|
-
|
81
|
-
api_key: ::Bcome::Driver::Gcp::Authentication::ApiKey
|
88
|
+
service_account: ::Bcome::Driver::Gcp::Authentication::ServiceAccount
|
89
|
+
# api_key: ::Bcome::Driver::Gcp::Authentication::ApiKey
|
82
90
|
}
|
83
91
|
end
|
84
92
|
|
@@ -94,7 +102,43 @@ module Bcome::Driver
|
|
94
102
|
def authentication_scheme
|
95
103
|
# Service scopes are specified directly from the network config
|
96
104
|
# A minumum scope of https://www.googleapis.com/auth/compute.readonly is required in order to list resources.
|
97
|
-
|
105
|
+
|
106
|
+
auth_scheme_key = @params[:authentication_scheme].to_sym
|
107
|
+
auth_scheme = auth_schemes[auth_scheme_key]
|
108
|
+
raise ::Bcome::Exception::InvalidGcpAuthenticationScheme, "Invalid GCP authentication scheme '#{auth_scheme_key}' for node #{@node.namespace}" unless auth_scheme
|
109
|
+
|
110
|
+
case auth_scheme_key
|
111
|
+
when :oauth
|
112
|
+
|
113
|
+
client_config = ::Bcome::Driver::Gcp::Authentication::OauthClientConfig.new(service_scopes, oauth_filename)
|
114
|
+
|
115
|
+
# Prevent second oauth flow during same session with same credentials, different inventory.
|
116
|
+
# If we already have an outh authentication scheme for the same scopes & oauth credentials, then we'll return that one
|
117
|
+
|
118
|
+
# If the scheme is set, return it
|
119
|
+
return @authentication_scheme if @authentication_scheme
|
120
|
+
|
121
|
+
# Look to see if we have an existing oauth scheme setup for the same scopes & credentials file
|
122
|
+
if @authentication_scheme = ::Bcome::Driver::Gcp::Authentication::OauthSessionStore.instance.in_memory_session_for(client_config)
|
123
|
+
@compute_service = @authentication_scheme.service
|
124
|
+
|
125
|
+
return @authentication_scheme
|
126
|
+
end
|
127
|
+
|
128
|
+
# Otherwise, we'll create a new outh scheme and register it with the session store
|
129
|
+
@authentication_scheme = auth_scheme.new(self, compute_service, client_config, @node)
|
130
|
+
::Bcome::Driver::Gcp::Authentication::OauthSessionStore.instance << @authentication_scheme
|
131
|
+
@authentication_scheme
|
132
|
+
|
133
|
+
when :service_account
|
134
|
+
@authentication_scheme ||= auth_scheme.new(compute_service, service_scopes, @node, @params[:service_account_credentials], self)
|
135
|
+
else
|
136
|
+
raise ::Bcome::Exception::InvalidGcpAuthenticationScheme, "Invalid GCP authentication scheme '#{auth_scheme_key}' for node #{@node.namespace}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def oauth_filename
|
141
|
+
@params[:secrets_path] || @params[:secrets_filename]
|
98
142
|
end
|
99
143
|
|
100
144
|
def gcp_service
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bcome::Driver::Gcp::Authentication
|
4
|
+
class Base
|
5
|
+
include ::Bcome::LoadingBar::Handler
|
6
|
+
|
7
|
+
## Overrides
|
8
|
+
def authorized?
|
9
|
+
raise 'Should be overidden'
|
10
|
+
end
|
11
|
+
|
12
|
+
## Loading bar -
|
13
|
+
|
14
|
+
def loader_title
|
15
|
+
'Authenticating' + "\s#{@driver.pretty_provider_name.bc_blue.bold}\s#{@driver.pretty_resource_location.underline}".bc_green
|
16
|
+
end
|
17
|
+
|
18
|
+
## Credential helpers --
|
19
|
+
|
20
|
+
def credential_directory
|
21
|
+
'.gauth'
|
22
|
+
end
|
23
|
+
|
24
|
+
def full_path_to_credential_file
|
25
|
+
"#{credential_directory}/#{credential_file}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def credential_file
|
29
|
+
"#{@node.keyed_namespace}:#{credential_file_suffix}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def ensure_credential_directory
|
33
|
+
`mkdir -p #{credential_directory}`
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -5,19 +5,24 @@ require 'google/api_client/auth/storages/file_store'
|
|
5
5
|
require 'google/api_client/client_secrets'
|
6
6
|
|
7
7
|
module Bcome::Driver::Gcp::Authentication
|
8
|
-
class Oauth
|
8
|
+
class Oauth < Base
|
9
|
+
include Utilities
|
10
|
+
|
9
11
|
credential_directory = '.gauth'
|
10
|
-
credential_file_suffix = 'oauth2.json'
|
11
12
|
|
12
|
-
|
13
|
+
attr_reader :scopes, :secrets_filename, :service, :client_config
|
13
14
|
|
14
|
-
def initialize(driver, service,
|
15
|
+
def initialize(driver, service, client_config, node)
|
15
16
|
@service = service
|
16
|
-
@scopes = scopes
|
17
|
+
@scopes = client_config.scopes
|
17
18
|
@node = node
|
18
19
|
@driver = driver
|
20
|
+
@client_config = client_config
|
21
|
+
@secrets_filename = client_config.secrets_filename
|
22
|
+
@path_to_secrets = "#{credential_directory}/#{@secrets_filename}"
|
23
|
+
|
24
|
+
raise ::Bcome::Exception::Generic, "Missing OAuth 2.0 client secrets file from GCP network configuration. Cannot find '#{@path_to_secrets}'" unless File.exist?(@path_to_secrets) && File.file?(@path_to_secrets)
|
19
25
|
|
20
|
-
@path_to_secrets = "#{credential_directory}/#{path_to_secrets}"
|
21
26
|
# All credentials are held in .gauth
|
22
27
|
ensure_credential_directory
|
23
28
|
end
|
@@ -26,26 +31,10 @@ module Bcome::Driver::Gcp::Authentication
|
|
26
31
|
storage && !@storage.authorization.nil?
|
27
32
|
end
|
28
33
|
|
29
|
-
def storage
|
30
|
-
@storage ||= ::Google::APIClient::Storage.new(Google::APIClient::FileStore.new(full_path_to_credential_file))
|
31
|
-
end
|
32
|
-
|
33
|
-
def credential_directory
|
34
|
-
'.gauth'
|
35
|
-
end
|
36
|
-
|
37
34
|
def credential_file_suffix
|
38
35
|
'oauth2.json'
|
39
36
|
end
|
40
37
|
|
41
|
-
def full_path_to_credential_file
|
42
|
-
"#{credential_directory}/#{credential_file}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def credential_file
|
46
|
-
"#{@node.keyed_namespace}:#{credential_file_suffix}"
|
47
|
-
end
|
48
|
-
|
49
38
|
def authorize!
|
50
39
|
@service.authorization = storage.authorize
|
51
40
|
end
|
@@ -60,8 +49,14 @@ module Bcome::Driver::Gcp::Authentication
|
|
60
49
|
raise ::Bcome::Exception::MissingOrInvalidClientSecrets, "#{@path_to_secrets}. Gcp exception: #{e.class} #{e.message}"
|
61
50
|
end
|
62
51
|
|
63
|
-
def
|
64
|
-
|
52
|
+
def storage
|
53
|
+
@storage ||= ::Google::APIClient::Storage.new(Google::APIClient::FileStore.new(full_path_to_credential_file))
|
54
|
+
end
|
55
|
+
|
56
|
+
def credential_file
|
57
|
+
# If an authorization has the same scopes & secrets file, it is the same authorization. Hence we store the resulting oauth2 access credentials as the same file. This allows
|
58
|
+
# re-use of authorizations and prevents multiple oauth loops.
|
59
|
+
"#{@client_config.checksum}:#{credential_file_suffix}"
|
65
60
|
end
|
66
61
|
|
67
62
|
def do!
|
@@ -70,12 +65,16 @@ module Bcome::Driver::Gcp::Authentication
|
|
70
65
|
# Total bloat from google here. Thanks google... requiring at last possible moment.
|
71
66
|
require 'google/api_client/auth/installed_app'
|
72
67
|
|
73
|
-
|
68
|
+
wrap_indicator type: :basic, title: loader_title, completed_title: '' do
|
74
69
|
flow = Google::APIClient::InstalledAppFlow.new(
|
75
70
|
client_id: client_secrets.client_id,
|
76
71
|
client_secret: client_secrets.client_secret,
|
77
72
|
scope: @scopes
|
78
73
|
)
|
74
|
+
|
75
|
+
## Override the redirected-to screen so that clearer instruction can be given
|
76
|
+
flow.class.send(:remove_const,'RESPONSE_BODY') if flow.class.const_defined?('RESPONSE_BODY')
|
77
|
+
flow.class.send(:const_set,'RESPONSE_BODY', oauth_redirect_html)
|
79
78
|
|
80
79
|
begin
|
81
80
|
@service.authorization = flow.authorize(storage)
|
@@ -93,9 +92,5 @@ module Bcome::Driver::Gcp::Authentication
|
|
93
92
|
def notify_success
|
94
93
|
print "[\s" + "Credentials file written to\s" + full_path_to_credential_file + "\s]" + "\n"
|
95
94
|
end
|
96
|
-
|
97
|
-
def ensure_credential_directory
|
98
|
-
`mkdir -p #{credential_directory}`
|
99
|
-
end
|
100
95
|
end
|
101
96
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
module Bcome::Driver::Gcp::Authentication
|
6
|
+
class OauthClientConfig
|
7
|
+
attr_reader :scopes, :secrets_filename
|
8
|
+
|
9
|
+
def initialize(scopes, secrets_filename)
|
10
|
+
@scopes = scopes
|
11
|
+
@secrets_filename = secrets_filename
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
checksum == other.checksum
|
16
|
+
end
|
17
|
+
|
18
|
+
def checksum
|
19
|
+
@checksum ||= ::Digest::MD5.hexdigest(Marshal.dump("#{@scopes}-#{@secrets_filename}"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bcome::Driver::Gcp::Authentication
|
4
|
+
class OauthSessionStore
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@oauth_sessions = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def in_memory_session_for(oauth_client_config)
|
12
|
+
existing_session = @oauth_sessions.detect do |session|
|
13
|
+
session.client_config == oauth_client_config
|
14
|
+
end
|
15
|
+
existing_session
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(session)
|
19
|
+
@oauth_sessions << session
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,7 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Bcome::Driver::Gcp::Authentication
|
4
|
-
class ServiceAccount
|
5
|
-
def initialize(service, scopes, node,
|
4
|
+
class ServiceAccount < Base
|
5
|
+
def initialize(service, scopes, node, credentials_file_name, driver)
|
6
|
+
@service = service
|
7
|
+
@scopes = scopes
|
8
|
+
@node = node
|
9
|
+
@driver = driver
|
10
|
+
@credentials_file_name = credentials_file_name
|
11
|
+
ensure_credential_directory
|
12
|
+
ensure_credentials_file
|
13
|
+
end
|
14
|
+
|
15
|
+
def do!
|
16
|
+
@service.authorization = service_account
|
17
|
+
end
|
18
|
+
|
19
|
+
def authorized?
|
20
|
+
!@service.authorization.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def service_account
|
24
|
+
@service_account ||= ::Bcome::Driver::Gcp::Authentication::SignetServiceAccountClient.new(@scopes, credentials_file_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def credentials_file_path
|
28
|
+
has_namespaced_keyed_filename? ? namespaced_keyed_filename : defined_credentials_files
|
29
|
+
end
|
30
|
+
|
31
|
+
def ensure_credentials_file
|
32
|
+
return if has_namespaced_keyed_filename?
|
33
|
+
raise ::Bcome::Exception::MissingGcpServiceAccountCredentialsFilename unless @credentials_file_name
|
34
|
+
end
|
35
|
+
|
36
|
+
## New implementation - we take a defined file name for the service account credentials
|
37
|
+
## Clean & may be re-used
|
38
|
+
def defined_credentials_files
|
39
|
+
"#{credential_directory}/#{@credentials_file_name}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_namespaced_keyed_filename?
|
43
|
+
@has_namespaced_keyed_filename ||= File.exist?(namespaced_keyed_filename)
|
44
|
+
end
|
45
|
+
|
46
|
+
## Older implementation - we infer the credentials file from the namespace
|
47
|
+
## Retained to provide backwards compatibility
|
48
|
+
def namespaced_keyed_filename
|
49
|
+
full_path_to_credential_file
|
50
|
+
end
|
51
|
+
|
52
|
+
def credential_file_suffix
|
53
|
+
'service-account.json'
|
54
|
+
end
|
55
|
+
#######################################
|
56
|
+
|
57
|
+
def authorize!
|
58
|
+
storage.authorize
|
59
|
+
@service.authorization = storage.authorization
|
60
|
+
end
|
6
61
|
end
|
7
62
|
end
|