puppet 2.6.11 → 2.6.12
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +33 -0
- data/conf/redhat/puppet.spec +7 -4
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application/cert.rb +17 -3
- data/lib/puppet/application/kick.rb +0 -2
- data/lib/puppet/defaults.rb +52 -3
- data/lib/puppet/network/handler/ca.rb +16 -106
- data/lib/puppet/network/handler/master.rb +0 -3
- data/lib/puppet/network/handler/runner.rb +1 -0
- data/lib/puppet/ssl/certificate.rb +6 -0
- data/lib/puppet/ssl/certificate_authority.rb +86 -11
- data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
- data/lib/puppet/ssl/certificate_factory.rb +112 -91
- data/lib/puppet/ssl/certificate_request.rb +88 -1
- data/lib/puppet/ssl/host.rb +16 -3
- data/lib/puppet/type/file.rb +0 -1
- data/lib/puppet/util/command_line/puppetca +23 -2
- data/lib/puppet/util/monkey_patches.rb +69 -0
- data/lib/puppet/util/settings.rb +5 -0
- data/spec/integration/defaults_spec.rb +11 -0
- data/spec/integration/network/handler_spec.rb +1 -1
- data/spec/unit/configurer_spec.rb +2 -2
- data/spec/unit/network/handler/ca_spec.rb +86 -0
- data/spec/unit/ssl/certificate_authority/interface_spec.rb +92 -53
- data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
- data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
- data/spec/unit/ssl/certificate_request_spec.rb +62 -1
- data/spec/unit/ssl/certificate_spec.rb +31 -0
- data/spec/unit/ssl/host_spec.rb +44 -2
- data/spec/unit/util/settings_spec.rb +10 -0
- data/test/language/functions.rb +0 -1
- data/test/language/snippets.rb +0 -9
- data/test/lib/puppettest/exetest.rb +1 -1
- data/test/lib/puppettest/servertest.rb +0 -1
- data/test/rails/rails.rb +0 -1
- data/test/ral/type/filesources.rb +0 -60
- metadata +5 -34
- data/lib/puppet/network/client.rb +0 -179
- data/lib/puppet/network/client/ca.rb +0 -56
- data/lib/puppet/network/client/file.rb +0 -6
- data/lib/puppet/network/client/proxy.rb +0 -27
- data/lib/puppet/network/client/report.rb +0 -26
- data/lib/puppet/network/client/runner.rb +0 -10
- data/lib/puppet/network/client/status.rb +0 -4
- data/lib/puppet/network/http_server.rb +0 -3
- data/lib/puppet/network/http_server/mongrel.rb +0 -150
- data/lib/puppet/network/http_server/webrick.rb +0 -155
- data/lib/puppet/network/xmlrpc/client.rb +0 -211
- data/lib/puppet/sslcertificates.rb +0 -146
- data/lib/puppet/sslcertificates/ca.rb +0 -375
- data/lib/puppet/sslcertificates/certificate.rb +0 -255
- data/lib/puppet/sslcertificates/inventory.rb +0 -38
- data/lib/puppet/sslcertificates/monkey_patch.rb +0 -6
- data/lib/puppet/sslcertificates/support.rb +0 -146
- data/spec/integration/network/client_spec.rb +0 -19
- data/spec/unit/network/client_spec.rb +0 -45
- data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
- data/spec/unit/sslcertificates/ca_spec.rb +0 -110
- data/test/certmgr/certmgr.rb +0 -308
- data/test/certmgr/inventory.rb +0 -69
- data/test/certmgr/support.rb +0 -105
- data/test/network/client/ca.rb +0 -69
- data/test/network/client/dipper.rb +0 -34
- data/test/network/handler/ca.rb +0 -273
- data/test/network/server/mongrel_test.rb +0 -99
- data/test/network/server/webrick.rb +0 -128
- data/test/network/xmlrpc/client.rb +0 -45
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'puppet/network/client'
|
2
|
-
|
3
|
-
# Request a certificate from the remote system.
|
4
|
-
class Puppet::Network::Client::CA < Puppet::Network::Client
|
5
|
-
class InvalidCertificate < Puppet::Error; end
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
options = symbolize_options(options)
|
9
|
-
unless options.include?(:Server) or options.include?(:CA)
|
10
|
-
options[:Server] = Puppet[:ca_server]
|
11
|
-
options[:Port] = Puppet[:ca_port]
|
12
|
-
end
|
13
|
-
super(options)
|
14
|
-
end
|
15
|
-
|
16
|
-
# This client is really only able to request certificates for the
|
17
|
-
# current host. It uses the Puppet.settings settings to figure everything out.
|
18
|
-
def request_cert
|
19
|
-
Puppet.settings.use(:main, :ssl)
|
20
|
-
|
21
|
-
if cert = read_cert
|
22
|
-
return cert
|
23
|
-
end
|
24
|
-
|
25
|
-
begin
|
26
|
-
cert, cacert = @driver.getcert(csr.to_pem)
|
27
|
-
rescue => detail
|
28
|
-
puts detail.backtrace if Puppet[:trace]
|
29
|
-
raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
|
30
|
-
end
|
31
|
-
|
32
|
-
if cert.nil? or cert == ""
|
33
|
-
return nil
|
34
|
-
end
|
35
|
-
|
36
|
-
begin
|
37
|
-
@cert = OpenSSL::X509::Certificate.new(cert)
|
38
|
-
@cacert = OpenSSL::X509::Certificate.new(cacert)
|
39
|
-
rescue => detail
|
40
|
-
raise InvalidCertificate.new(
|
41
|
-
"Invalid certificate: #{detail}"
|
42
|
-
)
|
43
|
-
end
|
44
|
-
|
45
|
-
unless @cert.check_private_key(key)
|
46
|
-
raise InvalidCertificate, "Certificate does not match private key. Try 'puppetca --clean #{Puppet[:certname]}' on the server."
|
47
|
-
end
|
48
|
-
|
49
|
-
# Only write the cert out if it passes validating.
|
50
|
-
Puppet.settings.write(:hostcert) do |f| f.print cert end
|
51
|
-
Puppet.settings.write(:localcacert) do |f| f.print cacert end
|
52
|
-
|
53
|
-
@cert
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# unlike the other client classes (again, this design sucks) this class
|
2
|
-
# is basically just a proxy class -- it calls its methods on the driver
|
3
|
-
# and that's about it
|
4
|
-
class Puppet::Network::Client::ProxyClient < Puppet::Network::Client
|
5
|
-
def self.mkmethods
|
6
|
-
interface = self.handler.interface
|
7
|
-
namespace = interface.prefix
|
8
|
-
|
9
|
-
|
10
|
-
interface.methods.each { |ary|
|
11
|
-
method = ary[0]
|
12
|
-
Puppet.debug "#{self}: defining #{namespace}.#{method}"
|
13
|
-
define_method(method) { |*args|
|
14
|
-
begin
|
15
|
-
@driver.send(method, *args)
|
16
|
-
rescue XMLRPC::FaultException => detail
|
17
|
-
#Puppet.err "Could not call %s.%s: %s" %
|
18
|
-
# [namespace, method, detail.faultString]
|
19
|
-
#raise NetworkClientError,
|
20
|
-
# "XMLRPC Error: #{detail.faultString}"
|
21
|
-
raise NetworkClientError, detail.faultString
|
22
|
-
end
|
23
|
-
}
|
24
|
-
}
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class Puppet::Network::Client::Report < Puppet::Network::Client
|
2
|
-
@handler = Puppet::Network::Handler.handler(:report)
|
3
|
-
|
4
|
-
def initialize(hash = {})
|
5
|
-
hash[:Report] = self.class.handler.new if hash.include?(:Report)
|
6
|
-
|
7
|
-
super(hash)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Send our report. We get the transaction report and convert it to YAML
|
11
|
-
# as appropriate.
|
12
|
-
def report(transreport)
|
13
|
-
report = YAML.dump(transreport)
|
14
|
-
|
15
|
-
report = CGI.escape(report) unless self.local
|
16
|
-
|
17
|
-
# Now send the report
|
18
|
-
file = nil
|
19
|
-
benchmark(:info, "Sent transaction report") do
|
20
|
-
file = @driver.report(report)
|
21
|
-
end
|
22
|
-
|
23
|
-
file
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
@@ -1,150 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# File: 06-11-14-mongrel_xmlrpc.rb
|
3
|
-
# Author: Manuel Holtgrewe <purestorm at ggnore.net>
|
4
|
-
#
|
5
|
-
# Copyright (c) 2006 Manuel Holtgrewe, 2007 Luke Kanies
|
6
|
-
#
|
7
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
8
|
-
# a copy of this software and associated documentation files (the
|
9
|
-
# "Software"), to deal in the Software without restriction, including
|
10
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
11
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
13
|
-
# the following conditions:
|
14
|
-
#
|
15
|
-
# The above copyright notice and this permission notice shall be
|
16
|
-
# included in all copies or substantial portions of the Software.
|
17
|
-
#
|
18
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
22
|
-
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
23
|
-
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
24
|
-
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
-
# SOFTWARE.
|
26
|
-
|
27
|
-
# This file is based heavily on a file retrieved from
|
28
|
-
# http://ttt.ggnore.net/2006/11/15/xmlrpc-with-mongrel-and-ruby-off-rails/
|
29
|
-
|
30
|
-
require 'rubygems'
|
31
|
-
require 'mongrel'
|
32
|
-
require 'xmlrpc/server'
|
33
|
-
require 'puppet/network/xmlrpc/server'
|
34
|
-
require 'puppet/network/http_server'
|
35
|
-
require 'puppet/network/client_request'
|
36
|
-
require 'puppet/network/handler'
|
37
|
-
|
38
|
-
require 'resolv'
|
39
|
-
|
40
|
-
# This handler can be hooked into Mongrel to accept HTTP requests. After
|
41
|
-
# checking whether the request itself is sane, the handler forwards it
|
42
|
-
# to an internal instance of XMLRPC::BasicServer to process it.
|
43
|
-
#
|
44
|
-
# You can access the server by calling the Handler's "xmlrpc_server"
|
45
|
-
# attribute accessor method and add XMLRPC handlers there. For example:
|
46
|
-
#
|
47
|
-
# <pre>
|
48
|
-
# handler = XmlRpcHandler.new
|
49
|
-
# handler.xmlrpc_server.add_handler("my.add") { |a, b| a.to_i + b.to_i }
|
50
|
-
# </pre>
|
51
|
-
module Puppet::Network
|
52
|
-
class HTTPServer::Mongrel < ::Mongrel::HttpHandler
|
53
|
-
attr_reader :xmlrpc_server
|
54
|
-
|
55
|
-
def initialize(handlers)
|
56
|
-
if Puppet[:debug]
|
57
|
-
$mongrel_debug_client = true
|
58
|
-
Puppet.debug 'Mongrel client debugging enabled. [$mongrel_debug_client = true].'
|
59
|
-
end
|
60
|
-
# Create a new instance of BasicServer. We are supposed to subclass it
|
61
|
-
# but that does not make sense since we would not introduce any new
|
62
|
-
# behaviour and we have to subclass Mongrel::HttpHandler so our handler
|
63
|
-
# works for Mongrel.
|
64
|
-
@xmlrpc_server = Puppet::Network::XMLRPCServer.new
|
65
|
-
handlers.each do |name|
|
66
|
-
unless handler = Puppet::Network::Handler.handler(name)
|
67
|
-
raise ArgumentError, "Invalid handler #{name}"
|
68
|
-
end
|
69
|
-
@xmlrpc_server.add_handler(handler.interface, handler.new({}))
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# This method produces the same results as XMLRPC::CGIServer.serve
|
74
|
-
# from Ruby's stdlib XMLRPC implementation.
|
75
|
-
def process(request, response)
|
76
|
-
# Make sure this has been a POST as required for XMLRPC.
|
77
|
-
request_method = request.params[Mongrel::Const::REQUEST_METHOD] || Mongrel::Const::GET
|
78
|
-
if request_method != "POST"
|
79
|
-
response.start(405) { |head, out| out.write("Method Not Allowed") }
|
80
|
-
return
|
81
|
-
end
|
82
|
-
|
83
|
-
# Make sure the user has sent text/xml data.
|
84
|
-
request_mime = request.params["CONTENT_TYPE"] || "text/plain"
|
85
|
-
if parse_content_type(request_mime).first != "text/xml"
|
86
|
-
response.start(400) { |head, out| out.write("Bad Request") }
|
87
|
-
return
|
88
|
-
end
|
89
|
-
|
90
|
-
# Make sure there is data in the body at all.
|
91
|
-
length = request.params[Mongrel::Const::CONTENT_LENGTH].to_i
|
92
|
-
if length <= 0
|
93
|
-
response.start(411) { |head, out| out.write("Length Required") }
|
94
|
-
return
|
95
|
-
end
|
96
|
-
|
97
|
-
# Check the body to be valid.
|
98
|
-
if request.body.nil? or request.body.size != length
|
99
|
-
response.start(400) { |head, out| out.write("Bad Request") }
|
100
|
-
return
|
101
|
-
end
|
102
|
-
|
103
|
-
info = client_info(request)
|
104
|
-
|
105
|
-
# All checks above passed through
|
106
|
-
response.start(200) do |head, out|
|
107
|
-
head["Content-Type"] = "text/xml; charset=utf-8"
|
108
|
-
begin
|
109
|
-
out.write(@xmlrpc_server.process(request.body, info))
|
110
|
-
rescue => detail
|
111
|
-
puts detail.backtrace
|
112
|
-
raise
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def client_info(request)
|
120
|
-
params = request.params
|
121
|
-
ip = params["HTTP_X_FORWARDED_FOR"] ? params["HTTP_X_FORWARDED_FOR"].split(',').last.strip : params["REMOTE_ADDR"]
|
122
|
-
# JJM #906 The following dn.match regular expression is forgiving
|
123
|
-
# enough to match the two Distinguished Name string contents
|
124
|
-
# coming from Apache, Pound or other reverse SSL proxies.
|
125
|
-
if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
|
126
|
-
client = dn_matchdata[1].to_str
|
127
|
-
valid = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
|
128
|
-
else
|
129
|
-
begin
|
130
|
-
client = Resolv.getname(ip)
|
131
|
-
rescue => detail
|
132
|
-
Puppet.err "Could not resolve #{ip}: #{detail}"
|
133
|
-
client = "unknown"
|
134
|
-
end
|
135
|
-
valid = false
|
136
|
-
end
|
137
|
-
|
138
|
-
info = Puppet::Network::ClientRequest.new(client, ip, valid)
|
139
|
-
|
140
|
-
info
|
141
|
-
end
|
142
|
-
|
143
|
-
# Taken from XMLRPC::ParseContentType
|
144
|
-
def parse_content_type(str)
|
145
|
-
a, *b = str.split(";")
|
146
|
-
return a.strip, *b
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
@@ -1,155 +0,0 @@
|
|
1
|
-
require 'puppet'
|
2
|
-
require 'webrick'
|
3
|
-
require 'webrick/https'
|
4
|
-
require 'fcntl'
|
5
|
-
|
6
|
-
require 'puppet/sslcertificates/support'
|
7
|
-
require 'puppet/network/xmlrpc/webrick_servlet'
|
8
|
-
require 'puppet/network/http_server'
|
9
|
-
require 'puppet/network/client'
|
10
|
-
require 'puppet/network/handler'
|
11
|
-
|
12
|
-
module Puppet
|
13
|
-
class ServerError < RuntimeError; end
|
14
|
-
module Network
|
15
|
-
# The old-school, pure ruby webrick server, which is the default serving
|
16
|
-
# mechanism.
|
17
|
-
class HTTPServer::WEBrick < WEBrick::HTTPServer
|
18
|
-
include Puppet::SSLCertificates::Support
|
19
|
-
|
20
|
-
# Read the CA cert and CRL and populate an OpenSSL::X509::Store
|
21
|
-
# with them, with flags appropriate for checking client
|
22
|
-
# certificates for revocation
|
23
|
-
def x509store
|
24
|
-
unless File.exist?(Puppet[:cacrl])
|
25
|
-
# No CRL, no store needed
|
26
|
-
return nil
|
27
|
-
end
|
28
|
-
crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
|
29
|
-
store = OpenSSL::X509::Store.new
|
30
|
-
store.purpose = OpenSSL::X509::PURPOSE_ANY
|
31
|
-
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
|
32
|
-
raise Puppet::Error, "Could not find CA certificate" unless self.ca_cert
|
33
|
-
|
34
|
-
store.add_file(Puppet[:localcacert])
|
35
|
-
store.add_crl(crl)
|
36
|
-
store
|
37
|
-
end
|
38
|
-
|
39
|
-
# Set up the http log.
|
40
|
-
def httplog
|
41
|
-
args = []
|
42
|
-
|
43
|
-
# yuck; separate http logs
|
44
|
-
file = nil
|
45
|
-
Puppet.settings.use(:main, :ssl, Puppet[:name])
|
46
|
-
if Puppet.run_mode.master?
|
47
|
-
file = Puppet[:masterhttplog]
|
48
|
-
else
|
49
|
-
file = Puppet[:httplog]
|
50
|
-
end
|
51
|
-
|
52
|
-
# open the log manually to prevent file descriptor leak
|
53
|
-
file_io = open(file, "a+")
|
54
|
-
file_io.sync
|
55
|
-
file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
56
|
-
|
57
|
-
args << file_io
|
58
|
-
args << WEBrick::Log::DEBUG if Puppet[:debug]
|
59
|
-
|
60
|
-
log = WEBrick::Log.new(*args)
|
61
|
-
|
62
|
-
|
63
|
-
log
|
64
|
-
end
|
65
|
-
|
66
|
-
# Create our server, yo.
|
67
|
-
def initialize(hash = {})
|
68
|
-
Puppet.info "Starting server for Puppet version #{Puppet.version}"
|
69
|
-
|
70
|
-
if handlers = hash[:Handlers]
|
71
|
-
handler_instances = setup_handlers(handlers)
|
72
|
-
else
|
73
|
-
raise ServerError, "A server must have handlers"
|
74
|
-
end
|
75
|
-
|
76
|
-
unless self.read_cert
|
77
|
-
if ca = handler_instances.find { |handler| handler.is_a?(Puppet::Network::Handler.ca) }
|
78
|
-
request_cert(ca)
|
79
|
-
else
|
80
|
-
raise Puppet::Error, "No certificate and no CA; cannot get cert"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
setup_webrick(hash)
|
85
|
-
|
86
|
-
begin
|
87
|
-
super(hash)
|
88
|
-
rescue => detail
|
89
|
-
puts detail.backtrace if Puppet[:trace]
|
90
|
-
raise Puppet::Error, "Could not start WEBrick: #{detail}"
|
91
|
-
end
|
92
|
-
|
93
|
-
# make sure children don't inherit the sockets
|
94
|
-
listeners.each { |sock|
|
95
|
-
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
96
|
-
}
|
97
|
-
|
98
|
-
Puppet.info "Listening on port #{hash[:Port]}"
|
99
|
-
|
100
|
-
# this creates a new servlet for every connection,
|
101
|
-
# but all servlets have the same list of handlers
|
102
|
-
# thus, the servlets can have their own state -- passing
|
103
|
-
# around the requests and such -- but the handlers
|
104
|
-
# have a global state
|
105
|
-
|
106
|
-
# mount has to be called after the server is initialized
|
107
|
-
servlet = Puppet::Network::XMLRPC::WEBrickServlet.new( handler_instances)
|
108
|
-
self.mount("/RPC2", servlet)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Create a ca client to set up our cert for us.
|
112
|
-
def request_cert(ca)
|
113
|
-
client = Puppet::Network::Client.ca.new(:CA => ca)
|
114
|
-
raise Puppet::Error, "Could get certificate" unless client.request_cert
|
115
|
-
end
|
116
|
-
|
117
|
-
# Create all of our handler instances.
|
118
|
-
def setup_handlers(handlers)
|
119
|
-
raise ServerError, "Handlers must have arguments" unless handlers.is_a?(Hash)
|
120
|
-
|
121
|
-
handlers.collect { |handler, args|
|
122
|
-
hclass = nil
|
123
|
-
unless hclass = Puppet::Network::Handler.handler(handler)
|
124
|
-
raise ServerError, "Invalid handler #{handler}"
|
125
|
-
end
|
126
|
-
hclass.new(args)
|
127
|
-
}
|
128
|
-
end
|
129
|
-
|
130
|
-
# Handle all of the many webrick arguments.
|
131
|
-
def setup_webrick(hash)
|
132
|
-
hash[:Port] ||= Puppet[:masterport]
|
133
|
-
hash[:Logger] ||= self.httplog
|
134
|
-
hash[:AccessLog] ||= [
|
135
|
-
[ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
|
136
|
-
[ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
|
137
|
-
]
|
138
|
-
|
139
|
-
hash[:SSLCertificateStore] = x509store
|
140
|
-
hash[:SSLCertificate] = self.cert
|
141
|
-
hash[:SSLPrivateKey] = self.key
|
142
|
-
hash[:SSLStartImmediately] = true
|
143
|
-
hash[:SSLEnable] = true
|
144
|
-
hash[:SSLCACertificateFile] = Puppet[:localcacert]
|
145
|
-
hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
|
146
|
-
hash[:SSLCertName] = nil
|
147
|
-
|
148
|
-
if addr = Puppet[:bindaddress] and addr != ""
|
149
|
-
hash[:BindAddress] = addr
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|