Skip to content

Commit

Permalink
Add linuxbridge mechanism support for ML2 plugin
Browse files Browse the repository at this point in the history
Add support for the Linux Bridge mechanism. It includes support
for VXLAN tunneling and L2 population.

Change-Id: I0faca3d4603c6eacbbaa61adef7b742b3a262641
  • Loading branch information
mgagne committed Jul 14, 2014
1 parent faff95b commit bddd060
Show file tree
Hide file tree
Showing 4 changed files with 362 additions and 107 deletions.
156 changes: 156 additions & 0 deletions manifests/agents/ml2/linuxbridge.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# == Class: neutron::agents::ml2::linuxbridge
#
# Setups Linuxbridge Neutron agent for ML2 plugin.
#
# === Parameters
#
# [*package_ensure*]
# (optional) Package ensure state.
# Defaults to 'present'.
#
# [*enabled*]
# (required) Whether or not to enable the agent.
# Defaults to true.
#
# [*tunnel_types*]
# (optional) List of types of tunnels to use when utilizing tunnels.
# Supported tunnel types are: vxlan.
# Defaults to an empty list.
#
# [*local_ip*]
# (optional) Local IP address to use for VXLAN endpoints.
# Required when enabling tunneling.
# Defaults to false.
#
# [*vxlan_group*]
# (optional) Multicast group for vxlan interface. If unset, disables VXLAN
# multicast mode. Should be an Multicast IP (v4 or v6) address.
# Default to '224.0.0.1'.
#
# [*vxlan_ttl*]
# (optional) TTL for vxlan interface protocol packets..
# Default to undef.
#
# [*vxlan_tos*]
# (optional) TOS for vxlan interface protocol packets..
# Defaults to undef.
#
# [*polling_interval*]
# (optional) The number of seconds the agent will wait between
# polling for local device changes.
# Defaults to 2.
#
# [*l2_population*]
# (optional) Extension to use alongside ml2 plugin's l2population
# mechanism driver. It enables the plugin to populate VXLAN forwarding table.
# Defaults to false.
#
# [*physical_interface_mappings*]
# (optional) List of <physical_network>:<physical_interface>
# tuples mapping physical network names to agent's node-specific physical
# network interfaces. Defaults to empty list.
#
# [*firewall_driver*]
# (optional) Firewall driver for realizing neutron security group function.
# Defaults to 'neutron.agent.linux.iptables_firewall.IptablesFirewallDriver'.
#
class neutron::agents::ml2::linuxbridge (
$package_ensure = 'present',
$enabled = true,
$tunnel_types = [],
$local_ip = false,
$vxlan_group = '224.0.0.1',
$vxlan_ttl = false,
$vxlan_tos = false,
$polling_interval = 2,
$l2_population = false,
$physical_interface_mappings = [],
$firewall_driver = 'neutron.agent.linux.iptables_firewall.IptablesFirewallDriver'
) {

validate_array($tunnel_types)
validate_array($physical_interface_mappings)

include neutron::params

Package['neutron-plugin-linuxbridge-agent'] -> Neutron_plugin_linuxbridge<||>
Neutron_plugin_linuxbridge<||> ~> Service['neutron-plugin-linuxbridge-agent']

if ('vxlan' in $tunnel_types) {

if ! $local_ip {
fail('The local_ip parameter is required when vxlan tunneling is enabled')
}

if $vxlan_group {
neutron_plugin_linuxbridge { 'vxlan/vxlan_group': value => $vxlan_group }
} else {
neutron_plugin_linuxbridge { 'vxlan/vxlan_group': ensure => absent }
}

if $vxlan_ttl {
neutron_plugin_linuxbridge { 'vxlan/vxlan_ttl': value => $vxlan_ttl }
} else {
neutron_plugin_linuxbridge { 'vxlan/vxlan_ttl': ensure => absent }
}

if $vxlan_tos {
neutron_plugin_linuxbridge { 'vxlan/vxlan_tos': value => $vxlan_tos }
} else {
neutron_plugin_linuxbridge { 'vxlan/vxlan_tos': ensure => absent }
}

neutron_plugin_linuxbridge {
'vxlan/enable_vxlan': value => true;
'vxlan/local_ip': value => $local_ip;
'vxlan/l2_population': value => $l2_population;
}
} else {
neutron_plugin_linuxbridge {
'vxlan/enable_vxlan': value => false;
'vxlan/local_ip': ensure => absent;
'vxlan/vxlan_group': ensure => absent;
'vxlan/l2_population': ensure => absent;
}
}

neutron_plugin_linuxbridge {
'agent/polling_interval': value => $polling_interval;
'linux_bridge/physical_interface_mappings': value => join($physical_interface_mappings, ',');
}

if $firewall_driver {
neutron_plugin_linuxbridge { 'securitygroup/firewall_driver': value => $firewall_driver }
} else {
neutron_plugin_linuxbridge { 'securitygroup/firewall_driver': ensure => absent }
}

if $::neutron::params::linuxbridge_agent_package {
package { 'neutron-plugin-linuxbridge-agent':
ensure => $package_ensure,
name => $::neutron::params::linuxbridge_agent_package,
}
} else {
# Some platforms (RedHat) do not provide a separate
# neutron plugin linuxbridge agent package.
if ! defined(Package['neutron-plugin-linuxbridge-agent']) {
package { 'neutron-plugin-linuxbridge-agent':
ensure => $package_ensure,
name => $::neutron::params::linuxbridge_server_package,
}
}
}

if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}

service { 'neutron-plugin-linuxbridge-agent':
ensure => $service_ensure,
name => $::neutron::params::linuxbridge_agent_service,
enable => $enabled,
require => Class['neutron']
}
}
29 changes: 3 additions & 26 deletions manifests/plugins/ml2.pp
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,15 @@

include neutron::params

Neutron_plugin_ml2<||> ~> Service <| title == 'neutron-server' |>
Neutron_plugin_ml2<||> ~> Service<| title == 'neutron-server' |>

# test mechanism drivers
validate_array($mechanism_drivers)
if ! $mechanism_drivers {
warning('Without networking mechanism driver, ml2 will not communicate with L2 agents')
}

# In RH, the link is used to start Neutron process but in Debian,
# it's used only to manage database synchronization.
# In RH, the link is used to start Neutron process but in Debian, it's used only
# to manage database synchronization.
file {'/etc/neutron/plugin.ini':
ensure => link,
target => '/etc/neutron/plugins/ml2/ml2_conf.ini'
Expand All @@ -138,32 +137,10 @@
vxlan_group => $vxlan_group,
}

# Configure ml2_conf.ini
neutron_plugin_ml2 {
'ml2/type_drivers': value => join($type_drivers, ',');
'ml2/tenant_network_types': value => join($tenant_network_types, ',');
'ml2/mechanism_drivers': value => join($mechanism_drivers, ',');
'securitygroup/enable_security_group': value => $enable_security_group;
}

if ('linuxbridge' in $mechanism_drivers) {
if ($::osfamily == 'RedHat') {
package { 'neutron-plugin-linuxbridge':
ensure => present,
name => $::neutron::params::linuxbridge_server_package,
}
Package['neutron-plugin-linuxbridge'] -> Neutron_plugin_linuxbridge<||>
}
if ('l2population' in $mechanism_drivers) {
neutron_plugin_linuxbridge {
'vxlan/enable_vxlan': value => true;
'vxlan/l2_population': value => true;
}
} else {
neutron_plugin_linuxbridge {
'vxlan/l2_population': value => false;
}
}
}

}
157 changes: 157 additions & 0 deletions spec/classes/neutron_agents_ml2_linuxbridge_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
require 'spec_helper'

describe 'neutron::agents::ml2::linuxbridge' do

let :pre_condition do
"class { 'neutron': rabbit_password => 'passw0rd' }"
end

let :default_params do
{ :package_ensure => 'present',
:enabled => true,
:tunnel_types => [],
:local_ip => false,
:vxlan_group => '224.0.0.1',
:vxlan_ttl => false,
:vxlan_tos => false,
:polling_interval => 2,
:l2_population => false,
:physical_interface_mappings => [],
:firewall_driver => 'neutron.agent.linux.iptables_firewall.IptablesFirewallDriver' }
end

let :params do
{}
end

shared_examples_for 'neutron plugin linuxbridge agent with ml2 plugin' do

context 'with default parameters' do
it { should contain_class('neutron::params') }

it 'configures ml2_conf.ini' do
should contain_neutron_plugin_linuxbridge('agent/polling_interval').with_value(default_params[:polling_interval])
should contain_neutron_plugin_linuxbridge('linux_bridge/physical_interface_mappings').with_value(default_params[:physical_interface_mappings].join(','))
should contain_neutron_plugin_linuxbridge('securitygroup/firewall_driver').with_value(default_params[:firewall_driver])
end

it 'installs neutron linuxbridge agent package' do
if platform_params.has_key?(:linuxbridge_agent_package)
linuxbridge_agent_package = platform_params[:linuxbridge_agent_package]
else
linuxbridge_agent_package = platform_params[:linuxbridge_server_package]
end

should contain_package('neutron-plugin-linuxbridge-agent').with(
:name => linuxbridge_agent_package,
:ensure => default_params[:package_ensure]
)

should contain_package('neutron-plugin-linuxbridge-agent').with_before(/Neutron_plugin_linuxbridge\[.+\]/)
end

it 'configures neutron linuxbridge agent service' do
should contain_service('neutron-plugin-linuxbridge-agent').with(
:name => platform_params[:linuxbridge_agent_service],
:enable => true,
:ensure => 'running',
:require => 'Class[Neutron]'
)
end

it 'does not configre VXLAN tunneling' do
should contain_neutron_plugin_linuxbridge('vxlan/enable_vxlan').with_value(false)
should contain_neutron_plugin_linuxbridge('vxlan/local_ip').with_ensure('absent')
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_group').with_ensure('absent')
should contain_neutron_plugin_linuxbridge('vxlan/l2_population').with_ensure('absent')
end
end

context 'with VXLAN tunneling enabled' do
before do
params.merge!({
:tunnel_types => ['vxlan'],
:local_ip => '192.168.0.10'
})
end

context 'when providing all parameters' do
it 'configures ml2_conf.ini' do
should contain_neutron_plugin_linuxbridge('vxlan/enable_vxlan').with_value(true)
should contain_neutron_plugin_linuxbridge('vxlan/local_ip').with_value(params[:local_ip])
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_group').with_value(default_params[:vxlan_group])
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_ttl').with_ensure('absent')
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_tos').with_ensure('absent')
should contain_neutron_plugin_linuxbridge('vxlan/l2_population').with_value(default_params[:l2_population])
end
end

context 'when not providing or overriding some parameters' do
before do
params.merge!({
:vxlan_group => '224.0.0.2',
:vxlan_ttl => 10,
:vxlan_tos => 2,
:l2_population => true,
})
end

it 'configures ml2_conf.ini' do
should contain_neutron_plugin_linuxbridge('vxlan/enable_vxlan').with_value(true)
should contain_neutron_plugin_linuxbridge('vxlan/local_ip').with_value(params[:local_ip])
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_group').with_value(params[:vxlan_group])
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_ttl').with_value(params[:vxlan_ttl])
should contain_neutron_plugin_linuxbridge('vxlan/vxlan_tos').with_value(params[:vxlan_tos])
should contain_neutron_plugin_linuxbridge('vxlan/l2_population').with_value(params[:l2_population])
end
end
end

context 'when providing the physical_interface_mappings parameter' do
before do
params.merge!(:physical_interface_mappings => ['physnet0:eth0', 'physnet1:eth1'])
end

it 'configures physical interface mappings' do
should contain_neutron_plugin_linuxbridge('linux_bridge/physical_interface_mappings').with_value(
params[:physical_interface_mappings].join(',')
)
end
end

context 'with firewall_driver parameter set to false' do
before :each do
params.merge!(:firewall_driver => false)
end
it 'removes firewall driver configuration' do
should contain_neutron_plugin_linuxbridge('securitygroup/firewall_driver').with_ensure('absent')
end
end
end

context 'on Debian platforms' do
let :facts do
{ :osfamily => 'Debian' }
end

let :platform_params do
{ :linuxbridge_agent_package => 'neutron-plugin-linuxbridge-agent',
:linuxbridge_agent_service => 'neutron-plugin-linuxbridge-agent' }
end

it_configures 'neutron plugin linuxbridge agent with ml2 plugin'
end

context 'on RedHat platforms' do
let :facts do
{ :osfamily => 'RedHat' }
end

let :platform_params do
{ :linuxbridge_server_package => 'openstack-neutron-linuxbridge',
:linuxbridge_agent_service => 'neutron-linuxbridge-agent' }
end

it_configures 'neutron plugin linuxbridge agent with ml2 plugin'
end
end
Loading

0 comments on commit bddd060

Please sign in to comment.