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.
- checksums.yaml +5 -5
- data/bin/oneflow +30 -9
- data/bin/oneflow-template +4 -5
- data/bin/onehook +2 -2
- data/bin/oneimage +6 -6
- data/bin/onemarketapp +3 -3
- data/bin/onetemplate +3 -3
- data/bin/oneuser +1 -1
- data/bin/onevcenter +15 -6
- data/bin/onevm +11 -69
- data/bin/onevmgroup +3 -3
- data/bin/onevnet +3 -3
- data/bin/onevntemplate +3 -3
- data/bin/onevrouter +3 -3
- data/bin/onezone +20 -0
- data/lib/one_helper/oneacct_helper.rb +5 -1
- data/lib/one_helper/onevcenter_helper.rb +7 -6
- data/lib/one_helper/onevm_helper.rb +92 -31
- data/lib/one_helper/onezone_helper.rb +13 -1
- data/lib/one_helper.rb +109 -123
- data/share/schemas/xsd/host.xsd +21 -1
- data/share/schemas/xsd/monitoring_data.xsd +23 -11
- data/share/schemas/xsd/opennebula_configuration.xsd +1 -0
- data/share/schemas/xsd/showback.xsd +1 -0
- data/share/schemas/xsd/vm.xsd +64 -10
- data/share/schemas/xsd/vm_pool.xsd +3 -26
- data/share/schemas/xsd/vnet.xsd +4 -1
- data/share/schemas/xsd/zone.xsd +1 -0
- data/share/schemas/xsd/zone_pool.xsd +1 -0
- metadata +80 -81
@@ -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 =
|
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.
|
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 = "
|
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 =
|
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.
|
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/
|
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
|
-
|
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 =
|
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
|
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
|
-
|
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']['
|
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/
|
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
|
-
|
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
|
-
|
619
|
-
|
620
|
-
|
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
|
-
|
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
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
hash['element']
|
1259
|
-
end
|
1288
|
+
hash = replace_refs(hash)
|
1289
|
+
|
1290
|
+
hash
|
1260
1291
|
end
|
1261
1292
|
|
1262
|
-
#
|
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
|
1265
|
-
#
|
1266
|
-
# @
|
1267
|
-
#
|
1268
|
-
|
1269
|
-
|
1270
|
-
return unless
|
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
|
-
#
|
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
|
1320
|
-
# @param elements [Array] Path to get
|
1311
|
+
# @param [Hash] XSD definition transfomred in hash
|
1321
1312
|
#
|
1322
|
-
# @return [
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
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
|
-
#
|
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
|
1354
|
-
# @param elements [Array] Path to check
|
1324
|
+
# @param [Hash] XSD definition transfomred in hash
|
1355
1325
|
#
|
1356
|
-
# @return [Boolean]
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
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
|
-
#
|
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
|
1337
|
+
# @param hash [Hash] Resource information in hash format
|
1338
|
+
# @param xsd [Hash] XSD of the resource, transformed into hash
|
1367
1339
|
#
|
1368
|
-
|
1369
|
-
|
1370
|
-
type = yield if block_given?
|
1340
|
+
def check_xsd(hash, xsd)
|
1341
|
+
return unless hash or hash.empty?
|
1371
1342
|
|
1372
|
-
|
1373
|
-
return value unless type
|
1343
|
+
hash.each do |k, v|
|
1374
1344
|
|
1375
|
-
|
1376
|
-
|
1345
|
+
# find the elem definition in xsd array
|
1346
|
+
xsd_elem = xsd.select { |e| e['name'] == k }.first unless xsd.nil?
|
1377
1347
|
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
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
|
data/share/schemas/xsd/host.xsd
CHANGED
@@ -53,7 +53,27 @@
|
|
53
53
|
<xs:element name="PCI_DEVICES">
|
54
54
|
<xs:complexType>
|
55
55
|
<xs:sequence>
|
56
|
-
<xs:element name="PCI"
|
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:
|
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
|
-
|
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
|
-
|
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>
|