bcome 1.3.6 → 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.
- checksums.yaml +4 -4
- data/bin/bcome +13 -8
- data/lib/bcome.rb +7 -11
- data/lib/objects/bcome/version.rb +19 -1
- data/lib/objects/bootup.rb +13 -5
- data/lib/objects/command/local.rb +2 -0
- data/lib/objects/config_factory.rb +3 -0
- data/lib/objects/driver/base.rb +36 -4
- data/lib/objects/driver/bucket.rb +6 -4
- data/lib/objects/driver/ec2.rb +35 -4
- data/lib/objects/driver/gcp.rb +124 -0
- data/lib/objects/driver/gcp/authentication/api_key.rb +6 -0
- data/lib/objects/driver/gcp/authentication/oauth.rb +101 -0
- data/lib/objects/driver/gcp/authentication/service_account.rb +7 -0
- data/lib/objects/driver/static.rb +2 -0
- data/lib/objects/encryptor.rb +26 -24
- data/lib/objects/exception/argument_error_invoking_method_from_command_line.rb +8 -4
- data/lib/objects/exception/base.rb +14 -10
- data/lib/objects/exception/can_only_subselect_on_inventory.rb +8 -4
- data/lib/objects/exception/cannot_authenticate_to_gcp.rb +11 -0
- data/lib/objects/exception/cannot_find_internal_registry_klass.rb +8 -4
- data/lib/objects/exception/cannot_find_inventory.rb +11 -0
- data/lib/objects/exception/cannot_find_subselection_parent.rb +8 -4
- data/lib/objects/exception/cant_find_key_in_cloud_tags.rb +8 -4
- data/lib/objects/exception/cant_find_key_in_metadata.rb +8 -4
- data/lib/objects/exception/cant_find_proxy_host_by_identifier.rb +8 -4
- data/lib/objects/exception/cant_find_proxy_host_by_namespace.rb +8 -4
- data/lib/objects/exception/could_not_initiate_ssh_connection.rb +8 -4
- data/lib/objects/exception/could_not_initiate_ssh_connection_through_backend_proxy.rb +8 -4
- data/lib/objects/exception/could_not_retrieve_terraform_output.rb +11 -0
- data/lib/objects/exception/deprecation_warning.rb +9 -7
- data/lib/objects/exception/duplicate_command_line_argument_key.rb +8 -4
- data/lib/objects/exception/ec2_driver_missing_provisioning_region.rb +8 -4
- data/lib/objects/exception/failed_to_run_local_command.rb +8 -4
- data/lib/objects/exception/generic.rb +11 -0
- data/lib/objects/exception/interactive_session_halt.rb +6 -2
- data/lib/objects/exception/invalid_bcome_breadcrumb.rb +8 -4
- data/lib/objects/exception/invalid_breadcrumb.rb +8 -4
- data/lib/objects/exception/invalid_context_command.rb +8 -4
- data/lib/objects/exception/invalid_gcp_authentication_scheme.rb +11 -0
- data/lib/objects/exception/invalid_identifier.rb +8 -4
- data/lib/objects/exception/invalid_machines_cache_config.rb +8 -4
- data/lib/objects/exception/invalid_matcher_query.rb +8 -4
- data/lib/objects/exception/invalid_meta_data_config.rb +8 -4
- data/lib/objects/exception/invalid_metadata_encryption_key.rb +8 -4
- data/lib/objects/exception/invalid_network_config.rb +8 -4
- data/lib/objects/exception/invalid_network_driver_type.rb +8 -4
- data/lib/objects/exception/invalid_port_forward_request.rb +11 -0
- data/lib/objects/exception/invalid_proxy_config.rb +8 -4
- data/lib/objects/exception/invalid_regexp_matcher_in_registry.rb +8 -4
- data/lib/objects/exception/invalid_registry_arguments_type.rb +8 -4
- data/lib/objects/exception/invalid_registry_command_name_length.rb +8 -4
- data/lib/objects/exception/invalid_registry_data_config.rb +8 -4
- data/lib/objects/exception/invalid_restriction_key_in_registry.rb +8 -4
- data/lib/objects/exception/invalid_ssh_config.rb +8 -4
- data/lib/objects/exception/inventories_cannot_have_subviews.rb +8 -4
- data/lib/objects/exception/malformed_command_line_arguments.rb +8 -4
- data/lib/objects/exception/method_invocation_requires_parameter.rb +8 -4
- data/lib/objects/exception/method_name_conflict_in_registry.rb +8 -4
- data/lib/objects/exception/missing_argument_for_registry_command.rb +8 -4
- data/lib/objects/exception/missing_description_on_view.rb +8 -4
- data/lib/objects/exception/missing_execute_on_registry_object.rb +8 -4
- data/lib/objects/exception/missing_gcp_authentication_scheme.rb +11 -0
- data/lib/objects/exception/missing_gcp_service_scopes.rb +11 -0
- data/lib/objects/exception/missing_identifier_on_view.rb +8 -4
- data/lib/objects/exception/missing_inventory_contributors.rb +11 -0
- data/lib/objects/exception/missing_ip_address_on_server.rb +8 -4
- data/lib/objects/exception/missing_network_config.rb +8 -4
- data/lib/objects/exception/missing_or_invalid_client_secrets.rb +11 -0
- data/lib/objects/exception/missing_params_for_rsync.rb +8 -4
- data/lib/objects/exception/missing_params_for_scp.rb +8 -4
- data/lib/objects/exception/missing_subselection_key.rb +8 -4
- data/lib/objects/exception/missing_type_on_view.rb +8 -4
- data/lib/objects/exception/no_node_found_for_breadcrumb.rb +8 -4
- data/lib/objects/exception/no_node_named_by_identifier.rb +8 -4
- data/lib/objects/exception/node_identifiers_must_be_unique.rb +8 -4
- data/lib/objects/exception/orchestration_script_does_not_exist.rb +8 -4
- data/lib/objects/exception/proxy_host_node_does_not_have_public_ip_address.rb +8 -4
- data/lib/objects/exception/unknown_dynamic_server_type.rb +11 -0
- data/lib/objects/exception/unknown_method_for_namespace.rb +8 -4
- data/lib/objects/interactive/session.rb +4 -1
- data/lib/objects/interactive/session_item/base.rb +2 -0
- data/lib/objects/interactive/session_item/capture_input.rb +2 -0
- data/lib/objects/interactive/session_item/transparent_ssh.rb +29 -23
- data/lib/objects/loading_bar/handler.rb +80 -0
- data/lib/objects/loading_bar/indicator/base.rb +64 -0
- data/lib/objects/loading_bar/indicator/basic.rb +34 -0
- data/lib/objects/loading_bar/indicator/progress.rb +26 -0
- data/lib/objects/loading_bar/pid_bucket.rb +27 -0
- data/lib/objects/modules/context.rb +13 -9
- data/lib/objects/modules/registry_management.rb +16 -10
- data/lib/objects/modules/ui_output.rb +10 -6
- data/lib/objects/modules/workspace_commands.rb +159 -155
- data/lib/objects/modules/workspace_menu.rb +129 -130
- data/lib/objects/node/attributes.rb +13 -21
- data/lib/objects/node/base.rb +113 -71
- data/lib/objects/node/cache_handler.rb +2 -0
- data/lib/objects/node/collection.rb +10 -9
- data/lib/objects/node/factory.rb +35 -28
- data/lib/objects/node/inventory/base.rb +100 -100
- data/lib/objects/node/inventory/defined.rb +110 -89
- data/lib/objects/node/inventory/merge.rb +43 -0
- data/lib/objects/node/inventory/subselect.rb +64 -46
- data/lib/objects/node/kube/base.rb +51 -0
- data/lib/objects/node/kube/container.rb +9 -0
- data/lib/objects/node/kube/estate.rb +19 -0
- data/lib/objects/node/kube/namespace.rb +24 -0
- data/lib/objects/node/kube/pod.rb +24 -0
- data/lib/objects/node/kube_wrap.rb +26 -0
- data/lib/objects/node/meta/base.rb +8 -1
- data/lib/objects/node/meta/cloud.rb +2 -0
- data/lib/objects/node/meta/local.rb +2 -0
- data/lib/objects/node/meta_data_factory.rb +3 -1
- data/lib/objects/node/meta_data_loader.rb +27 -28
- data/lib/objects/node/resources/base.rb +5 -1
- data/lib/objects/node/resources/inventory.rb +7 -5
- data/lib/objects/node/resources/merged.rb +38 -0
- data/lib/objects/node/resources/sub_inventory.rb +7 -4
- data/lib/objects/node/server/base.rb +88 -66
- data/lib/objects/node/server/dynamic/base.rb +23 -0
- data/lib/objects/node/server/{dynamic.rb → dynamic/ec2.rb} +14 -13
- data/lib/objects/node/server/dynamic/gcp.rb +47 -0
- data/lib/objects/node/server/static.rb +13 -2
- data/lib/objects/orchestration/base.rb +10 -0
- data/lib/objects/orchestration/interactive_terraform.rb +62 -27
- data/lib/objects/orchestrator.rb +22 -0
- data/lib/objects/parser/bread_crumb.rb +3 -1
- data/lib/objects/registry/arguments/base.rb +3 -1
- data/lib/objects/registry/arguments/command_line.rb +6 -1
- data/lib/objects/registry/arguments/console.rb +4 -1
- data/lib/objects/registry/command/base.rb +3 -0
- data/lib/objects/registry/command/external.rb +4 -2
- data/lib/objects/registry/command/group.rb +6 -3
- data/lib/objects/registry/command/internal.rb +3 -1
- data/lib/objects/registry/command/shortcut.rb +17 -9
- data/lib/objects/registry/command_list.rb +2 -0
- data/lib/objects/registry/loader.rb +10 -10
- data/lib/objects/ssh/bootstrap.rb +3 -1
- data/lib/objects/ssh/command.rb +10 -5
- data/lib/objects/ssh/command_exec.rb +13 -9
- data/lib/objects/ssh/connection_wrangler.rb +105 -0
- data/lib/objects/ssh/connector.rb +100 -0
- data/lib/objects/ssh/driver.rb +27 -230
- data/lib/objects/ssh/driver_concerns/command_strings.rb +17 -0
- data/lib/objects/ssh/driver_concerns/connection.rb +78 -0
- data/lib/objects/ssh/driver_concerns/functions.rb +89 -0
- data/lib/objects/ssh/driver_concerns/user.rb +32 -0
- data/lib/objects/ssh/{proxy_data.rb → proxy_hop.rb} +52 -7
- data/lib/objects/ssh/script_exec.rb +4 -1
- data/lib/objects/ssh/tunnel/local_port_forward.rb +5 -6
- data/lib/objects/ssh/tunnel_keeper.rb +21 -0
- data/lib/objects/ssh/window.rb +31 -0
- data/lib/objects/startup.rb +52 -0
- data/lib/objects/system/local.rb +3 -0
- data/lib/objects/terraform/output.rb +41 -0
- data/lib/objects/workspace.rb +3 -14
- data/patches/irb.rb +27 -3
- data/patches/string-encrypt.rb +20 -23
- data/patches/string.rb +5 -1
- data/patches/string_stylesheet.rb +2 -0
- metadata +95 -18
- data/lib/objects/progress_bar.rb +0 -30
- data/lib/objects/ssh/connection_handler.rb +0 -101
- data/lib/objects/terraform/parser.rb +0 -23
- data/lib/objects/terraform/state.rb +0 -40
@@ -1,17 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bcome::Node::Server::Dynamic
|
4
|
+
class Ec2 < Bcome::Node::Server::Dynamic::Base
|
3
5
|
class << self
|
4
|
-
def
|
5
|
-
|
6
|
+
def dynamic_server_type
|
7
|
+
:ec2
|
6
8
|
end
|
7
9
|
|
8
10
|
def new_from_fog_instance(fog_instance, parent)
|
9
11
|
identifier = fog_instance.tags['Name']
|
10
|
-
|
11
|
-
if parent.override_server_identifier?
|
12
|
-
identifier =~ /#{parent.override_identifier}/
|
13
|
-
identifier = Regexp.last_match(1) if Regexp.last_match(1)
|
14
|
-
end
|
12
|
+
identifier = override_identifier(parent, identifier)
|
15
13
|
|
16
14
|
params = {
|
17
15
|
identifier: identifier,
|
@@ -22,17 +20,20 @@ module Bcome::Node::Server
|
|
22
20
|
ec2_server: fog_instance
|
23
21
|
}
|
24
22
|
|
25
|
-
new(parent: parent,
|
26
|
-
views: params)
|
23
|
+
new(parent: parent, views: params)
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
27
|
+
def host
|
28
|
+
'EC2'
|
29
|
+
end
|
30
|
+
|
30
31
|
def do_generate_cloud_tags
|
31
|
-
raw_tags =
|
32
|
+
raw_tags = cloud_server ? cloud_server.tags.deep_symbolize_keys : {}
|
32
33
|
::Bcome::Node::Meta::Cloud.new(raw_tags)
|
33
34
|
end
|
34
35
|
|
35
|
-
def
|
36
|
+
def cloud_server
|
36
37
|
views[:ec2_server]
|
37
38
|
end
|
38
39
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bcome::Node::Server::Dynamic
|
4
|
+
class Gcp < Bcome::Node::Server::Dynamic::Base
|
5
|
+
class << self
|
6
|
+
def dynamic_server_type
|
7
|
+
:gcp
|
8
|
+
end
|
9
|
+
|
10
|
+
def new_from_gcp_instance(gcp_instance, parent)
|
11
|
+
identifier = gcp_instance.name
|
12
|
+
identifier = override_identifier(parent, identifier)
|
13
|
+
|
14
|
+
## For now we support only the first network interface
|
15
|
+
first_interface = gcp_instance.network_interfaces.first
|
16
|
+
network_ip = first_interface.network_ip
|
17
|
+
|
18
|
+
## And we get the first access config (terraform uses the same pattern for accessing GCP machines also)
|
19
|
+
first_access_config = first_interface.access_configs ? first_interface.access_configs.first : nil
|
20
|
+
nat_ip = first_access_config ? first_access_config.nat_ip : nil
|
21
|
+
|
22
|
+
params = {
|
23
|
+
identifier: identifier,
|
24
|
+
description: "GCP server - #{identifier}",
|
25
|
+
internal_ip_address: network_ip,
|
26
|
+
public_ip_address: nat_ip,
|
27
|
+
gcp_server: gcp_instance
|
28
|
+
}
|
29
|
+
|
30
|
+
new(parent: parent, views: params)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def host
|
35
|
+
'GCP'
|
36
|
+
end
|
37
|
+
|
38
|
+
def do_generate_cloud_tags
|
39
|
+
raw_labels = cloud_server.labels ? cloud_server.labels.deep_symbolize_keys : {}
|
40
|
+
::Bcome::Node::Meta::Cloud.new(raw_labels)
|
41
|
+
end
|
42
|
+
|
43
|
+
def cloud_server
|
44
|
+
views[:gcp_server]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Node::Server
|
2
4
|
class Static < Bcome::Node::Server::Base
|
3
|
-
def
|
4
|
-
'static
|
5
|
+
def host
|
6
|
+
'static'
|
5
7
|
end
|
6
8
|
|
7
9
|
def initialize(params)
|
@@ -10,12 +12,21 @@ module Bcome::Node::Server
|
|
10
12
|
@public_ip_address = config[:public_ip_address]
|
11
13
|
@internal_ip_address = config[:internal_ip_address]
|
12
14
|
@cloud_tags = config[:cloud_tags]
|
15
|
+
@description = config[:description]
|
13
16
|
verify_we_have_at_least_one_interface(config)
|
14
17
|
super
|
15
18
|
end
|
16
19
|
|
17
20
|
attr_reader :cloud_tags
|
18
21
|
|
22
|
+
attr_reader :public_ip_address
|
23
|
+
|
24
|
+
attr_reader :internal_ip_address
|
25
|
+
|
26
|
+
attr_reader :cloud_tags
|
27
|
+
|
28
|
+
attr_reader :description
|
29
|
+
|
19
30
|
def verify_we_have_at_least_one_interface(config)
|
20
31
|
raise Bcome::Exception::MissingIpaddressOnServer, config unless has_at_least_one_interface?
|
21
32
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Orchestration
|
2
4
|
class Base
|
3
5
|
def initialize(node, arguments)
|
@@ -7,7 +9,15 @@ module Bcome::Orchestration
|
|
7
9
|
|
8
10
|
def do_execute
|
9
11
|
raise Bcome::Exception::MissingExecuteOnRegistryObject, self.class.to_s unless respond_to?(:execute)
|
12
|
+
|
10
13
|
execute
|
11
14
|
end
|
15
|
+
|
16
|
+
def method_missing(method_sym, *_arguments)
|
17
|
+
## A thread error deep in the bowels of IRB is not playing well with orchestration missing methods within the orchestration namespace. Until this can be resolved,
|
18
|
+
## I've re-implemented it here.
|
19
|
+
|
20
|
+
raise NameError, "NameError (undefined local variable or method '#{method_sym}' for #{self.class}"
|
21
|
+
end
|
12
22
|
end
|
13
23
|
end
|
@@ -1,18 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Orchestration
|
2
|
-
class InteractiveTerraform < Bcome::Orchestration::Base
|
4
|
+
class InteractiveTerraform < Bcome::Orchestration::Base
|
5
|
+
## Prototype interactive terraform shell embedded within bcome.
|
6
|
+
|
7
|
+
# * Provides access to the metadata framework, so that data may be shared between Orchestrative processes and Terraform
|
8
|
+
# * Transparent authorization, by passing in cloud authorisation details from the bcome session
|
9
|
+
# * Passes in SSH credentials directly, which can be used to bootstrap machines.
|
3
10
|
|
4
|
-
QUIT =
|
5
|
-
COMMAND_PROMPT = "enter command or '#{QUIT}' to quit: " +
|
11
|
+
QUIT = '\\q'
|
12
|
+
COMMAND_PROMPT = "enter command or '#{QUIT}' to quit: " + 'terraform'.informational + "\s"
|
6
13
|
|
7
14
|
def execute
|
8
15
|
show_intro_text
|
9
16
|
wait_for_command_input
|
10
17
|
end
|
11
|
-
|
18
|
+
|
12
19
|
def show_intro_text
|
13
20
|
puts "\n"
|
14
21
|
puts "INTERACTIVE TERRAFORM\n".underline
|
15
|
-
puts "Namespace:\s" +
|
22
|
+
puts "Namespace:\s" + @node.namespace.to_s.informational
|
16
23
|
puts "Configuration Path:\s" + "#{path_to_env_config}/*".informational
|
17
24
|
puts "\nConfigured metadata:\s" + terraform_metadata.inspect.informational
|
18
25
|
|
@@ -22,6 +29,13 @@ module Bcome::Orchestration
|
|
22
29
|
# PROCESSING INTERACTIVE COMMANDS
|
23
30
|
#
|
24
31
|
def process_command(raw_command)
|
32
|
+
if raw_command =~ /destroy/
|
33
|
+
are_you_sure_message = "Are you SURE you want to 'destroy'? Make sure you know what will be destroyed before you continue. (y/n):".warning
|
34
|
+
response = wait_for_input(are_you_sure_message)
|
35
|
+
response = wait_for_input(are_you_sure_message) until %w[y n].include?(response)
|
36
|
+
return if response == 'n'
|
37
|
+
end
|
38
|
+
|
25
39
|
full_command = command(raw_command)
|
26
40
|
@node.execute_local(full_command)
|
27
41
|
wait_for_command_input
|
@@ -31,50 +45,71 @@ module Bcome::Orchestration
|
|
31
45
|
#
|
32
46
|
def wait_for_command_input
|
33
47
|
raw_command = wait_for_input
|
34
|
-
unless raw_command == QUIT
|
35
|
-
process_command(raw_command)
|
36
|
-
end
|
48
|
+
process_command(raw_command) unless raw_command == QUIT
|
37
49
|
end
|
38
|
-
|
50
|
+
|
39
51
|
def wait_for_input(message = COMMAND_PROMPT)
|
40
52
|
::Readline.readline("\n#{message}", true).squeeze('').to_s
|
41
|
-
end
|
53
|
+
end
|
42
54
|
|
43
55
|
# COMMAND PROCESSING
|
44
56
|
def terraform_metadata
|
45
|
-
@terraform_metadata ||= @node.metadata.fetch(
|
46
|
-
end
|
57
|
+
@terraform_metadata ||= @node.metadata.fetch('terraform', @node.metadata.fetch(:terraform, {}))
|
58
|
+
end
|
47
59
|
|
48
|
-
# Get the terraform variables for this stack, and merge in with our
|
60
|
+
# Get the terraform variables for this stack, and merge in with our networking & ssh credentials
|
49
61
|
def form_var_string
|
50
62
|
terraform_vars = terraform_metadata
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
|
64
|
+
terraform_vars.each do |key, value|
|
65
|
+
# Join arrays into a string (note we cannot handle nested arrays yet)
|
66
|
+
terraform_vars[key] = value.join(',') if value.is_a?(Array)
|
67
|
+
end
|
68
|
+
|
69
|
+
cleaned_data = terraform_vars.reject do |_k, v|
|
70
|
+
v.is_a?(Hash)
|
71
|
+
end # we can't yet handle nested terraform metadata on the command line so no hashes
|
72
|
+
|
73
|
+
all_vars = cleaned_data
|
74
|
+
|
75
|
+
if @node.network_driver.has_network_credentials?
|
76
|
+
network_credentials = @node.network_driver.network_credentials
|
77
|
+
all_vars = cleaned_data.merge(network_credentials)
|
78
|
+
end
|
79
|
+
|
80
|
+
all_vars[:ssh_user] = @node.ssh_driver.user
|
81
|
+
all_vars[:ssh_key_path] = @node.ssh_driver.ssh_keys.first
|
82
|
+
|
83
|
+
all_vars.collect { |key, value| "-var #{key}=\"#{value}\"" }.join("\s")
|
63
84
|
end
|
64
85
|
|
65
86
|
def var_string
|
66
87
|
@var_string ||= form_var_string
|
67
88
|
end
|
68
89
|
|
90
|
+
def backend_config_parameter_string
|
91
|
+
## Backend configs are loaded before Terraform Core which means that we cannot use variables directly in our backend config.
|
92
|
+
## This is a pain as we'll have authorised with GCP via the console, and so all sesssion have an access token readily available.
|
93
|
+
## This patch passes the access token directly to terraform as a parameter.
|
94
|
+
|
95
|
+
## GCP only for now. Support for AWS may come later as needed/requested.
|
96
|
+
return '' unless @node.network_driver.is_a?(::Bcome::Driver::Gcp)
|
97
|
+
|
98
|
+
"\s-backend-config \"access_token=#{@node.network_driver.network_credentials[:access_token]}\"\s"
|
99
|
+
end
|
100
|
+
|
69
101
|
# Retrieve the path to the terraform configurations for this stack
|
70
102
|
def path_to_env_config
|
71
|
-
@path_to_env_config ||= "terraform/environments/#{@node.namespace.gsub(
|
103
|
+
@path_to_env_config ||= "terraform/environments/#{@node.namespace.gsub(':', '_')}"
|
72
104
|
end
|
73
105
|
|
74
106
|
# Formulate a terraform command
|
75
107
|
def command(raw_command)
|
108
|
+
# if raw_command == "init"
|
109
|
+
# "cd #{path_to_env_config} ; terraform #{raw_command} #{backend_config_parameter_string}"
|
110
|
+
# else
|
76
111
|
"cd #{path_to_env_config} ; terraform #{raw_command} #{var_string}"
|
112
|
+
# end
|
77
113
|
end
|
78
|
-
|
79
114
|
end
|
80
115
|
end
|
data/lib/objects/orchestrator.rb
CHANGED
@@ -1,10 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ::Bcome::Orchestrator
|
2
4
|
include ::Singleton
|
3
5
|
|
4
6
|
attr_reader :context
|
5
7
|
|
6
8
|
def initialize
|
9
|
+
reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset!
|
7
13
|
@silence = false
|
14
|
+
@tail_command_output = false
|
15
|
+
@multi_node = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_multi_node?
|
19
|
+
@multi_node == true
|
8
20
|
end
|
9
21
|
|
10
22
|
def silence_command_output!
|
@@ -15,9 +27,19 @@ class ::Bcome::Orchestrator
|
|
15
27
|
@silence == true
|
16
28
|
end
|
17
29
|
|
30
|
+
def tail_all_command_output!(node)
|
31
|
+
@multi_node = node.machines.size > 1
|
32
|
+
@tail_command_output = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def tail_all_command_output?
|
36
|
+
@tail_command_output == true
|
37
|
+
end
|
38
|
+
|
18
39
|
def get(breadcrumb = nil)
|
19
40
|
context = ::Bcome::Bootup.traverse(breadcrumb)
|
20
41
|
raise Bcome::Exception::NoNodeFoundForBreadcrumb, breadcrumb unless context
|
42
|
+
|
21
43
|
context.load_nodes if context.inventory? && !context.nodes_loaded?
|
22
44
|
context
|
23
45
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Parser
|
2
4
|
class BreadCrumb
|
3
5
|
attr_reader :crumbs
|
@@ -25,7 +27,7 @@ module Bcome::Parser
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def validate!
|
28
|
-
#raise Bcome::Exception::InvalidBcomeBreadcrumb.new "- letters, numbers & underscores only" unless @raw_crumbs =~ /^([a-z0-9A-Z_]+)(:\s*[a-z0-9A-Z_]+)*:?$/i
|
30
|
+
# raise Bcome::Exception::InvalidBcomeBreadcrumb.new "- letters, numbers & underscores only" unless @raw_crumbs =~ /^([a-z0-9A-Z_]+)(:\s*[a-z0-9A-Z_]+)*:?$/i
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Arguments
|
2
4
|
class Base
|
3
5
|
attr_reader :arguments, :defaults, :processed_arguments, :merged_arguments
|
@@ -10,7 +12,7 @@ module Bcome::Registry::Arguments
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def initialize(_arguments, defaults)
|
13
|
-
@defaults = defaults
|
15
|
+
@defaults = defaults || {}
|
14
16
|
validate
|
15
17
|
end
|
16
18
|
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Arguments
|
2
4
|
class CommandLine < Base
|
3
5
|
def initialize(arguments, defaults)
|
4
|
-
@arguments = arguments
|
6
|
+
@arguments = arguments || []
|
5
7
|
@processed_arguments = {}
|
6
8
|
super
|
7
9
|
end
|
@@ -21,14 +23,17 @@ module Bcome::Registry::Arguments
|
|
21
23
|
@arguments.each do |argument|
|
22
24
|
argument =~ /^(.+)=(.+)$/
|
23
25
|
raise Bcome::Exception::MalformedCommandLineArguments, argument unless Regexp.last_match(1) || Regexp.last_match(2)
|
26
|
+
|
24
27
|
key = Regexp.last_match(1).to_sym; value = Regexp.last_match(2)
|
25
28
|
raise Bcome::Exception::DuplicateCommandLineArgumentKey, "'#{key}'" if @processed_arguments.key?(key)
|
29
|
+
|
26
30
|
@processed_arguments[key] = value
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def validate
|
31
35
|
raise Bcome::Exception::InvalidRegistryArgumentType, 'invalid argument format' unless @arguments.is_a?(Array)
|
36
|
+
|
32
37
|
super
|
33
38
|
end
|
34
39
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Arguments
|
2
4
|
class Console < Base
|
3
5
|
def initialize(arguments, defaults)
|
4
|
-
@arguments = arguments
|
6
|
+
@arguments = arguments || {}
|
5
7
|
super
|
6
8
|
end
|
7
9
|
|
@@ -9,6 +11,7 @@ module Bcome::Registry::Arguments
|
|
9
11
|
|
10
12
|
def validate
|
11
13
|
raise Bcome::Exception::InvalidRegistryArgumentType, 'invalid argument format' unless @arguments.is_a?(Hash)
|
14
|
+
|
12
15
|
super
|
13
16
|
end
|
14
17
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Command
|
2
4
|
class Base
|
3
5
|
class << self
|
4
6
|
def new_from_raw_command(data)
|
5
7
|
raise Bcome::Exception::InvalidContextCommand, "#{data.inspect} is missing key type" unless data[:type]
|
6
8
|
raise Bcome::Exception::InvalidContextCommand, "#{data.inspect} has invalid type '#{data[:type]}'" unless is_valid_type?(data[:type])
|
9
|
+
|
7
10
|
valid_types[data[:type].to_sym].new(data)
|
8
11
|
end
|
9
12
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Command
|
2
4
|
class External < Base
|
3
5
|
# In which the bcome context is passed to an external call
|
@@ -28,8 +30,8 @@ module Bcome::Registry::Command
|
|
28
30
|
error_message_suffix = "- missing '#{substitution}' from command '#{local_command}'"
|
29
31
|
raise Bcome::Exception::MissingArgumentForRegistryCommand, error_message_suffix
|
30
32
|
end
|
31
|
-
|
32
|
-
substitute_with = [TrueClass, FalseClass].include?(substitute_with.class) ? (substitute_with ?
|
33
|
+
|
34
|
+
substitute_with = [TrueClass, FalseClass].include?(substitute_with.class) ? (substitute_with ? 'true' : 'false') : substitute_with
|
33
35
|
substituted_command.gsub!("%#{substitution}%", substitute_with)
|
34
36
|
end
|
35
37
|
substituted_command
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bcome::Registry::Command
|
2
4
|
class Group
|
3
5
|
def initialize(node)
|
@@ -32,7 +34,8 @@ module Bcome::Registry::Command
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def item_spacing(item)
|
35
|
-
raise ::Bcome::Exception::InvalidRegistryCommandNameLength
|
37
|
+
raise ::Bcome::Exception::InvalidRegistryCommandNameLength, "command '#{item}' exceeds length limit of #{menu_item_spacing_length}" if item.length > menu_item_spacing_length
|
38
|
+
|
36
39
|
"\s" * (menu_item_spacing_length - item.length)
|
37
40
|
end
|
38
41
|
|
@@ -48,7 +51,7 @@ module Bcome::Registry::Command
|
|
48
51
|
::Bcome::System::Local.instance.in_console_session?
|
49
52
|
end
|
50
53
|
|
51
|
-
def pretty_print
|
54
|
+
def pretty_print
|
52
55
|
puts "\nRegistry commands".title + "\sfor #{@node.class} #{@node.keyed_namespace}".resource_value + "\n\n"
|
53
56
|
all_commands.sort.each do |group_name, commands|
|
54
57
|
puts tab_spacing + group_name.title + "\n\n"
|
@@ -63,7 +66,7 @@ module Bcome::Registry::Command
|
|
63
66
|
puts tab_spacing + ("\s" * menu_item_spacing_length) + 'usage: '.instructional + usage_string
|
64
67
|
|
65
68
|
if defaults.keys.any?
|
66
|
-
defaults_usage = in_console_session? ? "\s
|
69
|
+
defaults_usage = in_console_session? ? "\s#{defaults.collect { |key, _value| "\"#{key}=your-value\"" }.join(",\s")}" : "\s" + defaults.collect { |key, _value| "#{key}=your-value" }.join("\s")
|
67
70
|
puts tab_spacing + ("\s" * menu_item_spacing_length) + "defaults:\s".instructional + defaults.collect { |k, v| "#{k}=#{v}" }.join(', ')
|
68
71
|
puts tab_spacing + ("\s" * menu_item_spacing_length) + "override:\s".instructional + usage_string + defaults_usage
|
69
72
|
end
|