morpheus-cli 4.2.6 → 4.2.7
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 +4 -0
- data/lib/morpheus/api/clouds_interface.rb +14 -0
- data/lib/morpheus/api/guidance_interface.rb +47 -0
- data/lib/morpheus/api/users_interface.rb +7 -0
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/account_groups_command.rb +1 -1
- data/lib/morpheus/cli/approvals_command.rb +2 -2
- data/lib/morpheus/cli/apps.rb +26 -30
- data/lib/morpheus/cli/blueprints_command.rb +1 -1
- data/lib/morpheus/cli/budgets_command.rb +2 -2
- data/lib/morpheus/cli/change_password_command.rb +0 -1
- data/lib/morpheus/cli/cli_command.rb +19 -9
- data/lib/morpheus/cli/clouds.rb +107 -10
- data/lib/morpheus/cli/clusters.rb +12 -12
- data/lib/morpheus/cli/commands/standard/curl_command.rb +7 -0
- data/lib/morpheus/cli/deployments.rb +2 -2
- data/lib/morpheus/cli/environments_command.rb +1 -1
- data/lib/morpheus/cli/execution_request_command.rb +1 -1
- data/lib/morpheus/cli/groups.rb +1 -1
- data/lib/morpheus/cli/guidance_command.rb +529 -0
- data/lib/morpheus/cli/hosts.rb +2 -10
- data/lib/morpheus/cli/instances.rb +31 -13
- data/lib/morpheus/cli/integrations_command.rb +1 -1
- data/lib/morpheus/cli/jobs_command.rb +2 -2
- data/lib/morpheus/cli/library_container_types_command.rb +4 -4
- data/lib/morpheus/cli/library_instance_types_command.rb +3 -3
- data/lib/morpheus/cli/library_spec_templates_command.rb +1 -1
- data/lib/morpheus/cli/load_balancers.rb +2 -2
- data/lib/morpheus/cli/mixins/print_helper.rb +43 -3
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +251 -165
- data/lib/morpheus/cli/network_routers_command.rb +1 -1
- data/lib/morpheus/cli/price_sets_command.rb +2 -2
- data/lib/morpheus/cli/provisioning_licenses_command.rb +1 -1
- data/lib/morpheus/cli/remote.rb +6 -1
- data/lib/morpheus/cli/reports_command.rb +1 -1
- data/lib/morpheus/cli/security_group_rules.rb +1 -1
- data/lib/morpheus/cli/security_groups.rb +13 -5
- data/lib/morpheus/cli/service_plans_command.rb +2 -2
- data/lib/morpheus/cli/user_groups_command.rb +2 -6
- data/lib/morpheus/cli/user_settings_command.rb +31 -5
- data/lib/morpheus/cli/user_sources_command.rb +3 -3
- data/lib/morpheus/cli/users.rb +117 -90
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +2 -2
- data/lib/morpheus/cli/whitelabel_settings_command.rb +95 -15
- data/lib/morpheus/cli/wiki_command.rb +2 -2
- data/lib/morpheus/cli/workflows.rb +2 -3
- data/lib/morpheus/formatters.rb +14 -5
- metadata +4 -2
@@ -207,7 +207,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
207
207
|
print_h2 "Tenant Permissions"
|
208
208
|
print cyan
|
209
209
|
description_cols = {
|
210
|
-
"Visibility" => lambda{|it| it['permissions']['visibility']},
|
210
|
+
"Visibility" => lambda{|it| (it['permissions']['visibility'] || '').capitalize},
|
211
211
|
"Tenants" => lambda{|it|
|
212
212
|
accounts = (it['permissions']['tenantPermissions'] || {})['accounts'] || []
|
213
213
|
accounts.count > 0 ? accounts.join(', ') : ''
|
@@ -64,7 +64,7 @@ class Morpheus::Cli::PriceSetsCommand
|
|
64
64
|
|
65
65
|
price_sets = json_response['priceSets']
|
66
66
|
if price_sets.empty?
|
67
|
-
print
|
67
|
+
print cyan,"No price sets found.",reset,"\n"
|
68
68
|
else
|
69
69
|
rows = price_sets.collect do |it|
|
70
70
|
{
|
@@ -166,7 +166,7 @@ class Morpheus::Cli::PriceSetsCommand
|
|
166
166
|
end
|
167
167
|
print as_pretty_table(rows, [:id, :name, :pricing], options)
|
168
168
|
else
|
169
|
-
print
|
169
|
+
print cyan,"No prices.",reset,"\n"
|
170
170
|
end
|
171
171
|
print reset,"\n"
|
172
172
|
return 0
|
@@ -4,7 +4,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand
|
|
4
4
|
include Morpheus::Cli::CliCommand
|
5
5
|
set_command_name :'provisioning-licenses'
|
6
6
|
register_subcommands :list, :get, :add, :update, :remove, :reservations, :'list-types'
|
7
|
-
|
7
|
+
|
8
8
|
def connect(opts)
|
9
9
|
@api_client = establish_remote_appliance_connection(opts)
|
10
10
|
@provisioning_licenses_interface = @api_client.provisioning_licenses
|
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -334,6 +334,9 @@ EOT
|
|
334
334
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
335
335
|
opts.banner = subcommand_usage("[name]")
|
336
336
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet, :dry_run, :remote])
|
337
|
+
opts.on('-a', '--all', "Check all remotes.") do
|
338
|
+
checkall = true
|
339
|
+
end
|
337
340
|
opts.footer = <<-EOT
|
338
341
|
Check the status of a remote appliance.
|
339
342
|
[name] is optional. This is the name of a remote. Default is the current remote. Can be passed as 'all'. to perform remote check-all.
|
@@ -341,7 +344,9 @@ This makes a request to the configured appliance url and updates the status and
|
|
341
344
|
EOT
|
342
345
|
end
|
343
346
|
optparse.parse!(args)
|
344
|
-
|
347
|
+
if checkall == true
|
348
|
+
return _check_all_appliances(options)
|
349
|
+
end
|
345
350
|
if args.count == 0
|
346
351
|
id_list = ['current']
|
347
352
|
else
|
@@ -513,7 +513,7 @@ class Morpheus::Cli::ReportsCommand
|
|
513
513
|
report_types = json_response['reportTypes']
|
514
514
|
|
515
515
|
if report_types.empty?
|
516
|
-
print
|
516
|
+
print cyan,"No report types found.",reset,"\n"
|
517
517
|
else
|
518
518
|
columns = {
|
519
519
|
"NAME" => 'name',
|
@@ -175,7 +175,7 @@ EOT
|
|
175
175
|
rules = json_response['rules']
|
176
176
|
print_h1 "Morpheus Security Group Rules for Security Group ID: #{security_group_id}"
|
177
177
|
if rules.empty?
|
178
|
-
print yellow,"No
|
178
|
+
print yellow,"No security group rules currently configured.",reset,"\n"
|
179
179
|
else
|
180
180
|
rules = rules.sort {|x,y| x["id"] <=> y["id"] }
|
181
181
|
rules.each do |rule|
|
@@ -64,7 +64,7 @@ class Morpheus::Cli::SecurityGroups
|
|
64
64
|
security_groups = json_response['securityGroups']
|
65
65
|
|
66
66
|
if security_groups.empty?
|
67
|
-
print
|
67
|
+
print cyan,"No security groups found.",reset,"\n"
|
68
68
|
else
|
69
69
|
active_id = @active_security_group[@appliance_name.to_sym]
|
70
70
|
# table_color = options[:color] || cyan
|
@@ -289,6 +289,9 @@ class Morpheus::Cli::SecurityGroups
|
|
289
289
|
options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
290
290
|
end
|
291
291
|
end
|
292
|
+
opts.on('--can-manage LIST', Array, "Tenant Can Manage, comma separated list of account IDs that can manage") do |list|
|
293
|
+
options['canManage'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
294
|
+
end
|
292
295
|
opts.on('--visibility [private|public]', String, "Visibility") do |val|
|
293
296
|
options['visibility'] = val
|
294
297
|
end
|
@@ -385,9 +388,10 @@ class Morpheus::Cli::SecurityGroups
|
|
385
388
|
end
|
386
389
|
|
387
390
|
# Tenants
|
388
|
-
if options['tenants']
|
391
|
+
if options['tenants'] || options['canManage']
|
389
392
|
payload['tenantPermissions'] = {}
|
390
|
-
payload['tenantPermissions']['accounts'] = options['tenants']
|
393
|
+
payload['tenantPermissions']['accounts'] = ((options['tenants'] || []) + (options['canManage'] || [])).uniq
|
394
|
+
payload['tenantPermissions']['canManageAccounts'] = options['canManage'] if options['canManage']
|
391
395
|
end
|
392
396
|
|
393
397
|
# Visibility
|
@@ -459,6 +463,9 @@ class Morpheus::Cli::SecurityGroups
|
|
459
463
|
options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
460
464
|
end
|
461
465
|
end
|
466
|
+
opts.on('--can-manage LIST', Array, "Tenant Can Manage, comma separated list of account IDs that can manage") do |list|
|
467
|
+
options['canManage'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
468
|
+
end
|
462
469
|
opts.on('--visibility [private|public]', String, "Visibility") do |val|
|
463
470
|
options['visibility'] = val
|
464
471
|
end
|
@@ -507,9 +514,10 @@ class Morpheus::Cli::SecurityGroups
|
|
507
514
|
end
|
508
515
|
|
509
516
|
# Tenants
|
510
|
-
if options['tenants']
|
517
|
+
if options['tenants'] || options['canManage']
|
511
518
|
payload['tenantPermissions'] = {}
|
512
|
-
payload['tenantPermissions']['accounts'] = options['tenants']
|
519
|
+
payload['tenantPermissions']['accounts'] = ((options['tenants'] || []) + (options['canManage'] || [])).uniq
|
520
|
+
payload['tenantPermissions']['canManageAccounts'] = options['canManage'] if options['canManage']
|
513
521
|
end
|
514
522
|
|
515
523
|
# Visibility
|
@@ -74,7 +74,7 @@ class Morpheus::Cli::ServicePlanCommand
|
|
74
74
|
|
75
75
|
plans = json_response['servicePlans']
|
76
76
|
if plans.empty?
|
77
|
-
print
|
77
|
+
print cyan,"No service plans found.",reset,"\n"
|
78
78
|
else
|
79
79
|
rows = plans.collect do |it|
|
80
80
|
{
|
@@ -221,7 +221,7 @@ class Morpheus::Cli::ServicePlanCommand
|
|
221
221
|
]
|
222
222
|
print as_pretty_table(rows, columns, options)
|
223
223
|
else
|
224
|
-
print
|
224
|
+
print cyan,"No price sets.",reset,"\n"
|
225
225
|
end
|
226
226
|
|
227
227
|
print_permissions(service_plan['permissions'], ['plans', 'groupDefaults'])
|
@@ -127,13 +127,9 @@ class Morpheus::Cli::UserGroupsCommand
|
|
127
127
|
print_description_list(description_cols, user_group)
|
128
128
|
|
129
129
|
## Users
|
130
|
-
|
131
|
-
print_h2 "User (1)"
|
132
|
-
else
|
133
|
-
print_h2 "Users (#{users.size})"
|
134
|
-
end
|
130
|
+
print_h2 "Users (#{users.size})"
|
135
131
|
if users.size == 0
|
136
|
-
print
|
132
|
+
print cyan,"No users",reset,"\n"
|
137
133
|
else
|
138
134
|
user_columns = [
|
139
135
|
{"ID" => lambda {|user| user['id'] } },
|
@@ -364,23 +364,38 @@ class Morpheus::Cli::UserSettingsCommand
|
|
364
364
|
raw_args = args
|
365
365
|
options = {}
|
366
366
|
params = {}
|
367
|
+
client_id = nil
|
368
|
+
all_clients = false
|
367
369
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
368
370
|
opts.banner = subcommand_usage("[client-id]")
|
371
|
+
opts.on("--all", "--all", "Clear tokens for all Client IDs instead of a specific client.") do
|
372
|
+
all_clients = true
|
373
|
+
end
|
374
|
+
# opts.on("--client-id", "Client ID. eg. morph-api, morph-cli") do |val|
|
375
|
+
# params['clientId'] = val.to_s
|
376
|
+
# end
|
369
377
|
opts.on("--user-id ID", String, "User ID") do |val|
|
370
378
|
params['userId'] = val.to_s
|
371
379
|
end
|
372
380
|
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
373
381
|
opts.footer = "Clear API access token for a specific client.\n" +
|
374
|
-
"[client-id] is required. This is the id of an api client."
|
382
|
+
"[client-id] or --all is required. This is the id of an api client."
|
375
383
|
end
|
376
384
|
optparse.parse!(args)
|
377
385
|
connect(options)
|
378
|
-
if args.count
|
386
|
+
if args.count > 1 || (args.count == 0 && all_clients == false)
|
379
387
|
print_error Morpheus::Terminal.angry_prompt
|
380
388
|
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
381
389
|
return 1
|
382
390
|
end
|
383
|
-
|
391
|
+
if args[0]
|
392
|
+
params['clientId'] = args[0]
|
393
|
+
end
|
394
|
+
if params['clientId'] == 'all'
|
395
|
+
params.delete('clientId')
|
396
|
+
all_clients = true
|
397
|
+
# clears all when clientId is omitted, no api parameter needed.
|
398
|
+
end
|
384
399
|
begin
|
385
400
|
payload = {}
|
386
401
|
@user_settings_interface.setopts(options)
|
@@ -400,9 +415,20 @@ class Morpheus::Cli::UserSettingsCommand
|
|
400
415
|
# if params['clientId'] == Morpheus::APIClient::CLIENT_ID
|
401
416
|
# logout_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).logout
|
402
417
|
# end
|
403
|
-
|
418
|
+
success_msg = "Success"
|
419
|
+
if all_clients
|
420
|
+
success_msg = "Cleared all access tokens"
|
421
|
+
else
|
422
|
+
success_msg = "Cleared #{params['clientId']} access token"
|
423
|
+
end
|
424
|
+
if params['userId']
|
425
|
+
success_msg << " for user #{params['userId']}"
|
426
|
+
end
|
427
|
+
print_green_success success_msg
|
404
428
|
if params['clientId'] == Morpheus::APIClient::CLIENT_ID
|
405
|
-
|
429
|
+
if params['userId'].nil? # should check against current user id
|
430
|
+
print yellow,"Your current access token is no longer valid, you will need to login again.",reset,"\n"
|
431
|
+
end
|
406
432
|
end
|
407
433
|
# get_args = [] + (options[:remote] ? ["-r",options[:remote]] : []) + (params['userId'] ? ['--user-id', params['userId'].to_s] : [])
|
408
434
|
# get(get_args)
|
@@ -187,7 +187,7 @@ class Morpheus::Cli::UserSourcesCommand
|
|
187
187
|
print_description_list(columns, user_source_config)
|
188
188
|
# print reset,"\n"
|
189
189
|
else
|
190
|
-
print
|
190
|
+
print cyan,"No config found.","\n",reset
|
191
191
|
end
|
192
192
|
|
193
193
|
role_mappings = user_source['roleMappings']
|
@@ -204,7 +204,7 @@ class Morpheus::Cli::UserSourcesCommand
|
|
204
204
|
print as_pretty_table(role_mappings, role_mapping_columns)
|
205
205
|
print "\n",reset
|
206
206
|
else
|
207
|
-
print
|
207
|
+
print cyan,"No role mappings found for this user source.","\n",reset
|
208
208
|
end
|
209
209
|
return 0
|
210
210
|
rescue RestClient::Exception => e
|
@@ -801,7 +801,7 @@ class Morpheus::Cli::UserSourcesCommand
|
|
801
801
|
]
|
802
802
|
print as_pretty_table(my_option_types, columns)
|
803
803
|
else
|
804
|
-
print
|
804
|
+
print cyan,"No option types found.","\n",reset
|
805
805
|
end
|
806
806
|
|
807
807
|
print reset,"\n"
|
data/lib/morpheus/cli/users.rb
CHANGED
@@ -10,6 +10,7 @@ require 'json'
|
|
10
10
|
class Morpheus::Cli::Users
|
11
11
|
include Morpheus::Cli::CliCommand
|
12
12
|
include Morpheus::Cli::AccountsHelper
|
13
|
+
include Morpheus::Cli::WhoamiHelper
|
13
14
|
register_subcommands :list, :count, :get, :add, :update, :remove, :permissions
|
14
15
|
register_subcommands :'passwd' => :change_password
|
15
16
|
alias_subcommand :details, :get
|
@@ -21,7 +22,6 @@ class Morpheus::Cli::Users
|
|
21
22
|
|
22
23
|
def connect(opts)
|
23
24
|
@api_client = establish_remote_appliance_connection(opts)
|
24
|
-
@whoami_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).whoami
|
25
25
|
@users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
|
26
26
|
@accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
|
27
27
|
@roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
|
@@ -113,25 +113,39 @@ class Morpheus::Cli::Users
|
|
113
113
|
|
114
114
|
def get(args)
|
115
115
|
options = {}
|
116
|
+
params = {}
|
116
117
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
117
118
|
opts.banner = subcommand_usage("[username]")
|
118
|
-
opts.on(
|
119
|
-
options[:
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
119
|
+
opts.on(nil,'--feature-access', "Display Feature Access") do |val|
|
120
|
+
options[:include_features_access] = true
|
121
|
+
params['includeAccess'] = true
|
122
|
+
end
|
123
|
+
opts.on(nil,'--group-access', "Display Group Access") do
|
124
|
+
options[:include_sites_access] = true
|
125
|
+
params['includeAccess'] = true
|
126
|
+
end
|
127
|
+
opts.on(nil,'--cloud-access', "Display Cloud Access") do
|
128
|
+
options[:include_zones_access] = true
|
129
|
+
params['includeAccess'] = true
|
130
|
+
end
|
131
|
+
opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
|
132
|
+
options[:include_instance_types_access] = true
|
133
|
+
params['includeAccess'] = true
|
134
|
+
end
|
135
|
+
opts.on(nil,'--blueprint-access', "Display Blueprint Access") do
|
136
|
+
options[:include_app_templates_access] = true
|
137
|
+
params['includeAccess'] = true
|
138
|
+
end
|
130
139
|
opts.on(nil,'--all', "Display All Access Lists") do
|
131
|
-
options[:
|
132
|
-
options[:
|
133
|
-
options[:
|
134
|
-
options[:
|
140
|
+
options[:include_features_access] = true
|
141
|
+
options[:include_sites_access] = true
|
142
|
+
options[:include_zones_access] = true
|
143
|
+
options[:include_instance_types_access] = true
|
144
|
+
options[:include_app_templates_access] = true
|
145
|
+
params['includeAccess'] = true
|
146
|
+
end
|
147
|
+
opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
|
148
|
+
options[:display_none_access] = true
|
135
149
|
end
|
136
150
|
build_common_options(opts, options, [:account, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
137
151
|
opts.footer = "Get details about a user." + "\n" +
|
@@ -151,44 +165,50 @@ class Morpheus::Cli::Users
|
|
151
165
|
@users_interface.setopts(options)
|
152
166
|
if options[:dry_run]
|
153
167
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
154
|
-
print_dry_run @users_interface.dry.get(account_id, args[0].to_i,
|
168
|
+
print_dry_run @users_interface.dry.get(account_id, args[0].to_i, params)
|
155
169
|
else
|
156
|
-
print_dry_run @users_interface.dry.get(account_id, {username: args[0]})
|
170
|
+
print_dry_run @users_interface.dry.get(account_id, {username: args[0]}, params)
|
157
171
|
end
|
158
|
-
# if options[:include_feature_access]
|
159
|
-
# print_dry_run @users_interface.dry.feature_permissions(account_id, ":id")
|
160
|
-
# end
|
161
172
|
return
|
162
173
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
174
|
+
|
175
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
176
|
+
user_id = args[0].to_i
|
177
|
+
else
|
178
|
+
user = find_user_by_username(account_id, args[0])
|
179
|
+
|
180
|
+
if user.nil?
|
181
|
+
print_red_alert "User #{args[0]} not found"
|
182
|
+
exit 1
|
183
|
+
end
|
184
|
+
user_id = user['id']
|
185
|
+
end
|
186
|
+
|
187
|
+
user = @users_interface.get(account_id, user_id, params)['user']
|
188
|
+
|
189
|
+
if user.nil?
|
190
|
+
print_red_alert "User #{args[0]} not found"
|
191
|
+
exit 1
|
192
|
+
end
|
193
|
+
|
194
|
+
is_tenant_account = current_account['id'] != user['account']['id']
|
195
|
+
|
168
196
|
json_response = {'user' => user}
|
169
|
-
|
197
|
+
|
170
198
|
if options[:json]
|
171
199
|
puts as_json(json_response, options, "user")
|
172
|
-
#puts as_json(@users_interface.feature_permissions(account_id, user['id']), options) if options[:include_feature_access]
|
173
200
|
return 0
|
174
201
|
elsif options[:yaml]
|
175
202
|
puts as_yaml(json_response, options, "user")
|
176
|
-
#puts as_yaml(@users_interface.feature_permissions(account_id, user['id']), options) if options[:include_feature_access]
|
177
203
|
return 0
|
178
204
|
elsif options[:csv]
|
179
205
|
puts records_as_csv([user], options)
|
180
206
|
return 0
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
# permissions (Array) has replaced featurePermissions (map)
|
187
|
-
user_feature_permissions = user_feature_permissions_json['permissions'] || user_feature_permissions_json['featurePermissions']
|
188
|
-
end
|
189
|
-
print_h1 "User Details", options
|
190
|
-
print cyan
|
191
|
-
description_cols = {
|
207
|
+
end
|
208
|
+
|
209
|
+
print_h1 "User Details", options
|
210
|
+
print cyan
|
211
|
+
description_cols = {
|
192
212
|
"ID" => 'id',
|
193
213
|
"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
194
214
|
# "First" => 'firstName',
|
@@ -200,34 +220,33 @@ class Morpheus::Cli::Users
|
|
200
220
|
"Role" => lambda {|it| format_user_role_names(it) },
|
201
221
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
202
222
|
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
223
|
+
}
|
224
|
+
print_description_list(description_cols, user)
|
225
|
+
|
226
|
+
available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type', 'app_templates' => 'Blueprint'}
|
227
|
+
available_field_options.each do |field, label|
|
228
|
+
if !(field == 'sites' && is_tenant_account) && options["include_#{field}_access".to_sym]
|
229
|
+
access = user['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
|
230
|
+
access = access.reject {|it| it['access'] == 'none'} if !options[:display_none_access]
|
231
|
+
|
232
|
+
print_h2 "#{label} Access", options
|
233
|
+
print cyan
|
234
|
+
|
235
|
+
if access.count > 0
|
236
|
+
access.each {|it| it['access'] = get_access_string(it['access'])}
|
237
|
+
|
238
|
+
if ['features', 'instance_types'].include?(field)
|
239
|
+
print as_pretty_table(access, [:name, :code, :access], options)
|
216
240
|
else
|
217
|
-
|
218
|
-
{code: code, access: get_access_string(access) }
|
219
|
-
end
|
220
|
-
print as_pretty_table(rows, [:code, :access], options)
|
241
|
+
print as_pretty_table(access, [:name, :access], options)
|
221
242
|
end
|
222
|
-
|
223
243
|
else
|
224
|
-
|
244
|
+
println yellow,"No #{label} Access Found.",reset
|
225
245
|
end
|
226
246
|
end
|
227
|
-
|
228
|
-
print cyan
|
229
|
-
print reset,"\n"
|
230
247
|
end
|
248
|
+
print cyan
|
249
|
+
print reset,"\n"
|
231
250
|
rescue RestClient::Exception => e
|
232
251
|
print_rest_exception(e, options)
|
233
252
|
return 1
|
@@ -239,7 +258,10 @@ class Morpheus::Cli::Users
|
|
239
258
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
240
259
|
opts.banner = subcommand_usage("[username]")
|
241
260
|
build_common_options(opts, options, [:account, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
242
|
-
opts.
|
261
|
+
opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
|
262
|
+
options[:display_none_access] = true
|
263
|
+
end
|
264
|
+
opts.footer = "Display Access for a user." + "\n" +
|
243
265
|
"[username] is required. This is the username or id of a user."
|
244
266
|
end
|
245
267
|
optparse.parse!(args)
|
@@ -257,46 +279,51 @@ class Morpheus::Cli::Users
|
|
257
279
|
return 1 if user.nil?
|
258
280
|
@users_interface.setopts(options)
|
259
281
|
if options[:dry_run]
|
260
|
-
print_dry_run @users_interface.dry.
|
282
|
+
print_dry_run @users_interface.dry.permissions(account_id, user['id'])
|
261
283
|
return
|
262
284
|
end
|
263
|
-
|
264
|
-
|
265
|
-
|
285
|
+
|
286
|
+
is_tenant_account = current_account['id'] != user['account']['id']
|
287
|
+
|
288
|
+
json_response = @users_interface.permissions(account_id, user['id'])
|
289
|
+
|
266
290
|
if options[:json]
|
267
|
-
puts as_json(json_response, options, '
|
291
|
+
puts as_json(json_response, options, 'access')
|
268
292
|
return 0
|
269
293
|
elsif options[:yaml]
|
270
|
-
puts as_yaml(json_response, options, '
|
294
|
+
puts as_yaml(json_response, options, 'access')
|
271
295
|
return 0
|
272
296
|
elsif options[:csv]
|
273
|
-
puts records_as_csv(json_response['
|
297
|
+
puts records_as_csv(json_response['access'], options)
|
274
298
|
return 0
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
299
|
+
end
|
300
|
+
|
301
|
+
print_h1 "User Permissions: #{user['username']}", options
|
302
|
+
|
303
|
+
available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type', 'app_templates' => 'Blueprint'}
|
304
|
+
available_field_options.each do |field, label|
|
305
|
+
if !(field == 'sites' && is_tenant_account)
|
306
|
+
access = json_response['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
|
307
|
+
access = access.reject {|it| it['access'] == 'none'} if !options[:display_none_access]
|
308
|
+
|
309
|
+
print_h2 "#{label} Access", options
|
281
310
|
print cyan
|
282
|
-
|
283
|
-
|
284
|
-
|
311
|
+
|
312
|
+
if access.count > 0
|
313
|
+
access.each {|it| it['access'] = get_access_string(it['access'])}
|
314
|
+
|
315
|
+
if ['features', 'instance_types'].include?(field)
|
316
|
+
print as_pretty_table(access, [:name, :code, :access], options)
|
317
|
+
else
|
318
|
+
print as_pretty_table(access, [:name, :access], options)
|
285
319
|
end
|
286
|
-
print as_pretty_table(rows, [:name, :code, :access], options)
|
287
320
|
else
|
288
|
-
|
289
|
-
{code: code, access: get_access_string(access) }
|
290
|
-
end
|
291
|
-
print as_pretty_table(rows, [:code, :access], options)
|
321
|
+
println yellow,"No #{label} Access Found.",reset
|
292
322
|
end
|
293
|
-
|
294
|
-
else
|
295
|
-
print yellow,"No permissions found.",reset,"\n"
|
296
323
|
end
|
297
|
-
print reset,"\n"
|
298
|
-
return 0
|
299
324
|
end
|
325
|
+
print cyan
|
326
|
+
print reset,"\n"
|
300
327
|
rescue RestClient::Exception => e
|
301
328
|
print_rest_exception(e, options)
|
302
329
|
return 1
|