puppet 0.25.1 → 0.25.2
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 +159 -135
- data/Rakefile +4 -1
- data/conf/gentoo/conf.d/puppetmaster +1 -1
- data/conf/osx/createpackage.sh +12 -0
- data/conf/osx/preflight +4 -0
- data/conf/redhat/puppet.spec +12 -2
- data/conf/redhat/server.init +1 -0
- data/conf/redhat/server.sysconfig +1 -1
- data/ext/ldap/puppet.schema +5 -9
- data/ext/puppetlast +2 -1
- data/ext/rack/README +2 -2
- data/ext/regexp_nodes/classes/databases +2 -0
- data/ext/regexp_nodes/classes/webservers +2 -0
- data/ext/regexp_nodes/parameters/environment/prod +1 -0
- data/ext/regexp_nodes/parameters/environment/qa +3 -0
- data/ext/regexp_nodes/regexp_nodes.rb +215 -0
- data/lib/puppet.rb +1 -1
- data/lib/puppet/agent.rb +2 -2
- data/lib/puppet/application/puppet.rb +1 -1
- data/lib/puppet/application/puppetd.rb +1 -1
- data/lib/puppet/application/puppetdoc.rb +4 -3
- data/lib/puppet/application/puppetrun.rb +5 -14
- data/lib/puppet/application/ralsh.rb +9 -25
- data/lib/puppet/configurer.rb +2 -1
- data/lib/puppet/configurer/fact_handler.rb +8 -6
- data/lib/puppet/daemon.rb +2 -2
- data/lib/puppet/defaults.rb +21 -2
- data/lib/puppet/external/pson/common.rb +1 -1
- data/lib/puppet/external/pson/pure.rb +3 -3
- data/lib/puppet/feature/base.rb +3 -0
- data/lib/puppet/feature/selinux.rb +3 -0
- data/lib/puppet/feature/zlib.rb +6 -0
- data/lib/puppet/file_serving/base.rb +16 -1
- data/lib/puppet/file_serving/metadata.rb +46 -9
- data/lib/puppet/file_serving/mount/file.rb +4 -1
- data/lib/puppet/indirector/catalog/active_record.rb +5 -0
- data/lib/puppet/indirector/envelope.rb +1 -3
- data/lib/puppet/indirector/indirection.rb +13 -16
- data/lib/puppet/indirector/node/ldap.rb +7 -4
- data/lib/puppet/indirector/ssl_file.rb +1 -1
- data/lib/puppet/network/authstore.rb +48 -118
- data/lib/puppet/network/client/resource.rb +2 -15
- data/lib/puppet/network/format.rb +2 -12
- data/lib/puppet/network/format_handler.rb +15 -1
- data/lib/puppet/network/formats.rb +19 -4
- data/lib/puppet/network/handler/fileserver.rb +1 -0
- data/lib/puppet/network/http/handler.rb +1 -0
- data/lib/puppet/network/http/rack/httphandler.rb +0 -18
- data/lib/puppet/network/http/rack/rest.rb +4 -4
- data/lib/puppet/network/http/rack/xmlrpc.rb +4 -4
- data/lib/puppet/network/http/webrick.rb +2 -1
- data/lib/puppet/network/server.rb +1 -1
- data/lib/puppet/node/environment.rb +20 -9
- data/lib/puppet/parameter.rb +17 -1
- data/lib/puppet/parser/ast/boolean_operator.rb +2 -2
- data/lib/puppet/parser/ast/leaf.rb +5 -1
- data/lib/puppet/parser/ast/resourceparam.rb +4 -0
- data/lib/puppet/parser/ast/selector.rb +4 -0
- data/lib/puppet/parser/functions/generate.rb +2 -2
- data/lib/puppet/parser/functions/shellquote.rb +1 -1
- data/lib/puppet/property.rb +3 -11
- data/lib/puppet/provider/cron/crontab.rb +2 -0
- data/lib/puppet/provider/host/parsed.rb +9 -9
- data/lib/puppet/provider/package/blastwave.rb +7 -6
- data/lib/puppet/provider/package/portage.rb +23 -27
- data/lib/puppet/provider/package/rug.rb +1 -1
- data/lib/puppet/provider/package/sun.rb +5 -3
- data/lib/puppet/provider/service/daemontools.rb +1 -1
- data/lib/puppet/provider/service/debian.rb +1 -1
- data/lib/puppet/provider/service/runit.rb +1 -1
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +2 -1
- data/lib/puppet/provider/sshkey/parsed.rb +3 -5
- data/lib/puppet/provider/zone/solaris.rb +1 -1
- data/lib/puppet/rails.rb +9 -2
- data/lib/puppet/rails/benchmark.rb +1 -1
- data/lib/puppet/rails/host.rb +2 -7
- data/lib/puppet/rails/resource.rb +20 -26
- data/lib/puppet/resource/catalog.rb +3 -3
- data/lib/puppet/resource/reference.rb +13 -25
- data/lib/puppet/ssl/certificate.rb +3 -2
- data/lib/puppet/ssl/host.rb +14 -33
- data/lib/puppet/sslcertificates.rb +1 -5
- data/lib/puppet/sslcertificates/ca.rb +8 -7
- data/lib/puppet/transaction.rb +15 -12
- data/lib/puppet/type.rb +12 -5
- data/lib/puppet/type/file.rb +26 -32
- data/lib/puppet/type/file/content.rb +5 -5
- data/lib/puppet/type/file/ensure.rb +6 -17
- data/lib/puppet/type/file/mode.rb +18 -1
- data/lib/puppet/type/file/source.rb +12 -12
- data/lib/puppet/type/host.rb +6 -9
- data/lib/puppet/type/k5login.rb +1 -1
- data/lib/puppet/type/maillist.rb +4 -7
- data/lib/puppet/type/port.rb +6 -5
- data/lib/puppet/type/resources.rb +12 -12
- data/lib/puppet/type/sshkey.rb +5 -5
- data/lib/puppet/type/tidy.rb +9 -2
- data/lib/puppet/type/yumrepo.rb +3 -1
- data/lib/puppet/util.rb +64 -56
- data/lib/puppet/util/backups.rb +2 -1
- data/lib/puppet/util/filetype.rb +46 -0
- data/lib/puppet/util/log.rb +10 -18
- data/lib/puppet/util/log_paths.rb +14 -0
- data/lib/puppet/util/methodhelper.rb +3 -4
- data/lib/puppet/util/monkey_patches.rb +8 -0
- data/lib/puppet/util/rdoc/generators/puppet_generator.rb +5 -3
- data/lib/puppet/util/rdoc/parser.rb +32 -16
- data/lib/puppet/util/reference.rb +6 -3
- data/lib/puppet/util/selinux.rb +21 -14
- data/lib/puppet/util/settings.rb +30 -25
- data/lib/puppet/util/settings/file_setting.rb +7 -4
- data/lib/puppet/util/subclass_loader.rb +1 -1
- data/lib/puppet/util/suidmanager.rb +11 -1
- data/lib/puppet/util/tagging.rb +22 -4
- data/man/man8/filebucket.8 +23 -18
- data/man/man8/pi.8 +42 -20
- data/man/man8/puppet.8 +47 -32
- data/man/man8/puppet.conf.8 +807 -764
- data/man/man8/puppetca.8 +24 -14
- data/man/man8/puppetd.8 +33 -16
- data/man/man8/puppetdoc.8 +71 -18
- data/man/man8/puppetmasterd.8 +18 -25
- data/man/man8/puppetqd.8 +60 -0
- data/man/man8/puppetrun.8 +27 -14
- data/man/man8/ralsh.8 +33 -40
- data/spec/integration/bin/puppetmasterd.rb +3 -2
- data/spec/integration/defaults.rb +11 -0
- data/spec/integration/file_serving/metadata.rb +1 -0
- data/spec/integration/indirector/file_content/file_server.rb +2 -1
- data/spec/integration/ssl/certificate_request.rb +2 -0
- data/spec/integration/type/file.rb +20 -1
- data/spec/shared_behaviours/file_serving.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/application/puppet.rb +11 -30
- data/spec/unit/application/puppetd.rb +1 -0
- data/spec/unit/application/puppetdoc.rb +13 -4
- data/spec/unit/application/puppetmasterd.rb +1 -0
- data/spec/unit/application/puppetrun.rb +12 -2
- data/spec/unit/application/ralsh.rb +39 -22
- data/spec/unit/configurer.rb +6 -0
- data/spec/unit/configurer/fact_handler.rb +15 -1
- data/spec/unit/file_serving/metadata.rb +128 -16
- data/spec/unit/file_serving/mount/file.rb +8 -0
- data/spec/unit/indirector/catalog/active_record.rb +20 -1
- data/spec/unit/indirector/catalog/compiler.rb +2 -1
- data/spec/unit/indirector/indirection.rb +29 -18
- data/spec/unit/indirector/node/ldap.rb +20 -6
- data/spec/unit/network/authstore.rb +197 -0
- data/spec/unit/network/format_handler.rb +28 -8
- data/spec/unit/network/formats.rb +31 -0
- data/spec/unit/network/http/handler.rb +10 -0
- data/spec/unit/network/http/webrick.rb +2 -2
- data/spec/unit/network/rest_authconfig.rb +2 -2
- data/spec/unit/network/rights.rb +1 -1
- data/spec/unit/node/environment.rb +39 -23
- data/spec/unit/other/selinux.rb +2 -2
- data/spec/unit/parameter.rb +8 -0
- data/spec/unit/parser/ast/leaf.rb +9 -0
- data/spec/unit/parser/ast/selector.rb +8 -1
- data/spec/unit/parser/lexer.rb +1 -1
- data/spec/unit/parser/resource.rb +11 -0
- data/spec/unit/parser/resource/reference.rb +13 -1
- data/spec/unit/property.rb +6 -0
- data/spec/unit/provider/mount/parsed.rb +3 -1
- data/spec/unit/provider/service/debian.rb +1 -1
- data/spec/unit/provider/ssh_authorized_key/parsed.rb +9 -1
- data/spec/unit/provider/sshkey/parsed.rb +19 -0
- data/spec/unit/rails.rb +22 -9
- data/spec/unit/rails/resource.rb +20 -0
- data/spec/unit/ssl/host.rb +19 -57
- data/spec/unit/transaction.rb +39 -4
- data/spec/unit/type.rb +9 -0
- data/spec/unit/type/file/content.rb +29 -0
- data/spec/unit/type/maillist.rb +42 -0
- data/spec/unit/type/resources.rb +66 -1
- data/spec/unit/type/tidy.rb +14 -1
- data/spec/unit/util/autoload.rb +2 -0
- data/spec/unit/util/ldap/connection.rb +1 -1
- data/spec/unit/util/log.rb +14 -0
- data/spec/unit/util/monkey_patches.rb +103 -0
- data/spec/unit/util/queue.rb +10 -2
- data/spec/unit/util/selinux.rb +61 -2
- data/spec/unit/util/settings.rb +19 -0
- data/spec/unit/util/settings/file_setting.rb +25 -0
- data/spec/unit/util/tagging.rb +10 -0
- data/tasks/rake/changelog.rake +15 -0
- data/tasks/rake/ci.rake +22 -0
- data/tasks/rake/dailybuild.rake +9 -0
- data/tasks/rake/gem.rake +46 -0
- data/tasks/rake/git_workflow.rake +121 -0
- data/tasks/rake/metrics.rake +6 -0
- data/tasks/rake/sign.rake +14 -0
- data/tasks/rake/testbranch.rake +16 -0
- data/tasks/rake/tracdocs.rake +8 -0
- data/test/data/providers/ssh_authorized_key/parsed/authorized_keys +1 -0
- metadata +1042 -1288
- data/ext/bin/sleeper +0 -67
- data/ext/module_puppet +0 -209
data/lib/puppet/configurer.rb
CHANGED
@@ -93,7 +93,7 @@ class Puppet::Configurer
|
|
93
93
|
duration = thinmark do
|
94
94
|
result = catalog_class.find(name, fact_options.merge(:ignore_cache => true))
|
95
95
|
end
|
96
|
-
rescue => detail
|
96
|
+
rescue Exception => detail
|
97
97
|
puts detail.backtrace if Puppet[:trace]
|
98
98
|
Puppet.err "Could not retrieve catalog from remote server: %s" % detail
|
99
99
|
end
|
@@ -123,6 +123,7 @@ class Puppet::Configurer
|
|
123
123
|
# Convert a plain resource catalog into our full host catalog.
|
124
124
|
def convert_catalog(result, duration)
|
125
125
|
catalog = result.to_ral
|
126
|
+
catalog.finalize
|
126
127
|
catalog.retrieval_duration = duration
|
127
128
|
catalog.host_config = true
|
128
129
|
catalog.write_class_file
|
@@ -11,14 +11,13 @@ module Puppet::Configurer::FactHandler
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def find_facts
|
14
|
-
reload_facter()
|
15
|
-
|
16
14
|
# This works because puppetd configures Facts to use 'facter' for
|
17
15
|
# finding facts and the 'rest' terminus for caching them. Thus, we'll
|
18
16
|
# compile them and then "cache" them on the server.
|
19
17
|
begin
|
18
|
+
reload_facter()
|
20
19
|
Puppet::Node::Facts.find(Puppet[:certname])
|
21
|
-
rescue => detail
|
20
|
+
rescue Exception => detail
|
22
21
|
puts detail.backtrace if Puppet[:trace]
|
23
22
|
raise Puppet::Error, "Could not retrieve local facts: %s" % detail
|
24
23
|
end
|
@@ -28,12 +27,15 @@ module Puppet::Configurer::FactHandler
|
|
28
27
|
facts = find_facts
|
29
28
|
#format = facts.class.default_format
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
if facts.support_format?(:b64_zlib_yaml)
|
31
|
+
format = :b64_zlib_yaml
|
32
|
+
else
|
33
|
+
format = :yaml
|
34
|
+
end
|
33
35
|
|
34
36
|
text = facts.render(format)
|
35
37
|
|
36
|
-
return {:facts_format =>
|
38
|
+
return {:facts_format => format, :facts => CGI.escape(text)}
|
37
39
|
end
|
38
40
|
|
39
41
|
# Retrieve facts from the central server.
|
data/lib/puppet/daemon.rb
CHANGED
@@ -31,10 +31,10 @@ class Puppet::Daemon
|
|
31
31
|
$stderr.reopen $stdout
|
32
32
|
Puppet::Util::Log.reopen
|
33
33
|
rescue => detail
|
34
|
-
|
34
|
+
Puppet.err "Could not start %s: %s" % [Puppet[:name], detail]
|
35
|
+
Puppet::Util::secure_open("/tmp/daemonout", "w") { |f|
|
35
36
|
f.puts "Could not start %s: %s" % [Puppet[:name], detail]
|
36
37
|
}
|
37
|
-
Puppet.err "Could not start %s: %s" % [Puppet[:name], detail]
|
38
38
|
exit(12)
|
39
39
|
end
|
40
40
|
end
|
data/lib/puppet/defaults.rb
CHANGED
@@ -86,6 +86,10 @@ module Puppet
|
|
86
86
|
:mkusers => [false,
|
87
87
|
"Whether to create the necessary user and group that puppetd will
|
88
88
|
run as."],
|
89
|
+
:manage_internal_file_permissions => [true,
|
90
|
+
"Whether Puppet should manage the owner, group, and mode of files
|
91
|
+
it uses internally"
|
92
|
+
],
|
89
93
|
:path => {:default => "none",
|
90
94
|
:desc => "The shell search path. Defaults to whatever is inherited
|
91
95
|
from the parent process.",
|
@@ -156,7 +160,7 @@ module Puppet
|
|
156
160
|
:http_proxy_port => [3128,
|
157
161
|
"The HTTP proxy port to use for outgoing connections"],
|
158
162
|
:http_enable_post_connection_check => [true,
|
159
|
-
"Boolean;
|
163
|
+
"Boolean; whether or not puppetd should validate the server
|
160
164
|
SSL certificate against the request hostname."],
|
161
165
|
:filetimeout => [ 15,
|
162
166
|
"The minimum time to wait (in seconds) between checking for updates in
|
@@ -192,7 +196,10 @@ module Puppet
|
|
192
196
|
:config_version => ["", "How to determine the configuration version. By default, it will be the
|
193
197
|
time that the configuration is parsed, but you can provide a shell script to override how the
|
194
198
|
version is determined. The output of this script will be added to every log message in the
|
195
|
-
reports, allowing you to correlate changes on your hosts to the source version on the server."]
|
199
|
+
reports, allowing you to correlate changes on your hosts to the source version on the server."],
|
200
|
+
:zlib => [true,
|
201
|
+
"Boolean; whether to use the zlib library",
|
202
|
+
]
|
196
203
|
)
|
197
204
|
|
198
205
|
hostname = Facter["hostname"].value
|
@@ -522,6 +529,18 @@ module Puppet
|
|
522
529
|
authority requests. It's a separate server because it cannot
|
523
530
|
and does not need to horizontally scale."],
|
524
531
|
:ca_port => ["$masterport", "The port to use for the certificate authority."],
|
532
|
+
:catalog_format => {
|
533
|
+
:default => "",
|
534
|
+
:desc => "(Deprecated for 'preferred_serialization_format') What format to
|
535
|
+
use to dump the catalog. Only supports 'marshal' and 'yaml'. Only
|
536
|
+
matters on the client, since it asks the server for a specific format.",
|
537
|
+
:hook => proc { |value|
|
538
|
+
if value
|
539
|
+
Puppet.warning "Setting 'catalog_format' is deprecated; use 'preferred_serialization_format' instead."
|
540
|
+
Puppet.settings[:preferred_serialization_format] = value
|
541
|
+
end
|
542
|
+
}
|
543
|
+
},
|
525
544
|
:preferred_serialization_format => ["pson", "The preferred means of serializing
|
526
545
|
ruby instances for passing over the wire. This won't guarantee that all
|
527
546
|
instances will be serialized using this method, since not all classes
|
@@ -11,8 +11,8 @@ module PSON
|
|
11
11
|
UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
|
12
12
|
UTF8toUTF16.iconv('no bom')
|
13
13
|
rescue LoadError
|
14
|
-
|
15
|
-
|
14
|
+
# We actually don't care
|
15
|
+
Puppet.warning "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
|
16
16
|
rescue Errno::EINVAL, Iconv::InvalidEncoding
|
17
17
|
# Iconv doesn't support big endian utf-16. Let's try to hack this manually
|
18
18
|
# into the converters.
|
@@ -50,7 +50,7 @@ module PSON
|
|
50
50
|
UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
|
51
51
|
end
|
52
52
|
rescue Errno::EINVAL, Iconv::InvalidEncoding
|
53
|
-
|
53
|
+
Puppet.warning "iconv doesn't seem to support UTF-8/UTF-16 conversions"
|
54
54
|
ensure
|
55
55
|
$VERBOSE = old_verbose
|
56
56
|
end
|
data/lib/puppet/feature/base.rb
CHANGED
@@ -22,7 +22,7 @@ class Puppet::FileServing::Base
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Return the full path to our file. Fails if there's no path set.
|
25
|
-
def full_path
|
25
|
+
def full_path(dummy_argument=:work_arround_for_ruby_GC_bug)
|
26
26
|
(if relative_path.nil? or relative_path == "" or relative_path == "."
|
27
27
|
path
|
28
28
|
else
|
@@ -74,4 +74,19 @@ class Puppet::FileServing::Base
|
|
74
74
|
end
|
75
75
|
File.send(@stat_method, full_path())
|
76
76
|
end
|
77
|
+
|
78
|
+
def to_pson_data_hash
|
79
|
+
{
|
80
|
+
# No 'document_type' since we don't send these bare
|
81
|
+
'data' => {
|
82
|
+
'path' => @path,
|
83
|
+
'relative_path' => @relative_path,
|
84
|
+
'links' => @links
|
85
|
+
},
|
86
|
+
'metadata' => {
|
87
|
+
'api_version' => 1
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
77
92
|
end
|
@@ -22,18 +22,15 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
|
|
22
22
|
PARAM_ORDER = [:mode, :ftype, :owner, :group]
|
23
23
|
|
24
24
|
def attributes_with_tabs
|
25
|
+
raise(ArgumentError, "Cannot manage files of type #{ftype}") unless ['file','directory','link'].include? ftype
|
25
26
|
desc = []
|
26
27
|
PARAM_ORDER.each { |check|
|
27
28
|
check = :ftype if check == :type
|
28
29
|
desc << send(check)
|
29
30
|
}
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
when "link"; desc << @destination
|
34
|
-
else
|
35
|
-
raise ArgumentError, "Cannot manage files of type %s" % ftype
|
36
|
-
end
|
32
|
+
desc << checksum
|
33
|
+
desc << @destination rescue nil if ftype == 'link'
|
37
34
|
|
38
35
|
return desc.join("\t")
|
39
36
|
end
|
@@ -66,13 +63,53 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
|
|
66
63
|
@checksum = ("{%s}" % @checksum_type) + send("%s_file" % @checksum_type, path).to_s
|
67
64
|
when "link"
|
68
65
|
@destination = File.readlink(real_path)
|
66
|
+
@checksum = ("{%s}" % @checksum_type) + send("%s_file" % @checksum_type, real_path).to_s rescue nil
|
69
67
|
else
|
70
68
|
raise ArgumentError, "Cannot manage files of type %s" % stat.ftype
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
def initialize(
|
75
|
-
@
|
76
|
-
|
72
|
+
def initialize(path,data={})
|
73
|
+
@owner = data.delete('owner')
|
74
|
+
@group = data.delete('group')
|
75
|
+
@mode = data.delete('mode')
|
76
|
+
if checksum = data.delete('checksum')
|
77
|
+
@checksum_type = checksum['type']
|
78
|
+
@checksum = checksum['value']
|
79
|
+
end
|
80
|
+
@checksum_type ||= "md5"
|
81
|
+
@ftype = data.delete('type')
|
82
|
+
@destination = data.delete('destination')
|
83
|
+
super(path,data)
|
84
|
+
end
|
85
|
+
|
86
|
+
PSON.register_document_type('FileMetadata',self)
|
87
|
+
def to_pson_data_hash
|
88
|
+
{
|
89
|
+
'document_type' => 'FileMetadata',
|
90
|
+
'data' => super['data'].update({
|
91
|
+
'owner' => owner,
|
92
|
+
'group' => group,
|
93
|
+
'mode' => mode,
|
94
|
+
'checksum' => {
|
95
|
+
'type' => checksum_type,
|
96
|
+
'value' => checksum
|
97
|
+
},
|
98
|
+
'type' => ftype,
|
99
|
+
'destination' => destination,
|
100
|
+
}),
|
101
|
+
'metadata' => {
|
102
|
+
'api_version' => 1
|
103
|
+
}
|
104
|
+
}
|
77
105
|
end
|
106
|
+
|
107
|
+
def to_pson(*args)
|
108
|
+
to_pson_data_hash.to_pson(*args)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.from_pson(data)
|
112
|
+
new(data.delete('path'), data)
|
113
|
+
end
|
114
|
+
|
78
115
|
end
|
@@ -25,7 +25,10 @@ class Puppet::FileServing::Mount::File < Puppet::FileServing::Mount
|
|
25
25
|
|
26
26
|
file = ::File.join(full_path, relative_path)
|
27
27
|
|
28
|
-
|
28
|
+
if ! FileTest.exist?(file)
|
29
|
+
Puppet.info("File does not exist or is not accessible: #{file}")
|
30
|
+
return nil
|
31
|
+
end
|
29
32
|
|
30
33
|
return file
|
31
34
|
end
|
@@ -30,6 +30,11 @@ class Puppet::Resource::Catalog::ActiveRecord < Puppet::Indirector::ActiveRecord
|
|
30
30
|
host.merge_resources(catalog.vertices)
|
31
31
|
host.last_compile = Time.now
|
32
32
|
|
33
|
+
if node = Puppet::Node.find(catalog.name)
|
34
|
+
host.ip = node.parameters["ipaddress"]
|
35
|
+
host.environment = node.environment
|
36
|
+
end
|
37
|
+
|
33
38
|
host.save
|
34
39
|
end
|
35
40
|
end
|
@@ -161,22 +161,19 @@ class Puppet::Indirector::Indirection
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
# Expire a cached object, if one is cached. Note that we
|
165
|
-
# remove it
|
166
|
-
#
|
164
|
+
# Expire a cached object, if one is cached. Note that we now actually
|
165
|
+
# remove it if possible, and only mark it as expired if destroy isn't
|
166
|
+
# supported.
|
167
167
|
def expire(key, *args)
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
instance.expiration = Time.now - 60
|
178
|
-
|
179
|
-
cache.save(request(:save, instance, *args))
|
168
|
+
if cache? and instance = cache.find(request(:find, key, *args))
|
169
|
+
Puppet.info "Expiring the #{name} cache of #{instance.name}"
|
170
|
+
if cache.respond_to? :destroy
|
171
|
+
cache.destroy(request(:destroy, instance, *args))
|
172
|
+
else
|
173
|
+
instance.expiration = Time.now - 1
|
174
|
+
cache.save(request(:save,instance,*args))
|
175
|
+
end
|
176
|
+
end
|
180
177
|
end
|
181
178
|
|
182
179
|
# Search for an instance in the appropriate terminus, caching the
|
@@ -216,7 +213,7 @@ class Puppet::Indirector::Indirection
|
|
216
213
|
return nil
|
217
214
|
end
|
218
215
|
|
219
|
-
Puppet.debug "Using cached
|
216
|
+
Puppet.debug "Using cached #{name} for #{request.key}, good until #{cached.expiration}"
|
220
217
|
return cached
|
221
218
|
end
|
222
219
|
|
@@ -55,7 +55,7 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
|
|
55
55
|
end
|
56
56
|
|
57
57
|
infos = []
|
58
|
-
ldapsearch(filter) { |entry| infos << entry2hash(entry) }
|
58
|
+
ldapsearch(filter) { |entry| infos << entry2hash(entry, request.options[:fqdn]) }
|
59
59
|
|
60
60
|
return infos.collect do |info|
|
61
61
|
info2node(info[:name], info)
|
@@ -73,14 +73,17 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
|
|
73
73
|
|
74
74
|
# The attributes that Puppet will stack as array over the full
|
75
75
|
# hierarchy.
|
76
|
-
def stacked_attributes
|
76
|
+
def stacked_attributes(dummy_argument=:work_arround_for_ruby_GC_bug)
|
77
77
|
Puppet[:ldapstackedattrs].split(/\s*,\s*/)
|
78
78
|
end
|
79
79
|
|
80
80
|
# Convert the found entry into a simple hash.
|
81
|
-
def entry2hash(entry)
|
81
|
+
def entry2hash(entry, fqdn = false)
|
82
82
|
result = {}
|
83
|
-
|
83
|
+
|
84
|
+
cn = entry.dn[ /cn\s*=\s*([^,\s]+)/i,1]
|
85
|
+
dcs = entry.dn.scan(/dc\s*=\s*([^,\s]+)/i)
|
86
|
+
result[:name] = fqdn ? ([cn]+dcs).join('.') : cn
|
84
87
|
result[:parent] = get_parent_from_entry(entry) if parent_attribute
|
85
88
|
result[:classes] = get_classes_from_entry(entry)
|
86
89
|
result[:stacked] = get_stacked_values_from_entry(entry)
|
@@ -91,7 +91,7 @@ class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus
|
|
91
91
|
def save(request)
|
92
92
|
path = path(request.key)
|
93
93
|
dir = File.dirname(path)
|
94
|
-
|
94
|
+
|
95
95
|
raise Puppet::Error.new("Cannot save %s; parent directory %s does not exist" % [request.key, dir]) unless FileTest.directory?(dir)
|
96
96
|
raise Puppet::Error.new("Cannot save %s; parent directory %s is not writable" % [request.key, dir]) unless FileTest.writable?(dir)
|
97
97
|
|
@@ -49,7 +49,7 @@ module Puppet
|
|
49
49
|
return decl.result
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
info "defaulting to no access for %s" % name
|
53
53
|
return false
|
54
54
|
end
|
55
55
|
|
@@ -78,11 +78,7 @@ module Puppet
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def interpolate(match)
|
81
|
-
declarations = @declarations.collect
|
82
|
-
ace.interpolate(match)
|
83
|
-
end
|
84
|
-
declarations.sort!
|
85
|
-
Thread.current[:declarations] = declarations
|
81
|
+
Thread.current[:declarations] = @declarations.collect { |ace| ace.interpolate(match) }.sort
|
86
82
|
end
|
87
83
|
|
88
84
|
def reset_interpolation
|
@@ -96,8 +92,7 @@ module Puppet
|
|
96
92
|
# this is used if we want to override the this purely immutable list
|
97
93
|
# by a modified version in a multithread safe way.
|
98
94
|
def declarations
|
99
|
-
|
100
|
-
@declarations
|
95
|
+
Thread.current[:declarations] || @declarations
|
101
96
|
end
|
102
97
|
|
103
98
|
# Store the results of a pattern into our hash. Basically just
|
@@ -130,46 +125,21 @@ module Puppet
|
|
130
125
|
# The length. Only used for iprange and domain.
|
131
126
|
attr_accessor :length
|
132
127
|
|
133
|
-
# Sort the declarations
|
128
|
+
# Sort the declarations most specific first.
|
134
129
|
def <=>(other)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# Then by type
|
141
|
-
if r = compare(self.ip?, other.ip?)
|
142
|
-
return r
|
143
|
-
end
|
144
|
-
|
145
|
-
# Next sort based on length
|
146
|
-
unless self.length == other.length
|
147
|
-
# Longer names/ips should go first, because they're more
|
148
|
-
# specific.
|
149
|
-
return other.length <=> self.length
|
150
|
-
end
|
151
|
-
|
152
|
-
# Then sort deny before allow
|
153
|
-
if r = compare(self.deny?, other.deny?)
|
154
|
-
return r
|
155
|
-
end
|
156
|
-
|
157
|
-
# We've already sorted by name and length, so all that's left
|
158
|
-
# is the pattern
|
159
|
-
if ip?
|
160
|
-
return self.pattern.to_s <=> other.pattern.to_s
|
161
|
-
else
|
162
|
-
return self.pattern <=> other.pattern
|
163
|
-
end
|
130
|
+
compare(exact?, other.exact?) ||
|
131
|
+
compare(ip?, other.ip?) ||
|
132
|
+
((length != other.length) && (other.length <=> length)) ||
|
133
|
+
compare(deny?, other.deny?) ||
|
134
|
+
( ip? ? pattern.to_s <=> other.pattern.to_s : pattern <=> other.pattern)
|
164
135
|
end
|
165
136
|
|
166
137
|
def deny?
|
167
|
-
|
138
|
+
type == :deny
|
168
139
|
end
|
169
140
|
|
170
|
-
# Are we an exact match?
|
171
141
|
def exact?
|
172
|
-
|
142
|
+
@exact == :exact
|
173
143
|
end
|
174
144
|
|
175
145
|
def initialize(type, pattern)
|
@@ -179,16 +149,12 @@ module Puppet
|
|
179
149
|
|
180
150
|
# Are we an IP type?
|
181
151
|
def ip?
|
182
|
-
|
152
|
+
name == :ip
|
183
153
|
end
|
184
154
|
|
185
155
|
# Does this declaration match the name/ip combo?
|
186
156
|
def match?(name, ip)
|
187
|
-
|
188
|
-
return pattern.include?(IPAddr.new(ip))
|
189
|
-
else
|
190
|
-
return matchname?(name)
|
191
|
-
end
|
157
|
+
ip? ? pattern.include?(IPAddr.new(ip)) : matchname?(name)
|
192
158
|
end
|
193
159
|
|
194
160
|
# Set the pattern appropriately. Also sets the name and length.
|
@@ -199,15 +165,11 @@ module Puppet
|
|
199
165
|
|
200
166
|
# Mapping a type of statement into a return value.
|
201
167
|
def result
|
202
|
-
|
203
|
-
when :allow; true
|
204
|
-
else
|
205
|
-
false
|
206
|
-
end
|
168
|
+
type == :allow
|
207
169
|
end
|
208
170
|
|
209
171
|
def to_s
|
210
|
-
"
|
172
|
+
"#{type}: #{pattern}"
|
211
173
|
end
|
212
174
|
|
213
175
|
# Set the declaration type. Either :allow or :deny.
|
@@ -238,86 +200,54 @@ module Puppet
|
|
238
200
|
# -1 if the first is true, and 1 if the second is true. Used
|
239
201
|
# in the <=> operator.
|
240
202
|
def compare(me, them)
|
241
|
-
|
242
|
-
if me
|
243
|
-
return -1
|
244
|
-
elsif them
|
245
|
-
return 1
|
246
|
-
else
|
247
|
-
return false
|
248
|
-
end
|
249
|
-
end
|
250
|
-
return nil
|
203
|
+
(me and them) ? nil : me ? -1 : them ? 1 : nil
|
251
204
|
end
|
252
205
|
|
253
206
|
# Does the name match our pattern?
|
254
207
|
def matchname?(name)
|
255
208
|
name = munge_name(name)
|
256
|
-
|
257
|
-
|
258
|
-
# If it's an exact match, then just return false, since the
|
259
|
-
# exact didn't match.
|
260
|
-
if exact?
|
261
|
-
return false
|
262
|
-
end
|
263
|
-
|
264
|
-
# If every field in the pattern matches, then we consider it
|
265
|
-
# a match.
|
266
|
-
pattern.zip(name) do |p,n|
|
267
|
-
unless p == n
|
268
|
-
return false
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
return true
|
209
|
+
(pattern == name) or (not exact? and pattern.zip(name).all? { |p,n| p == n })
|
273
210
|
end
|
274
211
|
|
275
212
|
# Convert the name to a common pattern.
|
276
213
|
def munge_name(name)
|
277
214
|
# LAK:NOTE http://snurl.com/21zf8 [groups_google_com]
|
278
|
-
# Change to
|
279
|
-
|
215
|
+
# Change to name.downcase.split(".",-1).reverse for FQDN support
|
216
|
+
name.downcase.split(".").reverse
|
280
217
|
end
|
281
218
|
|
282
219
|
# Parse our input pattern and figure out what kind of allowal
|
283
220
|
# statement it is. The output of this is used for later matching.
|
221
|
+
Octet = '(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])'
|
222
|
+
IPv4 = "#{Octet}\.#{Octet}\.#{Octet}\.#{Octet}"
|
223
|
+
IPv6_full = "_:_:_:_:_:_:_:_|_:_:_:_:_:_::_?|_:_:_:_:_::((_:)?_)?|_:_:_:_::((_:){0,2}_)?|_:_:_::((_:){0,3}_)?|_:_::((_:){0,4}_)?|_::((_:){0,5}_)?|::((_:){0,6}_)?"
|
224
|
+
IPv6_partial = "_:_:_:_:_:_:|_:_:_:_::(_:)?|_:_::(_:){0,2}|_::(_:){0,3}"
|
225
|
+
# It should be:
|
226
|
+
# IP = "#{IPv4}|#{IPv6_full}|(#{IPv6_partial}#{IPv4})".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
|
227
|
+
# but ruby's ipaddr lib doesn't support the hybrid format
|
228
|
+
IP = "#{IPv4}|#{IPv6_full}".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
|
284
229
|
def parse(value)
|
285
|
-
|
286
|
-
#
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
when /^\*(\.([a-zA-Z][-\w]*)){1,}$/ # *.domain.com
|
307
|
-
@name = :domain
|
308
|
-
@pattern = munge_name(value)
|
309
|
-
@pattern.pop # take off the '*'
|
310
|
-
@length = @pattern.length
|
311
|
-
when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2
|
312
|
-
@name = :dynamic
|
313
|
-
@pattern = munge_name(value)
|
314
|
-
when /^[a-zA-Z0-9][-a-zA-Z0-9_.@]*$/
|
315
|
-
@pattern = [value]
|
316
|
-
@length = nil # force an exact match
|
317
|
-
@name = :opaque
|
318
|
-
else
|
319
|
-
raise AuthStoreError, "Invalid pattern %s" % value
|
320
|
-
end
|
230
|
+
@name,@exact,@length,@pattern = *case value
|
231
|
+
when /^(?:#{IP})\/(\d+)$/ # 12.34.56.78/24, a001:b002::efff/120, c444:1000:2000::9:192.168.0.1/112
|
232
|
+
[:ip,:inexact,$1.to_i,IPAddr.new(value)]
|
233
|
+
when /^(#{IP})$/ # 10.20.30.40,
|
234
|
+
[:ip,:exact,nil,IPAddr.new(value)]
|
235
|
+
when /^(#{Octet}\.){1,3}\*$/ # an ip address with a '*' at the end
|
236
|
+
segments = value.split(".")[0..-2]
|
237
|
+
bits = 8*segments.length
|
238
|
+
[:ip,:inexact,bits,IPAddr.new((segments+[0,0,0])[0,4].join(".") + "/#{bits}")]
|
239
|
+
when /^(\w[-\w]*\.)+[-\w]+$/ # a full hostname
|
240
|
+
# Change to /^(\w[-\w]*\.)+[-\w]+\.?$/ for FQDN support
|
241
|
+
[:domain,:exact,nil,munge_name(value)]
|
242
|
+
when /^\*(\.(\w[-\w]*)){1,}$/ # *.domain.com
|
243
|
+
host_sans_star = munge_name(value)[0..-2]
|
244
|
+
[:domain,:inexact,host_sans_star.length,host_sans_star]
|
245
|
+
when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2
|
246
|
+
[:dynamic,:exact,nil,munge_name(value)]
|
247
|
+
when /^\w[-.@\w]*$/ # ? Just like a host name but allow '@'s and ending '.'s
|
248
|
+
[:opaque,:exact,nil,[value]]
|
249
|
+
else
|
250
|
+
raise AuthStoreError, "Invalid pattern %s" % value
|
321
251
|
end
|
322
252
|
end
|
323
253
|
end
|