Implement stonith levels resource
This resource implements a stonith levels definition. This is used so that we can define a specific sequence of stonith operations on a node. More documentation about stonith levels can be found here: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/high_availability_add-on_reference/#s1-fencelevels-HAAR Change-Id: I9cc5064e776a3771e30d853d9453026d2731c98d
This commit is contained in:
parent
48c8599793
commit
ebef43cadf
51
lib/puppet/provider/pcmk_stonith_level/default.rb
Normal file
51
lib/puppet/provider/pcmk_stonith_level/default.rb
Normal file
@ -0,0 +1,51 @@
|
||||
require_relative '../pcmk_common'
|
||||
|
||||
Puppet::Type.type(:pcmk_stonith_level).provide(:default) do
|
||||
desc 'A base resource definition for a pacemaker stonith level definition'
|
||||
|
||||
### overloaded methods
|
||||
def create
|
||||
level = @resource[:level]
|
||||
target = @resource[:target]
|
||||
stonith_resources = @resource[:stonith_resources]
|
||||
res = stonith_resources.join(',')
|
||||
cmd = 'stonith level add ' + level.to_s + ' ' + target + ' ' + res
|
||||
|
||||
pcs('create', "#{name}-#{target}-#{res}", cmd, @resource[:tries],
|
||||
@resource[:try_sleep], @resource[:verify_on_create], @resource[:post_success_sleep])
|
||||
end
|
||||
|
||||
def destroy
|
||||
# Any corresponding location rules will be deleted by
|
||||
# pcs automatically, if present
|
||||
target = @resource[:target]
|
||||
level = @resource[:level]
|
||||
cmd = 'stonith level remove ' + level.to_s + ' ' + target
|
||||
pcs('delete', @resource[:name], cmd, @resource[:tries],
|
||||
@resource[:try_sleep], @resource[:verify_on_create], @resource[:post_success_sleep])
|
||||
end
|
||||
|
||||
def exists?
|
||||
# stonith level output is a bit cumbersome to parse:
|
||||
# Target: overcloud-galera-0
|
||||
# Level 1 - stonith-fence_ipmilan-006809859383,stonith-fence_compute-fence-nova
|
||||
# Target: overcloud-novacompute-0
|
||||
# Level 1 - stonith-fence_ipmilan-006809859383,stonith-fence_compute-fence-nova
|
||||
# Level 2 - stonith-fence_ipmilan-006809859383,stonith-fence_compute-fence-nova
|
||||
# Target: overcloud-rabbit-0
|
||||
# Level 2 - stonith-fence_ipmilan-006809859383,stonith-fence_compute-fence-nova
|
||||
target = @resource[:target]
|
||||
level = @resource[:level]
|
||||
stonith_resources = @resource[:stonith_resources]
|
||||
res = stonith_resources.join(',')
|
||||
Puppet.debug("Exists: stonith level exists #{level} #{target} #{res}")
|
||||
# The below cmd return the "Level X - ...." strings after the Target: string until the next
|
||||
# Target: string (or until the bottom of the file if it is the last Target in the output
|
||||
cmd = 'stonith level | sed -n "/^Target: ' + target + '$/,/^Target:/{/^Target: ' + target + '$/b;/^Target:/b;p}"'
|
||||
cmd += ' | grep -e "Level[[:space:]]*' + level.to_s + '[[:space:]]*-[[:space:]]*' + res + '"'
|
||||
ret = pcs('show', @resource[:name], cmd, @resource[:tries],
|
||||
@resource[:try_sleep], @resource[:verify_on_create], @resource[:post_success_sleep])
|
||||
|
||||
return ret == false ? false : true
|
||||
end
|
||||
end
|
99
lib/puppet/type/pcmk_stonith_level.rb
Normal file
99
lib/puppet/type/pcmk_stonith_level.rb
Normal file
@ -0,0 +1,99 @@
|
||||
require 'puppet/parameter/boolean'
|
||||
|
||||
Puppet::Type.newtype(:pcmk_stonith_level) do
|
||||
@doc = "Base resource definition for a pacemaker stonith level resource"
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name) do
|
||||
desc "A unique name for the stonith level"
|
||||
end
|
||||
|
||||
newparam(:level) do
|
||||
desc "The stonith level"
|
||||
munge do |value|
|
||||
if value.is_a?(String)
|
||||
unless value =~ /^[\d]+$/
|
||||
raise ArgumentError, "The stonith level must be an integer"
|
||||
end
|
||||
value = Integer(value)
|
||||
end
|
||||
raise ArgumentError, "Level must be an integer >= 1" if value < 1
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:target) do
|
||||
desc "The pacemaker stonith target to apply the level to"
|
||||
end
|
||||
|
||||
newparam(:stonith_resources) do
|
||||
desc "The array containing the list of stonith devices"
|
||||
# FIXME: check for an array of strings
|
||||
end
|
||||
|
||||
## borrowed from exec.rb
|
||||
newparam(:tries) do
|
||||
desc "The number of times to attempt to create a pcs resource.
|
||||
Defaults to '1'."
|
||||
|
||||
munge do |value|
|
||||
if value.is_a?(String)
|
||||
unless value =~ /^[\d]+$/
|
||||
raise ArgumentError, "Tries must be an integer"
|
||||
end
|
||||
value = Integer(value)
|
||||
end
|
||||
raise ArgumentError, "Tries must be an integer >= 1" if value < 1
|
||||
value
|
||||
end
|
||||
|
||||
defaultto 1
|
||||
end
|
||||
|
||||
newparam(:try_sleep) do
|
||||
desc "The time to sleep in seconds between 'tries'."
|
||||
|
||||
munge do |value|
|
||||
if value.is_a?(String)
|
||||
unless value =~ /^[-\d.]+$/
|
||||
raise ArgumentError, "try_sleep must be a number"
|
||||
end
|
||||
value = Float(value)
|
||||
end
|
||||
raise ArgumentError, "try_sleep cannot be a negative number" if value < 0
|
||||
value
|
||||
end
|
||||
|
||||
defaultto 0
|
||||
end
|
||||
|
||||
newparam(:verify_on_create, :boolean => true, :parent => Puppet::Parameter::Boolean) do
|
||||
desc "Whether to verify pcs resource creation with an additional
|
||||
call to 'pcs resource show' rather than just relying on the exit
|
||||
status of 'pcs resource create'. When true, $try_sleep
|
||||
determines how long to wait to verify and $post_success_sleep is
|
||||
ignored. Defaults to `false`."
|
||||
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newparam(:post_success_sleep) do
|
||||
desc "The time to sleep after successful pcs action. The reason to set
|
||||
this is to avoid immediate back-to-back 'pcs resource create' calls
|
||||
when creating multiple resources. Defaults to '0'."
|
||||
|
||||
munge do |value|
|
||||
if value.is_a?(String)
|
||||
unless value =~ /^[-\d.]+$/
|
||||
raise ArgumentError, "post_success_sleep must be a number"
|
||||
end
|
||||
value = Float(value)
|
||||
end
|
||||
raise ArgumentError, "post_success_sleep cannot be a negative number" if value < 0
|
||||
value
|
||||
end
|
||||
|
||||
defaultto 0
|
||||
end
|
||||
end
|
90
manifests/stonith/level.pp
Normal file
90
manifests/stonith/level.pp
Normal file
@ -0,0 +1,90 @@
|
||||
# == Define: pacemaker::stonith::level
|
||||
#
|
||||
# A resource type to create pacemaker stonith levels
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*level*]
|
||||
# (required) The stonith level
|
||||
#
|
||||
# [*target*]
|
||||
# (required) The stonith level target
|
||||
#
|
||||
# [*stonith_resources*]
|
||||
# (required) Array containing the list of stonith devices
|
||||
#
|
||||
# [*ensure*]
|
||||
# (optional) Whether to make sure resource is created or removed
|
||||
# Defaults to present
|
||||
#
|
||||
# [*post_success_sleep*]
|
||||
# (optional) How long to wait acfter successful action
|
||||
# Defaults to 0
|
||||
#
|
||||
# [*tries*]
|
||||
# (optional) How many times to attempt to perform the action
|
||||
# Defaults to 1
|
||||
#
|
||||
# [*try_sleep*]
|
||||
# (optional) How long to wait between tries
|
||||
# Defaults to 0
|
||||
#
|
||||
# [*verify_on_create*]
|
||||
# (optional) Whether to verify creation of resource
|
||||
# Defaults to false
|
||||
#
|
||||
# === Dependencies
|
||||
#
|
||||
# None
|
||||
#
|
||||
# === Authors
|
||||
#
|
||||
# Michele Baldessari <michele@acksyn.org>
|
||||
#
|
||||
# === Copyright
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
define pacemaker::stonith::level(
|
||||
$level,
|
||||
$target,
|
||||
$stonith_resources,
|
||||
$ensure = 'present',
|
||||
$post_success_sleep = 0,
|
||||
$tries = 1,
|
||||
$try_sleep = 0,
|
||||
$verify_on_create = false,
|
||||
) {
|
||||
if $level == undef {
|
||||
fail('Must provide level')
|
||||
}
|
||||
if $target == undef {
|
||||
fail('Must provide target')
|
||||
}
|
||||
if $stonith_resources == undef {
|
||||
fail('Must provide stonith_resources')
|
||||
}
|
||||
$res = join($stonith_resources, '_')
|
||||
pcmk_stonith_level{ "stonith-level-${level}-${target}-${res}":
|
||||
ensure => $ensure,
|
||||
level => $level,
|
||||
target => $target,
|
||||
stonith_resources => $stonith_resources,
|
||||
post_success_sleep => $post_success_sleep,
|
||||
tries => $tries,
|
||||
try_sleep => $try_sleep,
|
||||
verify_on_create => $verify_on_create,
|
||||
}
|
||||
}
|
86
spec/defines/pacemaker_stonith_level_spec.rb
Normal file
86
spec/defines/pacemaker_stonith_level_spec.rb
Normal file
@ -0,0 +1,86 @@
|
||||
#
|
||||
# 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 'pacemaker::stonith::level', type: :define do
|
||||
|
||||
let(:title) { 'test' }
|
||||
|
||||
let(:pre_condition) { [
|
||||
'class pacemaker::corosync {}',
|
||||
'class { "pacemaker::corosync" : }'
|
||||
] }
|
||||
|
||||
|
||||
shared_examples_for 'pacemaker::stonith::level' do
|
||||
context 'with ensure absent' do
|
||||
let(:params) { {
|
||||
:ensure => 'absent',
|
||||
:level => '1',
|
||||
:target => 'node-foo',
|
||||
:stonith_resources => ['ipmi-node-foo','fence-bar'],
|
||||
:tries => 1,
|
||||
:try_sleep => 5,
|
||||
:verify_on_create => false,
|
||||
} }
|
||||
it {
|
||||
is_expected.to contain_pcmk_stonith_level("stonith-level-1-node-foo-ipmi-node-foo_fence-bar").with(
|
||||
:ensure => 'absent',
|
||||
:level => '1',
|
||||
:target => 'node-foo',
|
||||
:stonith_resources => ['ipmi-node-foo','fence-bar'],
|
||||
:tries => 1,
|
||||
:try_sleep => 5,
|
||||
:verify_on_create => false,
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
context 'with params' do
|
||||
let(:params) { {
|
||||
:level => '1',
|
||||
:target => 'node-foo',
|
||||
:stonith_resources => ['ipmi-node-foo','fence-bar'],
|
||||
:tries => 1,
|
||||
:try_sleep => 5,
|
||||
:verify_on_create => false,
|
||||
} }
|
||||
|
||||
it {
|
||||
is_expected.to contain_pcmk_stonith_level("stonith-level-1-node-foo-ipmi-node-foo_fence-bar").with(
|
||||
:ensure => 'present',
|
||||
:level => '1',
|
||||
:target => 'node-foo',
|
||||
:stonith_resources => ['ipmi-node-foo','fence-bar'],
|
||||
:tries => 1,
|
||||
:try_sleep => 5,
|
||||
:verify_on_create => false,
|
||||
)
|
||||
}
|
||||
|
||||
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 'pacemaker::stonith::level'
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user