192 lines
5.2 KiB
Ruby
192 lines
5.2 KiB
Ruby
module Puppet::Parser::Functions
|
|
newfunction(
|
|
:pacemaker_cluster_nodes,
|
|
type: :rvalue,
|
|
arity: -2,
|
|
doc: <<-eof
|
|
Convert different forms of node list to the required form.
|
|
|
|
Input data can be:
|
|
* String 'n1 n2a,n2b n3'
|
|
* Array ['n1', ['n2a','n2b'], 'n3']
|
|
* Hash { 'name' => 'n1', 'ring0' => '192.168.0.1' }
|
|
|
|
Hash can have optional keys: name, id, ip, votes,
|
|
|
|
Node id will be autogenerated unless id key is provided.
|
|
|
|
Internal nodes structure example:
|
|
```
|
|
[
|
|
{
|
|
name: 'node1',
|
|
id: '1',
|
|
votes: '2',
|
|
ring0: '192.168.0.1',
|
|
ring1: '172.16.0.1',
|
|
},
|
|
{
|
|
name: 'node2',
|
|
id: '2',
|
|
votes: '1',
|
|
ring0: '192.168.0.2',
|
|
ring1: '172.16.0.2',
|
|
},
|
|
{
|
|
name: 'node3',
|
|
id: '3',
|
|
votes: '1',
|
|
ring0: '192.168.0.3',
|
|
ring1: '172.16.0.3',
|
|
}
|
|
]
|
|
# All fields except at least one ring address are optional
|
|
```
|
|
|
|
If neither 'ring0' nor 'ring1' are found fields 'ip' and 'name' will be used.
|
|
|
|
Output forms:
|
|
* hash - output the hash of the node ids and their data (used for corosync config template)
|
|
* list - output the space ad comma separated nodes and interfaces (used for "pcs cluster setup")
|
|
* array - output the plain array of nodes (used for pacemaker_auth or "pcs cluster auth")
|
|
eof
|
|
) do |args|
|
|
nodes = args[0]
|
|
form = args[1] || 'hash'
|
|
form = form.to_s.downcase
|
|
raise(Puppet::Error, 'Nodes are not provided!') if [String, Hash, Array].include? nodes.class and nodes.empty?
|
|
forms = %w(list array hash)
|
|
raise(Puppet::Error, "Unknown form: '#{form}'") unless forms.include? form
|
|
|
|
array_formatter = lambda do |structure|
|
|
list = []
|
|
structure.each do |node|
|
|
next unless node.is_a? Hash
|
|
list << node['ring0'] if node['ring0']
|
|
list << node['ring1'] if node['ring1']
|
|
end
|
|
list.flatten.compact.uniq
|
|
end
|
|
|
|
list_formatter = lambda do |structure|
|
|
list = []
|
|
structure.each do |node|
|
|
node_rings = []
|
|
node_rings[0] = node['ring0'] if node['ring0']
|
|
node_rings[1] = node['ring1'] if node['ring1']
|
|
list << node_rings.join(',')
|
|
end
|
|
list.join ' '
|
|
end
|
|
|
|
hash_formatter = lambda do |structure|
|
|
hash = {}
|
|
structure.each do |node|
|
|
id = node['id']
|
|
next unless id
|
|
hash[id] = node
|
|
end
|
|
hash
|
|
end
|
|
|
|
node_split_to_rings = lambda do |node|
|
|
node = node.to_s.chomp.strip
|
|
rings = node.split ','
|
|
node_hash = {}
|
|
node_hash['ring0'] = rings[0].to_s if rings[0] and rings[0] != ''
|
|
node_hash['ring1'] = rings[1].to_s if rings[1] and rings[1] != ''
|
|
node_hash
|
|
end
|
|
|
|
node_hash_process = lambda do |node|
|
|
ring0 = node['ring0']
|
|
ring1 = node['ring1']
|
|
ring0 = node['ip'] if node['ip'] and not ring0
|
|
ring0 = node['name'] if node['name'] and not ring0
|
|
node_hash = {}
|
|
node_hash['ring0'] = ring0.to_s if ring0
|
|
node_hash['ring1'] = ring1.to_s if ring1
|
|
node_hash['name'] = node['name'].to_s if node['name']
|
|
node_hash['id'] = node['id'].to_s if node['id']
|
|
node_hash['vote'] = node['vote'].to_s if node['vote']
|
|
node_hash
|
|
end
|
|
|
|
string_parser = lambda do |string|
|
|
string = string.to_s.chomp.strip
|
|
node_list = []
|
|
string.split.each do |node|
|
|
node_hash = node_split_to_rings.call node
|
|
next unless node_hash['ring0'] or node_hash['ring1']
|
|
node_list << node_hash
|
|
end
|
|
node_list
|
|
end
|
|
|
|
array_parser = lambda do |array|
|
|
array = [array] unless array.is_a? Array
|
|
node_list = []
|
|
array.each do |node|
|
|
if node.is_a? Array
|
|
node_hash = {}
|
|
node_hash['ring0'] = node[0].to_s if node[0]
|
|
node_hash['ring1'] = node[1].to_s if node[1]
|
|
elsif node.is_a? Hash
|
|
node_hash = node_hash_process.call node
|
|
else
|
|
node_hash = node_split_to_rings.call node.to_s
|
|
end
|
|
next unless node_hash['ring0'] or node_hash['ring1']
|
|
node_list << node_hash
|
|
end
|
|
node_list
|
|
end
|
|
|
|
hash_parser = lambda do |hash|
|
|
raise(Puppet::Error, "Data is not a hash: #{hash.inspect}") unless hash.is_a? Hash
|
|
node_list = []
|
|
hash.each do |node_name, node|
|
|
node = node.dup
|
|
node['name'] = node_name if node_name and not node['name']
|
|
node_hash = node_hash_process.call node
|
|
next unless node_hash['ring0'] or node_hash['ring1']
|
|
node_list << node_hash
|
|
end
|
|
node_list
|
|
end
|
|
|
|
set_node_ids = lambda do |structure|
|
|
next_id = 1
|
|
structure.each do |node|
|
|
unless node['id']
|
|
node['id'] = next_id.to_s
|
|
next_id += 1
|
|
end
|
|
end
|
|
end
|
|
|
|
structure = []
|
|
|
|
if nodes.is_a? String
|
|
structure = string_parser.call nodes
|
|
elsif nodes.is_a? Array
|
|
structure = array_parser.call nodes
|
|
elsif nodes.is_a? Hash
|
|
structure = hash_parser.call nodes
|
|
else
|
|
raise(Puppet::Error, "Got unsupported nodes input data: #{nodes.inspect}")
|
|
end
|
|
|
|
set_node_ids.call structure
|
|
|
|
if form == 'hash'
|
|
hash_formatter.call structure
|
|
elsif form == 'list'
|
|
list_formatter.call structure
|
|
elsif form == 'array'
|
|
array_formatter.call structure
|
|
end
|
|
|
|
end
|
|
end
|