bcome 1.3.2 → 1.4.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 (165) hide show
  1. checksums.yaml +5 -5
  2. data/bin/bcome +13 -8
  3. data/lib/bcome.rb +7 -11
  4. data/lib/objects/bcome/version.rb +19 -1
  5. data/lib/objects/bootup.rb +13 -5
  6. data/lib/objects/command/local.rb +2 -0
  7. data/lib/objects/config_factory.rb +3 -0
  8. data/lib/objects/driver/base.rb +36 -4
  9. data/lib/objects/driver/bucket.rb +6 -4
  10. data/lib/objects/driver/ec2.rb +35 -4
  11. data/lib/objects/driver/gcp.rb +124 -0
  12. data/lib/objects/driver/gcp/authentication/api_key.rb +6 -0
  13. data/lib/objects/driver/gcp/authentication/oauth.rb +101 -0
  14. data/lib/objects/driver/gcp/authentication/service_account.rb +7 -0
  15. data/lib/objects/driver/static.rb +2 -0
  16. data/lib/objects/encryptor.rb +26 -24
  17. data/lib/objects/exception/argument_error_invoking_method_from_command_line.rb +8 -4
  18. data/lib/objects/exception/base.rb +14 -10
  19. data/lib/objects/exception/can_only_subselect_on_inventory.rb +8 -4
  20. data/lib/objects/exception/cannot_authenticate_to_gcp.rb +11 -0
  21. data/lib/objects/exception/cannot_find_internal_registry_klass.rb +8 -4
  22. data/lib/objects/exception/cannot_find_inventory.rb +11 -0
  23. data/lib/objects/exception/cannot_find_subselection_parent.rb +8 -4
  24. data/lib/objects/exception/cant_find_key_in_cloud_tags.rb +8 -4
  25. data/lib/objects/exception/cant_find_key_in_metadata.rb +8 -4
  26. data/lib/objects/exception/cant_find_proxy_host_by_identifier.rb +8 -4
  27. data/lib/objects/exception/cant_find_proxy_host_by_namespace.rb +8 -4
  28. data/lib/objects/exception/could_not_initiate_ssh_connection.rb +8 -4
  29. data/lib/objects/exception/could_not_initiate_ssh_connection_through_backend_proxy.rb +8 -4
  30. data/lib/objects/exception/could_not_retrieve_terraform_output.rb +11 -0
  31. data/lib/objects/exception/deprecation_warning.rb +9 -7
  32. data/lib/objects/exception/duplicate_command_line_argument_key.rb +8 -4
  33. data/lib/objects/exception/ec2_driver_missing_provisioning_region.rb +8 -4
  34. data/lib/objects/exception/failed_to_run_local_command.rb +8 -4
  35. data/lib/objects/exception/generic.rb +11 -0
  36. data/lib/objects/exception/interactive_session_halt.rb +6 -2
  37. data/lib/objects/exception/invalid_bcome_breadcrumb.rb +8 -4
  38. data/lib/objects/exception/invalid_breadcrumb.rb +8 -4
  39. data/lib/objects/exception/invalid_context_command.rb +8 -4
  40. data/lib/objects/exception/invalid_gcp_authentication_scheme.rb +11 -0
  41. data/lib/objects/exception/invalid_identifier.rb +8 -4
  42. data/lib/objects/exception/invalid_machines_cache_config.rb +8 -4
  43. data/lib/objects/exception/invalid_matcher_query.rb +8 -4
  44. data/lib/objects/exception/invalid_meta_data_config.rb +8 -4
  45. data/lib/objects/exception/invalid_metadata_encryption_key.rb +8 -4
  46. data/lib/objects/exception/invalid_network_config.rb +8 -4
  47. data/lib/objects/exception/invalid_network_driver_type.rb +8 -4
  48. data/lib/objects/exception/invalid_port_forward_request.rb +11 -0
  49. data/lib/objects/exception/invalid_proxy_config.rb +8 -4
  50. data/lib/objects/exception/invalid_regexp_matcher_in_registry.rb +8 -4
  51. data/lib/objects/exception/invalid_registry_arguments_type.rb +8 -4
  52. data/lib/objects/exception/invalid_registry_command_name_length.rb +8 -4
  53. data/lib/objects/exception/invalid_registry_data_config.rb +8 -4
  54. data/lib/objects/exception/invalid_restriction_key_in_registry.rb +8 -4
  55. data/lib/objects/exception/invalid_ssh_config.rb +8 -4
  56. data/lib/objects/exception/inventories_cannot_have_subviews.rb +8 -4
  57. data/lib/objects/exception/malformed_command_line_arguments.rb +8 -4
  58. data/lib/objects/exception/method_invocation_requires_parameter.rb +8 -4
  59. data/lib/objects/exception/method_name_conflict_in_registry.rb +8 -4
  60. data/lib/objects/exception/missing_argument_for_registry_command.rb +8 -4
  61. data/lib/objects/exception/missing_description_on_view.rb +8 -4
  62. data/lib/objects/exception/missing_execute_on_registry_object.rb +8 -4
  63. data/lib/objects/exception/missing_gcp_authentication_scheme.rb +11 -0
  64. data/lib/objects/exception/missing_gcp_service_scopes.rb +11 -0
  65. data/lib/objects/exception/missing_identifier_on_view.rb +8 -4
  66. data/lib/objects/exception/missing_inventory_contributors.rb +11 -0
  67. data/lib/objects/exception/missing_ip_address_on_server.rb +8 -4
  68. data/lib/objects/exception/missing_network_config.rb +8 -4
  69. data/lib/objects/exception/missing_or_invalid_client_secrets.rb +11 -0
  70. data/lib/objects/exception/missing_params_for_rsync.rb +8 -4
  71. data/lib/objects/exception/missing_params_for_scp.rb +8 -4
  72. data/lib/objects/exception/missing_subselection_key.rb +8 -4
  73. data/lib/objects/exception/missing_type_on_view.rb +8 -4
  74. data/lib/objects/exception/no_node_found_for_breadcrumb.rb +8 -4
  75. data/lib/objects/exception/no_node_named_by_identifier.rb +8 -4
  76. data/lib/objects/exception/node_identifiers_must_be_unique.rb +8 -4
  77. data/lib/objects/exception/orchestration_script_does_not_exist.rb +8 -4
  78. data/lib/objects/exception/proxy_host_node_does_not_have_public_ip_address.rb +8 -4
  79. data/lib/objects/exception/unknown_dynamic_server_type.rb +11 -0
  80. data/lib/objects/exception/unknown_method_for_namespace.rb +8 -4
  81. data/lib/objects/interactive/session.rb +4 -1
  82. data/lib/objects/interactive/session_item/base.rb +2 -0
  83. data/lib/objects/interactive/session_item/capture_input.rb +2 -0
  84. data/lib/objects/interactive/session_item/transparent_ssh.rb +29 -23
  85. data/lib/objects/loading_bar/handler.rb +80 -0
  86. data/lib/objects/loading_bar/indicator/base.rb +64 -0
  87. data/lib/objects/loading_bar/indicator/basic.rb +34 -0
  88. data/lib/objects/loading_bar/indicator/progress.rb +26 -0
  89. data/lib/objects/loading_bar/pid_bucket.rb +27 -0
  90. data/lib/objects/modules/context.rb +13 -9
  91. data/lib/objects/modules/registry_management.rb +16 -10
  92. data/lib/objects/modules/ui_output.rb +10 -6
  93. data/lib/objects/modules/workspace_commands.rb +159 -155
  94. data/lib/objects/modules/workspace_menu.rb +129 -124
  95. data/lib/objects/node/attributes.rb +13 -21
  96. data/lib/objects/node/base.rb +116 -67
  97. data/lib/objects/node/cache_handler.rb +2 -0
  98. data/lib/objects/node/collection.rb +10 -9
  99. data/lib/objects/node/factory.rb +35 -28
  100. data/lib/objects/node/inventory/base.rb +100 -100
  101. data/lib/objects/node/inventory/defined.rb +110 -89
  102. data/lib/objects/node/inventory/merge.rb +43 -0
  103. data/lib/objects/node/inventory/subselect.rb +64 -46
  104. data/lib/objects/node/kube/base.rb +51 -0
  105. data/lib/objects/node/kube/container.rb +9 -0
  106. data/lib/objects/node/kube/estate.rb +19 -0
  107. data/lib/objects/node/kube/namespace.rb +24 -0
  108. data/lib/objects/node/kube/pod.rb +24 -0
  109. data/lib/objects/node/kube_wrap.rb +26 -0
  110. data/lib/objects/node/meta/base.rb +8 -1
  111. data/lib/objects/node/meta/cloud.rb +2 -0
  112. data/lib/objects/node/meta/local.rb +2 -0
  113. data/lib/objects/node/meta_data_factory.rb +3 -1
  114. data/lib/objects/node/meta_data_loader.rb +29 -23
  115. data/lib/objects/node/resources/base.rb +5 -1
  116. data/lib/objects/node/resources/inventory.rb +7 -5
  117. data/lib/objects/node/resources/merged.rb +38 -0
  118. data/lib/objects/node/resources/sub_inventory.rb +7 -4
  119. data/lib/objects/node/server/base.rb +91 -65
  120. data/lib/objects/node/server/dynamic/base.rb +23 -0
  121. data/lib/objects/node/server/{dynamic.rb → dynamic/ec2.rb} +14 -13
  122. data/lib/objects/node/server/dynamic/gcp.rb +47 -0
  123. data/lib/objects/node/server/static.rb +13 -2
  124. data/lib/objects/orchestration/base.rb +10 -0
  125. data/lib/objects/orchestration/interactive_terraform.rb +62 -27
  126. data/lib/objects/orchestrator.rb +22 -0
  127. data/lib/objects/parser/bread_crumb.rb +3 -1
  128. data/lib/objects/registry/arguments/base.rb +3 -1
  129. data/lib/objects/registry/arguments/command_line.rb +6 -1
  130. data/lib/objects/registry/arguments/console.rb +4 -1
  131. data/lib/objects/registry/command/base.rb +3 -0
  132. data/lib/objects/registry/command/external.rb +4 -2
  133. data/lib/objects/registry/command/group.rb +6 -3
  134. data/lib/objects/registry/command/internal.rb +3 -1
  135. data/lib/objects/registry/command/shortcut.rb +17 -9
  136. data/lib/objects/registry/command_list.rb +2 -0
  137. data/lib/objects/registry/loader.rb +10 -10
  138. data/lib/objects/ssh/bootstrap.rb +3 -1
  139. data/lib/objects/ssh/command.rb +10 -5
  140. data/lib/objects/ssh/command_exec.rb +13 -9
  141. data/lib/objects/ssh/connection_wrangler.rb +105 -0
  142. data/lib/objects/ssh/connector.rb +100 -0
  143. data/lib/objects/ssh/driver.rb +27 -215
  144. data/lib/objects/ssh/driver_concerns/command_strings.rb +17 -0
  145. data/lib/objects/ssh/driver_concerns/connection.rb +78 -0
  146. data/lib/objects/ssh/driver_concerns/functions.rb +89 -0
  147. data/lib/objects/ssh/driver_concerns/user.rb +32 -0
  148. data/lib/objects/ssh/{proxy_data.rb → proxy_hop.rb} +52 -7
  149. data/lib/objects/ssh/script_exec.rb +4 -1
  150. data/lib/objects/ssh/tunnel/local_port_forward.rb +5 -6
  151. data/lib/objects/ssh/tunnel_keeper.rb +21 -0
  152. data/lib/objects/ssh/window.rb +31 -0
  153. data/lib/objects/startup.rb +52 -0
  154. data/lib/objects/system/local.rb +3 -0
  155. data/lib/objects/terraform/output.rb +41 -0
  156. data/lib/objects/workspace.rb +3 -14
  157. data/patches/irb.rb +29 -6
  158. data/patches/string-encrypt.rb +20 -23
  159. data/patches/string.rb +5 -1
  160. data/patches/string_stylesheet.rb +2 -0
  161. metadata +101 -23
  162. data/lib/objects/progress_bar.rb +0 -30
  163. data/lib/objects/ssh/connection_handler.rb +0 -101
  164. data/lib/objects/terraform/parser.rb +0 -23
  165. data/lib/objects/terraform/state.rb +0 -34
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bcome::Node
2
4
  class CacheHandler
3
5
  def initialize(inventory_node)
@@ -1,9 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bcome::Node
2
4
  class Collection < ::Bcome::Node::Base
3
- def self.to_s
4
- 'collection'
5
- end
6
-
7
5
  def inventories
8
6
  inv = []
9
7
  @resources.active.each do |r|
@@ -28,20 +26,23 @@ module Bcome::Node
28
26
  filtered_set
29
27
  end
30
28
 
31
- def machines
29
+ def machines(skip_for_hidden = true)
32
30
  set = []
33
- @resources.active.each do |resource|
31
+
32
+ resources = skip_for_hidden ? @resources.active.reject(&:hide?) : @resources.active
33
+
34
+ resources.each do |resource|
34
35
  if resource.inventory?
35
36
  resource.load_nodes unless resource.nodes_loaded?
36
37
  set << resource.resources.active
37
38
  else
38
- set << resource.machines
39
+ set << resource.machines(skip_for_hidden)
39
40
  end
40
41
  end
41
42
 
42
43
  set.flatten!
43
-
44
- filter_duplicates(set)
44
+ filtered_machines = filter_duplicates(set)
45
+ filtered_machines
45
46
  end
46
47
 
47
48
  def collection?
@@ -1,18 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bcome::Node
2
4
  class Factory
3
5
  include Singleton
4
6
 
5
7
  attr_reader :estate
6
8
 
7
- CONFIG_PATH = 'bcome'.freeze
8
- DEFAULT_CONFIG_NAME = 'networks.yml'.freeze
9
- SERVER_OVERRIDE_CONFIG_NAME = 'machines-data.yml'.freeze
10
- LOCAL_OVERRIDE_CONFIG_NAME = 'me.yml'.freeze
9
+ CONFIG_PATH = 'bcome'
10
+ DEFAULT_CONFIG_NAME = 'networks.yml'
11
+ SERVER_OVERRIDE_CONFIG_NAME = 'machines-data.yml'
12
+ LOCAL_OVERRIDE_CONFIG_NAME = 'me.yml'
13
+
14
+ INVENTORY_KEY = 'inventory'
15
+ COLLECTION_KEY = 'collection'
16
+ SUBSELECT_KEY = 'inventory-subselect'
17
+ MERGE_KEY = 'inventory-merge'
18
+ KUBE_CLUSTER = 'kube-cluster'
11
19
 
12
- INVENTORY_KEY = 'inventory'.freeze
13
- COLLECTION_KEY = 'collection'.freeze
14
- SUBSELECT_KEY = 'inventory-subselect'.freeze
15
- BCOME_RC_FILENAME = '.bcomerc'.freeze
20
+ BCOME_RC_FILENAME = '.bcomerc'
16
21
 
17
22
  def bucket
18
23
  @bucket ||= {}
@@ -24,7 +29,7 @@ module Bcome::Node
24
29
  end
25
30
 
26
31
  def config_path
27
- "#{CONFIG_PATH}/#{config_file_name}"
32
+ ENV['CONF'] || "#{CONFIG_PATH}/#{config_file_name}"
28
33
  end
29
34
 
30
35
  def machines_data_path
@@ -32,7 +37,7 @@ module Bcome::Node
32
37
  end
33
38
 
34
39
  def config_file_name
35
- @config_file_name ||= ENV['CONF'] ? ENV['CONF'] : DEFAULT_CONFIG_NAME
40
+ @config_file_name || DEFAULT_CONFIG_NAME
36
41
  end
37
42
 
38
43
  def create_tree(context_node, views)
@@ -53,11 +58,11 @@ module Bcome::Node
53
58
  raise Bcome::Exception::InvalidNetworkConfig, 'missing config type' unless config[:type]
54
59
 
55
60
  klass = klass_for_view_type[config[:type]]
56
-
61
+
57
62
  raise Bcome::Exception::InvalidNetworkConfig, "invalid config type #{config[:type]}" unless klass
58
63
 
59
64
  node = klass.new(views: config, parent: parent)
60
- create_tree(node, config[:views]) if config[:views] && config[:views].any?
65
+ create_tree(node, config[:views]) if config[:views]&.any?
61
66
  parent.resources << node if parent
62
67
 
63
68
  bucket[node.keyed_namespace] = node
@@ -66,20 +71,19 @@ module Bcome::Node
66
71
  end
67
72
 
68
73
  def validate_view(breadcrumb, data)
69
- unless data && data[:type]
70
- raise Bcome::Exception::InvalidNetworkConfig, "Missing namespace type for for namespace '#{breadcrumb}'"
71
- end
74
+ raise Bcome::Exception::InvalidNetworkConfig, "Missing namespace type for namespace '#{breadcrumb}'" unless data && data[:type]
72
75
 
73
- unless is_valid_view_type?(data[:type])
74
- raise Bcome::Exception::InvalidNetworkConfig, "Invalid View Type '#{data[:type]}' for namespace '#{breadcrumb}'. Expecting View Type to be one of: #{klass_for_view_type.keys.join(', ')}"
75
- end
76
+
77
+ raise Bcome::Exception::InvalidNetworkConfig, "Invalid View Type '#{data[:type]}' for namespace '#{breadcrumb}'. Expecting View Type to be one of: #{klass_for_view_type.keys.join(', ')}" unless is_valid_view_type?(data[:type])
76
78
  end
77
79
 
78
80
  def klass_for_view_type
79
81
  {
80
82
  COLLECTION_KEY => ::Bcome::Node::Collection,
81
83
  INVENTORY_KEY => ::Bcome::Node::Inventory::Defined,
82
- SUBSELECT_KEY => ::Bcome::Node::Inventory::Subselect
84
+ SUBSELECT_KEY => ::Bcome::Node::Inventory::Subselect,
85
+ MERGE_KEY => ::Bcome::Node::Inventory::Merge,
86
+ KUBE_CLUSTER => ::Bcome::Node::Kube::Estate
83
87
  }
84
88
  end
85
89
 
@@ -96,7 +100,7 @@ module Bcome::Node
96
100
  end
97
101
 
98
102
  def machines_data_for_namespace(namespace)
99
- machines_data[namespace] ? machines_data[namespace] : {}
103
+ machines_data[namespace] || {}
100
104
  end
101
105
 
102
106
  def rewrite_estate_config(data)
@@ -107,25 +111,27 @@ module Bcome::Node
107
111
 
108
112
  def load_estate_config
109
113
  config = YAML.load_file(config_path).deep_symbolize_keys
110
- return config
114
+ config.deep_merge(local_data)
111
115
  rescue ArgumentError, Psych::SyntaxError => e
112
116
  raise Bcome::Exception::InvalidNetworkConfig, 'Invalid yaml in network config' + e.message
113
117
  rescue Errno::ENOENT
114
118
  raise Bcome::Exception::DeprecationWarning if is_running_deprecated_configs?
119
+
115
120
  raise Bcome::Exception::MissingNetworkConfig, config_path
116
121
  end
117
122
 
118
123
  def load_machines_data
119
- return {} unless File.exist?(machines_data_path)
124
+ return {} unless File.exist?(machines_data_path)
125
+
120
126
  config = YAML.load_file(machines_data_path).deep_symbolize_keys
121
- return config
127
+ config
122
128
  rescue ArgumentError, Psych::SyntaxError => e
123
129
  raise Bcome::Exception::InvalidNetworkConfig, 'Invalid yaml in machines data config' + e.message
124
130
  end
125
131
 
126
132
  def local_data
127
133
  @local_data ||= load_local_data
128
- end
134
+ end
129
135
 
130
136
  def local_data_path
131
137
  "#{CONFIG_PATH}/#{LOCAL_OVERRIDE_CONFIG_NAME}"
@@ -133,16 +139,17 @@ module Bcome::Node
133
139
 
134
140
  def load_local_data
135
141
  return {} unless File.exist?(local_data_path)
136
- config = YAML.load_file(local_data_path)
142
+
143
+ config = YAML.load_file(local_data_path)
137
144
  return {} if config.nil?
138
- return config
145
+
146
+ config
139
147
  rescue ArgumentError, Psych::SyntaxError => e
140
148
  raise Bcome::Exception::InvalidNetworkConfig, 'Invalid yaml in machines data config' + e.message
141
149
  end
142
150
 
143
151
  def is_running_deprecated_configs?
144
- File.exist?("bcome/config/platform.yml")
152
+ File.exist?('bcome/config/platform.yml')
145
153
  end
146
-
147
154
  end
148
155
  end
@@ -1,104 +1,104 @@
1
- module Bcome::Node::Inventory
2
- class Base < ::Bcome::Node::Base
3
-
4
- def initialize(*params)
5
- super
6
- raise Bcome::Exception::InventoriesCannotHaveSubViews, @views if @views[:views] && !@views[:views].empty?
7
-
8
- @bootstrap = false
9
- end
10
-
11
- def meta_matches(matchers)
12
- data_wrapper = :metadata
13
- matches_for(data_wrapper, matchers)
14
- end
15
-
16
- def cloud_matches(matchers)
17
- data_wrapper = :cloud_tags
18
- matches_for(data_wrapper, matchers)
19
- end
20
-
21
- def machine_by_identifier(identifier)
22
- resources.active.select { |machine| machine.identifier == identifier }.first
23
- end
24
-
25
- def matches_for(data_wrapper, matchers)
26
- resources.active.select do |machine|
27
- machine.send(data_wrapper).has_key_and_value?(matchers)
28
- end
29
- end
30
-
31
- def toggle_bootstrap(set_to = (@bootstrap ? false : true))
32
- resources.active.each do |machine|
33
- machine.toggle_bootstrap(set_to)
34
- end
35
- @bootstrap = (@bootstrap ? false : true)
36
- return
37
- end
38
-
39
- def enabled_menu_items
40
- super + %i[ssh]
41
- end
42
-
43
- def menu_items
44
- base_items = super.dup
45
- base_items[:ssh] = {
46
- description: 'ssh directly into a resource',
47
- usage: 'ssh identifier',
48
- console_only: true
49
- }
50
-
51
- base_items
52
- end
53
-
54
- def resources
55
- @resources ||= ::Bcome::Node::Resources::Inventory.new
56
- end
57
-
58
- def ssh(identifier = nil)
59
- direct_invoke_server(:ssh, identifier)
60
- end
61
-
62
- def tags(identifier = nil)
63
- identifier.nil? ? direct_invoke_all_servers(:tags) : direct_invoke_server(:tags, identifier)
64
- end
65
-
66
- def direct_invoke_server(method, identifier)
67
- unless identifier
68
- puts "\nPlease provide a machine identifier, e.g. #{method} machinename\n".warning unless identifier
69
- return
70
- end
71
-
72
- if resource = resources.for_identifier(identifier)
73
- resource.send(method)
74
- else
75
- raise Bcome::Exception::InvalidBreadcrumb, "Cannot find a node named '#{identifier}'"
1
+ # frozen_string_literal: true
2
+
3
+ module Bcome
4
+ module Node
5
+ module Inventory
6
+ class Base < ::Bcome::Node::Base
7
+ def initialize(*params)
8
+ super
9
+ raise Bcome::Exception::InventoriesCannotHaveSubViews, @views if @views[:views] && !@views[:views].empty?
10
+ end
11
+
12
+ def meta_matches(matchers)
13
+ data_wrapper = :metadata
14
+ matches_for(data_wrapper, matchers)
15
+ end
16
+
17
+ def cloud_matches(matchers)
18
+ data_wrapper = :cloud_tags
19
+ matches_for(data_wrapper, matchers)
20
+ end
21
+
22
+ def machine_by_identifier(identifier)
23
+ resources.active.select { |machine| machine.identifier == identifier }.first
24
+ end
25
+
26
+ def matches_for(data_wrapper, matchers)
27
+ resources.active.select do |machine|
28
+ machine.send(data_wrapper).has_key_and_value?(matchers)
29
+ end
30
+ end
31
+
32
+ def enabled_menu_items
33
+ super + %i[ssh]
34
+ end
35
+
36
+ def menu_items
37
+ base_items = super.dup
38
+ base_items[:ssh] = {
39
+ description: 'ssh directly into a resource',
40
+ usage: 'ssh identifier',
41
+ console_only: true
42
+ }
43
+
44
+ base_items
45
+ end
46
+
47
+ def resources
48
+ @resources ||= ::Bcome::Node::Resources::Inventory.new
49
+ end
50
+
51
+ def ssh(identifier = nil)
52
+ direct_invoke_server(:ssh, identifier)
53
+ end
54
+
55
+ def tags(identifier = nil)
56
+ identifier.nil? ? direct_invoke_all_servers(:tags) : direct_invoke_server(:tags, identifier)
57
+ end
58
+
59
+ def direct_invoke_server(method, identifier)
60
+ # If we only have a single resource in our inventory, then just allow direct invocation
61
+ if resources.size == 1
62
+ resource = resources.first
63
+ else
64
+ # Otherwise, we expect to find the resource by its identifier
65
+ unless identifier
66
+ puts "\nPlease provide a machine identifier, e.g. #{method} machinename\n".warning unless identifier
67
+ return
68
+ end
69
+
70
+ resource = resources.for_identifier(identifier)
71
+ raise Bcome::Exception::InvalidBreadcrumb, "Cannot find a node named '#{identifier}'" unless resource
72
+ end
73
+
74
+ resource.send(method)
75
+ end
76
+
77
+ def direct_invoke_all_servers(method)
78
+ resources.active.each { |m| m.send(method) }
79
+ nil
80
+ end
81
+
82
+ def cache_nodes_in_memory
83
+ @cache_handler.do_cache_nodes!
84
+ end
85
+
86
+ def list_key
87
+ :server
88
+ end
89
+
90
+ def machines(skip_for_hidden = true)
91
+ skip_for_hidden ? resources.active : resources.active.reject(&:hide?)
92
+ end
93
+
94
+ def inventory?
95
+ true
96
+ end
97
+
98
+ def override_server_identifier?
99
+ respond_to?(:override_identifier) && !override_identifier.nil?
100
+ end
76
101
  end
77
102
  end
78
-
79
- def direct_invoke_all_servers(method)
80
- resources.active.each {|m| m.send(method) }
81
- return
82
- end
83
-
84
- def cache_nodes_in_memory
85
- @cache_handler.do_cache_nodes!
86
- end
87
-
88
- def list_key
89
- :server
90
- end
91
-
92
- def machines
93
- @resources.active
94
- end
95
-
96
- def inventory?
97
- true
98
- end
99
-
100
- def override_server_identifier?
101
- !@override_identifier.nil?
102
- end
103
103
  end
104
104
  end
@@ -1,117 +1,138 @@
1
- module Bcome::Node::Inventory
2
- class Defined < ::Bcome::Node::Inventory::Base
3
- MACHINES_CACHE_PATH = 'machines-cache.yml'.freeze
1
+ # frozen_string_literal: true
4
2
 
5
- def self.to_s
6
- 'inventory'
7
- end
3
+ module Bcome
4
+ module Node
5
+ module Inventory
6
+ class Defined < ::Bcome::Node::Inventory::Base
7
+ include ::Bcome::LoadingBar::Handler
8
8
 
9
- attr_reader :dynamic_nodes_loaded
9
+ MACHINES_CACHE_PATH = 'machines-cache.yml'
10
10
 
11
- def initialize(*params)
12
- @load_machines_from_cache = false
13
- @cache_handler = ::Bcome::Node::CacheHandler.new(self)
14
- super
15
- end
11
+ attr_reader :dynamic_nodes_loaded
16
12
 
17
- def enabled_menu_items
18
- super + %i[save reload]
19
- end
13
+ def initialize(*params)
14
+ @load_machines_from_cache = false
15
+ @cache_handler = ::Bcome::Node::CacheHandler.new(self)
16
+ super
17
+ end
20
18
 
21
- def menu_items
22
- base_items = super.dup
19
+ def enabled_menu_items
20
+ super + %i[save reload]
21
+ end
23
22
 
24
- base_items[:reload] = {
25
- description: "Restock this inventory from remote (hit 'save' after to persist)",
26
- console_only: true
27
- }
28
- base_items
29
- end
23
+ def menu_items
24
+ base_items = super.dup
30
25
 
31
- def reload
32
- resources.reset_duplicate_nodes!
33
- do_reload
34
- puts "\nDone. Hit 'ls' to see the refreshed inventory.\n".informational
35
- end
26
+ base_items[:reload] = {
27
+ description: "Restock this inventory from remote (hit 'save' after to persist)",
28
+ console_only: true
29
+ }
30
+ base_items
31
+ end
36
32
 
37
- def set_static_servers
38
- if raw_static_machines_from_cache
39
- raw_static_machines_from_cache.each do |server_config|
40
- resources << ::Bcome::Node::Server::Static.new(views: server_config, parent: self)
33
+ def reload
34
+ resources.reset_duplicate_nodes!
35
+ do_reload
36
+ puts "\n\nDone. Hit 'ls' to see the refreshed inventory.\n".informational
41
37
  end
42
- end
43
- end
44
38
 
45
- def raw_static_machines_from_cache
46
- load_machines_config[namespace.to_sym]
47
- end
39
+ def set_static_servers
40
+ cached_machines = raw_static_machines_from_cache
41
+
42
+ if cached_machines&.any?
43
+ wrap_indicator type: :basic, title: 'Loading' + "\sCACHE".bc_blue.bold + "\s" + namespace.to_s.underline, completed_title: '' do
44
+ cached_machines.each do |server_config|
45
+ resources << ::Bcome::Node::Server::Static.new(views: server_config, parent: self)
46
+ end
47
+ signal_success
48
+ end
49
+ end
50
+ end
48
51
 
49
- def machines_cache_path
50
- "#{::Bcome::Node::Factory::CONFIG_PATH}/#{MACHINES_CACHE_PATH}"
51
- end
52
+ def raw_static_machines_from_cache
53
+ load_machines_config[namespace.to_sym]
54
+ end
52
55
 
53
- def mark_as_cached!
54
- data = ::Bcome::Node::Factory.instance.load_estate_config
55
- data[namespace.to_sym][:load_machines_from_cache] = true
56
- ::Bcome::Node::Factory.instance.rewrite_estate_config(data)
57
- end
56
+ def machines_cache_path
57
+ "#{::Bcome::Node::Factory::CONFIG_PATH}/#{MACHINES_CACHE_PATH}"
58
+ end
59
+
60
+ def mark_as_cached!
61
+ data = ::Bcome::Node::Factory.instance.load_estate_config
62
+ data[namespace.to_sym][:load_machines_from_cache] = true
63
+ ::Bcome::Node::Factory.instance.rewrite_estate_config(data)
64
+ end
58
65
 
59
- def save
60
- @answer = ::Bcome::Interactive::Session.run(self,
61
- :capture_input, terminal_prompt: "\nAre you sure you want to cache these machines (saving will overwrite any previous selections) [Y|N] ? ")
66
+ def save
67
+ @answer = ::Bcome::Interactive::Session.run(self,
68
+ :capture_input, terminal_prompt: 'Are you sure you want to cache these machines (saving will overwrite any previous selections) [Y|N] ? ')
62
69
 
63
- if @answer && @answer == 'Y'
64
- cache_nodes_in_memory
65
- data = load_machines_config
66
- data[namespace] = views[:static_servers]
70
+ if @answer && @answer == 'Y'
71
+ cache_nodes_in_memory
72
+ data = load_machines_config
67
73
 
68
- File.open(machines_cache_path, 'w') do |file|
69
- file.write data.to_yaml
74
+ data.delete(namespace)
75
+ data.delete(namespace.to_sym)
76
+
77
+ data[namespace] = views[:static_servers]
78
+
79
+ File.open(machines_cache_path, 'w') do |file|
80
+ file.write data.to_yaml
81
+ end
82
+ mark_as_cached!
83
+ puts "\nMachines have been cached for node #{namespace}".informational
84
+ else
85
+ puts 'Nothing saved'.warning
86
+ end
70
87
  end
71
- mark_as_cached!
72
- puts "Machines have been cached for node #{namespace}".informational
73
- else
74
- puts 'Nothing saved'.warning
75
- end
76
- end
77
88
 
78
- def load_machines_config
79
- config = YAML.load_file(machines_cache_path).deep_symbolize_keys
80
- return config
81
- rescue ArgumentError, Psych::SyntaxError
82
- raise Bcome::Exception::InvalidMachinesCacheConfig, 'Invalid yaml in config'
83
- rescue Errno::ENOENT
84
- return {}
85
- end
89
+ def load_machines_config
90
+ config = YAML.load_file(machines_cache_path).deep_symbolize_keys
91
+ config
92
+ rescue ArgumentError, Psych::SyntaxError
93
+ raise Bcome::Exception::InvalidMachinesCacheConfig, 'Invalid yaml in config'
94
+ rescue Errno::ENOENT
95
+ {}
96
+ end
86
97
 
87
- def cache_nodes_in_memory
88
- @cache_handler.do_cache_nodes!
89
- end
98
+ def cache_nodes_in_memory
99
+ @cache_handler.do_cache_nodes!
100
+ end
90
101
 
91
- def do_reload
92
- resources.unset!
93
- load_dynamic_nodes
94
- end
102
+ def do_reload
103
+ resources.unset!
104
+ load_dynamic_nodes
105
+ end
95
106
 
96
- def load_nodes
97
- set_static_servers
98
- load_dynamic_nodes unless @load_machines_from_cache
99
- end
107
+ def load_nodes
108
+ set_static_servers
109
+ load_dynamic_nodes unless @load_machines_from_cache
110
+ end
100
111
 
101
- def load_dynamic_nodes
102
- raw_servers = fetch_server_list
112
+ def load_dynamic_nodes
113
+ raw_servers = fetch_server_list
103
114
 
104
- raw_servers.each do |raw_server|
105
- resources << ::Bcome::Node::Server::Dynamic.new_from_fog_instance(raw_server, self)
106
- end
115
+ raw_servers ||= []
107
116
 
108
- resources.rename_initial_duplicate if resources.should_rename_initial_duplicate?
117
+ raw_servers.each do |raw_server|
118
+ if raw_server.is_a?(Google::Apis::ComputeBeta::Instance)
119
+ resources << ::Bcome::Node::Server::Dynamic::Gcp.new_from_gcp_instance(raw_server, self)
120
+ elsif raw_server.is_a?(Fog::Compute::AWS::Server)
121
+ resources << ::Bcome::Node::Server::Dynamic::Ec2.new_from_fog_instance(raw_server, self)
122
+ else
123
+ raise Bcome::Exception::UnknownDynamicServerType, "Unknown dynamic server type #{raw_server.class}"
124
+ end
125
+ end
109
126
 
110
- end
127
+ resources.rename_initial_duplicate if resources.should_rename_initial_duplicate?
128
+ end
129
+
130
+ def fetch_server_list
131
+ return [] unless network_driver
111
132
 
112
- def fetch_server_list
113
- return [] unless network_driver
114
- network_driver.fetch_server_list(filters)
133
+ network_driver.fetch_server_list(filters)
134
+ end
135
+ end
115
136
  end
116
137
  end
117
138
  end