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::Resources
2
4
  class Base
3
5
  include Enumerable
@@ -23,7 +25,7 @@ module Bcome::Node::Resources
23
25
  end
24
26
 
25
27
  def should_rename_initial_duplicate?
26
- return false
28
+ false
27
29
  end
28
30
 
29
31
  def clear!
@@ -56,12 +58,14 @@ module Bcome::Node::Resources
56
58
  def disable(identifier)
57
59
  resource = for_identifier(identifier)
58
60
  raise Bcome::Exception::NoNodeNamedByIdentifier, identifier unless resource
61
+
59
62
  @disabled_resources << resource unless @disabled_resources.include?(resource)
60
63
  end
61
64
 
62
65
  def enable(identifier)
63
66
  resource = for_identifier(identifier)
64
67
  raise Bcome::Exception::NoNodeNamedByIdentifier, identifier unless resource
68
+
65
69
  @disabled_resources -= [resource]
66
70
  end
67
71
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bcome::Node::Resources
2
4
  class Inventory < Bcome::Node::Resources::Base
3
5
  def <<(node)
@@ -16,14 +18,14 @@ module Bcome::Node::Resources
16
18
  end
17
19
 
18
20
  def should_rename_initial_duplicate?
19
- return true
20
- end
21
+ true
22
+ end
21
23
 
22
24
  def rename_initial_duplicate
23
- duplicate_nodes.each do |node_identifier, count|
25
+ duplicate_nodes.each do |node_identifier, _count|
24
26
  node = for_identifier(node_identifier)
25
27
  node.identifier = "#{node.identifier}_1"
26
- end
28
+ end
27
29
  end
28
30
 
29
31
  def duplicate_nodes
@@ -32,7 +34,7 @@ module Bcome::Node::Resources
32
34
 
33
35
  def reset_duplicate_nodes!
34
36
  @duplicate_nodes = {}
35
- end
37
+ end
36
38
 
37
39
  def dynamic_nodes
38
40
  active.select(&:dynamic_server?)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bcome::Node::Resources
4
+ class Merged < Bcome::Node::Resources::Inventory
5
+ def initialize(config)
6
+ super
7
+ @inventory = config[:inventory]
8
+ run_select
9
+ end
10
+
11
+ def run_select
12
+ @inventory.contributing_inventories.each { |inventory| inventory.load_nodes unless inventory.nodes_loaded? }
13
+ @nodes = @inventory.contributing_inventories.collect { |inv| inv.resources.nodes }.flatten.collect(&:clone)
14
+
15
+ @nodes.map do |node|
16
+ node.add_list_attributes(origin: :origin_namespace)
17
+ end
18
+
19
+ @nodes
20
+ end
21
+
22
+ def update_nodes
23
+ new_set = []
24
+
25
+ @nodes.collect do |node|
26
+ new_node = node.dup_with_new_parent(@inventory)
27
+ if @inventory.override_server_identifier?
28
+ new_node.identifier =~ /#{@inventory.override_identifier}/
29
+ new_node.update_identifier(Regexp.last_match(1)) if Regexp.last_match(1)
30
+ end
31
+ # Register the new node with the registry
32
+ ::Bcome::Registry::Loader.instance.set_command_group_for_node(new_node)
33
+ new_set << new_node
34
+ end
35
+ @nodes = new_set
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bcome::Node::Resources
2
4
  class SubselectInventory < Bcome::Node::Resources::Inventory
3
5
  def initialize(config)
@@ -10,8 +12,9 @@ module Bcome::Node::Resources
10
12
  parent_inventory.load_nodes unless parent_inventory.nodes_loaded?
11
13
  new_set = parent_inventory.resources.nodes
12
14
 
13
- # Filter by ec2_filters
14
- new_set = filter_by_tags(new_set)
15
+ # ...by_tags: ec2
16
+ # ...by_label: gcp
17
+ new_set = filter_by_tags_or_label(new_set)
15
18
 
16
19
  @nodes = new_set
17
20
  end
@@ -34,7 +37,7 @@ module Bcome::Node::Resources
34
37
  @nodes = new_set
35
38
  end
36
39
 
37
- def filter_by_tags(nodes)
40
+ def filter_by_tags_or_label(nodes)
38
41
  tag_filters.each do |key, values|
39
42
  nodes = nodes.select { |node| node.has_tagged_value?(key, values) }
40
43
  end
@@ -50,7 +53,7 @@ module Bcome::Node::Resources
50
53
  end
51
54
 
52
55
  def tag_filters
53
- filters[:by_tag] ? filters[:by_tag] : {}
56
+ filters[:by_tag] || filters[:by_label] || {}
54
57
  end
55
58
 
56
59
  def parent_inventory
@@ -1,55 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'awesome_print'
4
+
1
5
  module Bcome::Node::Server
2
6
  class Base < Bcome::Node::Base
3
-
4
7
  attr_reader :origin_object_id
5
8
 
6
9
  def initialize(*params)
7
10
  super
8
11
  # Set the object_id - sub inventories dup servers into new collections. This allows us to spot duplicates when interacting with collections
9
12
  @origin_object_id = object_id
10
- @bootstrap = false
11
13
  end
12
14
 
13
- # override a server namespace's parameters. This enables features such as specific SSH parameters for a specific server, e.g. my use case was a
14
- # single debian box within an ubuntu network, where I needed to access the machine bootstrapping mode with the 'admin' rather 'ubuntu' username.
15
+ def host
16
+ raise 'Should be overidden'
17
+ end
18
+
19
+ # override a server namespace's parameters. This enables features such as specific SSH parameters for a specific server, e.g. my use case was a
20
+ # single debian box within an ubuntu network, where I needed to access the machine with the 'admin' rather 'ubuntu' username.
15
21
  def set_view_attributes
16
22
  super
17
23
  overridden_attributes = ::Bcome::Node::Factory.instance.machines_data_for_namespace(namespace.to_sym)
18
24
  overridden_attributes.each do |override_key, override_value|
19
- instance_variable_name = "@#{override_key}"
20
- instance_variable_set(instance_variable_name, override_value)
25
+ singleton_class.class_eval do
26
+ define_method(override_key) do
27
+ override_value
28
+ end
29
+ end
21
30
  end
22
31
  end
23
32
 
24
- def bootstrap?
25
- @bootstrap ? true : false
26
- end
27
-
28
- def toggle_bootstrap(set_to = (@bootstrap ? false : true))
29
- @bootstrap = set_to
30
- puts "Bootstrap #{bootstrap? ? "on" : "off" } for #{namespace}".informational
31
- end
32
-
33
33
  def dup_with_new_parent(new_parent)
34
- new_node = self.clone
34
+ new_node = clone
35
35
  new_node.update_parent(new_parent)
36
36
  new_node
37
- end
37
+ end
38
38
 
39
39
  def update_parent(new_parent)
40
40
  @parent = new_parent
41
41
  end
42
42
 
43
43
  def tags
44
- data_print_from_hash(cloud_tags.data, "Tags")
44
+ data_print_from_hash(cloud_tags.data, 'Tags')
45
45
  end
46
-
46
+
47
47
  def cloud_tags
48
48
  @generated_tags ||= do_generate_cloud_tags
49
49
  end
50
50
 
51
51
  def has_tagged_value?(key, values)
52
- matchers = { :key => key, :values => values }
52
+ matchers = { key: key, values: values }
53
53
  cloud_tags.has_key_and_value?(matchers)
54
54
  end
55
55
 
@@ -58,11 +58,11 @@ module Bcome::Node::Server
58
58
  end
59
59
 
60
60
  def do_generate_cloud_tags
61
- raise "Should be overidden"
61
+ raise 'Should be overidden'
62
62
  end
63
63
 
64
64
  def type
65
- "server"
65
+ 'server'
66
66
  end
67
67
 
68
68
  def machines
@@ -82,28 +82,34 @@ module Bcome::Node::Server
82
82
  end
83
83
 
84
84
  def enabled_menu_items
85
- (super + [:get, :ssh, :tags, :pseudo_tty]) - [:enable, :disable, :enable!, :disable!]
85
+ (super + %i[get ssh tags pseudo_tty tunnel]) - %i[enable disable enable! disable!]
86
86
  end
87
87
 
88
88
  def menu_items
89
89
  base_items = super.dup
90
90
  base_items[:tags] = {
91
- description: "print out remote EC2 tags"
91
+ description: 'print out remote EC2 tags'
92
92
  }
93
93
  base_items[:ssh] = {
94
- description: "initiate an ssh connection to this server",
94
+ description: 'initiate an ssh connection to this server'
95
95
  }
96
96
  base_items[:get] = {
97
- description: "Download a file or directory",
97
+ description: 'Download a file or directory',
98
98
  console_only: false,
99
- usage: "get \"/remote/path\", \"/local/path\"",
100
- terminal_usage: "get \"/remote/path\" \"/local/path\""
99
+ usage: 'get "/remote/path", "/local/path"',
100
+ terminal_usage: 'get "/remote/path" "/local/path"'
101
101
  }
102
102
  base_items[:pseudo_tty] = {
103
- description: "Invoke a pseudo-tty session",
103
+ description: 'Invoke a pseudo-tty session',
104
+ console_only: false,
105
+ usage: 'pseudo_tty "your command"',
106
+ terminal_usage: 'pseudo_tty "your command"'
107
+ }
108
+ base_items[:tunnel] = {
109
+ description: 'Create a Tunnel over SSH',
104
110
  console_only: false,
105
- usage: "pseudo_tty \"your command\"",
106
- terminal_usage: "pseudo_tty \"your command\""
111
+ usage: 'tunnel(local_port, destination_port)',
112
+ terminal_usage: 'tunnel local_port destination_port'
107
113
  }
108
114
 
109
115
  base_items
@@ -112,9 +118,16 @@ module Bcome::Node::Server
112
118
  def local_port_forward(start_port, end_port)
113
119
  ssh_driver.local_port_forward(start_port, end_port)
114
120
  end
121
+ alias tunnel local_port_forward
122
+
123
+ def reopen_ssh_connection
124
+ puts "Connecting\s".informational + identifier
125
+ close_ssh_connection
126
+ open_ssh_connection
127
+ end
115
128
 
116
- def open_ssh_connection
117
- ssh_driver.ssh_connection
129
+ def open_ssh_connection(ping = false)
130
+ ssh_driver.ssh_connection(ping)
118
131
  end
119
132
 
120
133
  def close_ssh_connection
@@ -128,7 +141,7 @@ module Bcome::Node::Server
128
141
  def has_no_ssh_connection?
129
142
  !has_ssh_connection?
130
143
  end
131
-
144
+
132
145
  def ssh
133
146
  ssh_driver.do_ssh
134
147
  end
@@ -142,17 +155,21 @@ module Bcome::Node::Server
142
155
 
143
156
  def execute_script(script_name)
144
157
  command_result = ::Bcome::Ssh::ScriptExec.execute(self, script_name)
145
- return command_result
158
+ command_result
146
159
  end
147
160
 
148
161
  def rsync(local_path, remote_path)
149
162
  ssh_driver.rsync(local_path, remote_path)
150
163
  end
151
-
152
- def put(local_path, remote_path)
164
+
165
+ def put(local_path, remote_path, *_params)
153
166
  ssh_driver.put(local_path, remote_path)
154
167
  end
155
168
 
169
+ def put_str(string, remote_path, *_params)
170
+ ssh_driver.put_str(string, remote_path)
171
+ end
172
+
156
173
  def get(remote_path, local_path)
157
174
  ssh_driver.get(remote_path, local_path)
158
175
  end
@@ -161,7 +178,7 @@ module Bcome::Node::Server
161
178
  puts "\n" + visual_hierarchy.hierarchy + "\n"
162
179
  puts pretty_description
163
180
  end
164
- alias :lsa :ls
181
+ alias lsa ls
165
182
 
166
183
  def ping
167
184
  ping_result = ssh_driver.ping
@@ -171,37 +188,37 @@ module Bcome::Node::Server
171
188
  def print_ping_result(ping_result = { success: true })
172
189
  result = {
173
190
  namespace => {
174
- "connection" => ping_result[:success] ? "success" : "failed",
175
- "ssh_config" => ssh_driver.pretty_config_details
191
+ 'connection' => ping_result[:success] ? 'success' : 'failed',
192
+ 'ssh_config' => ssh_driver.pretty_ssh_config
176
193
  }
177
194
  }
178
195
 
179
- unless ping_result[:success]
180
- result[namespace]["error"] = ping_result[:error].message
181
- end
182
-
196
+ result[namespace]['error'] = ping_result[:error].message if !ping_result[:success] && ping_result[:error]
183
197
  colour = ping_result[:success] ? :green : :red
184
198
 
185
- ap result, {
186
- :color => {
187
- hash: colour,
188
- symbol: colour,
189
- string: colour,
190
- keyword: colour,
191
- variable: colour,
192
- array: colour
193
- }
194
- }
199
+ ap(result, indent: -2, color: { hash: colour, symbol: colour, string: colour, keyword: colour, variable: colour, array: 'cyan' })
200
+ end
201
+
202
+ def add_list_attributes(attrs)
203
+ @attribs = list_attributes.merge(attrs)
204
+ end
205
+
206
+ def origin_namespace
207
+ parent.namespace
195
208
  end
196
209
 
197
210
  def list_attributes
211
+ @attribs ||= set_list_attributes
212
+ end
213
+
214
+ def set_list_attributes
198
215
  attribs = {
199
216
  "identifier": :identifier,
200
217
  "internal ip": :internal_ip_address,
201
218
  "public ip": :public_ip_address,
219
+ "host": :host
202
220
  }
203
221
 
204
- attribs.merge!("description": :description ) if has_description?
205
222
  attribs
206
223
  end
207
224
 
@@ -210,27 +227,37 @@ module Bcome::Node::Server
210
227
  d[:internal_ip_address] = internal_ip_address if internal_ip_address
211
228
  d[:public_ip_address] = public_ip_address if public_ip_address
212
229
  d[:description] = description if description
213
- d[:cloud_tags] = cloud_tags
230
+ d[:cloud_tags] = cloud_tags
214
231
  d
215
232
  end
216
233
 
217
234
  def do_run(raw_commands)
218
235
  raw_commands = raw_commands.is_a?(String) ? [raw_commands] : raw_commands
219
- commands = raw_commands.collect{|raw_command| ::Bcome::Ssh::Command.new({ :node => self, :raw => raw_command }) }
236
+ commands = raw_commands.collect { |raw_command| ::Bcome::Ssh::Command.new(node: self, raw: raw_command) }
220
237
  command_exec = ::Bcome::Ssh::CommandExec.new(commands)
221
238
  command_exec.execute!
222
- commands.each {|c| c.unset_node }
223
- return commands
239
+ commands.each(&:unset_node)
240
+ commands
224
241
  end
225
242
 
226
243
  def run(*raw_commands)
227
- raise ::Bcome::Exception::MethodInvocationRequiresParameter.new "Please specify commands when invoking 'run'" if raw_commands.empty?
228
- commands = do_run(raw_commands)
229
- commands
244
+ raise ::Bcome::Exception::MethodInvocationRequiresParameter, "Please specify commands when invoking 'run'" if raw_commands.empty?
245
+
246
+ do_run(raw_commands)
247
+ rescue IOError, Errno::EBADF
248
+ reopen_ssh_connection
249
+ do_run(raw_commands)
250
+ rescue Exception => e
251
+ if e.message == 'Unexpected spurious read wakeup'
252
+ reopen_ssh_connection
253
+ do_run(raw_commands)
254
+ else
255
+ raise e
256
+ end
230
257
  end
231
258
 
232
259
  def has_description?
233
- !@description.nil?
260
+ !description.nil?
234
261
  end
235
262
 
236
263
  def static_server?
@@ -240,6 +267,5 @@ module Bcome::Node::Server
240
267
  def dynamic_server?
241
268
  !static_server?
242
269
  end
243
-
244
- end
270
+ end
245
271
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bcome::Node::Server::Dynamic
4
+ class Base < Bcome::Node::Server::Base
5
+ class << self
6
+ def override_identifier(parent, identifier)
7
+ if parent.override_server_identifier?
8
+ identifier =~ /#{parent.override_identifier}/
9
+ identifier = Regexp.last_match(1) if Regexp.last_match(1)
10
+ end
11
+ identifier
12
+ end
13
+ end
14
+
15
+ def do_generate_cloud_tags
16
+ raise 'Should be overidden'
17
+ end
18
+
19
+ def cloud_server
20
+ raise 'Should be overidden'
21
+ end
22
+ end
23
+ end