102 lines
3.7 KiB
Ruby
102 lines
3.7 KiB
Ruby
module Puppet::Parser::Functions
|
|
newfunction(
|
|
:pcmk_nodes_added,
|
|
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
|
|
* String the version of pcs used
|
|
* Output of `crm_node -l` (only used to ease unit testing) (optional)
|
|
|
|
Output forms:
|
|
* array - output the plain array of nodes that have been added compared
|
|
to the running cluster. It returns an empty array in case the
|
|
cluster is not set up or if crm_node return an error
|
|
eof
|
|
) do |args|
|
|
# no point in doing this if the crm_node executable does not exist
|
|
return [] if Facter::Util::Resolution.which('crm_node') == nil
|
|
nodes = args[0]
|
|
addr_list = args[1]
|
|
pcs_version = args[2]
|
|
crm_node_list = args[3]
|
|
unless nodes.is_a? String
|
|
fail "Got unsupported nodes input data: #{nodes.inspect}"
|
|
end
|
|
unless addr_list.is_a? Array
|
|
fail "Got unsupported addr_list input data: #{addr_list.inspect}"
|
|
end
|
|
if crm_node_list && !crm_node_list.kind_of?(String) then
|
|
fail "Got unsupported crm_node_list #{crm_node_list.inspect}"
|
|
end
|
|
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 crm_node_list && crm_node_list.kind_of?(String) then
|
|
return [] if crm_node_list.empty?
|
|
crm_nodes_output = crm_node_list
|
|
else
|
|
# A typical crm_node -l output is like the following:
|
|
# [root@foobar-0 ~]# crm_node -l
|
|
# 3 foobar-2 member
|
|
# 1 foobar-0 member
|
|
# 2 foobar-1 lost
|
|
crm_nodes_output = `crm_node -l`
|
|
# if the command fails we certainly did not add any nodes
|
|
return [] if $?.exitstatus != 0
|
|
end
|
|
Puppet.debug("pcmk_nodes_added: crm_nodes_output #{crm_nodes_output}")
|
|
|
|
crm_nodes = []
|
|
crm_nodes_output.lines.each { |line|
|
|
(id, node, state, _) = line.split(" ").collect(&:strip)
|
|
valid_states = %w(member lost)
|
|
state.downcase! if state
|
|
crm_nodes.push(node.strip) if valid_states.include? state
|
|
}
|
|
nodes_added = node_list - crm_nodes
|
|
|
|
if pcs_version =~ /0.10/
|
|
# If the addr_list was specified we need to return a list 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 = []
|
|
nodes_addrs_added = node_list.zip(addr_list)
|
|
.select { |node_addr| nodes_added.include?(node_addr[0]) }
|
|
nodes_addrs_added.each do |node_addr|
|
|
node = node_addr[0]
|
|
ip = node_addr[1]
|
|
# 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_nodes_added: One of the addresses in addr_list is neither a String nor an Array"
|
|
end
|
|
ret << "#{node} #{addr}"
|
|
end
|
|
# only node_added is specified so we just return the original string
|
|
else
|
|
ret = nodes_added
|
|
end
|
|
elsif pcs_version =~ /0.9/
|
|
# With pcs 0.9 only non-knet clusters are supported, aka only one address can be used
|
|
# so we take the node name as we always did
|
|
ret = nodes_added
|
|
else
|
|
fail("pcmk_nodes_added: pcs #{pcs_version} is unsupported")
|
|
end
|
|
|
|
Puppet.debug("pcmk_nodes_added: #{ret} [#{node_list} - #{crm_nodes}]")
|
|
ret
|
|
end
|
|
end
|