VXLAN support
This patch is implementing support for VXLAN tunnel type for OVS plugin. Refactored neutron::plugins::ml2::validate_* to functions so they can be used in other manifests in module. Change-Id: Ic51ed794b27069809a151dc365ca108c8300c277
This commit is contained in:
parent
37d1c5b810
commit
766561df83
44
lib/puppet/parser/functions/validate_network_vlan_ranges.rb
Normal file
44
lib/puppet/parser/functions/validate_network_vlan_ranges.rb
Normal file
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# Martin Magr <mmagr@redhat.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced validation for VLAN configuration
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_network_vlan_ranges) do |args|
|
||||
value = args[0]
|
||||
if not value.kind_of?(Array)
|
||||
value = [value]
|
||||
end
|
||||
|
||||
value.each do |range|
|
||||
if m = /^(.+:)?(\d+):(\d+)$/.match(range)
|
||||
first_id = Integer(m[-2])
|
||||
second_id = Integer(m[-1])
|
||||
if (first_id > 4094) || (second_id > 4094)
|
||||
raise Puppet::Error, "vlan id are invalid."
|
||||
end
|
||||
if ((second_id - first_id) < 0 )
|
||||
raise Puppet::Error, "network vlan ranges are invalid."
|
||||
end
|
||||
elsif range
|
||||
raise Puppet::Error, "network vlan ranges are invalid."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
44
lib/puppet/parser/functions/validate_tunnel_id_ranges.rb
Normal file
44
lib/puppet/parser/functions/validate_tunnel_id_ranges.rb
Normal file
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# Martin Magr <mmagr@redhat.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced validation when using GRE
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_tunnel_id_ranges) do |args|
|
||||
value = args[0]
|
||||
if not value.kind_of?(Array)
|
||||
value = [value]
|
||||
end
|
||||
|
||||
value.each do |range|
|
||||
if m = /^(\d+):(\d+)$/.match(range)
|
||||
first_id = Integer(m[1])
|
||||
second_id = Integer(m[2])
|
||||
if ((second_id - first_id) > 1000000)
|
||||
raise Puppet::Error, "tunnel id ranges are to large."
|
||||
end
|
||||
if ((second_id - first_id) < 0 )
|
||||
raise Puppet::Error, "tunnel id ranges are invalid."
|
||||
end
|
||||
elsif range
|
||||
raise Puppet::Error, "tunnel id ranges are invalid."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
47
lib/puppet/parser/functions/validate_vni_ranges.rb
Normal file
47
lib/puppet/parser/functions/validate_vni_ranges.rb
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# Martin Magr <mmagr@redhat.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced validation when using VXLAN
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_vni_ranges) do |args|
|
||||
value = args[0]
|
||||
if not value.kind_of?(Array)
|
||||
value = [value]
|
||||
end
|
||||
|
||||
value.each do |range|
|
||||
if m = /^(\d+):(\d+)$/.match(range)
|
||||
first_id = Integer(m[1])
|
||||
second_id = Integer(m[2])
|
||||
if not (0 <= first_id && first_id <= 16777215)
|
||||
raise Puppet::Error, "vni ranges are invalid."
|
||||
end
|
||||
if not (0 <= second_id && second_id <= 16777215)
|
||||
raise Puppet::Error, "vni ranges are invalid."
|
||||
end
|
||||
if (second_id < first_id)
|
||||
raise Puppet::Error, "vni ranges are invalid."
|
||||
end
|
||||
elsif range
|
||||
raise Puppet::Error, "vni ranges are invalid."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -2,6 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# Martin Magr <mmagr@redhat.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -15,16 +16,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced testing for VLAN configuration
|
||||
# Advanced validation for VXLAN UDP port configuration
|
||||
#
|
||||
|
||||
define neutron::plugins::ml2::validate_network_vlan_ranges {
|
||||
$first_id = regsubst($name,'^(\d+):(\d+)$','\1') + 0
|
||||
$second_id = regsubst($name,'^(\d+):(\d+)$','\2') + 0
|
||||
if ($first_id > 4094) or ($second_id > 4094) {
|
||||
fail('vlan id are invalid.')
|
||||
}
|
||||
if (($second_id - $first_id) < 0 ) {
|
||||
fail('network vlan ranges are invalid.')
|
||||
}
|
||||
}
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_vxlan_udp_port) do |args|
|
||||
value = Integer(args[0])
|
||||
|
||||
# check if port is either default value or one of the private ports
|
||||
# according to http://tools.ietf.org/html/rfc6056
|
||||
if value != 4789 or (49151 >= value and value > 65535)
|
||||
raise Puppet::Error, "vxlan udp port is invalid."
|
||||
end
|
||||
end
|
||||
end
|
@ -15,8 +15,10 @@ class neutron::agents::ovs (
|
||||
$bridge_mappings = [],
|
||||
$integration_bridge = 'br-int',
|
||||
$enable_tunneling = false,
|
||||
$tunnel_types = [],
|
||||
$local_ip = false,
|
||||
$tunnel_bridge = 'br-tun',
|
||||
$vxlan_udp_port = 4789,
|
||||
$polling_interval = 2,
|
||||
$firewall_driver = 'neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver'
|
||||
) {
|
||||
@ -86,6 +88,18 @@ class neutron::agents::ovs (
|
||||
'OVS/tunnel_bridge': value => $tunnel_bridge;
|
||||
'OVS/local_ip': value => $local_ip;
|
||||
}
|
||||
|
||||
if $tunnel_types {
|
||||
neutron_plugin_ovs {
|
||||
'agent/tunnel_types': value => join($tunnel_types, ',');
|
||||
}
|
||||
}
|
||||
if 'vxlan' in $tunnel_types {
|
||||
validate_vxlan_udp_port($vxlan_udp_port)
|
||||
neutron_plugin_ovs {
|
||||
'agent/vxlan_udp_port': value => $vxlan_udp_port;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
neutron_plugin_ovs {
|
||||
'OVS/enable_tunneling': value => false;
|
||||
|
@ -89,7 +89,7 @@ class neutron::plugins::ml2 (
|
||||
$tenant_network_types = ['local', 'flat', 'vlan', 'gre', 'vxlan'],
|
||||
$mechanism_drivers = ['openvswitch', 'linuxbridge'],
|
||||
$flat_networks = ['*'],
|
||||
$network_vlan_ranges = ['10:50'],
|
||||
$network_vlan_ranges = ['physnet1:1000:2999'],
|
||||
$tunnel_id_ranges = ['20:100'],
|
||||
$vxlan_group = '224.0.0.1',
|
||||
$vni_ranges = ['10:100']
|
||||
|
@ -36,7 +36,7 @@ define neutron::plugins::ml2::driver (
|
||||
fail('when gre is part of type_drivers, tunnel_id_ranges should be given.')
|
||||
}
|
||||
|
||||
neutron::plugins::ml2::validate_tunnel_id_ranges { $tunnel_id_ranges:; }
|
||||
validate_tunnel_id_ranges($tunnel_id_ranges)
|
||||
|
||||
neutron_plugin_ml2 {
|
||||
'ml2_type_gre/tunnel_id_ranges': value => join($tunnel_id_ranges, ',');
|
||||
@ -48,7 +48,7 @@ define neutron::plugins::ml2::driver (
|
||||
fail('when vlan is part of type_drivers, network_vlan_ranges should be given.')
|
||||
}
|
||||
|
||||
neutron::plugins::ml2::validate_network_vlan_ranges { $network_vlan_ranges:; }
|
||||
validate_network_vlan_ranges($network_vlan_ranges)
|
||||
|
||||
neutron_plugin_ml2 {
|
||||
'ml2_type_vlan/network_vlan_ranges': value => join($network_vlan_ranges, ',');
|
||||
@ -73,7 +73,7 @@ define neutron::plugins::ml2::driver (
|
||||
}
|
||||
}
|
||||
|
||||
neutron::plugins::ml2::validate_vni_ranges { $vni_ranges: }
|
||||
validate_vni_ranges($vni_ranges)
|
||||
|
||||
neutron_plugin_ml2 {
|
||||
'ml2_type_vxlan/vxlan_group': value => $vxlan_group;
|
||||
|
@ -1,30 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced testing when using GRE
|
||||
#
|
||||
|
||||
define neutron::plugins::ml2::validate_tunnel_id_ranges {
|
||||
$first_id = regsubst($name,'^(\d+):(\d+)$','\1') + 0
|
||||
$second_id = regsubst($name,'^(\d+):(\d+)$','\2') + 0
|
||||
if (($second_id - $first_id) > 1000000) {
|
||||
fail('tunnel id ranges are to large.')
|
||||
}
|
||||
if (($second_id - $first_id) < 0 ) {
|
||||
fail('tunnel id ranges are invalid.')
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Advanced testing when using VXLAN
|
||||
#
|
||||
|
||||
define neutron::plugins::ml2::validate_vni_ranges {
|
||||
if ($name !~ /^(\d+):(\d+)$/) {
|
||||
fail('vni ranges are invalid.')
|
||||
}
|
||||
else {
|
||||
$first_id = regsubst($name,'^(\d+):(\d+)$','\1') + 0
|
||||
$second_id = regsubst($name,'^(\d+):(\d+)$','\2') + 0
|
||||
if ( $first_id > 16777215 ) or ( $second_id > 16777215 )
|
||||
or ( $first_id < 0 ) or ( $second_id < 0 )
|
||||
or ( $second_id < $first_id ) {
|
||||
fail('vni ranges are invalid.')
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,8 @@ class neutron::plugins::ovs (
|
||||
# if type is vlan or flat, a default of physnet1:1000:2000 is used
|
||||
# otherwise this will not be set by default.
|
||||
$network_vlan_ranges = undef,
|
||||
$tunnel_id_ranges = '1:1000'
|
||||
$tunnel_id_ranges = '1:1000',
|
||||
$vxlan_udp_port = 4789
|
||||
) {
|
||||
|
||||
include neutron::params
|
||||
@ -56,31 +57,33 @@ class neutron::plugins::ovs (
|
||||
'OVS/tenant_network_type': value => $tenant_network_type;
|
||||
}
|
||||
|
||||
if($tenant_network_type == 'gre') {
|
||||
if $tenant_network_type in ['gre', 'vxlan'] {
|
||||
validate_tunnel_id_ranges($tunnel_id_ranges)
|
||||
neutron_plugin_ovs {
|
||||
# this is set by the plugin and the agent - since the plugin node has the agent installed
|
||||
# we rely on it setting it.
|
||||
# TODO(ijw): do something with a virtualised node
|
||||
# 'OVS/enable_tunneling': value => 'True';
|
||||
'OVS/tunnel_id_ranges': value => $tunnel_id_ranges;
|
||||
'OVS/tunnel_type': value => $tenant_network_type;
|
||||
}
|
||||
}
|
||||
|
||||
# If the user hasn't specified vlan_ranges, fail for the modes where
|
||||
# it is required, otherwise keep it absent
|
||||
if ($tenant_network_type == 'vlan') or ($tenant_network_type == 'flat') {
|
||||
if ! $network_vlan_ranges {
|
||||
validate_vxlan_udp_port($vxlan_udp_port)
|
||||
neutron_plugin_ovs { 'OVS/vxlan_udp_port': value => $vxlan_udp_port; }
|
||||
|
||||
if ! $network_vlan_ranges {
|
||||
# If the user hasn't specified vlan_ranges, fail for the modes where
|
||||
# it is required, otherwise keep it absent
|
||||
if $tenant_network_type in ['vlan', 'flat'] {
|
||||
fail('When using the vlan network type, network_vlan_ranges is required')
|
||||
}
|
||||
} else {
|
||||
if ! $network_vlan_ranges {
|
||||
} else {
|
||||
neutron_plugin_ovs { 'OVS/network_vlan_ranges': ensure => absent }
|
||||
}
|
||||
}
|
||||
|
||||
# This might be set by the user for the gre case where
|
||||
# provider networks are in use
|
||||
if $network_vlan_ranges {
|
||||
} else {
|
||||
# This might be set by the user for the gre or vxlan case where
|
||||
# provider networks are in use
|
||||
validate_network_vlan_ranges($network_vlan_ranges)
|
||||
neutron_plugin_ovs {
|
||||
'OVS/network_vlan_ranges': value => $network_vlan_ranges
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ describe 'neutron::agents::ovs' do
|
||||
|
||||
let :pre_condition do
|
||||
"class { 'neutron': rabbit_password => 'passw0rd' }\n" +
|
||||
"class { 'neutron::plugins::ovs': network_vlan_ranges => 'test' }"
|
||||
"class { 'neutron::plugins::ovs': network_vlan_ranges => 'physnet1:1000:2000' }"
|
||||
end
|
||||
|
||||
let :default_params do
|
||||
@ -126,6 +126,20 @@ describe 'neutron::agents::ovs' do
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunneling' do
|
||||
before :each do
|
||||
params.merge!(:enable_tunneling => true,
|
||||
:local_ip => '127.0.0.1',
|
||||
:tunnel_types => ['vxlan'],
|
||||
:vxlan_udp_port => '4789')
|
||||
end
|
||||
|
||||
it 'should perform vxlan network configuration' do
|
||||
should contain_neutron_plugin_ovs('agent/tunnel_types').with_value(params[:tunnel_types])
|
||||
should contain_neutron_plugin_ovs('agent/vxlan_udp_port').with_value(params[:vxlan_udp_port])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,7 +24,7 @@ describe 'neutron::plugins::ovs' do
|
||||
|
||||
shared_examples_for 'neutron ovs plugin' do
|
||||
before do
|
||||
params.merge!(default_params)
|
||||
params.merge!(default_params) { |key, v1, v2| v1 }
|
||||
end
|
||||
|
||||
let :params do
|
||||
@ -57,12 +57,13 @@ describe 'neutron::plugins::ovs' do
|
||||
end
|
||||
|
||||
before do
|
||||
params.delete('network_vlan_ranges')
|
||||
params.delete(:network_vlan_ranges)
|
||||
end
|
||||
|
||||
it 'should perform gre network configuration' do
|
||||
should contain_neutron_plugin_ovs('OVS/tenant_network_type').with_value(params[:tenant_network_type])
|
||||
should contain_neutron_plugin_ovs('OVS/tunnel_id_ranges').with_value(params[:tunnel_id_ranges])
|
||||
should contain_neutron_plugin_ovs('OVS/network_vlan_ranges').with_ensure('absent')
|
||||
end
|
||||
end
|
||||
|
||||
@ -80,6 +81,79 @@ describe 'neutron::plugins::ovs' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunneling' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:vxlan_udp_port => '4789'}
|
||||
end
|
||||
|
||||
before do
|
||||
params.delete(:network_vlan_ranges)
|
||||
end
|
||||
|
||||
it 'should perform vxlan network configuration' do
|
||||
should contain_neutron_plugin_ovs('OVS/tenant_network_type').with_value(params[:tenant_network_type])
|
||||
should contain_neutron_plugin_ovs('OVS/vxlan_udp_port').with_value(params[:vxlan_udp_port])
|
||||
should contain_neutron_plugin_ovs('OVS/network_vlan_ranges').with_ensure('absent')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunnelling using bad vxlan_udp_port' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:vxlan_udp_port => '1',}
|
||||
end
|
||||
|
||||
it 'should fail if invalid port is passed' do
|
||||
expect { subject }.to raise_error(Puppet::Error, /vxlan udp port is invalid./)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunnelling using bad tunnel_id_ranges' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:tunnel_id_ranges => '100:9',}
|
||||
end
|
||||
|
||||
it 'should fail if invalid id range is passed' do
|
||||
expect { subject }.to raise_error(Puppet::Error, /tunnel id ranges are invalid./)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunneling and provider networks using bad network_vlan_ranges' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:network_vlan_ranges => 'physnet1:200:1'}
|
||||
end
|
||||
|
||||
it 'should fail if invalid vlan range is passed' do
|
||||
expect { subject }.to raise_error(Puppet::Error, /network vlan ranges are invalid./)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunneling using bad multiple network_vlan_ranges' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:network_vlan_ranges => ['physnet1:0:100', 'physnet2:1000:1']}
|
||||
end
|
||||
|
||||
it 'should fail if invalid network vlan range is passed' do
|
||||
expect { subject }.to raise_error(Puppet::Error, /network vlan ranges are invalid/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vxlan tunneling and provider networks' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'vxlan',
|
||||
:network_vlan_ranges => 'physnet1:1000:2000'}
|
||||
end
|
||||
|
||||
it 'should perform vxlan network configuration' do
|
||||
should contain_neutron_plugin_ovs('OVS/network_vlan_ranges').with_value(params[:network_vlan_ranges])
|
||||
should contain_neutron_plugin_ovs('OVS/tenant_network_type').with_value(params[:tenant_network_type])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a flat network' do
|
||||
let :params do
|
||||
{ :tenant_network_type => 'flat'}
|
||||
@ -106,7 +180,7 @@ describe 'neutron::plugins::ovs' do
|
||||
end
|
||||
|
||||
let :params do
|
||||
{ :network_vlan_ranges => 'test' }
|
||||
{ :network_vlan_ranges => 'physnet1:1000:2000' }
|
||||
end
|
||||
|
||||
let :platform_params do
|
||||
|
Loading…
Reference in New Issue
Block a user