puppet-pacemaker/agent_generator/agent_generator.rb

235 lines
6.3 KiB
Ruby
Executable File

#!/usr/bin/ruby
# Usage:
#
# * install a fence agent package e.g. fence-agents-ilo2
# * fence_ilo2 -o metadata > ilo.xml
# * fence-generator.rb ilo.xml fence_ilo2 fence-agents-ilo2
# [ XML metadata, name of the class, name of the package for dependency check ]
require 'rexml/document'
class FencingMetadataParser
def initialize(filename, agentName, packageName)
@agentName = agentName
@packageName = packageName
file = File.new(filename)
@doc = REXML::Document.new file
@params = []
@params_max_len = 14 # pcmk_host_list
end
def getPackageName
@packageName
end
def getAgentName
@agentName
end
def getParameters
## result have to be array as order should be preserved
return @params unless @params.empty?
@doc.elements.each('resource-agent/parameters/parameter') { |p|
param = {}
param['name'] = REXML::XPath.match(p, 'string(./@name)')[0]
@params_max_len = param['name'].length if param['name'].length > @params_max_len
param['type'] = REXML::XPath.match(p, 'string(./content/@type)')[0]
## if 'default' is list then we can not enter it as parameter !!
## this is problem only for 'cmd_prompt'
param['default'] = REXML::XPath.match(p, 'string(./content/@default)')[0]
param['description'] = REXML::XPath.match(p, 'string(./shortdesc)')[0]
## remove parameters that are not usable during automatic execution
@params.push(param) unless %w(help version).include?(param['name'])
}
@params
end
def getMaxLen
@params_max_len
end
end
class ManifestGenerator
def initialize(parser)
@parser = parser
end
def generate
puts <<-eos
# == Define: pacemaker::stonith::#{@parser.getAgentName}
#
# Module for managing Stonith for #{@parser.getAgentName}.
#
# WARNING: Generated by "rake generate_stonith", manual changes will
# be lost.
#
# === Parameters
#
#{getManifestDocumentation}# [*interval*]
# Interval between tries.
#
# [*ensure*]
# The desired state of the resource.
#
# [*tries*]
# The number of tries.
#
# [*try_sleep*]
# Time to sleep between tries.
#
# [*pcmk_host_list*]
# List of Pacemaker hosts.
#
# [*meta_attr*]
# (optional) String of meta attributes
# Defaults to undef
#
# [*deep_compare*]
# Enable deep comparing of resources and bundles
# When set to true a resource will be compared in full (options, meta parameters,..)
# to the existing one and in case of difference it will be repushed to the CIB
# Defaults to false
#
# [*update_settle_secs*]
# When deep_compare is enabled and puppet updates a resource, this
# parameter represents the number (in seconds) to wait for the cluster to settle
# after the resource update.
# Defaults to 600 (seconds)
#
# === Dependencies
# None
#
# === Authors
#
# Generated by rake generate_stonith task.
#
# === Copyright
#
# Copyright (C) 2016 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.
#
define pacemaker::stonith::#{@parser.getAgentName} (
#{getManifestParameters}
$deep_compare = false,
$update_settle_secs = 600,
) {
#{getVariableValues}
$pcmk_host_value_chunk = $pcmk_host_list ? {
undef => '$(/usr/sbin/crm_node -n)',
default => $pcmk_host_list,
}
$meta_attr_value_chunk = $meta_attr ? {
undef => '',
default => "meta ${meta_attr}",
}
# $title can be a mac address, remove the colons for pcmk resource name
$safe_title = regsubst($title, ':', '', 'G')
Exec<| title == 'wait-for-settle' |> -> Pcmk_stonith<||>
$param_string = "#{getChunks} op monitor interval=${interval} ${meta_attr_value_chunk}"
#{getPackageSnippet}
pcmk_stonith { "stonith-#{@parser.getAgentName}-${safe_title}":
ensure => $ensure,
stonith_type => '#{@parser.getAgentName}',
pcmk_host_list => $pcmk_host_value_chunk,
pcs_param_string => $param_string,
tries => $tries,
try_sleep => $try_sleep,
deep_compare => $deep_compare,
update_settle_secs => $update_settle_secs,
}
}
eos
end
def getPackageSnippet
text = ''
if @parser.getPackageName != 'None'
text += " if $ensure != 'absent' {\n"
text += " ensure_resource('package', '#{@parser.getPackageName}', { ensure => 'installed' })\n"
text += " Package['#{@parser.getPackageName}'] -> Pcmk_stonith[\"stonith-#{@parser.getAgentName}-${safe_title}\"]\n"
text += " }"
end
text
end
def getManifestDocumentation
text = ''
@parser.getParameters.each { |p|
text += "# [*#{p['name']}*]\n"
text += "# #{p['description']}\n#\n"
}
text
end
def getManifestParameters
text = ''
@parser.getParameters.each { |p|
text += format_param(p['name'])
}
text += "\n"
text += format_param('meta_attr', 'undef')
text += format_param('interval', "'60s'")
text += format_param('ensure', 'present')
text += format_param('pcmk_host_list')
text += "\n"
text += format_param('tries')
text += format_param('try_sleep')
text
end
def getVariableValues
text = ''
@parser.getParameters.each { |p|
text += " $#{p['name']}_chunk = $#{p['name']} ? {\n"
text += " undef => '',\n"
text += " default => \"#{p['name']}=\\\"${#{p['name']}}\\\"\",\n"
text += " }\n"
}
text
end
def getChunks
text = ''
@parser.getParameters.each { |p|
text += "${#{p['name']}_chunk} "
}
text
end
private
def format_param(param, value = 'undef')
" $%-#{@parser.getMaxLen}s = %s,\n" % [param, value]
end
end
if ARGV.length != 3
puts 'You have to enter three arguments: path to metadata, name of fence agent and fence agent package'
exit 1
end
metadata, agentName, packageName = ARGV
# e.g. parser = FencingMetadataParser.new("ilo.xml", "fence_ilo", "fence-agents-ilo2")
parser = FencingMetadataParser.new(metadata, agentName, packageName)
ManifestGenerator.new(parser).generate