morpheus-cli 4.2.16 → 4.2.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +8 -6
  4. data/lib/morpheus/api/api_client.rb +32 -14
  5. data/lib/morpheus/api/auth_interface.rb +4 -2
  6. data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
  7. data/lib/morpheus/api/backups_interface.rb +16 -0
  8. data/lib/morpheus/api/deploy_interface.rb +25 -56
  9. data/lib/morpheus/api/deployments_interface.rb +44 -55
  10. data/lib/morpheus/api/doc_interface.rb +57 -0
  11. data/lib/morpheus/api/instances_interface.rb +5 -0
  12. data/lib/morpheus/api/rest_interface.rb +40 -0
  13. data/lib/morpheus/api/user_sources_interface.rb +0 -15
  14. data/lib/morpheus/api/users_interface.rb +2 -3
  15. data/lib/morpheus/benchmarking.rb +2 -2
  16. data/lib/morpheus/cli.rb +4 -1
  17. data/lib/morpheus/cli/access_token_command.rb +27 -10
  18. data/lib/morpheus/cli/apps.rb +21 -15
  19. data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
  20. data/lib/morpheus/cli/backups_command.rb +271 -0
  21. data/lib/morpheus/cli/blueprints_command.rb +27 -61
  22. data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
  23. data/lib/morpheus/cli/budgets_command.rb +4 -4
  24. data/lib/morpheus/cli/cli_command.rb +99 -41
  25. data/lib/morpheus/cli/cloud_resource_pools_command.rb +16 -0
  26. data/lib/morpheus/cli/clouds.rb +7 -10
  27. data/lib/morpheus/cli/clusters.rb +0 -18
  28. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
  29. data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
  30. data/lib/morpheus/cli/credentials.rb +13 -9
  31. data/lib/morpheus/cli/deploy.rb +374 -0
  32. data/lib/morpheus/cli/deployments.rb +521 -197
  33. data/lib/morpheus/cli/deploys.rb +271 -126
  34. data/lib/morpheus/cli/doc.rb +182 -0
  35. data/lib/morpheus/cli/error_handler.rb +23 -8
  36. data/lib/morpheus/cli/errors.rb +3 -2
  37. data/lib/morpheus/cli/image_builder_command.rb +2 -2
  38. data/lib/morpheus/cli/instances.rb +136 -17
  39. data/lib/morpheus/cli/invoices_command.rb +59 -47
  40. data/lib/morpheus/cli/jobs_command.rb +2 -2
  41. data/lib/morpheus/cli/library_instance_types_command.rb +17 -3
  42. data/lib/morpheus/cli/library_layouts_command.rb +1 -1
  43. data/lib/morpheus/cli/login.rb +9 -3
  44. data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
  45. data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
  46. data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
  47. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  48. data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
  49. data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
  50. data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
  51. data/lib/morpheus/cli/network_routers_command.rb +1 -1
  52. data/lib/morpheus/cli/option_parser.rb +48 -5
  53. data/lib/morpheus/cli/option_types.rb +1 -1
  54. data/lib/morpheus/cli/projects_command.rb +7 -7
  55. data/lib/morpheus/cli/provisioning_licenses_command.rb +2 -2
  56. data/lib/morpheus/cli/remote.rb +3 -2
  57. data/lib/morpheus/cli/roles.rb +49 -92
  58. data/lib/morpheus/cli/security_groups.rb +7 -1
  59. data/lib/morpheus/cli/service_plans_command.rb +10 -10
  60. data/lib/morpheus/cli/setup.rb +1 -1
  61. data/lib/morpheus/cli/shell.rb +7 -6
  62. data/lib/morpheus/cli/subnets_command.rb +1 -1
  63. data/lib/morpheus/cli/tasks.rb +24 -10
  64. data/lib/morpheus/cli/tenants_command.rb +133 -163
  65. data/lib/morpheus/cli/user_groups_command.rb +20 -65
  66. data/lib/morpheus/cli/user_settings_command.rb +115 -13
  67. data/lib/morpheus/cli/user_sources_command.rb +57 -24
  68. data/lib/morpheus/cli/users.rb +210 -186
  69. data/lib/morpheus/cli/version.rb +1 -1
  70. data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
  71. data/lib/morpheus/cli/whoami.rb +113 -6
  72. data/lib/morpheus/cli/workflows.rb +11 -8
  73. data/lib/morpheus/ext/hash.rb +21 -0
  74. data/lib/morpheus/terminal.rb +1 -0
  75. metadata +12 -3
  76. data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -16,9 +16,6 @@ class Morpheus::Cli::Users
16
16
  alias_subcommand :details, :get
17
17
  set_default_subcommand :list
18
18
 
19
- #todo: TOO_SIMPL_REGEX = //i
20
- # TOO_SIMPLE_ERROR = "Password too simple. Password must contain at least one uppercase letter, one lowercase letter, a number, and a symbol."
21
-
22
19
  def initialize()
23
20
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
24
21
  end
@@ -35,57 +32,74 @@ class Morpheus::Cli::Users
35
32
  end
36
33
 
37
34
  def list(args)
35
+ params = {}
38
36
  options = {}
39
37
  optparse = Morpheus::Cli::OptionParser.new do |opts|
40
38
  opts.banner = subcommand_usage()
41
- build_common_options(opts, options, [:account, :list, :query, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
39
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
40
+ options[:global] = true
41
+ end
42
+ opts.on('--role AUTHORITY', String, "Role Name (authority)") do |val|
43
+ params['role'] ||= []
44
+ val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }.each do |v|
45
+ params['role'] << v
46
+ end
47
+ end
48
+ opts.on('--role-id ID', String, "Role ID") do |val|
49
+ params['roleId'] ||= []
50
+ val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }.each do |v|
51
+ params['roleId'] << v
52
+ end
53
+ end
54
+ build_standard_list_options(opts, options, [:account])
42
55
  opts.footer = "List users."
43
56
  end
44
57
  optparse.parse!(args)
58
+ # verify_args!(args:args, optparse:optparse, count:0)
59
+ options[:phrase] = args.join(" ") if args.count > 0
45
60
  connect(options)
46
- begin
47
-
48
- account = find_account_from_options(options)
49
- account_id = account ? account['id'] : nil
50
-
51
- params = {}
52
- params.merge!(parse_list_options(options))
53
- @users_interface.setopts(options)
54
- if options[:dry_run]
55
- print_dry_run @users_interface.dry.list(account_id, params)
56
- return
57
- end
58
- json_response = @users_interface.list(account_id, params)
59
- render_result = render_with_format(json_response, options, 'users')
60
- return 0 if render_result
61
+ account = find_account_from_options(options)
62
+ account_id = account ? account['id'] : nil
63
+ params['global'] = true if options[:global]
64
+ params.merge!(parse_list_options(options))
65
+ @users_interface.setopts(options)
66
+ if options[:dry_run]
67
+ print_dry_run @users_interface.dry.list(account_id, params)
68
+ return 0, nil
69
+ end
70
+ json_response = @users_interface.list(account_id, params)
71
+ render_response(json_response, options, "users") do
61
72
  users = json_response['users']
62
-
63
73
  title = "Morpheus Users"
64
74
  subtitles = []
65
75
  if account
66
- subtitles << "Account: #{account['name']}".strip
76
+ subtitles << "Tenant: #{account['name']}".strip
77
+ end
78
+ if params['global'] && json_response['global']
79
+ subtitles << "(All Tenants)"
67
80
  end
68
81
  subtitles += parse_list_subtitles(options)
69
82
  print_h1 title, subtitles, options
70
83
  if users.empty?
71
84
  print cyan,"No users found.",reset,"\n"
72
85
  else
73
- print_users_table(users, options)
86
+ print cyan
87
+ print as_pretty_table(users, list_user_column_definitions, options)
74
88
  print_results_pagination(json_response)
75
89
  end
76
90
  print reset,"\n"
77
- return 0
78
-
79
- rescue RestClient::Exception => e
80
- print_rest_exception(e, options)
81
- return 1
82
91
  end
92
+ return 0, nil
83
93
  end
84
94
 
85
95
  def count(args)
96
+ params = {}
86
97
  options = {}
87
98
  optparse = Morpheus::Cli::OptionParser.new do |opts|
88
99
  opts.banner = subcommand_usage("[options]")
100
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
101
+ options[:global] = true
102
+ end
89
103
  build_common_options(opts, options, [:account, :query, :remote, :dry_run])
90
104
  opts.footer = "Get the number of users."
91
105
  end
@@ -94,7 +108,7 @@ class Morpheus::Cli::Users
94
108
  begin
95
109
  account = find_account_from_options(options)
96
110
  account_id = account ? account['id'] : nil
97
- params = {}
111
+ params['global'] = true if options[:global]
98
112
  params.merge!(parse_list_options(options))
99
113
  @users_interface.setopts(options)
100
114
  if options[:dry_run]
@@ -118,7 +132,10 @@ class Morpheus::Cli::Users
118
132
  options = {}
119
133
  params = {}
120
134
  optparse = Morpheus::Cli::OptionParser.new do |opts|
121
- opts.banner = subcommand_usage("[username]")
135
+ opts.banner = subcommand_usage("[user]")
136
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
137
+ options[:global] = true
138
+ end
122
139
  opts.on('-p','--permissions', "Display Permissions") do |val|
123
140
  options[:include_features_access] = true
124
141
  params['includeAccess'] = true
@@ -155,82 +172,51 @@ class Morpheus::Cli::Users
155
172
  opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
156
173
  options[:display_none_access] = true
157
174
  end
158
- build_common_options(opts, options, [:account, :json, :yaml, :csv, :fields, :dry_run, :remote])
159
- opts.footer = "Get details about a user." + "\n" +
160
- "[username] is required. This is the username or id of a user."
175
+ build_standard_get_options(opts, options, [:account])
176
+ opts.footer = <<-EOT
177
+ Get details about a user.
178
+ [user] is required. This is the username or id of a user. Supports 1-N arguments.
179
+ EOT
161
180
  end
162
181
  optparse.parse!(args)
163
-
164
- if args.count < 1
165
- puts optparse
166
- return 1
167
- end
168
-
182
+ verify_args!(args:args, optparse:optparse, min:1)
169
183
  connect(options)
170
- begin
171
- account = find_account_from_options(options)
172
- account_id = account ? account['id'] : nil
173
- @users_interface.setopts(options)
174
- if options[:dry_run]
175
- if args[0].to_s =~ /\A\d{1,}\Z/
176
- print_dry_run @users_interface.dry.get(account_id, args[0].to_i, params)
177
- else
178
- print_dry_run @users_interface.dry.get(account_id, {username: args[0]}, params)
179
- end
180
- return
181
- end
184
+ id_list = parse_id_list(args)
185
+ return run_command_for_each_arg(id_list) do |arg|
186
+ _get(arg, params, options)
187
+ end
188
+ end
182
189
 
190
+ def _get(id, params, options={})
191
+ args = [id] # heh
192
+ account = find_account_from_options(options)
193
+ account_id = account ? account['id'] : nil
194
+ params['global'] = true if options[:global]
195
+ @users_interface.setopts(options)
196
+ if options[:dry_run]
183
197
  if args[0].to_s =~ /\A\d{1,}\Z/
184
- user_id = args[0].to_i
198
+ print_dry_run @users_interface.dry.get(account_id, args[0].to_i, params)
185
199
  else
186
- user = find_user_by_username(account_id, args[0])
187
-
188
- if user.nil?
189
- print_red_alert "User #{args[0]} not found"
190
- exit 1
191
- end
192
- user_id = user['id']
193
- end
194
-
195
- user = @users_interface.get(account_id, user_id, params)['user']
196
-
197
- if user.nil?
198
- print_red_alert "User #{args[0]} not found"
199
- exit 1
200
+ print_dry_run @users_interface.dry.list(account_id, params.merge({username: args[0]}))
200
201
  end
202
+ return
203
+ end
201
204
 
205
+ if args[0].to_s =~ /\A\d{1,}\Z/
206
+ user_id = args[0].to_i
207
+ else
208
+ user = find_user_by_username(account_id, args[0], params)
209
+ return 1 if user.nil?
210
+ user_id = user['id']
211
+ end
212
+ # always get by id, index does not return 'access'
213
+ json_response = @users_interface.get(account_id, user_id, params)
214
+ user = json_response['user']
215
+ render_response(json_response, options, "user") do
202
216
  is_tenant_account = current_account['id'] != user['account']['id']
203
-
204
- json_response = {'user' => user}
205
-
206
- if options[:json]
207
- puts as_json(json_response, options, "user")
208
- return 0
209
- elsif options[:yaml]
210
- puts as_yaml(json_response, options, "user")
211
- return 0
212
- elsif options[:csv]
213
- puts records_as_csv([user], options)
214
- return 0
215
- end
216
-
217
217
  print_h1 "User Details", options
218
218
  print cyan
219
- description_cols = {
220
- "ID" => 'id',
221
- "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
222
- "First Name" => 'firstName',
223
- "Last Name" => 'lastName',
224
- # "Name" => 'displayName',
225
- #"Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
226
- "Username" => 'username',
227
- "Email" => 'email',
228
- "Notifications" => lambda {|it| it['receiveNotifications'].nil? ? '' : format_boolean(it['receiveNotifications']) },
229
- "Role" => lambda {|it| format_user_role_names(it) },
230
- "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
231
- "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
232
- }
233
- print_description_list(description_cols, user)
219
+ print_description_list(user_column_definitions, user)
234
220
 
235
221
  # backward compatibility
236
222
  if user['access'].nil? && options[:include_features_access]
@@ -288,24 +274,25 @@ class Morpheus::Cli::Users
288
274
  end
289
275
  end
290
276
  end
291
- print cyan
292
277
  print reset,"\n"
293
- rescue RestClient::Exception => e
294
- print_rest_exception(e, options)
295
- return 1
296
278
  end
279
+ return 0
297
280
  end
298
281
 
299
282
  def permissions(args)
283
+ params = {}
300
284
  options = {}
301
285
  optparse = Morpheus::Cli::OptionParser.new do |opts|
302
- opts.banner = subcommand_usage("[username]")
286
+ opts.banner = subcommand_usage("[user]")
287
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
288
+ options[:global] = true
289
+ end
303
290
  build_common_options(opts, options, [:account, :json, :yaml, :csv, :fields, :dry_run, :remote])
304
291
  opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
305
292
  options[:display_none_access] = true
306
293
  end
307
294
  opts.footer = "Display Access for a user." + "\n" +
308
- "[username] is required. This is the username or id of a user."
295
+ "[user] is required. This is the username or id of a user."
309
296
  end
310
297
  optparse.parse!(args)
311
298
  verify_args!(args:args, optparse:optparse, count:1)
@@ -314,7 +301,8 @@ class Morpheus::Cli::Users
314
301
  begin
315
302
  account = find_account_from_options(options)
316
303
  account_id = account ? account['id'] : nil
317
- user = find_user_by_username_or_id(account_id, args[0])
304
+ params['global'] = true if options[:global]
305
+ user = find_user_by_username_or_id(account_id, args[0], params)
318
306
  return 1 if user.nil?
319
307
  @users_interface.setopts(options)
320
308
  if options[:dry_run]
@@ -414,10 +402,11 @@ class Morpheus::Cli::Users
414
402
  optparse = Morpheus::Cli::OptionParser.new do |opts|
415
403
  opts.banner = subcommand_usage("[username] [email] [first] [last] [options]")
416
404
  build_option_type_options(opts, options, add_user_option_types)
405
+ build_option_type_options(opts, options, add_user_advanced_option_types)
417
406
  build_common_options(opts, options, [:account, :options, :payload, :json, :dry_run])
418
407
  opts.footer = <<-EOT
419
408
  Create a new user.
420
- [username] is required. Username of the new user
409
+ [user] is required. Username of the new user
421
410
  [email] is required. Email address
422
411
  [first] is optional. First Name
423
412
  [last] is optional. Last Name
@@ -429,6 +418,9 @@ EOT
429
418
  options[:options]['email'] = args[1] if args[1]
430
419
  options[:options]['firstName'] = args[2] if args[2]
431
420
  options[:options]['lastName'] = args[3] if args[3]
421
+ if options[:options]['password']
422
+ options[:options]['passwordConfirmation'] = options[:options]['password']
423
+ end
432
424
  connect(options)
433
425
  begin
434
426
 
@@ -438,24 +430,27 @@ EOT
438
430
  payload = {}
439
431
  if options[:payload]
440
432
  payload = options[:payload]
441
- payload.deep_merge!(parse_passed_options(options))
433
+ payload.deep_merge!({'user' => parse_passed_options(options)})
442
434
  else
443
- # merge -O options into normally parsed options
444
- payload.deep_merge!(parse_passed_options(options))
435
+ payload.deep_merge!({'user' => parse_passed_options(options)})
445
436
  # remove role option_type, it is just for help display, the role prompt is separate down below
446
- prompt_option_types = add_user_option_types().reject {|it| 'role' == it['fieldName'] }
437
+ prompt_option_types = add_user_option_types().reject {|it| 'roles' == it['fieldName'] }
447
438
  v_prompt = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, options[:options], @api_client, options[:params])
448
439
  params.deep_merge!(v_prompt)
449
-
440
+ # do not prompt for advanced options
441
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_user_advanced_option_types, options[:options], @api_client, options[:params])
442
+ advanced_config.deep_compact!
443
+ params.deep_merge!(advanced_config)
450
444
  # prompt for roles
451
445
  selected_roles = []
452
- selected_roles += params.delete('role').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if params['role']
453
- selected_roles += params.delete('roles').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if params['roles']
446
+ selected_roles += payload['user'].delete('roleId').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['roleId']
447
+ selected_roles += payload['user'].delete('role').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['role']
448
+ selected_roles += payload['user'].delete('roles').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['roles']
454
449
  roles = prompt_user_roles(account_id, nil, selected_roles, options)
455
450
  if !roles.empty?
456
451
  params['roles'] = roles.collect {|r| {id: r['id']} }
457
- end
458
- payload = {'user' => params}
452
+ end
453
+ payload['user'].deep_merge!(params)
459
454
  end
460
455
  if options[:dry_run] && options[:json]
461
456
  puts as_json(payload, options)
@@ -471,21 +466,16 @@ EOT
471
466
  print JSON.pretty_generate(json_response)
472
467
  print "\n"
473
468
  else
474
- username = "" # json_response['user']['username']
475
- username = payload['user']['username'] if payload['user'] && payload['user']['username']
476
- if account
477
- print_green_success "Added user #{username} to account #{account['name']}"
478
- else
479
- print_green_success "Added user #{username}"
480
- end
481
- details_options = [username]
482
- if account
483
- details_options.push "--account-id", account['id'].to_s
469
+ user = json_response['user']
470
+ username = "" # json_response['user']['username']
471
+ username = user['username'] if user
472
+ if account
473
+ print_green_success "Added user #{username} to account #{account['name']}"
474
+ else
475
+ print_green_success "Added user #{username}"
476
+ end
477
+ return _get(user['id'], {}, options)
484
478
  end
485
- get(details_options + (options[:remote] ? ["-r",options[:remote]] : []))
486
- end
487
-
488
-
489
479
  rescue RestClient::Exception => e
490
480
  print_rest_exception(e, options)
491
481
  return 1
@@ -497,8 +487,12 @@ EOT
497
487
  params = {}
498
488
  payload = {}
499
489
  optparse = Morpheus::Cli::OptionParser.new do |opts|
500
- opts.banner = subcommand_usage("[username] [options]")
490
+ opts.banner = subcommand_usage("[user] [options]")
491
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
492
+ options[:global] = true
493
+ end
501
494
  build_option_type_options(opts, options, update_user_option_types)
495
+ build_option_type_options(opts, options, update_user_advanced_option_types)
502
496
  build_common_options(opts, options, [:account, :options, :payload, :json, :dry_run])
503
497
  end
504
498
  optparse.parse!(args)
@@ -508,26 +502,38 @@ EOT
508
502
 
509
503
  account = find_account_from_options(options)
510
504
  account_id = account ? account['id'] : nil
511
-
512
- user = find_user_by_username_or_id(account_id, args[0])
505
+ params['global'] = true if options[:global]
506
+ user = find_user_by_username_or_id(account_id, args[0], params)
513
507
  return 1 if user.nil?
514
508
 
515
509
  # use --payload
510
+ payload = {}
516
511
  if options[:payload]
517
512
  payload = options[:payload]
518
- payload.deep_merge!(parse_passed_options(options))
513
+ payload.deep_merge!({'user' => parse_passed_options(options)})
519
514
  else
520
- # inject -O key=value options
521
- # payload.deep_merge!(parse_passed_options(options))
522
- params.deep_merge!(parse_passed_options(options))
523
- # user_prompt_output = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, payload['user'], @api_client)
515
+ payload.deep_merge!({'user' => parse_passed_options(options)})
516
+
517
+ # remove role option_type, it is just for help display, the role prompt is separate down below
518
+ prompt_option_types = update_user_option_types().reject {|it| 'roles' == it['fieldName'] }
519
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(prompt_option_types, options[:options], @api_client, options[:params])
520
+ v_prompt.deep_compact!
521
+ params.deep_merge!(v_prompt)
522
+ # do not prompt for advanced options
523
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_user_advanced_option_types, options[:options], @api_client, options[:params])
524
+ advanced_config.deep_compact!
525
+ params.deep_merge!(advanced_config)
526
+
524
527
  selected_roles = []
525
- selected_roles += params.delete('role').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if params['role']
526
- selected_roles += params.delete('roles').split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if params['roles']
527
- roles = prompt_user_roles(account_id, user['id'], selected_roles, options.merge(no_prompt: true))
528
- # should it allow [] (no roles) ?
529
- if !roles.empty?
530
- params['roles'] = roles.collect {|r| {id: r['id']} }
528
+ selected_roles += payload['user'].delete('roleId').to_s.split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['roleId']
529
+ selected_roles += payload['user'].delete('role').to_s.split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['role']
530
+ selected_roles += payload['user'].delete('roles').to_s.split(',').collect {|r| r.strip.empty? ? nil : r.strip}.uniq if payload['user']['roles']
531
+ if !selected_roles.empty?
532
+ roles = prompt_user_roles(account_id, user['id'], selected_roles, options.merge(no_prompt: true))
533
+ # should it allow [] (no roles) ?
534
+ if !roles.empty?
535
+ params['roles'] = roles.collect {|r| {id: r['id']} }
536
+ end
531
537
  end
532
538
  payload.deep_merge!({'user' => params})
533
539
  if payload['user'].empty? # || options[:no_prompt]
@@ -541,7 +547,7 @@ EOT
541
547
  return
542
548
  end
543
549
  json_response = @users_interface.update(account_id, user['id'], payload)
544
-
550
+ user = json_response['user']
545
551
  if options[:json]
546
552
  print JSON.pretty_generate(json_response)
547
553
  print "\n"
@@ -551,13 +557,13 @@ EOT
551
557
  username = payload['user']['username']
552
558
  end
553
559
  print_green_success "Updated user #{username}"
554
- details_options = [username]
555
- if account
556
- details_options.push "--account-id", account['id'].to_s
557
- end
558
- get(details_options + (options[:remote] ? ["-r",options[:remote]] : []))
560
+ # details_options = [username]
561
+ # if account
562
+ # details_options.push "--account-id", account['id'].to_s
563
+ # end
564
+ # get(details_options + (options[:remote] ? ["-r",options[:remote]] : []))
565
+ return _get(user["id"], {}, options)
559
566
  end
560
-
561
567
  rescue RestClient::Exception => e
562
568
  print_rest_exception(e, options)
563
569
  return 1
@@ -565,26 +571,30 @@ EOT
565
571
  end
566
572
 
567
573
  def change_password(args)
574
+ params = {}
568
575
  options = {}
569
576
  new_password = nil
570
577
  optparse = Morpheus::Cli::OptionParser.new do |opts|
571
- opts.banner = subcommand_usage("[username] [password] [options]")
578
+ opts.banner = subcommand_usage("[user] [password] [options]")
579
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
580
+ options[:global] = true
581
+ end
572
582
  # opts.on('--password VALUE', String, "New password") do |val|
573
583
  # new_password = val
574
584
  # end
575
585
  build_standard_update_options(opts, options, [:account])
576
586
  end
577
587
  optparse.parse!(args)
578
- verify_args!(args:args, optparse:optparse, min:1,max:2) # [username] [password]
588
+ verify_args!(args:args, optparse:optparse, min:1,max:2) # [user] [password]
579
589
  connect(options)
580
590
  exit_code, err = 0, nil
581
591
 
582
592
  # user can be scoped to account (tenant)
583
593
  account = find_account_from_options(options)
584
594
  account_id = account ? account['id'] : nil
585
-
595
+ params['global'] = true if options[:global]
586
596
  # fetch the user to update
587
- user = find_user_by_username_or_id(account_id, args[0])
597
+ user = find_user_by_username_or_id(account_id, args[0], params)
588
598
  return 1 if user.nil?
589
599
 
590
600
  new_password = args[1] if args[1]
@@ -644,10 +654,14 @@ EOT
644
654
  end
645
655
 
646
656
  def remove(args)
657
+ params = {}
647
658
  options = {}
648
659
  optparse = Morpheus::Cli::OptionParser.new do |opts|
649
- opts.banner = subcommand_usage("[username]")
650
- build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
660
+ opts.banner = subcommand_usage("[user]")
661
+ opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
662
+ options[:global] = true
663
+ end
664
+ build_standard_remove_options(opts, options, [:account])
651
665
  end
652
666
  optparse.parse!(args)
653
667
 
@@ -658,19 +672,18 @@ EOT
658
672
 
659
673
  connect(options)
660
674
  begin
661
-
662
675
  account = find_account_from_options(options)
663
676
  account_id = account ? account['id'] : nil
664
-
665
- user = find_user_by_username_or_id(account_id, args[0])
677
+ params['global'] = true if options[:global]
678
+ user = find_user_by_username_or_id(account_id, args[0], params)
666
679
  return 1 if user.nil?
667
680
  unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the user #{user['username']}?")
668
- exit
681
+ exit 9, "arborted"
669
682
  end
670
683
  @users_interface.setopts(options)
671
684
  if options[:dry_run]
672
685
  print_dry_run @users_interface.dry.destroy(account_id, user['id'])
673
- return
686
+ return 0
674
687
  end
675
688
  json_response = @users_interface.destroy(account_id, user['id'])
676
689
 
@@ -697,19 +710,33 @@ EOT
697
710
  {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'displayOrder' => 4},
698
711
  {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 5},
699
712
  {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
700
- {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'description' => "Role names (comma separated)", 'displayOrder' => 7},
701
- {'fieldName' => 'receiveNotifications', 'fieldLabel' => 'Receive Notifications?', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'displayOrder' => 58},
713
+ {'fieldName' => 'roles', 'fieldLabel' => 'Roles', 'type' => 'text', 'description' => "Role authorities or IDs (comma separated)", 'displayOrder' => 7},
714
+ {'fieldName' => 'receiveNotifications', 'fieldLabel' => 'Receive Notifications?', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'displayOrder' => 8}
715
+ ]
716
+ end
717
+
718
+ def add_user_advanced_option_types
719
+ [
702
720
  {'fieldName' => 'linuxUsername', 'fieldLabel' => 'Linux Username', 'type' => 'text', 'required' => false, 'displayOrder' => 9},
703
- # {'fieldName' => 'linuxPassword', 'fieldLabel' => 'Linux Password', 'type' => 'password', 'required' => false, 'displayOrder' => 10},
704
- {'fieldName' => 'windowsUsername', 'fieldLabel' => 'Windows Username', 'type' => 'text', 'required' => false, 'displayOrder' => 11},
705
- # {'fieldName' => 'windowsPassword', 'fieldLabel' => 'Windows Password', 'type' => 'text', 'required' => false, 'displayOrder' => 12},
706
- # 'linuxUsername','windowsUsername','linuxKeyPairId'
721
+ {'fieldName' => 'linuxPassword', 'fieldLabel' => 'Linux Password', 'type' => 'password', 'required' => false, 'displayOrder' => 10},
722
+ {'fieldName' => 'linuxKeyPairId', 'fieldLabel' => 'SSH Key', 'type' => 'select', 'optionSource' => 'keyPairs', 'required' => false, 'displayOrder' => 11},
723
+ {'fieldName' => 'windowsUsername', 'fieldLabel' => 'Windows Username', 'type' => 'text', 'required' => false, 'displayOrder' => 12},
724
+ {'fieldName' => 'windowsPassword', 'fieldLabel' => 'Windows Password', 'type' => 'text', 'required' => false, 'displayOrder' => 13},
707
725
  ]
708
726
  end
709
727
 
710
728
  def update_user_option_types
711
729
  add_user_option_types.collect {|it|
712
- it['required'] = false
730
+ it.delete('required')
731
+ it.delete('defaultValue')
732
+ it
733
+ }
734
+ end
735
+
736
+ def update_user_advanced_option_types
737
+ add_user_advanced_option_types.collect {|it|
738
+ it.delete('required')
739
+ it.delete('defaultValue')
713
740
  it
714
741
  }
715
742
  end
@@ -732,7 +759,7 @@ EOT
732
759
 
733
760
  if available_roles.empty?
734
761
  print_red_alert "No available roles found."
735
- return 1
762
+ exit 1
736
763
  end
737
764
  role_options = available_roles.collect {|role|
738
765
  {'name' => role['authority'], 'value' => role['id']}
@@ -754,30 +781,27 @@ EOT
754
781
  print_red_alert "Invalid Roles: #{invalid_role_names.join(', ')}"
755
782
  exit 1
756
783
  end
757
- end
758
-
759
- if roles.empty?
784
+ else
760
785
  no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
761
- if !no_prompt
762
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => true}], options[:options])
763
- role_id = v_prompt['roleId']
764
- roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
765
- add_another_role = true
766
- while add_another_role do
767
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Another Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => false}], options[:options])
768
- if v_prompt['roleId'].to_s.empty?
769
- add_another_role = false
770
- else
771
- role_id = v_prompt['roleId']
772
- roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
773
- end
774
- end
786
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roles', 'fieldLabel' => 'Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => true}], options[:options])
787
+ role_id = v_prompt['roles']
788
+ roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
789
+ add_another_role = !no_prompt
790
+ while add_another_role do
791
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roles', 'fieldLabel' => 'Another Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => false}], options[:options])
792
+ if v_prompt['roles'].to_s.empty?
793
+ add_another_role = false
794
+ else
795
+ role_id = v_prompt['roles']
796
+ roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
775
797
  end
776
798
  end
777
-
778
- roles = roles.compact
779
- return roles
780
-
799
+
781
800
  end
782
801
 
802
+ roles = roles.compact
803
+ return roles
804
+
783
805
  end
806
+
807
+ end