Merge pull request #451 from enovance/bug/237/emilienm

High Availability refactorization
This commit is contained in:
François Charlier 2014-05-05 11:17:19 +02:00
commit 8a3f9e1b2e
5 changed files with 258 additions and 285 deletions

View File

@ -138,7 +138,7 @@ class cloud::dashboard(
server_names => $::hostname,
ipaddresses => $api_eth,
ports => $horizon_port,
options => 'check inter 2000 rise 2 fall 5'
options => "check inter 2000 rise 2 fall 5 cookie ${::hostname}"
}

View File

@ -51,108 +51,111 @@
#
# [*swift_api*]
# (optional) Enable or not Swift public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*ceilometer_api*]
# (optional) Enable or not Ceilometer public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*cinder_api*]
# (optional) Enable or not Cinder public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*glance_api*]
# (optional) Enable or not Glance API public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*glance_registry*]
# (optional) Enable or not Glance Registry public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*neutron_api*]
# (optional) Enable or not Neutron public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*heat_api*]
# (optional) Enable or not Heat public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*heat_cfn_api*]
# (optional) Enable or not Heat CFN public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*heat_cloudwatch_api*]
# (optional) Enable or not Heat Cloudwatch public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*nova_api*]
# (optional) Enable or not Nova public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*ec2_api*]
# (optional) Enable or not EC2 public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*metadata_api*]
# (optional) Enable or not Metadata public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*keystone_api*]
# (optional) Enable or not Keystone public binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*keystone_api_admin*]
# (optional) Enable or not Keystone admin binding.
# If true, both public and internal will attempt to be created except if vip_internal_ip is set to false (backward compatibility).
# If set to ['10.0.0.1'], only IP in the array (or in the string) will be configured in the pool. They must be part of keepalived_ip options.
# If set to false, no binding will be configure
# Defaults to true
#
# [*keystone_api_internal*]
# (optional) Enable or not Keystone internal binding.
# Defaults to true
#
# [*cinder_api_internal*]
# (optional) Enable or not Cinder internal binding.
# Defaults to true
#
# [*ceilometer_api_internal*]
# (optional) Enable or not Ceilometer internal binding.
# Defaults to true
#
# [*glance_api_internal*]
# (optional) Enable or not Glance API internal binding.
# Defaults to true
#
# [*glance_registry_internal*]
# (optional) Enable or not Glance Registry internal binding.
# Defaults to true
#
# [*nova_api_internal*]
# (optional) Enable or not Nova internal binding.
# Defaults to true
#
# [*ec2_api_internal*]
# (optional) Enable or not EC2 internal binding.
# Defaults to true
#
# [*neutron_api_internal*]
# (optional) Enable or not Neutron internal binding.
# Defaults to true
#
# [*swift_api_internal*]
# (optional) Enable or not Swift internal binding.
# Defaults to true
#
# [*heat_api_internal*]
# (optional) Enable or not Heat internal binding.
# Defaults to true
#
# [*heat_cfn_api_internal*]
# (optional) Enable or not Heat CFN internal binding.
# Defaults to true
#
# [*heat_cloudwatch_api_internal*]
# (optional) Enable or not Heat Cloudwatch internal binding.
# Defaults to true
# [*vip_public_ip*]
# (optional) Array or string for public VIP
# Should be part of keepalived_public_ips
# Defaults to '127.0.0.2'
#
# [*vip_internal_ip*]
# (optional) Array or string for internal VIP
# Should be part of keepalived_internal_ips
# Defaults to false (backward compatibility)
class cloud::loadbalancer(
$swift_api = true,
$ceilometer_api = true,
@ -167,62 +170,36 @@ class cloud::loadbalancer(
$ec2_api = true,
$metadata_api = true,
$keystone_api = true,
$swift_api_internal = true,
$ceilometer_api_internal = true,
$cinder_api_internal = true,
$glance_api_internal = true,
$glance_registry_internal = true,
$neutron_api_internal = true,
$heat_api_internal = true,
$heat_cfn_api_internal = true,
$heat_cloudwatch_api_internal = true,
$nova_api_internal = true,
$ec2_api_internal = true,
$metadata_api_internal = true,
$keystone_api_internal = true,
$keystone_api_admin = true,
$horizon = true,
$horizon_ssl = false,
$spice = true,
$haproxy_auth = 'admin:changeme',
$keepalived_state = 'BACKUP',
$keepalived_priority = 50,
$keepalived_priority = '50',
$keepalived_public_interface = 'eth0',
$keepalived_public_ipvs = ['127.0.0.1'],
$keepalived_internal_interface = 'eth1',
$keepalived_internal_ipvs = false,
$ks_ceilometer_internal_port = 8777,
$ks_ceilometer_public_port = 8777,
$ks_cinder_internal_port = 8776,
$ks_cinder_public_port = 8776,
$ks_ec2_internal_port = 8773,
$ks_ec2_public_port = 8773,
$ks_glance_api_internal_port = 9292,
$ks_glance_api_public_port = 9292,
$ks_glance_registry_internal_port = 9191,
$ks_glance_registry_public_port = 9191,
$ks_heat_cfn_internal_port = 8000,
$ks_heat_cfn_public_port = 8000,
$ks_heat_cloudwatch_internal_port = 8003,
$ks_heat_cloudwatch_public_port = 8003,
$ks_heat_internal_port = 8004,
$ks_heat_public_port = 8004,
$ks_keystone_admin_port = 35357,
$ks_keystone_internal_port = 5000,
$ks_keystone_public_port = 5000,
$ks_metadata_internal_port = 8775,
$ks_metadata_public_port = 8775,
$ks_neutron_internal_port = 9696,
$ks_neutron_public_port = 9696,
$ks_nova_internal_port = 8774,
$ks_nova_public_port = 8774,
$ks_swift_internal_port = 8080,
$ks_swift_public_port = 8080,
$horizon_port = 80,
$spice_port = 6082,
$vip_public_ip = '127.0.0.2',
$vip_public_ip = ['127.0.0.1'],
$vip_internal_ip = false,
$galera_ip = '127.0.0.1',
$galera_ip = ['127.0.0.1'],
# Deprecated parameters
$keepalived_interface = false,
$keepalived_ipvs = false,
@ -254,8 +231,11 @@ class cloud::loadbalancer(
}
# Ensure Keepalived is started before HAproxy to avoid binding errors.
# HAproxy is managed by Keepalived.
class { 'keepalived': } ->
class { 'haproxy': }
class { 'haproxy':
service_manage => false
}
keepalived::vrrp_script { 'haproxy':
name_is_process => true
@ -302,226 +282,88 @@ class cloud::loadbalancer(
}
}
if $keystone_api {
cloud::loadbalancer::listen_http {
'keystone_api_cluster':
ports => $ks_keystone_public_port,
listen_ip => $vip_public_ip;
'keystone_api_admin_cluster':
ports => $ks_keystone_admin_port,
listen_ip => $vip_public_ip;
}
# Instanciate HAproxy binding
cloud::loadbalancer::binding { 'keystone_api_cluster':
ip => $keystone_api,
port => $ks_keystone_public_port;
}
if $keystone_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'keystone_api_internal_cluster':
ports => $ks_keystone_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'keystone_api_admin_cluster':
ip => $keystone_api_admin,
port => $ks_keystone_admin_port;
}
if $swift_api {
cloud::loadbalancer::listen_http{
'swift_api_cluster':
ports => $ks_swift_public_port,
httpchk => 'httpchk /healthcheck',
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'swift_api_cluster':
ip => $swift_api,
port => $ks_swift_public_port,
httpchk => 'httpchk /healthcheck';
}
if $swift_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'swift_api_internal_cluster':
ports => $ks_swift_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'nova_api_cluster':
ip => $nova_api,
port => $ks_nova_public_port;
}
if $nova_api {
cloud::loadbalancer::listen_http{
'nova_api_cluster':
ports => $ks_nova_public_port,
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'ec2_api_cluster':
ip => $ec2_api,
port => $ks_ec2_public_port;
}
if $nova_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'nova_api_internal_cluster':
ports => $ks_nova_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'metadata_api_cluster':
ip => $metadata_api,
port => $ks_metadata_public_port;
}
if $ec2_api {
cloud::loadbalancer::listen_http{
'ec2_api_cluster':
ports => $ks_ec2_public_port,
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'spice_cluster':
ip => $spice,
port => $spice_port,
httpchk => 'httpchk GET /';
}
if $ec2_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'ec2_api_internal_cluster':
ports => $ks_ec2_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'glance_api_cluster':
ip => $glance_api,
port => $ks_glance_api_public_port;
}
if $metadata_api {
cloud::loadbalancer::listen_http{
'metadata_api_cluster':
ports => $ks_metadata_public_port,
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'glance_registry_cluster':
ip => $glance_registry,
port => $ks_glance_registry_internal_port;
}
if $metadata_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'metadata_api_internal_cluster':
ports => $ks_metadata_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'neutron_api_cluster':
ip => $neutron_api,
port => $ks_neutron_public_port;
}
if $spice {
cloud::loadbalancer::listen_http{
'spice_cluster':
ports => $spice_port,
listen_ip => $vip_public_ip,
httpchk => 'httpchk GET /';
}
cloud::loadbalancer::binding { 'cinder_api_cluster':
ip => $cinder_api,
port => $ks_cinder_public_port;
}
if $glance_api {
cloud::loadbalancer::listen_http{
'glance_api_cluster':
ports => $ks_glance_api_public_port,
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'ceilometer_api_cluster':
ip => $ceilometer_api,
port => $ks_ceilometer_public_port;
}
if $glance_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'glance_api_internal_cluster':
ports => $ks_glance_api_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'heat_api_cluster':
ip => $heat_api,
port => $ks_heat_public_port;
}
if $glance_registry {
warning('Glance Registry should not be exposed to public network.')
cloud::loadbalancer::listen_http{
'glance_registry_cluster':
ports => $ks_glance_registry_internal_port,
listen_ip => $vip_public_ip;
}
cloud::loadbalancer::binding { 'heat_cfn_api_cluster':
ip => $heat_cfn_api,
port => $ks_heat_cfn_public_port;
}
if $glance_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'glance_api_internal_cluster':
ports => $ks_glance_api_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $neutron_api {
cloud::loadbalancer::listen_http{
'neutron_api_cluster':
ports => $ks_neutron_public_port,
listen_ip => $vip_public_ip;
}
}
if $neutron_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'neutron_api_internal_cluster':
ports => $ks_neutron_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $cinder_api {
cloud::loadbalancer::listen_http{
'cinder_api_cluster':
ports => $ks_cinder_public_port,
listen_ip => $vip_public_ip;
}
}
if $cinder_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'cinder_api_internal_cluster':
ports => $ks_cinder_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $ceilometer_api {
cloud::loadbalancer::listen_http{
'ceilometer_api_cluster':
ports => $ks_ceilometer_public_port,
listen_ip => $vip_public_ip;
}
}
if $ceilometer_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'ceilometer_api_internal_cluster':
ports => $ks_ceilometer_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $heat_api {
cloud::loadbalancer::listen_http{
'heat_api_cluster':
ports => $ks_heat_public_port,
listen_ip => $vip_public_ip;
}
}
if $heat_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'heat_api_internal_cluster':
ports => $ks_heat_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $heat_cfn_api {
cloud::loadbalancer::listen_http{
'heat_api_cfn_cluster':
ports => $ks_heat_cfn_public_port,
listen_ip => $vip_public_ip;
}
}
if $heat_cfn_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'heat_cfn_internal_cluster':
ports => $ks_heat_cfn_internal_port,
listen_ip => $vip_internal_ip;
}
}
if $heat_cloudwatch_api {
cloud::loadbalancer::listen_http{
'heat_api_cloudwatch_cluster':
ports => $ks_heat_cloudwatch_public_port,
listen_ip => $vip_public_ip;
}
}
if $heat_cloudwatch_api_internal and $vip_internal_ip and $keepalived_internal_ipvs {
cloud::loadbalancer::listen_http {
'heat_cloudwatch_internal_cluster':
ports => $ks_heat_cloudwatch_internal_port,
listen_ip => $vip_internal_ip;
}
cloud::loadbalancer::binding { 'heat_cloudwatch_api_cluster':
ip => $heat_cloudwatch_api,
port => $ks_heat_cloudwatch_public_port;
}
if $horizon {
if $horizon_ssl {
cloud::loadbalancer::listen_https{
'horizon_cluster':
ports => $horizon_port,
listen_ip => $vip_public_ip;
cloud::loadbalancer::listen_https{ 'horizon_cluster':
ports => $horizon_port,
listen_ip => $vip_public_ip;
}
} else {
cloud::loadbalancer::listen_http{
'horizon_cluster':
ports => $horizon_port,
listen_ip => $vip_public_ip;
# Horizon URL is not the same on Red Hat and Debian/Ubuntu
if $::operatingsystem == 'RedHat' {
$horizon_auth_url = 'dashboard'
} else {
$horizon_auth_url = 'horizon'
}
cloud::loadbalancer::listen_http{ 'horizon_cluster':
ports => $horizon_port,
httpchk => "httpchk GET /$horizon_auth_url HTTP/1.0\r\nUser-Agent:\ HAproxy-${::hostname}",
options => { 'cookie' => 'sessionid prefix', 'balance' => 'leastconn' },
listen_ip => $vip_public_ip;
}
}
}

View File

@ -0,0 +1,63 @@
#
# Copyright (C) 2014 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.
define cloud::loadbalancer::binding (
$ip,
$port,
$httpchk = undef
){
include cloud::loadbalancer
# join all VIP together
$vip_public_ip_array = any2array($::cloud::loadbalancer::vip_public_ip)
$vip_internal_ip_array = any2array($::cloud::loadbalancer::vip_internal_ip)
if $::cloud::loadbalancer::vip_public_ip and $::cloud::loadbalancer::vip_internal_ip {
$all_vip_array = union($vip_public_ip_array, $vip_internal_ip_array)
}
if $::cloud::loadbalancer::vip_public_ip and ! $::cloud::loadbalancer::vip_internal_ip {
$all_vip_array = $vip_public_ip_array
}
if ! $::cloud::loadbalancer::vip_public_ip and $::cloud::loadbalancer::vip_internal_ip {
$all_vip_array = $vip_internal_ip_array
}
if ! $::cloud::loadbalancer::vip_internal_ip and ! $::cloud::loadbalancer::vip_public_ip {
fail('vip_public_ip and vip_internal_ip are both set to false, no binding is possible.')
}
# when we do not want binding
if ($ip == false) {
notice("no HAproxy binding for ${name} has been enabled.")
} else {
# when we want both internal & public binding
if ($ip == true) {
$listen_ip_real = $all_vip_array
} else {
# when binding is specified in parameter
if ($ip in $all_vip_array) {
$listen_ip_real = $ip
} else {
fail("${ip} is not part of VIP pools.")
}
}
cloud::loadbalancer::listen_http { $name :
ports => $port,
httpchk => $httpchk,
listen_ip => [$listen_ip_real];
}
}
}

View File

@ -20,16 +20,19 @@
define cloud::loadbalancer::listen_http(
$ports = 'unset',
$httpchk = 'httpchk',
$options = {},
$listen_ip = '0.0.0.0') {
$options_basic = {'mode' => 'http',
'balance' => 'roundrobin',
'http-check' => 'expect ! rstatus ^5',
'option' => ['tcpka', 'tcplog', $httpchk] }
$options_custom = merge($options_basic, $options)
haproxy::listen { $name:
ipaddress => $listen_ip,
ports => $ports,
options => {
'mode' => 'http',
'balance' => 'roundrobin',
'option' => ['tcpka', 'tcplog', $httpchk],
'http-check' => 'expect ! rstatus ^5',
}
options => $options_custom,
}
}

View File

@ -111,7 +111,7 @@ describe 'cloud::loadbalancer' do
end
end
context 'configure keepalived in backup' do
context 'when keepalived and HAproxy are in backup' do
it 'configure vrrp_instance with BACKUP state' do
should contain_keepalived__instance('1').with({
'interface' => params[:keepalived_public_interface],
@ -123,6 +123,9 @@ describe 'cloud::loadbalancer' do
'notify_backup' => '"/etc/init.d/haproxy stop"',
})
end # configure vrrp_instance with BACKUP state
it 'configure haproxy server without service managed' do
should contain_class('haproxy').with(:service_manage => false)
end # configure haproxy server
end # configure keepalived in backup
context 'configure keepalived in master' do
@ -139,6 +142,9 @@ describe 'cloud::loadbalancer' do
'notify_backup' => '"/etc/init.d/haproxy stop"',
})
end
it 'configure haproxy server with service managed' do
should contain_class('haproxy').with(:service_manage => false)
end # configure haproxy server
end # configure keepalived in master
context 'configure logrotate file' do
@ -171,6 +177,64 @@ describe 'cloud::loadbalancer' do
)}
end # configure monitor haproxy listen
# test backward compatibility
context 'configure OpenStack binding on public network only' do
it { should contain_haproxy__listen('spice_cluster').with(
:ipaddress => [params[:vip_public_ip]],
:ports => '6082'
)}
end
context 'configure OpenStack binding on both public and internal networks' do
before do
params.merge!(
:nova_api => true,
:galera_ip => '172.16.0.1',
:vip_public_ip => '172.16.0.1',
:vip_internal_ip => '192.168.0.1',
:keepalived_public_ipvs => ['172.16.0.1', '172.16.0.2'],
:keepalived_internal_ipvs => ['192.168.0.1', '192.168.0.2']
)
end
it { should contain_haproxy__listen('nova_api_cluster').with(
:ipaddress => ['172.16.0.1', '192.168.0.1'],
:ports => '8774'
)}
end
context 'disable an OpenStack service binding' do
before do
params.merge!(:metadata_api => false)
end
it { should_not contain_haproxy__listen('metadata_api_cluster') }
end
context 'should fail to configure OpenStack binding when vip_public_ip and vip_internal_ip are missing' do
before do
params.merge!(
:nova_api => true,
:galera_ip => '172.16.0.1',
:vip_public_ip => false,
:vip_internal_ip => false,
:keepalived_public_ipvs => ['172.16.0.1', '172.16.0.2']
)
end
it_raises 'a Puppet::Error', /vip_public_ip and vip_internal_ip are both set to false, no binding is possible./
end
context 'should fail to configure OpenStack binding when given VIP is not in the VIP pool list' do
before do
params.merge!(
:nova_api => '10.0.0.1',
:galera_ip => '172.16.0.1',
:vip_public_ip => '172.16.0.1',
:vip_internal_ip => false,
:keepalived_public_ipvs => ['172.16.0.1', '172.16.0.2']
)
end
it_raises 'a Puppet::Error', /10.0.0.1 is not part of VIP pools./
end
context 'with a public OpenStack VIP not in the keepalived VIP list' do
before do
params.merge!(
@ -202,6 +266,7 @@ describe 'cloud::loadbalancer' do
end
it_raises 'a Puppet::Error', /galera_ip should be part of keepalived_public_ipvs or keepalived_internal_ipvs./
end
end # shared:: openstack loadbalancer
context 'on Debian platforms' do