From: František Dvořák Date: Tue, 6 Sep 2016 20:23:48 +0000 (+0200) Subject: Properly compute network mask: X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=cfe175636a76a68e381f2047472a064e45f45b77;p=now.git Properly compute network mask: * ignore SIZE parameter - used only by OpenNebula * consider NETWORK_MASK parameter * default prefix is 24 (IPv4) or 64 (IPv6) --- diff --git a/lib/nebula.rb b/lib/nebula.rb index 3e76c54..a6a5952 100644 --- a/lib/nebula.rb +++ b/lib/nebula.rb @@ -114,44 +114,64 @@ module Now raise NowError.new(code), return_code.message end - def parse_range(vn_id, ar) - id = ar['AR_ID'] + def parse_range(vn_id, vn, ar) + id = ar['AR_ID'] || '(undef)' type = ar['TYPE'] - size = ar['SIZE'] + ip = ar['NETWORK_ADDRESS'] || vn['NETWORK_ADDRESS'] + mask = ar['NETWORK_MASK'] || vn['NETWORK_MASK'] + case type when 'IP4' ip = ar['IP'] - addr_size = 32 if ip.nil? || ip.empty? raise NowError.new(422), "Missing 'IP' in the address range #{id} of network #{vn_id}" end + address = IPAddress ip + if !ip.include? '/' + address.prefix = 24 + end when 'IP6', 'IP4_6' ip = ar['GLOBAL_PREFIX'] || ar['ULA_PREFIX'] - addr_size = 128 if ip.nil? || ip.empty? raise NowError.new(422), "Missing 'GLOBAL_PREFIX' in the address range #{id} of network #{vn_id}" end + address = IPAddress ip + if !ip.include? '/' + address.prefix = 64 + end + when nil + if ip.nil? || ip.empty? + raise NowError.new(422), "No address range and no NETWORK_ADDRESS in the network #{vn_id}" + end + address = IPAddress ip else raise NowError.new(501), "Unknown type '#{type}' in the address range #{id} of network #{vn_id}" end - if size.nil? || size.empty? - raise NowError.new(422), "Missing 'SIZE' in the address range #{id} of network #{vn_id}" + + # get the mask from NETWORK_MASK network parameter, if IP not in CIDR notation already + if !ip.include? '/' + if mask && !mask.empty? + if /\d+\.\d+\.\d+\.\d+/.match(mask) + address.netmask = mask + else + address.prefix = mask.to_i + end + end end - size = size.to_i - mask = addr_size - Math.log(size, 2).ceil - logger.debug "[parse_range] id=#{id}, address=#{ip}/#{mask} (size #{size})" - return Now::Range.new(address: IPAddress.parse("#{ip}/#{mask}"), allocation: 'dynamic') + logger.debug "[parse_range] network id=#{vn_id}, address=#{address.to_string}" + return Now::Range.new(address: address, allocation: 'dynamic') end def parse_ranges(vn_id, vn) - range = nil - vn.each('AR_POOL/AR') do |ar| - if !range.nil? + ar = nil + vn.each('AR_POOL/AR') do |a| + if !ar.nil? raise NowError.new(501), "Multiple address ranges found in network #{vn_id}" end - range = parse_range(vn_id, ar) + ar = a end + range = parse_range(vn_id, vn, ar) return range end diff --git a/spec/nebula/get_spec.rb b/spec/nebula/get_spec.rb index c5e6825..94eb280 100644 --- a/spec/nebula/get_spec.rb +++ b/spec/nebula/get_spec.rb @@ -5,6 +5,8 @@ describe 'network get' do net1 = l('network-example') net6a = l('network-ipv6-global') net6b = l('network-ipv6-local') + net_mask1 = l('network-mask1') + net_mask2 = l('network-mask2') nebula_base = Now::Nebula.new('opennebula' => { 'endpoint' => 'myendpoint' }) context 'example' do @@ -54,8 +56,6 @@ describe 'network get' do expect(network.id).to eq(id) expect(network.title).to eq('vx1') - #FIXME - pending('do not use size for netmask') expect(network.range).to eq(range) end end @@ -76,7 +76,46 @@ describe 'network get' do expect(network.id).to eq(id) expect(network.title).to eq('vx2') - pending('do not use size for netmask') + expect(network.range).to eq(range) + end + end + + context 'mask1' do + let(:client) do + instance_double('client', call: net_mask1) + end + let(:nebula) do + nebula_base.ctx = client + nebula_base + end + let(:id) { 0 } + let(:range) { Now::Range.new(address: IPAddress.parse('192.168.0.4/24'), allocation: 'dynamic') } + + it 'get' do + network = nebula.get(id) + + expect(network.id).to eq(id) + expect(network.title).to eq('example') + expect(network.range).to eq(range) + end + end + + context 'mask2' do + let(:client) do + instance_double('client', call: net_mask2) + end + let(:nebula) do + nebula_base.ctx = client + nebula_base + end + let(:id) { 0 } + let(:range) { Now::Range.new(address: IPAddress.parse('192.168.0.4/24'), allocation: 'dynamic') } + + it 'get' do + network = nebula.get(id) + + expect(network.id).to eq(id) + expect(network.title).to eq('example') expect(network.range).to eq(range) end end diff --git a/spec/nebula/network-mask1.xml b/spec/nebula/network-mask1.xml new file mode 100644 index 0000000..5f83e0d --- /dev/null +++ b/spec/nebula/network-mask1.xml @@ -0,0 +1,54 @@ + + 0 + 0 + 1 + oneadmin + users + example + + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + + + 0 + + + + + + + + 3 + + + + + + + + + + + + 3 + + + + diff --git a/spec/nebula/network-mask2.xml b/spec/nebula/network-mask2.xml new file mode 100644 index 0000000..8c95580 --- /dev/null +++ b/spec/nebula/network-mask2.xml @@ -0,0 +1,53 @@ + + 0 + 0 + 1 + oneadmin + users + example + + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + + + 0 + + + + + + + + 3 + + + + + + + + + + + + 3 + + + +