puppet 0.16.0 → 0.18.4
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 +98 -0
- data/Rakefile +5 -1
- data/bin/puppet +1 -1
- data/bin/puppetca +25 -11
- data/bin/puppetd +189 -66
- data/bin/puppetdoc +79 -62
- data/bin/puppetmasterd +93 -49
- data/bin/puppetrun +385 -0
- data/conf/redhat/client.init +5 -2
- data/conf/redhat/fileserver.conf +1 -1
- data/conf/redhat/lsb-config.patch +51 -0
- data/conf/redhat/puppet.spec +45 -18
- data/conf/redhat/puppetd.conf +32 -4
- data/conf/redhat/server.init +5 -2
- data/conf/solaris/pkginfo +7 -0
- data/conf/solaris/smf/puppetd.xml +77 -0
- data/conf/solaris/smf/puppetmasterd.xml +77 -0
- data/conf/solaris/smf/svc-puppetd +66 -0
- data/conf/solaris/smf/svc-puppetmasterd +62 -0
- data/examples/code/failers/noobjectrvalue +1 -0
- data/examples/code/snippets/deepclassheirarchy.pp +23 -0
- data/examples/code/snippets/defineoverrides.pp +17 -0
- data/examples/code/snippets/emptyexec.pp +3 -0
- data/examples/code/snippets/selectorvalues.pp +6 -1
- data/examples/code/snippets/tagged.pp +35 -0
- data/ext/ldap/puppet.schema +2 -2
- data/install.rb +4 -2
- data/lib/puppet.rb +206 -15
- data/lib/puppet/client.rb +30 -20
- data/lib/puppet/client/ca.rb +2 -2
- data/lib/puppet/client/dipper.rb +5 -9
- data/lib/puppet/client/master.rb +224 -44
- data/lib/puppet/client/pelement.rb +54 -9
- data/lib/puppet/client/proxy.rb +3 -2
- data/lib/puppet/client/reporter.rb +34 -0
- data/lib/puppet/client/runner.rb +17 -0
- data/lib/puppet/config.rb +136 -55
- data/lib/puppet/daemon.rb +59 -37
- data/lib/puppet/element.rb +2 -1
- data/lib/puppet/event.rb +14 -3
- data/lib/puppet/filetype.rb +28 -19
- data/lib/puppet/log.rb +297 -132
- data/lib/puppet/metric.rb +31 -131
- data/lib/puppet/networkclient.rb +73 -46
- data/lib/puppet/parameter.rb +49 -1
- data/lib/puppet/parsedfile.rb +32 -12
- data/lib/puppet/parser/ast.rb +6 -1
- data/lib/puppet/parser/ast/astarray.rb +32 -6
- data/lib/puppet/parser/ast/collection.rb +91 -0
- data/lib/puppet/parser/ast/compdef.rb +2 -2
- data/lib/puppet/parser/ast/component.rb +24 -11
- data/lib/puppet/parser/ast/function.rb +50 -0
- data/lib/puppet/parser/ast/hostclass.rb +70 -22
- data/lib/puppet/parser/ast/node.rb +17 -8
- data/lib/puppet/parser/ast/nodedef.rb +1 -1
- data/lib/puppet/parser/ast/objectdef.rb +28 -10
- data/lib/puppet/parser/ast/selector.rb +4 -1
- data/lib/puppet/parser/functions.rb +145 -0
- data/lib/puppet/parser/interpreter.rb +243 -86
- data/lib/puppet/parser/lexer.rb +5 -4
- data/lib/puppet/parser/parser.rb +586 -505
- data/lib/puppet/parser/scope.rb +337 -187
- data/lib/puppet/rails.rb +115 -0
- data/lib/puppet/rails/database.rb +40 -0
- data/lib/puppet/rails/host.rb +83 -0
- data/lib/puppet/rails/rails_object.rb +42 -0
- data/lib/puppet/rails/rails_parameter.rb +5 -0
- data/lib/puppet/reports/rrdgraph.rb +20 -0
- data/lib/puppet/reports/tagmail.rb +94 -0
- data/lib/puppet/server.rb +20 -4
- data/lib/puppet/server/authconfig.rb +14 -3
- data/lib/puppet/server/authstore.rb +2 -2
- data/lib/puppet/server/ca.rb +23 -11
- data/lib/puppet/server/filebucket.rb +10 -10
- data/lib/puppet/server/fileserver.rb +4 -8
- data/lib/puppet/server/master.rb +19 -22
- data/lib/puppet/server/pelement.rb +28 -16
- data/lib/puppet/server/report.rb +184 -0
- data/lib/puppet/server/runner.rb +62 -0
- data/lib/puppet/server/servlet.rb +23 -9
- data/lib/puppet/sslcertificates/ca.rb +25 -1
- data/lib/puppet/statechange.rb +34 -53
- data/lib/puppet/storage.rb +1 -2
- data/lib/puppet/transaction.rb +305 -133
- data/lib/puppet/transaction/report.rb +42 -0
- data/lib/puppet/transportable.rb +57 -33
- data/lib/puppet/type.rb +260 -127
- data/lib/puppet/type/component.rb +9 -21
- data/lib/puppet/type/cron.rb +367 -116
- data/lib/puppet/type/exec.rb +15 -16
- data/lib/puppet/type/group.rb +9 -1
- data/lib/puppet/type/nameservice.rb +2 -5
- data/lib/puppet/type/nameservice/netinfo.rb +3 -0
- data/lib/puppet/type/nameservice/objectadd.rb +23 -10
- data/lib/puppet/type/nameservice/pw.rb +16 -3
- data/lib/puppet/type/package.rb +25 -75
- data/lib/puppet/type/package/apple.rb +15 -1
- data/lib/puppet/type/package/apt.rb +37 -2
- data/lib/puppet/type/package/blastwave.rb +136 -0
- data/lib/puppet/type/package/dpkg.rb +4 -4
- data/lib/puppet/type/package/gem.rb +119 -0
- data/lib/puppet/type/package/openbsd.rb +7 -6
- data/lib/puppet/type/package/ports.rb +7 -2
- data/lib/puppet/type/package/rpm.rb +1 -1
- data/lib/puppet/type/package/sun.rb +23 -9
- data/lib/puppet/type/package/sunfreeware.rb +7 -0
- data/lib/puppet/type/package/yum.rb +16 -9
- data/lib/puppet/type/parsedtype.rb +7 -5
- data/lib/puppet/type/parsedtype/mount.rb +55 -34
- data/lib/puppet/type/parsedtype/port.rb +7 -1
- data/lib/puppet/type/parsedtype/sshkey.rb +6 -16
- data/lib/puppet/type/pfile.rb +115 -23
- data/lib/puppet/type/pfile/checksum.rb +18 -5
- data/lib/puppet/type/pfile/content.rb +2 -2
- data/lib/puppet/type/pfile/ensure.rb +3 -3
- data/lib/puppet/type/pfile/group.rb +2 -2
- data/lib/puppet/type/pfile/source.rb +28 -17
- data/lib/puppet/type/pfile/target.rb +25 -17
- data/lib/puppet/type/pfilebucket.rb +25 -6
- data/lib/puppet/type/schedule.rb +6 -6
- data/lib/puppet/type/service.rb +24 -14
- data/lib/puppet/type/service/debian.rb +1 -1
- data/lib/puppet/type/service/redhat.rb +13 -10
- data/lib/puppet/type/service/smf.rb +3 -3
- data/lib/puppet/type/state.rb +1 -2
- data/lib/puppet/type/symlink.rb +3 -4
- data/lib/puppet/type/user.rb +22 -10
- data/lib/puppet/type/yumrepo.rb +6 -1
- data/lib/puppet/type/zone.rb +595 -0
- data/lib/puppet/util.rb +58 -12
- data/test/client/client.rb +2 -2
- data/test/client/master.rb +92 -3
- data/test/client/pelement.rb +99 -0
- data/test/executables/puppetbin.rb +3 -4
- data/test/executables/puppetca.rb +3 -3
- data/test/executables/puppetd.rb +3 -3
- data/test/executables/puppetmasterd.rb +1 -5
- data/test/executables/puppetmodule.rb +2 -2
- data/test/language/ast.rb +200 -11
- data/test/language/functions.rb +245 -0
- data/test/language/interpreter.rb +155 -6
- data/test/language/lexer.rb +35 -2
- data/test/language/node.rb +48 -1
- data/test/language/parser.rb +250 -1
- data/test/language/rails.rb +105 -0
- data/test/language/scope.rb +304 -10
- data/test/language/snippets.rb +54 -5
- data/test/language/transportable.rb +60 -28
- data/test/other/config.rb +214 -1
- data/test/other/events.rb +67 -9
- data/test/other/log.rb +31 -5
- data/test/other/metrics.rb +23 -21
- data/test/other/parsedfile.rb +29 -2
- data/test/other/puppet.rb +79 -0
- data/test/other/report.rb +106 -0
- data/test/other/storage.rb +2 -2
- data/test/other/transactions.rb +128 -2
- data/test/puppet/utiltest.rb +10 -5
- data/test/puppettest.rb +193 -21
- data/test/server/authstore.rb +13 -4
- data/test/server/bucket.rb +33 -8
- data/test/server/ca.rb +44 -6
- data/test/server/master.rb +6 -7
- data/test/server/pelement.rb +15 -5
- data/test/server/report.rb +93 -0
- data/test/server/runner.rb +107 -0
- data/test/server/server.rb +28 -1
- data/test/types/cron.rb +339 -31
- data/test/types/file.rb +256 -24
- data/test/types/filebucket.rb +6 -2
- data/test/types/filesources.rb +41 -92
- data/test/types/group.rb +31 -1
- data/test/types/host.rb +2 -1
- data/test/types/mount.rb +18 -1
- data/test/types/package.rb +200 -18
- data/test/types/service.rb +5 -1
- data/test/types/sshkey.rb +2 -1
- data/test/types/symlink.rb +3 -2
- data/test/types/type.rb +180 -1
- data/test/types/user.rb +65 -27
- data/test/types/yumrepo.rb +15 -0
- data/test/types/zone.rb +437 -0
- metadata +43 -4
- data/bin/cf2puppet +0 -186
- data/conf/redhat/puppetmasterd.conf +0 -5
@@ -3,7 +3,7 @@ class Puppet::Parser::AST
|
|
3
3
|
# specified node, and this parse tree is only ever looked up when
|
4
4
|
# a client connects.
|
5
5
|
class NodeDef < AST::Branch
|
6
|
-
attr_accessor :names, :code, :parentclass, :keyword
|
6
|
+
attr_accessor :names, :code, :parentclass, :keyword, :scope
|
7
7
|
|
8
8
|
def each
|
9
9
|
[@names,@code].each { |child| yield child }
|
@@ -2,7 +2,7 @@ class Puppet::Parser::AST
|
|
2
2
|
# Any normal puppet object declaration. Can result in a class or a
|
3
3
|
# component, in addition to builtin types.
|
4
4
|
class ObjectDef < AST::Branch
|
5
|
-
attr_accessor :name, :type
|
5
|
+
attr_accessor :name, :type, :collectable
|
6
6
|
attr_reader :params
|
7
7
|
|
8
8
|
# probably not used at all
|
@@ -55,23 +55,40 @@ class Puppet::Parser::AST
|
|
55
55
|
raise error
|
56
56
|
end
|
57
57
|
|
58
|
+
hash = {}
|
59
|
+
# Evaluate all of the specified params.
|
60
|
+
@params.each { |param|
|
61
|
+
ary = param.safeevaluate(:scope => scope)
|
62
|
+
hash[ary[0]] = ary[1]
|
63
|
+
}
|
64
|
+
|
58
65
|
objnames = [nil]
|
59
|
-
#
|
66
|
+
# Determine our name if we have one.
|
60
67
|
if self.name
|
61
68
|
objnames = @name.safeevaluate(:scope => scope)
|
62
69
|
# it's easier to always use an array, even for only one name
|
63
70
|
unless objnames.is_a?(Array)
|
64
71
|
objnames = [objnames]
|
65
72
|
end
|
66
|
-
|
73
|
+
else
|
74
|
+
# See if they specified the name as a parameter instead of as a
|
75
|
+
# normal name (i.e., before the colon).
|
76
|
+
unless object # we're a builtin
|
77
|
+
if objclass = Puppet::Type.type(objtype)
|
78
|
+
namevar = objclass.namevar
|
67
79
|
|
68
|
-
|
80
|
+
tmp = hash["name"] || hash[namevar.to_s]
|
69
81
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
if tmp
|
83
|
+
objnames = [tmp]
|
84
|
+
end
|
85
|
+
else
|
86
|
+
# this should never happen, because we've already
|
87
|
+
# typechecked, but it's no real problem if it does happen.
|
88
|
+
# We just end up with an object with no name.
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
75
92
|
|
76
93
|
# this is where our implicit iteration takes place;
|
77
94
|
# if someone passed an array as the name, then we act
|
@@ -91,7 +108,8 @@ class Puppet::Parser::AST
|
|
91
108
|
:name => objname,
|
92
109
|
:arguments => hash,
|
93
110
|
:file => @file,
|
94
|
-
:line => @line
|
111
|
+
:line => @line,
|
112
|
+
:collectable => self.collectable
|
95
113
|
)
|
96
114
|
rescue Puppet::ParseError => except
|
97
115
|
except.line = self.line
|
@@ -19,7 +19,10 @@ class Puppet::Parser::AST
|
|
19
19
|
|
20
20
|
default = nil
|
21
21
|
|
22
|
-
|
22
|
+
#@values = [@values] unless @values.instance_of? AST::ASTArray
|
23
|
+
unless @values.instance_of? AST::ASTArray or @values.instance_of? Array
|
24
|
+
@values = [@values]
|
25
|
+
end
|
23
26
|
|
24
27
|
# Then look for a match in the options.
|
25
28
|
@values.each { |obj|
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Grr
|
2
|
+
require 'puppet/parser/scope'
|
3
|
+
|
4
|
+
module Puppet::Parser
|
5
|
+
module Functions
|
6
|
+
# A module for managing parser functions. Each specified function
|
7
|
+
# becomes an instance method on the Scope class.
|
8
|
+
|
9
|
+
# Create a new function type.
|
10
|
+
def self.newfunction(name, ftype = :statement, &block)
|
11
|
+
@functions ||= {}
|
12
|
+
name = name.intern if name.is_a? String
|
13
|
+
|
14
|
+
if @functions.include? name
|
15
|
+
raise Puppet::DevError, "Function %s already defined" % name
|
16
|
+
end
|
17
|
+
|
18
|
+
# We want to use a separate, hidden module, because we don't want
|
19
|
+
# people to be able to call them directly.
|
20
|
+
unless defined? FCollection
|
21
|
+
eval("module FCollection; end")
|
22
|
+
end
|
23
|
+
|
24
|
+
unless ftype == :statement or ftype == :rvalue
|
25
|
+
raise Puppet::DevError, "Invalid statement type %s" % ftype.inspect
|
26
|
+
end
|
27
|
+
|
28
|
+
fname = "function_" + name.to_s
|
29
|
+
Puppet::Parser::Scope.send(:define_method, fname, &block)
|
30
|
+
|
31
|
+
# Someday we'll support specifying an arity, but for now, nope
|
32
|
+
#@functions[name] = {:arity => arity, :type => ftype}
|
33
|
+
@functions[name] = {:type => ftype, :name => fname}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Determine if a given name is a function
|
37
|
+
def self.function(name)
|
38
|
+
name = name.intern if name.is_a? String
|
39
|
+
|
40
|
+
if @functions.include? name
|
41
|
+
return @functions[name][:name]
|
42
|
+
else
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Determine if a given function returns a value or not.
|
48
|
+
def self.rvalue?(name)
|
49
|
+
name = name.intern if name.is_a? String
|
50
|
+
|
51
|
+
if @functions.include? name
|
52
|
+
case @functions[name][:type]
|
53
|
+
when :statement: return false
|
54
|
+
when :rvalue: return true
|
55
|
+
end
|
56
|
+
else
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Include the specified classes
|
62
|
+
newfunction(:include) do |vals|
|
63
|
+
vals.each do |val|
|
64
|
+
if objecttype = lookuptype(val)
|
65
|
+
# It's a defined type, so set it into the scope so it can
|
66
|
+
# be evaluated.
|
67
|
+
setobject(
|
68
|
+
:type => val,
|
69
|
+
:arguments => {}
|
70
|
+
)
|
71
|
+
else
|
72
|
+
raise Puppet::ParseError, "Unknown class %s" % val
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Tag the current scope with each passed name
|
78
|
+
newfunction(:tag) do |vals|
|
79
|
+
vals.each do |val|
|
80
|
+
# Some hackery, because the tags are stored by object id
|
81
|
+
# for singletonness.
|
82
|
+
self.setclass(val.object_id, val)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Also add them as tags
|
86
|
+
self.tag(*vals)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Test whether a given tag is set. This functions as a big OR -- if any of the
|
90
|
+
# specified tags are unset, we return false.
|
91
|
+
newfunction(:tagged, :rvalue) do |vals|
|
92
|
+
classlist = self.classlist
|
93
|
+
|
94
|
+
retval = true
|
95
|
+
vals.each do |val|
|
96
|
+
unless classlist.include?(val) or self.tags.include?(val)
|
97
|
+
retval = false
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
return retval
|
103
|
+
end
|
104
|
+
|
105
|
+
# Test whether a given class or definition is defined
|
106
|
+
newfunction(:defined, :rvalue) do |vals|
|
107
|
+
retval = true
|
108
|
+
|
109
|
+
vals.each do |val|
|
110
|
+
unless builtintype?(val) or lookuptype(val)
|
111
|
+
retval = false
|
112
|
+
break
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
return retval
|
117
|
+
end
|
118
|
+
|
119
|
+
newfunction(:fail, :statement) do |vals|
|
120
|
+
vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
|
121
|
+
raise Puppet::ParseError, vals.to_s
|
122
|
+
end
|
123
|
+
|
124
|
+
newfunction(:template, :rvalue) do |vals|
|
125
|
+
require 'erb'
|
126
|
+
|
127
|
+
vals.collect do |file|
|
128
|
+
# Use a wrapper, so the template can't get access to the full
|
129
|
+
# Scope object.
|
130
|
+
debug "Retrieving template %s" % file
|
131
|
+
wrapper = Puppet::Parser::Scope::TemplateWrapper.new(self, file)
|
132
|
+
|
133
|
+
begin
|
134
|
+
wrapper.result()
|
135
|
+
rescue => detail
|
136
|
+
raise Puppet::ParseError,
|
137
|
+
"Failed to parse template %s: %s" %
|
138
|
+
[file, detail]
|
139
|
+
end
|
140
|
+
end.join("")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# $Id: functions.rb 1383 2006-07-11 16:52:20Z luke $
|
@@ -15,6 +15,14 @@ module Puppet
|
|
15
15
|
Puppet.setdefaults("ldap",
|
16
16
|
:ldapnodes => [false,
|
17
17
|
"Whether to search for node configurations in LDAP."],
|
18
|
+
:ldapssl => [false,
|
19
|
+
"Whether SSL should be used when searching for nodes.
|
20
|
+
Defaults to false because SSL usually requires certificates
|
21
|
+
to be set up on the client side."],
|
22
|
+
:ldaptls => [false,
|
23
|
+
"Whether TLS should be used when searching for nodes.
|
24
|
+
Defaults to false because TLS usually requires certificates
|
25
|
+
to be set up on the client side."],
|
18
26
|
:ldapserver => ["ldap",
|
19
27
|
"The LDAP server. Only used if ``ldapnodes`` is enabled."],
|
20
28
|
:ldapport => [389,
|
@@ -38,10 +46,41 @@ module Puppet
|
|
38
46
|
branch under your main directory."]
|
39
47
|
)
|
40
48
|
|
41
|
-
|
49
|
+
Puppet.setdefaults(:puppetmaster,
|
50
|
+
:storeconfigs => [false,
|
51
|
+
"Whether to store each client's configuration. This
|
52
|
+
requires ActiveRecord from Ruby on Rails."]
|
53
|
+
)
|
54
|
+
|
55
|
+
attr_accessor :ast
|
56
|
+
|
57
|
+
class << self
|
58
|
+
attr_writer :ldap
|
59
|
+
end
|
42
60
|
# just shorten the constant path a bit, using what amounts to an alias
|
43
61
|
AST = Puppet::Parser::AST
|
44
62
|
|
63
|
+
# Create an ldap connection. This is a class method so others can call
|
64
|
+
# it and use the same variables and such.
|
65
|
+
def self.ldap
|
66
|
+
unless defined? @ldap and @ldap
|
67
|
+
if Puppet[:ldapssl]
|
68
|
+
@ldap = LDAP::SSLConn.new(Puppet[:ldapserver], Puppet[:ldapport])
|
69
|
+
elsif Puppet[:ldaptls]
|
70
|
+
@ldap = LDAP::SSLConn.new(
|
71
|
+
Puppet[:ldapserver], Puppet[:ldapport], true
|
72
|
+
)
|
73
|
+
else
|
74
|
+
@ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
|
75
|
+
end
|
76
|
+
@ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
77
|
+
@ldap.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
|
78
|
+
@ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
|
79
|
+
end
|
80
|
+
|
81
|
+
return @ldap
|
82
|
+
end
|
83
|
+
|
45
84
|
# create our interpreter
|
46
85
|
def initialize(hash)
|
47
86
|
if @code = hash[:Code]
|
@@ -49,7 +88,6 @@ module Puppet
|
|
49
88
|
elsif ! @file = hash[:Manifest]
|
50
89
|
raise Puppet::DevError, "You must provide code or a manifest"
|
51
90
|
end
|
52
|
-
@filetimeout = hash[:ParseCheck] || 15
|
53
91
|
|
54
92
|
@lastchecked = 0
|
55
93
|
|
@@ -59,19 +97,24 @@ module Puppet
|
|
59
97
|
@usenodes = true
|
60
98
|
end
|
61
99
|
|
62
|
-
|
100
|
+
# By default, we only search the parse tree.
|
101
|
+
@nodesources = []
|
102
|
+
|
103
|
+
if Puppet[:ldapnodes]
|
104
|
+
@nodesources << :ldap
|
105
|
+
end
|
63
106
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
raise Puppet::Error,
|
71
|
-
"Could not set up node source %s" % source
|
107
|
+
if hash[:NodeSources]
|
108
|
+
hash[:NodeSources].each do |src|
|
109
|
+
if respond_to? "nodesearch_#{src.to_s}"
|
110
|
+
@nodesources << src.to_s.intern
|
111
|
+
else
|
112
|
+
Puppet.warning "Node source '#{src}' not supported"
|
72
113
|
end
|
73
114
|
end
|
74
|
-
|
115
|
+
end
|
116
|
+
|
117
|
+
@setup = false
|
75
118
|
|
76
119
|
# Set it to either the value or nil. This is currently only used
|
77
120
|
# by the cfengine module.
|
@@ -79,40 +122,49 @@ module Puppet
|
|
79
122
|
|
80
123
|
@local = hash[:Local] || false
|
81
124
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
begin
|
89
|
-
require 'ldap'
|
90
|
-
rescue LoadError
|
91
|
-
@ldap = nil
|
92
|
-
return
|
125
|
+
if hash.include?(:ForkSave)
|
126
|
+
@forksave = hash[:ForkSave]
|
127
|
+
else
|
128
|
+
# This is just too dangerous right now. Sorry, it's going
|
129
|
+
# to have to be slow.
|
130
|
+
@forksave = false
|
93
131
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
@ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
|
98
|
-
rescue => detail
|
99
|
-
raise Puppet::Error, "Could not connect to LDAP: %s" % detail
|
132
|
+
|
133
|
+
if Puppet[:storeconfigs]
|
134
|
+
Puppet::Rails.init
|
100
135
|
end
|
136
|
+
|
137
|
+
@files = []
|
138
|
+
|
139
|
+
# Create our parser object
|
140
|
+
parsefiles
|
101
141
|
end
|
102
142
|
|
103
|
-
# Search for our node in the various locations.
|
143
|
+
# Search for our node in the various locations. This only searches
|
144
|
+
# locations external to the files; the scope is responsible for
|
145
|
+
# searching the parse tree.
|
104
146
|
def nodesearch(node)
|
105
147
|
# At this point, stop at the first source that defines
|
106
148
|
# the node
|
107
149
|
@nodesources.each do |source|
|
108
150
|
method = "nodesearch_%s" % source
|
151
|
+
parent = nil
|
152
|
+
nodeclasses = nil
|
109
153
|
if self.respond_to? method
|
110
154
|
parent, nodeclasses = self.send(method, node)
|
111
|
-
end
|
112
155
|
|
113
|
-
|
114
|
-
|
115
|
-
|
156
|
+
if parent or (nodeclasses and !nodeclasses.empty?)
|
157
|
+
Puppet.info "Found %s in %s" % [node, source]
|
158
|
+
return parent, nodeclasses
|
159
|
+
else
|
160
|
+
# Look for a default node.
|
161
|
+
parent, nodeclasses = self.send(method, "default")
|
162
|
+
if parent or (nodeclasses and !nodeclasses.empty?)
|
163
|
+
Puppet.info "Found default node for %s in %s" %
|
164
|
+
[node, source]
|
165
|
+
return parent, nodeclasses
|
166
|
+
end
|
167
|
+
end
|
116
168
|
end
|
117
169
|
end
|
118
170
|
|
@@ -122,8 +174,16 @@ module Puppet
|
|
122
174
|
# Find the ldap node and extra the info, returning just
|
123
175
|
# the critical data.
|
124
176
|
def nodesearch_ldap(node)
|
125
|
-
unless defined? @ldap
|
126
|
-
|
177
|
+
unless defined? @ldap and @ldap
|
178
|
+
setup_ldap()
|
179
|
+
unless @ldap
|
180
|
+
Puppet.info "Skipping ldap source; no ldap connection"
|
181
|
+
return nil, []
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
if node =~ /\./
|
186
|
+
node = node.sub(/\..+/, '')
|
127
187
|
end
|
128
188
|
|
129
189
|
filter = Puppet[:ldapstring]
|
@@ -146,27 +206,39 @@ module Puppet
|
|
146
206
|
classes = []
|
147
207
|
|
148
208
|
found = false
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
209
|
+
count = 0
|
210
|
+
begin
|
211
|
+
# We're always doing a sub here; oh well.
|
212
|
+
@ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
|
213
|
+
found = true
|
214
|
+
if pattr
|
215
|
+
if values = entry.vals(pattr)
|
216
|
+
if values.length > 1
|
217
|
+
raise Puppet::Error,
|
218
|
+
"Node %s has more than one parent: %s" %
|
219
|
+
[node, values.inspect]
|
220
|
+
end
|
221
|
+
unless values.empty?
|
222
|
+
parent = values.shift
|
223
|
+
end
|
161
224
|
end
|
162
225
|
end
|
163
|
-
end
|
164
226
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
227
|
+
attrs.each { |attr|
|
228
|
+
if values = entry.vals(attr)
|
229
|
+
values.each do |v| classes << v end
|
230
|
+
end
|
231
|
+
}
|
232
|
+
end
|
233
|
+
rescue => detail
|
234
|
+
if count == 0
|
235
|
+
# Try reconnecting to ldap
|
236
|
+
@ldap = nil
|
237
|
+
setup_ldap()
|
238
|
+
retry
|
239
|
+
else
|
240
|
+
raise Puppet::Error, "LDAP Search failed: %s" % detail
|
241
|
+
end
|
170
242
|
end
|
171
243
|
|
172
244
|
classes.flatten!
|
@@ -179,8 +251,30 @@ module Puppet
|
|
179
251
|
@parsedate
|
180
252
|
end
|
181
253
|
|
254
|
+
# Add a new file to check for updateness.
|
255
|
+
def newfile(file)
|
256
|
+
unless @files.find { |f| f.file == file }
|
257
|
+
@files << Puppet::ParsedFile.new(file)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
182
261
|
# evaluate our whole tree
|
183
262
|
def run(client, facts)
|
263
|
+
# We have to leave this for after initialization because there
|
264
|
+
# seems to be a problem keeping ldap open after a fork.
|
265
|
+
unless @setup
|
266
|
+
@nodesources.each { |source|
|
267
|
+
method = "setup_%s" % source.to_s
|
268
|
+
if respond_to? method
|
269
|
+
begin
|
270
|
+
self.send(method)
|
271
|
+
rescue => detail
|
272
|
+
raise Puppet::Error,
|
273
|
+
"Could not set up node source %s" % source
|
274
|
+
end
|
275
|
+
end
|
276
|
+
}
|
277
|
+
end
|
184
278
|
parsefiles()
|
185
279
|
|
186
280
|
# Really, we should stick multiple names in here
|
@@ -217,10 +311,14 @@ module Puppet
|
|
217
311
|
args[:classes] += nodeclasses if nodeclasses
|
218
312
|
|
219
313
|
args[:parentnode] = parent if parent
|
314
|
+
|
315
|
+
if nodeclasses or parent
|
316
|
+
args[:searched] = true
|
317
|
+
end
|
220
318
|
end
|
221
319
|
|
222
320
|
begin
|
223
|
-
|
321
|
+
objects = scope.evaluate(args)
|
224
322
|
rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except
|
225
323
|
raise
|
226
324
|
rescue => except
|
@@ -232,6 +330,35 @@ module Puppet
|
|
232
330
|
#end
|
233
331
|
raise error
|
234
332
|
end
|
333
|
+
|
334
|
+
if Puppet[:storeconfigs]
|
335
|
+
storeconfigs(
|
336
|
+
:objects => objects,
|
337
|
+
:host => client,
|
338
|
+
:facts => facts
|
339
|
+
)
|
340
|
+
end
|
341
|
+
|
342
|
+
return objects
|
343
|
+
end
|
344
|
+
|
345
|
+
# Connect to the LDAP Server
|
346
|
+
def setup_ldap
|
347
|
+
self.class.ldap = nil
|
348
|
+
begin
|
349
|
+
require 'ldap'
|
350
|
+
rescue LoadError
|
351
|
+
Puppet.notice(
|
352
|
+
"Could not set up LDAP Connection: Missing ruby/ldap libraries"
|
353
|
+
)
|
354
|
+
@ldap = nil
|
355
|
+
return
|
356
|
+
end
|
357
|
+
begin
|
358
|
+
@ldap = self.class.ldap()
|
359
|
+
rescue => detail
|
360
|
+
raise Puppet::Error, "Could not connect to LDAP: %s" % detail
|
361
|
+
end
|
235
362
|
end
|
236
363
|
|
237
364
|
def scope
|
@@ -240,37 +367,29 @@ module Puppet
|
|
240
367
|
|
241
368
|
private
|
242
369
|
|
243
|
-
#
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
# FIXME When this produces errors, it should specify which
|
248
|
-
# node caused those errors.
|
249
|
-
if @usenodes
|
250
|
-
@scope = Puppet::Parser::Scope.new() # no parent scope
|
251
|
-
@scope.name = "top"
|
252
|
-
@scope.type = "puppet"
|
253
|
-
@scope.interp = self
|
254
|
-
Puppet.debug "Nodes defined"
|
255
|
-
@ast.safeevaluate(:scope => @scope)
|
256
|
-
else
|
257
|
-
Puppet.debug "No nodes defined"
|
258
|
-
return
|
370
|
+
# Check whether any of our files have changed.
|
371
|
+
def checkfiles
|
372
|
+
if @files.find { |f| f.changed? }
|
373
|
+
@parsedate = Time.now.to_i
|
259
374
|
end
|
260
375
|
end
|
261
376
|
|
377
|
+
# Parse the files, generating our parse tree. This automatically
|
378
|
+
# reparses only if files are updated, so it's safe to call multiple
|
379
|
+
# times.
|
262
380
|
def parsefiles
|
381
|
+
# First check whether there are updates to any non-puppet files
|
382
|
+
# like templates. If we need to reparse, this will get quashed,
|
383
|
+
# but it needs to be done first in case there's no reparse
|
384
|
+
# but there are other file changes.
|
385
|
+
checkfiles()
|
386
|
+
|
387
|
+
# Check if the parser should reparse.
|
263
388
|
if @file
|
264
389
|
if defined? @parser
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
unless @parser.reparse?
|
269
|
-
@lastchecked = Time.now
|
270
|
-
return false
|
271
|
-
end
|
272
|
-
else
|
273
|
-
return
|
390
|
+
unless @parser.reparse?
|
391
|
+
@lastchecked = Time.now
|
392
|
+
return false
|
274
393
|
end
|
275
394
|
end
|
276
395
|
|
@@ -284,6 +403,8 @@ module Puppet
|
|
284
403
|
end
|
285
404
|
|
286
405
|
if defined? @parser
|
406
|
+
# If this isn't our first time parsing in this process,
|
407
|
+
# note that we're reparsing.
|
287
408
|
Puppet.info "Reloading files"
|
288
409
|
end
|
289
410
|
# should i be creating a new parser each time...?
|
@@ -297,21 +418,57 @@ module Puppet
|
|
297
418
|
if @local
|
298
419
|
@ast = @parser.parse
|
299
420
|
else
|
300
|
-
|
301
|
-
@parser.parse
|
421
|
+
benchmark(:info, "Parsed manifest") do
|
422
|
+
@ast = @parser.parse
|
302
423
|
end
|
303
424
|
end
|
304
425
|
|
305
426
|
# Mark when we parsed, so we can check freshness
|
306
427
|
@parsedate = Time.now.to_i
|
307
428
|
@lastchecked = Time.now
|
429
|
+
end
|
430
|
+
|
431
|
+
# Store the configs into the database.
|
432
|
+
def storeconfigs(hash)
|
433
|
+
unless defined? ActiveRecord
|
434
|
+
require 'puppet/rails'
|
435
|
+
unless defined? ActiveRecord
|
436
|
+
raise LoadError,
|
437
|
+
"storeconfigs is enabled but rails is unavailable"
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
Puppet::Rails.init
|
442
|
+
|
443
|
+
# Fork the storage, since we don't need the client waiting
|
444
|
+
# on that. How do I avoid this duplication?
|
445
|
+
if @forksave
|
446
|
+
fork {
|
447
|
+
# We store all of the objects, even the collectable ones
|
448
|
+
benchmark(:info, "Stored configuration for #{hash[:client]}") do
|
449
|
+
# Try to batch things a bit, by putting them into
|
450
|
+
# a transaction
|
451
|
+
Puppet::Rails::Host.transaction do
|
452
|
+
Puppet::Rails::Host.store(hash)
|
453
|
+
end
|
454
|
+
end
|
455
|
+
}
|
456
|
+
else
|
457
|
+
# We store all of the objects, even the collectable ones
|
458
|
+
benchmark(:info, "Stored configuration for #{hash[:client]}") do
|
459
|
+
Puppet::Rails::Host.transaction do
|
460
|
+
Puppet::Rails::Host.store(hash)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
308
464
|
|
309
|
-
#
|
310
|
-
#
|
311
|
-
|
465
|
+
# Now that we've stored everything, we need to strip out
|
466
|
+
# the collectable objects so that they are not sent on
|
467
|
+
# to the host
|
468
|
+
hash[:objects].collectstrip!
|
312
469
|
end
|
313
470
|
end
|
314
471
|
end
|
315
472
|
end
|
316
473
|
|
317
|
-
# $Id: interpreter.rb
|
474
|
+
# $Id: interpreter.rb 1421 2006-07-21 23:12:51Z luke $
|