morpheus-cli 5.5.1.5 → 5.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +25 -0
  4. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  5. data/lib/morpheus/api/body_io.rb +22 -0
  6. data/lib/morpheus/api/catalog_item_types_interface.rb +5 -1
  7. data/lib/morpheus/api/clients_interface.rb +41 -0
  8. data/lib/morpheus/api/clouds_interface.rb +21 -0
  9. data/lib/morpheus/api/instances_interface.rb +8 -1
  10. data/lib/morpheus/api/integrations_interface.rb +30 -0
  11. data/lib/morpheus/api/library_instance_types_interface.rb +15 -3
  12. data/lib/morpheus/api/network_pool_server_types_interface.rb +9 -0
  13. data/lib/morpheus/api/plugins_interface.rb +22 -0
  14. data/lib/morpheus/api/roles_interface.rb +20 -1
  15. data/lib/morpheus/api/security_package_types_interface.rb +9 -0
  16. data/lib/morpheus/api/security_packages_interface.rb +9 -0
  17. data/lib/morpheus/api/security_scans_interface.rb +9 -0
  18. data/lib/morpheus/api/servers_interface.rb +17 -17
  19. data/lib/morpheus/api/storage_providers_interface.rb +1 -1
  20. data/lib/morpheus/api/virtual_images_interface.rb +1 -23
  21. data/lib/morpheus/cli/cli_command.rb +81 -7
  22. data/lib/morpheus/cli/commands/apps.rb +28 -2
  23. data/lib/morpheus/cli/commands/archives_command.rb +2 -2
  24. data/lib/morpheus/cli/commands/blueprints_command.rb +16 -0
  25. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +34 -2
  26. data/lib/morpheus/cli/commands/clients_command.rb +338 -0
  27. data/lib/morpheus/cli/commands/clouds.rb +127 -1
  28. data/lib/morpheus/cli/commands/clusters.rb +42 -12
  29. data/lib/morpheus/cli/commands/curl_command.rb +114 -135
  30. data/lib/morpheus/cli/commands/hosts.rb +108 -11
  31. data/lib/morpheus/cli/commands/instances.rb +115 -14
  32. data/lib/morpheus/cli/commands/integrations_command.rb +215 -4
  33. data/lib/morpheus/cli/commands/invoices_command.rb +20 -11
  34. data/lib/morpheus/cli/commands/jobs_command.rb +299 -190
  35. data/lib/morpheus/cli/commands/library_cluster_layouts_command.rb +16 -2
  36. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +14 -0
  37. data/lib/morpheus/cli/commands/library_container_templates_command.rb +131 -48
  38. data/lib/morpheus/cli/commands/library_container_types_command.rb +17 -4
  39. data/lib/morpheus/cli/commands/library_instance_types_command.rb +85 -7
  40. data/lib/morpheus/cli/commands/library_layouts_command.rb +32 -1
  41. data/lib/morpheus/cli/commands/library_option_lists_command.rb +30 -18
  42. data/lib/morpheus/cli/commands/library_option_types_command.rb +31 -14
  43. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +14 -0
  44. data/lib/morpheus/cli/commands/library_upgrades_command.rb +2 -2
  45. data/lib/morpheus/cli/commands/network_pool_server_types.rb +20 -0
  46. data/lib/morpheus/cli/commands/network_pool_servers_command.rb +55 -158
  47. data/lib/morpheus/cli/commands/network_pools_command.rb +49 -23
  48. data/lib/morpheus/cli/commands/networks_command.rb +262 -45
  49. data/lib/morpheus/cli/commands/plugins.rb +213 -0
  50. data/lib/morpheus/cli/commands/price_sets_command.rb +27 -8
  51. data/lib/morpheus/cli/commands/prices_command.rb +17 -5
  52. data/lib/morpheus/cli/commands/processes_command.rb +2 -1
  53. data/lib/morpheus/cli/commands/remote.rb +7 -10
  54. data/lib/morpheus/cli/commands/roles.rb +924 -335
  55. data/lib/morpheus/cli/commands/search_command.rb +2 -0
  56. data/lib/morpheus/cli/commands/security_groups.rb +72 -84
  57. data/lib/morpheus/cli/commands/security_package_types.rb +32 -0
  58. data/lib/morpheus/cli/commands/security_packages.rb +84 -0
  59. data/lib/morpheus/cli/commands/security_scans.rb +107 -0
  60. data/lib/morpheus/cli/commands/service_plans_command.rb +16 -14
  61. data/lib/morpheus/cli/commands/subnets_command.rb +15 -1
  62. data/lib/morpheus/cli/commands/tasks.rb +34 -1
  63. data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
  64. data/lib/morpheus/cli/commands/user_settings_command.rb +11 -2
  65. data/lib/morpheus/cli/commands/users.rb +50 -9
  66. data/lib/morpheus/cli/commands/virtual_images.rb +14 -0
  67. data/lib/morpheus/cli/commands/workflows.rb +14 -0
  68. data/lib/morpheus/cli/mixins/accounts_helper.rb +6 -5
  69. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +79 -0
  70. data/lib/morpheus/cli/mixins/jobs_helper.rb +4 -5
  71. data/lib/morpheus/cli/mixins/library_helper.rb +2 -0
  72. data/lib/morpheus/cli/mixins/logs_helper.rb +3 -0
  73. data/lib/morpheus/cli/mixins/monitoring_helper.rb +1 -1
  74. data/lib/morpheus/cli/mixins/print_helper.rb +29 -4
  75. data/lib/morpheus/cli/mixins/provisioning_helper.rb +38 -9
  76. data/lib/morpheus/cli/mixins/rest_command.rb +106 -8
  77. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +6 -2
  78. data/lib/morpheus/cli/option_types.rb +94 -25
  79. data/lib/morpheus/cli/version.rb +1 -1
  80. data/lib/morpheus/formatters.rb +10 -1
  81. metadata +15 -2
@@ -6,14 +6,21 @@ class Morpheus::Cli::Roles
6
6
  include Morpheus::Cli::ProvisioningHelper
7
7
  include Morpheus::Cli::WhoamiHelper
8
8
  register_subcommands :list, :get, :add, :update, :remove,
9
- :'list-permissions', :'update-feature-access', :'update-global-group-access',
10
- :'update-group-access', :'update-global-cloud-access', :'update-cloud-access',
11
- :'update-global-instance-type-access', :'update-instance-type-access',
12
- :'update-global-blueprint-access', :'update-blueprint-access',
13
- :'update-global-catalog-item-type-access', :'update-catalog-item-type-access',
14
- :'update-persona-access',
15
- :'update-global-vdi-pool-access', :'update-vdi-pool-access',
16
- :'update-global-report-type-access', :'update-report-type-access'
9
+ :'list-permissions', :'update-feature-access', :'update-default-feature-access',
10
+ :'update-group-access', :'update-global-group-access', :'update-default-group-access',
11
+ :'update-global-cloud-access', :'update-cloud-access', :'update-default-cloud-access',
12
+ :'update-global-instance-type-access', :'update-instance-type-access', :'update-default-instance-type-access',
13
+ :'update-global-blueprint-access', :'update-blueprint-access', :'update-default-blueprint-access',
14
+ :'update-global-catalog-item-type-access', :'update-catalog-item-type-access', :'update-default-catalog-item-type-access',
15
+ :'update-persona-access', :'update-default-persona-access',
16
+ :'update-global-vdi-pool-access', :'update-vdi-pool-access', :'update-default-vdi-pool-access',
17
+ :'update-global-report-type-access', :'update-report-type-access', :'update-default-report-type-access',
18
+ :'update-global-task-access', :'update-task-access', :'update-default-task-access',
19
+ :'update-global-workflow-access', :'update-workflow-access', :'update-default-workflow-access'
20
+ set_subcommands_hidden(
21
+ subcommands.keys.select{|c|
22
+ c.include?('update-global')
23
+ })
17
24
  alias_subcommand :details, :get
18
25
  set_default_subcommand :list
19
26
 
@@ -39,6 +46,9 @@ class Morpheus::Cli::Roles
39
46
  options = {}
40
47
  optparse = Morpheus::Cli::OptionParser.new do |opts|
41
48
  opts.banner = subcommand_usage("[search phrase]")
49
+ opts.on( '--tenant TENANT', "Tenant Filter for list of Roles." ) do |val|
50
+ options[:tenant] = val
51
+ end
42
52
  build_standard_list_options(opts, options)
43
53
  opts.footer = "List roles."
44
54
  end
@@ -57,6 +67,9 @@ class Morpheus::Cli::Roles
57
67
  return 0, nil
58
68
  end
59
69
  load_whoami()
70
+ if options[:tenant]
71
+ params[:tenant] = options[:tenant]
72
+ end
60
73
  json_response = @roles_interface.list(account_id, params)
61
74
 
62
75
  render_response(json_response, options, "roles") do
@@ -82,13 +95,13 @@ class Morpheus::Cli::Roles
82
95
  options = {}
83
96
  optparse = Morpheus::Cli::OptionParser.new do |opts|
84
97
  opts.banner = subcommand_usage("[role]")
85
- opts.on('-p','--permissions', "Display Permissions") do |val|
98
+ opts.on('-p','--permissions', "Display Permissions [deprecated]") do |val|
86
99
  options[:include_feature_access] = true
87
100
  end
88
- opts.on('-f','--feature-access', "Display Permissions [deprecated]") do |val|
101
+ opts.add_hidden_option('-p,')
102
+ opts.on('-f','--feature-access', "Display Feature Access") do |val|
89
103
  options[:include_feature_access] = true
90
104
  end
91
- opts.add_hidden_option('--feature-access')
92
105
  opts.on('-g','--group-access', "Display Group Access") do
93
106
  options[:include_group_access] = true
94
107
  end
@@ -105,7 +118,11 @@ class Morpheus::Cli::Roles
105
118
  options[:include_catalog_item_type_access] = true
106
119
  end
107
120
  opts.on(nil,'--personas', "Display Persona Access") do
108
- options[:include_personas_access] = true
121
+ options[:include_persona_access] = true
122
+ end
123
+ opts.add_hidden_option('--personas')
124
+ opts.on(nil,'--persona-access', "Display Persona Access") do
125
+ options[:include_persona_access] = true
109
126
  end
110
127
  opts.on(nil,'--vdi-pool-access', "Display VDI Pool Access") do
111
128
  options[:include_vdi_pool_access] = true
@@ -113,16 +130,19 @@ class Morpheus::Cli::Roles
113
130
  opts.on(nil,'--report-type-access', "Display Report Type Access") do
114
131
  options[:include_report_type_access] = true
115
132
  end
133
+ opts.on(nil,'--workflow-access', "Display Workflow Access") do
134
+ options[:include_workflow_access] = true
135
+ end
136
+ opts.on(nil,'--task-access', "Display Task Access") do
137
+ options[:include_task_access] = true
138
+ end
116
139
  opts.on('-a','--all', "Display All Access Lists") do
117
- options[:include_feature_access] = true
118
- options[:include_group_access] = true
119
- options[:include_cloud_access] = true
120
- options[:include_instance_type_access] = true
121
- options[:include_blueprint_access] = true
122
- options[:include_catalog_item_type_access] = true
123
- options[:include_personas_access] = true
124
- options[:include_vdi_pool_access] = true
125
- options[:include_report_type_access] = true
140
+ options[:include_all_access] = true
141
+ end
142
+ opts.on('--account-id ID', String, "Clarify Owner of Role") do |val|
143
+ if has_complete_access
144
+ options[:account_id] = val.to_s
145
+ end
126
146
  end
127
147
  build_standard_get_options(opts, options)
128
148
  opts.footer = <<-EOT
@@ -142,65 +162,51 @@ EOT
142
162
  def _get(id, options={})
143
163
  args = [id] # heh
144
164
  params = {}
165
+ account = find_account_from_options(options)
166
+ account_id = account ? account['id'] : nil
145
167
 
146
-
147
- account = find_account_from_options(options)
148
- account_id = account ? account['id'] : nil
149
-
150
- params.merge!(parse_query_options(options))
151
-
152
- @roles_interface.setopts(options)
153
- if options[:dry_run]
154
- if args[0].to_s =~ /\A\d{1,}\Z/
155
- print_dry_run @roles_interface.dry.get(account_id, args[0].to_i)
156
- else
157
- print_dry_run @roles_interface.dry.list(account_id, {name: args[0]})
158
- end
159
- return
160
- end
168
+ params.merge!(parse_query_options(options))
161
169
 
162
- # role = find_role_by_name_or_id(account_id, args[0])
163
- # exit 1 if role.nil?
164
- # refetch from show action, argh
165
- # json_response = @roles_interface.get(account_id, role['id'])
166
- # role = json_response['role']
167
- load_whoami()
168
- json_response = nil
169
- role = nil
170
+ @roles_interface.setopts(options)
171
+ if options[:dry_run]
170
172
  if args[0].to_s =~ /\A\d{1,}\Z/
171
- json_response = @roles_interface.get(account_id, args[0].to_i)
172
- role = json_response['role']
173
+ print_dry_run @roles_interface.dry.get(account_id, args[0].to_i)
173
174
  else
174
- role = find_role_by_name_or_id(account_id, args[0])
175
- exit 1 if role.nil?
176
- # refetch from show action, argh
177
- json_response = @roles_interface.get(account_id, role['id'])
178
- role = json_response['role']
175
+ print_dry_run @roles_interface.dry.list(account_id, {name: args[0]})
179
176
  end
177
+ return
178
+ end
179
+
180
+ load_whoami()
181
+ json_response = nil
182
+ role = nil
183
+ if args[0].to_s =~ /\A\d{1,}\Z/
184
+ json_response = @roles_interface.get(account_id, args[0].to_i)
185
+ role = json_response['role']
186
+ else
187
+ role = find_role_by_name_or_id(account_id, args[0])
188
+ exit 1 if role.nil?
189
+ # refetch from show action, argh
190
+ json_response = @roles_interface.get(account_id, role['id'])
191
+ role = json_response['role']
192
+ end
193
+
194
+ render_response(json_response, options, 'role') do
180
195
 
181
- render_response(json_response, options, 'role') do
182
-
183
196
  print cyan
184
197
  print_h1 "Role Details", options
185
198
  print cyan
186
199
  columns = @is_master_account ? role_column_definitions : subtenant_role_column_definitions
187
200
  print_description_list(columns, role, options)
188
201
 
189
- # print_h2 "Role Instance Limits", options
190
- # print cyan
191
- # print_description_list({
192
- # "Max Storage" => lambda {|it| (it && it['maxStorage'].to_i != 0) ? Filesize.from("#{it['maxStorage']} B").pretty : "no limit" },
193
- # "Max Memory" => lambda {|it| (it && it['maxMemory'].to_i != 0) ? Filesize.from("#{it['maxMemory']} B").pretty : "no limit" },
194
- # "CPU Count" => lambda {|it| (it && it['maxCpu'].to_i != 0) ? it['maxCpu'] : "no limit" }
195
- # }, role['instanceLimits'])
196
-
197
202
  print_h2 "Permissions", options
198
203
  print cyan
199
- if options[:include_feature_access]
204
+ if options[:include_feature_access] || options[:include_all_access]
200
205
  rows = json_response['featurePermissions'].collect do |it|
201
206
  {
202
207
  code: it['code'],
203
208
  name: it['name'],
209
+ subCategory: it['subCategory'],
204
210
  access: format_access_string(it['access']),
205
211
  }
206
212
  end
@@ -214,24 +220,28 @@ EOT
214
220
  phrase_regexp = /#{Regexp.escape(options[:phrase])}/i
215
221
  rows = rows.select {|row| row[:code].to_s =~ phrase_regexp || row[:name].to_s =~ phrase_regexp }
216
222
  end
217
- print as_pretty_table(rows, [:code, :name, :access], options)
223
+ print as_pretty_table(rows, [:code, :name, :subCategory, :access], options)
218
224
  # print reset,"\n"
219
225
  else
220
- print cyan,"Use --permissions to list feature permissions","\n"
226
+ print cyan,"Use --feature-access to list feature access","\n"
221
227
  end
222
228
 
223
229
  has_group_access = true
224
230
  has_cloud_access = true
225
- print_h2 "Global Access", options
231
+ print_h2 "Default Access", options
226
232
  global_access_columns = {
227
233
  "Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) },
228
234
  "Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) },
229
235
  "Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) },
230
236
  "Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) },
237
+ "Personas" => lambda {|it| get_access_string(it['globalPersonaAccess']) },
238
+ "Report Types" => lambda {|it| get_access_string(it['globalReportTypeAccess']) },
231
239
  "Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) },
232
240
  "VDI Pools" => lambda {|it| get_access_string(it['globalVdiPoolAccess']) },
233
- "Report Types" => lambda {|it| get_access_string(it['globalReportTypeAccess']) },
241
+ "Workflows" => lambda {|it| get_access_string(it['globalTaskSetAccess']) },
242
+ "Tasks" => lambda {|it| get_access_string(it['globalTaskAccess']) },
234
243
  }
244
+
235
245
  if role['roleType'].to_s.downcase == 'account'
236
246
  global_access_columns.delete("Groups")
237
247
  has_group_access = false
@@ -239,15 +249,16 @@ EOT
239
249
  global_access_columns.delete("Clouds")
240
250
  has_cloud_access = false
241
251
  end
252
+
242
253
  print as_pretty_table([json_response], global_access_columns, options)
243
254
 
244
255
  if has_group_access
245
256
  #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
246
257
  print cyan
247
- if json_response['globalSiteAccess'] == 'custom'
258
+ if json_response['sites'].find {|it| !it['access'].nil?}
248
259
  print_h2 "Group Access", options
249
- if options[:include_group_access]
250
- rows = json_response['sites'].collect do |it|
260
+ if options[:include_group_access] || options[:include_all_access]
261
+ rows = json_response['sites'].select {|it| !it['access'].nil?}.collect do |it|
251
262
  {
252
263
  name: it['name'],
253
264
  access: format_access_string(it['access'], ["none","read","full"]),
@@ -263,15 +274,15 @@ EOT
263
274
  # print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
264
275
  end
265
276
  end
266
-
277
+
267
278
  if has_cloud_access
268
279
  print cyan
269
280
  #puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
270
281
  #print "\n"
271
- if json_response['globalZoneAccess'] == 'custom'
282
+ if json_response['sites'].find{|it| !it['access'].nil?}
272
283
  print_h2 "Cloud Access", options
273
- if options[:include_cloud_access]
274
- rows = json_response['zones'].collect do |it|
284
+ if options[:include_cloud_access] || options[:include_all_access]
285
+ rows = json_response['zones'].select {|it| !it['access'].nil?}.collect do |it|
275
286
  {
276
287
  name: it['name'],
277
288
  access: format_access_string(it['access'], ["none","read","full"]),
@@ -293,195 +304,226 @@ EOT
293
304
  # print "\n"
294
305
  instance_type_global_access = json_response['globalInstanceTypeAccess']
295
306
  instance_type_permissions = role['instanceTypes'] ? role['instanceTypes'] : (json_response['instanceTypePermissions'] || [])
296
- if instance_type_global_access == 'custom'
307
+
308
+ # if have any custom, then we want to show the flag indicator
309
+ # if including, show
310
+
311
+ if options[:include_instance_type_access] || options[:include_all_access]
297
312
  print_h2 "Instance Type Access", options
298
- if options[:include_instance_type_access]
299
- rows = instance_type_permissions.collect do |it|
300
- {
301
- name: it['name'],
302
- access: format_access_string(it['access'], ["none","read","full"]),
303
- }
304
- end
305
- print as_pretty_table(rows, [:name, :access], options)
306
- else
307
- print cyan,"Use -i, --instance-type-access to list custom access","\n"
313
+ rows = instance_type_permissions.collect do |it|
314
+ {
315
+ name: it['name'],
316
+ access: format_access_string(it['access'], ["none","read","full"]),
317
+ }
308
318
  end
309
- # print reset,"\n"
310
- else
311
- # print "\n"
312
- # print cyan,bold,"Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}",reset,"\n"
319
+ print as_pretty_table(rows, [:name, :access], options)
320
+ elsif instance_type_permissions.find {|it| !it['access'].nil?}
321
+ print_h2 "Instance Type Access", options
322
+ print cyan,"Use -i, --instance-type-access to list custom access","\n"
313
323
  end
314
324
 
315
325
  blueprint_global_access = json_response['globalAppTemplateAccess'] || json_response['globalBlueprintAccess']
316
326
  blueprint_permissions = (role['appTemplates'] || role['blueprints']) ? (role['appTemplates'] || role['blueprints']) : (json_response['appTemplatePermissions'] || json_response['blueprintPermissions'] || [])
317
327
  print cyan
318
- # print_h2 "Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}", options
319
- # print "\n"
320
- if blueprint_global_access == 'custom'
328
+ if options[:include_blueprint_access] || options[:include_all_access]
321
329
  print_h2 "Blueprint Access", options
322
- if options[:include_blueprint_access]
323
- rows = blueprint_permissions.collect do |it|
324
- {
325
- name: it['name'],
326
- access: format_access_string(it['access'], ["none","read","full"]),
327
- }
328
- end
329
- print as_pretty_table(rows, [:name, :access], options)
330
- else
331
- print cyan,"Use -b, --blueprint-access to list custom access","\n"
330
+ rows = blueprint_permissions.select {|it| !it['access'].nil?}.collect do |it|
331
+ {
332
+ name: it['name'],
333
+ access: format_access_string(it['access'], ["none","read","full"]),
334
+ }
332
335
  end
333
- # print reset,"\n"
334
- else
335
- # print "\n"
336
- # print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
336
+ print as_pretty_table(rows, [:name, :access], options)
337
+ elsif blueprint_permissions.find {|it| !it['access'].nil?}
338
+ print_h2 "Blueprint Access", options
339
+ print cyan,"Use -b, --blueprint-access to list custom access","\n"
337
340
  end
338
-
341
+
339
342
  catalog_item_type_global_access = json_response['globalCatalogItemTypeAccess']
340
343
  catalog_item_type_permissions = role['catalogItemTypes'] ? role['catalogItemTypes'] : (json_response['catalogItemTypePermissions'] || [])
341
344
  print cyan
342
- # print_h2 "catalog_item_type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}", options
343
- # print "\n"
344
- if catalog_item_type_global_access == 'custom'
345
+ if options[:include_catalog_item_type_access] || options[:include_all_access]
345
346
  print_h2 "Catalog Item Type Access", options
346
- if options[:include_catalog_item_type_access]
347
- rows = catalog_item_type_permissions.collect do |it|
348
- {
349
- name: it['name'],
350
- access: format_access_string(it['access'], ["none","read","full"]),
351
- }
352
- end
353
- print as_pretty_table(rows, [:name, :access], options)
354
- else
355
- print cyan,"Use --catalog-item-type-access to list custom access","\n"
347
+ rows = catalog_item_type_permissions.select {|it| !it['access'].nil?}.collect do |it|
348
+ {
349
+ name: it['name'],
350
+ access: format_access_string(it['access'], ["none","read","full"]),
351
+ }
356
352
  end
357
- else
358
- # print "\n"
359
- # print cyan,bold,"Catalog Item Type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}",reset,"\n"
353
+ print as_pretty_table(rows, [:name, :access], options)
354
+ elsif catalog_item_type_permissions.find {|it| !it['access'].nil?}
355
+ print_h2 "Catalog Item Type Access", options
356
+ print cyan,"Use --catalog-item-type-access to list access","\n"
360
357
  end
361
-
358
+
359
+ persona_global_access = json_response['globalPersonaAccess']
362
360
  persona_permissions = role['personas'] ? role['personas'] : (json_response['personaPermissions'] || [])
363
- # if options[:include_personas_access]
364
361
  print cyan
365
- if persona_permissions
362
+ if options[:include_persona_access] || options[:include_all_access]
366
363
  print_h2 "Persona Access", options
367
364
  rows = persona_permissions.collect do |it|
368
365
  {
369
366
  name: it['name'],
370
- access: format_access_string(it['access'], ["none","read","full"]),
367
+ access: format_access_string(it['access'], ["none","full"]),
371
368
  }
372
369
  end
373
- print as_pretty_table(rows, [:name, :access], options)
370
+ print as_pretty_table(rows, [:name, :access], options)
371
+ elsif persona_permissions.find {|it| !it['access'].nil?}
372
+ print_h2 "Persona Access", options
373
+ print cyan,"Use --persona-access to list access","\n"
374
374
  end
375
375
 
376
- # print reset,"\n"
377
-
378
376
  vdi_pool_global_access = json_response['globalVdiPoolAccess']
379
377
  vdi_pool_permissions = role['vdiPools'] ? role['vdiPools'] : (json_response['vdiPoolPermissions'] || [])
380
378
  print cyan
381
- if vdi_pool_global_access == 'custom'
379
+ if options[:include_vdi_pool_access] || options[:include_all_access]
382
380
  print_h2 "VDI Pool Access", options
383
- if options[:include_vdi_pool_access]
384
- rows = vdi_pool_permissions.collect do |it|
385
- {
386
- name: it['name'],
387
- access: format_access_string(it['access'], ["none","full"]),
388
- }
389
- end
390
- print as_pretty_table(rows, [:name, :access], options)
391
- else
392
- print cyan,"Use --vdi-pool-access to list custom access","\n"
381
+ rows = vdi_pool_permissions.select {|it| !it['access'].nil?}.collect do |it|
382
+ {
383
+ name: it['name'],
384
+ access: format_access_string(it['access'], ["none","full"]),
385
+ }
393
386
  end
394
- else
395
- # print "\n"
396
- # print cyan,bold,"VDI Pool Access: #{get_access_string(json_response['globalVdiPoolAccess'])}",reset,"\n"
387
+ print as_pretty_table(rows, [:name, :access], options)
388
+ elsif vdi_pool_permissions.find {|it| !it['access'].nil?}
389
+ print_h2 "VDI Pool Access", options
390
+ print cyan,"Use --vdi-pool-access to list custom access","\n"
397
391
  end
398
392
 
399
393
  report_type_global_access = json_response['globalReportTypeAccess']
400
394
  report_type_permissions = role['reportTypes'] ? role['reportTypes'] : (json_response['reportTypePermissions'] || [])
401
395
  print cyan
402
- if report_type_global_access == 'custom'
396
+ if options[:include_report_type_access] || options[:include_all_access]
403
397
  print_h2 "Report Type Access", options
404
- if options[:include_report_type_access]
405
- rows = report_type_permissions.collect do |it|
406
- {
407
- name: it['name'],
408
- access: format_access_string(it['access'], ["none","full"]),
409
- }
410
- end
411
- print as_pretty_table(rows, [:name, :access], options)
412
- else
413
- print cyan,"Use --report-type-access to list custom access","\n"
398
+ rows = report_type_permissions.select {|it| !it['access'].nil?}.collect do |it|
399
+ {
400
+ name: it['name'],
401
+ access: format_access_string(it['access'], ["none","full"]),
402
+ }
414
403
  end
415
- else
416
- # print "\n"
417
- # print cyan,bold,"Report Type Access: #{get_access_string(json_response['globalReportTypeAccess'])}",reset,"\n"
404
+ print as_pretty_table(rows, [:name, :access], options)
405
+ elsif report_type_permissions.find {|it| !it['access'].nil?}
406
+ print_h2 "Report Type Access", options
407
+ print cyan,"Use --report-type-access to list custom access","\n"
418
408
  end
419
409
 
420
- end
421
- print reset,"\n"
410
+ task_global_access = json_response['globalTaskAccess']
411
+ task_permissions = role['tasks'] ? role['tasks'] : (json_response['taskPermissions'] || [])
412
+ print cyan
413
+ if options[:include_task_access] || options[:include_all_access]
414
+ print_h2 "Task Access", options
415
+ rows = task_permissions.collect do |it|
416
+ {
417
+ name: it['name'],
418
+ access: format_access_string(it['access'], ["none","full"]),
419
+ }
420
+ end
421
+ print as_pretty_table(rows, [:name, :access], options)
422
+ elsif task_permissions.find {|it| !it['access'].nil?}
423
+ print_h2 "Task Access", options
424
+ print cyan,"Use --task-access to list custom access","\n"
425
+ end
422
426
 
423
- return 0, nil
427
+ workflow_global_access = json_response['globalTaskSetAccess']
428
+ workflow_permissions = role['taskSets'] ? role['taskSets'] : (json_response['taskSetPermissions'] || [])
429
+ print cyan
430
+ if options[:include_workflow_access] || options[:include_all_access]
431
+ print_h2 "Workflow", options
432
+ rows = workflow_permissions.select {|it| !it['access'].nil?}.collect do |it|
433
+ {
434
+ name: it['name'],
435
+ access: format_access_string(it['access'], ["none","full"]),
436
+ }
437
+ end
438
+ print as_pretty_table(rows, [:name, :access], options)
439
+ elsif workflow_permissions.find {|it| !it['access'].nil?}
440
+ print_h2 "Workflow", options
441
+ print cyan,"Use --workflow-access to list custom access","\n"
442
+ end
443
+ print reset,"\n"
444
+ return 0, nil
445
+ end
424
446
  end
425
447
 
426
448
  def list_permissions(args)
427
449
  options = {}
450
+ available_categories = ['feature', 'group', 'cloud', 'instance-type', 'blueprint', 'report-type', 'persona', 'catalog-item-type', 'vdi-pool', 'workflow', 'task']
428
451
  optparse = Morpheus::Cli::OptionParser.new do |opts|
429
- opts.banner = subcommand_usage("[role]")
452
+ opts.banner = subcommand_usage("[role] [category]")
430
453
  build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
431
- opts.footer = "List the permissions for a role.\n" +
432
- "[role] is required. This is the name or id of a role."
454
+ opts.footer = "List the access for a role.\n" +
455
+ "[role] is required. This is the name or id of a role.\n" +
456
+ "[category] is optional. Available categories: #{ored_list(available_categories)}"
433
457
  end
458
+
434
459
  optparse.parse!(args)
435
- verify_args!(args:args, optparse:optparse, count:1)
460
+ verify_args!(args:args, optparse:optparse, min: 1, max:2)
436
461
  connect(options)
437
-
438
- account = find_account_from_options(options)
439
- account_id = account ? account['id'] : nil
440
462
 
441
- # role = find_role_by_name_or_id(account_id, args[0])
442
- # exit 1 if role.nil?
463
+ category = args[1].to_s.downcase if args[1]
443
464
 
444
- @roles_interface.setopts(options)
445
- if options[:dry_run]
446
- if args[0].to_s =~ /\A\d{1,}\Z/
447
- print_dry_run @roles_interface.dry.get(account_id, args[0].to_i)
448
- else
449
- print_dry_run @roles_interface.dry.list(account_id, {name: args[0]})
450
- end
451
- return
452
- end
465
+ if !category.nil? && !available_categories.include?(category)
466
+ raise_command_error("invalid category: #{category}", args, optparse)
467
+ end
468
+
469
+ account = find_account_from_options(options)
470
+ account_id = account ? account['id'] : nil
453
471
 
454
- json_response = nil
472
+ @roles_interface.setopts(options)
473
+ if options[:dry_run]
455
474
  if args[0].to_s =~ /\A\d{1,}\Z/
456
- json_response = @roles_interface.get(account_id, args[0].to_i)
457
- role = json_response['role']
475
+ print_dry_run @roles_interface.dry.get(account_id, args[0].to_i)
458
476
  else
459
- role = find_role_by_name_or_id(account_id, args[0])
460
- exit 1 if role.nil?
461
- # refetch from show action, argh
462
- json_response = @roles_interface.get(account_id, role['id'])
463
- role = json_response['role']
477
+ print_dry_run @roles_interface.dry.list(account_id, {name: args[0]})
464
478
  end
479
+ return
480
+ end
481
+
482
+ if args[0].to_s =~ /\A\d{1,}\Z/
483
+ role = @roles_interface.get(account_id, args[0].to_i)
484
+ else
485
+ role = find_role_by_name_or_id(account_id, args[0])
486
+ exit 1 if role.nil?
487
+ role = @roles_interface.get(account_id, role['id'])
488
+ end
465
489
 
466
- role_permissions = json_response['featurePermissions']
490
+ available_categories.reject! {|category| category == 'cloud'} if role['role']['roleType'] == 'user'
491
+ available_categories.reject! {|category| category == 'group'} if role['role']['roleType'] == 'account'
467
492
 
468
- if options[:json]
469
- puts as_json(role_permissions, options)
470
- return 0
471
- elsif options[:yaml]
472
- puts as_yaml(role_permissions, options)
473
- return 0
474
- elsif options[:csv]
475
- puts records_as_csv(role_permissions)
476
- return 0
477
- end
493
+ permission_name = -> (s) {
494
+ return 'sites' if s == 'group'
495
+ return 'zones' if s == 'cloud'
496
+ s = 'task-set' if s == 'workflow'
497
+ s = 'app-template' if s == 'blueprint'
498
+ s.split('-').map.with_index{|s,i| i == 0 ? s : s.capitalize}.join + 'Permissions'
499
+ }
500
+ permission_label = -> (s) {s.split('-').collect{|s| s.capitalize}.join(' ') + ' Permissions'}
478
501
 
479
- print cyan
480
- print_h1 "Role Permissions: [#{role['id']}] #{role['authority']}", options
502
+ if category.nil?
503
+ permissions = available_categories.collect{|category| role[permission_name.call(category)].map{|perm| perm.merge({'category' => permission_label.call(category)})}}.flatten
504
+ else
505
+ permissions = role[permission_name.call(category)]
506
+ end
481
507
 
482
- print cyan
483
- if role_permissions && role_permissions.size > 0
484
- rows = role_permissions.collect do |it|
508
+ if options[:json]
509
+ puts as_json(permissions, options)
510
+ return 0
511
+ elsif options[:yaml]
512
+ puts as_yaml(permissions, options)
513
+ return 0
514
+ elsif options[:csv]
515
+ puts records_as_csv(permissions, :include_fields => ['category', 'id', 'code', 'name', 'access', 'sub category'])
516
+ return 0
517
+ end
518
+
519
+ print cyan
520
+ print_h1 "Role: [#{role['role']['id']},#{role['role']['owner']['name']}] #{role['role']['authority']}", options
521
+
522
+ (category.nil? ? available_categories : [category]).each do |category|
523
+ print_h2 "#{permission_label.call(category)}", options
524
+ permissions = role[permission_name.call(category)]
525
+ if permissions.size > 0
526
+ rows = permissions.collect do |it|
485
527
  {
486
528
  code: it['code'],
487
529
  name: it['name'],
@@ -502,10 +544,8 @@ EOT
502
544
  else
503
545
  puts "No permissions found"
504
546
  end
505
-
506
- print reset,"\n"
507
- return 0
508
-
547
+ end
548
+ print reset,"\n"
509
549
  end
510
550
 
511
551
  def add(args)
@@ -518,74 +558,139 @@ EOT
518
558
  options[:permissions] ||= {}
519
559
  parse_access_csv(options[:permissions], val, args, optparse)
520
560
  end
521
- opts.on('--global-group-access ACCESS', String, "Update the global group (site) access: [none|read|custom|full]" ) do |val|
561
+ opts.add_hidden_option('--permissions')
562
+ opts.on('--feature-access CODE=ACCESS', String, "Set feature permission access by permission code. Example: dashboard=read,operations-wiki=full" ) do |val|
563
+ options[:permissions] ||= {}
564
+ parse_access_csv(options[:permissions], val, args, optparse)
565
+ end
566
+ opts.on('--global-group-access ACCESS', String, "Update the global group (site) access: [none|read|full]" ) do |val|
567
+ params['globalSiteAccess'] = val.to_s.downcase
568
+ end
569
+ opts.add_hidden_option('--global-group-access')
570
+ opts.on('--default-group-access ACCESS', String, "Update the default group (site) access: [none|read|full]" ) do |val|
522
571
  params['globalSiteAccess'] = val.to_s.downcase
523
572
  end
524
573
  opts.on('--groups ID=ACCESS', String, "Set group (site) to a custom access by group id. Example: 1=none,2=full,3=read" ) do |val|
525
574
  options[:group_permissions] ||= {}
526
575
  parse_access_csv(options[:group_permissions], val, args, optparse)
527
576
  end
528
- opts.on('--global-cloud-access ACCESS', String, "Update the global cloud (zone) access: [none|custom|full]" ) do |val|
577
+ opts.on('--global-cloud-access ACCESS', String, "Update the global cloud (zone) access: [none|read|full]" ) do |val|
578
+ params['globalZoneAccess'] = val.to_s.downcase
579
+ end
580
+ opts.add_hidden_option('--global-cloud-access')
581
+ opts.on('--default-cloud-access ACCESS', String, "Update the default cloud (zone) access: [none|read|full]" ) do |val|
529
582
  params['globalZoneAccess'] = val.to_s.downcase
530
583
  end
531
584
  opts.on('--clouds ID=ACCESS', String, "Set cloud (zone) to a custom access by cloud id. Example: 1=none,2=full,3=read" ) do |val|
532
585
  options[:cloud_permissions] ||= {}
533
586
  parse_access_csv(options[:cloud_permissions], val, args, optparse)
534
587
  end
535
- opts.on('--global-instance-type-access ACCESS', String, "Update the global instance type access: [none|custom|full]" ) do |val|
588
+ opts.on('--global-instance-type-access ACCESS', String, "Update the global instance type access: [none|full]" ) do |val|
589
+ params['globalInstanceTypeAccess'] = val.to_s.downcase
590
+ end
591
+ opts.add_hidden_option('--global-instance-type-access')
592
+ opts.on('--default-instance-type-access ACCESS', String, "Update the default instance type access: [none|full]" ) do |val|
536
593
  params['globalInstanceTypeAccess'] = val.to_s.downcase
537
594
  end
538
595
  opts.on('--instance-types CODE=ACCESS', String, "Set instance type to a custom access instance type code. Example: nginx=full,apache=none" ) do |val|
539
596
  options[:instance_type_permissions] ||= {}
540
597
  parse_access_csv(options[:instance_type_permissions], val, args, optparse)
541
598
  end
542
- opts.on('--global-blueprint-access ACCESS', String, "Update the global blueprint access: [none|custom|full]" ) do |val|
599
+ opts.on('--global-blueprint-access ACCESS', String, "Update the global blueprint access: [none|full]" ) do |val|
600
+ params['globalAppTemplateAccess'] = val.to_s.downcase
601
+ end
602
+ opts.add_hidden_option('--global-blueprint-access')
603
+ opts.on('--default-blueprint-access ACCESS', String, "Update the default blueprint access: [none|full]" ) do |val|
543
604
  params['globalAppTemplateAccess'] = val.to_s.downcase
544
605
  end
545
606
  opts.on('--blueprints ID=ACCESS', String, "Set blueprint to a custom access by blueprint id. Example: 1=full,2=none" ) do |val|
546
607
  options[:blueprint_permissions] ||= {}
547
608
  parse_access_csv(options[:blueprint_permissions], val, args, optparse)
548
609
  end
549
- opts.on('--global-catalog-item-type-access ACCESS', String, "Update the global catalog item type access: [none|custom|full]" ) do |val|
610
+ opts.on('--global-catalog-item-type-access ACCESS', String, "Update the global catalog item type access: [none|full]" ) do |val|
611
+ params['globalCatalogItemTypeAccess'] = val.to_s.downcase
612
+ end
613
+ opts.add_hidden_option('--global-catalog-item-type-access')
614
+ opts.on('--default-catalog-item-type-access ACCESS', String, "Update the default catalog item type access: [none|full]" ) do |val|
550
615
  params['globalCatalogItemTypeAccess'] = val.to_s.downcase
551
616
  end
552
617
  opts.on('--catalog-item-types CODE=ACCESS', String, "Set catalog item type to a custom access by catalog item type id. Example: 1=full,2=none" ) do |val|
553
618
  options[:catalog_item_type_permissions] ||= {}
554
619
  parse_access_csv(options[:catalog_item_type_permissions], val, args, optparse)
555
620
  end
621
+ opts.on('--default-persona-access ACCESS', String, "Update the default persona access: [none|full]" ) do |val|
622
+ params['globalPersonaAccess'] = val.to_s.downcase
623
+ end
556
624
  opts.on('--personas CODE=ACCESS', String, "Set persona to a custom access by persona code. Example: standard=full,serviceCatalog=full,vdi=full" ) do |val|
557
625
  options[:persona_permissions] ||= {}
558
626
  parse_access_csv(options[:persona_permissions], val, args, optparse)
559
627
  end
560
- opts.on('--global-vdi-pool-access-access ACCESS', String, "Update the global VDI pool access: [none|custom|full]" ) do |val|
628
+ opts.on('--global-vdi-pool-access-access ACCESS', String, "Update the global VDI pool access: [none|full]" ) do |val|
629
+ params['globalVdiPoolAccess'] = val.to_s.downcase
630
+ end
631
+ opts.add_hidden_option('--global-vdi-pool-access-access')
632
+ opts.on('--default-vdi-pool-access-access ACCESS', String, "Update the default VDI pool access: [none|full]" ) do |val|
561
633
  params['globalVdiPoolAccess'] = val.to_s.downcase
562
634
  end
563
635
  opts.on('--vdi-pools ID=ACCESS', String, "Set VDI pool to a custom access by VDI pool id. Example: 1=full,2=none" ) do |val|
564
636
  options[:vdi_pool_permissions] ||= {}
565
637
  parse_access_csv(options[:vdi_pool_permissions], val, args, optparse)
566
638
  end
567
- opts.on('--global-report-type-access ACCESS', String, "Update the global report type access: [none|custom|full]" ) do |val|
639
+ opts.on('--global-report-type-access ACCESS', String, "Update the global report type access: [none|full]" ) do |val|
640
+ params['globalReportTypeAccess'] = val.to_s.downcase
641
+ end
642
+ opts.on('--default-report-type-access ACCESS', String, "Update the default report type access: [none|full]" ) do |val|
568
643
  params['globalReportTypeAccess'] = val.to_s.downcase
569
644
  end
645
+ opts.add_hidden_option('--default-report-type-access')
570
646
  opts.on('--report-types CODE=ACCESS', String, "Set report type to a custom access by report type code. Example: appCost=none,guidance=full" ) do |val|
571
647
  options[:report_type_permissions] ||= {}
572
648
  parse_access_csv(options[:report_type_permissions], val, args, optparse)
573
649
  end
650
+ opts.on('--global-task-access ACCESS', String, "Set the global task access: [none|full]" ) do |val|
651
+ params['globalTaskAccess'] = val.to_s.downcase
652
+ end
653
+ opts.add_hidden_option('--global-task-access')
654
+ opts.on('--default-task-access ACCESS', String, "Set the default task access: [none|full]" ) do |val|
655
+ params['globalTaskAccess'] = val.to_s.downcase
656
+ end
657
+ opts.on('--tasks ID=ACCESS', String, "Set task to a custom access by task id. Example: 1=none,2=full" ) do |val|
658
+ options[:task_permissions] ||= {}
659
+ parse_access_csv(options[:task_permissions], val, args, optparse)
660
+ end
661
+ opts.on('--global-workflow-access ACCESS', String, "Set the default workflow access: [none|full]" ) do |val|
662
+ params['globalTaskSetAccess'] = val.to_s.downcase
663
+ end
664
+ opts.add_hidden_option('--global-workflow-access')
665
+ opts.on('--default-workflow-access ACCESS', String, "Set the default workflow access: [none|full]" ) do |val|
666
+ params['globalTaskSetAccess'] = val.to_s.downcase
667
+ end
668
+ opts.on('--workflows ID=ACCESS', String, "Set workflow to a custom access by workflow id. Example: 1=none,2=full" ) do |val|
669
+ options[:workflow_permissions] ||= {}
670
+ parse_access_csv(options[:workflow_permissions], val, args, optparse)
671
+ end
574
672
  opts.on('--reset-permissions', "Reset all feature permission access to none. This can be used in conjunction with --permissions to recreate the feature permission access for the role." ) do
575
673
  options[:reset_permissions] = true
576
674
  end
577
- opts.on('--reset-all-access', "Reset all access to none including permissions, global groups, instance types, etc. This can be used in conjunction with --permissions to recreate the feature permission access for the role." ) do
675
+ opts.add_hidden_option('--reset-permissions')
676
+ opts.on('--reset-feature-access', "Reset all feature permission access to none. This can be used in conjunction with --feature-access to recreate the feature permission access for the role." ) do
677
+ options[:reset_permissions] = true
678
+ end
679
+ opts.on('--reset-all-access', "Reset all access to none including permissions, global groups, instance types, etc. This can be used in conjunction with --feature-access to recreate the feature permission access for the role." ) do
578
680
  options[:reset_all_access] = true
681
+ end
682
+ opts.on('--owner ID', String, "Set the owner/tenant/account for the role by account id. Only master tenants with full permission for Tenant and Role may use this option." ) do |val|
683
+ params['owner'] = val
579
684
  end
580
685
  opts.footer = <<-EOT
581
686
  Create a new role.
582
687
  [name] is required. This is a unique name (authority) for the new role.
583
688
  All the role permissions and access values can be configured.
584
- Use --permissions "CODE=ACCESS,CODE=ACCESS" to update access levels for specific feature permissions identified by code.
585
- Use --global-instance-type-access custom --instance-types "CODE=ACCESS,CODE=ACCESS" to customize instance type access.
689
+ Use --feature-access "CODE=ACCESS,CODE=ACCESS" to update access levels for specific feature permissions identified by code.
690
+ Use --default-instance-type-access custom --instance-types "CODE=ACCESS,CODE=ACCESS" to customize instance type access.
586
691
  Only the specified permissions,instance types, etc. are updated.
587
- Use --reset-permissions to set access to "none" for all unspecified feature permissions.
588
- Use --reset-all-access to set access to "none" for all unspecified feature permissions and global access values for groups, instance types, etc.
692
+ Use --reset-feature-access to set access to "none" for all unspecified feature permissions.
693
+ Use --reset-all-access to set access to "none" for all unspecified feature permissions and default access values for groups, instance types, etc.
589
694
  EOT
590
695
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
591
696
  end
@@ -619,21 +724,35 @@ EOT
619
724
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2}], options[:options])
620
725
  role_payload['description'] = v_prompt['description']
621
726
 
622
- if @is_master_account
623
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleType', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => role_type_options, 'defaultValue' => 'user', 'displayOrder' => 3}], options[:options])
727
+ if params['owner']
728
+ if @is_master_account && has_complete_access
729
+ role_payload['owner'] = params['owner']
730
+ else
731
+ print_red_alert "You do not have the necessary authority to use owner option"
732
+ return
733
+ end
734
+ elsif @is_master_account && has_complete_access
735
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'owner', 'fieldLabel' => 'Owner', 'type' => 'select', 'selectOptions' => role_owner_options, 'defaultValue' => current_account['id'], 'displayOrder' => 3}], options[:options])
736
+ role_payload['owner'] = v_prompt['owner']
737
+ else
738
+ role_payload['owner'] = current_account['id']
739
+ end
740
+
741
+ if @is_master_account && role_payload['owner'] == current_account['id']
742
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleType', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => role_type_options, 'defaultValue' => 'user', 'displayOrder' => 4}], options[:options])
624
743
  role_payload['roleType'] = v_prompt['roleType']
625
744
  else
626
745
  role_payload['roleType'] = 'user'
627
746
  end
628
747
 
629
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4}], options[:options])
748
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'select', 'selectOptions' => base_role_options(role_payload), 'displayOrder' => 5}], options[:options])
630
749
  if v_prompt['baseRole'].to_s != ''
631
750
  base_role = find_role_by_name_or_id(account_id, v_prompt['baseRole'])
632
751
  exit 1 if base_role.nil?
633
752
  role_payload['baseRoleId'] = base_role['id']
634
753
  end
635
754
 
636
- if @is_master_account
755
+ if @is_master_account && role_payload['owner'] == current_account['id']
637
756
  if role_payload['roleType'] == 'user'
638
757
  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])
639
758
  role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
@@ -752,6 +871,32 @@ EOT
752
871
  end
753
872
  params['reportTypes'] = perms_array
754
873
  end
874
+ if options[:task_permissions]
875
+ perms_array = []
876
+ options[:task_permissions].each do |k,v|
877
+ task_id = k
878
+ access_value = v.to_s.empty? ? "none" : v.to_s
879
+ if task_id =~ /\A\d{1,}\Z/
880
+ perms_array << {"id" => task_id.to_i, "access" => access_value}
881
+ else
882
+ perms_array << {"name" => task_id, "access" => access_value}
883
+ end
884
+ end
885
+ params['tasks'] = perms_array
886
+ end
887
+ if options[:workflow_permissions]
888
+ perms_array = []
889
+ options[:workflow_permissions].each do |k,v|
890
+ workflow_id = k
891
+ access_value = v.to_s.empty? ? "none" : v.to_s
892
+ if workflow_id =~ /\A\d{1,}\Z/
893
+ perms_array << {"id" => workflow_id.to_i, "access" => access_value}
894
+ else
895
+ perms_array << {"name" => workflow_id, "access" => access_value}
896
+ end
897
+ end
898
+ params['workflows'] = perms_array
899
+ end
755
900
  if options[:reset_permissions]
756
901
  params["resetPermissions"] = true
757
902
  end
@@ -790,6 +935,10 @@ EOT
790
935
  if account
791
936
  details_options.push "--account-id", account['id'].to_s
792
937
  end
938
+
939
+ if role_payload['owner']
940
+ details_options.push "--account-id", role_payload['owner'].to_s
941
+ end
793
942
  get(details_options)
794
943
 
795
944
  rescue RestClient::Exception => e
@@ -808,35 +957,60 @@ EOT
808
957
  options[:permissions] ||= {}
809
958
  parse_access_csv(options[:permissions], val, args, optparse)
810
959
  end
811
- opts.on('--global-group-access ACCESS', String, "Update the global group (site) access: [none|read|custom|full]" ) do |val|
960
+ opts.add_hidden_option('--permissions')
961
+ opts.on('--feature-access CODE=ACCESS', String, "Set feature permission access by permission code. Example: dashboard=read,operations-wiki=full" ) do |val|
962
+ options[:permissions] ||= {}
963
+ parse_access_csv(options[:permissions], val, args, optparse)
964
+ end
965
+ opts.on('--global-group-access ACCESS', String, "Update the global group (site) access: [none|read|full]" ) do |val|
966
+ params['globalSiteAccess'] = val.to_s.downcase
967
+ end
968
+ opts.add_hidden_option('--global-group-access')
969
+ opts.on('--default-group-access ACCESS', String, "Update the default group (site) access: [none|read|full]" ) do |val|
812
970
  params['globalSiteAccess'] = val.to_s.downcase
813
971
  end
814
972
  opts.on('--groups ID=ACCESS', String, "Set group (site) to a custom access by group id. Example: 1=none,2=full,3=read" ) do |val|
815
973
  options[:group_permissions] ||= {}
816
974
  parse_access_csv(options[:group_permissions], val, args, optparse)
817
975
  end
818
- opts.on('--global-cloud-access ACCESS', String, "Update the global cloud (zone) access: [none|custom|full]" ) do |val|
976
+ opts.on('--global-cloud-access ACCESS', String, "Update the global cloud (zone) access: [none|read|full]" ) do |val|
977
+ params['globalZoneAccess'] = val.to_s.downcase
978
+ end
979
+ opts.add_hidden_option('--global-cloud-access')
980
+ opts.on('--default-cloud-access ACCESS', String, "Update the default cloud (zone) access: [none|read|full]" ) do |val|
819
981
  params['globalZoneAccess'] = val.to_s.downcase
820
982
  end
821
983
  opts.on('--clouds ID=ACCESS', String, "Set cloud (zone) to a custom access by cloud id. Example: 1=none,2=full,3=read" ) do |val|
822
984
  options[:cloud_permissions] ||= {}
823
985
  parse_access_csv(options[:cloud_permissions], val, args, optparse)
824
986
  end
825
- opts.on('--global-instance-type-access ACCESS', String, "Update the global instance type access: [none|custom|full]" ) do |val|
987
+ opts.on('--global-instance-type-access ACCESS', String, "Update the global instance type access: [none|full]" ) do |val|
988
+ params['globalInstanceTypeAccess'] = val.to_s.downcase
989
+ end
990
+ opts.add_hidden_option('--global-instance-type-access')
991
+ opts.on('--default-instance-type-access ACCESS', String, "Update the default instance type access: [none|full]" ) do |val|
826
992
  params['globalInstanceTypeAccess'] = val.to_s.downcase
827
993
  end
828
994
  opts.on('--instance-types CODE=ACCESS', String, "Set instance type to a custom access instance type code. Example: nginx=full,apache=none" ) do |val|
829
995
  options[:instance_type_permissions] ||= {}
830
996
  parse_access_csv(options[:instance_type_permissions], val, args, optparse)
831
997
  end
832
- opts.on('--global-blueprint-access ACCESS', String, "Update the global blueprint access: [none|custom|full]" ) do |val|
998
+ opts.on('--global-blueprint-access ACCESS', String, "Update the global blueprint access: [none|full]" ) do |val|
999
+ params['globalAppTemplateAccess'] = val.to_s.downcase
1000
+ end
1001
+ opts.add_hidden_option('--global-blueprint-access')
1002
+ opts.on('--default-blueprint-access ACCESS', String, "Update the default blueprint access: [none|full]" ) do |val|
833
1003
  params['globalAppTemplateAccess'] = val.to_s.downcase
834
1004
  end
835
1005
  opts.on('--blueprints ID=ACCESS', String, "Set blueprint to a custom access by blueprint id. Example: 1=full,2=none" ) do |val|
836
1006
  options[:blueprint_permissions] ||= {}
837
1007
  parse_access_csv(options[:blueprint_permissions], val, args, optparse)
838
1008
  end
839
- opts.on('--global-catalog-item-type-access ACCESS', String, "Update the global catalog item type access: [none|custom|full]" ) do |val|
1009
+ opts.on('--global-catalog-item-type-access ACCESS', String, "Update the global catalog item type access: [none|full]" ) do |val|
1010
+ params['globalCatalogItemTypeAccess'] = val.to_s.downcase
1011
+ end
1012
+ opts.add_hidden_option('--global-catalog-item-type-access')
1013
+ opts.on('--default-catalog-item-type-access ACCESS', String, "Update the default catalog item type access: [none|full]" ) do |val|
840
1014
  params['globalCatalogItemTypeAccess'] = val.to_s.downcase
841
1015
  end
842
1016
  opts.on('--catalog-item-types CODE=ACCESS', String, "Set catalog item type to a custom access by catalog item type id. Example: 1=full,2=none" ) do |val|
@@ -847,24 +1021,58 @@ EOT
847
1021
  options[:persona_permissions] ||= {}
848
1022
  parse_access_csv(options[:persona_permissions], val, args, optparse)
849
1023
  end
850
- opts.on('--global-vdi-pool-access-access ACCESS', String, "Update the global VDI pool access: [none|custom|full]" ) do |val|
1024
+ opts.on('--global-vdi-pool-access ACCESS', String, "Update the global VDI pool access: [none|full]" ) do |val|
1025
+ params['globalVdiPoolAccess'] = val.to_s.downcase
1026
+ end
1027
+ opts.add_hidden_option('--global-vdi-pool-access')
1028
+ opts.on('--default-vdi-pool-access ACCESS', String, "Update the default VDI pool access: [none|full]" ) do |val|
851
1029
  params['globalVdiPoolAccess'] = val.to_s.downcase
852
1030
  end
853
1031
  opts.on('--vdi-pools ID=ACCESS', String, "Set VDI pool to a custom access by VDI pool id. Example: 1=full,2=none" ) do |val|
854
1032
  options[:vdi_pool_permissions] ||= {}
855
1033
  parse_access_csv(options[:vdi_pool_permissions], val, args, optparse)
856
1034
  end
857
- opts.on('--global-report-type-access ACCESS', String, "Update the global report type access: [none|custom|full]" ) do |val|
1035
+ opts.on('--global-report-type-access ACCESS', String, "Update the global report type access: [none|full]" ) do |val|
1036
+ params['globalReportTypeAccess'] = val.to_s.downcase
1037
+ end
1038
+ opts.add_hidden_option('--global-report-type-access')
1039
+ opts.on('--default-report-type-access ACCESS', String, "Update the default report type access: [none|full]" ) do |val|
858
1040
  params['globalReportTypeAccess'] = val.to_s.downcase
859
1041
  end
860
1042
  opts.on('--report-types CODE=ACCESS', String, "Set report type to a custom access by report type code. Example: appCost=none,guidance=full" ) do |val|
861
1043
  options[:report_type_permissions] ||= {}
862
1044
  parse_access_csv(options[:report_type_permissions], val, args, optparse)
863
1045
  end
1046
+ opts.on('--global-task-access ACCESS', String, "Update the global task access: [none|full]" ) do |val|
1047
+ params['globalTaskAccess'] = val.to_s.downcase
1048
+ end
1049
+ opts.add_hidden_option('--global-task-access')
1050
+ opts.on('--default-task-access ACCESS', String, "Update the default task access: [none|full]" ) do |val|
1051
+ params['globalTaskAccess'] = val.to_s.downcase
1052
+ end
1053
+ opts.on('--tasks ID=ACCESS', String, "Set task to a custom access by task id. Example: 1=none,2=full" ) do |val|
1054
+ options[:task_permissions] ||= {}
1055
+ parse_access_csv(options[:task_permissions], val, args, optparse)
1056
+ end
1057
+ opts.on('--global-workflow-access ACCESS', String, "Update the global workflow access: [none|full]" ) do |val|
1058
+ params['globalTaskSetAccess'] = val.to_s.downcase
1059
+ end
1060
+ opts.add_hidden_option('--global-workflow-access')
1061
+ opts.on('--default-workflow-access ACCESS', String, "Update the default workflow access: [none|full]" ) do |val|
1062
+ params['globalTaskSetAccess'] = val.to_s.downcase
1063
+ end
1064
+ opts.on('--workflows ID=ACCESS', String, "Set workflow to a custom access by workflow id. Example: 1=none,2=full" ) do |val|
1065
+ options[:workflow_permissions] ||= {}
1066
+ parse_access_csv(options[:workflow_permissions], val, args, optparse)
1067
+ end
864
1068
  opts.on('--reset-permissions', "Reset all feature permission access to none. This can be used in conjunction with --permissions to recreate the feature permission access for the role." ) do
865
1069
  options[:reset_permissions] = true
866
1070
  end
867
- opts.on('--reset-all-access', "Reset all access to none including permissions, global groups, instance types, etc. This can be used in conjunction with --permissions to recreate the feature permission access for the role." ) do
1071
+ opts.add_hidden_option('--reset-permissions')
1072
+ opts.on('--reset-feature-access', "Reset all feature permission access to none. This can be used in conjunction with --feature-access to recreate the feature permission access for the role." ) do
1073
+ options[:reset_permissions] = true
1074
+ end
1075
+ opts.on('--reset-all-access', "Reset all access to none including permissions, global groups, instance types, etc. This can be used in conjunction with --feature-access to recreate the feature permission access for the role." ) do
868
1076
  options[:reset_all_access] = true
869
1077
  end
870
1078
  build_standard_update_options(opts, options)
@@ -872,10 +1080,10 @@ EOT
872
1080
  Update a role.
873
1081
  [role] is required. This is the name (authority) or id of a role.
874
1082
  All the role permissions and access values can be configured.
875
- Use --permissions "CODE=ACCESS,CODE=ACCESS" to update access levels for specific feature permissions identified by code.
876
- Use --global-instance-type-access custom --instance-types "CODE=ACCESS,CODE=ACCESS" to customize instance type access.
1083
+ Use --feature-access "CODE=ACCESS,CODE=ACCESS" to update access levels for specific feature permissions identified by code.
1084
+ Use --default-instance-type-access custom --instance-types "CODE=ACCESS,CODE=ACCESS" to customize instance type access.
877
1085
  Only the specified permissions,instance types, etc. are updated.
878
- Use --reset-permissions to set access to "none" for all unspecified feature permissions.
1086
+ Use --reset-feature-access to set access to "none" for all unspecified feature permissions.
879
1087
  Use --reset-all-access to set access to "none" for all unspecified feature permissions and global access values for groups, instance types, etc.
880
1088
  EOT
881
1089
  end
@@ -1016,6 +1224,32 @@ EOT
1016
1224
  end
1017
1225
  params['reportTypes'] = perms_array
1018
1226
  end
1227
+ if options[:task_permissions]
1228
+ perms_array = []
1229
+ options[:task_permissions].each do |k,v|
1230
+ task_id = k
1231
+ access_value = v.to_s.empty? ? "none" : v.to_s
1232
+ if task_id =~ /\A\d{1,}\Z/
1233
+ perms_array << {"id" => task_id.to_i, "access" => access_value}
1234
+ else
1235
+ perms_array << {"name" => task_id, "access" => access_value}
1236
+ end
1237
+ end
1238
+ params['tasks'] = perms_array
1239
+ end
1240
+ if options[:workflow_permissions]
1241
+ perms_array = []
1242
+ options[:workflow_permissions].each do |k,v|
1243
+ workflow_id = k
1244
+ access_value = v.to_s.empty? ? "none" : v.to_s
1245
+ if workflow_id =~ /\A\d{1,}\Z/
1246
+ perms_array << {"id" => workflow_id.to_i, "access" => access_value}
1247
+ else
1248
+ perms_array << {"name" => workflow_id, "access" => access_value}
1249
+ end
1250
+ end
1251
+ params['taskSets'] = perms_array
1252
+ end
1019
1253
  if options[:reset_permissions]
1020
1254
  params["resetPermissions"] = true
1021
1255
  end
@@ -1099,7 +1333,7 @@ EOT
1099
1333
 
1100
1334
  def update_feature_access(args)
1101
1335
  options = {}
1102
- allowed_access_values = ['full', 'user', 'read', 'none'] # just for display , veries per permission
1336
+ allowed_access_values = ["full", "full_decrypted", "group", "listfiles", "managerules", "no", "none", "provision", "read", "rolemappings", "user", "view", "yes"]
1103
1337
  permission_code = nil
1104
1338
  access_value = nil
1105
1339
  optparse = Morpheus::Cli::OptionParser.new do |opts|
@@ -1168,15 +1402,19 @@ EOT
1168
1402
  end
1169
1403
 
1170
1404
  def update_global_group_access(args)
1171
- usage = "Usage: morpheus roles update-global-group-access [role] [full|read|custom|none]"
1405
+ puts "#{yellow}DEPRECATED#{reset}"
1406
+ update_default_group_access(args)
1407
+ end
1408
+
1409
+ def update_default_group_access(args)
1172
1410
  options = {}
1173
1411
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1174
- opts.banner = subcommand_usage("[role] [full|read|custom|none]")
1412
+ opts.banner = subcommand_usage("[role] [access]")
1175
1413
  build_common_options(opts, options, [:json, :dry_run, :remote])
1176
1414
  opts.footer = <<-EOT
1177
- Update global group access for a role.
1415
+ Update default group access for a role.
1178
1416
  [role] is required. This is the name (authority) or id of a role.
1179
- [access] is required. This is the access level to assign: full, read, custom or none.
1417
+ [access] is required. This is the access level to assign: full, read, or none.
1180
1418
  Only applicable to User roles.
1181
1419
  EOT
1182
1420
  end
@@ -1188,7 +1426,7 @@ EOT
1188
1426
  end
1189
1427
  name = args[0]
1190
1428
  access_value = args[1].to_s.downcase
1191
- if !['full', 'read', 'custom', 'none'].include?(access_value)
1429
+ if !['full', 'read', 'none'].include?(access_value)
1192
1430
  puts optparse
1193
1431
  exit 1
1194
1432
  end
@@ -1212,7 +1450,7 @@ EOT
1212
1450
  print JSON.pretty_generate(json_response)
1213
1451
  print "\n"
1214
1452
  else
1215
- print_green_success "Role #{role['authority']} global group access updated"
1453
+ print_green_success "Role #{role['authority']} default group access updated"
1216
1454
  end
1217
1455
  rescue RestClient::Exception => e
1218
1456
  print_rest_exception(e, options)
@@ -1226,7 +1464,7 @@ EOT
1226
1464
  group_id = nil
1227
1465
  access_value = nil
1228
1466
  do_all = false
1229
- allowed_access_values = ['full', 'read', 'none']
1467
+ allowed_access_values = ['full', 'read', 'none', 'default']
1230
1468
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1231
1469
  opts.banner = subcommand_usage("[role] [group] [access]")
1232
1470
  opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
@@ -1244,7 +1482,6 @@ Update role access for a group or all groups.
1244
1482
  [role] is required. This is the name or id of a role.
1245
1483
  --group or --all is required. This is the name or id of a group.
1246
1484
  --access is required. This is the new access value: #{ored_list(allowed_access_values)}
1247
- Only applicable to User roles and when global group access is set to "custom".
1248
1485
  EOT
1249
1486
 
1250
1487
  end
@@ -1279,14 +1516,6 @@ EOT
1279
1516
  role = find_role_by_name_or_id(account_id, name)
1280
1517
  return 1 if role.nil?
1281
1518
 
1282
- role_json = @roles_interface.get(account_id, role['id'])
1283
- if role_json['globalSiteAccess'] != 'custom'
1284
- print "\n", red, "Global Group Access is currently: #{role_json['globalSiteAccess'].capitalize}"
1285
- print "\n", "You must first set it to Custom via `morpheus roles update-global-group-access \"#{name}\" custom`"
1286
- print "\n\n", reset
1287
- exit 1
1288
- end
1289
-
1290
1519
  group = nil
1291
1520
  if !do_all
1292
1521
  group = find_group_by_name_or_id_for_provisioning(group_id)
@@ -1326,15 +1555,19 @@ EOT
1326
1555
  end
1327
1556
 
1328
1557
  def update_global_cloud_access(args)
1329
- usage = "Usage: morpheus roles update-global-cloud-access [role] [full|custom|none]"
1558
+ puts "#{yellow}DEPRECATED#{reset}"
1559
+ update_default_cloud_access(args)
1560
+ end
1561
+
1562
+ def update_default_cloud_access(args)
1330
1563
  options = {}
1331
1564
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1332
- opts.banner = subcommand_usage("[role] [full|custom|none]")
1565
+ opts.banner = subcommand_usage("[role] [access]")
1333
1566
  build_common_options(opts, options, [:json, :dry_run, :remote])
1334
- opts.footer = <<-EOT
1335
- Update global cloud access for a role.
1567
+ opts.footer = <<-EOT
1568
+ Update default cloud access for a role.
1336
1569
  [role] is required. This is the name (authority) or id of a role.
1337
- [access] is required. This is the access level to assign: full, custom or none.
1570
+ [access] is required. This is the access level to assign: full, read or none.
1338
1571
  Only applicable to Tenant roles.
1339
1572
  EOT
1340
1573
  end
@@ -1346,7 +1579,7 @@ EOT
1346
1579
  end
1347
1580
  name = args[0]
1348
1581
  access_value = args[1].to_s.downcase
1349
- if !['full', 'custom', 'none'].include?(access_value)
1582
+ if !['full', 'read', 'none'].include?(access_value)
1350
1583
  puts optparse
1351
1584
  exit 1
1352
1585
  end
@@ -1370,7 +1603,7 @@ EOT
1370
1603
  print JSON.pretty_generate(json_response)
1371
1604
  print "\n"
1372
1605
  else
1373
- print_green_success "Role #{role['authority']} global cloud access updated"
1606
+ print_green_success "Role #{role['authority']} default cloud access updated"
1374
1607
  end
1375
1608
  rescue RestClient::Exception => e
1376
1609
  print_rest_exception(e, options)
@@ -1383,7 +1616,7 @@ EOT
1383
1616
  cloud_id = nil
1384
1617
  access_value = nil
1385
1618
  do_all = false
1386
- allowed_access_values = ['full', 'read', 'none']
1619
+ allowed_access_values = ['full', 'read', 'none', 'default']
1387
1620
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1388
1621
  opts.banner = subcommand_usage("[role]")
1389
1622
  opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
@@ -1401,7 +1634,6 @@ Update role access for a cloud or all clouds.
1401
1634
  [role] is required. This is the name or id of a role.
1402
1635
  --cloud or --all is required. This is the name or id of a cloud.
1403
1636
  --access is required. This is the new access value: #{ored_list(allowed_access_values)}
1404
- Only applicable to Tenant roles and when global cloud access is set to "custom".
1405
1637
  EOT
1406
1638
  end
1407
1639
  optparse.parse!(args)
@@ -1436,12 +1668,6 @@ EOT
1436
1668
  exit 1 if role.nil?
1437
1669
 
1438
1670
  role_json = @roles_interface.get(account_id, role['id'])
1439
- if role_json['globalZoneAccess'] != 'custom'
1440
- print "\n", red, "Global Cloud Access is currently: #{role_json['globalZoneAccess'].capitalize}"
1441
- print "\n", "You must first set it to Custom via `morpheus roles update-global-cloud-access \"#{name}\" custom`"
1442
- print "\n\n", reset
1443
- exit 1
1444
- end
1445
1671
 
1446
1672
  cloud = nil
1447
1673
  if !do_all
@@ -1481,15 +1707,19 @@ EOT
1481
1707
  end
1482
1708
 
1483
1709
  def update_global_instance_type_access(args)
1484
- usage = "Usage: morpheus roles update-global-instance-type-access [role] [full|custom|none]"
1710
+ puts "#{yellow}DEPRECATED#{reset}"
1711
+ update_default_instance_type_access(args)
1712
+ end
1713
+
1714
+ def update_default_instance_type_access(args)
1485
1715
  options = {}
1486
1716
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1487
- opts.banner = subcommand_usage("[role] [full|custom|none]")
1717
+ opts.banner = subcommand_usage("[role] [access]")
1488
1718
  build_common_options(opts, options, [:json, :dry_run, :remote])
1489
1719
  opts.footer = <<-EOT
1490
- Update global instance type access for a role.
1720
+ Update default instance type access for a role.
1491
1721
  [role] is required. This is the name (authority) or id of a role.
1492
- [access] is required. This is the access level to assign: full, custom or none.
1722
+ [access] is required. This is the access level to assign: full or none.
1493
1723
  EOT
1494
1724
  end
1495
1725
  optparse.parse!(args)
@@ -1500,7 +1730,7 @@ EOT
1500
1730
  end
1501
1731
  name = args[0]
1502
1732
  access_value = args[1].to_s.downcase
1503
- if !['full', 'custom', 'none'].include?(access_value)
1733
+ if !['full', 'none'].include?(access_value)
1504
1734
  puts optparse
1505
1735
  exit 1
1506
1736
  end
@@ -1525,7 +1755,7 @@ EOT
1525
1755
  print JSON.pretty_generate(json_response)
1526
1756
  print "\n"
1527
1757
  else
1528
- print_green_success "Role #{role['authority']} global instance type access updated"
1758
+ print_green_success "Role #{role['authority']} default instance type access updated"
1529
1759
  end
1530
1760
  rescue RestClient::Exception => e
1531
1761
  print_rest_exception(e, options)
@@ -1538,7 +1768,7 @@ EOT
1538
1768
  instance_type_name = nil
1539
1769
  access_value = nil
1540
1770
  do_all = false
1541
- allowed_access_values = ['full', 'none']
1771
+ allowed_access_values = ['full', 'none', 'default']
1542
1772
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1543
1773
  opts.banner = subcommand_usage("[role] [type] [access]")
1544
1774
  opts.on( '--instance-type INSTANCE_TYPE', String, "Instance Type name" ) do |val|
@@ -1587,13 +1817,6 @@ EOT
1587
1817
  return 1 if role.nil?
1588
1818
 
1589
1819
  role_json = @roles_interface.get(account_id, role['id'])
1590
- if role_json['globalInstanceTypeAccess'] != 'custom'
1591
- print "\n", red, "Global Instance Type Access is currently: #{role_json['globalInstanceTypeAccess'].capitalize}"
1592
- print "\n", "You must first set it to Custom via `morpheus roles update-global-instance-type-access \"#{name}\" custom`"
1593
- print "\n\n", reset
1594
- return 1
1595
- end
1596
-
1597
1820
  instance_type = nil
1598
1821
  if !do_all
1599
1822
  instance_type = find_instance_type_by_name(instance_type_name)
@@ -1632,15 +1855,19 @@ EOT
1632
1855
  end
1633
1856
 
1634
1857
  def update_global_blueprint_access(args)
1635
- usage = "Usage: morpheus roles update-global-blueprint-access [role] [full|custom|none]"
1858
+ puts "#{yellow}DEPRECATED#{reset}"
1859
+ update_default_blueprint_access(args)
1860
+ end
1861
+
1862
+ def update_default_blueprint_access(args)
1636
1863
  options = {}
1637
1864
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1638
- opts.banner = subcommand_usage("[role] [full|custom|none]")
1865
+ opts.banner = subcommand_usage("[role] [access]")
1639
1866
  build_common_options(opts, options, [:json, :dry_run, :remote])
1640
1867
  opts.footer = <<-EOT
1641
- Update global blueprint access for a role.
1868
+ Update default blueprint access for a role.
1642
1869
  [role] is required. This is the name (authority) or id of a role.
1643
- [access] is required. This is the access level to assign: full, custom or none.
1870
+ [access] is required. This is the access level to assign: full or none.
1644
1871
  EOT
1645
1872
  end
1646
1873
  optparse.parse!(args)
@@ -1651,7 +1878,7 @@ EOT
1651
1878
  end
1652
1879
  name = args[0]
1653
1880
  access_value = args[1].to_s.downcase
1654
- if !['full', 'custom', 'none'].include?(access_value)
1881
+ if !['full', 'none'].include?(access_value)
1655
1882
  puts optparse
1656
1883
  exit 1
1657
1884
  end
@@ -1676,7 +1903,7 @@ EOT
1676
1903
  print JSON.pretty_generate(json_response)
1677
1904
  print "\n"
1678
1905
  else
1679
- print_green_success "Role #{role['authority']} global blueprint access updated"
1906
+ print_green_success "Role #{role['authority']} default blueprint access updated"
1680
1907
  end
1681
1908
  rescue RestClient::Exception => e
1682
1909
  print_rest_exception(e, options)
@@ -1689,7 +1916,7 @@ EOT
1689
1916
  blueprint_id = nil
1690
1917
  access_value = nil
1691
1918
  do_all = false
1692
- allowed_access_values = ['full', 'none']
1919
+ allowed_access_values = ['full', 'none', 'default']
1693
1920
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1694
1921
  opts.banner = subcommand_usage("[role] [blueprint] [access]")
1695
1922
  opts.on( '--blueprint ID', String, "Blueprint ID or Name" ) do |val|
@@ -1741,12 +1968,6 @@ EOT
1741
1968
  role_json = @roles_interface.get(account_id, role['id'])
1742
1969
  blueprint_global_access = role_json['globalAppTemplateAccess'] || role_json['globalBlueprintAccess']
1743
1970
  blueprint_permissions = role_json['appTemplatePermissions'] || role_json['blueprintPermissions'] || []
1744
- if blueprint_global_access != 'custom'
1745
- print "\n", red, "Global Blueprint Access is currently: #{blueprint_global_access.to_s.capitalize}"
1746
- print "\n", "You must first set it to Custom via `morpheus roles update-global-blueprint-access \"#{name}\" custom`"
1747
- print "\n\n", reset
1748
- return 1
1749
- end
1750
1971
 
1751
1972
  # hacky, but support name or code lookup via the list returned in the show payload
1752
1973
  blueprint = nil
@@ -1796,15 +2017,19 @@ EOT
1796
2017
  end
1797
2018
 
1798
2019
  def update_global_catalog_item_type_access(args)
1799
- usage = "Usage: morpheus roles update-global-catalog-item-type-access [role] [full|custom|none]"
2020
+ puts "#{yellow}DEPRECATED#{reset}"
2021
+ update_default_catalog_item_type_access(args)
2022
+ end
2023
+
2024
+ def update_default_catalog_item_type_access(args)
1800
2025
  options = {}
1801
2026
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1802
- opts.banner = subcommand_usage("[role] [full|custom|none]")
2027
+ opts.banner = subcommand_usage("[role] [access]")
1803
2028
  build_common_options(opts, options, [:json, :dry_run, :remote])
1804
2029
  opts.footer = <<-EOT
1805
- Update global catalog item type access for a role.
2030
+ Update default catalog item type access for a role.
1806
2031
  [role] is required. This is the name (authority) or id of a role.
1807
- [access] is required. This is the access level to assign: full, custom or none.
2032
+ [access] is required. This is the access level to assign: full or none.
1808
2033
  EOT
1809
2034
  end
1810
2035
  optparse.parse!(args)
@@ -1815,7 +2040,7 @@ EOT
1815
2040
  end
1816
2041
  name = args[0]
1817
2042
  access_value = args[1].to_s.downcase
1818
- if !['full', 'custom', 'none'].include?(access_value)
2043
+ if !['full', 'none'].include?(access_value)
1819
2044
  puts optparse
1820
2045
  exit 1
1821
2046
  end
@@ -1840,7 +2065,7 @@ EOT
1840
2065
  print JSON.pretty_generate(json_response)
1841
2066
  print "\n"
1842
2067
  else
1843
- print_green_success "Role #{role['authority']} global catalog item type access updated"
2068
+ print_green_success "Role #{role['authority']} default catalog item type access updated"
1844
2069
  end
1845
2070
  rescue RestClient::Exception => e
1846
2071
  print_rest_exception(e, options)
@@ -1853,7 +2078,7 @@ EOT
1853
2078
  catalog_item_type_id = nil
1854
2079
  access_value = nil
1855
2080
  do_all = false
1856
- allowed_access_values = ['full', 'none']
2081
+ allowed_access_values = ['full', 'none', 'default']
1857
2082
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1858
2083
  opts.banner = subcommand_usage("[role] [catalog-item-type] [access]")
1859
2084
  opts.on( '--catalog-item-type ID', String, "Catalog Item Type ID or Name" ) do |val|
@@ -1905,12 +2130,6 @@ EOT
1905
2130
  role_json = @roles_interface.get(account_id, role['id'])
1906
2131
  catalog_item_type_global_access = role_json['globalCatalogItemTypeAccess']
1907
2132
  catalog_item_type_permissions = role_json['catalogItemTypePermissions'] || role_json['catalogItemTypes'] []
1908
- if catalog_item_type_global_access != 'custom'
1909
- print "\n", red, "Global Catalog Item Type Access is currently: #{catalog_item_type_global_access.to_s.capitalize}"
1910
- print "\n", "You must first set it to Custom via `morpheus roles update-global-catalog-item-type-access \"#{name}\" custom`"
1911
- print "\n\n", reset
1912
- return 1
1913
- end
1914
2133
 
1915
2134
  # hacky, but support name or code lookup via the list returned in the show payload
1916
2135
  catalog_item_type = nil
@@ -1957,13 +2176,64 @@ EOT
1957
2176
  end
1958
2177
  end
1959
2178
 
2179
+ def update_default_persona_access(args)
2180
+ options = {}
2181
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2182
+ opts.banner = subcommand_usage("[role] [access]")
2183
+ build_common_options(opts, options, [:json, :dry_run, :remote])
2184
+ opts.footer = <<-EOT
2185
+ Update default persona access for a role.
2186
+ [role] is required. This is the name (authority) or id of a role.
2187
+ [access] is required. This is the access level to assign: full or none.
2188
+ EOT
2189
+ end
2190
+ optparse.parse!(args)
2191
+
2192
+ if args.count < 2
2193
+ puts optparse
2194
+ exit 1
2195
+ end
2196
+ name = args[0]
2197
+ access_value = args[1].to_s.downcase
2198
+ if !['full', 'none'].include?(access_value)
2199
+ puts optparse
2200
+ exit 1
2201
+ end
2202
+
2203
+ connect(options)
2204
+ begin
2205
+ account = find_account_from_options(options)
2206
+ account_id = account ? account['id'] : nil
2207
+ role = find_role_by_name_or_id(account_id, name)
2208
+ exit 1 if role.nil?
2209
+
2210
+ params = {permissionCode: 'Persona', access: access_value}
2211
+ @roles_interface.setopts(options)
2212
+ if options[:dry_run]
2213
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
2214
+ return
2215
+ end
2216
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
2217
+
2218
+ if options[:json]
2219
+ print JSON.pretty_generate(json_response)
2220
+ print "\n"
2221
+ else
2222
+ print_green_success "Role #{role['authority']} default persona access updated"
2223
+ end
2224
+ rescue RestClient::Exception => e
2225
+ print_rest_exception(e, options)
2226
+ exit 1
2227
+ end
2228
+ end
2229
+
1960
2230
  def update_persona_access(args)
1961
2231
  options = {}
1962
2232
  persona_id = nil
1963
2233
  name = nil
1964
2234
  access_value = nil
1965
2235
  do_all = false
1966
- allowed_access_values = ['full', 'none']
2236
+ allowed_access_values = ['full', 'none', 'default']
1967
2237
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1968
2238
  opts.banner = subcommand_usage("[role] [persona] [access]")
1969
2239
  opts.on( '--persona CODE', String, "Persona Code" ) do |val|
@@ -2049,22 +2319,26 @@ EOT
2049
2319
  end
2050
2320
 
2051
2321
  def update_global_vdi_pool_access(args)
2052
- usage = "Usage: morpheus roles update-global-vdi-pool-access [role] [full|custom|none]"
2322
+ puts "#{yellow}DEPRECATED#{reset}"
2323
+ update_default_vdi_pool_access(args)
2324
+ end
2325
+
2326
+ def update_default_vdi_pool_access(args)
2053
2327
  options = {}
2054
2328
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2055
- opts.banner = subcommand_usage("[role] [full|custom|none]")
2329
+ opts.banner = subcommand_usage("[role] [access]")
2056
2330
  build_common_options(opts, options, [:json, :dry_run, :remote])
2057
2331
  opts.footer = <<-EOT
2058
- Update global VDI pool access for a role.
2332
+ Update default VDI pool access for a role.
2059
2333
  [role] is required. This is the name (authority) or id of a role.
2060
- [access] is required. This is the access level to assign: full, custom or none.
2334
+ [access] is required. This is the access level to assign: full or none.
2061
2335
  EOT
2062
2336
  end
2063
2337
  optparse.parse!(args)
2064
2338
  verify_args!(args:args, optparse:optparse, count: 2)
2065
2339
  name = args[0]
2066
2340
  access_value = args[1].to_s.downcase
2067
- if !['full', 'custom', 'none'].include?(access_value)
2341
+ if !['full', 'none'].include?(access_value)
2068
2342
  raise_command_error("invalid access value: #{args[1]}", args, optparse)
2069
2343
  end
2070
2344
 
@@ -2088,7 +2362,7 @@ EOT
2088
2362
  print JSON.pretty_generate(json_response)
2089
2363
  print "\n"
2090
2364
  else
2091
- print_green_success "Role #{role['authority']} global vdi pool access updated"
2365
+ print_green_success "Role #{role['authority']} default vdi pool access updated"
2092
2366
  end
2093
2367
  rescue RestClient::Exception => e
2094
2368
  print_rest_exception(e, options)
@@ -2101,7 +2375,7 @@ EOT
2101
2375
  vdi_pool_id = nil
2102
2376
  access_value = nil
2103
2377
  do_all = false
2104
- allowed_access_values = ['full', 'none']
2378
+ allowed_access_values = ['full', 'none', 'default']
2105
2379
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2106
2380
  opts.banner = subcommand_usage("[role] [vdi-pool] [access]")
2107
2381
  opts.on( '--vdi-pool ID', String, "VDI Pool ID or Name" ) do |val|
@@ -2121,8 +2395,6 @@ EOT
2121
2395
  end
2122
2396
  optparse.parse!(args)
2123
2397
 
2124
- # usage: update-vdi-pool-access [role] [access] --all
2125
- # update-vdi-pool-access [role] [vdi-pool] [access]
2126
2398
  name = args[0]
2127
2399
  if do_all
2128
2400
  verify_args!(args:args, optparse:optparse, min:1, max:2)
@@ -2155,12 +2427,6 @@ EOT
2155
2427
  role_json = @roles_interface.get(account_id, role['id'])
2156
2428
  vdi_pool_global_access = role_json['globalVdiPoolAccess']
2157
2429
  vdi_pool_permissions = role_json['vdiPoolPermissions'] || role_json['vdiPools'] || []
2158
- if vdi_pool_global_access != 'custom'
2159
- print "\n", red, "Global VDI Pool Access is currently: #{vdi_pool_global_access.to_s.capitalize}"
2160
- print "\n", "You must first set it to Custom via `morpheus roles update-global-vdi-pool-access \"#{name}\" custom`"
2161
- print "\n\n", reset
2162
- return 1
2163
- end
2164
2430
 
2165
2431
  # hacky, but support name or code lookup via the list returned in the show payload
2166
2432
  vdi_pool = nil
@@ -2208,26 +2474,29 @@ EOT
2208
2474
  end
2209
2475
 
2210
2476
  def update_global_report_type_access(args)
2211
- usage = "Usage: morpheus roles update-global-report-type-access [role] [full|custom|none]"
2477
+ puts "#{yellow}DEPRECATED#{reset}"
2478
+ update_default_report_type_access(args)
2479
+ end
2480
+
2481
+ def update_default_report_type_access(args)
2212
2482
  options = {}
2213
2483
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2214
- opts.banner = subcommand_usage("[role] [full|custom|none]")
2484
+ opts.banner = subcommand_usage("[role] [access]")
2215
2485
  build_common_options(opts, options, [:json, :dry_run, :remote])
2216
2486
  opts.footer = <<-EOT
2217
- Update global report type access for a role.
2487
+ Update default report type access for a role.
2218
2488
  [role] is required. This is the name (authority) or id of a role.
2219
- [access] is required. This is the access level to assign: full, custom or none.
2489
+ [access] is required. This is the access level to assign: full or none.
2220
2490
  EOT
2221
2491
  end
2222
2492
  optparse.parse!(args)
2223
2493
  verify_args!(args:args, optparse:optparse, count: 2)
2224
2494
  name = args[0]
2225
2495
  access_value = args[1].to_s.downcase
2226
- if !['full', 'custom', 'none'].include?(access_value)
2496
+ if !['full', 'none'].include?(access_value)
2227
2497
  raise_command_error("invalid access value: #{args[1]}", args, optparse)
2228
2498
  end
2229
2499
 
2230
-
2231
2500
  connect(options)
2232
2501
  begin
2233
2502
  account = find_account_from_options(options)
@@ -2247,7 +2516,7 @@ EOT
2247
2516
  print JSON.pretty_generate(json_response)
2248
2517
  print "\n"
2249
2518
  else
2250
- print_green_success "Role #{role['authority']} global report type access updated"
2519
+ print_green_success "Role #{role['authority']} default report type access updated"
2251
2520
  end
2252
2521
  rescue RestClient::Exception => e
2253
2522
  print_rest_exception(e, options)
@@ -2260,7 +2529,7 @@ EOT
2260
2529
  report_type_id = nil
2261
2530
  access_value = nil
2262
2531
  do_all = false
2263
- allowed_access_values = ['full', 'none']
2532
+ allowed_access_values = ['full', 'none', 'default']
2264
2533
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2265
2534
  opts.banner = subcommand_usage("[role] [report-type] [access]")
2266
2535
  opts.on( '--report-type ID', String, "Report Type ID or Name" ) do |val|
@@ -2314,12 +2583,6 @@ EOT
2314
2583
  role_json = @roles_interface.get(account_id, role['id'])
2315
2584
  report_type_global_access = role_json['globalReportTypeAccess']
2316
2585
  report_type_permissions = role_json['reportTypePermissions'] || role_json['reportTypes'] || []
2317
- if report_type_global_access != 'custom'
2318
- print "\n", red, "Global Report Type Access is currently: #{report_type_global_access.to_s.capitalize}"
2319
- print "\n", "You must first set it to Custom via `morpheus roles update-global-report-type-access \"#{name}\" custom`"
2320
- print "\n\n", reset
2321
- return 1
2322
- end
2323
2586
 
2324
2587
  # hacky, but support name or code lookup via the list returned in the show payload
2325
2588
  report_type = nil
@@ -2366,6 +2629,311 @@ EOT
2366
2629
  end
2367
2630
  end
2368
2631
 
2632
+ def update_global_task_access(args)
2633
+ puts "#{yellow}DEPRECATED#{reset}"
2634
+ update_default_task_access(args)
2635
+ end
2636
+
2637
+ def update_default_task_access(args)
2638
+ options = {}
2639
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2640
+ opts.banner = subcommand_usage("[role] [access]")
2641
+ build_common_options(opts, options, [:json, :dry_run, :remote])
2642
+ opts.footer = <<-EOT
2643
+ Update default task access for a role.
2644
+ [role] is required. This is the id of a role.
2645
+ [access] is required. This is the access level to assign: full or none.
2646
+ EOT
2647
+ end
2648
+ optparse.parse!(args)
2649
+ verify_args!(args:args, optparse:optparse, count: 2)
2650
+ name = args[0]
2651
+ access_value = args[1].to_s.downcase
2652
+ if !['full', 'none'].include?(access_value)
2653
+ raise_command_error("invalid access value: #{args[1]}", args, optparse)
2654
+ end
2655
+
2656
+ connect(options)
2657
+ begin
2658
+ account = find_account_from_options(options)
2659
+ account_id = account ? account['id'] : nil
2660
+ role = find_role_by_name_or_id(account_id, name)
2661
+ exit 1 if role.nil?
2662
+ # note: ReportTypes being plural is odd, the others are singular
2663
+ params = {permissionCode: 'Task', access: access_value}
2664
+ @roles_interface.setopts(options)
2665
+ if options[:dry_run]
2666
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
2667
+ return
2668
+ end
2669
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
2670
+
2671
+ if options[:json]
2672
+ print JSON.pretty_generate(json_response)
2673
+ print "\n"
2674
+ else
2675
+ print_green_success "Role #{role['authority']} default task access updated"
2676
+ end
2677
+ rescue RestClient::Exception => e
2678
+ print_rest_exception(e, options)
2679
+ exit 1
2680
+ end
2681
+ end
2682
+
2683
+ def update_task_access(args)
2684
+ options = {}
2685
+ task_id = nil
2686
+ access_value = nil
2687
+ do_all = false
2688
+ allowed_access_values = ['full', 'none', 'default']
2689
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2690
+ opts.banner = subcommand_usage("[role] [task] [access]")
2691
+ opts.on( '--task ID', String, "Task ID, code or name" ) do |val|
2692
+ report_type_id = val
2693
+ end
2694
+ opts.on( nil, '--all', "Update all tasks at once." ) do
2695
+ do_all = true
2696
+ end
2697
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
2698
+ access_value = val
2699
+ end
2700
+ build_common_options(opts, options, [:json, :dry_run, :remote])
2701
+ opts.footer = "Update role access for a task or all tasks.\n" +
2702
+ "[role] is required. This is the name, code or id of a task.\n" +
2703
+ "--task or --all is required. This is the name, code or id of a task.\n" +
2704
+ "--access is required. This is the new access value: #{ored_list(allowed_access_values)}"
2705
+ end
2706
+ optparse.parse!(args)
2707
+
2708
+ name = args[0]
2709
+ if do_all
2710
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
2711
+ access_value = args[1] if args[1]
2712
+ else
2713
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
2714
+ task_id = args[1] if args[1]
2715
+ access_value = args[2] if args[2]
2716
+ end
2717
+ if !task_id && !do_all
2718
+ raise_command_error("missing required argument: [task] or --all", args, optparse)
2719
+ end
2720
+ if !access_value
2721
+ raise_command_error("missing required argument: [access]", args, optparse)
2722
+ end
2723
+ access_value = access_value.to_s.downcase
2724
+ if !allowed_access_values.include?(access_value)
2725
+ raise_command_error("invalid access value: #{access_value}", args, optparse)
2726
+ puts optparse
2727
+ return 1
2728
+ end
2729
+
2730
+ connect(options)
2731
+ begin
2732
+ account = find_account_from_options(options)
2733
+ account_id = account ? account['id'] : nil
2734
+ role = find_role_by_name_or_id(account_id, name)
2735
+ return 1 if role.nil?
2736
+
2737
+ role_json = @roles_interface.get(account_id, role['id'])
2738
+ task_permissions = role_json['taskPermissions'] || role_json['tasks'] || []
2739
+
2740
+ # hacky, but support name or code lookup via the list returned in the show payload
2741
+ task = nil
2742
+ if !do_all
2743
+ if task_id.to_s =~ /\A\d{1,}\Z/
2744
+ task = task_permissions.find {|b| b['id'] == task_id.to_i }
2745
+ else
2746
+ task = task_permissions.find {|b| b['name'] == task_id || b['code'] == task_id }
2747
+ end
2748
+ if task.nil?
2749
+ print_red_alert "Task not found: '#{task_id}'"
2750
+ return 1
2751
+ end
2752
+ end
2753
+
2754
+ params = {}
2755
+ if do_all
2756
+ params['allTasks'] = true
2757
+ else
2758
+ params['taskId'] = task['id']
2759
+ end
2760
+ params['access'] = access_value == 'default' ? nil : access_value
2761
+ @roles_interface.setopts(options)
2762
+ if options[:dry_run]
2763
+ print_dry_run @roles_interface.dry.update_task(account_id, role['id'], params)
2764
+ return
2765
+ end
2766
+ json_response = @roles_interface.update_task(account_id, role['id'], params)
2767
+
2768
+ if options[:json]
2769
+ print JSON.pretty_generate(json_response)
2770
+ print "\n"
2771
+ else
2772
+ if do_all
2773
+ print_green_success "Role #{role['authority']} access updated for all tasks"
2774
+ else
2775
+ print_green_success "Role #{role['authority']} access updated for task #{task['name']}"
2776
+ end
2777
+ end
2778
+ return 0
2779
+ rescue RestClient::Exception => e
2780
+ print_rest_exception(e, options)
2781
+ exit 1
2782
+ end
2783
+ end
2784
+
2785
+ def update_global_workflow_access(args)
2786
+ puts "#{yellow}DEPRECATED#{reset}"
2787
+ update_default_workflow_access(args)
2788
+ end
2789
+
2790
+ def update_default_workflow_access(args)
2791
+ options = {}
2792
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2793
+ opts.banner = subcommand_usage("[role] [access]")
2794
+ build_common_options(opts, options, [:json, :dry_run, :remote])
2795
+ opts.footer = <<-EOT
2796
+ Update default workflow access for a role.
2797
+ [role] is required. This is the id of a role.
2798
+ [access] is required. This is the access level to assign: full or none.
2799
+ EOT
2800
+ end
2801
+ optparse.parse!(args)
2802
+ verify_args!(args:args, optparse:optparse, count: 2)
2803
+ name = args[0]
2804
+ access_value = args[1].to_s.downcase
2805
+ if !['full', 'none'].include?(access_value)
2806
+ raise_command_error("invalid access value: #{args[1]}", args, optparse)
2807
+ end
2808
+
2809
+ connect(options)
2810
+ begin
2811
+ account = find_account_from_options(options)
2812
+ account_id = account ? account['id'] : nil
2813
+ role = find_role_by_name_or_id(account_id, name)
2814
+ exit 1 if role.nil?
2815
+ params = {permissionCode: 'TaskSet', access: access_value}
2816
+ @roles_interface.setopts(options)
2817
+ if options[:dry_run]
2818
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
2819
+ return
2820
+ end
2821
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
2822
+
2823
+ if options[:json]
2824
+ print JSON.pretty_generate(json_response)
2825
+ print "\n"
2826
+ else
2827
+ print_green_success "Role #{role['authority']} default workflow access updated"
2828
+ end
2829
+ rescue RestClient::Exception => e
2830
+ print_rest_exception(e, options)
2831
+ exit 1
2832
+ end
2833
+ end
2834
+
2835
+ def update_workflow_access(args)
2836
+ options = {}
2837
+ workflow_id = nil
2838
+ access_value = nil
2839
+ do_all = false
2840
+ allowed_access_values = ['full', 'none', 'default']
2841
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2842
+ opts.banner = subcommand_usage("[role] [workflow] [access]")
2843
+ opts.on( '--workflow ID', String, "Workflow ID, code or Name" ) do |val|
2844
+ workflow_id = val
2845
+ end
2846
+ opts.on( nil, '--all', "Update all workflows at once." ) do
2847
+ do_all = true
2848
+ end
2849
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
2850
+ access_value = val
2851
+ end
2852
+ build_common_options(opts, options, [:json, :dry_run, :remote])
2853
+ opts.footer = "Update role access for a workflow or all workflows.\n" +
2854
+ "[role] is required. This is the name or id of a role.\n" +
2855
+ "--workflow or --all is required. This is the name, code or id of a workflow.\n" +
2856
+ "--access is required. This is the new access value: #{ored_list(allowed_access_values)}"
2857
+ end
2858
+ optparse.parse!(args)
2859
+
2860
+ name = args[0]
2861
+ if do_all
2862
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
2863
+ access_value = args[1] if args[1]
2864
+ else
2865
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
2866
+ workflow_id = args[1] if args[1]
2867
+ access_value = args[2] if args[2]
2868
+ end
2869
+ if !workflow_id && !do_all
2870
+ raise_command_error("missing required argument: [workflow] or --all", args, optparse)
2871
+ end
2872
+ if !access_value
2873
+ raise_command_error("missing required argument: [access]", args, optparse)
2874
+ end
2875
+ access_value = access_value.to_s.downcase
2876
+ if !allowed_access_values.include?(access_value)
2877
+ raise_command_error("invalid access value: #{access_value}", args, optparse)
2878
+ puts optparse
2879
+ return 1
2880
+ end
2881
+
2882
+ connect(options)
2883
+ begin
2884
+ account = find_account_from_options(options)
2885
+ account_id = account ? account['id'] : nil
2886
+ role = find_role_by_name_or_id(account_id, name)
2887
+ return 1 if role.nil?
2888
+
2889
+ role_json = @roles_interface.get(account_id, role['id'])
2890
+ workflow_permissions = role_json['taskSetPermissions'] || role_json['taskSets'] || []
2891
+
2892
+ # hacky, but support name or code lookup via the list returned in the show payload
2893
+ workflow = nil
2894
+ if !do_all
2895
+ if workflow_id.to_s =~ /\A\d{1,}\Z/
2896
+ workflow = workflow_permissions.find {|b| b['id'] == workflow_id.to_i }
2897
+ else
2898
+ workflow = workflow_permissions.find {|b| b['name'] == workflow_id }
2899
+ end
2900
+ if workflow.nil?
2901
+ print_red_alert "Workflow not found: '#{workflow_id}'"
2902
+ return 1
2903
+ end
2904
+ end
2905
+
2906
+ params = {}
2907
+ if do_all
2908
+ params['allTaskSets'] = true
2909
+ else
2910
+ params['taskSetId'] = workflow['id']
2911
+ end
2912
+ params['access'] = access_value == 'default' ? nil : access_value
2913
+ @roles_interface.setopts(options)
2914
+ if options[:dry_run]
2915
+ print_dry_run @roles_interface.dry.update_task_set(account_id, role['id'], params)
2916
+ return
2917
+ end
2918
+ json_response = @roles_interface.update_task_set(account_id, role['id'], params)
2919
+
2920
+ if options[:json]
2921
+ print JSON.pretty_generate(json_response)
2922
+ print "\n"
2923
+ else
2924
+ if do_all
2925
+ print_green_success "Role #{role['authority']} access updated for all workflows"
2926
+ else
2927
+ print_green_success "Role #{role['authority']} access updated for workflow #{workflow['name']}"
2928
+ end
2929
+ end
2930
+ return 0
2931
+ rescue RestClient::Exception => e
2932
+ print_rest_exception(e, options)
2933
+ exit 1
2934
+ end
2935
+ end
2936
+
2369
2937
  private
2370
2938
 
2371
2939
  def add_role_option_types
@@ -2396,6 +2964,27 @@ EOT
2396
2964
  ]
2397
2965
  end
2398
2966
 
2967
+ def role_owner_options
2968
+ @options_interface.options_for_source("tenants", {})['data']
2969
+ end
2970
+
2971
+ def base_role_options(role_payload)
2972
+ params = {"tenantId" => role_payload['owner'], "userId" => current_user['id'], "roleType" => role_payload['roleType'] }
2973
+ @options_interface.options_for_source("copyFromRole", params)['data']
2974
+ end
2975
+
2976
+ def has_complete_access
2977
+ has_access = false
2978
+ if @is_master_account
2979
+ admin_accounts = @user_permissions.select { |it| it['code'] == 'admin-accounts' && it['access'] == 'full'}
2980
+ admin_roles = @user_permissions.select { |it| it['code'] == 'admin-roles' && it['access'] == 'full' }
2981
+ if admin_accounts != nil && admin_roles != nil
2982
+ has_access = true
2983
+ end
2984
+ end
2985
+ has_access
2986
+ end
2987
+
2399
2988
  def parse_access_csv(output, val, args, optparse)
2400
2989
  output ||= {}
2401
2990
  val.split(",").each do |value_pair|