opennebula-cli 6.0.3 → 6.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -440,21 +440,6 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
440
440
  str_periodic << ', END_TYPE = 0'
441
441
  end
442
442
 
443
- rc = vm.info
444
-
445
- if OpenNebula.is_error?(rc)
446
- puts rc.message
447
- exit(-1)
448
- end
449
-
450
- ids = vm.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID')
451
-
452
- id = 0
453
- if !ids.nil? && !ids.empty?
454
- ids.map! {|e| e.to_i }
455
- id = ids.max + 1
456
- end
457
-
458
443
  sched = options[:schedule]
459
444
 
460
445
  # If the action is set to be executed from VM start to an specific
@@ -464,16 +449,14 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
464
449
  sched = sched.to_i
465
450
  end
466
451
 
467
- tmp_str = vm.user_template_str
468
-
469
- tmp_str << "\nSCHED_ACTION = "
470
- tmp_str << "[ID = #{id}, ACTION = #{action}, "
452
+ tmp_str = "SCHED_ACTION = ["
453
+ tmp_str << "ACTION = #{action}, "
471
454
  tmp_str << "WARNING = #{warning}," if warning
472
455
  tmp_str << "ARGS = \"#{options[:args]}\"," if options[:args]
473
456
  tmp_str << "TIME = #{sched}"
474
457
  tmp_str << str_periodic << ']'
475
458
 
476
- vm.update(tmp_str)
459
+ vm.sched_action_add(tmp_str)
477
460
  end
478
461
  end
479
462
 
@@ -491,7 +474,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
491
474
  exit(-1)
492
475
  end
493
476
 
494
- xpath = "USER_TEMPLATE/SCHED_ACTION[ID=#{action_id}]"
477
+ xpath = "TEMPLATE/SCHED_ACTION[ID=#{action_id}]"
495
478
 
496
479
  unless vm.retrieve_elements(xpath)
497
480
  STDERR.puts "Sched action #{action_id} not found"
@@ -509,12 +492,11 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
509
492
  vm.delete_element(xpath)
510
493
 
511
494
  # Add the modified sched action
512
- tmp_str = vm.user_template_str
513
- tmp_str << "\nSCHED_ACTION = ["
495
+ tmp_str = "\nSCHED_ACTION = ["
514
496
  tmp_str << str.split("\n").join(',')
515
497
  tmp_str << ']'
516
498
 
517
- rc = vm.update(tmp_str)
499
+ rc = vm.sched_action_update(action_id, tmp_str)
518
500
 
519
501
  if OpenNebula.is_error?(rc)
520
502
  STDERR.puts "Error updating: #{rc.message}"
@@ -670,6 +652,78 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
670
652
  YAML.load_file(self.class.table_conf)[:charters]
671
653
  end
672
654
 
655
+ # SSH into a VM
656
+ #
657
+ # @param args [Array] CLI arguments
658
+ # @param options [Hash] CLI parameters
659
+ def ssh(args, options)
660
+ perform_action(args[0], options, 'SSH') do |vm|
661
+ rc = vm.info
662
+
663
+ if OpenNebula.is_error?(rc)
664
+ STDERR.puts rc.message
665
+ exit(-1)
666
+ end
667
+
668
+ if vm.lcm_state_str != 'RUNNING'
669
+ STDERR.puts 'VM is not RUNNING, cannot SSH to it'
670
+ exit(-1)
671
+ end
672
+
673
+ # Get user to login
674
+ username = vm.retrieve_xmlelements('//TEMPLATE/CONTEXT/USERNAME')[0]
675
+
676
+ if !username.nil?
677
+ login = username.text
678
+ elsif !args[1].nil?
679
+ login = args[1]
680
+ else
681
+ login = 'root'
682
+ end
683
+
684
+ # Get CMD to run
685
+ options[:cmd].nil? ? cmd = '' : cmd = options[:cmd]
686
+
687
+ # Get NIC to connect
688
+ if options[:nic_id]
689
+ nic = vm.retrieve_xmlelements(
690
+ "//TEMPLATE/NIC[NIC_ID=\"#{options[:nic_id]}\"]"
691
+ )[0]
692
+ else
693
+ nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[SSH="YES"]')[0]
694
+ end
695
+
696
+ nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[1]')[0] if nic.nil?
697
+
698
+ if nic.nil?
699
+ STDERR.puts 'No NIC found'
700
+ exit(-1)
701
+ end
702
+
703
+ # If there is node port
704
+ if nic['EXTERNAL_PORT_RANGE']
705
+ ip = vm.to_hash['VM']['HISTORY_RECORDS']['HISTORY']
706
+ ip = [ip].flatten[-1]['HOSTNAME']
707
+ port = Integer(nic['EXTERNAL_PORT_RANGE'].split(':')[0]) + 21
708
+ else
709
+ ip = nic['IP']
710
+ port = 22
711
+ end
712
+
713
+ options[:ssh_opts].nil? ? opts = '' : opts = options[:ssh_opts]
714
+
715
+ if opts.empty?
716
+ exec(*%W[ssh #{login}@#{ip} -p #{port} #{cmd}])
717
+ else
718
+ exec('ssh', *opts.split, *%W[#{login}@#{ip} -p #{port} #{cmd}])
719
+ end
720
+ end
721
+
722
+ # rubocop:disable Style/SpecialGlobalVars
723
+ $?.exitstatus
724
+ # rubocop:enable Style/SpecialGlobalVars
725
+ end
726
+
673
727
  private
674
728
 
675
729
  def factory(id = nil)
@@ -1228,7 +1282,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
1228
1282
  format_history(vm)
1229
1283
  end
1230
1284
 
1231
- if vm.has_elements?('/VM/USER_TEMPLATE/SCHED_ACTION')
1285
+ if vm.has_elements?('/VM/TEMPLATE/SCHED_ACTION')
1232
1286
  puts
1233
1287
  CLIHelper.print_header(str_h1 % 'SCHEDULED ACTIONS', false)
1234
1288
 
@@ -1246,7 +1300,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
1246
1300
  end
1247
1301
 
1248
1302
  column :SCHEDULED, '', :adjust => true do |d|
1249
- OpenNebulaHelper.time_to_str(d['TIME'], false) \
1303
+ t2 = d['TIME'].to_i
1304
+ t2 += vm['STIME'].to_i unless d['TIME'] =~ /^[0-9].*/
1305
+
1306
+ OpenNebulaHelper.time_to_str(t2, false) \
1250
1307
  unless d.nil?
1251
1308
  end
1252
1309
 
@@ -1297,7 +1354,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
1297
1354
 
1298
1355
  column :CHARTER, '', :left, :adjust, :size => 15 do |d|
1299
1356
  t1 = Time.now
1300
- t2 = Time.at(vm['STIME'].to_i + d['TIME'].to_i)
1357
+ t2 = d['TIME'].to_i
1358
+ t2 += vm['STIME'].to_i unless d['TIME'] =~ /^[0-9].*/
1359
+
1360
+ t2 = Time.at(t2)
1301
1361
 
1302
1362
  days = ((t2 - t1) / (24 * 3600)).round(2)
1303
1363
  hours = ((t2 - t1) / 3600).round(2)
@@ -1305,7 +1365,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
1305
1365
 
1306
1366
  if days > 1
1307
1367
  show = "In #{days} days"
1308
- elsif days < 1 && hours > 1
1368
+ elsif days <= 1 && hours > 1
1309
1369
  show = "In #{hours} hours"
1310
1370
  elsif minutes > 0
1311
1371
  show = "In #{minutes} minutes"
@@ -1313,18 +1373,19 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
1313
1373
  show = 'Already done'
1314
1374
  end
1315
1375
 
1316
- if (t1 - vm['STIME'].to_i).to_i > d['WARNING'].to_i
1376
+ wrn = d['WARNING']
1377
+ if !wrn.nil? && (t1 - vm['STIME'].to_i).to_i > wrn.to_i
1317
1378
  "#{show} *"
1318
1379
  else
1319
1380
  show
1320
1381
  end
1321
1382
  end
1322
- end.show([vm_hash['VM']['USER_TEMPLATE']['SCHED_ACTION']].flatten,
1383
+ end.show([vm_hash['VM']['TEMPLATE']['SCHED_ACTION']].flatten,
1323
1384
  {})
1324
1385
  end
1325
1386
 
1326
1387
  if !options[:all]
1327
- vm.delete_element('/VM/USER_TEMPLATE/SCHED_ACTION')
1388
+ vm.delete_element('/VM/TEMPLATE/SCHED_ACTION')
1328
1389
  end
1329
1390
 
1330
1391
  if vm.has_elements?('/VM/USER_TEMPLATE')
@@ -499,6 +499,13 @@ class OneZoneHelper < OpenNebulaHelper::OneHelper
499
499
  "onezone.yaml"
500
500
  end
501
501
 
502
+ def self.state_to_str(id)
503
+ id = id.to_i
504
+ state_str = Zone::ZONE_STATES[id]
505
+
506
+ Zone::SHORT_ZONE_STATES[state_str]
507
+ end
508
+
502
509
  def format_pool(options)
503
510
  config_file = self.class.table_conf
504
511
 
@@ -524,7 +531,11 @@ class OneZoneHelper < OpenNebulaHelper::OneHelper
524
531
  helper.get_fed_index(d["TEMPLATE"]['ENDPOINT'])
525
532
  end
526
533
 
527
- default :CURRENT, :ID, :NAME, :ENDPOINT, :FED_INDEX
534
+ column :STAT, 'Zone status', :left, :size => 6 do |d|
535
+ OneZoneHelper.state_to_str(d['STATE'])
536
+ end
537
+
538
+ default :CURRENT, :ID, :NAME, :ENDPOINT, :FED_INDEX, :STAT
528
539
  end
529
540
 
530
541
  table
@@ -591,6 +602,7 @@ class OneZoneHelper < OpenNebulaHelper::OneHelper
591
602
  CLIHelper.print_header(str_h1 % "ZONE #{zone['ID']} INFORMATION")
592
603
  puts str % ["ID", zone.id.to_s]
593
604
  puts str % ["NAME", zone.name]
605
+ puts str % ["STATE",zone.state_str]
594
606
  puts
595
607
 
596
608
  zone_hash=zone.to_hash
data/lib/one_helper.rb CHANGED
@@ -576,6 +576,7 @@ EOT
576
576
  p_r, p_w = IO.pipe
577
577
 
578
578
  Signal.trap('PIPE', 'SIG_IGN')
579
+ Signal.trap('PIPE', 'EXIT')
579
580
 
580
581
  lpid = fork do
581
582
  $stdin.reopen(p_r)
@@ -615,10 +616,9 @@ EOT
615
616
  page = ""
616
617
 
617
618
  if options[:xml]
618
- pool.each {|e|
619
- elements += 1
620
- page << e.to_xml(true) << "\n"
621
- }
619
+ elements += 1
620
+
621
+ page << pool.to_xml(true)
622
622
  else
623
623
  pname = pool.pool_name
624
624
  ename = pool.element_name
@@ -899,6 +899,9 @@ EOT
899
899
 
900
900
 
901
901
  def list_pool(options, top=false, filter_flag=nil)
902
+ # Capture Broken pipe
903
+ Signal.trap('PIPE', 'EXIT')
904
+
902
905
  table = format_pool(options)
903
906
 
904
907
  if options[:describe]
@@ -920,15 +923,11 @@ EOT
920
923
  elsif options[:json]
921
924
  list_pool_format(pool, options, filter_flag) do |pool|
922
925
  hash = check_resource_xsd(pool, pname)
923
- hash[pname] = check_resource_xsd(hash[pname], ename)
924
-
925
926
  puts ::JSON.pretty_generate(hash)
926
927
  end
927
928
  elsif options[:yaml]
928
929
  list_pool_format(pool, options, filter_flag) do |pool|
929
930
  hash = check_resource_xsd(pool, pname)
930
- hash[pname] = check_resource_xsd(hash[pname], ename)
931
-
932
931
  puts hash.to_yaml(:indent => 4)
933
932
  end
934
933
  else
@@ -936,6 +935,9 @@ EOT
936
935
  end
937
936
 
938
937
  return 0
938
+ rescue SystemExit, Interrupt
939
+ # Rescue ctrl + c when paginated
940
+ 0
939
941
  end
940
942
 
941
943
  # Check if a resource defined by attributes is referenced in pool
@@ -1223,11 +1225,41 @@ EOT
1223
1225
 
1224
1226
  return hash unless xsd
1225
1227
 
1226
- hash[ename] = check_xsd(hash[ename], nil, ename, xsd)
1228
+ if xsd.keys.include?('complexType')
1229
+ xsd = xsd['complexType']['sequence']['element']
1230
+ else
1231
+ xsd = xsd['element']
1232
+ end
1233
+
1234
+ xsd = [ xsd ] unless xsd.is_a? Array
1235
+
1236
+ check_xsd(hash[ename], xsd)
1227
1237
 
1228
1238
  hash
1229
1239
  end
1230
1240
 
1241
+
1242
+ # Replaces refs in xsd definition
1243
+ # limited func: only traverse hashes (not arrays), but works well for pools
1244
+ #
1245
+ # @param h [Hash] XSD in hash format
1246
+ #
1247
+ # @return [Object] XSD but where ref were, there inner XSD is loaded
1248
+ def replace_refs(h)
1249
+ return h unless h.is_a? Hash
1250
+
1251
+ if h.keys.include? 'ref'
1252
+ ref_xsd = read_xsd(h['ref'])
1253
+ return ref_xsd unless ref_xsd.nil?
1254
+ return h
1255
+ else
1256
+ h.each do |k,v|
1257
+ h[k] = replace_refs(v)
1258
+ end
1259
+ end
1260
+ end
1261
+
1262
+
1231
1263
  # Read XSD file and parse to XML
1232
1264
  #
1233
1265
  # @param ename [String] Element name to read XSD
@@ -1250,141 +1282,95 @@ EOT
1250
1282
  end
1251
1283
 
1252
1284
  hash = Hash.from_xml(Nokogiri::XML(File.read(file)).to_s)
1285
+
1253
1286
  hash = hash['schema']['element']
1254
1287
 
1255
- if hash.keys.include?('complexType')
1256
- hash['complexType']['sequence']['element']
1257
- else
1258
- hash['element']
1259
- end
1288
+ hash = replace_refs(hash)
1289
+
1290
+ hash
1260
1291
  end
1261
1292
 
1262
- # Check values XSD
1293
+ # Decides if given xsd definiton should be array in xml
1294
+ # Must be hash and contain either 'maxOccurs' => unbounded'
1295
+ # or 'maxOccurs' => >1
1263
1296
  #
1264
- # @param hash [Object] Resource information in hash format
1265
- # @param elements [Array] Keys to check
1266
- # @param ename [String] Element name to take XSD
1267
- # @param xsd [Hash] XSD file content
1268
- # @param parents [Array] Parent keys of current hash
1269
- def check_xsd(hash, elements, ename, xsd, parents = [])
1270
- return unless hash
1271
-
1272
- if (hash.is_a? Hash) && !hash.empty?
1273
- hash.map do |ki, vi|
1274
- vi = [vi].flatten if is_array?(xsd, [ki])
1275
-
1276
- if (vi.is_a? Hash) && !vi.empty?
1277
- parents << ki
1278
-
1279
- vi.map do |kj, vj|
1280
- parents << kj
1281
-
1282
- path = (parents + [ki, kj]).uniq
1283
- vj = [vj].flatten if is_array?(xsd, path)
1284
-
1285
- hash[ki][kj] = check_xsd(vj,
1286
- [ki, kj],
1287
- ename,
1288
- xsd,
1289
- parents)
1290
- end
1291
-
1292
- parents.clear
1293
- elsif vi.is_a? Array
1294
- hash[ki] = check_xsd(vi, [ki], ename, xsd, parents)
1295
- else
1296
- hash[ki] = check_xsd(vi, [ki], ename, xsd, parents)
1297
- end
1298
- end
1299
-
1300
- hash
1301
- elsif hash.is_a? Array
1302
- ret = []
1303
-
1304
- hash.each do |v|
1305
- ret << check_xsd(v, elements, ename, xsd, parents)
1306
- end
1307
-
1308
- ret
1309
- else
1310
- check_type(hash) do
1311
- type = get_xsd_path(xsd, elements)
1312
- type['type'] unless type.nil?
1313
- end
1314
- end
1297
+ # @param e [Hash] XSD definition transfomred in hash
1298
+ #
1299
+ # @return [Boolean]
1300
+ #
1301
+ def is_array?(e)
1302
+ return false if e.nil?
1303
+ return false unless e.is_a? Hash
1304
+ e['maxOccurs'] == 'unbounded' || e['maxOccurs'].to_i > 1
1315
1305
  end
1316
1306
 
1317
- # Get xsd path value
1307
+ # Decides if given xsd definiton is complex type sequence
1308
+ # Must be hash and contain nested hash
1309
+ # ['complexType']['sequence']['element']
1318
1310
  #
1319
- # @param xsd [Hash] XSD information
1320
- # @param elements [Array] Path to get
1311
+ # @param [Hash] XSD definition transfomred in hash
1321
1312
  #
1322
- # @return [Hash] Path information
1323
- def get_xsd_path(xsd, elements)
1324
- return unless elements
1325
-
1326
- element = elements.shift
1327
-
1328
- # Return nil, because is an empty complexType
1329
- return unless element
1330
-
1331
- element = [xsd].flatten.find do |v|
1332
- v['name'] == element || v['ref'] == element
1333
- end
1334
-
1335
- # Return nil, because element was not find in XSD
1336
- return unless element
1337
-
1338
- if element.keys.include?('complexType') && !elements.empty?
1339
- if element['complexType']['all']
1340
- element = element['complexType']['all']['element']
1341
- else
1342
- element = element['complexType']['sequence']['element']
1343
- end
1344
-
1345
- get_xsd_path(element, elements)
1346
- else
1347
- element
1348
- end
1313
+ # @return [Boolean]
1314
+ #
1315
+ def xsd_complex_sequence?(x)
1316
+ x['complexType']['sequence']['element'] rescue return false
1317
+ true
1349
1318
  end
1350
1319
 
1351
- # CHeck if current element is an array
1320
+ # Decides if given xsd definiton is complex type all
1321
+ # Must be hash and contain nested hash
1322
+ # ['complexType']['all']['element']
1352
1323
  #
1353
- # @param xsd [Hash] XSD information
1354
- # @param elements [Array] Path to check
1324
+ # @param [Hash] XSD definition transfomred in hash
1355
1325
  #
1356
- # @return [Boolean] True if it's an array, false otherwise
1357
- def is_array?(xsd, elements)
1358
- max = get_xsd_path(xsd, elements)
1359
- max = max['maxOccurs'] if max
1360
-
1361
- max == 'unbounded' || max.to_i > 1
1326
+ # @return [Boolean]
1327
+ #
1328
+ def xsd_complex_all?(x)
1329
+ x['complexType']['all']['element'] rescue return false
1330
+ true
1362
1331
  end
1363
1332
 
1364
- # Check XSD type for especific value
1333
+ # Recursively traverse the OpenNebula resource (in Hash) and it's XSD
1334
+ # Where array is required in XSD, there encapsulate the entry into [ ]
1335
+ # Typically usefull for single disk, snapshots etc.
1365
1336
  #
1366
- # @param value [Object] Value to check
1337
+ # @param hash [Hash] Resource information in hash format
1338
+ # @param xsd [Hash] XSD of the resource, transformed into hash
1367
1339
  #
1368
- # @return [Object] nil if the type is not correct, value otherwise
1369
- def check_type(value)
1370
- type = yield if block_given?
1340
+ def check_xsd(hash, xsd)
1341
+ return unless hash or hash.empty?
1371
1342
 
1372
- # If there is no type, return current value
1373
- return value unless type
1343
+ hash.each do |k, v|
1374
1344
 
1375
- types = %w[string decimal integer boolean date time]
1376
- type = type.split(':')[1]
1345
+ # find the elem definition in xsd array
1346
+ xsd_elem = xsd.select { |e| e['name'] == k }.first unless xsd.nil?
1377
1347
 
1378
- if types.include?(type)
1379
- # If the current type is different, return string
1380
- # because this value doesn't respect the type
1381
- if (value.is_a? Hash) || (value.is_a? Array)
1382
- ''
1383
- else
1384
- value
1348
+ if xsd_complex_sequence?(xsd_elem) || xsd_complex_all?(xsd_elem)
1349
+
1350
+ # go deeper in xsd, xsd is ehter complex sequence or all
1351
+ begin
1352
+ inner_xsd = xsd_elem['complexType']['sequence']['element']
1353
+ rescue
1354
+ inner_xsd = xsd_elem['complexType']['all']['element']
1355
+ end
1356
+
1357
+ # recursively traverse resource - hash
1358
+ if v.is_a? Hash
1359
+ hash[k] = check_xsd(v, inner_xsd)
1360
+
1361
+ # recursively traverse resource - array
1362
+ elsif v.is_a? Array
1363
+ hash[k] = []
1364
+ v.each do |e|
1365
+ hash[k] << check_xsd(e, inner_xsd)
1366
+ end
1367
+ end
1368
+ end
1369
+
1370
+ # if XSD requires array, do so in resource if missing
1371
+ if is_array?(xsd_elem) && (! v.is_a? Array)
1372
+ hash[k] = [ v ]
1385
1373
  end
1386
- else
1387
- value
1388
1374
  end
1389
1375
  end
1390
1376
  end
@@ -53,7 +53,27 @@
53
53
  <xs:element name="PCI_DEVICES">
54
54
  <xs:complexType>
55
55
  <xs:sequence>
56
- <xs:element name="PCI" type="xs:anyType" minOccurs="0" maxOccurs="unbounded"/>
56
+ <xs:element name="PCI" minOccurs="0" maxOccurs="unbounded">
57
+ <xs:complexType>
58
+ <xs:sequence>
59
+ <xs:element name="ADDRESS" type="xs:string"/>
60
+ <xs:element name="BUS" type="xs:string"/>
61
+ <xs:element name="CLASS" type="xs:string"/>
62
+ <xs:element name="CLASS_NAME" type="xs:string"/>
63
+ <xs:element name="DEVICE" type="xs:string"/>
64
+ <xs:element name="DEVICE_NAME" type="xs:string"/>
65
+ <xs:element name="DOMAIN" type="xs:string"/>
66
+ <xs:element name="FUNCTION" type="xs:string"/>
67
+ <xs:element name="NUMA_NODE" type="xs:string"/>
68
+ <xs:element name="SHORT_ADDRESS" type="xs:string"/>
69
+ <xs:element name="SLOT" type="xs:string"/>
70
+ <xs:element name="TYPE" type="xs:string"/>
71
+ <xs:element name="VENDOR" type="xs:string"/>
72
+ <xs:element name="VENDOR_NAME" type="xs:string"/>
73
+ <xs:element name="VMID" type="xs:integer"/>
74
+ </xs:sequence>
75
+ </xs:complexType>
76
+ </xs:element>
57
77
  </xs:sequence>
58
78
  </xs:complexType>
59
79
  </xs:element>
@@ -6,17 +6,37 @@
6
6
  <xs:sequence>
7
7
  <xs:element name="MONITORING" minOccurs="0" maxOccurs="unbounded">
8
8
  <xs:complexType>
9
- <xs:all>
9
+ <xs:sequence>
10
+ <!-- Percentage of 1 CPU consumed (two fully consumed cpu is 2.0) -->
10
11
  <xs:element name="CPU" type="xs:decimal" minOccurs="0" maxOccurs="1"/>
12
+ <!-- Amount of bytes read from disk-->
11
13
  <xs:element name="DISKRDBYTES" type="xs:integer" minOccurs="0" maxOccurs="1"/>
14
+ <!-- Number of IO read operations -->
12
15
  <xs:element name="DISKRDIOPS" type="xs:integer" minOccurs="0" maxOccurs="1"/>
16
+ <!-- Amount of bytes written to disk -->
13
17
  <xs:element name="DISKWRBYTES" type="xs:integer" minOccurs="0" maxOccurs="1"/>
18
+ <!-- Number of IO write operations -->
14
19
  <xs:element name="DISKWRIOPS" type="xs:integer" minOccurs="0" maxOccurs="1"/>
20
+ <!-- Disk size details -->
21
+ <xs:element name="DISK_SIZE" minOccurs="0" maxOccurs="unbounded">
22
+ <xs:complexType>
23
+ <xs:sequence>
24
+ <xs:element name="ID" type="xs:integer"/>
25
+ <xs:element name="SIZE" type="xs:integer"/>
26
+ </xs:sequence>
27
+ </xs:complexType>
28
+ </xs:element>
29
+ <!-- ID of the VM -->
15
30
  <xs:element name="ID" type="xs:integer" minOccurs="0" maxOccurs="1"/>
31
+ <!-- Consumption in kilobytes -->
16
32
  <xs:element name="MEMORY" type="xs:integer" minOccurs="0" maxOccurs="1"/>
17
- <xs:element name="NETTX" type="xs:integer" minOccurs="0" maxOccurs="1"/>
33
+ <!-- Received bytes from the network -->
18
34
  <xs:element name="NETRX" type="xs:integer" minOccurs="0" maxOccurs="1"/>
35
+ <!-- Sent bytes to the network -->
36
+ <xs:element name="NETTX" type="xs:integer" minOccurs="0" maxOccurs="1"/>
37
+ <!-- Exact time when monitoring info were retieved -->
19
38
  <xs:element name="TIMESTAMP" type="xs:integer" minOccurs="0" maxOccurs="1"/>
39
+ <!-- vCetner information -->
20
40
  <xs:element name="VCENTER_ESX_HOST" type="xs:string" minOccurs="0" maxOccurs="1"/>
21
41
  <xs:element name="VCENTER_GUEST_STATE" type="xs:string" minOccurs="0" maxOccurs="1"/>
22
42
  <xs:element name="VCENTER_RP_NAME" type="xs:string" minOccurs="0" maxOccurs="1"/>
@@ -24,15 +44,7 @@
24
44
  <xs:element name="VCENTER_VMWARETOOLS_VERSION" type="xs:string" minOccurs="0" maxOccurs="1"/>
25
45
  <xs:element name="VCENTER_VMWARETOOLS_VERSION_STATUS" type="xs:string" minOccurs="0" maxOccurs="1"/>
26
46
  <xs:element name="VCENTER_VM_NAME" type="xs:string" minOccurs="0" maxOccurs="1"/>
27
- <xs:element name="DISK_SIZE" minOccurs="0" maxOccurs="unbounded">
28
- <xs:complexType>
29
- <xs:sequence>
30
- <xs:element name="ID" type="xs:integer"/>
31
- <xs:element name="SIZE" type="xs:integer"/>
32
- </xs:sequence>
33
- </xs:complexType>
34
- </xs:element>
35
- </xs:all>
47
+ </xs:sequence>
36
48
  </xs:complexType>
37
49
  </xs:element>
38
50
  </xs:sequence>
@@ -303,6 +303,7 @@
303
303
  </xs:complexType>
304
304
  </xs:element>
305
305
 
306
+ <xs:element name="USER_ENCRYPTED_ATTR" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
306
307
  <xs:element name="USER_RESTRICTED_ATTR" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
307
308
 
308
309
  <xs:element name="VLAN_IDS" minOccurs="0" maxOccurs="1">
@@ -20,6 +20,7 @@
20
20
  <xs:element name="DISK_COST" type="xs:float"/>
21
21
  <xs:element name="TOTAL_COST" type="xs:float"/>
22
22
  <xs:element name="HOURS" type="xs:float"/>
23
+ <xs:element name="RHOURS" type="xs:float" minOccurs="0" maxOccurs="1"/>
23
24
  </xs:sequence>
24
25
  </xs:complexType>
25
26
  </xs:element>