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
@@ -42,71 +42,39 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
42
42
|
def list(args)
|
43
43
|
options = {}
|
44
44
|
params = {}
|
45
|
+
ref_ids = []
|
45
46
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
46
|
-
opts.banner = subcommand_usage()
|
47
|
-
|
47
|
+
opts.banner = subcommand_usage("[search]")
|
48
|
+
build_standard_list_options(opts, options)
|
48
49
|
opts.footer = "List storage buckets."
|
49
50
|
end
|
50
51
|
optparse.parse!(args)
|
51
|
-
if args.count != 0
|
52
|
-
print_error Morpheus::Terminal.angry_prompt
|
53
|
-
puts_error "wrong number of arguments, expected 0 and got #{args.count}\n#{optparse}"
|
54
|
-
return 1
|
55
|
-
end
|
56
52
|
connect(options)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
return 0
|
72
|
-
elsif options[:csv]
|
73
|
-
puts records_as_csv(storage_providers, options)
|
74
|
-
return 0
|
75
|
-
end
|
76
|
-
title = "Morpheus Storage Buckets"
|
77
|
-
subtitles = []
|
78
|
-
subtitles += parse_list_subtitles(options)
|
79
|
-
print_h1 title, subtitles
|
80
|
-
if storage_providers.empty?
|
53
|
+
if args.count > 0
|
54
|
+
options[:phrase] = args.join(" ")
|
55
|
+
end
|
56
|
+
params.merge!(parse_list_options(options))
|
57
|
+
@storage_providers_interface.setopts(options)
|
58
|
+
if options[:dry_run]
|
59
|
+
print_dry_run @storage_providers_interface.dry.list(params)
|
60
|
+
return
|
61
|
+
end
|
62
|
+
json_response = @storage_providers_interface.list(params)
|
63
|
+
storage_buckets = json_response['storageBuckets']
|
64
|
+
render_response(json_response, options, 'storageBuckets') do
|
65
|
+
print_h1 "Morpheus Storage Buckets", parse_list_subtitles(options), options
|
66
|
+
if storage_buckets.empty?
|
81
67
|
print cyan,"No storage buckets found.",reset,"\n"
|
82
68
|
else
|
83
|
-
|
84
|
-
|
85
|
-
id: storage_provider['id'],
|
86
|
-
name: storage_provider['name'],
|
87
|
-
provider: format_storage_provider_type(storage_provider),
|
88
|
-
bucket: format_bucket_name(storage_provider),
|
89
|
-
backups: storage_provider['defaultBackupTarget'] ? 'Yes' : 'No',
|
90
|
-
deployments: storage_provider['defaultDeploymentTarget'] ? 'Yes' : 'No',
|
91
|
-
virtualImages: storage_provider['defaultVirtualImageTarget'] ? 'Yes' : 'No',
|
92
|
-
}
|
93
|
-
row
|
94
|
-
}
|
95
|
-
columns = [:id, :name, {:provider => {:display_name => "Provider Type".upcase} }, {:bucket => {:display_name => "Bucket Name".upcase} }, :backups, :deployments]
|
96
|
-
if options[:include_fields]
|
97
|
-
columns = options[:include_fields]
|
98
|
-
rows = storage_providers
|
99
|
-
end
|
100
|
-
print cyan
|
101
|
-
print as_pretty_table(rows, columns, options)
|
102
|
-
print reset
|
103
|
-
print_results_pagination(json_response, {:label => "storage bucket", :n_label => "storage buckets"})
|
69
|
+
print as_pretty_table(storage_buckets, storage_bucket_column_definitions.upcase_keys!, options)
|
70
|
+
print_results_pagination(json_response)
|
104
71
|
end
|
105
72
|
print reset,"\n"
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
73
|
+
end
|
74
|
+
if storage_buckets.empty?
|
75
|
+
return 1, "no storage buckets found"
|
76
|
+
else
|
77
|
+
return 0, nil
|
110
78
|
end
|
111
79
|
end
|
112
80
|
|
@@ -1232,6 +1200,22 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
1232
1200
|
|
1233
1201
|
private
|
1234
1202
|
|
1203
|
+
def storage_bucket_column_definitions()
|
1204
|
+
{
|
1205
|
+
"ID" => 'id',
|
1206
|
+
"Name" => 'name',
|
1207
|
+
# "Description" => 'description',
|
1208
|
+
"Provider Type" => lambda {|it| format_storage_provider_type(it) },
|
1209
|
+
"Bucket Name" => lambda {|it| format_bucket_name(it) },
|
1210
|
+
# "Source" => lambda {|it| it['source'] },
|
1211
|
+
"Backups" => lambda {|it| format_boolean(it['defaultBackupTarget']) },
|
1212
|
+
"Deployments" => lambda {|it| format_boolean(it['defaultDeploymentTarget']) },
|
1213
|
+
"Virtual Images" => lambda {|it| format_boolean(it['defaultVirtualImageTarget']) },
|
1214
|
+
# "Archive Snapshots" => lambda {|it| format_boolean(it['copyToStore']) },
|
1215
|
+
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
1216
|
+
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
1217
|
+
}
|
1218
|
+
end
|
1235
1219
|
|
1236
1220
|
def get_storage_provider_types()
|
1237
1221
|
[
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
# CLI command usages
|
4
|
+
# UI is Costing - Usage
|
5
|
+
# API is /billing and returns usages
|
6
|
+
class Morpheus::Cli::UsageCommand
|
7
|
+
include Morpheus::Cli::CliCommand
|
8
|
+
include Morpheus::Cli::OptionSourceHelper
|
9
|
+
|
10
|
+
set_command_name :'usage'
|
11
|
+
|
12
|
+
register_subcommands :list #, :list_tenant, :list_clouds, :list_zones, :list_zones, :list_zones, :list_zones
|
13
|
+
|
14
|
+
def connect(opts)
|
15
|
+
@api_client = establish_remote_appliance_connection(opts)
|
16
|
+
@billing_interface = @api_client.billing
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle(args)
|
20
|
+
handle_subcommand(args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def list(args)
|
24
|
+
options = {}
|
25
|
+
params = {}
|
26
|
+
ref_ids = []
|
27
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
28
|
+
opts.banner = subcommand_usage("[search]")
|
29
|
+
opts.on( '-t', '--type TYPE', "Filter by type" ) do |val|
|
30
|
+
params['type'] = parse_usage_type(val)
|
31
|
+
end
|
32
|
+
opts.on( '-c', '--cloud CLOUD', "Filter by cloud" ) do |val|
|
33
|
+
options[:cloud] = val
|
34
|
+
end
|
35
|
+
opts.on('--start DATE', String, "Start date in the format YYYY-MM-DD.") do |val|
|
36
|
+
params['startDate'] = val #parse_time(val).utc.iso8601
|
37
|
+
end
|
38
|
+
opts.on('--end DATE', String, "End date in the format YYYY-MM-DD. Default is now.") do |val|
|
39
|
+
params['endDate'] = val #parse_time(val).utc.iso8601
|
40
|
+
end
|
41
|
+
opts.on('--sigdig DIGITS', "Significant digits when rounding cost values for display as currency. Default is 5.") do |val|
|
42
|
+
options[:sigdig] = val.to_i
|
43
|
+
end
|
44
|
+
build_standard_list_options(opts, options)
|
45
|
+
opts.footer = "List usages."
|
46
|
+
end
|
47
|
+
optparse.parse!(args)
|
48
|
+
connect(options)
|
49
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
50
|
+
if args.count > 0
|
51
|
+
options[:phrase] = args.join(" ")
|
52
|
+
end
|
53
|
+
params.merge!(parse_list_options(options))
|
54
|
+
# --cloud
|
55
|
+
if options[:cloud]
|
56
|
+
params['cloud'] = parse_id_list(options[:cloud]).collect {|cloud_id|
|
57
|
+
if cloud_id.to_s =~ /\A\d{1,}\Z/
|
58
|
+
cloud_id
|
59
|
+
else
|
60
|
+
cloud = find_cloud_option(cloud_id)
|
61
|
+
return 1 if cloud.nil?
|
62
|
+
cloud['id']
|
63
|
+
end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
@billing_interface.setopts(options)
|
68
|
+
if options[:dry_run]
|
69
|
+
print_dry_run @billing_interface.dry.list(params)
|
70
|
+
return
|
71
|
+
end
|
72
|
+
json_response = @billing_interface.list(params)
|
73
|
+
usages = json_response[usage_list_key]
|
74
|
+
render_response(json_response, options, usage_list_key) do
|
75
|
+
print_h1 "Morpheus Usages", parse_list_subtitles(options), options
|
76
|
+
if usages.empty?
|
77
|
+
print cyan,"No usages found.",reset,"\n"
|
78
|
+
else
|
79
|
+
list_columns = {
|
80
|
+
"ID" => 'id',
|
81
|
+
"Cloud" => 'zoneName',
|
82
|
+
"Type" => lambda {|it| format_usage_type(it) },
|
83
|
+
"Name" => 'name',
|
84
|
+
"Plan" => 'planName',
|
85
|
+
"Start Date" => lambda {|it| format_local_dt(it['startDate']) },
|
86
|
+
"End Date" => lambda {|it| format_local_dt(it['endDate']) },
|
87
|
+
"Usage Status" => lambda {|it| format_usage_status(it) },
|
88
|
+
"Usage Price" => lambda {|it| format_money(it['price'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
|
89
|
+
}
|
90
|
+
print as_pretty_table(usages, list_columns.upcase_keys!, options)
|
91
|
+
print_results_pagination(json_response)
|
92
|
+
end
|
93
|
+
print reset,"\n"
|
94
|
+
end
|
95
|
+
if usages.empty?
|
96
|
+
return 1, "no usages found"
|
97
|
+
else
|
98
|
+
return 0, nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def usage_object_key
|
106
|
+
'usage'
|
107
|
+
end
|
108
|
+
|
109
|
+
def usage_list_key
|
110
|
+
'usages'
|
111
|
+
end
|
112
|
+
|
113
|
+
def format_usage_type(usage)
|
114
|
+
#return usage['costDetails']['refType']
|
115
|
+
ref_type = usage['costDetails'] ? usage['costDetails']['refType'].to_s : ''
|
116
|
+
if ref_type == 'discoveredServer'
|
117
|
+
'Discovered'
|
118
|
+
elsif ref_type == 'computeServer'
|
119
|
+
'Host'
|
120
|
+
elsif ref_type == 'container'
|
121
|
+
'Container'
|
122
|
+
else
|
123
|
+
ref_type.to_s
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def parse_usage_type(val)
|
128
|
+
type_string = val.to_s.downcase
|
129
|
+
if type_string == 'discoveredServer'
|
130
|
+
'discoveredServer'
|
131
|
+
elsif type_string == 'host'
|
132
|
+
'computeServer'
|
133
|
+
elsif type_string == 'container'
|
134
|
+
'container'
|
135
|
+
else
|
136
|
+
val
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def format_usage_status(usage, return_color=cyan)
|
141
|
+
#return usage['status'].to_s.capitalize
|
142
|
+
status_string = usage['status'].to_s
|
143
|
+
if status_string == 'stopped'
|
144
|
+
return "#{cyan}#{status_string.upcase}#{return_color}"
|
145
|
+
else
|
146
|
+
return "#{cyan}#{status_string.upcase}#{return_color}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
@@ -94,6 +94,7 @@ EOT
|
|
94
94
|
"Linux Key Pair" => lambda {|it| it['linuxKeyPairId'] },
|
95
95
|
"Windows Username" => lambda {|it| it['windowsUsername'] },
|
96
96
|
"Windows Password" => lambda {|it| it['windowsPassword'] },
|
97
|
+
"Default Persona" => lambda {|it| it['defaultPersona'] ? it['defaultPersona']['name'] : '' },
|
97
98
|
}
|
98
99
|
print_description_list(description_cols, user_settings)
|
99
100
|
|
data/lib/morpheus/cli/users.rb
CHANGED
@@ -161,12 +161,22 @@ class Morpheus::Cli::Users
|
|
161
161
|
options[:include_app_templates_access] = true
|
162
162
|
params['includeAccess'] = true
|
163
163
|
end
|
164
|
+
opts.on(nil,'--catalog-item-type-access', "Display Catalog Item Type Access") do
|
165
|
+
options[:include_catalog_item_types_access] = true
|
166
|
+
params['includeAccess'] = true
|
167
|
+
end
|
168
|
+
opts.on(nil,'--personas', "Display Persona Access") do
|
169
|
+
options[:include_personas_access] = true
|
170
|
+
params['includeAccess'] = true
|
171
|
+
end
|
164
172
|
opts.on(nil,'--all', "Display All Access Lists") do
|
165
173
|
options[:include_features_access] = true
|
166
174
|
options[:include_sites_access] = true
|
167
175
|
options[:include_zones_access] = true
|
168
176
|
options[:include_instance_types_access] = true
|
169
177
|
options[:include_app_templates_access] = true
|
178
|
+
options[:include_catalog_item_types_access] = true
|
179
|
+
options[:include_personas_access] = true
|
170
180
|
params['includeAccess'] = true
|
171
181
|
end
|
172
182
|
opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
|
@@ -241,7 +251,8 @@ EOT
|
|
241
251
|
puts yellow,"No permissions found.",reset
|
242
252
|
end
|
243
253
|
else
|
244
|
-
available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
|
254
|
+
available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
|
255
|
+
'app_templates' => 'Blueprint', 'catalog_item_types' => 'Catalog Item Types', 'personas' => 'Personas'}
|
245
256
|
available_field_options.each do |field, label|
|
246
257
|
if !(field == 'sites' && is_tenant_account) && options["include_#{field}_access".to_sym]
|
247
258
|
access = user['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
|
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/formatters.rb
CHANGED
@@ -365,8 +365,21 @@ def format_number(n, opts={})
|
|
365
365
|
return out
|
366
366
|
end
|
367
367
|
|
368
|
-
def format_sig_dig(n, sigdig=3)
|
369
|
-
sprintf("%.#{sigdig}f", n)
|
368
|
+
def format_sig_dig(n, sigdig=3, min_sigdig=nil, pad_zeros=false)
|
369
|
+
v = sprintf("%.#{sigdig}f", n)
|
370
|
+
if pad_zeros != true
|
371
|
+
v = v.to_f.to_s
|
372
|
+
end
|
373
|
+
if min_sigdig
|
374
|
+
v_parts = v.split(".")
|
375
|
+
decimal_str = v_parts[1]
|
376
|
+
if decimal_str == nil
|
377
|
+
v = v + "." + ('0' * min_sigdig)
|
378
|
+
elsif decimal_str.size < min_sigdig
|
379
|
+
v = v + ('0' * (min_sigdig - decimal_str.size))
|
380
|
+
end
|
381
|
+
end
|
382
|
+
v
|
370
383
|
end
|
371
384
|
|
372
385
|
def currency_sym(currency)
|
@@ -375,7 +388,7 @@ end
|
|
375
388
|
|
376
389
|
# returns currency amount formatted like "$4,5123.00". 0.00 is formatted as "$0"
|
377
390
|
# this is not ideal
|
378
|
-
def
|
391
|
+
def format_currency(amount, currency='usd', opts={})
|
379
392
|
amount = amount.to_f
|
380
393
|
if amount == 0
|
381
394
|
return currency_sym(currency).to_s + "0"
|
@@ -383,8 +396,10 @@ def format_money(amount, currency='usd', opts={})
|
|
383
396
|
# # return exponent notation like 3.4e-09
|
384
397
|
# return currency_sym(currency).to_s + "#{amount}"
|
385
398
|
else
|
386
|
-
sigdig = opts[:sigdig] ? opts[:sigdig].to_i : 2
|
387
|
-
|
399
|
+
sigdig = opts[:sigdig] ? opts[:sigdig].to_i : 2 # max decimal digits
|
400
|
+
min_sigdig = opts[:min_sigdig] ? opts[:min_sigdig].to_i : 2 # min decimal digits
|
401
|
+
display_value = format_sig_dig(amount, sigdig, min_sigdig, opts[:pad_zeros])
|
402
|
+
rtn = currency_sym(currency).to_s + display_value
|
388
403
|
if amount.to_i < 0
|
389
404
|
rtn = "(#{rtn})"
|
390
405
|
if opts[:minus_color]
|
@@ -394,3 +409,9 @@ def format_money(amount, currency='usd', opts={})
|
|
394
409
|
rtn
|
395
410
|
end
|
396
411
|
end
|
412
|
+
|
413
|
+
alias :format_money :format_currency
|
414
|
+
|
415
|
+
# def format_money(amount, currency='usd', opts={})
|
416
|
+
# format_currency(amount, currency, opts)
|
417
|
+
# end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2020-09-
|
14
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -185,8 +185,10 @@ files:
|
|
185
185
|
- lib/morpheus/api/backup_jobs_interface.rb
|
186
186
|
- lib/morpheus/api/backup_settings_interface.rb
|
187
187
|
- lib/morpheus/api/backups_interface.rb
|
188
|
+
- lib/morpheus/api/billing_interface.rb
|
188
189
|
- lib/morpheus/api/blueprints_interface.rb
|
189
190
|
- lib/morpheus/api/budgets_interface.rb
|
191
|
+
- lib/morpheus/api/catalog_item_types_interface.rb
|
190
192
|
- lib/morpheus/api/cloud_datastores_interface.rb
|
191
193
|
- lib/morpheus/api/cloud_folders_interface.rb
|
192
194
|
- lib/morpheus/api/cloud_policies_interface.rb
|
@@ -305,6 +307,7 @@ files:
|
|
305
307
|
- lib/morpheus/cli/blueprints_command.rb
|
306
308
|
- lib/morpheus/cli/boot_scripts_command.rb
|
307
309
|
- lib/morpheus/cli/budgets_command.rb
|
310
|
+
- lib/morpheus/cli/catalog_command.rb
|
308
311
|
- lib/morpheus/cli/change_password_command.rb
|
309
312
|
- lib/morpheus/cli/cli_command.rb
|
310
313
|
- lib/morpheus/cli/cli_registry.rb
|
@@ -333,6 +336,7 @@ files:
|
|
333
336
|
- lib/morpheus/cli/commands/standard/source_command.rb
|
334
337
|
- lib/morpheus/cli/commands/standard/ssl_verification_command.rb
|
335
338
|
- lib/morpheus/cli/commands/standard/tee_command.rb
|
339
|
+
- lib/morpheus/cli/commands/standard/update_command.rb
|
336
340
|
- lib/morpheus/cli/commands/standard/version_command.rb
|
337
341
|
- lib/morpheus/cli/containers_command.rb
|
338
342
|
- lib/morpheus/cli/credentials.rb
|
@@ -380,6 +384,7 @@ files:
|
|
380
384
|
- lib/morpheus/cli/logs_command.rb
|
381
385
|
- lib/morpheus/cli/mixins/accounts_helper.rb
|
382
386
|
- lib/morpheus/cli/mixins/backups_helper.rb
|
387
|
+
- lib/morpheus/cli/mixins/catalog_helper.rb
|
383
388
|
- lib/morpheus/cli/mixins/deployments_helper.rb
|
384
389
|
- lib/morpheus/cli/mixins/infrastructure_helper.rb
|
385
390
|
- lib/morpheus/cli/mixins/library_helper.rb
|
@@ -432,6 +437,7 @@ files:
|
|
432
437
|
- lib/morpheus/cli/subnets_command.rb
|
433
438
|
- lib/morpheus/cli/tasks.rb
|
434
439
|
- lib/morpheus/cli/tenants_command.rb
|
440
|
+
- lib/morpheus/cli/usage_command.rb
|
435
441
|
- lib/morpheus/cli/user_groups_command.rb
|
436
442
|
- lib/morpheus/cli/user_settings_command.rb
|
437
443
|
- lib/morpheus/cli/user_sources_command.rb
|