Enables OpenDaylight Clustering in HA deployments

Previously ODL was restricted to only running on the first node in an
tripleO HA deployment.  This patches enables clustering for ODL and
allows multiple ODL instances (minimum 3 for HA).

Partially-implements: blueprint opendaylight-ha

Change-Id: Ic9a955a1c2afc040b2f9c6fb86573c04a60f9f31
Signed-off-by: Tim Rozet <trozet@redhat.com>
This commit is contained in:
Tim Rozet 2017-01-25 15:09:32 -05:00
parent 4c07c75d5b
commit 0cec9b6f49
6 changed files with 135 additions and 15 deletions

View File

@ -44,3 +44,7 @@ mod 'ntp',
mod 'systemd',
:git => 'https://github.com/camptocamp/puppet-systemd',
:ref => 'master'
mod 'opendaylight',
:git => 'https://github.com/dfarrell07/puppet-opendaylight',
:ref => 'master'

View File

@ -22,19 +22,35 @@
# (Optional) The current step of the deployment
# Defaults to hiera('step')
#
# [*primary_node*]
# (Optional) The hostname of the first node of this role type
# Defaults to hiera('bootstrap_nodeid', undef)
# [*odl_api_ips*]
# (Optional) List of OpenStack Controller IPs for ODL API
# Defaults to hiera('opendaylight_api_node_ips')
#
# [*node_name*]
# (Optional) The short hostname of node
# Defaults to hiera('bootstack_nodeid')
#
class tripleo::profile::base::neutron::opendaylight (
$step = hiera('step'),
$primary_node = hiera('bootstrap_nodeid', undef),
$odl_api_ips = hiera('opendaylight_api_node_ips'),
$node_name = hiera('bootstack_nodeid')
) {
if $step >= 1 {
# Configure ODL only on first node of the role where this service is
# applied
if $primary_node == downcase($::hostname) {
validate_array($odl_api_ips)
if empty($odl_api_ips) {
fail('No IPs assigned to OpenDaylight Api Service')
} elsif size($odl_api_ips) == 2 {
fail('2 node OpenDaylight deployments are unsupported. Use 1 or greater than 2')
} elsif size($odl_api_ips) > 2 {
$node_string = split($node_name, '-')
$ha_node_index = $node_string[-1] + 1
class { '::opendaylight':
enable_ha => true,
ha_node_ips => $odl_api_ips,
ha_node_index => $ha_node_index,
}
} else {
include ::opendaylight
}
}

View File

@ -30,6 +30,10 @@
# (Optional) Password to configure for OpenDaylight
# Defaults to 'admin'
#
# [*odl_url_ip*]
# (Optional) Virtual IP address for ODL Api Service
# Defaults to hiera('opendaylight_api_vip')
#
# [*conn_proto*]
# (Optional) Protocol to use to for ODL REST access
# Defaults to hiera('opendaylight::nb_connection_protocol')
@ -43,14 +47,13 @@ class tripleo::profile::base::neutron::plugins::ml2::opendaylight (
$odl_port = hiera('opendaylight::odl_rest_port'),
$odl_username = hiera('opendaylight::username'),
$odl_password = hiera('opendaylight::password'),
$odl_url_ip = hiera('opendaylight_api_vip'),
$conn_proto = hiera('opendaylight::nb_connection_protocol'),
$step = hiera('step'),
) {
if $step >= 4 {
$odl_url_ip = hiera('opendaylight_api_vip')
if ! $odl_url_ip { fail('OpenDaylight Controller IP/VIP is Empty') }
if ! $odl_url_ip { fail('OpenDaylight API VIP is Empty') }
class { '::neutron::plugins::ml2::opendaylight':
odl_username => $odl_username,

View File

@ -30,6 +30,10 @@
# (Optional) List of OpenStack Controller IPs for ODL API
# Defaults to hiera('opendaylight_api_node_ips')
#
# [*odl_url_ip*]
# (Optional) Virtual IP address for ODL Api Service
# Defaults to hiera('opendaylight_api_vip')
#
# [*conn_proto*]
# (Optional) Protocol to use to for ODL REST access
# Defaults to hiera('opendaylight::nb_connection_protocol')
@ -43,25 +47,25 @@ class tripleo::profile::base::neutron::plugins::ovs::opendaylight (
$odl_port = hiera('opendaylight::odl_rest_port'),
$odl_check_url = hiera('opendaylight_check_url'),
$odl_api_ips = hiera('opendaylight_api_node_ips'),
$odl_url_ip = hiera('opendaylight_api_vip'),
$conn_proto = hiera('opendaylight::nb_connection_protocol'),
$step = hiera('step'),
) {
if $step >= 4 {
$opendaylight_controller_ip = $odl_api_ips[0]
$odl_url_ip = hiera('opendaylight_api_vip')
if ! $opendaylight_controller_ip { fail('OpenDaylight Controller IP is Empty') }
if empty($odl_api_ips) { fail('No IPs assigned to OpenDaylight Api Service') }
if ! $odl_url_ip { fail('OpenDaylight API VIP is Empty') }
# Build URL to check if ODL is up before connecting OVS
$opendaylight_url = "${conn_proto}://${odl_url_ip}:${odl_port}/${odl_check_url}"
$odl_ovsdb_str = join(regsubst($odl_api_ips, '.+', 'tcp:\0:6640'), ' ')
class { '::neutron::plugins::ovs::opendaylight':
tunnel_ip => hiera('neutron::agents::ml2::ovs::local_ip'),
odl_check_url => $opendaylight_url,
odl_ovsdb_iface => "tcp:${opendaylight_controller_ip}:6640",
odl_ovsdb_iface => $odl_ovsdb_str,
}
}
}

View File

@ -0,0 +1,5 @@
---
features:
- Adds OpenDaylight HA support. Now when ODL is applied to three or
more nodes ODL will be deployed as a cluster in HA, rather than
the previous behavior of only running on the first node.

View File

@ -0,0 +1,88 @@
#
# Copyright (C) 2017 Red Hat, Inc.
#
# 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.
#
require 'spec_helper'
describe 'tripleo::profile::base::neutron::opendaylight' do
let :params do
{ :step => 1,
:node_name => 'overcloud-controller-0',
}
end
shared_examples_for 'tripleo::profile::base::neutron::opendaylight' do
before :each do
facts.merge!({ :step => params[:step] })
end
context 'with noha' do
before do
params.merge!({
:odl_api_ips => ['192.0.2.5']
})
end
it 'should install and configure opendaylight' do
is_expected.to contain_class('opendaylight')
end
end
context 'with empty OpenDaylight API IPs' do
before do
params.merge!({
:odl_api_ips => []
})
end
it 'should fail to install OpenDaylight' do
is_expected.to compile.and_raise_error(/No IPs assigned to OpenDaylight Api Service/)
end
end
context 'with 2 OpenDaylight API IPs' do
before do
params.merge!({
:odl_api_ips => ['192.0.2.5', '192.0.2.6']
})
end
it 'should fail to install OpenDaylight' do
is_expected.to compile.and_raise_error(/2 node OpenDaylight deployments are unsupported. Use 1 or greater than 2/)
end
end
context 'with HA and 3 OpenDaylight API IPs' do
before do
params.merge!({
:odl_api_ips => ['192.0.2.5', '192.0.2.6', '192.0.2.7']
})
end
it 'should install and configure OpenDaylight in HA' do
is_expected.to contain_class('opendaylight').with(
:enable_ha => true,
:ha_node_ips => params[:odl_api_ips],
:ha_node_index => '1',
)
end
end
end
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) do
facts.merge({ :hostname => 'node.example.com' })
end
it_behaves_like 'tripleo::profile::base::neutron::opendaylight'
end
end
end