Add initial provider from connectivity-checker-plugin

Change-Id: I8a94b2707292b3e3a226835ec19acd3e1524b1dd
blueprint: graph-concept-extension
(cherry picked from commit 23faf225d9)
This commit is contained in:
Sergey Vasilenko 2016-08-19 16:46:10 +03:00 committed by Bulat Gaifullin
parent 6d8a7cbaf5
commit 931af23aab
3 changed files with 185 additions and 0 deletions

View File

@ -0,0 +1,91 @@
require 'yaml'
Puppet::Type.type(:connectivity_checker).provide(:threaded) do
defaultfor :kernel => :linux
commands :ping => 'ping' # not used, but accounted while default provider
def ensure
:absent
end
def ensure=(value)
# calculate host hash
network_scheme = @resource[:network_scheme]
network_metadata = @resource[:network_metadata]
actual_endpoints = network_scheme['endpoints'].reject{|k,v| v['IP'].empty? or v['IP'].include?('dhcp') or v['IP'] == 'none' or !v['IP'] }
roles_for_test = network_scheme['roles'].select{|k,v| actual_endpoints.keys.include?(v)}
# generate test-scheme for this node
test_scheme = {}
actual_endpoints.keys.each do |enp|
test_scheme[enp] = roles_for_test.select{|k,v| v==enp}.keys()
end
#puts test_scheme.to_yaml()
# process nodes from network_metadata and construct test plan, corresponded test_scheme
test_plan = {}
network_metadata['nodes'].each do |nodename, node_attrs|
net_roles = node_attrs['network_roles'].select{|k,v| roles_for_test.include?(k)}
test_plan[nodename] = {}
test_scheme.each do |ntwrk, ntrls|
ipaddr = net_roles.select{|k,v| ntrls.include?(k)}.values.sort.uniq[0]
next if ipaddr.to_s == ''
test_plan[nodename][ntwrk] = {
:host => ipaddr,
:tries => @resource[:ping_tries],
:timeout => @resource[:ping_timeout],
}
end
end
#puts test_plan.to_yaml()
# test (ping) neighboors
work = {}
# fork per-host worker for parallel pinging.
test_plan.each do |nodename, networks|
work[nodename] = {}
work[nodename][:thr] = Thread.new(nodename, networks) do |nodename, networks|
#Thread.current[:nodename] = nodename
Thread.current[:errors] = []
networks.each do |netname, netattrs|
Thread.current[:cmd] = "ping -n -q -c #{netattrs[:tries]} -w #{netattrs[:timeout]} #{netattrs[:host]}"
Thread.current[:rc] = 0
if ! system(Thread.current[:cmd], {:out => :close, :err => :close})
Thread.current[:rc] = $?.exitstatus()
Thread.current[:errors] << {
:rc => Thread.current[:rc],
:cmd => "command `#{Thread.current[:cmd]}` was failed with code #{Thread.current[:rc]}",
:net => netname
}
end
end
end
end
# waitall only for all pinger threads
work.each do |nodename, rrr|
rrr[:thr].join()
end
# process results
err_report = {}
work.each do |nodename, rrr|
if ! rrr[:thr][:errors].empty?
err_report[nodename] = []
rrr[:thr][:errors].each do |err|
err_report[nodename] << "Unaccessible through '#{err[:net]}', #{err[:cmd]}"
end
end
end
if ! err_report.empty?
msg = "Connectivity check error. Nodes: #{err_report.to_yaml.sub!('---','')}"
if @resource[:non_destructive].to_s == 'true'
warn(msg)
else
fail(msg)
end
end
return :present
end
end

View File

@ -0,0 +1,81 @@
Puppet::Type.newtype(:connectivity_checker) do
desc 'Ping an neighboor host\'s IPs through each existing network'
newparam(:name) do
desc 'Resource name. fake parameter.'
isnamevar
end
newproperty(:ensure) do
newvalues :present, :absent
defaultto :present
end
newparam(:network_scheme) do
desc 'Actual network_scheme hash from Hiera'
end
newparam(:network_metadata) do
desc 'Actual network_metadata hash from Hiera'
end
newparam(:non_destructive) do
desc "Define whether we should fail on connectivity issues"
newvalues(:true, :yes, :on, :false, :no, :off)
aliasvalue(:yes, :true)
aliasvalue(:on, :true)
aliasvalue(:no, :false)
aliasvalue(:off, :false)
defaultto :false
end
newparam(:ping_tries) do
desc "How tries to ping should be for success"
defaultto 5
validate do |val|
if val.to_i <= 0
raise ArgumentError, "ping_tries should be positive integer, not an '#{val}'"
end
end
munge do |val|
if val.to_i <= 5
val = 5
end
return val.to_i
end
end
newparam(:ping_timeout) do
desc "Timeout for each ping call"
defaultto 20
validate do |val|
if val.to_i <= 0
raise ArgumentError, "ping_timeout should be positive integer, not an '#{val}'"
end
end
end
# Up to future usage, check connectivity by huge packets, closest to
# interface MTU with noDF flag
#
# newparam(:use_huge_packets) do
# desc "Whether to bring the interface up"
# newvalues(:true, :yes, :on, :false, :no, :off)
# aliasvalue(:yes, :true)
# aliasvalue(:on, :true)
# aliasvalue(:no, :false)
# aliasvalue(:off, :false)
# defaultto :false
# end
#
# newparam(:fix_source_ipaddr) do
# desc "Whether the source IP should be fixed up to primary interface ipaddr"
# newvalues(:true, :yes, :on, :false, :no, :off)
# aliasvalue(:yes, :true)
# aliasvalue(:on, :true)
# aliasvalue(:no, :false)
# aliasvalue(:off, :false)
# defaultto :false
# end
end

View File

@ -0,0 +1,13 @@
notice('MODULAR: connectivity-checker.pp')
$plugin_name = 'connectivity_checker'
$plugin_settings = hiera_hash("${plugin_name}", {})
$task_deploy = hiera('task_deploy', false)
connectivity_checker { 'netconfig':
network_scheme => hiera_hash('network_scheme'),
network_metadata => hiera_hash('network_metadata'),
non_destructive => pick($plugin_settings['non_destructive'], false),
ping_tries => pick($plugin_settings['ping_tries'], 5),
ping_timeout => pick($plugin_settings['ping_timeout'], 20),
}