fuel-library/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/url_available.rb

118 lines
4.1 KiB
Ruby

require 'pp'
require 'timeout'
require 'net/http'
require 'open-uri'
require 'uri'
module URI
# Define 'mirror:' scheme
class MIRROR < HTTP; end
@@schemes['MIRROR'] = MIRROR
end
Puppet::Parser::Functions::newfunction(:url_available, :arity => -2, :doc => <<-EOS
The url_available function attempts to make a http request to a url and throws
a puppet error if the URL is unavailable. The url_available function can take
up to two paramters. The first paramter is the URL which is required and can be
one of the following:
1) String - a single url string
3) Hash - a hash with the url set to the key of 'uri'
2) Array - an array of url strings or an array of hashes that match the
previous format.
The second paramter is a proxy url. It should be a valid uri and will be parsed
to ensure it is properly formated. It should be noted that if the url provided
to the url_available function is a hash, the proxy can be specified using a key
named 'proxy'. The hostname, port, username and password will be parsed from
this uri to be used when issuing a request via the proxy.
Examples:
# no proxy
url_available('http://www.google.com')
url_available(['http://www.google.com', 'http://www.mirantis.com'])
url_available({ 'uri' => 'http://www.google.com' })
url_available([{ 'uri' => 'http://www.google.com' },
{ 'uri' => 'http://www.mirantis.com' }]
# with a proxy
url_available('http://www.google.com', 'http://proxy.example.com:3128/')
url_available({ 'uri' => 'http://www.google.com',
'proxy' => 'http://proxy.example.com:3128'})
# with a proxy with authentication
url_available('http://www.google.com', 'http://user:pass@proxy.example.com:3128/')
url_available({ 'uri' => 'http://www.google.com',
'proxy' => 'http://user:pass@proxy.example.com:3128/'})
EOS
) do |argv|
url, http_proxy = argv
threads_count = 16
Thread.abort_on_exception=true
def fetch(url, http_proxy = nil)
# proxy variables, set later if http_proxy is provided or there is a proxy
# element provided as part of the a url that is a Hash
proxy_host = nil
proxy_port = nil
proxy_user = nil
proxy_pass = nil
# check the type of url being passed, if hash look for the uri key
if url.instance_of? Hash
uri = url.fetch 'uri', nil
http_proxy = url.fetch 'proxy', nil
elsif url.instance_of? String
uri = url
else
raise Puppet::ParseError, "Invalid url type passed to the url_available
function. Must be of type String or Hash."
end
# attempt to parse the proxy if it's not nil or a blank string
unless [nil, ''].include?(http_proxy)
begin
proxy = URI.parse(http_proxy)
proxy_host = proxy.host
proxy_port = proxy.port
proxy_user, proxy_pass = proxy.userinfo.split(/:/) if proxy.userinfo
rescue Exception => e
puts "Unable to parse proxy settings from '#{http_proxy}', will ignore proxy setting. Error '#{e}'"
end
end
puts "Checking #{uri}\n"
begin
out = Timeout::timeout(180) do
u = URI.parse(uri)
http = Net::HTTP.new(u.host, u.port, proxy_host, proxy_port, proxy_user, proxy_pass)
http.open_timeout = 60
http.read_timeout = 60
request = Net::HTTP::Get.new(u.request_uri)
response = http.request(request)
end
rescue OpenURI::HTTPError => error
raise Puppet::Error, "ERROR: Unable to fetch url '#{uri}', error '#{error.io}'. Please verify node connectivity to this URL, or remove it from the settings page if it is invalid."
rescue Exception => e
raise Puppet::Error, "ERROR: Unable to fetch url '#{uri}', error '#{e}'. Please verify node connectivity to this URL, or remove it from the settings page if it is invalid."
end
end
# if passed an array, iterate through the array an check each element
# within a thread pool equal to threads_count
if url.instance_of? Array
url.each_slice(threads_count) do |group|
threads = []
group.each do |u|
threads << Thread.new do
fetch(u, http_proxy)
end
end
threads.each(&:join)
end
else
fetch(url, http_proxy)
end
return true
end
# vim: set ts=2 sw=2 et :