opennebula-cli 6.0.2 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/oneflow +102 -9
- data/bin/oneflow-template +4 -5
- data/bin/oneimage +2 -2
- data/bin/onemarket +20 -0
- data/bin/onevcenter +15 -6
- data/bin/onevm +9 -66
- data/bin/onezone +20 -0
- data/lib/one_helper/oneacct_helper.rb +5 -1
- data/lib/one_helper/onemarket_helper.rb +12 -1
- data/lib/one_helper/onevcenter_helper.rb +2 -2
- data/lib/one_helper/onevm_helper.rb +98 -36
- data/lib/one_helper/onezone_helper.rb +13 -1
- data/lib/one_helper.rb +117 -129
- data/share/schemas/xsd/api_info.xsd +2 -2
- data/share/schemas/xsd/hook_message_api.xsd +1 -1
- data/share/schemas/xsd/hook_message_state.xsd +1 -1
- data/share/schemas/xsd/host.xsd +21 -1
- data/share/schemas/xsd/marketplace.xsd +1 -0
- data/share/schemas/xsd/monitoring_data.xsd +23 -11
- 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 +2 -1
- metadata +6 -6
@@ -124,7 +124,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
124
124
|
:name => 'weekly',
|
125
125
|
:large => '--weekly days',
|
126
126
|
:description => 'Repeats the schedule action the days of the week ' \
|
127
|
-
'specified, it can be a number between 0
|
127
|
+
'specified, it can be a number between 0 (Sunday) to 6 (Saturday) ' \
|
128
|
+
'separated with commas. ' \
|
128
129
|
'For example: onevm resume 0 --schedule "09/23 14:15" --weekly 0,2,4',
|
129
130
|
:format => String
|
130
131
|
}
|
@@ -133,8 +134,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
133
134
|
:name => 'monthly',
|
134
135
|
:large => '--monthly days',
|
135
136
|
:description => 'Repeats the schedule action the days of the month ' \
|
136
|
-
'specified, it can be a number between
|
137
|
-
'For example: onevm resume 0 --schedule "09/23 14:15" --monthly
|
137
|
+
'specified, it can be a number between 1,31 separated with commas. ' \
|
138
|
+
'For example: onevm resume 0 --schedule "09/23 14:15" --monthly 1,14',
|
138
139
|
:format => String
|
139
140
|
}
|
140
141
|
|
@@ -142,7 +143,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
142
143
|
:name => 'yearly',
|
143
144
|
:large => '--yearly days',
|
144
145
|
:description => 'Repeats the schedule action the days of the year ' \
|
145
|
-
'specified, it can be a number between 0,365 separated with commas.' \
|
146
|
+
'specified, it can be a number between 0,365 separated with commas. ' \
|
146
147
|
'For example: onevm resume 0 --schedule "09/23 14:15" --yearly 30,60',
|
147
148
|
:format => String
|
148
149
|
}
|
@@ -151,7 +152,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
151
152
|
:name => 'hourly',
|
152
153
|
:large => '--hourly hour',
|
153
154
|
:description => 'Repeats the schedule action each hours specified,' \
|
154
|
-
'it can be a number between 0,168 separated with commas.' \
|
155
|
+
'it can be a number between 0,168 separated with commas. ' \
|
155
156
|
'For example: onevm resume 0 --schedule "09/23 14:15" --hourly 1,5',
|
156
157
|
:format => Numeric
|
157
158
|
}
|
@@ -439,21 +440,6 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
439
440
|
str_periodic << ', END_TYPE = 0'
|
440
441
|
end
|
441
442
|
|
442
|
-
rc = vm.info
|
443
|
-
|
444
|
-
if OpenNebula.is_error?(rc)
|
445
|
-
puts rc.message
|
446
|
-
exit(-1)
|
447
|
-
end
|
448
|
-
|
449
|
-
ids = vm.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID')
|
450
|
-
|
451
|
-
id = 0
|
452
|
-
if !ids.nil? && !ids.empty?
|
453
|
-
ids.map! {|e| e.to_i }
|
454
|
-
id = ids.max + 1
|
455
|
-
end
|
456
|
-
|
457
443
|
sched = options[:schedule]
|
458
444
|
|
459
445
|
# If the action is set to be executed from VM start to an specific
|
@@ -463,16 +449,14 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
463
449
|
sched = sched.to_i
|
464
450
|
end
|
465
451
|
|
466
|
-
tmp_str =
|
467
|
-
|
468
|
-
tmp_str << "\nSCHED_ACTION = "
|
469
|
-
tmp_str << "[ID = #{id}, ACTION = #{action}, "
|
452
|
+
tmp_str = "SCHED_ACTION = ["
|
453
|
+
tmp_str << "ACTION = #{action}, "
|
470
454
|
tmp_str << "WARNING = #{warning}," if warning
|
471
455
|
tmp_str << "ARGS = \"#{options[:args]}\"," if options[:args]
|
472
456
|
tmp_str << "TIME = #{sched}"
|
473
457
|
tmp_str << str_periodic << ']'
|
474
458
|
|
475
|
-
vm.
|
459
|
+
vm.sched_action_add(tmp_str)
|
476
460
|
end
|
477
461
|
end
|
478
462
|
|
@@ -490,7 +474,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
490
474
|
exit(-1)
|
491
475
|
end
|
492
476
|
|
493
|
-
xpath = "
|
477
|
+
xpath = "TEMPLATE/SCHED_ACTION[ID=#{action_id}]"
|
494
478
|
|
495
479
|
unless vm.retrieve_elements(xpath)
|
496
480
|
STDERR.puts "Sched action #{action_id} not found"
|
@@ -508,12 +492,11 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
508
492
|
vm.delete_element(xpath)
|
509
493
|
|
510
494
|
# Add the modified sched action
|
511
|
-
tmp_str =
|
512
|
-
tmp_str << "\nSCHED_ACTION = ["
|
495
|
+
tmp_str = "\nSCHED_ACTION = ["
|
513
496
|
tmp_str << str.split("\n").join(',')
|
514
497
|
tmp_str << ']'
|
515
498
|
|
516
|
-
rc = vm.
|
499
|
+
rc = vm.sched_action_update(action_id, tmp_str)
|
517
500
|
|
518
501
|
if OpenNebula.is_error?(rc)
|
519
502
|
STDERR.puts "Error updating: #{rc.message}"
|
@@ -669,6 +652,78 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
669
652
|
YAML.load_file(self.class.table_conf)[:charters]
|
670
653
|
end
|
671
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
|
+
|
672
727
|
private
|
673
728
|
|
674
729
|
def factory(id = nil)
|
@@ -1227,7 +1282,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
1227
1282
|
format_history(vm)
|
1228
1283
|
end
|
1229
1284
|
|
1230
|
-
if vm.has_elements?('/VM/
|
1285
|
+
if vm.has_elements?('/VM/TEMPLATE/SCHED_ACTION')
|
1231
1286
|
puts
|
1232
1287
|
CLIHelper.print_header(str_h1 % 'SCHEDULED ACTIONS', false)
|
1233
1288
|
|
@@ -1245,7 +1300,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
1245
1300
|
end
|
1246
1301
|
|
1247
1302
|
column :SCHEDULED, '', :adjust => true do |d|
|
1248
|
-
|
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) \
|
1249
1307
|
unless d.nil?
|
1250
1308
|
end
|
1251
1309
|
|
@@ -1296,7 +1354,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
1296
1354
|
|
1297
1355
|
column :CHARTER, '', :left, :adjust, :size => 15 do |d|
|
1298
1356
|
t1 = Time.now
|
1299
|
-
t2 =
|
1357
|
+
t2 = d['TIME'].to_i
|
1358
|
+
t2 += vm['STIME'].to_i unless d['TIME'] =~ /^[0-9].*/
|
1359
|
+
|
1360
|
+
t2 = Time.at(t2)
|
1300
1361
|
|
1301
1362
|
days = ((t2 - t1) / (24 * 3600)).round(2)
|
1302
1363
|
hours = ((t2 - t1) / 3600).round(2)
|
@@ -1304,7 +1365,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
1304
1365
|
|
1305
1366
|
if days > 1
|
1306
1367
|
show = "In #{days} days"
|
1307
|
-
elsif days
|
1368
|
+
elsif days <= 1 && hours > 1
|
1308
1369
|
show = "In #{hours} hours"
|
1309
1370
|
elsif minutes > 0
|
1310
1371
|
show = "In #{minutes} minutes"
|
@@ -1312,18 +1373,19 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
1312
1373
|
show = 'Already done'
|
1313
1374
|
end
|
1314
1375
|
|
1315
|
-
|
1376
|
+
wrn = d['WARNING']
|
1377
|
+
if !wrn.nil? && (t1 - vm['STIME'].to_i).to_i > wrn.to_i
|
1316
1378
|
"#{show} *"
|
1317
1379
|
else
|
1318
1380
|
show
|
1319
1381
|
end
|
1320
1382
|
end
|
1321
|
-
end.show([vm_hash['VM']['
|
1383
|
+
end.show([vm_hash['VM']['TEMPLATE']['SCHED_ACTION']].flatten,
|
1322
1384
|
{})
|
1323
1385
|
end
|
1324
1386
|
|
1325
1387
|
if !options[:all]
|
1326
|
-
vm.delete_element('/VM/
|
1388
|
+
vm.delete_element('/VM/TEMPLATE/SCHED_ACTION')
|
1327
1389
|
end
|
1328
1390
|
|
1329
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
|
@@ -1893,8 +1879,10 @@ EOT
|
|
1893
1879
|
if options[:size]
|
1894
1880
|
ar << ', SIZE = ' << options[:size]
|
1895
1881
|
else
|
1896
|
-
|
1897
|
-
|
1882
|
+
unless options[:ip6]
|
1883
|
+
STDERR.puts 'Address range needs to specify size (-s size)'
|
1884
|
+
exit(-1)
|
1885
|
+
end
|
1898
1886
|
end
|
1899
1887
|
|
1900
1888
|
if options[:ip6]
|
@@ -2164,10 +2152,10 @@ EOT
|
|
2164
2152
|
when 'number', 'number-float'
|
2165
2153
|
if type == 'number'
|
2166
2154
|
header += 'Integer: '
|
2167
|
-
exp = INT_EXP
|
2155
|
+
exp = OneTemplateHelper::INT_EXP
|
2168
2156
|
else
|
2169
2157
|
header += 'Float: '
|
2170
|
-
exp = FLOAT_EXP
|
2158
|
+
exp = OneTemplateHelper::FLOAT_EXP
|
2171
2159
|
end
|
2172
2160
|
|
2173
2161
|
begin
|
@@ -2193,13 +2181,13 @@ EOT
|
|
2193
2181
|
end
|
2194
2182
|
|
2195
2183
|
if type == 'range'
|
2196
|
-
exp = INT_EXP
|
2184
|
+
exp = OneTemplateHelper::INT_EXP
|
2197
2185
|
min = min.to_i
|
2198
2186
|
max = max.to_i
|
2199
2187
|
|
2200
2188
|
header += "Integer in the range [#{min}..#{max}]: "
|
2201
2189
|
else
|
2202
|
-
exp = FLOAT_EXP
|
2190
|
+
exp = OneTemplateHelper::FLOAT_EXP
|
2203
2191
|
min = min.to_f
|
2204
2192
|
max = max.to_f
|
2205
2193
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<!-- The information sent to the hook when $API is used in an API Hook
|
2
|
+
<!-- The information sent to the hook when $API is used in an API Hook follow the following schema -->
|
3
3
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://opennebula.org/XMLSchema" elementFormDefault="qualified" targetNamespace="http://opennebula.org/XMLSchema">
|
4
4
|
<xs:element name="CALL_INFO">
|
5
5
|
<xs:complexType>
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<xs:complexType>
|
14
14
|
<xs:sequence>
|
15
15
|
<xs:element name="POSITION" type="xs:integer"/>
|
16
|
-
<xs:element name="TYPE" type="xs:
|
16
|
+
<xs:element name="TYPE" type="xs:string">
|
17
17
|
<xs:simpleType>
|
18
18
|
<xs:restriction base="xs:string">
|
19
19
|
<xs:enumeration value="IN"/>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<xs:sequence>
|
7
7
|
<xs:element name="HOOK_TYPE" type="xs:string" fixed="API"/>
|
8
8
|
<xs:element name="CALL" type="xs:string"/>
|
9
|
-
<!-- CALL_INFO type is defined in
|
9
|
+
<!-- CALL_INFO type is defined in api_info.xsd -->
|
10
10
|
<xs:element ref="CALL_INFO" maxOccurs="unbounded" minOccurs="0"/>
|
11
11
|
</xs:sequence>
|
12
12
|
</xs:complexType>
|
@@ -16,7 +16,7 @@
|
|
16
16
|
<xs:element name="STATE" type="xs:string"/>
|
17
17
|
<xs:element name="LCM_STATE" type="xs:string" maxOccurs="1" minOccurs="0"/>
|
18
18
|
<xs:element name="REMOTE_HOST" type="xs:string" maxOccurs="1" minOccurs="0"/>
|
19
|
-
<!-- The template of the resource (VM or Host) is
|
19
|
+
<!-- The template of the resource (VM or Host) is included here -->
|
20
20
|
<xs:element ref="HOST" maxOccurs="1" minOccurs="0"/>
|
21
21
|
<xs:element ref="VM" maxOccurs="1" minOccurs="0"/>
|
22
22
|
</xs:sequence>
|