Puppet使用ENC报'Could not load external node results for'

因为Puppet同步采取了主动触发和定时同步两种策略,几乎每次的报错都是在定时同步时出现...

Puppet Server采用双主结构,Web ui使用Foreman,为了确定这个报错是出现在那台服务器上, 通过对源代码的log增加主机标记最终定位到了这个错误只是出现在一台服务器上...,出现的很偶然,但所有的错误标记中,都是它....

Level  Resource    message

err Puppet  Could not retrieve catalog from remote server: Error 400 on SERVER: Failed when searching for node xxx: 001。,Could not load external node results for xxx: undefined method `inject' for false:FalseClass ::--- false

notice  Puppet  Using cached catalog

err Puppet  Could not retrieve catalog; skipping run

最后面的 :: --- false    其中::是在log中追加的分解符,方便区分, --- false 是返回的output的信息..

在Puppet源代码中 , 通过indirector与enc相关的find方法中可以看到这个find方法接受一个参数 request

indirector/node/exec.rb

def find(request)

output = super or return nil

# Translate the output to ruby.

result = translate(request.key, output)

create_node(request.key, result)

end


output 是调用父方法的find

父方法的find会调用enc脚本获取返回值,如果失败或调用不成功则为Nil..

这时会继续通过translate方法,将yaml输出转为ruby的对象

如果output为nil,这时yaml在读取这个数据的时候就会抛出异常,异常就是收到的Puppet邮件告警的内容了。
 

def translate(name, output)

YAML.load(output).inject({}) do |hash, data|                                           

case data[0]                                                                         

when String                                                                           

hash[data[0].intern] = data[1]                                                     

when Symbol                                                                           

hash[data[0]] = data[1]                                                             

else                                                                                 

raise Puppet::Error, "key is a #{data[0].class}, not a string or symbol"           

end                                                                                   

hash                                                                                 

end                                                                                     

rescue => detail                                                                         

raise Puppet::Error, "001,Could not load external node results for #{name}: #{detail} ::#{output} "

end

罗嗦了一大堆,其实就是node.rb的脚本在通过api取参数的时候,没有获得200...导致的。

通过指向一个错误的WEB服务器地址,可以看到 开头--- false。。。。

[root@test puppet]# ruby node1.rb test

--- false

Error retrieving node test: Net::HTTPNotFound 

分析node.rb

def enc(certname)

foreman_url      = "#{url}/node/#{certname}?format=yml"

uri              = URI.parse(foreman_url)

req              = Net::HTTP::Get.new(uri.request_uri)

http            = Net::HTTP.new(uri.host, uri.port)

http.use_ssl    = uri.scheme == 'https'

if http.use_ssl?

if SETTINGS[:ssl_ca] && !SETTINGS[:ssl_ca].empty?

http.ca_file = SETTINGS[:ssl_ca]

http.verify_mode = OpenSSL::SSL::VERIFY_PEER

else

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

end

if SETTINGS[:ssl_cert] && !SETTINGS[:ssl_cert].empty? && SETTINGS[:ssl_key] && !SETTINGS[:ssl_key].empty?

http.cert = OpenSSL::X509::Certificate.new(File.read(SETTINGS[:ssl_cert]))

http.key  = OpenSSL::PKey::RSA.new(File.read(SETTINGS[:ssl_key]), nil)

end

end

res = http.start { |http| http.request(req) }

raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"

res.body

end


脚本的前面都是在构造一个http的对象...,直接看倒数第三行

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e8514e8feb7f69e744b3eaa410f818c4.html