morpheus-cli 5.2.4.1 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +1 -3
  4. data/lib/morpheus/api/api_client.rb +48 -14
  5. data/lib/morpheus/api/certificate_types_interface.rb +14 -0
  6. data/lib/morpheus/api/certificates_interface.rb +9 -0
  7. data/lib/morpheus/api/integration_types_interface.rb +14 -0
  8. data/lib/morpheus/api/integrations_interface.rb +7 -22
  9. data/lib/morpheus/api/network_services_interface.rb +14 -0
  10. data/lib/morpheus/api/read_interface.rb +23 -0
  11. data/lib/morpheus/api/rest_interface.rb +12 -10
  12. data/lib/morpheus/api/roles_interface.rb +7 -0
  13. data/lib/morpheus/api/servers_interface.rb +7 -0
  14. data/lib/morpheus/api/user_settings_interface.rb +38 -18
  15. data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
  16. data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
  17. data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
  18. data/lib/morpheus/api/vdi_interface.rb +28 -0
  19. data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
  20. data/lib/morpheus/cli.rb +9 -2
  21. data/lib/morpheus/cli/activity_command.rb +7 -4
  22. data/lib/morpheus/cli/apps.rb +59 -75
  23. data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
  24. data/lib/morpheus/cli/certificates_command.rb +575 -0
  25. data/lib/morpheus/cli/cli_command.rb +61 -6
  26. data/lib/morpheus/cli/clouds.rb +1 -0
  27. data/lib/morpheus/cli/clusters.rb +5 -2
  28. data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
  29. data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
  30. data/lib/morpheus/cli/dashboard_command.rb +3 -3
  31. data/lib/morpheus/cli/execution_request_command.rb +15 -5
  32. data/lib/morpheus/cli/hosts.rb +245 -224
  33. data/lib/morpheus/cli/instances.rb +150 -167
  34. data/lib/morpheus/cli/integrations_command.rb +588 -41
  35. data/lib/morpheus/cli/invoices_command.rb +23 -46
  36. data/lib/morpheus/cli/login.rb +7 -0
  37. data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
  38. data/lib/morpheus/cli/mixins/print_helper.rb +36 -18
  39. data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
  40. data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
  41. data/lib/morpheus/cli/network_domains_command.rb +2 -2
  42. data/lib/morpheus/cli/network_routers_command.rb +22 -9
  43. data/lib/morpheus/cli/networks_command.rb +2 -2
  44. data/lib/morpheus/cli/option_types.rb +34 -33
  45. data/lib/morpheus/cli/remote.rb +3 -2
  46. data/lib/morpheus/cli/reports_command.rb +5 -2
  47. data/lib/morpheus/cli/roles.rb +215 -55
  48. data/lib/morpheus/cli/service_plans_command.rb +4 -1
  49. data/lib/morpheus/cli/subnets_command.rb +11 -2
  50. data/lib/morpheus/cli/user_settings_command.rb +268 -57
  51. data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
  52. data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
  53. data/lib/morpheus/cli/vdi_command.rb +359 -0
  54. data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
  55. data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
  56. data/lib/morpheus/cli/version.rb +1 -1
  57. data/lib/morpheus/rest_client.rb +30 -0
  58. data/lib/morpheus/terminal.rb +15 -7
  59. metadata +18 -2
@@ -0,0 +1,159 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ # CLI command VDI Allocation management
4
+ # UI is Tools: VDI Allocations
5
+ # API is /vdi-allocations and returns vdiAllocations
6
+ class Morpheus::Cli::VdiAllocationsCommand
7
+ include Morpheus::Cli::CliCommand
8
+ include Morpheus::Cli::VdiHelper
9
+ include Morpheus::Cli::OptionSourceHelper
10
+
11
+ set_command_name :'vdi-allocations'
12
+ set_command_description "View VDI allocations"
13
+
14
+ register_subcommands :list, :get
15
+
16
+ def connect(opts)
17
+ @api_client = establish_remote_appliance_connection(opts)
18
+ @vdi_pools_interface = @api_client.vdi_pools
19
+ @vdi_allocations_interface = @api_client.vdi_allocations
20
+ @option_types_interface = @api_client.option_types
21
+ end
22
+
23
+ def handle(args)
24
+ handle_subcommand(args)
25
+ end
26
+
27
+ def list(args)
28
+ options = {}
29
+ params = {}
30
+ ref_ids = []
31
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
32
+ opts.banner = subcommand_usage("[search]")
33
+ build_standard_list_options(opts, options)
34
+ opts.on('--id ID', String, "Filter by VDI Allocation ID" ) do |val|
35
+ params['id'] = parse_id_list(val)
36
+ end
37
+ opts.on('--status STATUS', String, "Filter by VDI Allocation Status" ) do |val|
38
+ params['status'] = parse_id_list(val)
39
+ end
40
+ opts.on('--pool POOL', String, "Filter by VDI Pool Name or ID" ) do |val|
41
+ options[:pool] = val
42
+ end
43
+ opts.on('-u', '--user USER', "Filter by User Username or ID" ) do |val|
44
+ options[:user] = val
45
+ end
46
+ opts.footer = "List VDI allocations."
47
+ end
48
+ optparse.parse!(args)
49
+ connect(options)
50
+ if args.count > 0
51
+ options[:phrase] = args.join(" ")
52
+ end
53
+ params.merge!(parse_list_options(options))
54
+ # --id
55
+ if options[:pool]
56
+ pool_ids = parse_id_list(options[:pool]).collect { |it|
57
+ vdi_pool = find_vdi_pool_by_name_or_id(it)
58
+ vdi_pool ? vdi_pool['id'] : nil
59
+ }
60
+ return 1 if pool_ids.include?(nil)
61
+ params['poolId'] = pool_ids
62
+ end
63
+ # --pool
64
+ if options[:pool]
65
+ pool_ids = parse_id_list(options[:pool]).collect { |it|
66
+ vdi_pool = find_vdi_pool_by_name_or_id(it)
67
+ vdi_pool ? vdi_pool['id'] : nil
68
+ }
69
+ return 1 if pool_ids.include?(nil)
70
+ params['poolId'] = pool_ids
71
+ end
72
+ # --user
73
+ if options[:user]
74
+ user_ids = parse_user_id_list(options[:user])
75
+ return 1 if user_ids.nil?
76
+ params['userId'] = user_ids
77
+ end
78
+ @vdi_allocations_interface.setopts(options)
79
+ if options[:dry_run]
80
+ print_dry_run @vdi_allocations_interface.dry.list(params)
81
+ return
82
+ end
83
+ json_response = @vdi_allocations_interface.list(params)
84
+ render_response(json_response, options, vdi_allocation_list_key) do
85
+ vdi_allocations = json_response[vdi_allocation_list_key]
86
+ print_h1 "Morpheus VDI Allocations", parse_list_subtitles(options), options
87
+ if vdi_allocations.empty?
88
+ print cyan,"No VDI allocations found.",reset,"\n"
89
+ else
90
+ list_columns = vdi_allocation_column_definitions.upcase_keys!
91
+ print as_pretty_table(vdi_allocations, list_columns, options)
92
+ print_results_pagination(json_response)
93
+ end
94
+ print reset,"\n"
95
+ end
96
+ return 0, nil
97
+ end
98
+
99
+ def get(args)
100
+ params = {}
101
+ options = {}
102
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
103
+ opts.banner = subcommand_usage("[allocation]")
104
+ build_standard_get_options(opts, options)
105
+ opts.footer = <<-EOT
106
+ Get details about a specific VDI allocation.
107
+ [allocation] is required. This is the id of a VDI allocation.
108
+ EOT
109
+ end
110
+ optparse.parse!(args)
111
+ verify_args!(args:args, optparse:optparse, min:1)
112
+ connect(options)
113
+ params.merge!(parse_query_options(options))
114
+ id_list = parse_id_list(args)
115
+ return run_command_for_each_arg(id_list) do |arg|
116
+ _get(arg, params, options)
117
+ end
118
+ end
119
+
120
+ def _get(id, params, options)
121
+ @vdi_allocations_interface.setopts(options)
122
+ if options[:dry_run]
123
+ print_dry_run @vdi_allocations_interface.dry.get(id, params)
124
+ return
125
+ end
126
+ json_response = @vdi_allocations_interface.get(id, params)
127
+ vdi_allocation = json_response[vdi_allocation_object_key]
128
+ render_response(json_response, options, vdi_allocation_object_key) do
129
+ print_h1 "VDI Allocation Details", [], options
130
+ print cyan
131
+ show_columns = vdi_allocation_column_definitions
132
+ print_description_list(show_columns, vdi_allocation)
133
+ print reset,"\n"
134
+ end
135
+ return 0, nil
136
+ end
137
+
138
+ private
139
+
140
+ def vdi_allocation_column_definitions()
141
+ {
142
+ "ID" => lambda {|it| it['id'] },
143
+ "Pool" => lambda {|it| it['pool'] ? it['pool']['name'] : nil },
144
+ "Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : nil },
145
+ "User" => lambda {|it| it['user'] ? it['user']['username'] : nil },
146
+ "Status" => lambda {|it| format_vdi_allocation_status(it) },
147
+ "Created" => lambda {|it| format_local_dt it['dateCreated'] },
148
+ "Last Reserved" => lambda {|it| format_local_dt it['lastReserved'] },
149
+ "Release Date" => lambda {|it| format_local_dt it['releaseDate'] }
150
+ }
151
+ end
152
+
153
+ def vdi_allocation_list_column_definitions()
154
+ vdi_allocation_column_definitions()
155
+ end
156
+
157
+ # finders are in VdiHelper mixin
158
+
159
+ end
@@ -0,0 +1,317 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ # CLI command VDI App management
4
+ # UI is Tools: VDI Apps
5
+ # API is /vdi-apps and returns vdiApps
6
+ class Morpheus::Cli::VdiAppsCommand
7
+ include Morpheus::Cli::CliCommand
8
+ include Morpheus::Cli::VdiHelper
9
+ include Morpheus::Cli::OptionSourceHelper
10
+
11
+ set_command_name :'vdi-apps'
12
+ set_command_description "View and manage VDI apps"
13
+
14
+ register_subcommands :list, :get, :add, :update, :remove
15
+
16
+ def connect(opts)
17
+ @api_client = establish_remote_appliance_connection(opts)
18
+ @vdi_apps_interface = @api_client.vdi_apps
19
+ @vdi_apps_interface = @api_client.vdi_apps
20
+ @vdi_apps_interface = @api_client.vdi_apps
21
+ @option_types_interface = @api_client.option_types
22
+ end
23
+
24
+ def handle(args)
25
+ handle_subcommand(args)
26
+ end
27
+
28
+ def list(args)
29
+ options = {}
30
+ params = {}
31
+ ref_ids = []
32
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
33
+ opts.banner = subcommand_usage("[search]")
34
+ build_standard_list_options(opts, options)
35
+ opts.footer = "List VDI apps."
36
+ end
37
+ optparse.parse!(args)
38
+ connect(options)
39
+ if args.count > 0
40
+ options[:phrase] = args.join(" ")
41
+ end
42
+ params.merge!(parse_list_options(options))
43
+ @vdi_apps_interface.setopts(options)
44
+ if options[:dry_run]
45
+ print_dry_run @vdi_apps_interface.dry.list(params)
46
+ return
47
+ end
48
+ json_response = @vdi_apps_interface.list(params)
49
+ render_response(json_response, options, vdi_app_list_key) do
50
+ vdi_apps = json_response[vdi_app_list_key]
51
+ print_h1 "Morpheus VDI Apps", parse_list_subtitles(options), options
52
+ if vdi_apps.empty?
53
+ print cyan,"No VDI apps found.",reset,"\n"
54
+ else
55
+ print as_pretty_table(vdi_apps, vdi_app_list_column_definitions.upcase_keys!, options)
56
+ print_results_pagination(json_response)
57
+ end
58
+ print reset,"\n"
59
+ end
60
+ return 0, nil
61
+ end
62
+
63
+ def get(args)
64
+ params = {}
65
+ options = {}
66
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
67
+ opts.banner = subcommand_usage("[app]")
68
+ build_standard_get_options(opts, options)
69
+ opts.footer = <<-EOT
70
+ Get details about a specific VDI app.
71
+ [app] is required. This is the name or id of a VDI app.
72
+ EOT
73
+ end
74
+ optparse.parse!(args)
75
+ verify_args!(args:args, optparse:optparse, min:1)
76
+ connect(options)
77
+ params.merge!(parse_query_options(options))
78
+ id_list = parse_id_list(args)
79
+ return run_command_for_each_arg(id_list) do |arg|
80
+ _get(arg, params, options)
81
+ end
82
+ end
83
+
84
+ def _get(id, params, options)
85
+ vdi_app = nil
86
+ if id.to_s !~ /\A\d{1,}\Z/
87
+ vdi_app = find_vdi_app_by_name(id)
88
+ return 1, "VDI app not found for #{id}" if vdi_app.nil?
89
+ id = vdi_app['id']
90
+ end
91
+ @vdi_apps_interface.setopts(options)
92
+ if options[:dry_run]
93
+ print_dry_run @vdi_apps_interface.dry.get(id, params)
94
+ return
95
+ end
96
+ json_response = @vdi_apps_interface.get(id, params)
97
+ vdi_app = json_response[vdi_app_object_key]
98
+ config = vdi_app['config'] || {}
99
+ # export just the config as json or yaml (default)
100
+ if options[:show_config]
101
+ unless options[:json] || options[:yaml] || options[:csv]
102
+ options[:yaml] = true
103
+ end
104
+ return render_with_format(config, options)
105
+ end
106
+ render_response(json_response, options, vdi_app_object_key) do
107
+ print_h1 "VDI App Details", [], options
108
+ print cyan
109
+ show_columns = vdi_app_column_definitions
110
+ show_columns.delete("VDI Apps") unless vdi_app['apps']
111
+ show_columns.delete("VDI App") unless vdi_app['app']
112
+ show_columns.delete("Guest Console Jump Host") unless vdi_app['guestConsoleJumpHost']
113
+ show_columns.delete("Guest Console Jump Port") unless vdi_app['guestConsoleJumpPort']
114
+ show_columns.delete("Guest Console Jump Username") unless vdi_app['guestConsoleJumpUsername']
115
+ show_columns.delete("Guest Console Jump Password") unless vdi_app['guestConsoleJumpPassword']
116
+ show_columns.delete("Guest Console Jump Keypair") unless vdi_app['guestConsoleJumpKeypair']
117
+ print_description_list(show_columns, vdi_app)
118
+
119
+
120
+ print reset,"\n"
121
+ end
122
+ return 0, nil
123
+ end
124
+
125
+ def add(args)
126
+ options = {}
127
+ params = {}
128
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
129
+ opts.banner = subcommand_usage("[name] [options]")
130
+ build_option_type_options(opts, options, add_vdi_app_option_types)
131
+ build_standard_add_options(opts, options)
132
+ opts.footer = <<-EOT
133
+ Create a new VDI app.
134
+ EOT
135
+ end
136
+ optparse.parse!(args)
137
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
138
+ options[:options]['name'] = args[0] if args[0]
139
+ if options[:options]['logo']
140
+ options[:options]['iconPath'] = 'custom'
141
+ end
142
+ connect(options)
143
+ payload = {}
144
+ if options[:payload]
145
+ payload = options[:payload]
146
+ payload.deep_merge!({vdi_app_object_key => parse_passed_options(options)})
147
+ else
148
+ payload.deep_merge!({vdi_app_object_key => parse_passed_options(options)})
149
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_vdi_app_option_types, options[:options], @api_client, options[:params])
150
+ params.deep_merge!(v_prompt)
151
+ params.booleanize!
152
+ # logo upload requires multipart instead of json
153
+ if params['logo']
154
+ params['logo'] = File.new(File.expand_path(params['logo']), 'rb')
155
+ payload[:multipart] = true
156
+ end
157
+ payload[vdi_app_object_key].deep_merge!(params)
158
+ end
159
+ @vdi_apps_interface.setopts(options)
160
+ if options[:dry_run]
161
+ print_dry_run @vdi_apps_interface.dry.create(payload)
162
+ return 0, nil
163
+ end
164
+ json_response = @vdi_apps_interface.create(payload)
165
+ vdi_app = json_response[vdi_app_object_key]
166
+ render_response(json_response, options, vdi_app_object_key) do
167
+ print_green_success "Added VDI app #{vdi_app['name']}"
168
+ return _get(vdi_app["id"], {}, options)
169
+ end
170
+ return 0, nil
171
+ end
172
+
173
+ def update(args)
174
+ options = {}
175
+ params = {}
176
+ payload = {}
177
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
178
+ opts.banner = subcommand_usage("[app] [options]")
179
+ build_option_type_options(opts, options, update_vdi_app_option_types)
180
+ build_standard_update_options(opts, options)
181
+ opts.footer = <<-EOT
182
+ Update a VDI app.
183
+ [app] is required. This is the name or id of a VDI app.
184
+ EOT
185
+ end
186
+ optparse.parse!(args)
187
+ verify_args!(args:args, optparse:optparse, count:1)
188
+ if options[:options]['logo']
189
+ options[:options]['iconPath'] = 'custom'
190
+ end
191
+ connect(options)
192
+ vdi_app = find_vdi_app_by_name_or_id(args[0])
193
+ return 1 if vdi_app.nil?
194
+ payload = {}
195
+ if options[:payload]
196
+ payload = options[:payload]
197
+ payload.deep_merge!({vdi_app_object_key => parse_passed_options(options)})
198
+ else
199
+ payload.deep_merge!({vdi_app_object_key => parse_passed_options(options)})
200
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_vdi_app_option_types, options[:options], @api_client, options[:params])
201
+ v_prompt.deep_compact!
202
+ params.deep_merge!(v_prompt)
203
+ params.booleanize!
204
+ # logo upload requires multipart instead of json
205
+ if params['logo']
206
+ params['logo'] = File.new(File.expand_path(params['logo']), 'rb')
207
+ payload[:multipart] = true
208
+ end
209
+ payload.deep_merge!({vdi_app_object_key => params})
210
+ if payload[vdi_app_object_key].empty? # || options[:no_prompt]
211
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
212
+ end
213
+ end
214
+ @vdi_apps_interface.setopts(options)
215
+ if options[:dry_run]
216
+ print_dry_run @vdi_apps_interface.dry.update(vdi_app['id'], payload)
217
+ return
218
+ end
219
+ json_response = @vdi_apps_interface.update(vdi_app['id'], payload)
220
+ vdi_app = json_response[vdi_app_object_key]
221
+ render_response(json_response, options, vdi_app_object_key) do
222
+ print_green_success "Updated VDI app #{vdi_app['name']}"
223
+ return _get(vdi_app["id"], {}, options)
224
+ end
225
+ return 0, nil
226
+ end
227
+
228
+ def remove(args)
229
+ options = {}
230
+ params = {}
231
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
232
+ opts.banner = subcommand_usage("[app] [options]")
233
+ build_standard_remove_options(opts, options)
234
+ opts.footer = <<-EOT
235
+ Delete a VDI app.
236
+ [app] is required. This is the name or id of a VDI app.
237
+ EOT
238
+ end
239
+ optparse.parse!(args)
240
+ verify_args!(args:args, optparse:optparse, count:1)
241
+ connect(options)
242
+ vdi_app = find_vdi_app_by_name_or_id(args[0])
243
+ return 1 if vdi_app.nil?
244
+ @vdi_apps_interface.setopts(options)
245
+ if options[:dry_run]
246
+ print_dry_run @vdi_apps_interface.dry.destroy(vdi_app['id'], params)
247
+ return
248
+ end
249
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the VDI app #{vdi_app['name']}?")
250
+ return 9, "aborted command"
251
+ end
252
+ json_response = @vdi_apps_interface.destroy(vdi_app['id'], params)
253
+ render_response(json_response, options) do
254
+ print_green_success "Removed VDI app #{vdi_app['name']}"
255
+ end
256
+ return 0, nil
257
+ end
258
+
259
+ private
260
+
261
+ def vdi_app_list_column_definitions()
262
+
263
+ {
264
+ "ID" => 'id',
265
+ "Name" => 'name',
266
+ # "Description" => 'description',
267
+ "Launch Prefix" => 'launchPrefix',
268
+ # "Logo" => 'logo',
269
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
270
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
271
+ }
272
+ end
273
+
274
+ def vdi_app_column_definitions()
275
+ {
276
+ "ID" => 'id',
277
+ "Name" => 'name',
278
+ "Description" => 'description',
279
+ "Launch Prefix" => 'launchPrefix',
280
+ "Logo" => 'logo',
281
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
282
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
283
+ }
284
+ end
285
+
286
+ def add_vdi_app_option_types
287
+ [
288
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Choose a unique name for the VDI App'},
289
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'description' => 'Description'},
290
+ {'fieldName' => 'launchPrefix', 'fieldLabel' => 'Launch Prefix', 'type' => 'text', 'required' => true, 'description' => 'The RDS App Name Prefix. Note: Must start with || (i.e. ||notepad) to launch notepad'},
291
+ #{'code' => 'vdiApp.iconPath', 'fieldName' => 'iconPath', 'fieldLabel' => 'Logo', 'type' => 'select', 'optionSource' => 'iconList', 'defaultValue' => 'resource'},
292
+ # iconList does not include custom, so add it ourselves..
293
+ # only prompt for logo file if custom
294
+ {'code' => 'vdiApp.iconPath', 'fieldName' => 'iconPath', 'fieldLabel' => 'Logo', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
295
+ dropdown = api_client.options.options_for_source("iconList")['data']
296
+ if !dropdown.find {|it| it['value'] == 'custom'}
297
+ dropdown.push({'name' => 'Custom', 'value' => 'custom'})
298
+ end
299
+ dropdown
300
+ }, 'description' => 'Logo icon path or custom if uploading a custom logo', 'defaultValue' => 'resource'},
301
+ {'dependsOnCode' => 'vdiApp.iconPath:custom', 'fieldName' => 'logo', 'fieldLabel' => 'Logo File', 'type' => 'file', 'required' => true, 'description' => 'Local filepath of image file to upload as custom icon'},
302
+ ]
303
+ end
304
+
305
+ def update_vdi_app_option_types
306
+ list = add_vdi_app_option_types.collect {|it|
307
+ it.delete('required')
308
+ it.delete('defaultValue')
309
+ it
310
+ }
311
+ list = list.reject {|it| ["type"].include? it['fieldName'] }
312
+ list
313
+ end
314
+
315
+ # finders are in VdiHelper mixin
316
+
317
+ end