Add cluster_members_addr parameter to specify ip addresses used in cluster setup

Due to https://bugzilla.redhat.com/show_bug.cgi?id=1659389 we need to be
able to specify the exact ip addresses being used in the cluster setup.
This support exists also for corosync 2.x based systems, but seems to be
quite a necessity when using corosync 3.x + knet. So let's add this
feature in order to cover for the next Centos/RHEL release.

Change-Id: I03d23177c7a913127ffc2f6d01a6318cb80d09c5
This commit is contained in:
Michele Baldessari 2018-12-18 18:41:57 +01:00
parent 7b55ac38ec
commit 93482ade19
3 changed files with 86 additions and 2 deletions

View File

@ -0,0 +1,49 @@
module Puppet::Parser::Functions
newfunction(
:pcmk_cluster_setup,
type: :rvalue,
arity: -1,
doc: <<-eof
Input data cluster_members string separated by a space:
* String A space-separated string containing a list of node names
* String A list containing either a single string (single ip) or a list of strings
(multiple ipaddresses) associated to each cluster node
Output forms:
* string - Output A string to be used in the cluster setup call to pcs
eof
) do |args|
nodes = args[0]
addr_list = args[1]
fail "pcmk_cluster_setup: Got unsupported nodes input data: #{nodes.inspect}" if not nodes.is_a? String
fail "pcmk_cluster_setup: Got unsupported addr_list input data: #{addr_list.inspect}" if not addr_list.is_a? Array
node_list = nodes.split()
fail "pcmk_cluster_setup: node list and addr list should be of the same size when defined and not empty" if addr_list.size > 0 and addr_list.size != node_list.size
# If the addr_list was specified we need to return a string in the form of
# node1 addr=1.2.3.4 node2 addr=1.2.3.5 addr=1.2.3.6 node3 addr=1.2.3.7
if addr_list.size > 0
ret = ''
node_list.zip(addr_list).each do |node, ip|
# addr can be '1.2.3.4' or ['1.2.3.4', '1.2.3.5'] or
if ip.is_a? String
addr = "addr=#{ip}"
elsif ip.is_a? Array
addr = ''
ip.each do |i|
addr += "addr=#{i}"
addr += " " if not i.equal?(ip.last)
end
else
fail "pcmk_cluster_setup: One of the addresses in addr_list is neither a String nor an Array"
end
ret += "#{node} #{addr}"
ret += " " if not node.equal?(node_list.last)
end
# only node_list is specified so we just return the original string
else
ret = nodes.strip()
end
ret
end
end

View File

@ -4,9 +4,18 @@
#
# === Parameters
# [*cluster_members*]
# (required) A space-separted list of cluster IP's or names to run the
# (required) A space-separted list of cluster IP's or names to run the
# authentication against
#
# [*cluster_members_addr*]
# (optional) An array of arrays containing the node addresses to be used
# As ring addresses in corosync (as required by corosync3+knet). For example:
# [[10.0.0.1], [10.0.0.10], [10.0.0.20,10.0.0.21]] with nodes [n1, n2, n3]
# will create the cluster as follows:
# pcs cluster setup clustername n1 addr=10.0.0.1 n2 addr=10.0.0.10 \
# n3 addr=10.0.0.20 addr=10.0.0.21
# Defaults to []
#
# [*cluster_members_rrp*]
# (optional) A space-separated list of cluster IP's or names pair where each
# component represent a resource on respectively ring0 and ring1
@ -89,6 +98,7 @@
#
class pacemaker::corosync(
$cluster_members,
$cluster_members_addr = [],
$cluster_members_rrp = undef,
$cluster_name = 'clustername',
$cluster_setup_extras = {},
@ -207,7 +217,7 @@ class pacemaker::corosync(
}
if ! $cluster_members_rrp {
$cluster_members_rrp_real = $cluster_members
$cluster_members_rrp_real = pcmk_cluster_setup($cluster_members, $cluster_members_addr)
} else {
$cluster_members_rrp_real = $cluster_members_rrp
}

View File

@ -0,0 +1,25 @@
require 'spec_helper'
describe 'pcmk_cluster_setup' do
context 'interface' do
it { is_expected.to run.with_params(123,[]).and_raise_error(Puppet::Error, /pcmk_cluster_setup: Got unsupported nodes input data/) }
it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::Error, /pcmk_cluster_setup: Got unsupported addr_list input data/) }
it { is_expected.to run.with_params('n1 n2 n3', ['1', '2']).and_raise_error(Puppet::Error, /pcmk_cluster_setup: node list and addr list should be of the same size when defined and not empty/) }
it { is_expected.to run.with_params('n1 n2 n3', ['1', ['2'], nil]).and_raise_error(Puppet::Error, /pcmk_cluster_setup: One of the addresses in addr_list is neither a String nor an Array/) }
end
it 'returns the original node string when no addresses are specified' do
is_expected.to run.with_params('n1 n2 n3', []).and_return('n1 n2 n3')
is_expected.to run.with_params('n1 n2', []).and_return('n1 n2')
is_expected.to run.with_params('n1', []).and_return('n1')
is_expected.to run.with_params('n1 ', []).and_return('n1')
end
it 'returns the correct cluster setup cmd given both nodes and ip address' do
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', ['1.1.1.1', '2.2.2.2', '3.3.3.3']).and_return('ctr-0 addr=1.1.1.1 ctr-1 addr=2.2.2.2 ctr-2 addr=3.3.3.3')
is_expected.to run.with_params('ctr-0 ctr-1', ['1.1.1.1', ['2.2.2.2', '3.3.3.3']]).and_return('ctr-0 addr=1.1.1.1 ctr-1 addr=2.2.2.2 addr=3.3.3.3')
is_expected.to run.with_params('ctr-0', [['2.2.2.2', '3.3.3.3', '4.4.4.4']]).and_return('ctr-0 addr=2.2.2.2 addr=3.3.3.3 addr=4.4.4.4')
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', [['1.1.1.1'], ['2.2.2.2'], '3.3.3.3']).and_return('ctr-0 addr=1.1.1.1 ctr-1 addr=2.2.2.2 ctr-2 addr=3.3.3.3')
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', [['1fe80::7ed:a95d:ed26:f5b', 'fe80::7ed:a95d:ed26:f5c', 'fe80::7ed:a95d:ed26:f5d'], ['1.1.1.1', '2.2.2.2'], '3.3.3.3']).and_return('ctr-0 addr=1fe80::7ed:a95d:ed26:f5b addr=fe80::7ed:a95d:ed26:f5c addr=fe80::7ed:a95d:ed26:f5d ctr-1 addr=1.1.1.1 addr=2.2.2.2 ctr-2 addr=3.3.3.3')
end
end