morpheus-cli 3.5.2 → 3.5.3
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/api_client.rb +16 -0
- data/lib/morpheus/api/blueprints_interface.rb +84 -0
- data/lib/morpheus/api/execution_request_interface.rb +33 -0
- data/lib/morpheus/api/instances_interface.rb +21 -0
- data/lib/morpheus/api/packages_interface.rb +25 -5
- data/lib/morpheus/api/processes_interface.rb +34 -0
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +8 -0
- data/lib/morpheus/api/user_settings_interface.rb +76 -0
- data/lib/morpheus/cli.rb +5 -1
- data/lib/morpheus/cli/alias_command.rb +1 -1
- data/lib/morpheus/cli/app_templates.rb +2 -1
- data/lib/morpheus/cli/apps.rb +173 -19
- data/lib/morpheus/cli/blueprints_command.rb +2134 -0
- data/lib/morpheus/cli/cli_command.rb +3 -1
- data/lib/morpheus/cli/clouds.rb +4 -10
- data/lib/morpheus/cli/coloring_command.rb +14 -8
- data/lib/morpheus/cli/containers_command.rb +92 -5
- data/lib/morpheus/cli/execution_request_command.rb +313 -0
- data/lib/morpheus/cli/hosts.rb +188 -7
- data/lib/morpheus/cli/instances.rb +472 -9
- data/lib/morpheus/cli/login.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +8 -0
- data/lib/morpheus/cli/mixins/processes_helper.rb +134 -0
- data/lib/morpheus/cli/option_types.rb +21 -16
- data/lib/morpheus/cli/packages_command.rb +469 -17
- data/lib/morpheus/cli/processes_command.rb +313 -0
- data/lib/morpheus/cli/remote.rb +20 -9
- data/lib/morpheus/cli/roles.rb +186 -6
- data/lib/morpheus/cli/shell.rb +10 -1
- data/lib/morpheus/cli/tasks.rb +4 -1
- data/lib/morpheus/cli/user_settings_command.rb +431 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +1 -1
- data/lib/morpheus/formatters.rb +14 -0
- data/lib/morpheus/morpkg.rb +119 -0
- data/morpheus-cli.gemspec +1 -0
- metadata +26 -2
data/lib/morpheus/cli/shell.rb
CHANGED
@@ -530,7 +530,12 @@ class Morpheus::Cli::Shell
|
|
530
530
|
return Morpheus::Cli::SourceCommand.new.handle(input.split[1..-1])
|
531
531
|
end
|
532
532
|
cmd_result = nil
|
533
|
-
|
533
|
+
unless input =~ /log-level/
|
534
|
+
@return_to_log_level = Morpheus::Logging.log_level
|
535
|
+
end
|
536
|
+
unless input =~ /coloring/
|
537
|
+
@return_to_coloring = Term::ANSIColor::coloring?
|
538
|
+
end
|
534
539
|
begin
|
535
540
|
argv = Shellwords.shellsplit(input)
|
536
541
|
cmd_name = argv[0]
|
@@ -561,6 +566,10 @@ class Morpheus::Cli::Shell
|
|
561
566
|
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
562
567
|
@return_to_log_level = nil
|
563
568
|
end
|
569
|
+
if @return_to_coloring != nil
|
570
|
+
Term::ANSIColor::coloring = @return_to_coloring
|
571
|
+
@return_to_coloring = nil
|
572
|
+
end
|
564
573
|
end
|
565
574
|
|
566
575
|
# commands should be a number or nil (treated as 0)
|
data/lib/morpheus/cli/tasks.rb
CHANGED
@@ -24,15 +24,18 @@ class Morpheus::Cli::Tasks
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def list(args)
|
27
|
+
params = {}
|
27
28
|
options = {}
|
28
29
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
29
30
|
opts.banner = subcommand_usage()
|
31
|
+
opts.on('--types x,y,z', Array, "Filter by task type code(s)") do |val|
|
32
|
+
params['taskTypeCodes'] = val
|
33
|
+
end
|
30
34
|
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
31
35
|
end
|
32
36
|
optparse.parse!(args)
|
33
37
|
connect(options)
|
34
38
|
begin
|
35
|
-
params = {}
|
36
39
|
params.merge!(parse_list_options(options))
|
37
40
|
if options[:dry_run]
|
38
41
|
print_dry_run @tasks_interface.dry.get(params)
|
@@ -0,0 +1,431 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
class Morpheus::Cli::UserSettingsCommand
|
4
|
+
include Morpheus::Cli::CliCommand
|
5
|
+
|
6
|
+
set_command_name :'user-settings'
|
7
|
+
|
8
|
+
register_subcommands :get, :update, :'update-avatar', :'view-avatar', :'regenerate-access-token', :'clear-access-token', :'list-clients'
|
9
|
+
|
10
|
+
set_default_subcommand :get
|
11
|
+
|
12
|
+
def initialize()
|
13
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect(opts)
|
17
|
+
@api_client = establish_remote_appliance_connection(opts)
|
18
|
+
@user_settings_interface = @api_client.user_settings
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle(args)
|
22
|
+
handle_subcommand(args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(args)
|
26
|
+
raw_args = args
|
27
|
+
options = {}
|
28
|
+
params = {}
|
29
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
30
|
+
opts.banner = subcommand_usage()
|
31
|
+
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
32
|
+
opts.footer = "Get your user settings."
|
33
|
+
end
|
34
|
+
optparse.parse!(args)
|
35
|
+
connect(options)
|
36
|
+
if args.count != 0
|
37
|
+
print_error Morpheus::Terminal.angry_prompt
|
38
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
39
|
+
return 1
|
40
|
+
end
|
41
|
+
|
42
|
+
begin
|
43
|
+
params.merge!(parse_list_options(options))
|
44
|
+
if options[:dry_run]
|
45
|
+
print_dry_run @user_settings_interface.dry.get(params)
|
46
|
+
return
|
47
|
+
end
|
48
|
+
json_response = @user_settings_interface.get(params)
|
49
|
+
if options[:json]
|
50
|
+
puts as_json(json_response, options, "user")
|
51
|
+
return 0
|
52
|
+
elsif options[:yaml]
|
53
|
+
puts as_yaml(json_response, options, "user")
|
54
|
+
return 0
|
55
|
+
elsif options[:csv]
|
56
|
+
puts records_as_csv([json_response['user']], options)
|
57
|
+
return 0
|
58
|
+
end
|
59
|
+
|
60
|
+
user_settings = json_response['user'] || json_response['userSettings']
|
61
|
+
access_tokens = user_settings['accessTokens'] || json_response['accessTokens'] || json_response['apiAccessTokens'] || []
|
62
|
+
|
63
|
+
print_h1 "User Settings"
|
64
|
+
print cyan
|
65
|
+
description_cols = {
|
66
|
+
#"ID" => lambda {|it| it['id'] },
|
67
|
+
"ID" => lambda {|it| it['id'] },
|
68
|
+
"Username" => lambda {|it| it['username'] },
|
69
|
+
"First Name" => lambda {|it| it['firstName'] },
|
70
|
+
"Last Name" => lambda {|it| it['lastName'] },
|
71
|
+
"Email" => lambda {|it| it['email'] },
|
72
|
+
"Avatar" => lambda {|it| it['avatar'] ? it['avatar'].split('/').last : '' },
|
73
|
+
"Notifications" => lambda {|it| format_boolean(it['receiveNotifications']) },
|
74
|
+
"Linux Username" => lambda {|it| it['linuxUsername'] },
|
75
|
+
"Linux Password" => lambda {|it| it['linuxPassword'] },
|
76
|
+
"Linux Key Pair" => lambda {|it| it['linuxKeyPairId'] },
|
77
|
+
"Windows Username" => lambda {|it| it['windowsUsername'] },
|
78
|
+
"Windows Password" => lambda {|it| it['windowsPassword'] },
|
79
|
+
}
|
80
|
+
print_description_list(description_cols, user_settings)
|
81
|
+
|
82
|
+
if access_tokens && !access_tokens.empty?
|
83
|
+
print_h2 "API Access Tokens"
|
84
|
+
cols = {
|
85
|
+
#"ID" => lambda {|it| it['id'] },
|
86
|
+
"Client ID" => lambda {|it| it['clientId'] },
|
87
|
+
"Username" => lambda {|it| it['username'] },
|
88
|
+
"Expiration" => lambda {|it| format_local_dt(it['expiration']) }
|
89
|
+
}
|
90
|
+
print cyan
|
91
|
+
puts as_pretty_table(access_tokens, cols)
|
92
|
+
end
|
93
|
+
|
94
|
+
print reset #, "\n"
|
95
|
+
return 0
|
96
|
+
rescue RestClient::Exception => e
|
97
|
+
print_rest_exception(e, options)
|
98
|
+
return 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def update(args)
|
104
|
+
raw_args = args
|
105
|
+
options = {}
|
106
|
+
params = {}
|
107
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
108
|
+
opts.banner = subcommand_usage("[options]")
|
109
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
110
|
+
opts.footer = "Update your user settings."
|
111
|
+
end
|
112
|
+
optparse.parse!(args)
|
113
|
+
connect(options)
|
114
|
+
if args.count != 0
|
115
|
+
print_error Morpheus::Terminal.angry_prompt
|
116
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
117
|
+
return 1
|
118
|
+
end
|
119
|
+
|
120
|
+
begin
|
121
|
+
payload = {}
|
122
|
+
if options[:payload]
|
123
|
+
payload = options[:payload]
|
124
|
+
else
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
if options[:options]
|
129
|
+
payload['user'] ||= {}
|
130
|
+
payload['user'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) })
|
131
|
+
end
|
132
|
+
|
133
|
+
if options[:dry_run]
|
134
|
+
print_dry_run @user_settings_interface.dry.update(params, payload)
|
135
|
+
return
|
136
|
+
end
|
137
|
+
json_response = @user_settings_interface.update(params, payload)
|
138
|
+
if options[:quiet]
|
139
|
+
return 0
|
140
|
+
elsif options[:json]
|
141
|
+
puts as_json(json_response, options)
|
142
|
+
return 0
|
143
|
+
end
|
144
|
+
|
145
|
+
print_green_success "Updated user settings"
|
146
|
+
get([])
|
147
|
+
return 0
|
148
|
+
rescue RestClient::Exception => e
|
149
|
+
print_rest_exception(e, options)
|
150
|
+
return 1
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_avatar(args)
|
155
|
+
options = {}
|
156
|
+
params = {}
|
157
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
158
|
+
opts.banner = subcommand_usage("[file]")
|
159
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
160
|
+
opts.footer = "Update your avatar profile image.\n" +
|
161
|
+
"[file] is required. This is the local path of a file to upload [png|jpg|svg]."
|
162
|
+
end
|
163
|
+
optparse.parse!(args)
|
164
|
+
connect(options)
|
165
|
+
if args.count != 1
|
166
|
+
print_error Morpheus::Terminal.angry_prompt
|
167
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
168
|
+
return 1
|
169
|
+
end
|
170
|
+
filename = File.expand_path(args[0].to_s)
|
171
|
+
image_file = nil
|
172
|
+
if filename && File.file?(filename)
|
173
|
+
# maybe validate it's an image file? [.png|jpg|svg]
|
174
|
+
image_file = File.new(filename, 'rb')
|
175
|
+
else
|
176
|
+
# print_red_alert "File not found: #{filename}"
|
177
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}File not found: #{filename}"
|
178
|
+
return 1
|
179
|
+
end
|
180
|
+
|
181
|
+
begin
|
182
|
+
if options[:dry_run]
|
183
|
+
print_dry_run @user_settings_interface.dry.update_avatar(image_file, params)
|
184
|
+
return
|
185
|
+
end
|
186
|
+
json_response = @user_settings_interface.update_avatar(image_file, params)
|
187
|
+
if options[:quiet]
|
188
|
+
return 0
|
189
|
+
elsif options[:json]
|
190
|
+
puts as_json(json_response, options)
|
191
|
+
return 0
|
192
|
+
end
|
193
|
+
|
194
|
+
print_green_success "Updated avatar"
|
195
|
+
get([])
|
196
|
+
return 0
|
197
|
+
rescue RestClient::Exception => e
|
198
|
+
print_rest_exception(e, options)
|
199
|
+
return 1
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def remove_avatar(args)
|
204
|
+
options = {}
|
205
|
+
params = {}
|
206
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
207
|
+
opts.banner = subcommand_usage("[file]")
|
208
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
209
|
+
opts.footer = "Remove your avatar profile image."
|
210
|
+
end
|
211
|
+
optparse.parse!(args)
|
212
|
+
connect(options)
|
213
|
+
if args.count != 0
|
214
|
+
print_error Morpheus::Terminal.angry_prompt
|
215
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
216
|
+
return 1
|
217
|
+
end
|
218
|
+
|
219
|
+
begin
|
220
|
+
if options[:dry_run]
|
221
|
+
print_dry_run @user_settings_interface.dry.remove_avatar(params)
|
222
|
+
return
|
223
|
+
end
|
224
|
+
json_response = @user_settings_interface.remove_avatar(params)
|
225
|
+
if options[:quiet]
|
226
|
+
return 0
|
227
|
+
elsif options[:json]
|
228
|
+
puts as_json(json_response, options)
|
229
|
+
return 0
|
230
|
+
end
|
231
|
+
|
232
|
+
print_green_success "Removed avatar"
|
233
|
+
get([])
|
234
|
+
return 0
|
235
|
+
rescue RestClient::Exception => e
|
236
|
+
print_rest_exception(e, options)
|
237
|
+
return 1
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def view_avatar(args)
|
242
|
+
raw_args = args
|
243
|
+
options = {}
|
244
|
+
params = {}
|
245
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
246
|
+
opts.banner = subcommand_usage()
|
247
|
+
build_common_options(opts, options, [:remote])
|
248
|
+
opts.footer = "View your avatar profile image.\n" +
|
249
|
+
"This opens the avatar image url with a web browser."
|
250
|
+
end
|
251
|
+
optparse.parse!(args)
|
252
|
+
connect(options)
|
253
|
+
if args.count != 0
|
254
|
+
print_error Morpheus::Terminal.angry_prompt
|
255
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
256
|
+
return 1
|
257
|
+
end
|
258
|
+
|
259
|
+
begin
|
260
|
+
|
261
|
+
json_response = @user_settings_interface.get(params)
|
262
|
+
user_settings = json_response['user'] || json_response['userSettings']
|
263
|
+
|
264
|
+
if user_settings['avatar']
|
265
|
+
link = user_settings['avatar']
|
266
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
267
|
+
system "start #{link}"
|
268
|
+
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
|
269
|
+
system "open #{link}"
|
270
|
+
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
|
271
|
+
system "xdg-open #{link}"
|
272
|
+
end
|
273
|
+
return 0, nil
|
274
|
+
else
|
275
|
+
print_error red,"No avatar image found.",reset,"\n"
|
276
|
+
return 1
|
277
|
+
end
|
278
|
+
|
279
|
+
rescue RestClient::Exception => e
|
280
|
+
print_rest_exception(e, options)
|
281
|
+
return 1
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def regenerate_access_token(args)
|
286
|
+
raw_args = args
|
287
|
+
options = {}
|
288
|
+
params = {}
|
289
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
290
|
+
opts.banner = subcommand_usage("[client-id]")
|
291
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
292
|
+
opts.footer = "Regenerate API access token for a specific client.\n" +
|
293
|
+
"[client-id] is required. This is the id of an api client."
|
294
|
+
end
|
295
|
+
optparse.parse!(args)
|
296
|
+
connect(options)
|
297
|
+
if args.count != 1
|
298
|
+
print_error Morpheus::Terminal.angry_prompt
|
299
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
300
|
+
return 1
|
301
|
+
end
|
302
|
+
params['clientId'] = args[0]
|
303
|
+
begin
|
304
|
+
payload = {}
|
305
|
+
if options[:dry_run]
|
306
|
+
print_dry_run @user_settings_interface.dry.regenerate_access_token(params, payload)
|
307
|
+
return
|
308
|
+
end
|
309
|
+
json_response = @user_settings_interface.regenerate_access_token(params, payload)
|
310
|
+
new_access_token = json_response['token']
|
311
|
+
# update credentials if regenerating cli token
|
312
|
+
if params['clientId'] == 'morph-cli'
|
313
|
+
if new_access_token
|
314
|
+
login_opts = {:remote_token => new_access_token}
|
315
|
+
login_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).login(login_opts)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
if options[:quiet]
|
319
|
+
return 0
|
320
|
+
elsif options[:json]
|
321
|
+
puts as_json(json_response, options)
|
322
|
+
return 0
|
323
|
+
end
|
324
|
+
print_green_success "Regenerated #{params['clientId']} access token: #{new_access_token}"
|
325
|
+
get([])
|
326
|
+
return 0
|
327
|
+
rescue RestClient::Exception => e
|
328
|
+
print_rest_exception(e, options)
|
329
|
+
return 1
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def clear_access_token(args)
|
334
|
+
raw_args = args
|
335
|
+
options = {}
|
336
|
+
params = {}
|
337
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
338
|
+
opts.banner = subcommand_usage("[client-id]")
|
339
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
340
|
+
opts.footer = "Clear API access token for a specific client.\n" +
|
341
|
+
"[client-id] is required. This is the id of an api client."
|
342
|
+
end
|
343
|
+
optparse.parse!(args)
|
344
|
+
connect(options)
|
345
|
+
if args.count != 1
|
346
|
+
print_error Morpheus::Terminal.angry_prompt
|
347
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
348
|
+
return 1
|
349
|
+
end
|
350
|
+
params['clientId'] = args[0]
|
351
|
+
begin
|
352
|
+
payload = {}
|
353
|
+
if options[:dry_run]
|
354
|
+
print_dry_run @user_settings_interface.dry.clear_access_token(params, payload)
|
355
|
+
return
|
356
|
+
end
|
357
|
+
json_response = @user_settings_interface.clear_access_token(params, payload)
|
358
|
+
if options[:quiet]
|
359
|
+
return 0
|
360
|
+
elsif options[:json]
|
361
|
+
puts as_json(json_response, options)
|
362
|
+
return 0
|
363
|
+
end
|
364
|
+
new_access_token = json_response['token']
|
365
|
+
# update credentials if regenerating cli token
|
366
|
+
# if params['clientId'] == 'morph-cli'
|
367
|
+
# logout_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).logout
|
368
|
+
# end
|
369
|
+
print_green_success "Cleared #{params['clientId']} access token"
|
370
|
+
if params['clientId'] == 'morph-cli'
|
371
|
+
print yellow,"Your current access token is no longer valid, you will need to login again.",reset,"\n"
|
372
|
+
end
|
373
|
+
#get([])
|
374
|
+
return 0
|
375
|
+
rescue RestClient::Exception => e
|
376
|
+
print_rest_exception(e, options)
|
377
|
+
return 1
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
def list_clients(args)
|
382
|
+
raw_args = args
|
383
|
+
options = {}
|
384
|
+
params = {}
|
385
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
386
|
+
opts.banner = subcommand_usage()
|
387
|
+
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
388
|
+
opts.footer = "List available api clients."
|
389
|
+
end
|
390
|
+
optparse.parse!(args)
|
391
|
+
connect(options)
|
392
|
+
if args.count != 0
|
393
|
+
print_error Morpheus::Terminal.angry_prompt
|
394
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
395
|
+
return 1
|
396
|
+
end
|
397
|
+
|
398
|
+
begin
|
399
|
+
params.merge!(parse_list_options(options))
|
400
|
+
if options[:dry_run]
|
401
|
+
print_dry_run @user_settings_interface.dry.available_clients(params)
|
402
|
+
return
|
403
|
+
end
|
404
|
+
json_response = @user_settings_interface.available_clients(params)
|
405
|
+
if options[:json]
|
406
|
+
puts as_json(json_response, options, "clients")
|
407
|
+
return 0
|
408
|
+
elsif options[:yaml]
|
409
|
+
puts as_yaml(json_response, options, "clients")
|
410
|
+
return 0
|
411
|
+
elsif options[:csv]
|
412
|
+
puts records_as_csv(json_response['clients'], options)
|
413
|
+
return 0
|
414
|
+
end
|
415
|
+
|
416
|
+
clients = json_response['clients'] || json_response['apiClients']
|
417
|
+
print_h1 "Morpheus API Clients"
|
418
|
+
columns = {
|
419
|
+
"Client ID" => lambda {|it| it['clientId'] }
|
420
|
+
}
|
421
|
+
print cyan
|
422
|
+
puts as_pretty_table(clients, columns)
|
423
|
+
print reset #, "\n"
|
424
|
+
return 0
|
425
|
+
rescue RestClient::Exception => e
|
426
|
+
print_rest_exception(e, options)
|
427
|
+
return 1
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
end
|