opennebula 5.12.12 → 5.13.80.pre

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 +5 -5
  2. data/lib/DriverExecHelper.rb +43 -27
  3. data/lib/OpenNebulaDriver.rb +7 -3
  4. data/lib/VirtualMachineDriver.rb +8 -1
  5. data/lib/cloud/CloudClient.rb +1 -1
  6. data/lib/datacenter.rb +1258 -0
  7. data/lib/datastore.rb +1025 -0
  8. data/lib/distributed_firewall.rb +280 -0
  9. data/lib/file_helper.rb +370 -0
  10. data/lib/host.rb +1517 -0
  11. data/lib/logical_port.rb +50 -0
  12. data/lib/logical_switch.rb +77 -0
  13. data/lib/memoize.rb +74 -0
  14. data/lib/models/role.rb +1126 -0
  15. data/lib/models/service.rb +709 -0
  16. data/lib/models.rb +32 -0
  17. data/lib/network.rb +635 -0
  18. data/lib/nsx_client.rb +144 -0
  19. data/lib/nsx_component.rb +28 -0
  20. data/lib/nsx_constants.rb +149 -0
  21. data/lib/nsx_driver.rb +78 -0
  22. data/lib/nsx_error.rb +77 -0
  23. data/lib/nsx_rule.rb +193 -0
  24. data/lib/nsxt_client.rb +176 -0
  25. data/lib/nsxt_dfw.rb +196 -0
  26. data/lib/nsxt_logical_port.rb +94 -0
  27. data/lib/nsxt_rule.rb +188 -0
  28. data/lib/nsxt_tz.rb +38 -0
  29. data/lib/nsxv_client.rb +176 -0
  30. data/lib/nsxv_dfw.rb +202 -0
  31. data/lib/nsxv_logical_port.rb +107 -0
  32. data/lib/nsxv_rule.rb +172 -0
  33. data/lib/nsxv_tz.rb +41 -0
  34. data/lib/opaque_network.rb +134 -0
  35. data/lib/opennebula/document.rb +7 -28
  36. data/lib/opennebula/document_json.rb +41 -11
  37. data/lib/opennebula/error.rb +3 -0
  38. data/lib/opennebula/flow/grammar.rb +1195 -0
  39. data/lib/opennebula/flow/service_pool.rb +190 -0
  40. data/lib/opennebula/flow/service_template.rb +572 -0
  41. data/lib/opennebula/flow/service_template_ext.rb +84 -0
  42. data/lib/opennebula/flow/service_template_pool.rb +32 -0
  43. data/lib/opennebula/flow/validator.rb +499 -0
  44. data/lib/opennebula/flow.rb +23 -0
  45. data/lib/opennebula/hook.rb +4 -11
  46. data/lib/opennebula/image.rb +16 -13
  47. data/lib/opennebula/lockable_ext.rb +163 -0
  48. data/lib/opennebula/marketplaceapp.rb +8 -118
  49. data/lib/opennebula/marketplaceapp_ext.rb +522 -0
  50. data/lib/opennebula/oneflow_client.rb +3 -2
  51. data/lib/opennebula/pool.rb +3 -2
  52. data/lib/opennebula/template.rb +3 -12
  53. data/lib/opennebula/template_ext.rb +325 -0
  54. data/lib/opennebula/user.rb +25 -1
  55. data/lib/opennebula/virtual_machine.rb +24 -206
  56. data/lib/opennebula/virtual_machine_ext.rb +469 -0
  57. data/lib/opennebula/virtual_machine_pool.rb +0 -4
  58. data/lib/opennebula/virtual_network.rb +3 -9
  59. data/lib/opennebula/virtual_router.rb +3 -11
  60. data/lib/opennebula/vm_group.rb +3 -10
  61. data/lib/opennebula/vntemplate.rb +3 -12
  62. data/lib/opennebula/wait_ext.rb +222 -0
  63. data/lib/opennebula.rb +4 -1
  64. data/lib/rest_client.rb +201 -0
  65. data/lib/scripts_common.rb +180 -0
  66. data/lib/transport_zone.rb +43 -0
  67. data/lib/vcenter_driver.rb +8 -21
  68. data/lib/vcenter_importer.rb +616 -0
  69. data/lib/vi_client.rb +281 -0
  70. data/lib/vi_helper.rb +312 -0
  71. data/lib/virtual_machine.rb +3477 -0
  72. data/lib/virtual_wire.rb +158 -0
  73. data/lib/vm_device.rb +80 -0
  74. data/lib/vm_disk.rb +202 -0
  75. data/lib/vm_folder.rb +69 -0
  76. data/lib/vm_helper.rb +30 -0
  77. data/lib/vm_monitor.rb +303 -0
  78. data/lib/vm_nic.rb +70 -0
  79. data/lib/vm_template.rb +1961 -0
  80. data/lib/vmm_importer.rb +121 -0
  81. metadata +140 -26
@@ -0,0 +1,572 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ require 'parse-cron'
18
+
19
+ module OpenNebula
20
+
21
+ # Service Template
22
+ class ServiceTemplate < DocumentJSON
23
+
24
+ ROLE_SCHEMA = {
25
+ :type => :object,
26
+ :properties => {
27
+ 'name' => {
28
+ :type => :string,
29
+ :required => true,
30
+ :regex => /^\w+$/
31
+ },
32
+ 'cardinality' => {
33
+ :type => :integer,
34
+ :default => 1,
35
+ :minimum => 0
36
+ },
37
+ 'vm_template' => {
38
+ :type => :integer,
39
+ :required => true
40
+ },
41
+ 'vm_template_contents' => {
42
+ :type => :string,
43
+ :required => false
44
+ },
45
+ 'parents' => {
46
+ :type => :array,
47
+ :items => {
48
+ :type => :string
49
+ }
50
+ },
51
+ 'shutdown_action' => {
52
+ :type => :string,
53
+ :enum => %w[
54
+ terminate
55
+ terminate-hard
56
+ shutdown
57
+ shutdown-hard
58
+ ],
59
+ :required => false
60
+ },
61
+ 'min_vms' => {
62
+ :type => :integer,
63
+ :required => false,
64
+ :minimum => 0
65
+ },
66
+ 'max_vms' => {
67
+ :type => :integer,
68
+ :required => false,
69
+ :minimum => 0
70
+ },
71
+ 'cooldown' => {
72
+ :type => :integer,
73
+ :required => false,
74
+ :minimum => 0
75
+ },
76
+ 'elasticity_policies' => {
77
+ :type => :array,
78
+ :items => {
79
+ :type => :object,
80
+ :properties => {
81
+ 'type' => {
82
+ :type => :string,
83
+ :enum => %w[
84
+ CHANGE
85
+ CARDINALITY
86
+ PERCENTAGE_CHANGE
87
+ ],
88
+ :required => true
89
+ },
90
+ 'adjust' => {
91
+ :type => :integer,
92
+ :required => true
93
+ },
94
+ 'min_adjust_step' => {
95
+ :type => :integer,
96
+ :required => false,
97
+ :minimum => 1
98
+ },
99
+ 'period_number' => {
100
+ :type => :integer,
101
+ :required => false,
102
+ :minimum => 0
103
+ },
104
+ 'period' => {
105
+ :type => :integer,
106
+ :required => false,
107
+ :minimum => 0
108
+ },
109
+ 'expression' => {
110
+ :type => :string,
111
+ :required => true
112
+ },
113
+ 'cooldown' => {
114
+ :type => :integer,
115
+ :required => false,
116
+ :minimum => 0
117
+ }
118
+ # 'statistic' => {
119
+ # # SampleCount | Average | Sum | Minimum | Maximum
120
+ # :type => :string
121
+ # }
122
+ }
123
+ }
124
+ },
125
+ 'scheduled_policies' => {
126
+ :type => :array,
127
+ :items => {
128
+ :type => :object,
129
+ :properties => {
130
+ 'type' => {
131
+ :type => :string,
132
+ :enum => %w[
133
+ CHANGE
134
+ CARDINALITY
135
+ PERCENTAGE_CHANGE
136
+ ],
137
+ :required => true
138
+ },
139
+ 'adjust' => {
140
+ :type => :integer,
141
+ :required => true
142
+ },
143
+ 'min_adjust_step' => {
144
+ :type => :integer,
145
+ :required => false,
146
+ :minimum => 1
147
+ },
148
+ 'start_time' => {
149
+ :type => :string,
150
+ :required => false
151
+ },
152
+ 'recurrence' => {
153
+ :type => :string,
154
+ :required => false
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ SCHEMA = {
163
+ :type => :object,
164
+ :properties => {
165
+ 'name' => {
166
+ :type => :string,
167
+ :required => true
168
+ },
169
+ 'deployment' => {
170
+ :type => :string,
171
+ :enum => %w[none straight],
172
+ :default => 'none'
173
+ },
174
+ 'description' => {
175
+ :type => :string,
176
+ :default => ''
177
+ },
178
+ 'shutdown_action' => {
179
+ :type => :string,
180
+ :enum => %w[
181
+ terminate
182
+ terminate-hard
183
+ shutdown
184
+ shutdown-hard
185
+ ],
186
+ :required => false
187
+ },
188
+ 'roles' => {
189
+ :type => :array,
190
+ :items => ROLE_SCHEMA,
191
+ :required => true
192
+ },
193
+ 'custom_attrs' => {
194
+ :type => :object,
195
+ :properties => {},
196
+ :required => false
197
+ },
198
+ 'custom_attrs_values' => {
199
+ :type => :object,
200
+ :properties => {},
201
+ :required => false
202
+ },
203
+ 'ready_status_gate' => {
204
+ :type => :boolean,
205
+ :required => false
206
+ },
207
+ 'automatic_deletion' => {
208
+ :type => :boolean,
209
+ :required => false
210
+ },
211
+ 'networks' => {
212
+ :type => :object,
213
+ :properties => {},
214
+ :required => false
215
+ },
216
+ 'networks_values' => {
217
+ :type => :array,
218
+ :items => {
219
+ :type => :object,
220
+ :properties => {}
221
+ },
222
+ :required => false
223
+ }
224
+ }
225
+ }
226
+
227
+ # List of attributes that can't be changed in update operation
228
+ #
229
+ # registration_time: this is internal info managed by OneFlow server
230
+ IMMUTABLE_ATTRS = %w[
231
+ registration_time
232
+ ]
233
+
234
+ def self.init_default_vn_name_template(vn_name_template)
235
+ # rubocop:disable Style/ClassVars
236
+ @@vn_name_template = vn_name_template
237
+ # rubocop:enable Style/ClassVars
238
+ end
239
+
240
+ DOCUMENT_TYPE = 101
241
+
242
+ def allocate(template_json)
243
+ template = JSON.parse(template_json)
244
+
245
+ ServiceTemplate.validate(template)
246
+
247
+ template['registration_time'] = Integer(Time.now)
248
+
249
+ super(template.to_json, template['name'])
250
+ end
251
+
252
+ # Delete service template
253
+ #
254
+ # @param type [String] Delete type
255
+ # - none: just the service template
256
+ # - all: delete VM templates, images and service template
257
+ # - templates: delete VM templates and service template
258
+ def delete(type = nil)
259
+ case type
260
+ when 'all'
261
+ recursive = true
262
+ when 'templates'
263
+ recursive = false
264
+ end
265
+
266
+ if type && type != 'none'
267
+ rc = vm_template_ids
268
+
269
+ return rc if OpenNebula.is_error?(rc)
270
+
271
+ rc = rc.each do |t_id|
272
+ t = OpenNebula::Template.new_with_id(t_id, @client)
273
+ rc = t.info
274
+
275
+ break rc if OpenNebula.is_error?(rc)
276
+
277
+ rc = t.delete(recursive)
278
+
279
+ break rc if OpenNebula.is_error?(rc)
280
+ end
281
+ end
282
+
283
+ return rc if OpenNebula.is_error?(rc)
284
+
285
+ super()
286
+ end
287
+
288
+ # Retrieves the template
289
+ #
290
+ # @return [String] json template
291
+ def template
292
+ @body.to_json
293
+ end
294
+
295
+ # Replaces the template contents
296
+ #
297
+ # @param template_json [String] New template contents
298
+ # @param append [true, false] True to append new attributes instead of
299
+ # replace the whole template
300
+ #
301
+ # @return [nil, OpenNebula::Error] nil in case of success, Error
302
+ # otherwise
303
+ def update(template_json, append = false)
304
+ rc = info
305
+
306
+ return rc if OpenNebula.is_error?(rc)
307
+
308
+ template = JSON.parse(template_json)
309
+
310
+ IMMUTABLE_ATTRS.each do |attr|
311
+ next if template[attr] == @body[attr]
312
+
313
+ return [false, "service_template/#{attr}"]
314
+ end
315
+
316
+ template = @body.merge(template) if append
317
+
318
+ ServiceTemplate.validate(template)
319
+
320
+ super(template.to_json)
321
+ end
322
+
323
+ # Clone service template and the VM templates asssociated to it
324
+ #
325
+ # @param name [String] New template name
326
+ # @param mode [Symbol] Cloning mode (:all, :templates)
327
+ #
328
+ # @return [Integer] New document ID
329
+ def clone_recursively(name, mode)
330
+ recursive = mode == 'all'
331
+
332
+ # clone the document to get new ID
333
+ new_id = clone(name)
334
+
335
+ return new_id if OpenNebula.is_error?(new_id)
336
+
337
+ doc = OpenNebula::ServiceTemplate.new_with_id(new_id, @client)
338
+ rc = doc.info
339
+
340
+ return rc if OpenNebula.is_error?(rc)
341
+
342
+ body = JSON.parse(doc["TEMPLATE/#{TEMPLATE_TAG}"])
343
+ cloned_templates = {}
344
+
345
+ # iterate over roles to clone templates
346
+ rc = body['roles'].each do |role|
347
+ t_id = role['vm_template']
348
+
349
+ # if the template has already been cloned, just update the value
350
+ if cloned_templates.keys.include?(t_id)
351
+ role['vm_template'] = cloned_templates[t_id]
352
+ next
353
+ end
354
+
355
+ template = OpenNebula::Template.new_with_id(t_id, @client)
356
+ rc = template.info
357
+
358
+ break rc if OpenNebula.is_error?(rc)
359
+
360
+ rc = template.clone("#{template.name}-#{name}", recursive)
361
+
362
+ break rc if OpenNebula.is_error?(rc)
363
+
364
+ # add new ID to the hash
365
+ cloned_templates[t_id] = rc
366
+
367
+ role['vm_template'] = rc
368
+ end
369
+
370
+ # if any error, rollback and delete the left templates
371
+ if OpenNebula.is_error?(rc)
372
+ cloned_templates.each do |_, value|
373
+ template = OpenNebula::Template.new_with_id(value, @client)
374
+
375
+ rc = template.info
376
+
377
+ break rc if OpenNebula.is_error?(rc)
378
+
379
+ rc = template.delete(recursive)
380
+
381
+ break rc if OpenNebula.is_error?(rc)
382
+ end
383
+
384
+ return rc
385
+ end
386
+
387
+ # update the template with the new body
388
+ doc.update(body.to_json)
389
+
390
+ # return the new document ID
391
+ new_id
392
+ end
393
+
394
+ # Replaces the raw template contents
395
+ #
396
+ # @param template [String] New template contents, in the form KEY = VAL
397
+ # @param append [true, false] True to append new attributes instead of
398
+ # replace the whole template
399
+ #
400
+ # @return [nil, OpenNebula::Error] nil in case of success, Error
401
+ # otherwise
402
+ def update_raw(template_raw, append = false)
403
+ super(template_raw, append)
404
+ end
405
+
406
+ def self.validate(template)
407
+ validator = Validator::Validator.new(
408
+ :default_values => true,
409
+ :delete_extra_properties => false,
410
+ :allow_extra_properties => true
411
+ )
412
+
413
+ validator.validate!(template, SCHEMA)
414
+
415
+ validate_values(template)
416
+ end
417
+
418
+ def instantiate(merge_template)
419
+ rc = nil
420
+
421
+ if merge_template.nil?
422
+ instantiate_template = JSON.parse(@body.to_json)
423
+ else
424
+ instantiate_template = JSON.parse(@body.to_json)
425
+ .merge(merge_template)
426
+ end
427
+
428
+ begin
429
+ ServiceTemplate.validate(instantiate_template)
430
+
431
+ xml = OpenNebula::Service.build_xml
432
+ service = OpenNebula::Service.new(xml, @client)
433
+
434
+ rc = service.allocate(instantiate_template.to_json)
435
+ rescue Validator::ParseException, JSON::ParserError => e
436
+ return e
437
+ end
438
+
439
+ return rc if OpenNebula.is_error?(rc)
440
+
441
+ service.info
442
+ service
443
+ end
444
+
445
+ def self.validate_values(template)
446
+ parser = ElasticityGrammarParser.new
447
+
448
+ roles = template['roles']
449
+
450
+ roles.each_with_index do |role, role_index|
451
+ roles[role_index+1..-1].each do |other_role|
452
+ if role['name'] == other_role['name']
453
+ raise Validator::ParseException,
454
+ "Role name '#{role['name']}' is repeated"
455
+ end
456
+ end
457
+
458
+ if !role['min_vms'].nil? &&
459
+ role['min_vms'].to_i > role['cardinality'].to_i
460
+
461
+ raise Validator::ParseException,
462
+ "Role '#{role['name']}' 'cardinality' must be " \
463
+ "greater than or equal to 'min_vms'"
464
+ end
465
+
466
+ if !role['max_vms'].nil? &&
467
+ role['max_vms'].to_i < role['cardinality'].to_i
468
+
469
+ raise Validator::ParseException,
470
+ "Role '#{role['name']}' 'cardinality' must be " \
471
+ "lower than or equal to 'max_vms'"
472
+ end
473
+
474
+ if ((role['elasticity_policies'] &&
475
+ !role['elasticity_policies'].empty?) ||
476
+ (role['scheduled_policies'] &&
477
+ !role['scheduled_policies'].empty?)) &&
478
+ (role['min_vms'].nil? || role['max_vms'].nil?)
479
+ raise Validator::ParseException,
480
+ "Role '#{role['name']}' with " \
481
+ " 'elasticity_policies' or " \
482
+ "'scheduled_policies'must define both 'min_vms'" \
483
+ " and 'max_vms'"
484
+ end
485
+
486
+ if role['elasticity_policies']
487
+ role['elasticity_policies'].each_with_index do |policy,
488
+ index|
489
+ exp = policy['expression']
490
+
491
+ if exp.empty?
492
+ raise Validator::ParseException,
493
+ "Role '#{role['name']}', elasticity policy " \
494
+ "##{index} 'expression' cannot be empty"
495
+ end
496
+
497
+ treetop = parser.parse(exp)
498
+ next unless treetop.nil?
499
+
500
+ raise Validator::ParseException,
501
+ "Role '#{role['name']}', elasticity policy " \
502
+ "##{index} 'expression' parse error: " \
503
+ "#{parser.failure_reason}"
504
+ end
505
+ end
506
+
507
+ next unless role['scheduled_policies']
508
+
509
+ role['scheduled_policies'].each_with_index do |policy, index|
510
+ start_time = policy['start_time']
511
+ recurrence = policy['recurrence']
512
+
513
+ if !start_time.nil?
514
+ if !policy['recurrence'].nil?
515
+ raise Validator::ParseException,
516
+ "Role '#{role['name']}', scheduled policy "\
517
+ "##{index} must define "\
518
+ "'start_time' or 'recurrence', but not both"
519
+ end
520
+
521
+ begin
522
+ next if start_time.match(/^\d+$/)
523
+
524
+ Time.parse(start_time)
525
+ rescue ArgumentError
526
+ raise Validator::ParseException,
527
+ "Role '#{role['name']}', scheduled policy " \
528
+ "##{index} 'start_time' is not a valid " \
529
+ 'Time. Try with YYYY-MM-DD hh:mm:ss or ' \
530
+ '0YYY-MM-DDThh:mm:ssZ'
531
+ end
532
+ elsif !recurrence.nil?
533
+ begin
534
+ cron_parser = CronParser.new(recurrence)
535
+ cron_parser.next
536
+ rescue StandardError
537
+ raise Validator::ParseException,
538
+ "Role '#{role['name']}', scheduled policy " \
539
+ "##{index} 'recurrence' is not a valid " \
540
+ 'cron expression'
541
+ end
542
+ else
543
+ raise Validator::ParseException,
544
+ "Role '#{role['name']}', scheduled policy #" \
545
+ "#{index} needs to define either " \
546
+ "'start_time' or 'recurrence'"
547
+ end
548
+ end
549
+ end
550
+ end
551
+
552
+ # Retreives all associated VM templates IDs
553
+ #
554
+ # @return [Array] VM templates IDs
555
+ def vm_template_ids
556
+ rc = info
557
+
558
+ return rc if OpenNebula.is_error?(rc)
559
+
560
+ ret = []
561
+
562
+ @body['roles'].each do |role|
563
+ t_id = Integer(role['vm_template'])
564
+ ret << t_id unless ret.include?(t_id)
565
+ end
566
+
567
+ ret
568
+ end
569
+
570
+ end
571
+
572
+ end
@@ -0,0 +1,84 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ # Module to decorate ServiceTemplate class with additional helpers not directly
18
+ # exposed through the OpenNebula XMLRPC API. The extensions include
19
+ # - mp_import helper that imports a template into a marketplace
20
+ #
21
+ # rubocop:disable Style/ClassAndModuleChildren
22
+ module OpenNebula::ServiceTemplateExt
23
+
24
+ def self.extend_object(obj)
25
+ if !obj.is_a?(OpenNebula::ServiceTemplate)
26
+ raise StandardError, "Cannot extended #{obj.class} " \
27
+ 'with MarketPlaceAppExt'
28
+ end
29
+
30
+ class << obj
31
+
32
+ ####################################################################
33
+ # Public extended interface
34
+ ####################################################################
35
+ # Imports service template into marketplace
36
+ #
37
+ # @param templates [Hash] Service roles templates information
38
+ # @param market_id [Integer] Marketplace ID to import app
39
+ # @param name [String] Service Template App name
40
+ def mp_import(templates, market_id, name)
41
+ template = ''
42
+ name ||= "#{@body['name']}-#{SecureRandom.hex[0..9]}"
43
+
44
+ template = <<-EOT
45
+ NAME = "#{name}"
46
+ ORIGIN_ID = "-1"
47
+ TYPE = "SERVICE_TEMPLATE"
48
+ APPTEMPLATE64 = "#{Base64.strict_encode64(@body.to_json)}"
49
+ EOT
50
+
51
+ # Add VM template name into roles information
52
+ @body['roles'].each do |role|
53
+ # Find role template into templates to get the name to use
54
+ t = templates.find do |_, v|
55
+ v[:template]['ID'].to_i == role['vm_template']
56
+ end
57
+
58
+ next if t.nil? || t[1].nil? || t[1][:name].nil?
59
+
60
+ app_name = t[1][:name]
61
+
62
+ template << <<-EOT
63
+ ROLE = [ NAME="#{role['name']}", APP="#{app_name}"]
64
+ EOT
65
+
66
+ role.delete('vm_template')
67
+ end
68
+
69
+ xml = MarketPlaceApp.build_xml
70
+ app = MarketPlaceApp.new(xml, @client)
71
+ rc = app.allocate(template, market_id)
72
+
73
+ if OpenNebula.is_error?(rc)
74
+ [-1, rc]
75
+ else
76
+ [0, app.id]
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ end
84
+ # rubocop:enable Style/ClassAndModuleChildren
@@ -0,0 +1,32 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ module OpenNebula
18
+
19
+ # Service Template pool
20
+ class ServiceTemplatePool < DocumentPoolJSON
21
+
22
+ DOCUMENT_TYPE = 101
23
+
24
+ def factory(element_xml)
25
+ s_template = OpenNebula::ServiceTemplate.new(element_xml, @client)
26
+ s_template.load_body
27
+ s_template
28
+ end
29
+
30
+ end
31
+
32
+ end