1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
|
require 'openssl'
require 'puppet'
require 'puppet/parser/interpreter'
require 'puppet/sslcertificates'
require 'xmlrpc/server'
require 'yaml'
class Puppet::Network::Handler
class MasterError < Puppet::Error; end
class Master < Handler
desc "Puppet's configuration interface. Used for all interactions related to
generating client configurations."
include Puppet::Util
attr_accessor :ast
attr_reader :ca
@interface = XMLRPC::Service::Interface.new("puppetmaster") { |iface|
iface.add_method("string getconfig(string)")
iface.add_method("int freshness()")
}
# Tell a client whether there's a fresh config for it
def freshness(client = nil, clientip = nil)
client ||= Facter.value("hostname")
config_handler.version(client, clientip)
end
def initialize(hash = {})
args = {}
if hash[:Local]
@local = hash[:Local]
else
@local = false
end
args[:Local] = true
if hash.include?(:CA) and hash[:CA]
@ca = Puppet::SSLCertificates::CA.new()
else
@ca = nil
end
Puppet.debug("Creating interpreter")
# This is only used by the cfengine module, or if --loadclasses was
# specified in +puppet+.
if hash.include?(:Classes)
args[:Classes] = hash[:Classes]
end
@config_handler = Puppet::Network::Handler.handler(:configuration).new(args)
end
# Call our various handlers; this handler is getting deprecated.
def getconfig(facts, format = "marshal", client = nil, clientip = nil)
facts = decode_facts(facts)
client, clientip = clientname(client, clientip, facts)
# Pass the facts to the fact handler
Puppet::Node::Facts.new(client, facts).save unless local?
# And get the configuration from the config handler
config = nil
benchmark(:notice, "Compiled configuration for %s" % client) do
config = config_handler.configuration(client)
end
return translate(config.extract)
end
private
# Manipulate the client name as appropriate.
def clientname(name, ip, facts)
# Always use the hostname from Facter.
client = facts["hostname"]
clientip = facts["ipaddress"]
if Puppet[:node_name] == 'cert'
if name
client = name
end
if ip
clientip = ip
end
end
return client, clientip
end
def config_handler
unless defined? @config_handler
@config_handler = Puppet::Network::Handler.handler(:config).new :local => local?
end
@config_handler
end
#
def decode_facts(facts)
if @local
# we don't need to do anything, since we should already
# have raw objects
Puppet.debug "Our client is local"
else
Puppet.debug "Our client is remote"
begin
facts = YAML.load(CGI.unescape(facts))
rescue => detail
raise XMLRPC::FaultException.new(
1, "Could not rebuild facts"
)
end
end
return facts
end
# Translate our configuration appropriately for sending back to a client.
def translate(config)
if local?
config
else
CGI.escape(config.to_yaml(:UseBlock => true))
end
end
end
end
|