Added availability zone hints

Neutron in mitaka supports availability zone hints. Support
has been added by providing a means to update neutron server,
l3 agent, and dhcp agent for this feature. The neutron_network
and neutron_router provider has been updated to support
availability zone hints.

Change-Id: I99c6c36d7354aec5176589a95e8e7f0ea1dfede7
Closes-Bug: 1569686
This commit is contained in:
Matthew Black 2016-04-26 22:01:06 -04:00 committed by Matthew J Black
parent 56d2a46738
commit b88984e055
12 changed files with 168 additions and 10 deletions

View File

@ -41,7 +41,8 @@ Puppet::Type.type(:neutron_network).provide(
:provider_segmentation_id => attrs['provider:segmentation_id'], :provider_segmentation_id => attrs['provider:segmentation_id'],
:router_external => attrs['router:external'], :router_external => attrs['router:external'],
:shared => attrs['shared'], :shared => attrs['shared'],
:tenant_id => attrs['tenant_id'] :tenant_id => attrs['tenant_id'],
:availability_zone_hint => attrs['availability_zone_hint']
) )
end end
self.do_not_manage = false self.do_not_manage = false
@ -99,6 +100,11 @@ Puppet::Type.type(:neutron_network).provide(
network_opts << '--router:external' network_opts << '--router:external'
end end
if @resource[:availability_zone_hint]
network_opts << \
"--availability-zone-hint=#{@resource[:availability_zone_hint]}"
end
results = auth_neutron('net-create', '--format=shell', results = auth_neutron('net-create', '--format=shell',
network_opts, resource[:name]) network_opts, resource[:name])
@ -114,6 +120,7 @@ Puppet::Type.type(:neutron_network).provide(
:router_external => attrs['router:external'], :router_external => attrs['router:external'],
:shared => attrs['shared'], :shared => attrs['shared'],
:tenant_id => attrs['tenant_id'], :tenant_id => attrs['tenant_id'],
:availability_zone_hint => attrs['availability_zone_hint']
} }
end end
@ -150,6 +157,13 @@ Puppet::Type.type(:neutron_network).provide(
end end
end end
def availability_zone_hint=(value)
if self.class.do_not_manage
fail("Not managing Neutron_network[#{@resource[:name]}] due to earlier Neutron API failures.")
end
auth_neutron('net-update', "--availability-zone-hint=#{value}", name)
end
[ [
:provider_network_type, :provider_network_type,
:provider_physical_network, :provider_physical_network,

View File

@ -36,7 +36,8 @@ Puppet::Type.type(:neutron_router).provide(
:status => attrs['status'], :status => attrs['status'],
:distributed => attrs['distributed'], :distributed => attrs['distributed'],
:ha => attrs['ha'], :ha => attrs['ha'],
:tenant_id => attrs['tenant_id'] :tenant_id => attrs['tenant_id'],
:availability_zone_hint => attrs['availability_zone_hint']
) )
end end
self.do_not_manage = false self.do_not_manage = false
@ -83,6 +84,10 @@ Puppet::Type.type(:neutron_router).provide(
opts << "--ha=#{@resource[:ha]}" opts << "--ha=#{@resource[:ha]}"
end end
if @resource[:availability_zone_hint]
opts << "--availability-zone-hint=#{@resource[:availability_zone_hint]}"
end
results = auth_neutron("router-create", '--format=shell', results = auth_neutron("router-create", '--format=shell',
opts, resource[:name]) opts, resource[:name])
@ -95,6 +100,7 @@ Puppet::Type.type(:neutron_router).provide(
:external_gateway_info => attrs['external_gateway_info'], :external_gateway_info => attrs['external_gateway_info'],
:status => attrs['status'], :status => attrs['status'],
:tenant_id => attrs['tenant_id'], :tenant_id => attrs['tenant_id'],
:availability_zone_hint => attrs['availability_zone_hint']
} }
if @resource[:gateway_network_name] if @resource[:gateway_network_name]
@ -188,4 +194,16 @@ Puppet::Type.type(:neutron_router).provide(
end end
end end
def availability_zone_hint=(value)
if self.class.do_not_manage
fail("Not managing Neutron_router[#{@resource[:name]}] due to earlier Neutron API failures.")
end
results = auth_neutron("router-show", '--format=shell', resource[:name])
attrs = self.class.parse_creation_output(results)
set_admin_state_up(false)
auth_neutron('router-update', "--availability-zone-hint=#{value}", name)
if attrs['admin_state_up'] == 'True'
set_admin_state_up(true)
end
end
end end

View File

@ -69,6 +69,10 @@ Puppet::Type.newtype(:neutron_network) do
end end
end end
newproperty(:availability_zone_hint) do
desc 'The availability zone hint to provide the scheduler'
end
# Require the neutron-server service to be running # Require the neutron-server service to be running
autorequire(:service) do autorequire(:service) do
['neutron-server'] ['neutron-server']

View File

@ -92,6 +92,10 @@ Puppet::Type.newtype(:neutron_router) do
end end
end end
newproperty(:availability_zone_hint) do
desc 'The availability zone hint to provide the scheduler'
end
validate do validate do
if self[:ensure] != :present if self[:ensure] != :present
return return

View File

@ -69,6 +69,11 @@
# in the dhcp config. # in the dhcp config.
# Defaults to false. # Defaults to false.
# #
# [*availability_zone*]
# (optional) The availability zone of the agent.
# Neutron will only schedule dhcp on the agent based on availability zone
# Defaults to $::os_service_default
#
# === Deprecated Parameters # === Deprecated Parameters
# #
# [*dhcp_domain*] # [*dhcp_domain*]
@ -92,6 +97,7 @@ class neutron::agents::dhcp (
$enable_metadata_network = false, $enable_metadata_network = false,
$dhcp_broadcast_reply = $::os_service_default, $dhcp_broadcast_reply = $::os_service_default,
$purge_config = false, $purge_config = false,
$availability_zone = $::os_service_default,
# DEPRECATED PARAMETERS # DEPRECATED PARAMETERS
$dhcp_domain = $::os_service_default, $dhcp_domain = $::os_service_default,
) { ) {
@ -142,6 +148,7 @@ class neutron::agents::dhcp (
'DEFAULT/dhcp_broadcast_reply': value => $dhcp_broadcast_reply; 'DEFAULT/dhcp_broadcast_reply': value => $dhcp_broadcast_reply;
'DEFAULT/dnsmasq_config_file': value => $dnsmasq_config_file; 'DEFAULT/dnsmasq_config_file': value => $dnsmasq_config_file;
'DEFAULT/dnsmasq_dns_servers': value => join(any2array($dnsmasq_dns_servers), ','); 'DEFAULT/dnsmasq_dns_servers': value => join(any2array($dnsmasq_dns_servers), ',');
'AGENT/availability_zone': value => $availability_zone;
} }
if ! is_service_default ($dhcp_domain) { if ! is_service_default ($dhcp_domain) {

View File

@ -83,6 +83,11 @@
# in the l3 config. # in the l3 config.
# Defaults to false. # Defaults to false.
# #
# [*availability_zone*]
# (optional) The availability zone of the agent.
# Neutron will only schedule routers on the agent based on availability zone
# Defaults to $::os_service_default
#
# === Deprecated Parameters # === Deprecated Parameters
# #
# [*external_network_bridge*] # [*external_network_bridge*]
@ -112,6 +117,7 @@ class neutron::agents::l3 (
$ha_vrrp_advert_int = '3', $ha_vrrp_advert_int = '3',
$agent_mode = 'legacy', $agent_mode = 'legacy',
$purge_config = false, $purge_config = false,
$availability_zone = $::os_service_default,
# DEPRECATED PARAMETERS # DEPRECATED PARAMETERS
$external_network_bridge = $::os_service_default, $external_network_bridge = $::os_service_default,
$router_id = $::os_service_default, $router_id = $::os_service_default,
@ -152,6 +158,7 @@ class neutron::agents::l3 (
'DEFAULT/periodic_fuzzy_delay': value => $periodic_fuzzy_delay; 'DEFAULT/periodic_fuzzy_delay': value => $periodic_fuzzy_delay;
'DEFAULT/enable_metadata_proxy': value => $enable_metadata_proxy; 'DEFAULT/enable_metadata_proxy': value => $enable_metadata_proxy;
'DEFAULT/agent_mode': value => $agent_mode; 'DEFAULT/agent_mode': value => $agent_mode;
'AGENT/availability_zone': value => $availability_zone;
} }
if $::neutron::params::l3_agent_package { if $::neutron::params::l3_agent_package {

View File

@ -154,10 +154,22 @@
# [*lock_path*] # [*lock_path*]
# (optional) Deprecated. Use lock_path parameter on base neutron class instead. # (optional) Deprecated. Use lock_path parameter on base neutron class instead.
# #
# [*network_scheduler_driver*]
# (optional) The scheduler used when scheduling networks
# neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler to use availability zone hints scheduling.
# Defaults to $::os_service_default
#
# Example:
#
# class { 'neutron':
# network_scheduler_driver => 'neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler'
# }
#
# [*router_scheduler_driver*] # [*router_scheduler_driver*]
# (optional) Driver to use for scheduling router to a default L3 agent. Could be: # (optional) Driver to use for scheduling router to a default L3 agent. Could be:
# neutron.scheduler.l3_agent_scheduler.ChanceScheduler to schedule a router in a random way # neutron.scheduler.l3_agent_scheduler.ChanceScheduler to schedule a router in a random way
# neutron.scheduler.l3_agent_scheduler.LeastRoutersScheduler to allocate on an L3 agent with the least number of routers bound. # neutron.scheduler.l3_agent_scheduler.LeastRoutersScheduler to allocate on an L3 agent with the least number of routers bound.
# neutron.scheduler.l3_agent_scheduler.AZLeastRoutersScheduler to use availability zone hints.
# Defaults to: neutron.scheduler.l3_agent_scheduler.ChanceScheduler # Defaults to: neutron.scheduler.l3_agent_scheduler.ChanceScheduler
# #
# [*router_distributed*] # [*router_distributed*]
@ -166,6 +178,28 @@
# Also can be the type of the router on the create request (admin-only attribute). # Also can be the type of the router on the create request (admin-only attribute).
# Defaults to $::os_service_default # Defaults to $::os_service_default
# #
# [*dhcp_load_type*]
# (optional) The resource type whos load is being reported by the agent.
# The expected values are either 'networks', 'subnets', 'ports'.
# Defaults to $::os_service_default
#
# Example:
#
# class { 'neutron':
# dhcp_load_type => 'networks'
# }
#
# [*default_availability_zones*]
# (optional) A list of availability zones that are picked when availability zone is not specified
# The expected input is an array when specified.
# Defaults to $::os_service_default
#
# Example:
#
# class { 'neutron':
# default_availability_zones => ['zone1', 'zone2']
# }
#
# [*allow_automatic_l3agent_failover*] # [*allow_automatic_l3agent_failover*]
# (optional) Allow automatic rescheduling of routers from dead L3 agents with # (optional) Allow automatic rescheduling of routers from dead L3 agents with
# admin_state_up set to True to alive agents. # admin_state_up set to True to alive agents.
@ -281,6 +315,9 @@ class neutron::server (
$agent_down_time = $::os_service_default, $agent_down_time = $::os_service_default,
$router_scheduler_driver = 'neutron.scheduler.l3_agent_scheduler.ChanceScheduler', $router_scheduler_driver = 'neutron.scheduler.l3_agent_scheduler.ChanceScheduler',
$router_distributed = $::os_service_default, $router_distributed = $::os_service_default,
$network_scheduler_driver = $::os_service_default,
$dhcp_load_type = $::os_service_default,
$default_availability_zones = $::os_service_default,
$allow_automatic_l3agent_failover = $::os_service_default, $allow_automatic_l3agent_failover = $::os_service_default,
$l3_ha = false, $l3_ha = false,
$max_l3_agents_per_router = 3, $max_l3_agents_per_router = 3,
@ -311,6 +348,14 @@ class neutron::server (
# Work-around LP#1551974. neutron requires the keystoneclient to auth tokens # Work-around LP#1551974. neutron requires the keystoneclient to auth tokens
include ::keystone::client include ::keystone::client
if !is_service_default($default_availability_zones) {
validate_array($default_availability_zones)
}
if !is_service_default($dhcp_load_type) {
validate_re($dhcp_load_type, ['^networks$', '^subnets$', '^ports$'], 'Must pass either networks, subnets, or ports as values for dhcp_load_type')
}
if $ensure_fwaas_package { if $ensure_fwaas_package {
if ($::osfamily == 'Debian') { if ($::osfamily == 'Debian') {
# Debian platforms # Debian platforms
@ -391,6 +436,9 @@ class neutron::server (
'DEFAULT/router_scheduler_driver': value => $router_scheduler_driver; 'DEFAULT/router_scheduler_driver': value => $router_scheduler_driver;
'DEFAULT/router_distributed': value => $router_distributed; 'DEFAULT/router_distributed': value => $router_distributed;
'DEFAULT/allow_automatic_l3agent_failover': value => $allow_automatic_l3agent_failover; 'DEFAULT/allow_automatic_l3agent_failover': value => $allow_automatic_l3agent_failover;
'DEFAULT/network_scheduler_driver': value => $network_scheduler_driver;
'DEFAULT/dhcp_load_type': value => $dhcp_load_type;
'DEFAULT/default_availability_zones': value => join(any2array($default_availability_zones), ',');
} }
if $state_path { if $state_path {

View File

@ -0,0 +1,6 @@
---
features:
- Added the configuration options to configure neutron availability zones
for server and agents.
- Providers updated to being able to configure router/network with availability
zone.

View File

@ -50,6 +50,7 @@ describe 'neutron::agents::dhcp' do
is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/force_metadata').with_value('<SERVICE DEFAULT>'); is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/force_metadata').with_value('<SERVICE DEFAULT>');
is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/enable_metadata_network').with_value(p[:enable_metadata_network]); is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/enable_metadata_network').with_value(p[:enable_metadata_network]);
is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/dhcp_broadcast_reply').with_value('<SERVICE DEFAULT>'); is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/dhcp_broadcast_reply').with_value('<SERVICE DEFAULT>');
is_expected.to contain_neutron_dhcp_agent_config('AGENT/availability_zone').with_value('<SERVICE DEFAULT>');
end end
it 'installs neutron dhcp agent package' do it 'installs neutron dhcp agent package' do
@ -140,6 +141,15 @@ describe 'neutron::agents::dhcp' do
is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/enable_metadata_network').with_value('true'); is_expected.to contain_neutron_dhcp_agent_config('DEFAULT/enable_metadata_network').with_value('true');
end end
end end
context 'when availability zone is set' do
before :each do
params.merge!(:availability_zone => 'zone1')
end
it 'should configure availability zone' do
is_expected.to contain_neutron_dhcp_agent_config('AGENT/availability_zone').with_value(p[:availability_zone]);
end
end
end end
shared_examples_for 'neutron dhcp agent with dnsmasq_config_file specified' do shared_examples_for 'neutron dhcp agent with dnsmasq_config_file specified' do

View File

@ -47,6 +47,7 @@ describe 'neutron::agents::l3' do
is_expected.to contain_neutron_l3_agent_config('DEFAULT/periodic_interval').with_value('<SERVICE DEFAULT>') is_expected.to contain_neutron_l3_agent_config('DEFAULT/periodic_interval').with_value('<SERVICE DEFAULT>')
is_expected.to contain_neutron_l3_agent_config('DEFAULT/periodic_fuzzy_delay').with_value('<SERVICE DEFAULT>') is_expected.to contain_neutron_l3_agent_config('DEFAULT/periodic_fuzzy_delay').with_value('<SERVICE DEFAULT>')
is_expected.to contain_neutron_l3_agent_config('DEFAULT/enable_metadata_proxy').with_value('<SERVICE DEFAULT>') is_expected.to contain_neutron_l3_agent_config('DEFAULT/enable_metadata_proxy').with_value('<SERVICE DEFAULT>')
is_expected.to contain_neutron_l3_agent_config('AGENT/availability_zone').with_value('<SERVICE DEFAULT>')
end end
it 'passes purge to resource' do it 'passes purge to resource' do
@ -105,6 +106,16 @@ describe 'neutron::agents::l3' do
is_expected.to contain_neutron_l3_agent_config('DEFAULT/ha_vrrp_advert_int').with_value(p[:ha_vrrp_advert_int]) is_expected.to contain_neutron_l3_agent_config('DEFAULT/ha_vrrp_advert_int').with_value(p[:ha_vrrp_advert_int])
end end
end end
context 'with availability zone' do
before :each do
params.merge!(:availability_zone => 'zone1')
end
it 'configures availability zone' do
is_expected.to contain_neutron_l3_agent_config('AGENT/availability_zone').with_value(p[:availability_zone])
end
end
end end
context 'on Debian platforms' do context 'on Debian platforms' do

View File

@ -200,6 +200,32 @@ describe 'neutron::server' do
is_expected.not_to contain_neutron_config('keystone_authtoken/auth_type') is_expected.not_to contain_neutron_config('keystone_authtoken/auth_type')
end end
end end
context 'with a bad dhcp_load_type value' do
before :each do
params.merge!(:dhcp_load_type => 'badvalue')
end
it_raises 'a Puppet::Error', /Must pass either networks, subnets, or ports as values for dhcp_load_type/
end
context 'with availability zone hints set' do
before :each do
params.merge!(:dhcp_load_type => 'networks',
:router_scheduler_driver => 'neutron.scheduler.l3_agent_scheduler.AZLeastRoutersScheduler',
:network_scheduler_driver => 'neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler',
:default_availability_zones => ['zone1', 'zone2']
)
end
it 'should configure neutron server for availability zones' do
is_expected.to contain_neutron_config('DEFAULT/default_availability_zones').with_value('zone1,zone2')
is_expected.to contain_neutron_config('DEFAULT/router_scheduler_driver').with_value('neutron.scheduler.l3_agent_scheduler.AZLeastRoutersScheduler')
is_expected.to contain_neutron_config('DEFAULT/network_scheduler_driver').with_value('neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler')
is_expected.to contain_neutron_config('DEFAULT/dhcp_load_type').with_value('networks')
end
end
end end
shared_examples_for 'a neutron server with broken authentication' do shared_examples_for 'a neutron server with broken authentication' do

View File

@ -19,6 +19,7 @@ describe provider_class do
:distributed => 'True', :distributed => 'True',
:ha => 'False', :ha => 'False',
:tenant_id => '60f9544eb94c42a6b7e8e98c2be981b1', :tenant_id => '60f9544eb94c42a6b7e8e98c2be981b1',
:availability_zone_hint => 'zone1',
} }
end end
@ -43,12 +44,14 @@ name="router1"
status="ACTIVE" status="ACTIVE"
distributed="True" distributed="True"
ha="False" ha="False"
tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"' tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"
availability-zone-hint="zone1"'
provider.expects(:auth_neutron).with('router-create', provider.expects(:auth_neutron).with('router-create',
'--format=shell', ["--tenant_id=#{router_attrs[:tenant_id]}", '--format=shell', ["--tenant_id=#{router_attrs[:tenant_id]}",
"--distributed=#{router_attrs[:distributed]}", "--distributed=#{router_attrs[:distributed]}",
"--ha=#{router_attrs[:ha]}"], "--ha=#{router_attrs[:ha]}",
"--availability-zone-hint=#{router_attrs[:availability_zone_hint]}"],
router_name).returns(output) router_name).returns(output)
provider.create provider.create