49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/puppet/parser/functions/foreman.rb', line 49
newfunction(:foreman, :type => :rvalue) do |args|
raise Puppet::ParseError, "Foreman: Must supply a Hash to foreman(), not a #{args[0].class}" unless args[0].is_a? Hash
args_hash = args[0]
item = args_hash["item"]
search = args_hash["search"]
per_page = args_hash["per_page"] || "20"
use_tfmproxy = args_hash["use_tfmproxy"] || false
foreman_url = args_hash["foreman_url"] || "https://localhost" foreman_user = args_hash["foreman_user"] || "admin" foreman_pass = args_hash["foreman_pass"] || "changeme" filter_result = args_hash['filter_result'] || false
timeout = (args_hash['timeout'] || 5).to_i
searchable_items = %w{ environments fact_values hosts hostgroups puppetclasses smart_proxies subnets }
raise Puppet::ParseError, "Foreman: Invalid item to search on: #{item}, must be one of #{searchable_items.join(", ")}." unless searchable_items.include?(item)
raise Puppet::ParseError, "Foreman: Invalid filter_result: #{filter_result}, must be a String or an Array" unless filter_result.is_a? String or filter_result.is_a? Array or filter_result.is_a? Hash or filter_result == false
begin
path = "/api/#{CGI.escape(item)}?search=#{CGI.escape(search)}&per_page=#{CGI.escape(per_page)}"
req = Net::HTTP::Get.new(path)
req['Content-Type'] = 'application/json'
req['Accept'] = 'application/json'
if use_tfmproxy
configfile = '/etc/foreman-proxy/settings.yml'
configfile = use_tfmproxy if use_tfmproxy.is_a? String
raise Puppet::ParseError, "File #{configfile} not found while use_tfmproxy is enabled" unless File.exists?(configfile)
tfmproxy = YAML.load(File.read(configfile))
uri = URI.parse(tfmproxy[:foreman_url])
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ca_file = tfmproxy[:foreman_ssl_ca]
http.cert = OpenSSL::X509::Certificate.new(File.read(tfmproxy[:foreman_ssl_cert]))
http.key = OpenSSL::PKey::RSA.new(File.read(tfmproxy[:foreman_ssl_key]), nil)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
else
uri = URI.parse(foreman_url)
http = Net::HTTP.new(uri.host, uri.port)
req.basic_auth(foreman_user, foreman_pass)
http.use_ssl = true if uri.scheme == 'https'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
end
results = Timeout::timeout(timeout) { PSON.parse http.request(req).body }
rescue Exception => e
raise Puppet::ParseError, "Failed to contact Foreman at #{foreman_url}: #{e}"
end
if filter_result != false and results.has_key?('results')
filtered_results = Array.new
if filter_result.is_a? String
results['results'].each do |result|
if result.has_key?(filter_result)
filtered_results << result[filter_result]
end
end
elsif filter_result.is_a? Array
results['results'].each do |result|
resulthash = Hash.new
result.each do |key,value|
if filter_result.include? key
resulthash[key] = result[key]
end
end
if resulthash != {}
filtered_results << resulthash
end
end
else
results['results'].each do |result|
resulthash = Hash.new
result.each do |key,value|
if filter_result.include? key
resulthash[filter_result[key]] = result[key]
end
end
if resulthash != {}
filtered_results << resulthash
end
end
end
return filtered_results
end
return results
end
|