From 564e57930f0a717aa8f6556c426f5144ae6153bf Mon Sep 17 00:00:00 2001 From: Javier Pena Date: Thu, 11 Dec 2014 15:32:31 +0100 Subject: [PATCH] Enable HA, DVR and router relocation in Neutron Enable support to configure HA routers, DVR and automatic router rescheduling in Neutron. Note it requires PR #191 to o-p-m, and probably some other fixes to allow all tests to pass. Change-Id: I40761602715c16531d89da0e700358c16c302ef1 --- manifests/network/controller.pp | 37 ++++++++---- manifests/network/l3.pp | 52 +++++++++++++++-- manifests/network/vswitch.pp | 52 +++++++++-------- spec/classes/cloud_network_controller_spec.rb | 45 +++++++++++++++ spec/classes/cloud_network_l3_spec.rb | 56 ++++++++++++++++++- spec/classes/cloud_network_vswitch_spec.rb | 18 +++++- 6 files changed, 218 insertions(+), 42 deletions(-) diff --git a/manifests/network/controller.pp b/manifests/network/controller.pp index ebfbb161..def77b9d 100644 --- a/manifests/network/controller.pp +++ b/manifests/network/controller.pp @@ -108,6 +108,15 @@ # Supported values: 'ml2', 'n1kv'. # Defaults to 'ml2' # +# [*l3_ha*] +# (optional) Enable L3 agent HA +# Defaults to false. +# +# [*router_distributed*] +# (optional) Create distributed tenant routers by default +# Right now, DVR is not compatible with l3_ha +# Defaults to false +# # [*ks_keystone_admin_port*] # (optional) TCP port to connect to Keystone API from admin network # Defaults to '35357' @@ -160,18 +169,20 @@ class cloud::network::controller( $nova_region_name = 'RegionOne', $manage_ext_network = false, $firewall_settings = {}, - $flat_networks = ['public'], - $tenant_network_types = ['gre'], - $type_drivers = ['gre', 'vlan', 'flat'], - $provider_vlan_ranges = ['physnet1:1000:2999'], - $plugin = 'ml2', + $flat_networks = ['public'], + $tenant_network_types = ['gre'], + $type_drivers = ['gre', 'vlan', 'flat'], + $provider_vlan_ranges = ['physnet1:1000:2999'], + $plugin = 'ml2', + $l3_ha = false, + $router_distributed = false, # only needed by cisco n1kv plugin - $n1kv_vsm_ip = '127.0.0.1', - $n1kv_vsm_password = 'secrete', - $ks_keystone_admin_port = 35357, + $n1kv_vsm_ip = '127.0.0.1', + $n1kv_vsm_password = 'secrete', + $ks_keystone_admin_port = 35357, # only needed by ml2 plugin - $tunnel_id_ranges = ['1:10000'], - $vni_ranges = ['1:10000'], + $tunnel_id_ranges = ['1:10000'], + $vni_ranges = ['1:10000'], ) { include 'cloud::network' @@ -179,6 +190,10 @@ class cloud::network::controller( $encoded_user = uriescape($neutron_db_user) $encoded_password = uriescape($neutron_db_password) + if $l3_ha and $router_distributed { + fail 'l3_ha and router_distributed are mutually exclusive, only one of them can be set to true' + } + class { 'neutron::server': auth_password => $ks_neutron_password, auth_host => $ks_keystone_admin_host, @@ -188,6 +203,8 @@ class cloud::network::controller( mysql_module => '2.2', api_workers => $::processorcount, agent_down_time => '60', + l3_ha => $l3_ha, + router_distributed => $router_distributed, } case $plugin { diff --git a/manifests/network/l3.pp b/manifests/network/l3.pp index 0b7f407e..e59fd646 100644 --- a/manifests/network/l3.pp +++ b/manifests/network/l3.pp @@ -35,16 +35,51 @@ # (optional) Disable TSO on Neutron interfaces # Defaults to true # +# [*ha_enabled*] +# (optional) Enable HA for L3 agent or not. +# Defaults to false +# +# [*ha_vrrp_auth_type*] +# (optional) VRRP authentication type. Can be AH or PASS. +# Defaults to "PASS" +# +# [*ha_vrrp_auth_password*] +# (optional) VRRP authentication password. Required if ha_enabled = true. +# Defaults to undef +# +# [*allow_automatic_l3agent_failover*] +# (optional) Automatically reschedule routers from offline L3 agents to online +# L3 agents. +# Defaults to 'False' +# +# [*agent_mode*] +# (optional) The working mode for the agent. +# 'legacy': default behavior (without DVR) +# 'dvr': enable DVR for an L3 agent running on compute node (DVR in production) +# 'dvr_snat': enable DVR with centralized SNAT support (DVR for single-host, for testing only) +# Right now, DVR is not compatible with ha_enabled +# Defaults to 'legacy' +# class cloud::network::l3( - $external_int = 'eth1', - $ext_provider_net = false, - $debug = true, - $manage_tso = true, + $external_int = 'eth1', + $ext_provider_net = false, + $debug = true, + $manage_tso = true, + $ha_enabled = false, + $ha_vrrp_auth_type = 'PASS', + $ha_vrrp_auth_password = undef, + $allow_automatic_l3agent_failover = false, + $agent_mode = 'legacy', + ) { include 'cloud::network' include 'cloud::network::vswitch' + if $ha_enabled and $agent_mode != 'legacy' { + fail 'ha_enabled requires agent_mode to be set to legacy' + } + if ! $ext_provider_net { vs_bridge{'br-ex': external_ids => 'bridge-id=br-ex', @@ -59,8 +94,13 @@ class cloud::network::l3( } class { 'neutron::agents::l3': - debug => $debug, - external_network_bridge => $external_network_bridge_real + debug => $debug, + external_network_bridge => $external_network_bridge_real, + ha_enabled => $ha_enabled, + ha_vrrp_auth_type => $ha_vrrp_auth_type, + ha_vrrp_auth_password => $ha_vrrp_auth_password, + allow_automatic_l3agent_failover => $allow_automatic_l3agent_failover, + agent_mode => $agent_mode, } class { 'neutron::agents::metering': diff --git a/manifests/network/vswitch.pp b/manifests/network/vswitch.pp index 6e637cfe..10d663d6 100644 --- a/manifests/network/vswitch.pp +++ b/manifests/network/vswitch.pp @@ -46,6 +46,10 @@ # [*provider_bridge_mappings*] # (optional) List of : # +# [*enable_distributed_routing*] +# (optional) Enable support for distributed routing on L2 agent. +# Defaults to false. +# # [*n1kv_vsm_ip*] # (required) N1KV VSM (Virtual Supervisor Module) VM's IP. # Defaults to 127.0.0.1 @@ -136,26 +140,27 @@ # class cloud::network::vswitch( # common - $driver = 'ml2_ovs', - $manage_ext_network = false, - $external_int = 'eth1', - $external_bridge = 'br-pub', - $firewall_settings = {}, + $driver = 'ml2_ovs', + $manage_ext_network = false, + $external_int = 'eth1', + $external_bridge = 'br-pub', + $firewall_settings = {}, # common to ml2 - $tunnel_types = ['gre'], - $tunnel_eth = '127.0.0.1', + $tunnel_types = ['gre'], + $tunnel_eth = '127.0.0.1', # ml2_ovs - $provider_bridge_mappings = ['public:br-pub'], + $provider_bridge_mappings = ['public:br-pub'], + $enable_distributed_routing = false, # n1kv_vem - $n1kv_vsm_ip = '127.0.0.1', - $n1kv_vsm_domain_id = 1000, - $host_mgmt_intf = 'eth1', - $uplink_profile = {}, - $vtep_config = {}, - $node_type = 'compute', - $vteps_in_same_subnet = false, - $n1kv_source = '', - $n1kv_version = 'present', + $n1kv_vsm_ip = '127.0.0.1', + $n1kv_vsm_domain_id = 1000, + $host_mgmt_intf = 'eth1', + $uplink_profile = {}, + $vtep_config = {}, + $node_type = 'compute', + $vteps_in_same_subnet = false, + $n1kv_source = '', + $n1kv_version = 'present', ) { include 'cloud::network' @@ -163,12 +168,13 @@ class cloud::network::vswitch( case $driver { 'ml2_ovs': { class { 'neutron::agents::ml2::ovs': - enable_tunneling => true, - l2_population => true, - polling_interval => '15', - tunnel_types => $tunnel_types, - bridge_mappings => $provider_bridge_mappings, - local_ip => $tunnel_eth + enable_tunneling => true, + l2_population => true, + polling_interval => '15', + tunnel_types => $tunnel_types, + bridge_mappings => $provider_bridge_mappings, + local_ip => $tunnel_eth, + enable_distributed_routing => $enable_distributed_routing } if $::osfamily == 'RedHat' { diff --git a/spec/classes/cloud_network_controller_spec.rb b/spec/classes/cloud_network_controller_spec.rb index 787e3b44..741a319c 100644 --- a/spec/classes/cloud_network_controller_spec.rb +++ b/spec/classes/cloud_network_controller_spec.rb @@ -172,6 +172,51 @@ describe 'cloud::network::controller' do end end + context 'with L3 HA' do + before :each do + params.merge!(:l3_ha => true) + end + it 'should configure L3 HA' do + is_expected.to contain_class('neutron::server').with( + :l3_ha => true + ) + end + end + + context 'without L3 HA' do + it 'should not configure L3 HA' do + is_expected.to contain_class('neutron::server').with( + :l3_ha => false + ) + end + end + + context 'with DVR' do + before :each do + params.merge!(:router_distributed => true) + end + it 'should enable distributed routing' do + is_expected.to contain_class('neutron::server').with( + :router_distributed => true + ) + end + end + + context 'without DVR' do + it 'should not enable distributed routing' do + is_expected.to contain_class('neutron::server').with( + :router_distributed => false + ) + end + end + + context 'with L3 HA and DVR' do + before :each do + params.merge!(:router_distributed => true, + :l3_ha => true) + end + it_raises 'a Puppet::Error', /l3_ha and router_distributed are mutually exclusive, only one of them can be set to true/ + end end context 'on Debian platforms' do diff --git a/spec/classes/cloud_network_l3_spec.rb b/spec/classes/cloud_network_l3_spec.rb index 09047052..01480400 100644 --- a/spec/classes/cloud_network_l3_spec.rb +++ b/spec/classes/cloud_network_l3_spec.rb @@ -35,7 +35,8 @@ describe 'cloud::network::l3' do let :params do { :debug => true, - :external_int => 'eth1' } + :external_int => 'eth1', + :allow_automatic_l3agent_failover => false } end it 'configure neutron common' do @@ -62,7 +63,8 @@ describe 'cloud::network::l3' do it 'configure neutron l3' do is_expected.to contain_class('neutron::agents::l3').with( :debug => true, - :external_network_bridge => 'br-ex' + :external_network_bridge => 'br-ex', + :allow_automatic_l3agent_failover => params[:allow_automatic_l3agent_failover] ) end it 'configure br-ex bridge' do @@ -128,6 +130,56 @@ describe 'cloud::network::l3' do is_expected.not_to contain_exec('start-tso-script') end end + + context 'when configuring L3 HA' do + before :each do + params.merge!(:ha_enabled => true, + :ha_vrrp_auth_type => 'PASS', + :ha_vrrp_auth_password => 'test') + end + it 'should configure L3 HA' do + is_expected.to contain_class('neutron::agents::l3').with( + :ha_enabled => true, + :ha_vrrp_auth_type => 'PASS', + :ha_vrrp_auth_password => 'test' + ) + end + end + + context 'when not configuring L3 HA' do + it 'should not configure L3 HA' do + is_expected.to contain_class('neutron::agents::l3').with( + :ha_enabled => false, + ) + end + end + + context 'when enabling DVR' do + before :each do + params.merge!(:agent_mode => 'dvr') + end + it 'should enable DVR' do + is_expected.to contain_class('neutron::agents::l3').with( + :agent_mode => 'dvr', + ) + end + end + + context 'when not enabling DVR' do + it 'should not enable DVR' do + is_expected.to contain_class('neutron::agents::l3').with( + :agent_mode => 'legacy', + ) + end + end + + context 'with L3 HA and DVR' do + before :each do + params.merge!(:agent_mode => 'dvr', + :ha_enabled => true) + end + it_raises 'a Puppet::Error', /ha_enabled requires agent_mode to be set to legacy/ + end end context 'on Debian platforms' do diff --git a/spec/classes/cloud_network_vswitch_spec.rb b/spec/classes/cloud_network_vswitch_spec.rb index 362d8502..6078ad50 100644 --- a/spec/classes/cloud_network_vswitch_spec.rb +++ b/spec/classes/cloud_network_vswitch_spec.rb @@ -66,7 +66,23 @@ describe 'cloud::network::vswitch' do :enable_tunneling => true, :tunnel_types => ['gre'], :bridge_mappings => ['public:br-pub'], - :local_ip => '10.0.1.1' + :local_ip => '10.0.1.1', + :enable_distributed_routing => false + ) + end + end + + context 'when running ML2 plugin with OVS driver and distributed routing' do + before :each do + params.merge!(:enable_distributed_routing => true) + end + it 'configure neutron vswitch with distributed routing' do + is_expected.to contain_class('neutron::agents::ml2::ovs').with( + :enable_tunneling => true, + :tunnel_types => ['gre'], + :bridge_mappings => ['public:br-pub'], + :local_ip => '10.0.1.1', + :enable_distributed_routing => true ) end end