morpheus-cli 3.6.8 → 3.6.9
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/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/login.rb
CHANGED
|
@@ -18,7 +18,7 @@ class Morpheus::Cli::Login
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def usage
|
|
21
|
-
"Usage: morpheus login"
|
|
21
|
+
"Usage: morpheus login [username] [password]"
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def handle(args)
|
|
@@ -36,13 +36,33 @@ class Morpheus::Cli::Login
|
|
|
36
36
|
opts.on( '-p', '--password PASSWORD', "Password" ) do |val|
|
|
37
37
|
password = val
|
|
38
38
|
end
|
|
39
|
-
opts.on( '-
|
|
39
|
+
opts.on( '-t', '--test', "Test credentials only, does not update stored credentials for the appliance." ) do
|
|
40
|
+
options[:test_only] = true
|
|
41
|
+
end
|
|
42
|
+
opts.on( '-T', '--token ACCESS_TOKEN', "Use an existing access token to login instead of authenticating with a username and password." ) do |val|
|
|
40
43
|
options[:remote_token] = val
|
|
41
44
|
end
|
|
42
|
-
build_common_options(opts, options, [:json, :remote, :quiet])
|
|
45
|
+
build_common_options(opts, options, [:json, :dry_run, :remote, :quiet], [:remote_username, :remote_password, :remote_token])
|
|
46
|
+
opts.footer = "Login to a remote appliance with a username and password or an access token.\n" +
|
|
47
|
+
"[username] is required .\n" +
|
|
48
|
+
"[password] is required.\n" +
|
|
49
|
+
"Logging in with username and password will make an authentication api request to obtain an access token.\n" +
|
|
50
|
+
"The --token option can be used to login with an existing token instead of username and password.\n" +
|
|
51
|
+
"Using --token makes a whoami api request to validate the token.\n" +
|
|
52
|
+
"If successful, the access token will be saved with the active session for the remote appliance.\n" +
|
|
53
|
+
"This command will first logout any active session before attempting to login.\n" +
|
|
54
|
+
"The --test option can be used for testing credentials without updating your active session."
|
|
55
|
+
|
|
43
56
|
end
|
|
44
57
|
optparse.parse!(args)
|
|
45
|
-
|
|
58
|
+
if args.count > 2
|
|
59
|
+
print_error Morpheus::Terminal.angry_prompt
|
|
60
|
+
puts_error "#{command_name} list expects 0-2 arguments and received #{args.count}: #{args}\n#{optparse}"
|
|
61
|
+
return 1
|
|
62
|
+
end
|
|
63
|
+
username = args[0] if args[0]
|
|
64
|
+
password = args[1] if args[1]
|
|
65
|
+
|
|
46
66
|
# connect(options)
|
|
47
67
|
if options[:remote]
|
|
48
68
|
appliance = Morpheus::Cli::Remote.appliances[options[:remote].to_sym]
|
|
@@ -53,41 +73,74 @@ class Morpheus::Cli::Login
|
|
|
53
73
|
end
|
|
54
74
|
if !@appliance_name
|
|
55
75
|
print_error red, "You have no appliance named '#{options[:remote]}' configured. See the `remote list` command.", reset, "\n"
|
|
56
|
-
return
|
|
76
|
+
return 1
|
|
57
77
|
end
|
|
78
|
+
elsif options[:remote_url]
|
|
79
|
+
# --remote-url
|
|
80
|
+
@appliance_name, @appliance_url = nil, appliance[:remote_url]
|
|
58
81
|
else
|
|
59
82
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
60
83
|
if !@appliance_name
|
|
61
84
|
print_error yellow, "Please specify a remote appliance with -r or see the command `remote use`", reset, "\n"
|
|
62
|
-
return
|
|
85
|
+
return 1
|
|
63
86
|
end
|
|
64
87
|
end
|
|
65
88
|
|
|
66
89
|
begin
|
|
67
|
-
if options[:quiet]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return false
|
|
71
|
-
end
|
|
90
|
+
if (options[:quiet] && (!options[:remote_token]) && !(username && password))
|
|
91
|
+
print_error yellow,"Please specify username and password, or token.", reset, "\n"
|
|
92
|
+
return 1
|
|
72
93
|
end
|
|
73
|
-
options[:remote_username] = username if username
|
|
74
|
-
options[:remote_password] = password if password
|
|
75
|
-
#options[:remote_url] = true # will skip credentials save
|
|
76
|
-
login_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).login(options)
|
|
77
94
|
|
|
78
|
-
|
|
79
|
-
|
|
95
|
+
options[:username] = username if username
|
|
96
|
+
options[:password] = password if password
|
|
80
97
|
|
|
81
|
-
|
|
98
|
+
do_save = true
|
|
99
|
+
if options[:test_only] || options[:remote_url]
|
|
100
|
+
do_save = false
|
|
101
|
+
end
|
|
102
|
+
#old_wallet = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
|
|
103
|
+
|
|
104
|
+
login_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).login(options, do_save)
|
|
105
|
+
if options[:dry_run]
|
|
106
|
+
return 0
|
|
107
|
+
end
|
|
108
|
+
wallet = login_result
|
|
109
|
+
|
|
110
|
+
# needed here too?
|
|
82
111
|
::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
83
112
|
|
|
84
|
-
|
|
113
|
+
# should happen here, not in Credentials.login()
|
|
114
|
+
# if options[:json]
|
|
115
|
+
# puts as_json(login_result)
|
|
116
|
+
# return (login_result && login_result['access_token']) ? 0 : 1
|
|
117
|
+
# end
|
|
118
|
+
|
|
119
|
+
if wallet && wallet['access_token']
|
|
120
|
+
# Login Success!
|
|
85
121
|
if !options[:quiet]
|
|
86
|
-
|
|
122
|
+
if options[:test_only]
|
|
123
|
+
print green,"Success! Credentials verified for #{wallet['username']}.", reset, "\n"
|
|
124
|
+
else
|
|
125
|
+
print green,"Success! Logged in to #{@appliance_name} as #{wallet['username']}.", reset, "\n"
|
|
126
|
+
end
|
|
87
127
|
end
|
|
88
128
|
return 0 # , nil
|
|
89
129
|
else
|
|
90
|
-
|
|
130
|
+
# Login Failed
|
|
131
|
+
# so login() already prints 'Bad Credentials' (deprecate class Credentials plz)
|
|
132
|
+
# tell them if they're logged out now.
|
|
133
|
+
if !options[:quiet]
|
|
134
|
+
if options[:test_only]
|
|
135
|
+
# you are fine, nothing has changed
|
|
136
|
+
else
|
|
137
|
+
# if old_wallet && old_wallet['access_token']
|
|
138
|
+
# #print reset,"You are no longer logged in. Goodbye #{old_wallet['username']}!", reset, "\n"
|
|
139
|
+
# # todo: prompt to recover wallet ?
|
|
140
|
+
# end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
return 1, "Login failed"
|
|
91
144
|
end
|
|
92
145
|
|
|
93
146
|
rescue RestClient::Exception => e
|
data/lib/morpheus/cli/logout.rb
CHANGED
|
@@ -17,7 +17,6 @@ class Morpheus::Cli::Logout
|
|
|
17
17
|
|
|
18
18
|
def connect(opts)
|
|
19
19
|
#@api_client = establish_remote_appliance_connection(opts)
|
|
20
|
-
#@access_token = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials(options)
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def usage
|
|
@@ -45,8 +44,8 @@ class Morpheus::Cli::Logout
|
|
|
45
44
|
puts_error "Please specify a Morpheus Appliance to logout of with -r or see the command `remote use`"
|
|
46
45
|
return 1
|
|
47
46
|
end
|
|
48
|
-
|
|
49
|
-
token =
|
|
47
|
+
wallet = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials
|
|
48
|
+
token = wallet ? wallet['access_token'] : nil
|
|
50
49
|
if !token
|
|
51
50
|
if !options[:quiet]
|
|
52
51
|
puts "You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}"
|
|
@@ -57,7 +56,7 @@ class Morpheus::Cli::Logout
|
|
|
57
56
|
# note: this also handles updating appliance session info
|
|
58
57
|
Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).logout()
|
|
59
58
|
if !options[:quiet]
|
|
60
|
-
puts "#{cyan}Logged out of #{@appliance_name}. Goodbye
|
|
59
|
+
puts "#{cyan}Logged out of #{@appliance_name}. Goodbye #{wallet['username']}!#{reset}"
|
|
61
60
|
end
|
|
62
61
|
end
|
|
63
62
|
# recalcuate echo vars
|
|
@@ -110,7 +110,7 @@ module Morpheus::Cli::AccountsHelper
|
|
|
110
110
|
return nil
|
|
111
111
|
elsif roles.size > 1
|
|
112
112
|
print_red_alert "#{roles.size} roles by name #{name}"
|
|
113
|
-
print_roles_table(roles, {color: red})
|
|
113
|
+
print_roles_table(roles, {color: red, thin: true})
|
|
114
114
|
print reset,"\n\n"
|
|
115
115
|
return nil
|
|
116
116
|
else
|
|
@@ -148,7 +148,7 @@ module Morpheus::Cli::AccountsHelper
|
|
|
148
148
|
return nil
|
|
149
149
|
elsif users.size > 1
|
|
150
150
|
print_red_alert "#{users.size} users by username #{username}"
|
|
151
|
-
print_users_table(users, {color: red})
|
|
151
|
+
print_users_table(users, {color: red, thin: true})
|
|
152
152
|
print reset,"\n\n"
|
|
153
153
|
return nil
|
|
154
154
|
else
|
|
@@ -156,8 +156,32 @@ module Morpheus::Cli::AccountsHelper
|
|
|
156
156
|
end
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
-
def
|
|
160
|
-
|
|
159
|
+
def find_all_user_ids(account_id, usernames)
|
|
160
|
+
user_ids = []
|
|
161
|
+
if usernames.is_a?(String)
|
|
162
|
+
usernames = usernames.split(",").collect {|it| it.to_s.strip }.select {|it| it }.uniq
|
|
163
|
+
else
|
|
164
|
+
usernames = usernames.collect {|it| it.to_s.strip }.select {|it| it }.uniq
|
|
165
|
+
end
|
|
166
|
+
usernames.each do |username|
|
|
167
|
+
# save a query
|
|
168
|
+
#user = find_user_by_username_or_id(nil, username)
|
|
169
|
+
if username.to_s =~ /\A\d{1,}\Z/
|
|
170
|
+
user_ids << username.to_i
|
|
171
|
+
else
|
|
172
|
+
user = find_user_by_username(account_id, username)
|
|
173
|
+
if user.nil?
|
|
174
|
+
return nil
|
|
175
|
+
else
|
|
176
|
+
user_ids << user['id']
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
user_ids
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def print_accounts_table(accounts, options={})
|
|
184
|
+
table_color = options.key?(:color) ? options[:color] : cyan
|
|
161
185
|
rows = accounts.collect do |account|
|
|
162
186
|
status_state = nil
|
|
163
187
|
if account['active']
|
|
@@ -205,8 +229,8 @@ module Morpheus::Cli::AccountsHelper
|
|
|
205
229
|
return str
|
|
206
230
|
end
|
|
207
231
|
|
|
208
|
-
def print_roles_table(roles,
|
|
209
|
-
table_color =
|
|
232
|
+
def print_roles_table(roles, options={})
|
|
233
|
+
table_color = options.key?(:color) ? options[:color] : cyan
|
|
210
234
|
# tp roles, [
|
|
211
235
|
# 'id',
|
|
212
236
|
# 'name',
|
|
@@ -226,28 +250,36 @@ module Morpheus::Cli::AccountsHelper
|
|
|
226
250
|
dateCreated: format_local_dt(role['dateCreated'])
|
|
227
251
|
}
|
|
228
252
|
end
|
|
229
|
-
|
|
230
|
-
tp rows, [
|
|
253
|
+
columns = [
|
|
231
254
|
:id,
|
|
232
255
|
:name,
|
|
233
256
|
:description,
|
|
234
|
-
#
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
257
|
+
# options[:is_master_account] ? :scope : nil,
|
|
258
|
+
options[:is_master_account] ? :type : nil,
|
|
259
|
+
options[:is_master_account] ? :multitenant : nil,
|
|
260
|
+
options[:is_master_account] ? :owner : nil,
|
|
238
261
|
{:dateCreated => {:display_name => "Date Created"} }
|
|
239
262
|
].compact
|
|
240
|
-
|
|
263
|
+
if options[:include_fields]
|
|
264
|
+
columns = options[:include_fields]
|
|
265
|
+
end
|
|
266
|
+
# print table_color if table_color
|
|
267
|
+
print as_pretty_table(rows, columns, options)
|
|
268
|
+
# print reset if table_color
|
|
241
269
|
end
|
|
242
270
|
|
|
243
|
-
def print_users_table(users,
|
|
244
|
-
table_color =
|
|
271
|
+
def print_users_table(users, options={})
|
|
272
|
+
table_color = options[:color] || cyan
|
|
245
273
|
rows = users.collect do |user|
|
|
246
274
|
{id: user['id'], username: user['username'], name: user['displayName'], first: user['firstName'], last: user['lastName'], email: user['email'], role: format_user_role_names(user), account: user['account'] ? user['account']['name'] : nil}
|
|
247
275
|
end
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
276
|
+
columns = [:id, :account, :first, :last, :username, :email, :role]
|
|
277
|
+
if options[:include_fields]
|
|
278
|
+
columns = options[:include_fields]
|
|
279
|
+
end
|
|
280
|
+
#print table_color if table_color
|
|
281
|
+
print as_pretty_table(rows, columns, options)
|
|
282
|
+
#print reset if table_color
|
|
251
283
|
end
|
|
252
284
|
|
|
253
285
|
def format_user_role_names(user)
|
|
@@ -4,6 +4,7 @@ require 'json'
|
|
|
4
4
|
require 'yaml'
|
|
5
5
|
require 'ostruct'
|
|
6
6
|
require 'io/console'
|
|
7
|
+
require 'morpheus/logging'
|
|
7
8
|
|
|
8
9
|
module Morpheus::Cli::PrintHelper
|
|
9
10
|
|
|
@@ -34,6 +35,7 @@ module Morpheus::Cli::PrintHelper
|
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
# puts red message to stderr
|
|
38
|
+
# why this not stderr yet? use print_error or if respond_to?(:my_terminal)
|
|
37
39
|
def print_red_alert(msg)
|
|
38
40
|
#$stderr.print "#{red}#{msg}#{reset}\n"
|
|
39
41
|
print "#{red}#{msg}#{reset}\n"
|
|
@@ -51,9 +53,18 @@ module Morpheus::Cli::PrintHelper
|
|
|
51
53
|
# title - subtitle1, subtitle2
|
|
52
54
|
# ==================
|
|
53
55
|
#
|
|
54
|
-
def print_h1(title, subtitles=
|
|
55
|
-
#
|
|
56
|
-
|
|
56
|
+
def print_h1(title, subtitles=nil, options=nil)
|
|
57
|
+
# ok, support all these formats for now:
|
|
58
|
+
# print_h1(title, options={})
|
|
59
|
+
# print_h1(title, subtitles, options={})
|
|
60
|
+
# this can go away when we have a dirty @current_options
|
|
61
|
+
if subtitles.is_a?(Hash)
|
|
62
|
+
options = subtitles
|
|
63
|
+
subtitles = (options[:subtitles] || []).flatten
|
|
64
|
+
end
|
|
65
|
+
subtitles = (subtitles || []).flatten
|
|
66
|
+
options ||= {}
|
|
67
|
+
color = options[:color] || cyan
|
|
57
68
|
out = ""
|
|
58
69
|
out << "\n"
|
|
59
70
|
out << "#{color}#{bold}#{title}#{reset}"
|
|
@@ -61,15 +72,27 @@ module Morpheus::Cli::PrintHelper
|
|
|
61
72
|
out << "#{color} | #{subtitles.join(', ')}#{reset}"
|
|
62
73
|
end
|
|
63
74
|
out << "\n"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
if options[:border_style] == :thin
|
|
76
|
+
out << "\n"
|
|
77
|
+
else
|
|
78
|
+
out << "#{color}#{bold}==================#{reset}\n\n"
|
|
79
|
+
end
|
|
67
80
|
print out
|
|
68
81
|
end
|
|
69
82
|
|
|
70
|
-
def print_h2(title, subtitles=
|
|
71
|
-
#
|
|
72
|
-
|
|
83
|
+
def print_h2(title, subtitles=nil, options=nil)
|
|
84
|
+
# ok, support all these formats for now:
|
|
85
|
+
# print_h2(title={})
|
|
86
|
+
# print_h2(title, options={})
|
|
87
|
+
# print_h2(title, subtitles, options={})
|
|
88
|
+
# this can go away when we have a dirty @current_options
|
|
89
|
+
if subtitles.is_a?(Hash)
|
|
90
|
+
options = subtitles
|
|
91
|
+
subtitles = (options[:subtitles] || []).flatten
|
|
92
|
+
end
|
|
93
|
+
subtitles = (subtitles || []).flatten
|
|
94
|
+
options ||= {}
|
|
95
|
+
color = options[:color] || cyan
|
|
73
96
|
out = ""
|
|
74
97
|
out << "\n"
|
|
75
98
|
out << "#{color}#{bold}#{title}#{reset}"
|
|
@@ -77,9 +100,11 @@ module Morpheus::Cli::PrintHelper
|
|
|
77
100
|
out << "#{color} - #{subtitles.join(', ')}#{reset}"
|
|
78
101
|
end
|
|
79
102
|
out << "\n"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
103
|
+
if options[:border_style] == :thin
|
|
104
|
+
out << "\n"
|
|
105
|
+
else
|
|
106
|
+
out << "#{color}---------------------#{reset}\n\n"
|
|
107
|
+
end
|
|
83
108
|
print out
|
|
84
109
|
end
|
|
85
110
|
|
|
@@ -99,45 +124,92 @@ module Morpheus::Cli::PrintHelper
|
|
|
99
124
|
end
|
|
100
125
|
end
|
|
101
126
|
|
|
102
|
-
def print_dry_run(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
127
|
+
def print_dry_run(api_request, options={})
|
|
128
|
+
# 2nd argument used to be command_string (String)
|
|
129
|
+
command_string = nil
|
|
130
|
+
if options.is_a?(String)
|
|
131
|
+
command_string = options
|
|
132
|
+
options = {}
|
|
133
|
+
end
|
|
134
|
+
options ||= {}
|
|
135
|
+
# api client injects common command options here
|
|
136
|
+
if api_request[:command_options]
|
|
137
|
+
options = options.merge(api_request[:command_options])
|
|
138
|
+
end
|
|
139
|
+
options ||= {}
|
|
140
|
+
# parse params request arguments
|
|
141
|
+
http_method = api_request[:method]
|
|
142
|
+
url = api_request[:url]
|
|
143
|
+
headers = api_request[:headers]
|
|
144
|
+
params = nil
|
|
145
|
+
if api_request[:params] && !api_request[:params].empty?
|
|
146
|
+
params = api_request[:params]
|
|
147
|
+
elsif api_request[:headers] && api_request[:headers][:params]
|
|
148
|
+
# params inside headers for restclient reasons..
|
|
149
|
+
params = api_request[:headers][:params]
|
|
150
|
+
elsif api_request[:query] && !api_request[:query].empty?
|
|
151
|
+
params = api_request[:query]
|
|
152
|
+
end
|
|
153
|
+
query_string = params
|
|
154
|
+
if query_string.respond_to?(:map)
|
|
155
|
+
query_string = URI.encode_www_form(query_string)
|
|
156
|
+
end
|
|
108
157
|
if query_string && !query_string.empty?
|
|
109
158
|
url = "#{url}?#{query_string}"
|
|
110
159
|
end
|
|
111
160
|
request_string = "#{http_method.to_s.upcase} #{url}".strip
|
|
112
|
-
payload =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
161
|
+
payload = api_request[:payload] || api_request[:body]
|
|
162
|
+
|
|
163
|
+
#Morpheus::Logging::DarkPrinter.puts "API payload is: (#{payload.class}) #{payload.inspect}"
|
|
164
|
+
|
|
165
|
+
# curl output?
|
|
166
|
+
if api_request[:curl] || options[:curl]
|
|
167
|
+
print "\n"
|
|
168
|
+
puts "#{cyan}#{bold}#{dark}CURL COMMAND#{reset}\n"
|
|
169
|
+
print format_curl_command(http_method, url, headers, payload, options)
|
|
170
|
+
print "\n",reset
|
|
171
|
+
return
|
|
119
172
|
end
|
|
120
|
-
|
|
121
|
-
print
|
|
122
|
-
|
|
173
|
+
|
|
174
|
+
# print this thing:
|
|
175
|
+
# REQUEST:
|
|
176
|
+
# POST http://morpheusdata.com/api/whoami
|
|
177
|
+
# f it..removing this, just DRY RUN printed at the start of command
|
|
178
|
+
print "\n"
|
|
179
|
+
# if command_string != false
|
|
180
|
+
# if command_string
|
|
181
|
+
# print_h1 "DRY RUN > #{command_string}"
|
|
182
|
+
# else
|
|
183
|
+
# #print "\n"
|
|
184
|
+
# #print_h1 "DRY RUN"
|
|
185
|
+
# end
|
|
186
|
+
# end
|
|
187
|
+
puts "#{cyan}#{bold}#{dark}REQUEST#{reset}\n"
|
|
188
|
+
# print cyan
|
|
189
|
+
# print "Request: ", "\n"
|
|
190
|
+
# print reset
|
|
191
|
+
request_string = "#{http_method.to_s.upcase} #{url}".strip
|
|
123
192
|
print request_string, "\n"
|
|
124
193
|
print cyan
|
|
125
194
|
if payload
|
|
126
|
-
|
|
127
|
-
begin
|
|
128
|
-
payload = JSON.parse(payload)
|
|
129
|
-
rescue => e
|
|
130
|
-
#payload = "(unparsable) #{payload}"
|
|
131
|
-
end
|
|
132
|
-
end
|
|
195
|
+
|
|
133
196
|
print "\n"
|
|
134
|
-
if
|
|
135
|
-
|
|
136
|
-
|
|
197
|
+
if api_request[:headers] && api_request[:headers]['Content-Type'] == 'application/json'
|
|
198
|
+
if payload.is_a?(String)
|
|
199
|
+
begin
|
|
200
|
+
payload = JSON.parse(payload)
|
|
201
|
+
rescue => e
|
|
202
|
+
#payload = "(unparsable) #{payload}"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
puts "#{cyan}#{bold}#{dark}JSON#{reset}\n"
|
|
206
|
+
# print "JSON: ", "\n"
|
|
207
|
+
# print reset
|
|
137
208
|
print JSON.pretty_generate(payload)
|
|
138
209
|
else
|
|
139
|
-
|
|
140
|
-
|
|
210
|
+
content_type = api_request[:headers]['Content-Type'] || 'application/x-www-form-urlencoded'
|
|
211
|
+
print "Content-Type: #{content_type}", "\n"
|
|
212
|
+
# print "Body: ", "\n"
|
|
141
213
|
print reset
|
|
142
214
|
if payload.is_a?(File)
|
|
143
215
|
# pretty_size = Filesize.from("#{payload.size} B").pretty.strip
|
|
@@ -147,7 +219,17 @@ module Morpheus::Cli::PrintHelper
|
|
|
147
219
|
elsif payload.is_a?(String)
|
|
148
220
|
print payload
|
|
149
221
|
else
|
|
150
|
-
|
|
222
|
+
if content_type == 'application/x-www-form-urlencoded'
|
|
223
|
+
body_str = payload.to_s
|
|
224
|
+
begin
|
|
225
|
+
body_str = URI.encode_www_form(payload)
|
|
226
|
+
rescue => ex
|
|
227
|
+
# raise ex
|
|
228
|
+
end
|
|
229
|
+
print body_str
|
|
230
|
+
else
|
|
231
|
+
print payload
|
|
232
|
+
end
|
|
151
233
|
end
|
|
152
234
|
end
|
|
153
235
|
end
|
|
@@ -155,6 +237,82 @@ module Morpheus::Cli::PrintHelper
|
|
|
155
237
|
print reset
|
|
156
238
|
end
|
|
157
239
|
|
|
240
|
+
# format_curl_command generates a valid curl command for the given api request
|
|
241
|
+
# @param api_request [Hash] api request, typically returned from api_client.dry.execute()
|
|
242
|
+
# @param options [Hash] common cli options
|
|
243
|
+
# formats command like:
|
|
244
|
+
#
|
|
245
|
+
# curl -XPOST "https://api.gomorpheus.com/api/cypher" \
|
|
246
|
+
# -H "Authorization: BEARER ******************" \
|
|
247
|
+
# -H "Content-Type: application/json" \
|
|
248
|
+
# -d '{
|
|
249
|
+
# "value": "mysecret"
|
|
250
|
+
# }'
|
|
251
|
+
def format_curl_command(http_method, url, headers, payload=nil, options={})
|
|
252
|
+
options ||= {}
|
|
253
|
+
# build curl [options]
|
|
254
|
+
out = ""
|
|
255
|
+
out << "curl -X#{http_method.to_s.upcase} '#{url}'"
|
|
256
|
+
if headers
|
|
257
|
+
headers.each do |k,v|
|
|
258
|
+
# avoid weird [:headers][:params]
|
|
259
|
+
unless k == :params
|
|
260
|
+
header_value = v
|
|
261
|
+
out << ' \\' + "\n"
|
|
262
|
+
header_line = " -H \"#{k.is_a?(Symbol) ? k.to_s.capitalize : k.to_s}: #{v}\""
|
|
263
|
+
out << header_line
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
if payload && !payload.empty?
|
|
268
|
+
out << + ' \\' + "\n"
|
|
269
|
+
if headers && headers['Content-Type'] == 'application/json'
|
|
270
|
+
if payload.is_a?(String)
|
|
271
|
+
begin
|
|
272
|
+
payload = JSON.parse(payload)
|
|
273
|
+
rescue => e
|
|
274
|
+
#payload = "(unparsable) #{payload}"
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
if payload.is_a?(Hash)
|
|
278
|
+
out << " -d '#{as_json(payload, options)}'"
|
|
279
|
+
else
|
|
280
|
+
out << " -d '#{payload}'"
|
|
281
|
+
end
|
|
282
|
+
else
|
|
283
|
+
content_type = headers['Content-Type'] || 'application/x-www-form-urlencoded'
|
|
284
|
+
|
|
285
|
+
if payload.is_a?(File)
|
|
286
|
+
# pretty_size = Filesize.from("#{payload.size} B").pretty.strip
|
|
287
|
+
pretty_size = "#{payload.size} B"
|
|
288
|
+
# print "File: #{payload.path} (#{payload.size} bytes)"
|
|
289
|
+
out << " -d @#{payload.path}"
|
|
290
|
+
elsif payload.is_a?(String)
|
|
291
|
+
out << " -d '#{payload}'"
|
|
292
|
+
else
|
|
293
|
+
if content_type == 'application/x-www-form-urlencoded'
|
|
294
|
+
body_str = payload.to_s
|
|
295
|
+
begin
|
|
296
|
+
body_str = URI.encode_www_form(payload)
|
|
297
|
+
rescue => ex
|
|
298
|
+
# raise ex
|
|
299
|
+
end
|
|
300
|
+
out << " -d '#{body_str}'"
|
|
301
|
+
else
|
|
302
|
+
out << " -d '#{payload}'"
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
out << "\n"
|
|
307
|
+
else
|
|
308
|
+
out << "\n"
|
|
309
|
+
end
|
|
310
|
+
if options[:scrub]
|
|
311
|
+
out = Morpheus::Logging.scrub_message(out)
|
|
312
|
+
end
|
|
313
|
+
return out
|
|
314
|
+
|
|
315
|
+
end
|
|
158
316
|
def print_results_pagination(json_response, options={})
|
|
159
317
|
# print cyan,"\nViewing #{json_response['meta']['offset'].to_i + 1}-#{json_response['meta']['offset'].to_i + json_response['meta']['size'].to_i} of #{json_response['meta']['total']}\n", reset
|
|
160
318
|
print format_results_pagination(json_response, options)
|
|
@@ -473,7 +631,14 @@ module Morpheus::Cli::PrintHelper
|
|
|
473
631
|
end
|
|
474
632
|
|
|
475
633
|
# format header spacer row
|
|
476
|
-
|
|
634
|
+
if options[:border_style] == :thin
|
|
635
|
+
# a simpler looking table
|
|
636
|
+
cell_delim = " "
|
|
637
|
+
h_line = header_cells.collect {|cell| ("-" * cell.strip.size).ljust(cell.size, ' ') }.join(cell_delim)
|
|
638
|
+
else
|
|
639
|
+
# default border style
|
|
640
|
+
h_line = header_cells.collect {|cell| ("-" * cell.size) }.join(cell_delim.gsub(" ", "-"))
|
|
641
|
+
end
|
|
477
642
|
|
|
478
643
|
# format data rows
|
|
479
644
|
formatted_rows = []
|