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/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 = []
|