morpheus-cli 2.10.0 → 2.10.1

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/morpheus +27 -32
  3. data/lib/morpheus/api/accounts_interface.rb +36 -47
  4. data/lib/morpheus/api/api_client.rb +141 -110
  5. data/lib/morpheus/api/app_templates_interface.rb +56 -72
  6. data/lib/morpheus/api/apps_interface.rb +111 -132
  7. data/lib/morpheus/api/auth_interface.rb +30 -0
  8. data/lib/morpheus/api/clouds_interface.rb +71 -76
  9. data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
  10. data/lib/morpheus/api/dashboard_interface.rb +10 -17
  11. data/lib/morpheus/api/deploy_interface.rb +60 -72
  12. data/lib/morpheus/api/deployments_interface.rb +53 -71
  13. data/lib/morpheus/api/groups_interface.rb +55 -45
  14. data/lib/morpheus/api/instance_types_interface.rb +19 -23
  15. data/lib/morpheus/api/instances_interface.rb +179 -177
  16. data/lib/morpheus/api/key_pairs_interface.rb +11 -17
  17. data/lib/morpheus/api/license_interface.rb +18 -23
  18. data/lib/morpheus/api/load_balancers_interface.rb +54 -69
  19. data/lib/morpheus/api/logs_interface.rb +25 -29
  20. data/lib/morpheus/api/options_interface.rb +13 -17
  21. data/lib/morpheus/api/provision_types_interface.rb +19 -22
  22. data/lib/morpheus/api/roles_interface.rb +75 -94
  23. data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
  24. data/lib/morpheus/api/security_groups_interface.rb +39 -51
  25. data/lib/morpheus/api/servers_interface.rb +113 -115
  26. data/lib/morpheus/api/setup_interface.rb +31 -0
  27. data/lib/morpheus/api/task_sets_interface.rb +36 -38
  28. data/lib/morpheus/api/tasks_interface.rb +56 -69
  29. data/lib/morpheus/api/users_interface.rb +67 -76
  30. data/lib/morpheus/api/virtual_images_interface.rb +61 -61
  31. data/lib/morpheus/api/whoami_interface.rb +12 -15
  32. data/lib/morpheus/cli.rb +71 -60
  33. data/lib/morpheus/cli/accounts.rb +254 -315
  34. data/lib/morpheus/cli/alias_command.rb +219 -0
  35. data/lib/morpheus/cli/app_templates.rb +264 -272
  36. data/lib/morpheus/cli/apps.rb +608 -671
  37. data/lib/morpheus/cli/cli_command.rb +259 -21
  38. data/lib/morpheus/cli/cli_registry.rb +99 -14
  39. data/lib/morpheus/cli/clouds.rb +599 -372
  40. data/lib/morpheus/cli/config_file.rb +126 -0
  41. data/lib/morpheus/cli/credentials.rb +141 -117
  42. data/lib/morpheus/cli/dashboard_command.rb +48 -56
  43. data/lib/morpheus/cli/deployments.rb +254 -268
  44. data/lib/morpheus/cli/deploys.rb +150 -142
  45. data/lib/morpheus/cli/error_handler.rb +38 -0
  46. data/lib/morpheus/cli/groups.rb +551 -179
  47. data/lib/morpheus/cli/hosts.rb +862 -617
  48. data/lib/morpheus/cli/instance_types.rb +103 -95
  49. data/lib/morpheus/cli/instances.rb +1335 -1009
  50. data/lib/morpheus/cli/key_pairs.rb +82 -90
  51. data/lib/morpheus/cli/library.rb +498 -499
  52. data/lib/morpheus/cli/license.rb +83 -101
  53. data/lib/morpheus/cli/load_balancers.rb +314 -300
  54. data/lib/morpheus/cli/login.rb +66 -44
  55. data/lib/morpheus/cli/logout.rb +47 -46
  56. data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
  57. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
  58. data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
  59. data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
  60. data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
  61. data/lib/morpheus/cli/option_parser.rb +35 -0
  62. data/lib/morpheus/cli/option_types.rb +232 -192
  63. data/lib/morpheus/cli/recent_activity_command.rb +61 -65
  64. data/lib/morpheus/cli/remote.rb +446 -199
  65. data/lib/morpheus/cli/roles.rb +884 -906
  66. data/lib/morpheus/cli/security_group_rules.rb +213 -203
  67. data/lib/morpheus/cli/security_groups.rb +237 -192
  68. data/lib/morpheus/cli/shell.rb +338 -231
  69. data/lib/morpheus/cli/tasks.rb +326 -308
  70. data/lib/morpheus/cli/users.rb +457 -462
  71. data/lib/morpheus/cli/version.rb +1 -1
  72. data/lib/morpheus/cli/version_command.rb +16 -18
  73. data/lib/morpheus/cli/virtual_images.rb +526 -345
  74. data/lib/morpheus/cli/whoami.rb +125 -111
  75. data/lib/morpheus/cli/workflows.rb +338 -185
  76. data/lib/morpheus/formatters.rb +8 -1
  77. data/lib/morpheus/logging.rb +1 -1
  78. data/lib/morpheus/rest_client.rb +17 -8
  79. metadata +9 -3
  80. data/lib/morpheus/api/custom_instance_types.rb +0 -55
@@ -10,911 +10,889 @@ require 'json'
10
10
  class Morpheus::Cli::Roles
11
11
  include Morpheus::Cli::CliCommand
12
12
  include Morpheus::Cli::AccountsHelper
13
-
14
- def initialize()
15
- @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
- #@active_groups = ::Morpheus::Cli::Groups.load_group_file
17
- end
18
-
19
- def connect(opts)
20
- @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
21
- if @access_token.empty?
22
- print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
23
- exit 1
24
- end
25
- @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
26
- @whoami_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).whoami
27
- @users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
28
- @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
29
- @roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
30
- @active_groups = ::Morpheus::Cli::Groups.load_group_file
31
- @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
32
- @options_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).options
33
- #@clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
34
- @instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
35
-
36
- end
37
-
38
- def handle(args)
39
- usage = "Usage: morpheus roles [list,details,add,update,remove,update-feature-access,update-global-group-access,update-group-access,update-global-cloud-access,update-cloud-access,update-global-instance-type-access,update-instance-type-access] [name]"
40
- if args.empty?
41
- puts "\n#{usage}\n\n"
42
- exit 1
43
- end
44
-
45
- case args[0]
46
- when 'list'
47
- list(args[1..-1])
48
- when 'details'
49
- details(args[1..-1])
50
- when 'add'
51
- add(args[1..-1])
52
- when 'update'
53
- update(args[1..-1])
54
- when 'remove'
55
- remove(args[1..-1])
56
- when 'update-feature-access'
57
- update_feature_access(args[1..-1])
58
- when 'update-global-group-access'
59
- update_global_group_access(args[1..-1])
60
- when 'update-group-access'
61
- update_group_access(args[1..-1])
62
- when 'update-global-cloud-access'
63
- update_global_cloud_access(args[1..-1])
64
- when 'update-cloud-access'
65
- update_cloud_access(args[1..-1])
66
- when 'update-global-instance-type-access'
67
- update_global_instance_type_access(args[1..-1])
68
- when 'update-instance-type-access'
69
- update_instance_type_access(args[1..-1])
70
- else
71
- puts "\n#{usage}\n\n"
72
- exit 127
73
- end
74
- end
75
-
76
- def list(args)
77
- usage = "Usage: morpheus roles list"
78
- options = {}
79
- optparse = OptionParser.new do|opts|
80
- opts.banner = usage
81
- build_common_options(opts, options, [:list, :json])
82
- end
83
- optparse.parse(args)
84
-
85
- connect(options)
86
- begin
87
-
88
- load_whoami()
89
-
90
- account = find_account_from_options(options)
91
- account_id = account ? account['id'] : nil
92
-
93
- params = {}
94
- [:phrase, :offset, :max, :sort, :direction].each do |k|
95
- params[k] = options[k] unless options[k].nil?
96
- end
97
-
98
- json_response = @roles_interface.list(account_id, params)
99
- roles = json_response['roles']
100
-
101
- if options[:json]
102
- print JSON.pretty_generate(json_response)
103
- print "\n"
104
- else
105
- print "\n" ,cyan, bold, "Morpheus Roles\n","==================", reset, "\n\n"
106
- if roles.empty?
107
- puts yellow,"No roles found.",reset
108
- else
109
- print_roles_table(roles, {is_master_account: @is_master_account})
110
- end
111
- print reset,"\n\n"
112
- end
113
- rescue RestClient::Exception => e
114
- print_rest_exception(e, options)
115
- exit 1
116
- end
117
- end
118
-
119
- def details(args)
120
- usage = "Usage: morpheus roles details [name]"
121
- options = {}
122
- optparse = OptionParser.new do|opts|
123
- opts.banner = usage
124
- opts.on(nil,'--feature-access', "Display Feature Access") do |val|
125
- options[:include_feature_access] = true
126
- end
127
- opts.on(nil,'--group-access', "Display Group Access") do
128
- options[:include_group_access] = true
129
- end
130
- opts.on(nil,'--cloud-access', "Display Cloud Access") do
131
- options[:include_cloud_access] = true
132
- end
133
- opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
134
- options[:include_instance_type_access] = true
135
- end
136
- opts.on(nil,'--all-access', "Display All Access Lists") do
137
- options[:include_feature_access] = true
138
- options[:include_group_access] = true
139
- options[:include_cloud_access] = true
140
- options[:include_instance_type_access] = true
141
- end
142
- build_common_options(opts, options, [:json])
143
- end
144
- optparse.parse(args)
145
-
146
- if args.count < 1
147
- puts "\n#{usage}\n\n"
148
- exit 1
149
- end
150
- name = args[0]
151
-
152
- connect(options)
153
- begin
154
-
155
- account = find_account_from_options(options)
156
- account_id = account ? account['id'] : nil
157
-
158
- role = find_role_by_name(account_id, name)
159
- exit 1 if role.nil?
160
-
161
- json_response = @roles_interface.get(account_id, role['id'])
162
- role = json_response['role']
163
-
164
- if options[:json]
165
- print JSON.pretty_generate(json_response)
166
- print "\n"
167
- else
168
- print "\n" ,cyan, bold, "Role Details\n","==================", reset, "\n\n"
169
- print cyan
170
- puts "ID: #{role['id']}"
171
- puts "Name: #{role['authority']}"
172
- puts "Description: #{role['description']}"
173
- puts "Scope: #{role['scope']}"
174
- puts "Type: #{format_role_type(role)}"
175
- puts "Multitenant: #{role['multitenant'] ? 'Yes' : 'No'}"
176
- puts "Owner: #{role['owner'] ? role['owner']['name'] : nil}"
177
- puts "Date Created: #{format_local_dt(role['dateCreated'])}"
178
- puts "Last Updated: #{format_local_dt(role['lastUpdated'])}"
179
-
180
- print "\n" ,cyan, bold, "Role Instance Limits\n","==================", reset, "\n\n"
181
- print cyan
182
- puts "Max Storage (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxStorage'] : 0}"
183
- puts "Max Memory (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxMemory'] : 0}"
184
- puts "CPU Count: #{role['instanceLimits'] ? role['instanceLimits']['maxCpu'] : 0}"
185
-
186
- print "\n" ,cyan, bold, "Feature Access\n","==================", reset, "\n\n"
187
- print cyan
188
-
189
- if options[:include_feature_access]
190
- rows = json_response['featurePermissions'].collect do |it|
191
- {
192
- code: it['code'],
193
- name: it['name'],
194
- access: get_access_string(it['access']),
195
- }
196
- end
197
- tp rows, [:code, :name, :access]
198
- else
199
- puts "Use --feature-access to list feature access"
200
- end
201
-
202
- print "\n" ,cyan, bold, "Group Access\n","==================", reset, "\n\n"
203
- print cyan
204
-
205
- puts "Global Group Access: #{get_access_string(json_response['globalSiteAccess'])}\n\n"
206
- if json_response['globalSiteAccess'] == 'custom'
207
- if options[:include_group_access]
208
- rows = json_response['sites'].collect do |it|
209
- {
210
- name: it['name'],
211
- access: get_access_string(it['access']),
212
- }
213
- end
214
- tp rows, [:name, :access]
215
- else
216
- puts "Use --group-access to list custom access"
217
- end
218
- end
219
-
220
- print "\n" ,cyan, bold, "Cloud Access\n","==================", reset, "\n\n"
221
- print cyan
222
-
223
- puts "Global Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}\n\n"
224
- if json_response['globalZoneAccess'] == 'custom'
225
- if options[:include_cloud_access]
226
- rows = json_response['zones'].collect do |it|
227
- {
228
- name: it['name'],
229
- access: get_access_string(it['access']),
230
- }
231
- end
232
- tp rows, [:name, :access]
233
- else
234
- puts "Use --cloud-access to list custom access"
235
- end
236
- end
237
-
238
- print "\n" ,cyan, bold, "Instance Type Access\n","==================", reset, "\n\n"
239
- print cyan
240
-
241
- puts "Global Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}\n\n"
242
- if json_response['globalInstanceTypeAccess'] == 'custom'
243
- if options[:include_instance_type_access]
244
- rows = json_response['instanceTypePermissions'].collect do |it|
245
- {
246
- name: it['name'],
247
- access: get_access_string(it['access']),
248
- }
249
- end
250
- tp rows, [:name, :access]
251
- else
252
- puts "Use --instance-type-access to list custom access"
253
- end
254
- end
255
-
256
- print reset,"\n\n"
257
- end
258
- rescue RestClient::Exception => e
259
- print_rest_exception(e, options)
260
- exit 1
261
- end
262
- end
263
-
264
- def add(args)
265
- usage = "Usage: morpheus roles add [options]"
266
- options = {}
267
- optparse = OptionParser.new do|opts|
268
- opts.banner = usage
269
- build_common_options(opts, options, [:options, :json])
270
- end
271
- optparse.parse(args)
272
-
273
- connect(options)
274
- begin
275
-
276
- load_whoami()
277
-
278
- account = find_account_from_options(options)
279
- account_id = account ? account['id'] : nil
280
-
281
- # argh, some options depend on others here...eg. multitenant is only available when roleType == 'user'
282
- #prompt_option_types = update_role_option_types()
283
-
284
- role_payload = {}
285
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1}], options[:options])
286
- role_payload['authority'] = v_prompt['authority']
287
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2}], options[:options])
288
- role_payload['description'] = v_prompt['description']
289
-
290
- if @is_master_account
291
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleType', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => role_type_options, 'defaultValue' => 'user', 'displayOrder' => 3}], options[:options])
292
- role_payload['roleType'] = v_prompt['roleType']
293
- else
294
- role_payload['roleType'] = 'user'
295
- end
296
-
297
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4}], options[:options])
298
- if v_prompt['baseRole'].to_s != ''
299
- base_role = find_role_by_name(account_id, v_prompt['baseRole'])
300
- exit 1 if base_role.nil?
301
- role_payload['baseRoleId'] = base_role['id']
302
- end
303
-
304
- if @is_master_account
305
- if role_payload['roleType'] == 'user'
306
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use', 'displayOrder' => 5}], options[:options])
307
- role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
308
- end
309
- end
310
-
311
- role_payload['instanceLimits'] = {}
312
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8}], options[:options])
313
- if v_prompt['instanceLimits.maxStorage'].to_s.strip != ''
314
- role_payload['instanceLimits']['maxStorage'] = v_prompt['instanceLimits.maxStorage'].to_i
315
- end
316
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9}], options[:options])
317
- if v_prompt['instanceLimits.maxMemory'].to_s.strip != ''
318
- role_payload['instanceLimits']['maxMemory'] = v_prompt['instanceLimits.maxMemory'].to_i
319
- end
320
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10}], options[:options])
321
- if v_prompt['instanceLimits.maxCpu'].to_s.strip != ''
322
- role_payload['instanceLimits']['maxCpu'] = v_prompt['instanceLimits.maxCpu'].to_i
323
- end
324
-
325
- request_payload = {role: role_payload}
326
- response = @roles_interface.create(account_id, request_payload)
327
-
328
- if account
329
- print_green_success "Added role #{role_payload['authority']} to account #{account['name']}"
330
- else
331
- print_green_success "Added role #{role_payload['authority']}"
332
- end
333
-
334
- details_options = [role_payload["authority"]]
335
- if account
336
- details_options.push "--account-id", account['id'].to_s
337
- end
338
- details(details_options)
339
-
340
- rescue RestClient::Exception => e
341
- print_rest_exception(e, options)
342
- exit 1
343
- end
344
- end
345
-
346
- def update(args)
347
- usage = "Usage: morpheus roles update [name] [options]"
348
- options = {}
349
- optparse = OptionParser.new do|opts|
350
- opts.banner = usage
351
- build_common_options(opts, options, [:options, :json])
352
- end
353
- optparse.parse(args)
354
-
355
- if args.count < 1
356
- puts "\n#{usage}\n\n"
357
- exit 1
358
- end
359
- name = args[0]
360
-
361
- connect(options)
362
-
363
- begin
364
-
365
- load_whoami()
366
-
367
- account = find_account_from_options(options)
368
- account_id = account ? account['id'] : nil
369
-
370
- role = find_role_by_name(account_id, name)
371
- exit 1 if role.nil?
372
-
373
- prompt_option_types = update_role_option_types()
374
- if !@is_master_account
375
- prompt_option_types = prompt_option_types.reject {|it| ['roleType', 'multitenant'].include?(it['fieldName']) }
376
- end
377
- if role['roleType'] != 'user'
378
- prompt_option_types = prompt_option_types.reject {|it| ['multitenant'].include?(it['fieldName']) }
379
- end
380
- #params = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, options[:options], @api_client, options[:params])
381
- params = options[:options] || {}
382
-
383
- if params.empty?
384
- puts "\n#{usage}\n\n"
385
- option_lines = prompt_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
386
- puts "\nAvailable Options:\n#{option_lines}\n\n"
387
- exit 1
388
- end
389
-
390
- #puts "parsed params is : #{params.inspect}"
391
- role_keys = ['authority', 'description', 'instanceLimits']
392
- role_payload = params.select {|k,v| role_keys.include?(k) }
393
- if !role_payload['instanceLimits']
394
- role_payload['instanceLimits'] = {}
395
- role_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
396
- role_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
397
- role_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
398
- end
399
-
400
- if params['multitenant'].to_s != ''
401
- role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
402
- end
403
- request_payload = {role: role_payload}
404
- response = @roles_interface.update(account_id, role['id'], request_payload)
405
-
406
- print_green_success "Updated role #{role_payload['authority']}"
407
-
408
- details_options = [role_payload["authority"] || role['authority']]
409
- if account
410
- details_options.push "--account-id", account['id'].to_s
411
- end
412
- details(details_options)
413
-
414
- rescue RestClient::Exception => e
415
- print_rest_exception(e, options)
416
- exit 1
417
- end
418
- end
419
-
420
- def remove(args)
421
- usage = "Usage: morpheus roles remove [name]"
422
- options = {}
423
- optparse = OptionParser.new do|opts|
424
- opts.banner = usage
425
- build_common_options(opts, options, [:auto_confirm, :json])
426
- end
427
- optparse.parse(args)
428
-
429
- if args.count < 1
430
- puts "\n#{usage}\n\n"
431
- exit 1
432
- end
433
- name = args[0]
434
-
435
- connect(options)
436
- begin
437
-
438
- account = find_account_from_options(options)
439
- account_id = account ? account['id'] : nil
440
-
441
- role = find_role_by_name(account_id, name)
442
- exit 1 if role.nil?
443
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the role #{role['authority']}?")
444
- exit
445
- end
446
- json_response = @roles_interface.destroy(account_id, role['id'])
447
-
448
- if options[:json]
449
- print JSON.pretty_generate(json_response)
450
- print "\n"
451
- else
452
- print_green_success "Role #{role['authority']} removed"
453
- end
454
-
455
- rescue RestClient::Exception => e
456
- print_rest_exception(e, options)
457
- exit 1
458
- end
459
- end
460
-
461
- def update_feature_access(args)
462
- usage = "Usage: morpheus roles update-feature-access [name] [code] [full|read|custom|none]"
463
- options = {}
464
- optparse = OptionParser.new do|opts|
465
- opts.banner = usage
466
- build_common_options(opts, options, [:json])
467
- end
468
- optparse.parse(args)
469
-
470
- if args.count < 3
471
- puts "\n#{usage}\n\n"
472
- exit 1
473
- end
474
- name = args[0]
475
- permission_code = args[1]
476
- access_value = args[2].to_s.downcase
477
- if !['full', 'read', 'custom', 'none'].include?(access_value)
478
- puts "\n#{usage}\n\n"
479
- exit 1
480
- end
481
-
482
- connect(options)
483
- begin
484
-
485
- account = find_account_from_options(options)
486
- account_id = account ? account['id'] : nil
487
-
488
- role = find_role_by_name(account_id, name)
489
- exit 1 if role.nil?
490
-
491
- params = {permissionCode: permission_code, access: access_value}
492
- json_response = @roles_interface.update_permission(account_id, role['id'], params)
493
-
494
- if options[:json]
495
- print JSON.pretty_generate(json_response)
496
- print "\n"
497
- else
498
- print_green_success "Role #{role['authority']} feature access updated"
499
- end
500
-
501
- rescue RestClient::Exception => e
502
- print_rest_exception(e, options)
503
- exit 1
504
- end
505
- end
506
-
507
- def update_global_group_access(args)
508
- usage = "Usage: morpheus roles update-global-group-access [name] [full|read|custom|none]"
509
- options = {}
510
- optparse = OptionParser.new do|opts|
511
- opts.banner = usage
512
- build_common_options(opts, options, [:json])
513
- end
514
- optparse.parse(args)
515
-
516
- if args.count < 2
517
- puts "\n#{usage}\n\n"
518
- exit 1
519
- end
520
- name = args[0]
521
- access_value = args[1].to_s.downcase
522
- if !['full', 'read', 'custom', 'none'].include?(access_value)
523
- puts "\n#{usage}\n\n"
524
- exit 1
525
- end
526
-
527
- connect(options)
528
- begin
529
-
530
- account = find_account_from_options(options)
531
- account_id = account ? account['id'] : nil
532
-
533
- role = find_role_by_name(account_id, name)
534
- exit 1 if role.nil?
535
-
536
- params = {permissionCode: 'ComputeSite', access: access_value}
537
- json_response = @roles_interface.update_permission(account_id, role['id'], params)
538
-
539
- if options[:json]
540
- print JSON.pretty_generate(json_response)
541
- print "\n"
542
- else
543
- print_green_success "Role #{role['authority']} global group access updated"
544
- end
545
-
546
- rescue RestClient::Exception => e
547
- print_rest_exception(e, options)
548
- exit 1
549
- end
550
- end
551
-
552
- def update_group_access(args)
553
- usage = "Usage: morpheus roles update-group-access [name] [group_name] [full|read|none]"
554
- options = {}
555
- optparse = OptionParser.new do|opts|
556
- opts.banner = usage
557
- build_common_options(opts, options, [:json])
558
- end
559
- optparse.parse(args)
560
-
561
- if args.count < 2
562
- puts "\n#{usage}\n\n"
563
- exit 1
564
- end
565
- name = args[0]
566
- group_name = args[1]
567
- access_value = args[2].to_s.downcase
568
- if !['full', 'read', 'none'].include?(access_value)
569
- puts "\n#{usage}\n\n"
570
- exit 1
571
- end
572
-
573
- connect(options)
574
- begin
575
-
576
- account = find_account_from_options(options)
577
- account_id = account ? account['id'] : nil
578
-
579
- role = find_role_by_name(account_id, name)
580
- exit 1 if role.nil?
581
-
582
- role_json = @roles_interface.get(account_id, role['id'])
583
-
584
- if role_json['globalSiteAccess'] != 'custom'
585
- print "\n", red, "Global Group Access is currently: #{role_json['globalSiteAccess'].capitalize}"
586
- print "\n", "You must first set it to Custom via `morpheus roles update-global-group-access \"#{name}\" custom`"
587
- print "\n\n", reset
588
- exit 1
589
- end
590
-
591
- # group_id = find_group_id_by_name(group_name)
592
- # exit 1 if group_id.nil?
593
- group = find_group_by_name(group_name)
594
- exit 1 if group.nil?
595
- group_id = group['id']
596
-
597
- params = {groupId: group_id, access: access_value}
598
- json_response = @roles_interface.update_group(account_id, role['id'], params)
599
-
600
- if options[:json]
601
- print JSON.pretty_generate(json_response)
602
- print "\n"
603
- else
604
- print_green_success "Role #{role['authority']} global group access updated"
605
- end
606
-
607
- rescue RestClient::Exception => e
608
- print_rest_exception(e, options)
609
- exit 1
610
- end
611
- end
612
-
613
- def update_global_cloud_access(args)
614
- usage = "Usage: morpheus roles update-global-cloud-access [name] [full|custom|none]"
615
- options = {}
616
- optparse = OptionParser.new do|opts|
617
- opts.banner = usage
618
- build_common_options(opts, options, [:json])
619
- end
620
- optparse.parse(args)
621
-
622
- if args.count < 2
623
- puts "\n#{usage}\n\n"
624
- exit 1
625
- end
626
- name = args[0]
627
- access_value = args[1].to_s.downcase
628
- if !['full', 'custom', 'none'].include?(access_value)
629
- puts "\n#{usage}\n\n"
630
- exit 1
631
- end
632
-
633
- connect(options)
634
- begin
635
-
636
- account = find_account_from_options(options)
637
- account_id = account ? account['id'] : nil
638
-
639
- role = find_role_by_name(account_id, name)
640
- exit 1 if role.nil?
641
-
642
- params = {permissionCode: 'ComputeZone', access: access_value}
643
- json_response = @roles_interface.update_permission(account_id, role['id'], params)
644
-
645
- if options[:json]
646
- print JSON.pretty_generate(json_response)
647
- print "\n"
648
- else
649
- print_green_success "Role #{role['authority']} global cloud access updated"
650
- end
651
-
652
- rescue RestClient::Exception => e
653
- print_rest_exception(e, options)
654
- exit 1
655
- end
656
- end
657
-
658
- def update_cloud_access(args)
659
- usage = "Usage: morpheus roles update-cloud-access [name] [cloud_name] [full|none]"
660
- options = {}
661
- optparse = OptionParser.new do|opts|
662
- opts.banner = usage
663
- opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
664
- options[:group] = val
665
- end
666
- build_common_options(opts, options, [:json])
667
- end
668
- optparse.parse(args)
669
-
670
- if args.count < 2
671
- puts "\n#{usage}\n\n"
672
- exit 1
673
- end
674
- name = args[0]
675
- cloud_name = args[1]
676
- access_value = args[2].to_s.downcase
677
- if !['full', 'none'].include?(access_value)
678
- puts "\n#{usage}\n\n"
679
- exit 1
680
- end
681
-
682
- connect(options)
683
- begin
684
-
685
- account = find_account_from_options(options)
686
- account_id = account ? account['id'] : nil
687
-
688
- role = find_role_by_name(account_id, name)
689
- exit 1 if role.nil?
690
-
691
- role_json = @roles_interface.get(account_id, role['id'])
692
-
693
- if role_json['globalZoneAccess'] != 'custom'
694
- print "\n", red, "Global Cloud Access is currently: #{role_json['globalZoneAccess'].capitalize}"
695
- print "\n", "You must first set it to Custom via `morpheus roles update-global-cloud-access \"#{name}\" custom`"
696
- print "\n\n", reset
697
- exit 1
698
- end
699
-
700
- group_id = nil
701
- if !options[:group].nil?
702
- group_id = find_group_id_by_name(options[:group])
703
- else
704
- group_id = @active_groups[@appliance_name.to_sym]
705
- end
706
-
707
- if group_id.nil?
708
- print_red_alert "Group not found or specified!"
709
- exit 1
710
- end
711
-
712
- cloud_id = find_cloud_id_by_name(group_id, cloud_name)
713
- exit 1 if cloud_id.nil?
714
- params = {cloudId: cloud_id, access: access_value}
715
- json_response = @roles_interface.update_cloud(account_id, role['id'], params)
716
-
717
- if options[:json]
718
- print JSON.pretty_generate(json_response)
719
- print "\n"
720
- else
721
- print_green_success "Role #{role['authority']} global cloud access updated"
722
- end
723
-
724
- rescue RestClient::Exception => e
725
- print_rest_exception(e, options)
726
- exit 1
727
- end
728
- end
729
-
730
- def update_global_instance_type_access(args)
731
- usage = "Usage: morpheus roles update-global-instance-type-access [name] [full|custom|none]"
732
- options = {}
733
- optparse = OptionParser.new do|opts|
734
- opts.banner = usage
735
- build_common_options(opts, options, [:json])
736
- end
737
- optparse.parse(args)
738
-
739
- if args.count < 2
740
- puts "\n#{usage}\n\n"
741
- exit 1
742
- end
743
- name = args[0]
744
- access_value = args[1].to_s.downcase
745
- if !['full', 'custom', 'none'].include?(access_value)
746
- puts "\n#{usage}\n\n"
747
- exit 1
748
- end
749
-
750
-
751
- connect(options)
752
- begin
753
-
754
- account = find_account_from_options(options)
755
- account_id = account ? account['id'] : nil
756
-
757
- role = find_role_by_name(account_id, name)
758
- exit 1 if role.nil?
759
-
760
- params = {permissionCode: 'InstanceType', access: access_value}
761
- json_response = @roles_interface.update_permission(account_id, role['id'], params)
762
-
763
- if options[:json]
764
- print JSON.pretty_generate(json_response)
765
- print "\n"
766
- else
767
- print_green_success "Role #{role['authority']} global instance type access updated"
768
- end
769
-
770
- rescue RestClient::Exception => e
771
- print_rest_exception(e, options)
772
- exit 1
773
- end
774
- end
775
-
776
- def update_instance_type_access(args)
777
- usage = "Usage: morpheus roles update-instance-type-access [name] [instance_type_name] [full|none]"
778
- options = {}
779
- optparse = OptionParser.new do|opts|
780
- opts.banner = usage
781
- build_common_options(opts, options, [:json])
782
- end
783
- optparse.parse(args)
784
-
785
- if args.count < 2
786
- puts "\n#{usage}\n\n"
787
- exit 1
788
- end
789
- name = args[0]
790
- instance_type_name = args[1]
791
- access_value = args[2].to_s.downcase
792
- if !['full', 'none'].include?(access_value)
793
- puts "\n#{usage}\n\n"
794
- exit 1
795
- end
796
-
797
- connect(options)
798
- begin
799
-
800
- account = find_account_from_options(options)
801
- account_id = account ? account['id'] : nil
802
-
803
- role = find_role_by_name(account_id, name)
804
- exit 1 if role.nil?
805
-
806
- role_json = @roles_interface.get(account_id, role['id'])
807
-
808
- if role_json['globalInstanceTypeAccess'] != 'custom'
809
- print "\n", red, "Global Instance Type Access is currently: #{role_json['globalInstanceTypeAccess'].capitalize}"
810
- print "\n", "You must first set it to Custom via `morpheus roles update-global-instance-type-access \"#{name}\" custom`"
811
- print "\n\n", reset
812
- exit 1
813
- end
814
-
815
- instance_type = find_instance_type_by_name(instance_type_name)
816
- exit 1 if instance_type.nil?
817
-
818
- params = {instanceTypeId: instance_type['id'], access: access_value}
819
- json_response = @roles_interface.update_instance_type(account_id, role['id'], params)
820
-
821
- if options[:json]
822
- print JSON.pretty_generate(json_response)
823
- print "\n"
824
- else
825
- print_green_success "Role #{role['authority']} global instance type access updated"
826
- end
827
-
828
- rescue RestClient::Exception => e
829
- print_rest_exception(e, options)
830
- exit 1
831
- end
832
- end
833
-
834
- private
835
-
836
- # def get_access_string(val)
837
- # val ||= 'none'
838
- # if val == 'none'
839
- # "#{white}#{val.to_s.capitalize}#{cyan}"
840
- # else
841
- # "#{green}#{val.to_s.capitalize}#{cyan}"
842
- # end
843
- # end
844
-
845
- def add_role_option_types
846
- [
847
- {'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
848
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
849
- {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user', 'displayOrder' => 3},
850
- {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4},
851
- {'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use', 'displayOrder' => 5},
852
- {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
853
- {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
854
- {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
855
- ]
856
- end
857
-
858
- "A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use"
859
- def update_role_option_types
860
- add_role_option_types.reject {|it| ['roleType', 'baseRole'].include?(it['fieldName']) }
861
- end
862
-
863
-
864
- def find_group_by_name(name)
865
- group_results = @groups_interface.get(name)
866
- if group_results['groups'].empty?
867
- print_red_alert "Group not found by name #{name}"
868
- return nil
869
- end
870
- return group_results['groups'][0]
871
- end
872
-
873
- # no worky, returning {"success"=>true, "data"=>[]}
874
- # def find_group_id_by_name(name)
875
- # option_results = @options_interface.options_for_source('groups',{})
876
- # puts "option_results: #{option_results.inspect}"
877
- # match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
878
- # if match.nil?
879
- # print_red_alert "Group not found by name #{name}"
880
- # return nil
881
- # else
882
- # return match['value']
883
- # end
884
- # end
885
-
886
- def find_cloud_id_by_name(group_id, name)
887
- option_results = @options_interface.options_for_source('clouds', {groupId: group_id})
888
- match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
889
- if match.nil?
890
- print_red_alert "Cloud not found by name #{name}"
891
- return nil
892
- else
893
- return match['value']
894
- end
895
- end
896
-
897
- def find_instance_type_by_name(name)
898
- results = @instance_types_interface.get({name: name})
899
- if results['instanceTypes'].empty?
900
- print_red_alert "Instance Type not found by name #{name}"
901
- return nil
902
- end
903
- return results['instanceTypes'][0]
904
- end
905
-
906
- def load_whoami
907
- whoami_response = @whoami_interface.get()
908
- @current_user = whoami_response["user"]
909
- if @current_user.empty?
910
- print_red_alert "Unauthenticated. Please login."
911
- exit 1
912
- end
913
- @is_master_account = whoami_response["isMasterAccount"]
914
- end
915
-
916
- def role_type_options
917
- [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}]
918
- end
13
+ register_subcommands :list, :get, :add, :update, :remove, :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access'
14
+ alias_subcommand :details, :get
15
+ set_default_subcommand :list
16
+
17
+ def connect(opts)
18
+ @api_client = establish_remote_appliance_connection(opts)
19
+ @whoami_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).whoami
20
+ @users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
21
+ @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
22
+ @roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
23
+ @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
24
+ @options_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).options
25
+ #@clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
26
+ @instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
27
+ @active_group_id = Morpheus::Cli::Groups.active_group
28
+ end
29
+
30
+ def handle(args)
31
+ handle_subcommand(args)
32
+ end
33
+
34
+ def list(args)
35
+ options = {}
36
+ optparse = OptionParser.new do|opts|
37
+ opts.banner = subcommand_usage()
38
+ build_common_options(opts, options, [:list, :json, :dry_run])
39
+ end
40
+ optparse.parse!(args)
41
+
42
+ connect(options)
43
+ begin
44
+ load_whoami()
45
+
46
+ account = find_account_from_options(options)
47
+ account_id = account ? account['id'] : nil
48
+ params = {}
49
+ [:phrase, :offset, :max, :sort, :direction].each do |k|
50
+ params[k] = options[k] unless options[k].nil?
51
+ end
52
+
53
+ if options[:dry_run]
54
+ print_dry_run @roles_interface.dry.list(account_id, params)
55
+ return
56
+ end
57
+ json_response = @roles_interface.list(account_id, params)
58
+ roles = json_response['roles']
59
+ if options[:json]
60
+ print JSON.pretty_generate(json_response)
61
+ print "\n"
62
+ else
63
+ print "\n" ,cyan, bold, "Morpheus Roles\n","==================", reset, "\n\n"
64
+ if roles.empty?
65
+ puts yellow,"No roles found.",reset
66
+ else
67
+ print_roles_table(roles, {is_master_account: @is_master_account})
68
+ print_results_pagination(json_response)
69
+ end
70
+ print reset,"\n"
71
+ end
72
+ rescue RestClient::Exception => e
73
+ print_rest_exception(e, options)
74
+ exit 1
75
+ end
76
+ end
77
+
78
+ def get(args)
79
+ options = {}
80
+ optparse = OptionParser.new do|opts|
81
+ opts.banner = subcommand_usage("[name]")
82
+ opts.on(nil,'--feature-access', "Display Feature Access") do |val|
83
+ options[:include_feature_access] = true
84
+ end
85
+ opts.on(nil,'--group-access', "Display Group Access") do
86
+ options[:include_group_access] = true
87
+ end
88
+ opts.on(nil,'--cloud-access', "Display Cloud Access") do
89
+ options[:include_cloud_access] = true
90
+ end
91
+ opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
92
+ options[:include_instance_type_access] = true
93
+ end
94
+ opts.on(nil,'--all-access', "Display All Access Lists") do
95
+ options[:include_feature_access] = true
96
+ options[:include_group_access] = true
97
+ options[:include_cloud_access] = true
98
+ options[:include_instance_type_access] = true
99
+ end
100
+ build_common_options(opts, options, [:json, :dry_run])
101
+ end
102
+ optparse.parse!(args)
103
+
104
+ if args.count < 1
105
+ puts optparse
106
+ exit 1
107
+ end
108
+ name = args[0]
109
+
110
+ connect(options)
111
+ begin
112
+ account = find_account_from_options(options)
113
+ account_id = account ? account['id'] : nil
114
+ if options[:dry_run]
115
+ print_dry_run @roles_interface.dry.list(account_id, {name: name})
116
+ return
117
+ end
118
+
119
+ role = find_role_by_name_or_id(account_id, name)
120
+ exit 1 if role.nil?
121
+
122
+ json_response = @roles_interface.get(account_id, role['id'])
123
+ role = json_response['role']
124
+
125
+ if options[:json]
126
+ print JSON.pretty_generate(json_response)
127
+ print "\n"
128
+ else
129
+ print "\n" ,cyan, bold, "Role Details\n","==================", reset, "\n\n"
130
+ print cyan
131
+ puts "ID: #{role['id']}"
132
+ puts "Name: #{role['authority']}"
133
+ puts "Description: #{role['description']}"
134
+ puts "Scope: #{role['scope']}"
135
+ puts "Type: #{format_role_type(role)}"
136
+ puts "Multitenant: #{role['multitenant'] ? 'Yes' : 'No'}"
137
+ puts "Owner: #{role['owner'] ? role['owner']['name'] : nil}"
138
+ puts "Date Created: #{format_local_dt(role['dateCreated'])}"
139
+ puts "Last Updated: #{format_local_dt(role['lastUpdated'])}"
140
+
141
+ print "\n" ,cyan, bold, "Role Instance Limits\n","==================", reset, "\n\n"
142
+ print cyan
143
+ puts "Max Storage (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxStorage'] : 0}"
144
+ puts "Max Memory (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxMemory'] : 0}"
145
+ puts "CPU Count: #{role['instanceLimits'] ? role['instanceLimits']['maxCpu'] : 0}"
146
+
147
+ print "\n" ,cyan, bold, "Feature Access\n","==================", reset, "\n\n"
148
+ print cyan
149
+
150
+ if options[:include_feature_access]
151
+ rows = json_response['featurePermissions'].collect do |it|
152
+ {
153
+ code: it['code'],
154
+ name: it['name'],
155
+ access: get_access_string(it['access']),
156
+ }
157
+ end
158
+ tp rows, [:code, :name, :access]
159
+ else
160
+ puts "Use --feature-access to list feature access"
161
+ end
162
+
163
+ print "\n" ,cyan, bold, "Group Access\n","==================", reset, "\n\n"
164
+ print cyan
165
+ puts "Global Group Access: #{get_access_string(json_response['globalSiteAccess'])}\n\n"
166
+ if json_response['globalSiteAccess'] == 'custom'
167
+ if options[:include_group_access]
168
+ rows = json_response['sites'].collect do |it|
169
+ {
170
+ name: it['name'],
171
+ access: get_access_string(it['access']),
172
+ }
173
+ end
174
+ tp rows, [:name, :access]
175
+ else
176
+ puts "Use --group-access to list custom access"
177
+ end
178
+ end
179
+
180
+ print "\n" ,cyan, bold, "Cloud Access\n","==================", reset, "\n\n"
181
+ print cyan
182
+ puts "Global Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}\n\n"
183
+ if json_response['globalZoneAccess'] == 'custom'
184
+ if options[:include_cloud_access]
185
+ rows = json_response['zones'].collect do |it|
186
+ {
187
+ name: it['name'],
188
+ access: get_access_string(it['access']),
189
+ }
190
+ end
191
+ tp rows, [:name, :access]
192
+ else
193
+ puts "Use --cloud-access to list custom access"
194
+ end
195
+ end
196
+
197
+ print "\n" ,cyan, bold, "Instance Type Access\n","==================", reset, "\n\n"
198
+ print cyan
199
+ puts "Global Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}\n\n"
200
+ if json_response['globalInstanceTypeAccess'] == 'custom'
201
+ if options[:include_instance_type_access]
202
+ rows = json_response['instanceTypePermissions'].collect do |it|
203
+ {
204
+ name: it['name'],
205
+ access: get_access_string(it['access']),
206
+ }
207
+ end
208
+ tp rows, [:name, :access]
209
+ else
210
+ puts "Use --instance-type-access to list custom access"
211
+ end
212
+ end
213
+
214
+ print reset,"\n"
215
+ end
216
+ rescue RestClient::Exception => e
217
+ print_rest_exception(e, options)
218
+ exit 1
219
+ end
220
+ end
221
+
222
+ def add(args)
223
+ usage = "Usage: morpheus roles add [options]"
224
+ options = {}
225
+ optparse = OptionParser.new do|opts|
226
+ opts.banner = subcommand_usage("[name] [options]")
227
+ build_common_options(opts, options, [:options, :json, :dry_run])
228
+ end
229
+ optparse.parse!(args)
230
+
231
+ connect(options)
232
+ begin
233
+
234
+ load_whoami()
235
+ account = find_account_from_options(options)
236
+ account_id = account ? account['id'] : nil
237
+
238
+ # argh, some options depend on others here...eg. multitenant is only available when roleType == 'user'
239
+ #prompt_option_types = update_role_option_types()
240
+
241
+ role_payload = {}
242
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1}], options[:options])
243
+ role_payload['authority'] = v_prompt['authority']
244
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2}], options[:options])
245
+ role_payload['description'] = v_prompt['description']
246
+
247
+ if @is_master_account
248
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleType', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => role_type_options, 'defaultValue' => 'user', 'displayOrder' => 3}], options[:options])
249
+ role_payload['roleType'] = v_prompt['roleType']
250
+ else
251
+ role_payload['roleType'] = 'user'
252
+ end
253
+
254
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4}], options[:options])
255
+ if v_prompt['baseRole'].to_s != ''
256
+ base_role = find_role_by_name_or_id(account_id, v_prompt['baseRole'])
257
+ exit 1 if base_role.nil?
258
+ role_payload['baseRoleId'] = base_role['id']
259
+ end
260
+
261
+ if @is_master_account
262
+ if role_payload['roleType'] == 'user'
263
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use', 'displayOrder' => 5}], options[:options])
264
+ role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
265
+ end
266
+ end
267
+
268
+ role_payload['instanceLimits'] = {}
269
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8}], options[:options])
270
+ if v_prompt['instanceLimits.maxStorage'].to_s.strip != ''
271
+ role_payload['instanceLimits']['maxStorage'] = v_prompt['instanceLimits.maxStorage'].to_i
272
+ end
273
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9}], options[:options])
274
+ if v_prompt['instanceLimits.maxMemory'].to_s.strip != ''
275
+ role_payload['instanceLimits']['maxMemory'] = v_prompt['instanceLimits.maxMemory'].to_i
276
+ end
277
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10}], options[:options])
278
+ if v_prompt['instanceLimits.maxCpu'].to_s.strip != ''
279
+ role_payload['instanceLimits']['maxCpu'] = v_prompt['instanceLimits.maxCpu'].to_i
280
+ end
281
+
282
+ payload = {role: role_payload}
283
+
284
+ if options[:dry_run]
285
+ print_dry_run @roles_interface.dry.create(account_id, payload)
286
+ return
287
+ end
288
+ json_response = @roles_interface.create(account_id, payload)
289
+
290
+ if options[:json]
291
+ print JSON.pretty_generate(json_response)
292
+ print "\n"
293
+ return
294
+ end
295
+
296
+ if account
297
+ print_green_success "Added role #{role_payload['authority']} to account #{account['name']}"
298
+ else
299
+ print_green_success "Added role #{role_payload['authority']}"
300
+ end
301
+
302
+ details_options = [role_payload["authority"]]
303
+ if account
304
+ details_options.push "--account-id", account['id'].to_s
305
+ end
306
+ get(details_options)
307
+
308
+ rescue RestClient::Exception => e
309
+ print_rest_exception(e, options)
310
+ exit 1
311
+ end
312
+ end
313
+
314
+ def update(args)
315
+ usage = "Usage: morpheus roles update [name] [options]"
316
+ options = {}
317
+ optparse = OptionParser.new do|opts|
318
+ opts.banner = subcommand_usage("[name] [options]")
319
+ build_common_options(opts, options, [:options, :json, :dry_run])
320
+ end
321
+ optparse.parse!(args)
322
+
323
+ if args.count < 1
324
+ puts optparse
325
+ exit 1
326
+ end
327
+ name = args[0]
328
+ connect(options)
329
+ begin
330
+
331
+ load_whoami()
332
+
333
+ account = find_account_from_options(options)
334
+ account_id = account ? account['id'] : nil
335
+
336
+ role = find_role_by_name_or_id(account_id, name)
337
+ exit 1 if role.nil?
338
+
339
+ prompt_option_types = update_role_option_types()
340
+ if !@is_master_account
341
+ prompt_option_types = prompt_option_types.reject {|it| ['roleType', 'multitenant'].include?(it['fieldName']) }
342
+ end
343
+ if role['roleType'] != 'user'
344
+ prompt_option_types = prompt_option_types.reject {|it| ['multitenant'].include?(it['fieldName']) }
345
+ end
346
+ #params = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, options[:options], @api_client, options[:params])
347
+ params = options[:options] || {}
348
+
349
+ if params.empty?
350
+ puts optparse
351
+ option_lines = prompt_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
352
+ puts "\nAvailable Options:\n#{option_lines}\n\n"
353
+ exit 1
354
+ end
355
+
356
+ #puts "parsed params is : #{params.inspect}"
357
+ role_keys = ['authority', 'description', 'instanceLimits']
358
+ role_payload = params.select {|k,v| role_keys.include?(k) }
359
+ if !role_payload['instanceLimits']
360
+ role_payload['instanceLimits'] = {}
361
+ role_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
362
+ role_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
363
+ role_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
364
+ end
365
+
366
+ if params['multitenant'].to_s != ''
367
+ role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
368
+ end
369
+ payload = {role: role_payload}
370
+ if options[:dry_run]
371
+ print_dry_run @roles_interface.dry.update(account_id, role['id'], payload)
372
+ return
373
+ end
374
+ json_response = @roles_interface.update(account_id, role['id'], payload)
375
+ if options[:json]
376
+ print JSON.pretty_generate(json_response)
377
+ print "\n"
378
+ return
379
+ end
380
+
381
+ print_green_success "Updated role #{role_payload['authority']}"
382
+
383
+ details_options = [role_payload["authority"] || role['authority']]
384
+ if account
385
+ details_options.push "--account-id", account['id'].to_s
386
+ end
387
+ get(details_options)
388
+
389
+ rescue RestClient::Exception => e
390
+ print_rest_exception(e, options)
391
+ exit 1
392
+ end
393
+ end
394
+
395
+ def remove(args)
396
+ usage = "Usage: morpheus roles remove [name]"
397
+ options = {}
398
+ optparse = OptionParser.new do|opts|
399
+ opts.banner = subcommand_usage("[name]")
400
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
401
+ end
402
+ optparse.parse!(args)
403
+ if args.count < 1
404
+ puts optparse
405
+ exit 1
406
+ end
407
+ name = args[0]
408
+ connect(options)
409
+ begin
410
+
411
+ account = find_account_from_options(options)
412
+ account_id = account ? account['id'] : nil
413
+
414
+ role = find_role_by_name_or_id(account_id, name)
415
+ exit 1 if role.nil?
416
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the role #{role['authority']}?")
417
+ exit
418
+ end
419
+ if options[:dry_run]
420
+ print_dry_run @roles_interface.dry.destroy(account_id, role['id'])
421
+ return
422
+ end
423
+ json_response = @roles_interface.destroy(account_id, role['id'])
424
+ if options[:json]
425
+ print JSON.pretty_generate(json_response)
426
+ print "\n"
427
+ else
428
+ print_green_success "Role #{role['authority']} removed"
429
+ end
430
+ rescue RestClient::Exception => e
431
+ print_rest_exception(e, options)
432
+ exit 1
433
+ end
434
+ end
435
+
436
+ def update_feature_access(args)
437
+ usage = "Usage: morpheus roles update-feature-access [name] [code] [full|read|none]"
438
+ options = {}
439
+ optparse = OptionParser.new do|opts|
440
+ opts.banner = subcommand_usage("[name] [code] [full|read|none]")
441
+ build_common_options(opts, options, [:json, :dry_run])
442
+ end
443
+ optparse.parse!(args)
444
+
445
+ if args.count < 3
446
+ puts optparse
447
+ exit 1
448
+ end
449
+ name = args[0]
450
+ permission_code = args[1]
451
+ access_value = args[2].to_s.downcase
452
+ if !['full', 'read', 'custom', 'none'].include?(access_value)
453
+ puts optparse
454
+ exit 1
455
+ end
456
+
457
+ connect(options)
458
+ begin
459
+ account = find_account_from_options(options)
460
+ account_id = account ? account['id'] : nil
461
+ role = find_role_by_name_or_id(account_id, name)
462
+ exit 1 if role.nil?
463
+
464
+ params = {permissionCode: permission_code, access: access_value}
465
+ if options[:dry_run]
466
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
467
+ return
468
+ end
469
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
470
+
471
+ if options[:json]
472
+ print JSON.pretty_generate(json_response)
473
+ print "\n"
474
+ else
475
+ print_green_success "Role #{role['authority']} feature access updated"
476
+ end
477
+ rescue RestClient::Exception => e
478
+ print_rest_exception(e, options)
479
+ exit 1
480
+ end
481
+ end
482
+
483
+ def update_global_group_access(args)
484
+ usage = "Usage: morpheus roles update-global-group-access [name] [full|read|custom|none]"
485
+ options = {}
486
+ optparse = OptionParser.new do|opts|
487
+ opts.banner = subcommand_usage("[name] [code] [full|read|custom|none]")
488
+ build_common_options(opts, options, [:json, :dry_run])
489
+ end
490
+ optparse.parse!(args)
491
+
492
+ if args.count < 2
493
+ puts optparse
494
+ exit 1
495
+ end
496
+ name = args[0]
497
+ access_value = args[1].to_s.downcase
498
+ if !['full', 'read', 'custom', 'none'].include?(access_value)
499
+ puts optparse
500
+ exit 1
501
+ end
502
+
503
+ connect(options)
504
+ begin
505
+ account = find_account_from_options(options)
506
+ account_id = account ? account['id'] : nil
507
+ role = find_role_by_name_or_id(account_id, name)
508
+ exit 1 if role.nil?
509
+
510
+ params = {permissionCode: 'ComputeSite', access: access_value}
511
+ if options[:dry_run]
512
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
513
+ return
514
+ end
515
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
516
+
517
+ if options[:json]
518
+ print JSON.pretty_generate(json_response)
519
+ print "\n"
520
+ else
521
+ print_green_success "Role #{role['authority']} global group access updated"
522
+ end
523
+ rescue RestClient::Exception => e
524
+ print_rest_exception(e, options)
525
+ exit 1
526
+ end
527
+ end
528
+
529
+ def update_group_access(args)
530
+ usage = "Usage: morpheus roles update-group-access [name] [group_name] [full|read|none]"
531
+ options = {}
532
+ optparse = OptionParser.new do|opts|
533
+ opts.banner = subcommand_usage("[name] [group] [full|read|none]")
534
+ build_common_options(opts, options, [:json, :dry_run])
535
+ end
536
+ optparse.parse!(args)
537
+
538
+ if args.count < 2
539
+ puts optparse
540
+ exit 1
541
+ end
542
+ name = args[0]
543
+ group_name = args[1]
544
+ access_value = args[2].to_s.downcase
545
+ if !['full', 'read', 'none'].include?(access_value)
546
+ puts optparse
547
+ exit 1
548
+ end
549
+
550
+ connect(options)
551
+ begin
552
+ account = find_account_from_options(options)
553
+ account_id = account ? account['id'] : nil
554
+ role = find_role_by_name_or_id(account_id, name)
555
+ exit 1 if role.nil?
556
+
557
+ role_json = @roles_interface.get(account_id, role['id'])
558
+ if role_json['globalSiteAccess'] != 'custom'
559
+ print "\n", red, "Global Group Access is currently: #{role_json['globalSiteAccess'].capitalize}"
560
+ print "\n", "You must first set it to Custom via `morpheus roles update-global-group-access \"#{name}\" custom`"
561
+ print "\n\n", reset
562
+ exit 1
563
+ end
564
+
565
+ # group_id = find_group_id_by_name(group_name)
566
+ # exit 1 if group_id.nil?
567
+ group = find_group_by_name(group_name)
568
+ exit 1 if group.nil?
569
+ group_id = group['id']
570
+
571
+ params = {groupId: group_id, access: access_value}
572
+ if options[:dry_run]
573
+ print_dry_run @roles_interface.dry.update_group(account_id, role['id'], params)
574
+ return
575
+ end
576
+ json_response = @roles_interface.update_group(account_id, role['id'], params)
577
+
578
+ if options[:json]
579
+ print JSON.pretty_generate(json_response)
580
+ print "\n"
581
+ else
582
+ print_green_success "Role #{role['authority']} global group access updated"
583
+ end
584
+ rescue RestClient::Exception => e
585
+ print_rest_exception(e, options)
586
+ exit 1
587
+ end
588
+ end
589
+
590
+ def update_global_cloud_access(args)
591
+ usage = "Usage: morpheus roles update-global-cloud-access [name] [full|custom|none]"
592
+ options = {}
593
+ optparse = OptionParser.new do|opts|
594
+ opts.banner = subcommand_usage("[name] [full|custom|none]")
595
+ build_common_options(opts, options, [:json, :dry_run])
596
+ end
597
+ optparse.parse!(args)
598
+
599
+ if args.count < 2
600
+ puts optparse
601
+ exit 1
602
+ end
603
+ name = args[0]
604
+ access_value = args[1].to_s.downcase
605
+ if !['full', 'custom', 'none'].include?(access_value)
606
+ puts optparse
607
+ exit 1
608
+ end
609
+
610
+ connect(options)
611
+ begin
612
+ account = find_account_from_options(options)
613
+ account_id = account ? account['id'] : nil
614
+ role = find_role_by_name_or_id(account_id, name)
615
+ exit 1 if role.nil?
616
+
617
+ params = {permissionCode: 'ComputeZone', access: access_value}
618
+ if options[:dry_run]
619
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
620
+ return
621
+ end
622
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
623
+
624
+ if options[:json]
625
+ print JSON.pretty_generate(json_response)
626
+ print "\n"
627
+ else
628
+ print_green_success "Role #{role['authority']} global cloud access updated"
629
+ end
630
+ rescue RestClient::Exception => e
631
+ print_rest_exception(e, options)
632
+ exit 1
633
+ end
634
+ end
635
+
636
+ def update_cloud_access(args)
637
+ usage = "Usage: morpheus roles update-cloud-access [name] [cloud_name] [full|none]"
638
+ options = {}
639
+ optparse = OptionParser.new do|opts|
640
+ opts.banner = subcommand_usage("[name] [cloud] [full|none]")
641
+ opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
642
+ options[:group] = val
643
+ end
644
+ build_common_options(opts, options, [:json, :dry_run])
645
+ end
646
+ optparse.parse!(args)
647
+
648
+ if args.count < 2
649
+ puts optparse
650
+ exit 1
651
+ end
652
+ name = args[0]
653
+ cloud_name = args[1]
654
+ access_value = args[2].to_s.downcase
655
+ if !['full', 'none'].include?(access_value)
656
+ puts optparse
657
+ exit 1
658
+ end
659
+
660
+ connect(options)
661
+ begin
662
+ account = find_account_from_options(options)
663
+ account_id = account ? account['id'] : nil
664
+ role = find_role_by_name_or_id(account_id, name)
665
+ exit 1 if role.nil?
666
+
667
+ role_json = @roles_interface.get(account_id, role['id'])
668
+ if role_json['globalZoneAccess'] != 'custom'
669
+ print "\n", red, "Global Cloud Access is currently: #{role_json['globalZoneAccess'].capitalize}"
670
+ print "\n", "You must first set it to Custom via `morpheus roles update-global-cloud-access \"#{name}\" custom`"
671
+ print "\n\n", reset
672
+ exit 1
673
+ end
674
+
675
+ group_id = nil
676
+ if !options[:group].nil?
677
+ group_id = find_group_id_by_name(options[:group])
678
+ else
679
+ group_id = @active_group_id
680
+ end
681
+
682
+ if group_id.nil?
683
+ print_red_alert "Group not found or specified!"
684
+ exit 1
685
+ end
686
+
687
+ cloud_id = find_cloud_id_by_name(group_id, cloud_name)
688
+ exit 1 if cloud_id.nil?
689
+ params = {cloudId: cloud_id, access: access_value}
690
+ if options[:dry_run]
691
+ print_dry_run @roles_interface.dry.update_cloud(account_id, role['id'], params)
692
+ return
693
+ end
694
+ json_response = @roles_interface.update_cloud(account_id, role['id'], params)
695
+
696
+ if options[:json]
697
+ print JSON.pretty_generate(json_response)
698
+ print "\n"
699
+ else
700
+ print_green_success "Role #{role['authority']} global cloud access updated"
701
+ end
702
+ rescue RestClient::Exception => e
703
+ print_rest_exception(e, options)
704
+ exit 1
705
+ end
706
+ end
707
+
708
+ def update_global_instance_type_access(args)
709
+ usage = "Usage: morpheus roles update-global-instance-type-access [name] [full|custom|none]"
710
+ options = {}
711
+ optparse = OptionParser.new do|opts|
712
+ opts.banner = subcommand_usage("[name] [full|custom|none]")
713
+ build_common_options(opts, options, [:json, :dry_run])
714
+ end
715
+ optparse.parse!(args)
716
+
717
+ if args.count < 2
718
+ puts optparse
719
+ exit 1
720
+ end
721
+ name = args[0]
722
+ access_value = args[1].to_s.downcase
723
+ if !['full', 'custom', 'none'].include?(access_value)
724
+ puts optparse
725
+ exit 1
726
+ end
727
+
728
+
729
+ connect(options)
730
+ begin
731
+ account = find_account_from_options(options)
732
+ account_id = account ? account['id'] : nil
733
+ role = find_role_by_name_or_id(account_id, name)
734
+ exit 1 if role.nil?
735
+
736
+ params = {permissionCode: 'InstanceType', access: access_value}
737
+ if options[:dry_run]
738
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
739
+ return
740
+ end
741
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
742
+
743
+ if options[:json]
744
+ print JSON.pretty_generate(json_response)
745
+ print "\n"
746
+ else
747
+ print_green_success "Role #{role['authority']} global instance type access updated"
748
+ end
749
+ rescue RestClient::Exception => e
750
+ print_rest_exception(e, options)
751
+ exit 1
752
+ end
753
+ end
754
+
755
+ def update_instance_type_access(args)
756
+ usage = "Usage: morpheus roles update-instance-type-access [name] [instance_type_name] [full|none]"
757
+ options = {}
758
+ optparse = OptionParser.new do|opts|
759
+ opts.banner = subcommand_usage("[name] [instance-type] [full|none]")
760
+ build_common_options(opts, options, [:json, :dry_run])
761
+ end
762
+ optparse.parse!(args)
763
+
764
+ if args.count < 2
765
+ puts optparse
766
+ exit 1
767
+ end
768
+ name = args[0]
769
+ instance_type_name = args[1]
770
+ access_value = args[2].to_s.downcase
771
+ if !['full', 'none'].include?(access_value)
772
+ puts optparse
773
+ exit 1
774
+ end
775
+
776
+ connect(options)
777
+ begin
778
+ account = find_account_from_options(options)
779
+ account_id = account ? account['id'] : nil
780
+ role = find_role_by_name_or_id(account_id, name)
781
+ exit 1 if role.nil?
782
+
783
+ role_json = @roles_interface.get(account_id, role['id'])
784
+ if role_json['globalInstanceTypeAccess'] != 'custom'
785
+ print "\n", red, "Global Instance Type Access is currently: #{role_json['globalInstanceTypeAccess'].capitalize}"
786
+ print "\n", "You must first set it to Custom via `morpheus roles update-global-instance-type-access \"#{name}\" custom`"
787
+ print "\n\n", reset
788
+ exit 1
789
+ end
790
+
791
+ instance_type = find_instance_type_by_name(instance_type_name)
792
+ exit 1 if instance_type.nil?
793
+
794
+ params = {instanceTypeId: instance_type['id'], access: access_value}
795
+ if options[:dry_run]
796
+ print_dry_run @roles_interface.dry.update_instance_type(account_id, role['id'], params)
797
+ return
798
+ end
799
+ json_response = @roles_interface.update_instance_type(account_id, role['id'], params)
800
+
801
+ if options[:json]
802
+ print JSON.pretty_generate(json_response)
803
+ print "\n"
804
+ else
805
+ print_green_success "Role #{role['authority']} global instance type access updated"
806
+ end
807
+ rescue RestClient::Exception => e
808
+ print_rest_exception(e, options)
809
+ exit 1
810
+ end
811
+ end
812
+
813
+ private
814
+ # def get_access_string(val)
815
+ # val ||= 'none'
816
+ # if val == 'none'
817
+ # "#{white}#{val.to_s.capitalize}#{cyan}"
818
+ # else
819
+ # "#{green}#{val.to_s.capitalize}#{cyan}"
820
+ # end
821
+ # end
822
+
823
+ def add_role_option_types
824
+ [
825
+ {'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
826
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
827
+ {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user', 'displayOrder' => 3},
828
+ {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4},
829
+ {'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use', 'displayOrder' => 5},
830
+ {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
831
+ {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
832
+ {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
833
+ ]
834
+ end
835
+
836
+ "A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use"
837
+ def update_role_option_types
838
+ add_role_option_types.reject {|it| ['roleType', 'baseRole'].include?(it['fieldName']) }
839
+ end
840
+
841
+
842
+ def find_group_by_name(name)
843
+ group_results = @groups_interface.get(name)
844
+ if group_results['groups'].empty?
845
+ print_red_alert "Group not found by name #{name}"
846
+ return nil
847
+ end
848
+ return group_results['groups'][0]
849
+ end
850
+
851
+ # no worky, returning {"success"=>true, "data"=>[]}
852
+ # def find_group_id_by_name(name)
853
+ # option_results = @options_interface.options_for_source('groups',{})
854
+ # puts "option_results: #{option_results.inspect}"
855
+ # match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
856
+ # if match.nil?
857
+ # print_red_alert "Group not found by name #{name}"
858
+ # return nil
859
+ # else
860
+ # return match['value']
861
+ # end
862
+ # end
863
+
864
+ def find_cloud_id_by_name(group_id, name)
865
+ option_results = @options_interface.options_for_source('clouds', {groupId: group_id})
866
+ match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
867
+ if match.nil?
868
+ print_red_alert "Cloud not found by name #{name}"
869
+ return nil
870
+ else
871
+ return match['value']
872
+ end
873
+ end
874
+
875
+ def find_instance_type_by_name(name)
876
+ results = @instance_types_interface.get({name: name})
877
+ if results['instanceTypes'].empty?
878
+ print_red_alert "Instance Type not found by name #{name}"
879
+ return nil
880
+ end
881
+ return results['instanceTypes'][0]
882
+ end
883
+
884
+ def load_whoami
885
+ whoami_response = @whoami_interface.get()
886
+ @current_user = whoami_response["user"]
887
+ if @current_user.empty?
888
+ print_red_alert "Unauthenticated. Please login."
889
+ exit 1
890
+ end
891
+ @is_master_account = whoami_response["isMasterAccount"]
892
+ end
893
+
894
+ def role_type_options
895
+ [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}]
896
+ end
919
897
 
920
898
  end