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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bcome.rb +7 -0
  3. data/lib/objects/bcome/version.rb +3 -3
  4. data/lib/objects/bootup.rb +4 -3
  5. data/lib/objects/driver/base.rb +16 -2
  6. data/lib/objects/driver/ec2.rb +11 -2
  7. data/lib/objects/driver/gcp.rb +49 -5
  8. data/lib/objects/driver/gcp/authentication/base.rb +36 -0
  9. data/lib/objects/driver/gcp/authentication/oauth.rb +24 -29
  10. data/lib/objects/driver/gcp/authentication/oauth_client_config.rb +22 -0
  11. data/lib/objects/driver/gcp/authentication/oauth_session_store.rb +22 -0
  12. data/lib/objects/driver/gcp/authentication/service_account.rb +57 -2
  13. data/lib/objects/driver/gcp/authentication/signet/service_account.rb +27 -0
  14. data/lib/objects/driver/gcp/authentication/utilities.rb +42 -0
  15. data/lib/objects/encryptor.rb +83 -0
  16. data/lib/objects/exception/base.rb +10 -3
  17. data/lib/objects/exception/ec2_driver_missing_authorization_keys.rb +11 -0
  18. data/lib/objects/exception/empty_namespace_tree.rb +11 -0
  19. data/lib/objects/exception/gcp_auth_service_account_missing_credentials.rb +11 -0
  20. data/lib/objects/exception/invalid_metadata_encryption_key.rb +1 -1
  21. data/lib/objects/exception/missing_gcp_service_account_credentials_filename.rb +11 -0
  22. data/lib/objects/exception/user_orchestration_error.rb +11 -0
  23. data/lib/objects/initialization/factory.rb +36 -0
  24. data/lib/objects/initialization/structure.rb +18 -0
  25. data/lib/objects/initialization/utils.rb +20 -0
  26. data/lib/objects/loading_bar/handler.rb +1 -1
  27. data/lib/objects/loading_bar/indicator/base.rb +1 -0
  28. data/lib/objects/modules/draw.rb +49 -0
  29. data/lib/objects/modules/tree.rb +157 -0
  30. data/lib/objects/modules/workspace_commands.rb +2 -32
  31. data/lib/objects/modules/workspace_menu.rb +113 -48
  32. data/lib/objects/node/attributes.rb +6 -0
  33. data/lib/objects/node/base.rb +27 -7
  34. data/lib/objects/node/cache_handler.rb +1 -1
  35. data/lib/objects/node/factory.rb +15 -11
  36. data/lib/objects/node/inventory/base.rb +9 -3
  37. data/lib/objects/node/inventory/defined.rb +18 -15
  38. data/lib/objects/node/inventory/merge.rb +9 -1
  39. data/lib/objects/node/inventory/subselect.rb +6 -4
  40. data/lib/objects/node/meta_data_factory.rb +1 -1
  41. data/lib/objects/node/meta_data_loader.rb +2 -2
  42. data/lib/objects/node/resources/inventory.rb +19 -0
  43. data/lib/objects/node/resources/merged.rb +23 -14
  44. data/lib/objects/node/resources/sub_inventory.rb +6 -5
  45. data/lib/objects/node/server/base.rb +35 -22
  46. data/lib/objects/node/server/dynamic/ec2.rb +0 -1
  47. data/lib/objects/node/server/dynamic/gcp.rb +0 -1
  48. data/lib/objects/node/server/static.rb +22 -9
  49. data/lib/objects/orchestration/base.rb +7 -1
  50. data/lib/objects/orchestration/interactive_terraform.rb +10 -16
  51. data/lib/objects/registry/command/external.rb +6 -2
  52. data/lib/objects/registry/command/group.rb +5 -1
  53. data/lib/objects/registry/loader.rb +3 -0
  54. data/lib/objects/ssh/command.rb +4 -8
  55. data/lib/objects/ssh/command_exec.rb +3 -1
  56. data/lib/objects/ssh/connection_wrangler.rb +34 -17
  57. data/lib/objects/ssh/connector.rb +17 -9
  58. data/lib/objects/ssh/driver.rb +7 -18
  59. data/lib/objects/ssh/driver_concerns/connection.rb +3 -11
  60. data/lib/objects/ssh/driver_concerns/functions.rb +7 -7
  61. data/lib/objects/ssh/proxy_chain.rb +19 -0
  62. data/lib/objects/ssh/proxy_chain_link.rb +26 -0
  63. data/lib/objects/ssh/proxy_hop.rb +47 -18
  64. data/lib/objects/ssh/script_exec.rb +9 -11
  65. data/lib/objects/startup.rb +7 -1
  66. data/lib/objects/terraform/output.rb +5 -1
  67. data/lib/objects/workspace.rb +10 -0
  68. data/patches/irb.rb +35 -1
  69. data/patches/string.rb +13 -0
  70. metadata +71 -25
  71. data/lib/objects/driver/static.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ace465761e84db321e1de7eea860a3ade94ecda5d5e091e8784740b1cb07ea4
4
- data.tar.gz: 996329541843570edfef238c8a1dd46830402fd04586530b66810478b303b59c
3
+ metadata.gz: 6487e49ca4d5c08aa0ffa0debb3fa7451db2a2e5cafa03c4962e40bf8790f3dc
4
+ data.tar.gz: 8a0878e1514dd2207939474d30998e4ac777de4ef68da8eff0570fe776d54602
5
5
  SHA512:
6
- metadata.gz: db096f8fdde0c83e57519c5d09089d3d8e2bf26a4e4f07c675cf18aafb42a279ca7788114378dd7737e84f4279bbc09e141a1612669de6bea792370bd419fffd
7
- data.tar.gz: 4ed639e3378da6b8cefef9727c640d8462ff3fe01f35f63d30b28ef4cd3c50c8975cf7226f4b74f789068223238e860dd7f8300cc4861b18f25b6dec4149b9a7
6
+ metadata.gz: fccfbb6428abfc99e58865369574f04860833015d7dbe4062f93533dcf3b8362e051603371db25b396012ee94c51e565d0666c8766bd139b52577897da18e3ff
7
+ data.tar.gz: 920284c1ba38dfeb1c688fb78d262f7d5762a3350aa61fa6145045cde303599e391fe60076f2207bf2d90ccabafc38c7c0e38cda9a99dcc65bfad309ab37ebe1
@@ -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
- '1.4.0'
10
+ '2.0.0'
11
11
  end
12
12
 
13
13
  def self.release_name
14
- 'multicloud'
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
@@ -29,8 +29,7 @@ module Bcome
29
29
 
30
30
  def init_context(context)
31
31
  if @spawn_into_console
32
- puts "\n\n"
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.resource_for_identifier(crumb)
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
@@ -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
@@ -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 = "#{ENV['HOME']}/.fog"
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(filters)
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
@@ -39,8 +39,16 @@ module Bcome::Driver
39
39
  end
40
40
 
41
41
  def do_fetch_server_list(_filters)
42
- gcp_service.list_instances(@params[:project], @params[:zone])
43
- rescue Google::Apis::AuthorizationError
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
- serviceaccount: ::Bcome::Driver::Gcp::Authentication::ServiceAccount,
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
- @authentication_scheme ||= auth_scheme.new(self, compute_service, service_scopes, @node, @params[:secrets_path])
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
- include ::Bcome::LoadingBar::Handler
13
+ attr_reader :scopes, :secrets_filename, :service, :client_config
13
14
 
14
- def initialize(driver, service, scopes, node, path_to_secrets)
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 loader_title
64
- 'Authenticating' + "\s#{@driver.pretty_provider_name.bc_blue.bold}\s#{@driver.pretty_resource_location.underline}".bc_green
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
- wrap_indicator type: :basic, title: loader_title, completed_title: '' do
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, path_to_secrets); end
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