morpheus-cli 4.2.8 → 4.2.10
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/Dockerfile +1 -1
- data/lib/morpheus/api.rb +1 -1
- data/lib/morpheus/api/activity_interface.rb +9 -0
- data/lib/morpheus/api/api_client.rb +83 -27
- data/lib/morpheus/api/apps_interface.rb +21 -0
- data/lib/morpheus/api/dashboard_interface.rb +5 -21
- data/lib/morpheus/api/instances_interface.rb +3 -10
- data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
- data/lib/morpheus/api/invoices_interface.rb +7 -12
- data/lib/morpheus/api/library_layouts_interface.rb +8 -0
- data/lib/morpheus/api/ping_interface.rb +20 -0
- data/lib/morpheus/api/projects_interface.rb +33 -0
- data/lib/morpheus/api/setup_interface.rb +19 -36
- data/lib/morpheus/api/user_settings_interface.rb +0 -6
- data/lib/morpheus/api/whoami_interface.rb +4 -8
- data/lib/morpheus/benchmarking.rb +16 -26
- data/lib/morpheus/cli.rb +10 -5
- data/lib/morpheus/cli/access_token_command.rb +5 -8
- data/lib/morpheus/cli/activity_command.rb +146 -0
- data/lib/morpheus/cli/apps.rb +312 -121
- data/lib/morpheus/cli/archives_command.rb +1 -1
- data/lib/morpheus/cli/auth_command.rb +4 -11
- data/lib/morpheus/cli/blueprints_command.rb +196 -137
- data/lib/morpheus/cli/change_password_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +225 -72
- data/lib/morpheus/cli/cli_registry.rb +2 -2
- data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
- data/lib/morpheus/cli/clouds.rb +5 -20
- data/lib/morpheus/cli/clusters.rb +4 -28
- data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
- data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
- data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
- data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
- data/lib/morpheus/cli/containers_command.rb +3 -3
- data/lib/morpheus/cli/credentials.rb +13 -16
- data/lib/morpheus/cli/error_handler.rb +18 -12
- data/lib/morpheus/cli/errors.rb +45 -0
- data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
- data/lib/morpheus/cli/execution_request_command.rb +4 -4
- data/lib/morpheus/cli/groups.rb +84 -132
- data/lib/morpheus/cli/hosts.rb +6 -16
- data/lib/morpheus/cli/instances.rb +100 -183
- data/lib/morpheus/cli/invoices_command.rb +505 -71
- data/lib/morpheus/cli/library_layouts_command.rb +254 -166
- data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
- data/lib/morpheus/cli/library_option_types_command.rb +0 -96
- data/lib/morpheus/cli/license.rb +3 -0
- data/lib/morpheus/cli/login.rb +17 -37
- data/lib/morpheus/cli/logout.rb +9 -5
- data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
- data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
- data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
- data/lib/morpheus/cli/network_groups_command.rb +8 -2
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/ping.rb +252 -0
- data/lib/morpheus/cli/price_sets_command.rb +16 -27
- data/lib/morpheus/cli/prices_command.rb +34 -27
- data/lib/morpheus/cli/processes_command.rb +81 -7
- data/lib/morpheus/cli/projects_command.rb +607 -0
- data/lib/morpheus/cli/recent_activity_command.rb +87 -65
- data/lib/morpheus/cli/remote.rb +965 -974
- data/lib/morpheus/cli/reports_command.rb +3 -15
- data/lib/morpheus/cli/roles.rb +8 -31
- data/lib/morpheus/cli/service_plans_command.rb +25 -31
- data/lib/morpheus/cli/setup.rb +392 -0
- data/lib/morpheus/cli/shell.rb +144 -56
- data/lib/morpheus/cli/subnets_command.rb +71 -11
- data/lib/morpheus/cli/tasks.rb +3 -3
- data/lib/morpheus/cli/user_sources_command.rb +4 -4
- data/lib/morpheus/cli/users.rb +135 -109
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
- data/lib/morpheus/cli/whoami.rb +90 -129
- data/lib/morpheus/cli/wiki_command.rb +2 -14
- data/lib/morpheus/ext/rest_client.rb +36 -0
- data/lib/morpheus/formatters.rb +42 -5
- data/lib/morpheus/rest_client.rb +0 -10
- data/lib/morpheus/terminal.rb +41 -1
- data/lib/morpheus/util.rb +24 -0
- metadata +16 -3
- data/lib/morpheus/cli/command_error.rb +0 -22
|
@@ -355,93 +355,6 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
|
355
355
|
|
|
356
356
|
private
|
|
357
357
|
|
|
358
|
-
def find_instance_type_by_name_or_id(val)
|
|
359
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
|
360
|
-
return find_instance_type_by_id(val)
|
|
361
|
-
else
|
|
362
|
-
return find_instance_type_by_name(val)
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
def find_instance_type_by_id(id)
|
|
367
|
-
begin
|
|
368
|
-
json_response = @library_instance_types_interface.get(id.to_i)
|
|
369
|
-
return json_response['instanceType']
|
|
370
|
-
rescue RestClient::Exception => e
|
|
371
|
-
if e.response && e.response.code == 404
|
|
372
|
-
print_red_alert "Instance Type not found by id #{id}"
|
|
373
|
-
else
|
|
374
|
-
raise e
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
def find_instance_type_by_name(name)
|
|
380
|
-
json_response = @library_instance_types_interface.list({name: name.to_s})
|
|
381
|
-
instance_types = json_response['instanceTypes']
|
|
382
|
-
if instance_types.empty?
|
|
383
|
-
print_red_alert "Instance Type not found by name #{name}"
|
|
384
|
-
return nil
|
|
385
|
-
elsif instance_types.size > 1
|
|
386
|
-
print_red_alert "#{instance_types.size} instance types found by name #{name}"
|
|
387
|
-
print_instance_types_table(instance_types, {color: red})
|
|
388
|
-
print_red_alert "Try using ID instead"
|
|
389
|
-
print reset,"\n"
|
|
390
|
-
return nil
|
|
391
|
-
else
|
|
392
|
-
return instance_types[0]
|
|
393
|
-
end
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
def print_instance_types_table(instance_types, opts={})
|
|
397
|
-
columns = [
|
|
398
|
-
{"ID" => lambda {|instance_type| instance_type['id'] } },
|
|
399
|
-
{"NAME" => lambda {|instance_type| instance_type['name'] } },
|
|
400
|
-
{"CODE" => lambda {|instance_type| instance_type['code'] } },
|
|
401
|
-
{"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
|
|
402
|
-
{"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
|
|
403
|
-
{"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
|
|
404
|
-
{"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
|
|
405
|
-
]
|
|
406
|
-
if opts[:include_fields]
|
|
407
|
-
columns = opts[:include_fields]
|
|
408
|
-
end
|
|
409
|
-
print as_pretty_table(instance_types, columns, opts)
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
def format_instance_type_technology(instance_type)
|
|
413
|
-
if instance_type
|
|
414
|
-
instance_type['provisionTypeCode'].to_s.capitalize
|
|
415
|
-
else
|
|
416
|
-
""
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
def add_instance_type_option_types
|
|
421
|
-
[
|
|
422
|
-
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
|
423
|
-
{'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2, 'description' => 'Useful shortcode for provisioning naming schemes and export reference.'},
|
|
424
|
-
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 3},
|
|
425
|
-
{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'optionSource' => 'categories', 'required' => true, 'displayOrder' => 4},
|
|
426
|
-
{'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 5},
|
|
427
|
-
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 6},
|
|
428
|
-
{'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 7, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
|
|
429
|
-
{'fieldName' => 'hasSettings', 'fieldLabel' => 'Enable Settings', 'type' => 'checkbox', 'displayOrder' => 8},
|
|
430
|
-
{'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 9},
|
|
431
|
-
{'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 10, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
|
|
432
|
-
]
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
def update_instance_type_option_types(instance_type=nil)
|
|
436
|
-
opts = add_instance_type_option_types
|
|
437
|
-
opts = opts.reject {|it| ["logo"].include? it['fieldName'] }
|
|
438
|
-
if instance_type
|
|
439
|
-
opts = add_instance_type_option_types
|
|
440
|
-
opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
|
|
441
|
-
end
|
|
442
|
-
opts
|
|
443
|
-
end
|
|
444
|
-
|
|
445
358
|
def find_option_type_list_by_name_or_id(val)
|
|
446
359
|
if val.to_s =~ /\A\d{1,}\Z/
|
|
447
360
|
return find_option_type_list_by_id(val)
|
|
@@ -289,102 +289,6 @@ class Morpheus::Cli::LibraryOptionTypesCommand
|
|
|
289
289
|
|
|
290
290
|
private
|
|
291
291
|
|
|
292
|
-
def find_instance_type_by_name_or_id(val)
|
|
293
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
|
294
|
-
return find_instance_type_by_id(val)
|
|
295
|
-
else
|
|
296
|
-
return find_instance_type_by_name(val)
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
def find_instance_type_by_id(id)
|
|
301
|
-
begin
|
|
302
|
-
json_response = @library_instance_types_interface.get(id.to_i)
|
|
303
|
-
return json_response['instanceType']
|
|
304
|
-
rescue RestClient::Exception => e
|
|
305
|
-
if e.response && e.response.code == 404
|
|
306
|
-
print_red_alert "Instance Type not found by id #{id}"
|
|
307
|
-
else
|
|
308
|
-
raise e
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
def find_instance_type_by_name(name)
|
|
314
|
-
json_response = @library_instance_types_interface.list({name: name.to_s})
|
|
315
|
-
instance_types = json_response['instanceTypes']
|
|
316
|
-
if instance_types.empty?
|
|
317
|
-
print_red_alert "Instance Type not found by name #{name}"
|
|
318
|
-
return nil
|
|
319
|
-
elsif instance_types.size > 1
|
|
320
|
-
print_red_alert "#{instance_types.size} instance types found by name #{name}"
|
|
321
|
-
print_instance_types_table(instance_types, {color: red})
|
|
322
|
-
print_red_alert "Try using ID instead"
|
|
323
|
-
print reset,"\n"
|
|
324
|
-
return nil
|
|
325
|
-
else
|
|
326
|
-
return instance_types[0]
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def print_instance_types_table(instance_types, opts={})
|
|
331
|
-
columns = [
|
|
332
|
-
{"ID" => lambda {|instance_type| instance_type['id'] } },
|
|
333
|
-
{"NAME" => lambda {|instance_type| instance_type['name'] } },
|
|
334
|
-
{"CODE" => lambda {|instance_type| instance_type['code'] } },
|
|
335
|
-
{"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
|
|
336
|
-
{"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
|
|
337
|
-
{"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
|
|
338
|
-
{"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
|
|
339
|
-
]
|
|
340
|
-
if opts[:include_fields]
|
|
341
|
-
columns = opts[:include_fields]
|
|
342
|
-
end
|
|
343
|
-
print as_pretty_table(instance_types, columns, opts)
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
def format_instance_type_technology(instance_type)
|
|
347
|
-
if instance_type
|
|
348
|
-
instance_type['provisionTypeCode'].to_s.capitalize
|
|
349
|
-
else
|
|
350
|
-
""
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
def add_instance_type_option_types
|
|
355
|
-
[
|
|
356
|
-
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
|
357
|
-
{'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2, 'description' => 'Useful shortcode for provisioning naming schemes and export reference.'},
|
|
358
|
-
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 3},
|
|
359
|
-
{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'optionSource' => 'categories', 'required' => true, 'displayOrder' => 4},
|
|
360
|
-
{'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 5},
|
|
361
|
-
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 6},
|
|
362
|
-
{'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 7, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
|
|
363
|
-
{'fieldName' => 'hasSettings', 'fieldLabel' => 'Enable Settings', 'type' => 'checkbox', 'displayOrder' => 8},
|
|
364
|
-
{'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 9},
|
|
365
|
-
{'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 10, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
|
|
366
|
-
]
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
def update_instance_type_option_types(instance_type=nil)
|
|
370
|
-
opts = add_instance_type_option_types
|
|
371
|
-
opts = opts.reject {|it| ["logo"].include? it['fieldName'] }
|
|
372
|
-
if instance_type
|
|
373
|
-
opts = add_instance_type_option_types
|
|
374
|
-
opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
|
|
375
|
-
end
|
|
376
|
-
opts
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
def load_balance_protocols
|
|
380
|
-
[
|
|
381
|
-
{'name' => 'None', 'value' => ''},
|
|
382
|
-
{'name' => 'HTTP', 'value' => 'HTTP'},
|
|
383
|
-
{'name' => 'HTTPS', 'value' => 'HTTPS'},
|
|
384
|
-
{'name' => 'TCP', 'value' => 'TCP'}
|
|
385
|
-
]
|
|
386
|
-
end
|
|
387
|
-
|
|
388
292
|
# finders are in LibraryHelper
|
|
389
293
|
|
|
390
294
|
# lol
|
data/lib/morpheus/cli/license.rb
CHANGED
data/lib/morpheus/cli/login.rb
CHANGED
|
@@ -14,7 +14,7 @@ class Morpheus::Cli::Login
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def connect(opts)
|
|
17
|
-
|
|
17
|
+
# @api_client = establish_remote_appliance_connection({:skip_verify_access_token => true, :skip_login => true}.merge(opts))
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def usage
|
|
@@ -47,47 +47,27 @@ class Morpheus::Cli::Login
|
|
|
47
47
|
options[:remote_token] = val
|
|
48
48
|
end
|
|
49
49
|
build_common_options(opts, options, [:json, :dry_run, :remote, :quiet], [:remote_username, :remote_password, :remote_token])
|
|
50
|
-
opts.footer =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
opts.footer = <<-EOT
|
|
51
|
+
Login to a remote appliance with a username and password or using an access token.
|
|
52
|
+
Logging in with username and password will make an authentication api request to obtain an access token.
|
|
53
|
+
The --token option can be used to login with a valid access token instead of username and password.
|
|
54
|
+
The specified token will be verified by making a whoami api request
|
|
55
|
+
If successful, the access token will be saved with the active session for the remote appliance.
|
|
56
|
+
This command will first logout any active session before attempting authorization.
|
|
57
|
+
The --test option is available for testing credentials without updating your active session, neithing logging you out or in.
|
|
58
|
+
EOT
|
|
59
59
|
|
|
60
60
|
end
|
|
61
61
|
optparse.parse!(args)
|
|
62
|
-
|
|
63
|
-
print_error Morpheus::Terminal.angry_prompt
|
|
64
|
-
puts_error "#{command_name} list expects 0-2 arguments and received #{args.count}: #{args}\n#{optparse}"
|
|
65
|
-
return 1
|
|
66
|
-
end
|
|
62
|
+
verify_args!(args:args, max:2, optparse:optparse)
|
|
67
63
|
username = args[0] if args[0]
|
|
68
64
|
password = args[1] if args[1]
|
|
69
65
|
|
|
70
66
|
# connect(options)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
else
|
|
76
|
-
@appliance_name, @appliance_url = nil, nil
|
|
77
|
-
end
|
|
78
|
-
if !@appliance_name
|
|
79
|
-
print_error red, "You have no appliance named '#{options[:remote]}' configured. See the `remote list` command.", reset, "\n"
|
|
80
|
-
return 1
|
|
81
|
-
end
|
|
82
|
-
elsif options[:remote_url]
|
|
83
|
-
# --remote-url
|
|
84
|
-
@appliance_name, @appliance_url = nil, appliance[:remote_url]
|
|
85
|
-
else
|
|
86
|
-
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
87
|
-
if !@appliance_name
|
|
88
|
-
print_error yellow, "Please specify a remote appliance with -r or see the command `remote use`", reset, "\n"
|
|
89
|
-
return 1
|
|
90
|
-
end
|
|
67
|
+
@api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
|
|
68
|
+
|
|
69
|
+
if @remote_appliance[:authenticated]
|
|
70
|
+
puts "You will be automatically logged out of your current session as '#{@remote_appliance[:username]}'"
|
|
91
71
|
end
|
|
92
72
|
|
|
93
73
|
begin
|
|
@@ -124,9 +104,9 @@ class Morpheus::Cli::Login
|
|
|
124
104
|
# Login Success!
|
|
125
105
|
if !options[:quiet]
|
|
126
106
|
if options[:test_only]
|
|
127
|
-
print green,"Success! Credentials verified for #{wallet['username']}
|
|
107
|
+
print green,"Success! Test Credentials verified for #{wallet['username']}", reset, "\n"
|
|
128
108
|
else
|
|
129
|
-
print green,"Success! Logged in
|
|
109
|
+
print green,"Success! Logged in as #{wallet['username']}", reset, "\n"
|
|
130
110
|
end
|
|
131
111
|
end
|
|
132
112
|
return 0 # , nil
|
data/lib/morpheus/cli/logout.rb
CHANGED
|
@@ -15,8 +15,8 @@ class Morpheus::Cli::Logout
|
|
|
15
15
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def connect(
|
|
19
|
-
|
|
18
|
+
def connect(options)
|
|
19
|
+
@api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def usage
|
|
@@ -32,12 +32,16 @@ class Morpheus::Cli::Logout
|
|
|
32
32
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
33
33
|
opts.banner = usage
|
|
34
34
|
build_common_options(opts, options, [:remote, :quiet])
|
|
35
|
+
opts.footer = <<-EOT
|
|
36
|
+
Logout of a remote appliance.
|
|
37
|
+
This clears your credentials so that you will need to login again.
|
|
38
|
+
EOT
|
|
35
39
|
end
|
|
36
40
|
optparse.parse!(args)
|
|
37
|
-
|
|
41
|
+
verify_args!(args:args,count:0,optpare:optparse)
|
|
42
|
+
connect(options)
|
|
38
43
|
# establish @appliance_name, @appliance_url,
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
#@api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
|
|
41
45
|
begin
|
|
42
46
|
if !@appliance_name
|
|
43
47
|
print_error Morpheus::Terminal.angry_prompt
|
|
@@ -317,6 +317,8 @@ module Morpheus::Cli::AccountsHelper
|
|
|
317
317
|
#print reset if table_color
|
|
318
318
|
end
|
|
319
319
|
|
|
320
|
+
## These user access formatted methods should probably move up to PrintHelper to be more ubiquitous.
|
|
321
|
+
|
|
320
322
|
def format_user_role_names(user)
|
|
321
323
|
role_names = ""
|
|
322
324
|
if user && user['roles']
|
|
@@ -327,15 +329,89 @@ module Morpheus::Cli::AccountsHelper
|
|
|
327
329
|
role_names
|
|
328
330
|
end
|
|
329
331
|
|
|
330
|
-
def
|
|
331
|
-
|
|
332
|
-
if
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
332
|
+
def get_access_color(access)
|
|
333
|
+
access ||= 'none'
|
|
334
|
+
if access == 'none'
|
|
335
|
+
# maybe reset instead of white?
|
|
336
|
+
white
|
|
337
|
+
elsif access == 'read'
|
|
338
|
+
cyan
|
|
339
|
+
else
|
|
340
|
+
green
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def get_access_string(access, return_color=cyan)
|
|
345
|
+
get_access_color(access) + access + return_color
|
|
346
|
+
# access ||= 'none'
|
|
347
|
+
# if access == 'none'
|
|
348
|
+
# "#{white}#{access.to_s}#{return_color}"
|
|
349
|
+
# elsif access == 'read'
|
|
350
|
+
# "#{cyan}#{access.to_s.capitalize}#{return_color}"
|
|
351
|
+
# else
|
|
352
|
+
# "#{green}#{access.to_s}#{return_color}"
|
|
353
|
+
# end
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# this outputs a string that matches the length of all available access levels
|
|
357
|
+
# for outputting in a grid that looks like this:
|
|
358
|
+
#
|
|
359
|
+
# none
|
|
360
|
+
# full
|
|
361
|
+
# full
|
|
362
|
+
# user
|
|
363
|
+
# read
|
|
364
|
+
# full
|
|
365
|
+
# none
|
|
366
|
+
#
|
|
367
|
+
# Examples: format_permission_access("read")
|
|
368
|
+
# format_permission_access("custom", "full,custom,none")
|
|
369
|
+
def format_access_string(access, access_levels=nil, return_color=cyan)
|
|
370
|
+
access = access.to_s.downcase.strip
|
|
371
|
+
if access.empty?
|
|
372
|
+
access = "none"
|
|
373
|
+
end
|
|
374
|
+
if access_levels.nil?
|
|
375
|
+
access_levels = ["none","read","user","full"]
|
|
376
|
+
elsif access_levels.is_a?(Array)
|
|
377
|
+
# access_levels = access_levels
|
|
336
378
|
else
|
|
337
|
-
|
|
379
|
+
# parse values like "full,custom,none"
|
|
380
|
+
access_levels = [access_levels].flatten.collect {|it| it.strip.split(",") }.flatten.collect {|it| it.strip }.compact
|
|
381
|
+
end
|
|
382
|
+
# build padded string that contains access eg. 'full' or ' read'
|
|
383
|
+
access_levels_string = access_levels.join(",")
|
|
384
|
+
padded_value = ""
|
|
385
|
+
access_levels.each do |a|
|
|
386
|
+
# handle some unusual access values
|
|
387
|
+
# print custom, and provision where 'user' normally is at index 1
|
|
388
|
+
if (access == "custom" || access == "provision") && a == "user"
|
|
389
|
+
padded_value << access
|
|
390
|
+
else
|
|
391
|
+
if access == a
|
|
392
|
+
padded_value << access
|
|
393
|
+
else
|
|
394
|
+
padded_value << " " * a.size
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
# no matching access was found, so just print it in one slot
|
|
399
|
+
if padded_value == ""
|
|
400
|
+
padded_value = " " * access_levels[0].to_s.size
|
|
401
|
+
padded_value << access
|
|
402
|
+
end
|
|
403
|
+
# strip any extra whitespace off the end
|
|
404
|
+
if padded_value.size > access_levels_string.size
|
|
405
|
+
padded_value = padded_value.rstrip
|
|
338
406
|
end
|
|
407
|
+
# ok build out string
|
|
408
|
+
out = ""
|
|
409
|
+
access_color = get_access_color(access)
|
|
410
|
+
out << access_color if access_color
|
|
411
|
+
out << padded_value
|
|
412
|
+
out << reset if access_color
|
|
413
|
+
out << return_color if return_color
|
|
414
|
+
return out
|
|
339
415
|
end
|
|
340
416
|
|
|
341
417
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'morpheus/cli/mixins/print_helper'
|
|
2
|
+
|
|
3
|
+
# Mixin for Morpheus::Cli command classes
|
|
4
|
+
# Provides common methods for working with Operations.
|
|
5
|
+
# This includes the Dashboard, Activity, and more... (coming soon)
|
|
6
|
+
module Morpheus::Cli::OperationsHelper
|
|
7
|
+
|
|
8
|
+
def self.included(klass)
|
|
9
|
+
klass.send :include, Morpheus::Cli::PrintHelper
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def format_activity_severity(severity, return_color=cyan)
|
|
13
|
+
out = ""
|
|
14
|
+
status_string = severity
|
|
15
|
+
if status_string == 'critical'
|
|
16
|
+
out << "#{red}#{status_string.capitalize}#{return_color}"
|
|
17
|
+
elsif status_string == 'warning'
|
|
18
|
+
out << "#{yellow}#{status_string.capitalize}#{return_color}"
|
|
19
|
+
elsif status_string == 'info'
|
|
20
|
+
out << "#{cyan}#{status_string.capitalize}#{return_color}"
|
|
21
|
+
else
|
|
22
|
+
out << "#{cyan}#{status_string}#{return_color}"
|
|
23
|
+
end
|
|
24
|
+
out
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def format_activity_display_object(item)
|
|
28
|
+
out = ""
|
|
29
|
+
if item['name']
|
|
30
|
+
out << item['name']
|
|
31
|
+
end
|
|
32
|
+
if item['objectType']
|
|
33
|
+
out << " (#{item['objectType']} #{item['objectId']})"
|
|
34
|
+
end
|
|
35
|
+
if item['deleted']
|
|
36
|
+
out << " [deleted]"
|
|
37
|
+
end
|
|
38
|
+
out
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|