morpheus-cli 5.5.2.2 → 5.5.3.1
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/.gitignore +2 -1
- data/Dockerfile +1 -1
- data/README.md +57 -4
- data/Rakefile +9 -0
- data/bin/morpheus +4 -4
- data/lib/morpheus/api/api_client.rb +20 -2
- data/lib/morpheus/api/appliance_settings_interface.rb +15 -0
- data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
- data/lib/morpheus/api/archive_files_interface.rb +3 -3
- data/lib/morpheus/api/clients_interface.rb +2 -2
- data/lib/morpheus/api/clusters_interface.rb +8 -1
- data/lib/morpheus/api/containers_interface.rb +29 -16
- data/lib/morpheus/api/custom_instance_types_interface.rb +0 -2
- data/lib/morpheus/api/cypher_interface.rb +1 -2
- data/lib/morpheus/api/doc_interface.rb +8 -6
- data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
- data/lib/morpheus/api/guidance_settings_interface.rb +17 -0
- data/lib/morpheus/api/health_interface.rb +1 -1
- data/lib/morpheus/api/image_builder_interface.rb +3 -3
- data/lib/morpheus/api/instances_interface.rb +25 -0
- data/lib/morpheus/api/logs_interface.rb +2 -4
- data/lib/morpheus/api/monitoring_interface.rb +6 -6
- data/lib/morpheus/api/monitoring_settings_interface.rb +25 -0
- data/lib/morpheus/api/network_server_groups_interface.rb +7 -0
- data/lib/morpheus/api/packages_interface.rb +1 -1
- data/lib/morpheus/api/reports_interface.rb +1 -1
- data/lib/morpheus/api/servers_interface.rb +9 -1
- data/lib/morpheus/api/storage_providers_interface.rb +2 -2
- data/lib/morpheus/api/virtual_images_interface.rb +1 -1
- data/lib/morpheus/api.rb +2 -0
- data/lib/morpheus/benchmarking.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +79 -37
- data/lib/morpheus/cli/cli_registry.rb +19 -10
- data/lib/morpheus/cli/commands/access_token_command.rb +1 -1
- data/lib/morpheus/cli/commands/appliance_settings_command.rb +57 -2
- data/lib/morpheus/cli/commands/apps.rb +1 -1
- data/lib/morpheus/cli/commands/archives_command.rb +25 -33
- data/lib/morpheus/cli/commands/backup_settings_command.rb +1 -1
- data/lib/morpheus/cli/commands/blueprints_command.rb +10 -21
- data/lib/morpheus/cli/commands/boot_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/cat_command.rb +1 -1
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +18 -13
- data/lib/morpheus/cli/commands/clouds.rb +3 -3
- data/lib/morpheus/cli/commands/clusters.rb +154 -3
- data/lib/morpheus/cli/commands/containers_command.rb +398 -253
- data/lib/morpheus/cli/commands/cypher_command.rb +3 -0
- data/lib/morpheus/cli/commands/deployments.rb +1 -1
- data/lib/morpheus/cli/commands/deploys.rb +9 -9
- data/lib/morpheus/cli/commands/doc.rb +15 -16
- data/lib/morpheus/cli/commands/execution_request_command.rb +2 -2
- data/lib/morpheus/cli/commands/file_copy_request_command.rb +5 -5
- data/lib/morpheus/cli/commands/groups.rb +2 -2
- data/lib/morpheus/cli/commands/guidance_command.rb +2 -2
- data/lib/morpheus/cli/commands/guidance_settings.rb +148 -0
- data/lib/morpheus/cli/commands/health_command.rb +4 -4
- data/lib/morpheus/cli/commands/hosts.rb +43 -5
- data/lib/morpheus/cli/commands/image_builder_command.rb +1 -1
- data/lib/morpheus/cli/commands/instances.rb +419 -148
- data/lib/morpheus/cli/commands/integrations_command.rb +22 -20
- data/lib/morpheus/cli/commands/key_pairs.rb +2 -2
- data/lib/morpheus/cli/commands/library_container_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/library_container_templates_command.rb +2 -2
- data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -3
- data/lib/morpheus/cli/commands/library_spec_templates_command.rb +2 -2
- data/lib/morpheus/cli/commands/log_settings_command.rb +1 -1
- data/lib/morpheus/cli/commands/login.rb +1 -1
- data/lib/morpheus/cli/commands/man_command.rb +32 -18
- data/lib/morpheus/cli/commands/monitoring_settings.rb +228 -0
- data/lib/morpheus/cli/commands/network_server_groups_command.rb +222 -0
- data/lib/morpheus/cli/commands/packages_command.rb +11 -11
- data/lib/morpheus/cli/commands/plugins.rb +1 -1
- data/lib/morpheus/cli/commands/policies_command.rb +4 -4
- data/lib/morpheus/cli/commands/preseed_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/provisioning_settings_command.rb +1 -1
- data/lib/morpheus/cli/commands/remote.rb +1 -1
- data/lib/morpheus/cli/commands/reports_command.rb +13 -3
- data/lib/morpheus/cli/commands/security_groups.rb +1 -1
- data/lib/morpheus/cli/commands/shell.rb +40 -62
- data/lib/morpheus/cli/commands/snapshots.rb +3 -5
- data/lib/morpheus/cli/commands/source_command.rb +8 -16
- data/lib/morpheus/cli/commands/storage_providers_command.rb +7 -7
- data/lib/morpheus/cli/commands/tasks.rb +2 -2
- data/lib/morpheus/cli/commands/vdi_pools_command.rb +6 -6
- data/lib/morpheus/cli/commands/view.rb +5 -1
- data/lib/morpheus/cli/commands/whitelabel_settings_command.rb +5 -5
- data/lib/morpheus/cli/commands/whoami.rb +2 -2
- data/lib/morpheus/cli/credentials.rb +30 -8
- data/lib/morpheus/cli/dot_file.rb +8 -15
- data/lib/morpheus/cli/error_handler.rb +16 -0
- data/lib/morpheus/cli/errors.rb +8 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +17 -13
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +14 -12
- data/lib/morpheus/cli/mixins/rest_command.rb +23 -19
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +47 -24
- data/lib/morpheus/cli/option_parser.rb +5 -1
- data/lib/morpheus/cli/option_types.rb +59 -12
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli.rb +26 -16
- data/lib/morpheus/ext/rest_client.rb +3 -2
- data/lib/morpheus/ext/string.rb +6 -4
- data/lib/morpheus/formatters.rb +1 -1
- data/lib/morpheus/logging.rb +4 -4
- data/lib/morpheus/morpkg.rb +4 -4
- data/lib/morpheus/rest_client.rb +2 -2
- data/lib/morpheus/routes.rb +41 -9
- data/lib/morpheus/terminal.rb +65 -16
- data/lib/morpheus.rb +1 -1
- data/morpheus-cli.gemspec +1 -0
- data/test/api/containers_interface_test.rb +68 -0
- data/test/api/doc_interface_test.rb +35 -0
- data/test/api/instances_interface_test.rb +22 -0
- data/test/api/whoami_interface_test.rb +14 -0
- data/test/cli/access_token_test.rb +36 -0
- data/test/cli/auth_test.rb +82 -0
- data/test/cli/cli_test.rb +48 -0
- data/test/cli/containers_test.rb +92 -0
- data/test/cli/doc_test.rb +35 -0
- data/test/cli/help_test.rb +25 -0
- data/test/cli/instances_test.rb +36 -0
- data/test/cli/man_test.rb +14 -0
- data/test/cli/remote_test.rb +89 -0
- data/test/cli/roles_test.rb +34 -0
- data/test/cli/shell_test.rb +81 -0
- data/test/cli/version_test.rb +23 -0
- data/test/cli/view_test.rb +55 -0
- data/test/cli/whoami_test.rb +17 -0
- data/test/morpheus_test.rb +16 -0
- data/test/test_case.rb +338 -0
- data/test/test_config.rb +137 -0
- data/test/test_data_helper.rb +97 -0
- metadata +67 -3
|
@@ -14,12 +14,25 @@ module Morpheus
|
|
|
14
14
|
default_value = options[:default]
|
|
15
15
|
value_found = false
|
|
16
16
|
while value_found == false do
|
|
17
|
+
# if default_value.nil?
|
|
18
|
+
# print "#{message} (yes/no): "
|
|
19
|
+
# else
|
|
20
|
+
# print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
|
|
21
|
+
# end
|
|
22
|
+
# input = $stdin.gets.chomp!
|
|
23
|
+
|
|
24
|
+
# should use Readline.readline to probably
|
|
25
|
+
Readline.completion_append_character = ""
|
|
26
|
+
Readline.basic_word_break_characters = ''
|
|
27
|
+
Readline.completion_proc = nil
|
|
17
28
|
if default_value.nil?
|
|
18
|
-
|
|
29
|
+
confirm_prompt = "#{message} (yes/no): "
|
|
19
30
|
else
|
|
20
|
-
|
|
31
|
+
confirm_prompt = "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
|
|
21
32
|
end
|
|
22
|
-
input =
|
|
33
|
+
input = Readline.readline(confirm_prompt, false).to_s
|
|
34
|
+
input = input.chomp.strip
|
|
35
|
+
|
|
23
36
|
if input.empty? && !default_value.nil?
|
|
24
37
|
return !!default_value
|
|
25
38
|
end
|
|
@@ -86,6 +99,25 @@ module Morpheus
|
|
|
86
99
|
context_map = results
|
|
87
100
|
value = nil
|
|
88
101
|
value_found = false
|
|
102
|
+
|
|
103
|
+
# allow for mapping of domain to relevant type: domain.zone => router.zone
|
|
104
|
+
option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
|
|
105
|
+
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
|
106
|
+
help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
|
|
107
|
+
namespaces = field_key.split(".")
|
|
108
|
+
field_name = namespaces.pop
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# support --no-options --skip-option x,y,z --only-option x,y,z
|
|
112
|
+
if options[:no_options]
|
|
113
|
+
next
|
|
114
|
+
elsif options[:skip_options] && options[:skip_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
|
|
115
|
+
next
|
|
116
|
+
elsif options[:only_options] && !options[:only_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
|
|
117
|
+
next
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
89
121
|
field_group = (option_type['fieldGroup'] || 'default').to_s.sub(/options\Z/i, "").strip # avoid "ADVANCED OPTION OPTIONS"
|
|
90
122
|
|
|
91
123
|
if cur_field_group != field_group
|
|
@@ -105,12 +137,6 @@ module Morpheus
|
|
|
105
137
|
# end
|
|
106
138
|
# end
|
|
107
139
|
|
|
108
|
-
# allow for mapping of domain to relevant type: domain.zone => router.zone
|
|
109
|
-
option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
|
|
110
|
-
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
|
111
|
-
help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
|
|
112
|
-
namespaces = field_key.split(".")
|
|
113
|
-
field_name = namespaces.pop
|
|
114
140
|
|
|
115
141
|
# respect optionType.dependsOnCode
|
|
116
142
|
# i guess this switched to visibleOnCode, respect one or the other
|
|
@@ -612,6 +638,7 @@ module Morpheus
|
|
|
612
638
|
end
|
|
613
639
|
|
|
614
640
|
while !value_found do
|
|
641
|
+
#Readline.input = $stdin
|
|
615
642
|
Readline.completion_append_character = ""
|
|
616
643
|
Readline.basic_word_break_characters = ''
|
|
617
644
|
Readline.completion_proc = proc {|s|
|
|
@@ -703,6 +730,7 @@ module Morpheus
|
|
|
703
730
|
elsif no_prompt
|
|
704
731
|
input = default_value
|
|
705
732
|
else
|
|
733
|
+
#Readline.input = $stdin
|
|
706
734
|
Readline.completion_append_character = ""
|
|
707
735
|
Readline.basic_word_break_characters = ''
|
|
708
736
|
Readline.completion_proc = proc {|s|
|
|
@@ -970,8 +998,26 @@ module Morpheus
|
|
|
970
998
|
def self.password_prompt(option_type)
|
|
971
999
|
value_found = false
|
|
972
1000
|
while !value_found do
|
|
973
|
-
|
|
974
|
-
|
|
1001
|
+
# readline is still echoing secret with 'NUL:'' so just use $stdin on windows for now
|
|
1002
|
+
if Morpheus::Cli.windows?
|
|
1003
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
|
|
1004
|
+
input = $stdin.noecho(&:gets).chomp!
|
|
1005
|
+
else
|
|
1006
|
+
Readline.completion_append_character = ""
|
|
1007
|
+
Readline.basic_word_break_characters = ''
|
|
1008
|
+
Readline.completion_proc = nil
|
|
1009
|
+
# needs to work like $stdin.noecho
|
|
1010
|
+
Readline.pre_input_hook = lambda {
|
|
1011
|
+
Readline.output = File.open('/dev/null', 'w')
|
|
1012
|
+
#Readline.output = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
|
|
1013
|
+
#$stdout = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
|
|
1014
|
+
}
|
|
1015
|
+
password_prompt = "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
|
|
1016
|
+
input = Readline.readline(password_prompt, false).to_s.chomp
|
|
1017
|
+
Readline.pre_input_hook = nil
|
|
1018
|
+
Readline.output = Morpheus::Terminal.instance.stdout #my_terminal.stdout
|
|
1019
|
+
end
|
|
1020
|
+
|
|
975
1021
|
value = input
|
|
976
1022
|
print "\n"
|
|
977
1023
|
if input == '?'
|
|
@@ -991,6 +1037,7 @@ module Morpheus
|
|
|
991
1037
|
value = nil
|
|
992
1038
|
while !value_found do
|
|
993
1039
|
#print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
|
1040
|
+
#Readline.input = $stdin
|
|
994
1041
|
Readline.completion_append_character = ""
|
|
995
1042
|
Readline.basic_word_break_characters = ''
|
|
996
1043
|
Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
|
|
@@ -1005,7 +1052,7 @@ module Morpheus
|
|
|
1005
1052
|
value_found = true
|
|
1006
1053
|
elsif value
|
|
1007
1054
|
filename = File.expand_path(value)
|
|
1008
|
-
if !File.
|
|
1055
|
+
if !File.exist?(filename)
|
|
1009
1056
|
# print_red_alert "File not found: #{filename}"
|
|
1010
1057
|
# exit 1
|
|
1011
1058
|
print Term::ANSIColor.red," File not found: #{filename}",Term::ANSIColor.reset, "\n"
|
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/cli.rb
CHANGED
|
@@ -36,38 +36,48 @@ module Morpheus
|
|
|
36
36
|
begin
|
|
37
37
|
require 'rbconfig'
|
|
38
38
|
@@is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
|
39
|
-
rescue
|
|
39
|
+
rescue
|
|
40
40
|
# $stderr.puts "unable to determine if this is a Windows machine."
|
|
41
41
|
end
|
|
42
42
|
return @@is_windows
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
# load
|
|
45
|
+
# load! does the initial loading of all the CLI utilities and commands
|
|
46
46
|
def self.load!()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
require 'morpheus/api
|
|
50
|
-
|
|
51
|
-
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each {|file| load file }
|
|
52
|
-
|
|
53
|
-
# load mixins
|
|
54
|
-
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
|
|
47
|
+
|
|
48
|
+
# api interfaces
|
|
49
|
+
require 'morpheus/api'
|
|
50
|
+
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| require file }
|
|
55
51
|
|
|
56
|
-
#
|
|
52
|
+
# utilites
|
|
53
|
+
# Dir[File.dirname(__FILE__) + "/cli/*.rb"].each { |file| require file }
|
|
57
54
|
require 'morpheus/cli/cli_registry.rb'
|
|
58
55
|
require 'morpheus/cli/expression_parser.rb'
|
|
59
56
|
require 'morpheus/cli/dot_file.rb'
|
|
60
57
|
require 'morpheus/cli/errors'
|
|
58
|
+
require 'morpheus/cli/cli_command.rb'
|
|
59
|
+
require 'morpheus/cli/option_types.rb'
|
|
60
|
+
require 'morpheus/cli/credentials.rb'
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
load 'morpheus/cli/credentials.rb'
|
|
62
|
+
# mixins
|
|
63
|
+
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| require file }
|
|
65
64
|
|
|
66
|
-
#
|
|
67
|
-
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file|
|
|
65
|
+
# commands
|
|
66
|
+
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| require file }
|
|
68
67
|
|
|
69
68
|
end
|
|
70
69
|
|
|
70
|
+
# reload! can be used for live reloading changes while developing
|
|
71
|
+
def self.reload!()
|
|
72
|
+
# api interfaces
|
|
73
|
+
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| load file }
|
|
74
|
+
# mixins
|
|
75
|
+
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
|
|
76
|
+
# commands
|
|
77
|
+
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| load file }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# require all CLI modules now (on require)
|
|
71
81
|
load!
|
|
72
82
|
|
|
73
83
|
end
|
|
@@ -5,6 +5,7 @@ require 'rest-client'
|
|
|
5
5
|
module RestClient
|
|
6
6
|
class Request
|
|
7
7
|
|
|
8
|
+
alias_method :original_log_request, :log_request
|
|
8
9
|
def log_request
|
|
9
10
|
begin
|
|
10
11
|
return unless RestClient.log
|
|
@@ -14,10 +15,10 @@ module RestClient
|
|
|
14
15
|
out << payload.short_inspect if payload
|
|
15
16
|
out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
|
|
16
17
|
RestClient.log << out.join(', ') + "\n"
|
|
17
|
-
rescue
|
|
18
|
+
rescue
|
|
18
19
|
# something went wrong, wrong gem version maybe...above is from rest-client 2.0.2
|
|
19
20
|
# do it the old way
|
|
20
|
-
|
|
21
|
+
original_log_request()
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
=begin
|
data/lib/morpheus/ext/string.rb
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
class String
|
|
2
2
|
|
|
3
3
|
def pluralize
|
|
4
|
+
# hacky version of this until we want to depend on ActiveSupport
|
|
4
5
|
value = self.dup
|
|
5
6
|
if value == ""
|
|
6
7
|
value
|
|
7
8
|
elsif value[-1].chr == "y"
|
|
8
9
|
value[0..-2] + "ies"
|
|
9
10
|
elsif value[-1].chr == "s"
|
|
10
|
-
if value[-2..-1] == "
|
|
11
|
-
value
|
|
12
|
-
else
|
|
11
|
+
if value[-2..-1] == "ss"
|
|
13
12
|
value + "es"
|
|
13
|
+
else
|
|
14
|
+
value
|
|
14
15
|
end
|
|
15
16
|
else
|
|
16
17
|
value + "s"
|
|
@@ -18,13 +19,14 @@ class String
|
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def singularize
|
|
22
|
+
# hacky version of this until we want to depend on ActiveSupport
|
|
21
23
|
value = self.dup
|
|
22
24
|
if value == ""
|
|
23
25
|
value
|
|
24
26
|
elsif value.size > 3 && value[-3..-1] == "ies"
|
|
25
27
|
value[0..-4] + "y"
|
|
26
28
|
elsif value.size > 2 && value[-3..-1] == "ses"
|
|
27
|
-
value[0..-
|
|
29
|
+
value[0..-2]
|
|
28
30
|
elsif value[-1] == "s"
|
|
29
31
|
value[0..-2]
|
|
30
32
|
else
|
data/lib/morpheus/formatters.rb
CHANGED
data/lib/morpheus/logging.rb
CHANGED
|
@@ -85,18 +85,18 @@ module Morpheus::Logging
|
|
|
85
85
|
msg = msg.clone
|
|
86
86
|
# looks for RestClient format (hash.inspect) and request/curl output name: value
|
|
87
87
|
msg.gsub!(/Authorization\"\s?\=\>\s?\"Bearer [^"]+/i, 'Authorization"=>"Bearer ************')
|
|
88
|
-
msg.gsub!(/Authorization\:\s?Bearer [^"'
|
|
88
|
+
msg.gsub!(/Authorization\:\s?Bearer [^"']+/i, 'Authorization: Bearer ************')
|
|
89
89
|
# msg.gsub!(/#{AUTHORIZATION_HEADER}\"\s?\=\>\s?\"Bearer [^"]+/, "#{AUTHORIZATION_HEADER}"=>"Bearer ************")
|
|
90
|
-
# msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"'
|
|
90
|
+
# msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"']+/, "#{AUTHORIZATION_HEADER}: Bearer ************")
|
|
91
91
|
SECRET_TOKEN_HEADERS.each do |header|
|
|
92
92
|
msg.gsub!(/#{header}\"\s?\=\>\s?\"[^"]+/, "#{header}\"=>\"************")
|
|
93
|
-
msg.gsub!(/#{header}\:\s?[^"'
|
|
93
|
+
msg.gsub!(/#{header}\:\s?[^"']+/, "#{header}: ************")
|
|
94
94
|
end
|
|
95
95
|
msg.gsub!(/password\"\: "[^"]+/, 'password": "************') # json properties ending with password
|
|
96
96
|
msg.gsub!(/Password\"\: "[^"]+/, 'Password": "************') # json properties ending with Password
|
|
97
97
|
msg.gsub!(/password\"\s?\=\>\s?\"[^"]+/i, 'password"=>"************')
|
|
98
98
|
msg.gsub!(/password\=\"[^"]+/i, 'password="************')
|
|
99
|
-
msg.gsub!(/password\=[^"'
|
|
99
|
+
msg.gsub!(/password\=[^"'&]+/i, 'password=************') # buggy, wont work with ampersand or quotes in passwords! heh
|
|
100
100
|
msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation="************')
|
|
101
101
|
msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation=************')
|
|
102
102
|
end
|
data/lib/morpheus/morpkg.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Morpheus
|
|
|
9
9
|
def self.parse_package_manifest(source_directory)
|
|
10
10
|
source_directory = File.expand_path(source_directory)
|
|
11
11
|
manifest_filename = File.join(source_directory, "package-manifest.json")
|
|
12
|
-
if !File.
|
|
12
|
+
if !File.exist?(manifest_filename)
|
|
13
13
|
raise "Package manifest file not found: #{manifest_filename}"
|
|
14
14
|
end
|
|
15
15
|
manifest = JSON.parse(File.read(manifest_filename))
|
|
@@ -46,10 +46,10 @@ module Morpheus
|
|
|
46
46
|
elsif File.directory?(outfile)
|
|
47
47
|
outfile = File.join(outfile, "#{code}-#{version}.morpkg")
|
|
48
48
|
end
|
|
49
|
-
if Dir.
|
|
49
|
+
if Dir.exist?(outfile)
|
|
50
50
|
raise "Invalid package target. #{outfile} is the name of an existing directory."
|
|
51
51
|
end
|
|
52
|
-
if File.
|
|
52
|
+
if File.exist?(outfile)
|
|
53
53
|
if do_overwrite
|
|
54
54
|
# don't delete, just overwrite.
|
|
55
55
|
# File.delete(outfile)
|
|
@@ -58,7 +58,7 @@ module Morpheus
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
# build directories if needed
|
|
61
|
-
if !Dir.
|
|
61
|
+
if !Dir.exist?(File.dirname(outfile))
|
|
62
62
|
Dir.mkdir(File.dirname(outfile))
|
|
63
63
|
end
|
|
64
64
|
|
data/lib/morpheus/rest_client.rb
CHANGED
|
@@ -8,11 +8,11 @@ module Morpheus
|
|
|
8
8
|
class << self
|
|
9
9
|
|
|
10
10
|
def user_agent
|
|
11
|
-
if
|
|
11
|
+
if !defined?(@user_agent) || @user_agent.nil?
|
|
12
12
|
begin
|
|
13
13
|
@user_agent = "morpheus-cli #{Morpheus::Cli::VERSION}"
|
|
14
14
|
@user_agent = "#{@user_agent} (#{::RestClient::Platform.architecture}) #{::RestClient::Platform.ruby_agent_version}"
|
|
15
|
-
rescue
|
|
15
|
+
rescue
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
return @user_agent
|
data/lib/morpheus/routes.rb
CHANGED
|
@@ -123,8 +123,8 @@ module Morpheus::Routes
|
|
|
123
123
|
admin: {
|
|
124
124
|
accounts: {}, # Tenants
|
|
125
125
|
:'service-plans' => [
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"#!prices",
|
|
127
|
+
"#!pricesets"
|
|
128
128
|
],
|
|
129
129
|
roles: {},
|
|
130
130
|
users: {},
|
|
@@ -132,7 +132,19 @@ module Morpheus::Routes
|
|
|
132
132
|
integrations: {},
|
|
133
133
|
policies: {},
|
|
134
134
|
health: ["logs"],
|
|
135
|
-
settings:
|
|
135
|
+
settings: [
|
|
136
|
+
"#!appliance",
|
|
137
|
+
"#!whitelabel",
|
|
138
|
+
"provisioning",
|
|
139
|
+
"monitoring",
|
|
140
|
+
"backups",
|
|
141
|
+
"logs",
|
|
142
|
+
"#!guidance",
|
|
143
|
+
"environments",
|
|
144
|
+
"software-licenses",
|
|
145
|
+
"#!license",
|
|
146
|
+
"#!utilities"
|
|
147
|
+
],
|
|
136
148
|
},
|
|
137
149
|
:'user-settings' => {}, # User Settings (Profile)
|
|
138
150
|
} unless defined?(SITE_MAP)
|
|
@@ -161,14 +173,34 @@ module Morpheus::Routes
|
|
|
161
173
|
# find the one with smallest match index
|
|
162
174
|
|
|
163
175
|
# map well known aliases
|
|
164
|
-
case(path.
|
|
165
|
-
when "
|
|
176
|
+
case(path.dasherize.pluralize)
|
|
177
|
+
when "servers","hosts","vms","virtual-machines"
|
|
166
178
|
# actually should be "/infrastructure/inventory" unless id is passed, show route uses /servers though
|
|
167
179
|
path = "/infrastructure/servers"
|
|
168
|
-
when "
|
|
180
|
+
when "computes", "inventories"
|
|
169
181
|
path = "/infrastructure/inventory"
|
|
170
|
-
when "
|
|
182
|
+
when "tenants"
|
|
171
183
|
path = "/admin/accounts"
|
|
184
|
+
when "appliance-settings"
|
|
185
|
+
path = "/admin/settings/#!appliance"
|
|
186
|
+
when "whitelabel-settings"
|
|
187
|
+
path = "/admin/settings/#!whitelabel"
|
|
188
|
+
when "provisioning-settings"
|
|
189
|
+
path = "/admin/settings/#!provisioning"
|
|
190
|
+
when "monitoring-settings","monitor-settings"
|
|
191
|
+
path = "/admin/settings/monitoring"
|
|
192
|
+
when "backup-settings"
|
|
193
|
+
path = "/admin/settings/backups"
|
|
194
|
+
when "log-settings"
|
|
195
|
+
path = "/admin/settings/logs"
|
|
196
|
+
when "guidance-settings"
|
|
197
|
+
path = "/admin/settings/#!guidance"
|
|
198
|
+
when "environments"
|
|
199
|
+
path = "/admin/settings/environments"
|
|
200
|
+
when "software-licenses"
|
|
201
|
+
path = "/admin/settings/software-licenses"
|
|
202
|
+
when "license"
|
|
203
|
+
path = "/admin/settings/#!license"
|
|
172
204
|
end
|
|
173
205
|
# dasherize path and attempt to match the plural first
|
|
174
206
|
plural_path = path.pluralize
|
|
@@ -178,7 +210,7 @@ module Morpheus::Routes
|
|
|
178
210
|
end
|
|
179
211
|
|
|
180
212
|
best_route = nil
|
|
181
|
-
best_index = nil
|
|
213
|
+
#best_index = nil
|
|
182
214
|
best_prefix_words = nil
|
|
183
215
|
paths.each do |p|
|
|
184
216
|
if best_route.nil?
|
|
@@ -190,7 +222,7 @@ module Morpheus::Routes
|
|
|
190
222
|
#if best_index.nil? || match_index < best_index
|
|
191
223
|
if best_prefix_words.nil? || prefix_words.size < best_prefix_words.size
|
|
192
224
|
best_route = it
|
|
193
|
-
best_index = match_index
|
|
225
|
+
#best_index = match_index
|
|
194
226
|
best_prefix_words = prefix_words
|
|
195
227
|
end
|
|
196
228
|
end
|
data/lib/morpheus/terminal.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'morpheus/cli'
|
|
1
|
+
#require 'morpheus/cli' #todo: remove circular require...
|
|
2
2
|
require 'morpheus/benchmarking'
|
|
3
3
|
require 'morpheus/logging'
|
|
4
4
|
require 'morpheus/rest_client'
|
|
@@ -7,6 +7,7 @@ require 'morpheus/cli/dot_file'
|
|
|
7
7
|
require 'morpheus/cli/error_handler'
|
|
8
8
|
require 'morpheus/cli/expression_parser'
|
|
9
9
|
require 'morpheus/cli/option_parser'
|
|
10
|
+
require 'morpheus/cli/version'
|
|
10
11
|
require 'term/ansicolor'
|
|
11
12
|
|
|
12
13
|
module Morpheus
|
|
@@ -41,7 +42,13 @@ module Morpheus
|
|
|
41
42
|
include Morpheus::Benchmarking::HasBenchmarking
|
|
42
43
|
# todo: this can be combined with Cli::Shell
|
|
43
44
|
|
|
44
|
-
class Blackhole # <
|
|
45
|
+
class Blackhole # < File
|
|
46
|
+
|
|
47
|
+
def initialize(*args)
|
|
48
|
+
# we shouldn't actually need a File tho.. but Readline wants one
|
|
49
|
+
# File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
|
|
50
|
+
end
|
|
51
|
+
|
|
45
52
|
def accrete_data(*mgs)
|
|
46
53
|
# Singularity.push(*msgs)
|
|
47
54
|
return nil
|
|
@@ -61,7 +68,7 @@ module Morpheus
|
|
|
61
68
|
end
|
|
62
69
|
|
|
63
70
|
def self.prompt
|
|
64
|
-
if @prompt.nil?
|
|
71
|
+
if !defined?(@prompt) || @prompt.nil?
|
|
65
72
|
if ENV['MORPHEUS_PS1']
|
|
66
73
|
@prompt = ENV['MORPHEUS_PS1'].dup
|
|
67
74
|
else
|
|
@@ -91,7 +98,7 @@ module Morpheus
|
|
|
91
98
|
# the global Morpheus::Terminal instance
|
|
92
99
|
# This should go away, but it needed for now...
|
|
93
100
|
def self.instance
|
|
94
|
-
@morphterm
|
|
101
|
+
@morphterm ||= self.new({})
|
|
95
102
|
end
|
|
96
103
|
|
|
97
104
|
# hack alert! This should go away, but is needed for now...
|
|
@@ -112,13 +119,13 @@ module Morpheus
|
|
|
112
119
|
# @param stderr [IO] Default is STDERR
|
|
113
120
|
# @param [IO] stderr
|
|
114
121
|
# @stderr = stderr
|
|
115
|
-
def initialize(stdin
|
|
122
|
+
def initialize(stdin=$stdin,stdout=$stdout, stderr=$stderr, homedir=nil)
|
|
116
123
|
attrs = {}
|
|
117
124
|
if stdin.is_a?(Hash)
|
|
118
125
|
attrs = stdin.clone()
|
|
119
|
-
stdin = attrs[:stdin] ||
|
|
120
|
-
stdout = attrs[:stdout] ||
|
|
121
|
-
stderr = attrs[:stderr] ||
|
|
126
|
+
stdin = attrs[:stdin] || $stdin
|
|
127
|
+
stdout = attrs[:stdout] || $stdout
|
|
128
|
+
stderr = attrs[:stderr] || $stderr
|
|
122
129
|
homedir = attrs[:homedir] || attrs[:home] || attrs[:home_directory]
|
|
123
130
|
end
|
|
124
131
|
# establish IO
|
|
@@ -132,12 +139,12 @@ module Morpheus
|
|
|
132
139
|
set_home_directory(use_homedir)
|
|
133
140
|
|
|
134
141
|
# use colors by default
|
|
135
|
-
set_coloring(
|
|
142
|
+
set_coloring($stdout.isatty) #rescue nil
|
|
136
143
|
# Term::ANSIColor::coloring = STDOUT.isatty
|
|
137
144
|
# @coloring = Term::ANSIColor::coloring?
|
|
138
145
|
|
|
139
146
|
# startup script
|
|
140
|
-
if File.
|
|
147
|
+
if File.exist? Morpheus::Cli::DotFile.morpheus_profile_filename
|
|
141
148
|
@profile_dot_file = Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheus_profile_filename)
|
|
142
149
|
else
|
|
143
150
|
@profile_dot_file = nil
|
|
@@ -197,13 +204,52 @@ module Morpheus
|
|
|
197
204
|
@stderr
|
|
198
205
|
end
|
|
199
206
|
|
|
207
|
+
def with_pipes(opts, &block)
|
|
208
|
+
originals = {} #{stdout: stdout, stderr: stderr, stdin: stdin}
|
|
209
|
+
if opts[:stdout]
|
|
210
|
+
originals[:stdout] = stdout
|
|
211
|
+
set_stdout(opts[:stdout])
|
|
212
|
+
end
|
|
213
|
+
if opts[:stderr]
|
|
214
|
+
originals[:stderr] = stderr
|
|
215
|
+
set_stderr(opts[:stderr])
|
|
216
|
+
end
|
|
217
|
+
if opts[:stdin]
|
|
218
|
+
originals[:stdin] = stdin
|
|
219
|
+
set_stdin(opts[:stdin])
|
|
220
|
+
end
|
|
221
|
+
begin
|
|
222
|
+
yield
|
|
223
|
+
ensure
|
|
224
|
+
set_stdout(originals[:stdout]) if originals[:stdout]
|
|
225
|
+
set_stderr(originals[:stderr]) if originals[:stderr]
|
|
226
|
+
set_stdin(originals[:stdin]) if originals[:stdin]
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def with_stdout(io, &block)
|
|
231
|
+
with_pipes(stdout:io, &block)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def with_stderr(io, &block)
|
|
235
|
+
with_pipes(stderr:io, &block)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def with_stdout_and_stderr(io, &block)
|
|
239
|
+
with_pipes(stdout:io, stderr:io, &block)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def with_stdin(io, &block)
|
|
243
|
+
with_pipes(stdin:io, &block)
|
|
244
|
+
end
|
|
245
|
+
|
|
200
246
|
def home_directory=(homedir)
|
|
201
247
|
set_home_directory(homedir)
|
|
202
248
|
end
|
|
203
249
|
|
|
204
250
|
def set_home_directory(homedir)
|
|
205
251
|
full_homedir = File.expand_path(homedir)
|
|
206
|
-
# if !Dir.
|
|
252
|
+
# if !Dir.exist?(full_homedir)
|
|
207
253
|
# print_red_alert "Directory not found: #{full_homedir}"
|
|
208
254
|
# exit 1
|
|
209
255
|
# end
|
|
@@ -293,7 +339,7 @@ module Morpheus
|
|
|
293
339
|
# out << "Options:\n"
|
|
294
340
|
out << optparse.to_s
|
|
295
341
|
out << "\n"
|
|
296
|
-
out << "For more information, see https://
|
|
342
|
+
out << "For more information, see https://clidocs.morpheusdata.com"
|
|
297
343
|
out << "\n"
|
|
298
344
|
out
|
|
299
345
|
end
|
|
@@ -330,6 +376,10 @@ module Morpheus
|
|
|
330
376
|
# $stdin.gets(*args)
|
|
331
377
|
# end
|
|
332
378
|
|
|
379
|
+
def readline(*args)
|
|
380
|
+
# todo: one prompt to rule them all
|
|
381
|
+
end
|
|
382
|
+
|
|
333
383
|
# protected
|
|
334
384
|
|
|
335
385
|
def execute(input)
|
|
@@ -397,7 +447,7 @@ module Morpheus
|
|
|
397
447
|
set_home_directory(@use_home_directory)
|
|
398
448
|
# re-initialize some variables
|
|
399
449
|
# startup script
|
|
400
|
-
if File.
|
|
450
|
+
if File.exist? Morpheus::Cli::DotFile.morpheus_profile_filename
|
|
401
451
|
@profile_dot_file = Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheus_profile_filename)
|
|
402
452
|
else
|
|
403
453
|
@profile_dot_file = nil
|
|
@@ -414,7 +464,7 @@ module Morpheus
|
|
|
414
464
|
|
|
415
465
|
|
|
416
466
|
if @profile_dot_file && !@profile_dot_file_has_run
|
|
417
|
-
if !noprofile && File.
|
|
467
|
+
if !noprofile && File.exist?(@profile_dot_file.filename)
|
|
418
468
|
execute_profile_script()
|
|
419
469
|
end
|
|
420
470
|
end
|
|
@@ -466,14 +516,13 @@ module Morpheus
|
|
|
466
516
|
# return 127, nil
|
|
467
517
|
# end
|
|
468
518
|
|
|
469
|
-
if @benchmarking || args.include?('-B') || args.include?('--benchmark')
|
|
519
|
+
if (defined?(@benchmarking) && @benchmarking) || args.include?('-B') || args.include?('--benchmark')
|
|
470
520
|
benchmark_name = "morpheus #{formatted_cmd}"
|
|
471
521
|
benchmark_name.sub!(' -B', '')
|
|
472
522
|
benchmark_name.sub!(' --benchmark', '')
|
|
473
523
|
#benchmark_name << " -B"
|
|
474
524
|
start_benchmark(benchmark_name)
|
|
475
525
|
end
|
|
476
|
-
|
|
477
526
|
# shell is a Singleton command class
|
|
478
527
|
if args[0] == "shell"
|
|
479
528
|
require 'morpheus/cli/commands/shell'
|
data/lib/morpheus.rb
CHANGED