morpheus-cli 4.2.22 → 5.0.0
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/api_client.rb +14 -0
- data/lib/morpheus/api/billing_interface.rb +33 -0
- data/lib/morpheus/api/catalog_item_types_interface.rb +9 -0
- data/lib/morpheus/api/rest_interface.rb +0 -6
- data/lib/morpheus/api/roles_interface.rb +14 -0
- data/lib/morpheus/cli.rb +2 -2
- data/lib/morpheus/cli/apps.rb +3 -4
- data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
- data/lib/morpheus/cli/backups_command.rb +3 -0
- data/lib/morpheus/cli/catalog_command.rb +507 -0
- data/lib/morpheus/cli/cli_command.rb +19 -11
- data/lib/morpheus/cli/commands/standard/source_command.rb +1 -1
- data/lib/morpheus/cli/commands/standard/update_command.rb +76 -0
- data/lib/morpheus/cli/containers_command.rb +14 -0
- data/lib/morpheus/cli/hosts.rb +30 -2
- data/lib/morpheus/cli/instances.rb +19 -1
- data/lib/morpheus/cli/library_option_lists_command.rb +14 -6
- data/lib/morpheus/cli/mixins/accounts_helper.rb +7 -6
- data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
- data/lib/morpheus/cli/mixins/catalog_helper.rb +66 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +0 -1
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +46 -0
- data/lib/morpheus/cli/ping.rb +0 -1
- data/lib/morpheus/cli/remote.rb +0 -2
- data/lib/morpheus/cli/roles.rb +305 -3
- data/lib/morpheus/cli/storage_providers_command.rb +40 -56
- data/lib/morpheus/cli/usage_command.rb +150 -0
- data/lib/morpheus/cli/user_settings_command.rb +1 -0
- data/lib/morpheus/cli/users.rb +12 -1
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +26 -5
- metadata +8 -2
@@ -194,7 +194,7 @@ module Morpheus
|
|
194
194
|
if option_type['placeHolder']
|
195
195
|
value_label = option_type['placeHolder']
|
196
196
|
elsif option_type['type'] == 'checkbox'
|
197
|
-
value_label = 'on|off' # or.. true|false
|
197
|
+
value_label = '[on|off]' # or.. true|false
|
198
198
|
elsif option_type['type'] == 'number'
|
199
199
|
value_label = 'NUMBER'
|
200
200
|
elsif option_type['type'] == 'multiSelect'
|
@@ -204,12 +204,16 @@ module Morpheus
|
|
204
204
|
# elsif option['type'] == 'select'
|
205
205
|
end
|
206
206
|
opts.on("--#{full_field_name} #{value_label}", String, description) do |val|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
207
|
+
if option_type['type'] == 'checkbox'
|
208
|
+
val = (val.to_s != 'false' && val.to_s != 'off')
|
209
|
+
else
|
210
|
+
# attempt to parse JSON, this allows blank arrays for multiSelect like --tenants []
|
211
|
+
if (val.to_s[0] == '{' && val.to_s[-1] == '}') || (val.to_s[0] == '[' && val.to_s[-1] == ']')
|
212
|
+
begin
|
213
|
+
val = JSON.parse(val)
|
214
|
+
rescue
|
215
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to parse option value '#{val}' as JSON" if Morpheus::Logging.debug?
|
216
|
+
end
|
213
217
|
end
|
214
218
|
end
|
215
219
|
cur_namespace = custom_options
|
@@ -489,13 +493,17 @@ module Morpheus
|
|
489
493
|
|
490
494
|
when :query, :query_filters
|
491
495
|
# arbitrary query parameters in the format -Q "category=web&phrase=nginx"
|
496
|
+
# or pass it many times like -Q foo=bar -Q hello=world
|
492
497
|
opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is 'foo=bar&category=web'" ) do |val|
|
493
|
-
options[:query_filters_raw]
|
494
|
-
|
495
|
-
|
498
|
+
if options[:query_filters_raw] && !options[:query_filters_raw].empty?
|
499
|
+
options[:query_filters_raw] += ("&" + val)
|
500
|
+
else
|
501
|
+
options[:query_filters_raw] = val
|
502
|
+
end
|
503
|
+
options[:query_filters] ||= {}
|
496
504
|
val.split('&').each do |filter|
|
497
505
|
k, v = filter.split('=')
|
498
|
-
# allow
|
506
|
+
# allow woot:true instead of woot=true
|
499
507
|
if (k.include?(":") && v == nil)
|
500
508
|
k, v = k.split(":")
|
501
509
|
end
|
@@ -14,7 +14,7 @@ class Morpheus::Cli::SourceCommand
|
|
14
14
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
15
15
|
opts.banner = "Usage: morpheus #{command_name} [file] [file2]"
|
16
16
|
build_common_options(opts, options, [])
|
17
|
-
opts.footer = "This will execute a file
|
17
|
+
opts.footer = "This will execute a file as a script where each line is a morpheus command or expression."
|
18
18
|
end
|
19
19
|
optparse.parse!(args)
|
20
20
|
if args.count < 1
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# This is for use in dotfile scripts and the shell..
|
5
|
+
class Morpheus::Cli::UpdateCommand
|
6
|
+
include Morpheus::Cli::CliCommand
|
7
|
+
set_command_name :update
|
8
|
+
|
9
|
+
def handle(args)
|
10
|
+
options = {}
|
11
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
12
|
+
opts.banner = "Usage: morpheus #{command_name}"
|
13
|
+
opts.on( '-f', '--force', "Force Update, executes update even if latest version is already installed." ) do
|
14
|
+
options[:force] = true
|
15
|
+
end
|
16
|
+
build_common_options(opts, options, [:dry_run, :quiet])
|
17
|
+
opts.footer = "This will update the morpheus command line interface to the latest version.\nThis is done by executing the system command: `gem update #{morpheus_gem_name}`"
|
18
|
+
end
|
19
|
+
optparse.parse!(args)
|
20
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
21
|
+
|
22
|
+
current_version = Morpheus::Cli::VERSION
|
23
|
+
latest_version = get_latest_version()
|
24
|
+
latest_version = latest_version
|
25
|
+
|
26
|
+
if current_version == latest_version && !options[:force]
|
27
|
+
unless options[:quiet]
|
28
|
+
print cyan, "The latest version is already installed. (#{latest_version})", "\n", reset
|
29
|
+
end
|
30
|
+
return 0, nil
|
31
|
+
end
|
32
|
+
|
33
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to update the #{morpheus_gem_name} gem from version #{current_version} to version #{latest_version}?")
|
34
|
+
return 9, "aborted command"
|
35
|
+
end
|
36
|
+
|
37
|
+
gem_update_command = "gem update #{morpheus_gem_name}"
|
38
|
+
|
39
|
+
if options[:dry_run]
|
40
|
+
unless options[:quiet]
|
41
|
+
print "\n"
|
42
|
+
print "#{cyan}#{bold}#{dark}COMMAND#{reset}\n"
|
43
|
+
puts gem_update_command
|
44
|
+
print "\n", reset
|
45
|
+
end
|
46
|
+
return 0, nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# ok, update it
|
50
|
+
if options[:quiet]
|
51
|
+
system(gem_update_command)
|
52
|
+
else
|
53
|
+
`#{gem_update_command}`
|
54
|
+
end
|
55
|
+
|
56
|
+
if $?.success?
|
57
|
+
return 0, nil
|
58
|
+
else
|
59
|
+
return $?.exitstatus, "update failed"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def morpheus_gem_name
|
67
|
+
'morpheus-cli'
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_latest_version
|
71
|
+
result = HTTP.get("https://rubygems.org/api/v1/gems/#{morpheus_gem_name}.json")
|
72
|
+
json_response = JSON.parse(result.body)
|
73
|
+
json_response["version"]
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -35,6 +35,9 @@ class Morpheus::Cli::ContainersCommand
|
|
35
35
|
opts.on( nil, '--actions', "Display Available Actions" ) do
|
36
36
|
options[:include_available_actions] = true
|
37
37
|
end
|
38
|
+
opts.on( nil, '--costs', "Display Cost and Price" ) do
|
39
|
+
options[:include_costs] = true
|
40
|
+
end
|
38
41
|
opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
|
39
42
|
options[:refresh_until_status] ||= "running,failed"
|
40
43
|
if !val.to_s.empty?
|
@@ -99,6 +102,8 @@ class Morpheus::Cli::ContainersCommand
|
|
99
102
|
"Name" => lambda {|it| it['server'] ? it['server']['name'] : '(no server)' }, # there is a server.displayName too?
|
100
103
|
"Type" => lambda {|it| it['containerType'] ? it['containerType']['name'] : '' },
|
101
104
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
105
|
+
# "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
106
|
+
# "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
102
107
|
"Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : '' },
|
103
108
|
"Host" => lambda {|it| it['server'] ? it['server']['name'] : '' },
|
104
109
|
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
@@ -133,6 +138,15 @@ class Morpheus::Cli::ContainersCommand
|
|
133
138
|
end
|
134
139
|
end
|
135
140
|
|
141
|
+
if options[:include_costs]
|
142
|
+
print_h2 "Container Cost"
|
143
|
+
cost_columns = {
|
144
|
+
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
145
|
+
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
146
|
+
}
|
147
|
+
print_description_list(cost_columns, container)
|
148
|
+
end
|
149
|
+
|
136
150
|
print reset, "\n"
|
137
151
|
|
138
152
|
# refresh until a status is reached
|
data/lib/morpheus/cli/hosts.rb
CHANGED
@@ -119,6 +119,10 @@ class Morpheus::Cli::Hosts
|
|
119
119
|
end
|
120
120
|
optparse.parse!(args)
|
121
121
|
connect(options)
|
122
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
123
|
+
if args.count > 0
|
124
|
+
options[:phrase] = args.join(" ")
|
125
|
+
end
|
122
126
|
begin
|
123
127
|
params.merge!(parse_list_options(options))
|
124
128
|
account = nil
|
@@ -392,6 +396,9 @@ class Morpheus::Cli::Hosts
|
|
392
396
|
options = {}
|
393
397
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
394
398
|
opts.banner = subcommand_usage("[name]")
|
399
|
+
opts.on( nil, '--costs', "Display Cost and Price" ) do
|
400
|
+
options[:include_costs] = true
|
401
|
+
end
|
395
402
|
opts.on('--refresh [SECONDS]', String, "Refresh until status is provisioned,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
|
396
403
|
options[:refresh_until_status] ||= "provisioned,failed"
|
397
404
|
if !val.to_s.empty?
|
@@ -453,7 +460,7 @@ class Morpheus::Cli::Hosts
|
|
453
460
|
title = "Host Details"
|
454
461
|
print_h1 title, [], options
|
455
462
|
print cyan
|
456
|
-
|
463
|
+
server_columns = {
|
457
464
|
"ID" => 'id',
|
458
465
|
"Name" => 'name',
|
459
466
|
"Description" => 'description',
|
@@ -463,12 +470,23 @@ class Morpheus::Cli::Hosts
|
|
463
470
|
"Type" => lambda {|it| it['computeServerType'] ? it['computeServerType']['name'] : 'unmanaged' },
|
464
471
|
"Platform" => lambda {|it| it['serverOs'] ? it['serverOs']['name'].upcase : 'N/A' },
|
465
472
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
473
|
+
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
474
|
+
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
466
475
|
"Agent" => lambda {|it| it['agentInstalled'] ? "#{server['agentVersion'] || ''} updated at #{format_local_dt(server['lastAgentUpdate'])}" : '(not installed)' },
|
467
476
|
"Status" => lambda {|it| format_server_status(it) },
|
468
477
|
"Nodes" => lambda {|it| it['containers'] ? it['containers'].size : 0 },
|
469
478
|
"Power" => lambda {|it| format_server_power_state(it) },
|
470
|
-
}
|
479
|
+
}
|
471
480
|
|
481
|
+
if server['hourlyCost'].to_f == 0
|
482
|
+
server_columns.delete("Cost")
|
483
|
+
end
|
484
|
+
if server['hourlyPrice'].to_f == 0 || server['hourlyPrice'] == server['hourlyCost']
|
485
|
+
server_columns.delete("Price")
|
486
|
+
end
|
487
|
+
|
488
|
+
print_description_list(server_columns, server)
|
489
|
+
|
472
490
|
if server['statusMessage']
|
473
491
|
print_h2 "Status Message", options
|
474
492
|
if server['status'] == 'failed'
|
@@ -485,6 +503,16 @@ class Morpheus::Cli::Hosts
|
|
485
503
|
|
486
504
|
print_h2 "Host Usage", options
|
487
505
|
print_stats_usage(stats)
|
506
|
+
|
507
|
+
if options[:include_costs]
|
508
|
+
print_h2 "Host Cost"
|
509
|
+
cost_columns = {
|
510
|
+
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
511
|
+
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
512
|
+
}
|
513
|
+
print_description_list(cost_columns, server)
|
514
|
+
end
|
515
|
+
|
488
516
|
print reset, "\n"
|
489
517
|
|
490
518
|
|
@@ -96,7 +96,10 @@ class Morpheus::Cli::Instances
|
|
96
96
|
opts.footer = "List instances."
|
97
97
|
end
|
98
98
|
optparse.parse!(args)
|
99
|
-
verify_args!(args:args,
|
99
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
100
|
+
if args.count > 0
|
101
|
+
options[:phrase] = args.join(" ")
|
102
|
+
end
|
100
103
|
connect(options)
|
101
104
|
begin
|
102
105
|
params.merge!(parse_list_options(options))
|
@@ -1148,6 +1151,9 @@ class Morpheus::Cli::Instances
|
|
1148
1151
|
opts.on( nil, '--scaling', "Display Instance Scaling Settings" ) do
|
1149
1152
|
options[:include_scaling] = true
|
1150
1153
|
end
|
1154
|
+
opts.on( nil, '--costs', "Display Cost and Price" ) do
|
1155
|
+
options[:include_costs] = true
|
1156
|
+
end
|
1151
1157
|
opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
|
1152
1158
|
options[:refresh_until_status] ||= "running,failed"
|
1153
1159
|
if !val.to_s.empty?
|
@@ -1249,6 +1255,8 @@ class Morpheus::Cli::Instances
|
|
1249
1255
|
"Layout" => lambda {|it| it['layout'] ? it['layout']['name'] : '' },
|
1250
1256
|
"Version" => lambda {|it| it['instanceVersion'] },
|
1251
1257
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
1258
|
+
# "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
1259
|
+
# "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
1252
1260
|
"Environment" => 'instanceContext',
|
1253
1261
|
"Labels" => lambda {|it| it['tags'] ? it['tags'].join(',') : '' },
|
1254
1262
|
"Metadata" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
|
@@ -1304,6 +1312,16 @@ class Morpheus::Cli::Instances
|
|
1304
1312
|
print_h2 "Instance Usage", options
|
1305
1313
|
print_stats_usage(stats)
|
1306
1314
|
end
|
1315
|
+
|
1316
|
+
if options[:include_costs]
|
1317
|
+
print_h2 "Instance Cost"
|
1318
|
+
cost_columns = {
|
1319
|
+
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
1320
|
+
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
1321
|
+
}
|
1322
|
+
print_description_list(cost_columns, instance)
|
1323
|
+
end
|
1324
|
+
|
1307
1325
|
print reset, "\n"
|
1308
1326
|
|
1309
1327
|
# if options[:include_lb]
|
@@ -90,6 +90,9 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
90
90
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
91
91
|
opts.banner = subcommand_usage("[name]")
|
92
92
|
build_standard_get_options(opts, options)
|
93
|
+
opts.on(nil,'--no-items', "Do not display List Items") do |val|
|
94
|
+
options[:no_list_items] = true
|
95
|
+
end
|
93
96
|
opts.footer = "Get details about an option list.\n" +
|
94
97
|
"[name] is required. This is the name or id of an option list. Supports 1-N [name] arguments."
|
95
98
|
end
|
@@ -166,15 +169,20 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
166
169
|
print_h2 "Translation Script"
|
167
170
|
print reset,"#{option_type_list['translationScript']}","\n",reset
|
168
171
|
end
|
172
|
+
if !option_type_list['requestScript'].empty?
|
173
|
+
print_h2 "Request Script"
|
174
|
+
print reset,"#{option_type_list['requestScript']}","\n",reset
|
175
|
+
end
|
169
176
|
end
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
177
|
+
if options[:no_list_items] != true
|
178
|
+
list_items = option_type_list['listItems']
|
179
|
+
if list_items && list_items.size > 0
|
180
|
+
print_h2 "List Items"
|
181
|
+
print as_pretty_table(list_items, [:name, :value], options)
|
182
|
+
print_results_pagination({size: list_items.size, total: list_items.size})
|
183
|
+
end
|
175
184
|
end
|
176
185
|
print reset,"\n"
|
177
|
-
|
178
186
|
rescue RestClient::Exception => e
|
179
187
|
print_rest_exception(e, options)
|
180
188
|
exit 1
|
@@ -136,6 +136,7 @@ module Morpheus::Cli::AccountsHelper
|
|
136
136
|
"Multitenant" => lambda {|it|
|
137
137
|
format_boolean(it['multitenant']).to_s + (it['multitenantLocked'] ? " (LOCKED)" : "")
|
138
138
|
},
|
139
|
+
"Default Persona" => lambda {|it| it['defaultPersona'] ? it['defaultPersona']['name'] : '(standard)' },
|
139
140
|
"Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
|
140
141
|
#"Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
141
142
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
@@ -196,7 +197,7 @@ module Morpheus::Cli::AccountsHelper
|
|
196
197
|
|
197
198
|
## Users
|
198
199
|
|
199
|
-
def user_column_definitions()
|
200
|
+
def user_column_definitions(opts={})
|
200
201
|
{
|
201
202
|
"ID" => 'id',
|
202
203
|
"Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
@@ -206,15 +207,15 @@ module Morpheus::Cli::AccountsHelper
|
|
206
207
|
"Email" => 'email',
|
207
208
|
"Role" => lambda {|it| format_user_role_names(it) },
|
208
209
|
"Notifications" => lambda {|it| it['receiveNotifications'].nil? ? '' : format_boolean(it['receiveNotifications']) },
|
209
|
-
"Status" => lambda {|it| format_user_status(it) },
|
210
|
+
"Status" => lambda {|it| format_user_status(it, opts[:color] || cyan) },
|
210
211
|
"Last Login" => lambda {|it| format_duration_ago(it['lastLoginDate']) },
|
211
212
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
212
213
|
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
213
214
|
}
|
214
215
|
end
|
215
216
|
|
216
|
-
def list_user_column_definitions()
|
217
|
-
columns = user_column_definitions
|
217
|
+
def list_user_column_definitions(opts={})
|
218
|
+
columns = user_column_definitions(opts)
|
218
219
|
columns.delete("Notifications")
|
219
220
|
return columns.upcase_keys!
|
220
221
|
end
|
@@ -261,8 +262,8 @@ module Morpheus::Cli::AccountsHelper
|
|
261
262
|
return nil
|
262
263
|
elsif users.size > 1
|
263
264
|
print_red_alert "Found #{users.size} users by username '#{username}'. Try using ID instead: #{format_list(users.collect {|it| it['id']}, 'or', 3)}"
|
264
|
-
|
265
|
-
|
265
|
+
print_error "\n"
|
266
|
+
print_error as_pretty_table(users, list_user_column_definitions({color: red}), {color: red, thin: true})
|
266
267
|
print reset,"\n"
|
267
268
|
return nil
|
268
269
|
else
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'morpheus/cli/mixins/print_helper'
|
2
2
|
# Mixin for Morpheus::Cli command classes
|
3
|
-
# Provides common methods for
|
3
|
+
# Provides common methods for backups management
|
4
4
|
module Morpheus::Cli::BackupsHelper
|
5
5
|
|
6
6
|
def self.included(klass)
|
@@ -8,13 +8,11 @@ module Morpheus::Cli::BackupsHelper
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def backups_interface
|
11
|
-
# @api_client.groups
|
12
11
|
raise "#{self.class} has not defined @backups_interface" if @backups_interface.nil?
|
13
12
|
@backups_interface
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
# @api_client.groups
|
15
|
+
def backup_jobs_interfaces
|
18
16
|
raise "#{self.class} has not defined @backup_jobs_interface" if @backup_jobs_interface.nil?
|
19
17
|
@backup_jobs_interface
|
20
18
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'morpheus/cli/mixins/print_helper'
|
2
|
+
# Mixin for Morpheus::Cli command classes
|
3
|
+
# Provides common methods for infrastructure management
|
4
|
+
module Morpheus::Cli::CatalogHelper
|
5
|
+
|
6
|
+
def self.included(klass)
|
7
|
+
klass.send :include, Morpheus::Cli::PrintHelper
|
8
|
+
end
|
9
|
+
|
10
|
+
def catalog_item_types_interface
|
11
|
+
raise "#{self.class} has not defined @catalog_item_types_interface" if @catalog_item_types_interface.nil?
|
12
|
+
@catalog_item_types_interface
|
13
|
+
end
|
14
|
+
|
15
|
+
# def service_catalog_interface
|
16
|
+
# raise "#{self.class} has not defined @service_catalog_interface" if @service_catalog_interface.nil?
|
17
|
+
# @service_catalog_interface
|
18
|
+
# end
|
19
|
+
|
20
|
+
def catalog_item_type_object_key
|
21
|
+
'catalogItemType'
|
22
|
+
end
|
23
|
+
|
24
|
+
def catalog_item_type_list_key
|
25
|
+
'catalogItemTypes'
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_catalog_item_type_by_name_or_id(val)
|
29
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
30
|
+
return find_catalog_item_type_by_id(val)
|
31
|
+
else
|
32
|
+
return find_catalog_item_type_by_name(val)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_catalog_item_type_by_id(id)
|
37
|
+
begin
|
38
|
+
json_response = catalog_item_types_interface.get(id.to_i)
|
39
|
+
return json_response[catalog_item_type_object_key]
|
40
|
+
rescue RestClient::Exception => e
|
41
|
+
if e.response && e.response.code == 404
|
42
|
+
print_red_alert "catalog_item_type not found by id '#{id}'"
|
43
|
+
else
|
44
|
+
raise e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_catalog_item_type_by_name(name)
|
50
|
+
json_response = catalog_item_types_interface.list({name: name.to_s})
|
51
|
+
catalog_item_types = json_response[catalog_item_type_list_key]
|
52
|
+
if catalog_item_types.empty?
|
53
|
+
print_red_alert "catalog_item_type not found by name '#{name}'"
|
54
|
+
return nil
|
55
|
+
elsif catalog_item_types.size > 1
|
56
|
+
print_red_alert "#{catalog_item_types.size} catalog_item_types found by name '#{name}'"
|
57
|
+
puts_error as_pretty_table(catalog_item_types, [:id, :name], {color:red})
|
58
|
+
print_red_alert "Try using ID instead"
|
59
|
+
print reset,"\n"
|
60
|
+
return nil
|
61
|
+
else
|
62
|
+
return catalog_item_types[0]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|