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
132
133
134
135
136
137
138
139
140
141
|
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 = {}
# Allow specification of a code snippet or of a file
if code = hash[:Code]
args[:Code] = code
elsif man = hash[:Manifest]
args[:Manifest] = man
end
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")
if hash.include?(:UseNodes)
args[:UseNodes] = hash[:UseNodes]
elsif @local
args[:UseNodes] = false
end
# 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
# And get the configuration from the config handler
config = config_handler.configuration(client)
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
|