ovfparse 0.0.91 → 0.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/ovfparse/vmpackage.rb +9 -229
- metadata +4 -4
data/lib/ovfparse/vmpackage.rb
CHANGED
@@ -13,13 +13,6 @@ class VmPackage
|
|
13
13
|
|
14
14
|
@type = nil
|
15
15
|
|
16
|
-
UNKNOWN = 0
|
17
|
-
INSTALLED = 1
|
18
|
-
NOT_INSTALLED = 2
|
19
|
-
UNINSTALLED = 3
|
20
|
-
COPYING = 4
|
21
|
-
BOOTING = 5
|
22
|
-
CONFIGURING = 6
|
23
16
|
|
24
17
|
# List of attributes in an OVF product that we will extract / set
|
25
18
|
PRODUCT_ATTRIBUTES = [ {'full_name' => 'ovf:instance', 'node_ref' => 'instance', 'attribute_ref' => 'instance'},
|
@@ -49,7 +42,6 @@ class VmPackage
|
|
49
42
|
|
50
43
|
OVF_NAMESPACE = {'ovf' => 'http://schemas.dmtf.org/ovf/envelope/1'}
|
51
44
|
|
52
|
-
@state = UNKNOWN
|
53
45
|
|
54
46
|
attr_accessor :url, :name, :version, :state, :protocol, :size, :xml
|
55
47
|
|
@@ -172,13 +164,14 @@ class VmPackage
|
|
172
164
|
return xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]['id']
|
173
165
|
end
|
174
166
|
|
175
|
-
|
167
|
+
# note this is not part of the OVF spec. Specific users could overwrite this method to
|
168
|
+
# store/retrieve patch level in the description field, for example.
|
176
169
|
def getVmPatchLevel
|
177
|
-
patchNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection/ovf:Description')[0]
|
178
|
-
return patchNode.nil? ? '' : patchNode.text
|
179
170
|
end
|
180
171
|
|
181
|
-
|
172
|
+
def setVmPatchlevel
|
173
|
+
end
|
174
|
+
|
182
175
|
def getVmAttributes
|
183
176
|
return {
|
184
177
|
'name' => getVmName,
|
@@ -214,99 +207,6 @@ class VmPackage
|
|
214
207
|
return networks
|
215
208
|
end
|
216
209
|
|
217
|
-
# @todo refactor to cops extension module
|
218
|
-
# cpe and cops namespaces are not general purpose
|
219
|
-
def getVmProducts
|
220
|
-
products = Array.new
|
221
|
-
xml.root.add_namespace('cops', 'http://cops.mitre.org/1.1')
|
222
|
-
xml.root.add_namespace('cpe', 'http://cpe.mitre.org/dictionary/2.0')
|
223
|
-
|
224
|
-
xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:ProductSection').each { |productNode|
|
225
|
-
product = Hash.new
|
226
|
-
|
227
|
-
PRODUCT_ATTRIBUTES.each { |attribute_details|
|
228
|
-
product[attribute_details['attribute_ref']] = productNode[attribute_details['node_ref']]
|
229
|
-
}
|
230
|
-
|
231
|
-
PRODUCT_ELEMENTS.each { |element_details|
|
232
|
-
childNode = productNode.xpath(element_details['full_name'])[0]
|
233
|
-
product[element_details['element_ref']] = childNode.nil? ? '' : childNode.content
|
234
|
-
}
|
235
|
-
|
236
|
-
childNode = productNode.xpath('ovf:Icon')[0]
|
237
|
-
begin
|
238
|
-
product['icon'] = childNode.nil? ? '' :
|
239
|
-
(xml.xpath('ovf:Envelope/ovf:References/ovf:File').detect { |file| file['id'] == childNode['fileRef'] })['href']
|
240
|
-
rescue
|
241
|
-
puts "You have an icon reference to a file that doesn't exist in the References section."
|
242
|
-
return ''
|
243
|
-
end
|
244
|
-
|
245
|
-
properties = Array.new
|
246
|
-
productNode.xpath('ovf:Property').each { |propertyNode|
|
247
|
-
property = Hash.new
|
248
|
-
PROPERTY_ATTRIBUTES.each { |attribute_details|
|
249
|
-
property[attribute_details['attribute_ref']] = propertyNode[attribute_details['node_ref']]
|
250
|
-
}
|
251
|
-
|
252
|
-
PROPERTY_ELEMENTS.each { |element_details|
|
253
|
-
childNode = propertyNode.xpath(element_details['full_name'])[0]
|
254
|
-
property[element_details['element_ref']] = childNode.nil? ? '' : childNode.content
|
255
|
-
}
|
256
|
-
|
257
|
-
valueOptionsArray = Array.new
|
258
|
-
|
259
|
-
# @todo refactor to cops extension module
|
260
|
-
node = propertyNode.xpath('cops:ValueOptions')[0]
|
261
|
-
if(!node.nil?)
|
262
|
-
if (!node['selection'].nil?)
|
263
|
-
property['selection'] = node['selection']
|
264
|
-
end
|
265
|
-
node.xpath('cops:Option').each { |valueOption|
|
266
|
-
valueOptionsArray.push(valueOption.content)
|
267
|
-
}
|
268
|
-
end
|
269
|
-
|
270
|
-
default = propertyNode['value']
|
271
|
-
existingDefault = valueOptionsArray.detect { |option| option == default }
|
272
|
-
if (!default.nil? && default != '' && existingDefault.nil?)
|
273
|
-
valueOptionsArray.insert(0, default)
|
274
|
-
end
|
275
|
-
|
276
|
-
property['valueoptions'] = valueOptionsArray.join("\n")
|
277
|
-
|
278
|
-
# @todo refactor to cops extension module
|
279
|
-
actions = Array.new
|
280
|
-
node = propertyNode.xpath('cops:Action')[0]
|
281
|
-
if(!node.nil?)
|
282
|
-
node.xpath('cops:FindReplace').each { |findReplace|
|
283
|
-
actions.push({'action_type' => 'FindReplace', 'path' => findReplace.xpath('cops:Path')[0].content, 'value' => findReplace.xpath('cops:Token')[0].content})
|
284
|
-
}
|
285
|
-
node.xpath('cops:Insert').each { |insert|
|
286
|
-
lineNumberNode = insert.xpath('cops:LineNumber')[0]
|
287
|
-
lineNumber = lineNumberNode.nil? ? '' : lineNumberNode.content
|
288
|
-
actions.push({'action_type' => 'Insert', 'path' => insert.xpath('cops:Path')[0].content, 'value' => lineNumber})
|
289
|
-
}
|
290
|
-
node.xpath('cops:Registry').each { |registry|
|
291
|
-
actions.push({'action_type' => 'Registry', 'path' => registry.xpath('cops:RegistryPath')[0].content, 'value' => ''})
|
292
|
-
}
|
293
|
-
node.xpath('cops:Execute').each { |execute|
|
294
|
-
optionsNode = execute.xpath('cops:Options')[0]
|
295
|
-
options = optionsNode.nil? ? '' : optionsNode.content
|
296
|
-
actions.push({'action_type' => 'Execute', 'path' => execute.xpath('cops:Path')[0].content, 'value' => options})
|
297
|
-
}
|
298
|
-
|
299
|
-
end
|
300
|
-
|
301
|
-
container = [property, actions]
|
302
|
-
properties.push(container)
|
303
|
-
}
|
304
|
-
|
305
|
-
container = [product, properties]
|
306
|
-
products.push(container)
|
307
|
-
}
|
308
|
-
return products
|
309
|
-
end
|
310
210
|
|
311
211
|
def getVmCPUs
|
312
212
|
return getVirtualQuantity(3)
|
@@ -338,13 +238,6 @@ class VmPackage
|
|
338
238
|
xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]['ovf:id'] = newValue.to_s
|
339
239
|
end
|
340
240
|
|
341
|
-
# @todo refactor to cops extension module
|
342
|
-
# currently we're using description field for vmpatchlevel
|
343
|
-
def setVmPatchLevel(newValue)
|
344
|
-
osNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]
|
345
|
-
descNode = osNode.xpath('ovf:Description')[0] || osNode.add_child(xml.create_element('Description', {}))
|
346
|
-
descNode.content = newValue
|
347
|
-
end
|
348
241
|
|
349
242
|
def setVmCPUs(newValue)
|
350
243
|
setVirtualQuantity(3, newValue)
|
@@ -489,119 +382,6 @@ class VmPackage
|
|
489
382
|
}
|
490
383
|
end
|
491
384
|
|
492
|
-
def setVmProducts(products)
|
493
|
-
virtualSystem = xml.xpath('ovf:Envelope/ovf:VirtualSystem')[0]
|
494
|
-
productNodes = virtualSystem.xpath('ovf:ProductSection')
|
495
|
-
|
496
|
-
# @todo refactor to cops extension module, notice the "coat_properties"...
|
497
|
-
# Removing old ones that don't exist anymore, updating ones that do
|
498
|
-
productNodes.each { |productNode|
|
499
|
-
updated_product = products.detect { |product| productNode['class'] == product.product_class }
|
500
|
-
if(updated_product.nil?)
|
501
|
-
productNode.unlink
|
502
|
-
else
|
503
|
-
setAttributes(updated_product, productNode, PRODUCT_ATTRIBUTES)
|
504
|
-
setElements(updated_product, productNode, PRODUCT_ELEMENTS)
|
505
|
-
setProductIcon(updated_product.icon, productNode)
|
506
|
-
setProperties(productNode, updated_product.coat_properties)
|
507
|
-
end
|
508
|
-
}
|
509
|
-
|
510
|
-
# Adding new products
|
511
|
-
products.each { |product|
|
512
|
-
if((productNodes.detect { |node| node['class'] == product.product_class }).nil?)
|
513
|
-
newProductNode = virtualSystem.add_child(xml.create_element('ProductSection', {}))
|
514
|
-
setAttributes(product, newProductNode, PRODUCT_ATTRIBUTES)
|
515
|
-
setElements(product, newProductNode, PRODUCT_ELEMENTS)
|
516
|
-
setProductIcon(product.icon, newProductNode)
|
517
|
-
setProperties(newProductNode, product.coat_properties)
|
518
|
-
end
|
519
|
-
}
|
520
|
-
end
|
521
|
-
|
522
|
-
# @todo refactor to cops extension module, notice the "coat_properties"...
|
523
|
-
def setProperties(product, properties)
|
524
|
-
propertyNodes = product.xpath('ovf:Property')
|
525
|
-
|
526
|
-
propertyNodes.each { |propertyNode|
|
527
|
-
updated_property = properties.detect { |property| propertyNode['key'] == property.key }
|
528
|
-
if(updated_property.nil?)
|
529
|
-
propertyNode.unlink
|
530
|
-
else
|
531
|
-
product.add_child(propertyNode)
|
532
|
-
setAttributes(updated_property, propertyNode, PROPERTY_ATTRIBUTES)
|
533
|
-
setElements(updated_property, propertyNode, PROPERTY_ELEMENTS)
|
534
|
-
setValueOptions(propertyNode, updated_property)
|
535
|
-
propertyNode['ovf:type'] = 'string'
|
536
|
-
setActions(propertyNode, updated_property.coat_actions)
|
537
|
-
end
|
538
|
-
}
|
539
|
-
|
540
|
-
properties.each { |property|
|
541
|
-
if((propertyNodes.detect { |node| node['key'] == property.key }).nil?)
|
542
|
-
newPropertyNode = product.add_child(xml.create_element('Property', {}))
|
543
|
-
setAttributes(property, newPropertyNode, PROPERTY_ATTRIBUTES)
|
544
|
-
setElements(property, newPropertyNode, PROPERTY_ELEMENTS)
|
545
|
-
setValueOptions(newPropertyNode, property)
|
546
|
-
newPropertyNode['ovf:type'] = 'string'
|
547
|
-
setActions(newPropertyNode, property.coat_actions)
|
548
|
-
end
|
549
|
-
}
|
550
|
-
end
|
551
|
-
|
552
|
-
# @todo refactor to cops extension module
|
553
|
-
def setValueOptions(property_node, property)
|
554
|
-
values = property.valueoptions.split("\n")
|
555
|
-
valueOptionsNode = property_node.xpath('cops:ValueOptions')[0]
|
556
|
-
if(values.empty? && !valueOptionsNode.nil?)
|
557
|
-
valueOptionsNode.unlink
|
558
|
-
elsif(!values.empty?)
|
559
|
-
valueOptionsNode = valueOptionsNode.nil? ? property_node.add_child(xml.create_element('ValueOptions', {})) : property_node.add_child(valueOptionsNode)
|
560
|
-
valueOptionsNode.namespace = xml.root.namespace_definitions.detect{ |ns| ns.prefix == 'cops' }
|
561
|
-
valueOptionsNode['cops:selection'] = (property.selection || 'single')
|
562
|
-
valueOptionsNode['ovf:required'] = 'false'
|
563
|
-
valueOptionsNode.children.unlink
|
564
|
-
existingDefault = values.detect { |value| value == property.value }
|
565
|
-
if(property.value != '' && !property.value.nil? && existingValue.nil?)
|
566
|
-
valueOptionsNode.add_child(xml.create_element('Option', property.value))
|
567
|
-
end
|
568
|
-
values.each { |value|
|
569
|
-
valueOptionsNode.add_child(xml.create_element('Option', value))
|
570
|
-
}
|
571
|
-
end
|
572
|
-
end
|
573
|
-
|
574
|
-
# @todo refactor to cops extension module
|
575
|
-
def setActions(property, actions)
|
576
|
-
actionsNode = property.xpath('cops:Action')[0]
|
577
|
-
if(actions.empty? && !actionsNode.nil?)
|
578
|
-
actionsNode.unlink
|
579
|
-
elsif(!actions.empty?)
|
580
|
-
actionsNode = actionsNode.nil? ? property.add_child(xml.create_element('Action', {})) : property.add_child(actionsNode)
|
581
|
-
actionsNode.namespace = xml.root.namespace_definitions.detect{ |ns| ns.prefix == 'cops' }
|
582
|
-
actionsNode['ovf:required'] = 'false'
|
583
|
-
actionsNode.children.unlink
|
584
|
-
actions.each { |action|
|
585
|
-
newActionNode = actionsNode.add_child(xml.create_element(action.action_type, {}))
|
586
|
-
if(action.action_type == 'FindReplace')
|
587
|
-
newActionNode.add_child(xml.create_element('Path', action.path))
|
588
|
-
newActionNode.add_child(xml.create_element('Token', action.value))
|
589
|
-
elsif(action.action_type == 'Insert')
|
590
|
-
newActionNode.add_child(xml.create_element('Path', action.path))
|
591
|
-
if(action.value != '' && !action.value.nil?)
|
592
|
-
newActionNode.add_child(xml.create_element('LineNumber', action.value))
|
593
|
-
end
|
594
|
-
elsif(action.action_type == 'Registry')
|
595
|
-
newActionNode.add_child(xml.create_element('RegistryPath', action.path))
|
596
|
-
elsif(action.action_type == 'Execute')
|
597
|
-
newActionNode.add_child(xml.create_element('Path', action.path))
|
598
|
-
if(action.value != '' && !action.value.nil?)
|
599
|
-
newActionNode.add_child(xml.create_element('Options', action.value))
|
600
|
-
end
|
601
|
-
end
|
602
|
-
}
|
603
|
-
end
|
604
|
-
end
|
605
385
|
|
606
386
|
# @todo any need to make this a general purpose "writer" ?
|
607
387
|
def self.construct_skeleton
|
@@ -646,8 +426,8 @@ class VmPackage
|
|
646
426
|
}
|
647
427
|
}
|
648
428
|
}
|
649
|
-
|
650
|
-
node = Nokogiri::XML::Comment.new(xml.doc, ' skeleton framework constructed by
|
429
|
+
|
430
|
+
node = Nokogiri::XML::Comment.new(xml.doc, ' skeleton framework constructed by OVFparse ')
|
651
431
|
xml.doc.children[0].add_previous_sibling(node)
|
652
432
|
end
|
653
433
|
return builder.to_xml
|
@@ -658,8 +438,8 @@ class VmPackage
|
|
658
438
|
end
|
659
439
|
|
660
440
|
# @todo make this a general purpose signing util
|
661
|
-
def sign
|
662
|
-
node = Nokogiri::XML::Comment.new(xml,
|
441
|
+
def sign(signature)
|
442
|
+
node = Nokogiri::XML::Comment.new(xml, signature)
|
663
443
|
xml.children[0].add_next_sibling(node)
|
664
444
|
end
|
665
445
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ovfparse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 165
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 93
|
10
|
+
version: 0.0.93
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jim Barkley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-13 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|