opennebula-cli 6.0.2 → 6.2.0
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.
- 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>
|