morpheus-cli 3.6.8 → 3.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/morpheus/api/account_groups_interface.rb +2 -2
- data/lib/morpheus/api/accounts_interface.rb +4 -7
- data/lib/morpheus/api/api_client.rb +207 -70
- data/lib/morpheus/api/app_templates_interface.rb +7 -28
- data/lib/morpheus/api/apps_interface.rb +14 -21
- data/lib/morpheus/api/archive_buckets_interface.rb +2 -2
- data/lib/morpheus/api/archive_files_interface.rb +6 -6
- data/lib/morpheus/api/auth_interface.rb +14 -1
- data/lib/morpheus/api/blueprints_interface.rb +9 -16
- data/lib/morpheus/api/cloud_datastores_interface.rb +1 -1
- data/lib/morpheus/api/cloud_policies_interface.rb +1 -1
- data/lib/morpheus/api/clouds_interface.rb +18 -21
- data/lib/morpheus/api/cypher_interface.rb +19 -28
- data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
- data/lib/morpheus/api/group_policies_interface.rb +1 -1
- data/lib/morpheus/api/groups_interface.rb +4 -4
- data/lib/morpheus/api/image_builder_boot_scripts_interface.rb +1 -1
- data/lib/morpheus/api/image_builder_image_builds_interface.rb +2 -2
- data/lib/morpheus/api/image_builder_preseed_scripts_interface.rb +1 -1
- data/lib/morpheus/api/instances_interface.rb +17 -23
- data/lib/morpheus/api/logs_interface.rb +7 -10
- data/lib/morpheus/api/network_domains_interface.rb +1 -1
- data/lib/morpheus/api/network_groups_interface.rb +1 -1
- data/lib/morpheus/api/network_pool_servers_interface.rb +1 -1
- data/lib/morpheus/api/network_pools_interface.rb +1 -1
- data/lib/morpheus/api/network_proxies_interface.rb +1 -1
- data/lib/morpheus/api/network_services_interface.rb +1 -1
- data/lib/morpheus/api/networks_interface.rb +1 -1
- data/lib/morpheus/api/old_cypher_interface.rb +55 -0
- data/lib/morpheus/api/packages_interface.rb +1 -1
- data/lib/morpheus/api/policies_interface.rb +1 -1
- data/lib/morpheus/api/setup_interface.rb +1 -1
- data/lib/morpheus/api/storage_providers_interface.rb +1 -1
- data/lib/morpheus/api/whoami_interface.rb +1 -1
- data/lib/morpheus/benchmarking.rb +277 -0
- data/lib/morpheus/cli.rb +6 -22
- data/lib/morpheus/cli/access_token_command.rb +172 -0
- data/lib/morpheus/cli/accounts.rb +5 -0
- data/lib/morpheus/cli/apps.rb +93 -37
- data/lib/morpheus/cli/archives_command.rb +0 -2
- data/lib/morpheus/cli/auth_command.rb +112 -0
- data/lib/morpheus/cli/blueprints_command.rb +50 -13
- data/lib/morpheus/cli/change_password_command.rb +148 -0
- data/lib/morpheus/cli/cli_command.rb +173 -49
- data/lib/morpheus/cli/clouds.rb +15 -5
- data/lib/morpheus/cli/command_error.rb +7 -1
- data/lib/morpheus/cli/{alias_command.rb → commands/standard/alias_command.rb} +79 -51
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +399 -0
- data/lib/morpheus/cli/commands/standard/coloring_command.rb +60 -0
- data/lib/morpheus/cli/{curl_command.rb → commands/standard/curl_command.rb} +0 -7
- data/lib/morpheus/cli/commands/standard/debug_command.rb +61 -0
- data/lib/morpheus/cli/{echo_command.rb → commands/standard/echo_command.rb} +1 -1
- data/lib/morpheus/cli/{edit_profile_command.rb → commands/standard/edit_profile_command.rb} +0 -0
- data/lib/morpheus/cli/{edit_rc_command.rb → commands/standard/edit_rc_command.rb} +0 -0
- data/lib/morpheus/cli/commands/standard/get_prompt_command.rb +39 -0
- data/lib/morpheus/cli/commands/standard/history_command.rb +76 -0
- data/lib/morpheus/cli/{log_level_command.rb → commands/standard/log_level_command.rb} +1 -1
- data/lib/morpheus/cli/{man_command.rb → commands/standard/man_command.rb} +2 -2
- data/lib/morpheus/cli/commands/standard/rm_command.rb +14 -0
- data/lib/morpheus/cli/commands/standard/set_prompt_command.rb +54 -0
- data/lib/morpheus/cli/{sleep_command.rb → commands/standard/sleep_command.rb} +0 -0
- data/lib/morpheus/cli/{source_command.rb → commands/standard/source_command.rb} +0 -0
- data/lib/morpheus/cli/{ssl_verification_command.rb → commands/standard/ssl_verification_command.rb} +1 -1
- data/lib/morpheus/cli/commands/standard/tee_command.rb +14 -0
- data/lib/morpheus/cli/{version_command.rb → commands/standard/version_command.rb} +0 -0
- data/lib/morpheus/cli/credentials.rb +276 -87
- data/lib/morpheus/cli/cypher_command.rb +333 -214
- data/lib/morpheus/cli/error_handler.rb +12 -2
- data/lib/morpheus/cli/groups.rb +44 -20
- data/lib/morpheus/cli/hosts.rb +39 -16
- data/lib/morpheus/cli/instances.rb +114 -62
- data/lib/morpheus/cli/login.rb +74 -21
- data/lib/morpheus/cli/logout.rb +3 -4
- data/lib/morpheus/cli/mixins/accounts_helper.rb +50 -18
- data/lib/morpheus/cli/mixins/print_helper.rb +207 -42
- data/lib/morpheus/cli/old_cypher_command.rb +414 -0
- data/lib/morpheus/cli/option_parser.rb +6 -1
- data/lib/morpheus/cli/processes_command.rb +3 -0
- data/lib/morpheus/cli/remote.rb +11 -17
- data/lib/morpheus/cli/roles.rb +17 -17
- data/lib/morpheus/cli/security_groups.rb +47 -17
- data/lib/morpheus/cli/shell.rb +139 -79
- data/lib/morpheus/cli/tenants_command.rb +353 -0
- data/lib/morpheus/cli/users.rb +26 -18
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +14 -10
- data/lib/morpheus/formatters.rb +4 -4
- data/lib/morpheus/logging.rb +16 -8
- data/lib/morpheus/terminal.rb +63 -34
- metadata +28 -15
- data/lib/morpheus/cli/coloring_command.rb +0 -45
- data/lib/morpheus/cli/set_prompt_command.rb +0 -51
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -64,7 +64,7 @@ EOT
|
|
64
64
|
return 0
|
65
65
|
end
|
66
66
|
|
67
|
-
print_h1 "Morpheus Appliances"
|
67
|
+
print_h1 "Morpheus Appliances", [], options
|
68
68
|
if appliances.empty?
|
69
69
|
print yellow
|
70
70
|
puts "You have no appliances configured. See the `remote add` command."
|
@@ -494,9 +494,9 @@ EOT
|
|
494
494
|
|
495
495
|
if appliance[:active]
|
496
496
|
# print_h1 "Current Remote Appliance: #{appliance[:name]}"
|
497
|
-
print_h1 "Remote Appliance: #{appliance[:name]}"
|
497
|
+
print_h1 "Remote Appliance: #{appliance[:name]}", [], options
|
498
498
|
else
|
499
|
-
print_h1 "Remote Appliance: #{appliance[:name]}"
|
499
|
+
print_h1 "Remote Appliance: #{appliance[:name]}", [], options
|
500
500
|
end
|
501
501
|
print cyan
|
502
502
|
description_cols = {
|
@@ -560,7 +560,7 @@ EOT
|
|
560
560
|
|
561
561
|
# ok, delete it
|
562
562
|
::Morpheus::Cli::Remote.delete_remote(appliance_name)
|
563
|
-
|
563
|
+
|
564
564
|
# return result
|
565
565
|
if options[:quiet]
|
566
566
|
return 0, nil
|
@@ -667,7 +667,7 @@ EOT
|
|
667
667
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
668
668
|
opts.banner = subcommand_usage()
|
669
669
|
build_common_options(opts, options, [])
|
670
|
-
opts.footer = "
|
670
|
+
opts.footer = "Print the name of the current remote appliance"
|
671
671
|
end
|
672
672
|
optparse.parse!(args)
|
673
673
|
|
@@ -735,7 +735,7 @@ EOT
|
|
735
735
|
# end
|
736
736
|
return false
|
737
737
|
else
|
738
|
-
print_h1 "Morpheus Appliance Setup"
|
738
|
+
print_h1 "Morpheus Appliance Setup", [], options
|
739
739
|
|
740
740
|
puts "It looks like you're the first one here."
|
741
741
|
puts "Let's initialize your remote appliance at #{@appliance_url}"
|
@@ -743,7 +743,7 @@ EOT
|
|
743
743
|
|
744
744
|
|
745
745
|
# Master Account
|
746
|
-
print_h2 "Create Master Account"
|
746
|
+
print_h2 "Create Master Account", options
|
747
747
|
account_option_types = [
|
748
748
|
{'fieldName' => 'accountName', 'fieldLabel' => 'Master Account Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
749
749
|
]
|
@@ -751,7 +751,7 @@ EOT
|
|
751
751
|
payload.merge!(v_prompt)
|
752
752
|
|
753
753
|
# Master User
|
754
|
-
print_h2 "Create Master User"
|
754
|
+
print_h2 "Create Master User", options
|
755
755
|
user_option_types = [
|
756
756
|
{'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
|
757
757
|
{'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
|
@@ -774,7 +774,7 @@ EOT
|
|
774
774
|
payload.merge!(v_prompt)
|
775
775
|
|
776
776
|
# Extra settings
|
777
|
-
print_h2 "Initial Setup"
|
777
|
+
print_h2 "Initial Setup", options
|
778
778
|
extra_option_types = [
|
779
779
|
{'fieldName' => 'applianceName', 'fieldLabel' => 'Appliance Name', 'type' => 'text', 'required' => true, 'defaultValue' => nil},
|
780
780
|
{'fieldName' => 'applianceUrl', 'fieldLabel' => 'Appliance URL', 'type' => 'text', 'required' => true, 'defaultValue' => appliance_status_json['applianceUrl']},
|
@@ -847,10 +847,8 @@ EOT
|
|
847
847
|
out << "#{green}#{status_str.upcase}#{return_color}"
|
848
848
|
elsif status_str == "unreachable"
|
849
849
|
out << "#{red}#{status_str.upcase}#{return_color}"
|
850
|
-
elsif
|
851
|
-
out << "#{red}#{status_str.upcase}#{return_color}"
|
852
|
-
# elsif status_str == "unknown"
|
853
|
-
# out << "#{yellow}#{status_str}#{return_color}"
|
850
|
+
elsif ['error', 'net-error', 'ssl-error', 'http-timeout', 'unreachable']
|
851
|
+
out << "#{red}#{status_str.upcase.gsub('-',' ')}#{return_color}"
|
854
852
|
elsif status_str == "fresh"
|
855
853
|
# cold appliance, needs setup
|
856
854
|
out << "#{magenta}#{status_str.upcase}#{return_color}"
|
@@ -887,10 +885,6 @@ EOT
|
|
887
885
|
# Current User
|
888
886
|
#
|
889
887
|
username = app_map[:username]
|
890
|
-
# creds = app_map[:access_token]
|
891
|
-
#creds = Morpheus::Cli::Credentials.new(app_map[:name], app_map[:host]).load_saved_credentials()
|
892
|
-
|
893
|
-
|
894
888
|
|
895
889
|
if app_map[:status] == 'ready'
|
896
890
|
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -50,7 +50,7 @@ class Morpheus::Cli::Roles
|
|
50
50
|
params.merge!(parse_list_options(options))
|
51
51
|
|
52
52
|
if options[:dry_run]
|
53
|
-
print_dry_run @roles_interface.dry.list(account_id, params)
|
53
|
+
print_dry_run @roles_interface.dry.list(account_id, params), options
|
54
54
|
return
|
55
55
|
end
|
56
56
|
load_whoami()
|
@@ -69,11 +69,11 @@ class Morpheus::Cli::Roles
|
|
69
69
|
title = "Morpheus Roles"
|
70
70
|
subtitles = []
|
71
71
|
subtitles += parse_list_subtitles(options)
|
72
|
-
print_h1 title, subtitles
|
72
|
+
print_h1 title, subtitles, options
|
73
73
|
if roles.empty?
|
74
74
|
print cyan,"No roles found.",reset,"\n"
|
75
75
|
else
|
76
|
-
print_roles_table(roles, {is_master_account: @is_master_account})
|
76
|
+
print_roles_table(roles, options.merge({is_master_account: @is_master_account}))
|
77
77
|
print_results_pagination(json_response)
|
78
78
|
end
|
79
79
|
print reset,"\n"
|
@@ -164,7 +164,7 @@ class Morpheus::Cli::Roles
|
|
164
164
|
end
|
165
165
|
|
166
166
|
print cyan
|
167
|
-
print_h1 "Role Details"
|
167
|
+
print_h1 "Role Details", options
|
168
168
|
print cyan
|
169
169
|
description_cols = {
|
170
170
|
"ID" => 'id',
|
@@ -180,16 +180,16 @@ class Morpheus::Cli::Roles
|
|
180
180
|
}
|
181
181
|
print_description_list(description_cols, role)
|
182
182
|
|
183
|
-
print_h2 "Role Instance Limits"
|
184
|
-
print cyan
|
185
|
-
print_description_list({
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
}, role['instanceLimits'])
|
183
|
+
# print_h2 "Role Instance Limits", options
|
184
|
+
# print cyan
|
185
|
+
# print_description_list({
|
186
|
+
# "Max Storage" => lambda {|it| (it && it['maxStorage'].to_i != 0) ? Filesize.from("#{it['maxStorage']} B").pretty : "no limit" },
|
187
|
+
# "Max Memory" => lambda {|it| (it && it['maxMemory'].to_i != 0) ? Filesize.from("#{it['maxMemory']} B").pretty : "no limit" },
|
188
|
+
# "CPU Count" => lambda {|it| (it && it['maxCpu'].to_i != 0) ? it['maxCpu'] : "no limit" }
|
189
|
+
# }, role['instanceLimits'])
|
190
190
|
|
191
|
-
print_h2 "Feature Access"
|
192
|
-
print cyan
|
191
|
+
# print_h2 "Feature Access", options
|
192
|
+
# print cyan
|
193
193
|
|
194
194
|
if options[:include_feature_access]
|
195
195
|
rows = json_response['featurePermissions'].collect do |it|
|
@@ -204,7 +204,7 @@ class Morpheus::Cli::Roles
|
|
204
204
|
puts "Use --feature-access to list feature access"
|
205
205
|
end
|
206
206
|
|
207
|
-
print_h2 "Group Access"
|
207
|
+
print_h2 "Group Access", options
|
208
208
|
print cyan
|
209
209
|
puts "Global Group Access: #{get_access_string(json_response['globalSiteAccess'])}\n\n"
|
210
210
|
if json_response['globalSiteAccess'] == 'custom'
|
@@ -221,7 +221,7 @@ class Morpheus::Cli::Roles
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
224
|
-
print_h2 "Cloud Access"
|
224
|
+
print_h2 "Cloud Access", options
|
225
225
|
print cyan
|
226
226
|
puts "Global Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}\n\n"
|
227
227
|
if json_response['globalZoneAccess'] == 'custom'
|
@@ -238,7 +238,7 @@ class Morpheus::Cli::Roles
|
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
241
|
-
print_h2 "Instance Type Access"
|
241
|
+
print_h2 "Instance Type Access", options
|
242
242
|
print cyan
|
243
243
|
puts "Global Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}\n\n"
|
244
244
|
if json_response['globalInstanceTypeAccess'] == 'custom'
|
@@ -257,7 +257,7 @@ class Morpheus::Cli::Roles
|
|
257
257
|
|
258
258
|
blueprint_global_access = json_response['globalAppTemplateAccess'] || json_response['globalBlueprintAccess']
|
259
259
|
blueprint_permissions = json_response['appTemplatePermissions'] || json_response['blueprintPermissions'] || []
|
260
|
-
print_h2 "Blueprint Access"
|
260
|
+
print_h2 "Blueprint Access", options
|
261
261
|
print cyan
|
262
262
|
puts "Global Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}\n\n"
|
263
263
|
if blueprint_global_access == 'custom'
|
@@ -27,41 +27,71 @@ class Morpheus::Cli::SecurityGroups
|
|
27
27
|
options = {}
|
28
28
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
29
29
|
opts.banner = subcommand_usage()
|
30
|
-
build_common_options(opts, options, [:json, :dry_run])
|
30
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
31
31
|
end
|
32
32
|
optparse.parse!(args)
|
33
33
|
connect(options)
|
34
34
|
begin
|
35
35
|
params = {}
|
36
|
+
params.merge!(parse_list_options(options))
|
36
37
|
if options[:dry_run]
|
37
38
|
print_dry_run @security_groups_interface.dry.list(params)
|
38
39
|
return
|
39
40
|
end
|
40
41
|
json_response = @security_groups_interface.list(params)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
|
43
|
+
render_result = render_with_format(json_response, options, 'securityGroups')
|
44
|
+
return 0 if render_result
|
45
|
+
|
46
|
+
title = "Morpheus Security Groups"
|
47
|
+
subtitles = []
|
48
|
+
subtitles += parse_list_subtitles(options)
|
49
|
+
print_h1 title, subtitles
|
50
|
+
|
46
51
|
security_groups = json_response['securityGroups']
|
47
|
-
|
52
|
+
|
48
53
|
if security_groups.empty?
|
49
|
-
print yellow,"No
|
54
|
+
print yellow,"No security groups found.",reset,"\n"
|
50
55
|
else
|
51
56
|
active_id = @active_security_group[@appliance_name.to_sym]
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
# table_color = options[:color] || cyan
|
58
|
+
# rows = security_groups.collect do |security_group|
|
59
|
+
# {
|
60
|
+
# id: security_group['id'].to_s + ((security_group['id'] == active_id.to_i) ? " (active)" : ""),
|
61
|
+
# name: security_group['name'],
|
62
|
+
# description: security_group['description']
|
63
|
+
# }
|
64
|
+
# end
|
65
|
+
|
66
|
+
# columns = [
|
67
|
+
# :id,
|
68
|
+
# :name,
|
69
|
+
# :description,
|
70
|
+
# # :ports,
|
71
|
+
# # :status,
|
72
|
+
# ]
|
73
|
+
columns = {
|
74
|
+
"ID" => 'id',
|
75
|
+
"NAME" => 'name',
|
76
|
+
"DESCRIPTION" => 'description',
|
77
|
+
# need more to show here
|
78
|
+
}
|
79
|
+
# custom pretty table columns ...
|
80
|
+
if options[:include_fields]
|
81
|
+
columns = options[:include_fields]
|
58
82
|
end
|
59
|
-
|
60
|
-
|
83
|
+
print as_pretty_table(security_groups, columns, options)
|
84
|
+
print reset
|
85
|
+
if json_response['meta']
|
86
|
+
print_results_pagination(json_response, {:label => "security group", :n_label => "security groups"})
|
87
|
+
else
|
88
|
+
print_results_pagination({'meta'=>{'total'=>(json_response['securityGroupCount'] ? json_response['securityGroupCount'] : security_groups.size),'size'=>security_groups.size,'max'=>(params['max']||25),'offset'=>(params['offset']||0)}}, {:label => "security group", :n_label => "security groups"})
|
61
89
|
end
|
90
|
+
# print reset
|
62
91
|
end
|
63
92
|
print reset,"\n"
|
64
|
-
|
93
|
+
return 0
|
94
|
+
rescue RestClient::Exception => e
|
65
95
|
print_rest_exception(e, options)
|
66
96
|
exit 1
|
67
97
|
end
|
data/lib/morpheus/cli/shell.rb
CHANGED
@@ -10,6 +10,8 @@ require 'morpheus/cli/cli_command'
|
|
10
10
|
require 'morpheus/cli/error_handler'
|
11
11
|
require 'morpheus/cli/expression_parser'
|
12
12
|
require 'morpheus/terminal'
|
13
|
+
require 'morpheus/logging'
|
14
|
+
require 'morpheus/benchmarking'
|
13
15
|
|
14
16
|
#class Morpheus::Cli::Shell < Morpheus::Terminal
|
15
17
|
class Morpheus::Cli::Shell
|
@@ -88,7 +90,7 @@ class Morpheus::Cli::Shell
|
|
88
90
|
|
89
91
|
def recalculate_auto_complete_commands
|
90
92
|
@morpheus_commands = Morpheus::Cli::CliRegistry.all.keys.reject {|k| [:shell].include?(k) }
|
91
|
-
@shell_commands = [:clear, :history, :
|
93
|
+
@shell_commands = [:clear, :history, :reload!, :help, :exit]
|
92
94
|
@alias_commands = Morpheus::Cli::CliRegistry.all_aliases.keys
|
93
95
|
@exploded_commands = []
|
94
96
|
Morpheus::Cli::CliRegistry.all.each do |cmd, klass|
|
@@ -126,7 +128,7 @@ class Morpheus::Cli::Shell
|
|
126
128
|
@@insecure = true
|
127
129
|
Morpheus::RestClient.enable_ssl_verification = false
|
128
130
|
end
|
129
|
-
opts.on('-Z','--incognito', "Incognito mode. Use a temporary shell
|
131
|
+
opts.on('-Z','--incognito', "Incognito mode. Use a temporary shell. Remotes are loaded without without saved credentials or history logging.") do
|
130
132
|
@incognito_mode = true
|
131
133
|
#@norc = true # perhaps?
|
132
134
|
tmpdir = ENV['MORPHEUS_CLI_TMPDIR'] || ENV['TMPDIR'] || ENV['TMP']
|
@@ -167,11 +169,15 @@ class Morpheus::Cli::Shell
|
|
167
169
|
opts.on('-C','--nocolor', "Disable ANSI coloring") do
|
168
170
|
Term::ANSIColor::coloring = false
|
169
171
|
end
|
170
|
-
opts.on('-V','--debug', "Print extra output for debugging.") do
|
172
|
+
opts.on('-V','--debug', "Print extra output for debugging.") do
|
171
173
|
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
172
174
|
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
173
175
|
end
|
174
|
-
opts.on(
|
176
|
+
opts.on('-B','--benchmark', "Print benchmark time after each command is finished, including shell itself." ) do
|
177
|
+
Morpheus::Benchmarking.enabled = true
|
178
|
+
my_terminal.benchmarking = Morpheus::Benchmarking.enabled
|
179
|
+
end
|
180
|
+
opts.on( '-h', '--help', "Print this help" ) do
|
175
181
|
puts opts
|
176
182
|
exit
|
177
183
|
end
|
@@ -235,33 +241,12 @@ class Morpheus::Cli::Shell
|
|
235
241
|
return result
|
236
242
|
end
|
237
243
|
|
238
|
-
#
|
239
|
-
#
|
240
|
-
|
241
|
-
|
242
|
-
if result.is_a?(Array) # exit_code, err
|
243
|
-
exit_code = result[0].to_i
|
244
|
-
err = result[1]
|
245
|
-
elsif result == nil || result == true || result == 0
|
246
|
-
exit_code = 0
|
247
|
-
elsif result == false
|
248
|
-
exit_code = 1
|
249
|
-
# elsif result.is_a?(Integer)
|
250
|
-
# exit_code = result.to_i
|
251
|
-
else
|
252
|
-
exit_code = result.to_i
|
253
|
-
end
|
254
|
-
# return exit_code, err
|
255
|
-
return exit_code
|
256
|
-
end
|
257
|
-
|
258
|
-
# same as Terminal instance
|
244
|
+
# execute the input as an expression.
|
245
|
+
# provides support for operators '(', ')', '&&', '||', ';'
|
246
|
+
# logs entire input as one command in shell history
|
247
|
+
# logging is skipped for certain commands: exit, !, !!
|
259
248
|
def execute(input)
|
260
|
-
# args = Shellwords.shellsplit(input)
|
261
|
-
#cmd = args.shift
|
262
|
-
#execute_commands(input)
|
263
249
|
result = execute_commands_as_expression(input)
|
264
|
-
# skip logging of exit and !cmd
|
265
250
|
unless input.strip.empty? || (["exit", "history"].include?(input.strip)) || input.strip[0].to_s.chr == "!"
|
266
251
|
log_history_command(input.strip)
|
267
252
|
end
|
@@ -302,12 +287,14 @@ class Morpheus::Cli::Shell
|
|
302
287
|
if flow_cmd == '&&'
|
303
288
|
# AND operator
|
304
289
|
current_operator = flow_cmd
|
305
|
-
|
290
|
+
exit_code, cmd_err = parse_command_result(previous_command_result)
|
291
|
+
if exit_code != 0
|
306
292
|
still_executing = false
|
307
293
|
end
|
308
294
|
elsif flow_cmd == '||' # or with previous command
|
309
295
|
current_operator = flow_cmd
|
310
|
-
|
296
|
+
exit_code, err = parse_command_result(previous_command_result)
|
297
|
+
if exit_code == 0
|
311
298
|
still_executing = false
|
312
299
|
end
|
313
300
|
elsif flow_cmd == '|' # or with previous command
|
@@ -350,9 +337,6 @@ class Morpheus::Cli::Shell
|
|
350
337
|
#exit 0
|
351
338
|
elsif input == 'help'
|
352
339
|
|
353
|
-
#print_h1 "Morpheus Shell Help", [], white
|
354
|
-
#print "\n"
|
355
|
-
|
356
340
|
puts "You are in a morpheus client shell."
|
357
341
|
puts "See the available commands below."
|
358
342
|
|
@@ -390,37 +374,37 @@ class Morpheus::Cli::Shell
|
|
390
374
|
# Morpheus::Logging::DarkPrinter.puts "\nInterrupt. waking up from sleep early"
|
391
375
|
# end
|
392
376
|
# return 0
|
393
|
-
elsif input =~ /^history/
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
377
|
+
# elsif input =~ /^history/
|
378
|
+
# n_commands = input.sub(/^history\s?/, '').sub(/\-n\s?/, '')
|
379
|
+
# n_commands = n_commands.empty? ? 25 : n_commands.to_i
|
380
|
+
# cmd_numbers = @history.keys.last(n_commands)
|
381
|
+
# if cmd_numbers.size == 1
|
382
|
+
# puts "Last command"
|
383
|
+
# else
|
384
|
+
# puts "Last #{cmd_numbers.size} commands"
|
385
|
+
# end
|
386
|
+
# cmd_numbers.each do |cmd_number|
|
387
|
+
# cmd = @history[cmd_number]
|
388
|
+
# puts "#{cmd_number.to_s.rjust(3, ' ')} #{cmd}"
|
389
|
+
# end
|
390
|
+
# last_cmd = cmd_numbers.last ? @history[cmd_numbers.last] : nil
|
391
|
+
# if input != last_cmd # no consecutive
|
392
|
+
# log_history_command(input)
|
393
|
+
# end
|
394
|
+
# return 0
|
411
395
|
elsif input == 'clear'
|
412
396
|
print "\e[H\e[2J"
|
413
397
|
return 0
|
414
|
-
elsif input == 'flush-history' || input == 'flush_history'
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
398
|
+
# elsif input == 'flush-history' || input == 'flush_history'
|
399
|
+
# file_path = history_file_path
|
400
|
+
# if File.exists?(file_path)
|
401
|
+
# File.truncate(file_path, 0)
|
402
|
+
# end
|
403
|
+
# @history = {}
|
404
|
+
# @last_command_number = 0
|
405
|
+
# @history_logger = load_history_logger
|
406
|
+
# puts "history cleared!"
|
407
|
+
# return 0
|
424
408
|
# elsif input == "edit rc"
|
425
409
|
# fn = Morpheus::Cli::DotFile.morpheusrc_filename
|
426
410
|
# editor = ENV['EDITOR'] # || 'nano'
|
@@ -511,16 +495,17 @@ class Morpheus::Cli::Shell
|
|
511
495
|
Morpheus::RestClient.enable_ssl_verification = false
|
512
496
|
return 0
|
513
497
|
|
514
|
-
# use log-level [debug|info]
|
515
|
-
# elsif input =~ /^log_level/ # hidden for now
|
516
|
-
# log_level = input.sub(/^log_level\s*/, '').strip
|
517
|
-
# if log_level == ""
|
518
|
-
# puts "#{Morpheus::Logging.log_level}"
|
519
|
-
elsif input == "debug"
|
520
|
-
log_history_command(input)
|
521
|
-
return Morpheus::Cli::LogLevelCommand.new.handle(["debug"])
|
522
498
|
elsif ["hello","hi","hey","hola"].include?(input.strip.downcase)
|
523
|
-
|
499
|
+
# need a logged_in? method already damnit
|
500
|
+
#wallet = @wallet
|
501
|
+
wallet = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials
|
502
|
+
if wallet
|
503
|
+
# my_terminal.echo("#{input} %username!")
|
504
|
+
# todo: this morning|afternoon|evening would be pleasant
|
505
|
+
print "#{input} #{green}#{wallet['username']}#{reset}, how may I #{cyan}help#{reset} you?\n"
|
506
|
+
else
|
507
|
+
print "#{input}, how may I #{cyan}help#{reset} you?\n"
|
508
|
+
end
|
524
509
|
return 0
|
525
510
|
elsif input == "shell"
|
526
511
|
print "#{cyan}You are already in a shell.#{reset}\n"
|
@@ -531,21 +516,31 @@ class Morpheus::Cli::Shell
|
|
531
516
|
return Morpheus::Cli::SourceCommand.new.handle(input.split[1..-1])
|
532
517
|
end
|
533
518
|
cmd_result = nil
|
534
|
-
unless input =~ /log-level/
|
535
|
-
@return_to_log_level = Morpheus::Logging.log_level
|
536
|
-
end
|
537
|
-
unless input =~ /coloring/
|
538
|
-
@return_to_coloring = Term::ANSIColor::coloring?
|
539
|
-
end
|
540
519
|
begin
|
541
520
|
argv = Shellwords.shellsplit(input)
|
542
521
|
cmd_name = argv[0]
|
543
522
|
cmd_args = argv[1..-1]
|
523
|
+
# crap hack, naming conflicts can occur with aliases
|
524
|
+
@return_to_log_level = ["log-level","debug"].include?(cmd_name) ? nil : Morpheus::Logging.log_level
|
525
|
+
@return_to_coloring = ["coloring"].include?(cmd_name) ? nil : Term::ANSIColor::coloring?
|
526
|
+
@return_to_benchmarking = ["benchmark"].include?(cmd_name) ? nil : Morpheus::Benchmarking.enabled?
|
527
|
+
|
544
528
|
if Morpheus::Cli::CliRegistry.has_command?(cmd_name) || Morpheus::Cli::CliRegistry.has_alias?(cmd_name)
|
545
529
|
#log_history_command(input)
|
530
|
+
# start a benchmark, unless the command is benchmark of course
|
531
|
+
if my_terminal.benchmarking || cmd_args.include?("-B") || cmd_args.include?("--benchmark")
|
532
|
+
if cmd_name != 'benchmark' # jd: this does not work still 2 of them printed.. fix it!
|
533
|
+
# benchmark_name = "morpheus " + argv.reject {|it| it == '-B' || it == '--benchmark' }.join(' ')
|
534
|
+
benchmark_name = argv.reject {|it| it == '-B' || it == '--benchmark' }.join(' ')
|
535
|
+
start_benchmark(benchmark_name)
|
536
|
+
end
|
537
|
+
end
|
546
538
|
cmd_result = Morpheus::Cli::CliRegistry.exec(cmd_name, cmd_args)
|
539
|
+
cmd_exit_code, cmd_err = parse_command_result(cmd_result)
|
540
|
+
benchmark_record = stop_benchmark(cmd_exit_code, cmd_err) # if benchmarking?
|
541
|
+
Morpheus::Logging::DarkPrinter.puts(cyan + dark + benchmark_record.msg) if benchmark_record
|
547
542
|
else
|
548
|
-
puts_error "#{Morpheus::Terminal.angry_prompt}'#{cmd_name}' is not
|
543
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}'#{cmd_name}' is not recognized. Use 'help' to see the list of available commands."
|
549
544
|
@history_logger.warn "Unrecognized Command #{cmd_name}" if @history_logger
|
550
545
|
cmd_result = -1
|
551
546
|
end
|
@@ -571,6 +566,11 @@ class Morpheus::Cli::Shell
|
|
571
566
|
Term::ANSIColor::coloring = @return_to_coloring
|
572
567
|
@return_to_coloring = nil
|
573
568
|
end
|
569
|
+
if @return_to_benchmarking != nil
|
570
|
+
Morpheus::Benchmarking.enabled = @return_to_benchmarking
|
571
|
+
my_terminal.benchmarking = Morpheus::Benchmarking.enabled
|
572
|
+
@return_to_benchmarking = nil
|
573
|
+
end
|
574
574
|
end
|
575
575
|
|
576
576
|
# commands should be a number or nil (treated as 0)
|
@@ -664,7 +664,67 @@ class Morpheus::Cli::Shell
|
|
664
664
|
@last_command_number += 1
|
665
665
|
@history[@last_command_number] = cmd
|
666
666
|
if @history_logger
|
667
|
-
@history_logger.info "#{@current_username}@#{@appliance_name}
|
667
|
+
@history_logger.info "#{@current_username}@#{@appliance_name} -- : (cmd #{@last_command_number}) #{cmd}"
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
def last_command(n=25)
|
672
|
+
return list_history_commands(max:1)[0]
|
673
|
+
end
|
674
|
+
|
675
|
+
# list the N most recent commands, sorted oldest -> newest
|
676
|
+
# todo: support sort and order options..
|
677
|
+
def list_history_commands(options={})
|
678
|
+
history_records = []
|
679
|
+
max = options[:max] ? options[:max].to_i : 25
|
680
|
+
max = 50
|
681
|
+
load_history_from_log_file if !@history
|
682
|
+
cmd_numbers = @history.keys.last(max.to_i)
|
683
|
+
history_records = cmd_numbers.collect { |cmd_number| {command_number: cmd_number, command: @history[cmd_number]} }
|
684
|
+
last_cmd = cmd_numbers.last ? @history[cmd_numbers.last] : nil
|
685
|
+
# if input != last_cmd # no consecutive
|
686
|
+
# log_history_command(input)
|
687
|
+
# end
|
688
|
+
return history_records
|
689
|
+
end
|
690
|
+
|
691
|
+
def print_history(n)
|
692
|
+
n ||= 25
|
693
|
+
load_history_from_log_file if !@history
|
694
|
+
cmd_numbers = @history.keys.last(n.to_i)
|
695
|
+
if cmd_numbers.size == 1
|
696
|
+
puts "Last command"
|
697
|
+
else
|
698
|
+
puts "Last #{cmd_numbers.size} commands"
|
668
699
|
end
|
700
|
+
print cyan
|
701
|
+
cmd_numbers.each do |cmd_number|
|
702
|
+
cmd = @history[cmd_number]
|
703
|
+
puts "#{cmd_number.to_s.rjust(3, ' ')} #{cmd}"
|
704
|
+
end
|
705
|
+
print reset
|
706
|
+
#last_cmd = cmd_numbers.last ? @history[cmd_numbers.last] : nil
|
707
|
+
# if input != last_cmd # no consecutive
|
708
|
+
# log_history_command(input)
|
709
|
+
# end
|
710
|
+
return 0
|
711
|
+
end
|
712
|
+
|
713
|
+
def history_commands_count()
|
714
|
+
load_history_from_log_file if !@history
|
715
|
+
@history.keys.size
|
716
|
+
end
|
717
|
+
|
718
|
+
def flush_history(n=nil)
|
719
|
+
# todo: support only flushing last n commands
|
720
|
+
file_path = history_file_path
|
721
|
+
if File.exists?(file_path)
|
722
|
+
File.truncate(file_path, 0)
|
723
|
+
end
|
724
|
+
@history = {}
|
725
|
+
@last_command_number = 0
|
726
|
+
@history_logger = load_history_logger
|
727
|
+
print cyan, "Command history flushed!", reset, "\n"
|
728
|
+
return 0
|
669
729
|
end
|
670
730
|
end
|