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.

Files changed (198) hide show
  1. data/CHANGELOG +159 -135
  2. data/Rakefile +4 -1
  3. data/conf/gentoo/conf.d/puppetmaster +1 -1
  4. data/conf/osx/createpackage.sh +12 -0
  5. data/conf/osx/preflight +4 -0
  6. data/conf/redhat/puppet.spec +12 -2
  7. data/conf/redhat/server.init +1 -0
  8. data/conf/redhat/server.sysconfig +1 -1
  9. data/ext/ldap/puppet.schema +5 -9
  10. data/ext/puppetlast +2 -1
  11. data/ext/rack/README +2 -2
  12. data/ext/regexp_nodes/classes/databases +2 -0
  13. data/ext/regexp_nodes/classes/webservers +2 -0
  14. data/ext/regexp_nodes/parameters/environment/prod +1 -0
  15. data/ext/regexp_nodes/parameters/environment/qa +3 -0
  16. data/ext/regexp_nodes/regexp_nodes.rb +215 -0
  17. data/lib/puppet.rb +1 -1
  18. data/lib/puppet/agent.rb +2 -2
  19. data/lib/puppet/application/puppet.rb +1 -1
  20. data/lib/puppet/application/puppetd.rb +1 -1
  21. data/lib/puppet/application/puppetdoc.rb +4 -3
  22. data/lib/puppet/application/puppetrun.rb +5 -14
  23. data/lib/puppet/application/ralsh.rb +9 -25
  24. data/lib/puppet/configurer.rb +2 -1
  25. data/lib/puppet/configurer/fact_handler.rb +8 -6
  26. data/lib/puppet/daemon.rb +2 -2
  27. data/lib/puppet/defaults.rb +21 -2
  28. data/lib/puppet/external/pson/common.rb +1 -1
  29. data/lib/puppet/external/pson/pure.rb +3 -3
  30. data/lib/puppet/feature/base.rb +3 -0
  31. data/lib/puppet/feature/selinux.rb +3 -0
  32. data/lib/puppet/feature/zlib.rb +6 -0
  33. data/lib/puppet/file_serving/base.rb +16 -1
  34. data/lib/puppet/file_serving/metadata.rb +46 -9
  35. data/lib/puppet/file_serving/mount/file.rb +4 -1
  36. data/lib/puppet/indirector/catalog/active_record.rb +5 -0
  37. data/lib/puppet/indirector/envelope.rb +1 -3
  38. data/lib/puppet/indirector/indirection.rb +13 -16
  39. data/lib/puppet/indirector/node/ldap.rb +7 -4
  40. data/lib/puppet/indirector/ssl_file.rb +1 -1
  41. data/lib/puppet/network/authstore.rb +48 -118
  42. data/lib/puppet/network/client/resource.rb +2 -15
  43. data/lib/puppet/network/format.rb +2 -12
  44. data/lib/puppet/network/format_handler.rb +15 -1
  45. data/lib/puppet/network/formats.rb +19 -4
  46. data/lib/puppet/network/handler/fileserver.rb +1 -0
  47. data/lib/puppet/network/http/handler.rb +1 -0
  48. data/lib/puppet/network/http/rack/httphandler.rb +0 -18
  49. data/lib/puppet/network/http/rack/rest.rb +4 -4
  50. data/lib/puppet/network/http/rack/xmlrpc.rb +4 -4
  51. data/lib/puppet/network/http/webrick.rb +2 -1
  52. data/lib/puppet/network/server.rb +1 -1
  53. data/lib/puppet/node/environment.rb +20 -9
  54. data/lib/puppet/parameter.rb +17 -1
  55. data/lib/puppet/parser/ast/boolean_operator.rb +2 -2
  56. data/lib/puppet/parser/ast/leaf.rb +5 -1
  57. data/lib/puppet/parser/ast/resourceparam.rb +4 -0
  58. data/lib/puppet/parser/ast/selector.rb +4 -0
  59. data/lib/puppet/parser/functions/generate.rb +2 -2
  60. data/lib/puppet/parser/functions/shellquote.rb +1 -1
  61. data/lib/puppet/property.rb +3 -11
  62. data/lib/puppet/provider/cron/crontab.rb +2 -0
  63. data/lib/puppet/provider/host/parsed.rb +9 -9
  64. data/lib/puppet/provider/package/blastwave.rb +7 -6
  65. data/lib/puppet/provider/package/portage.rb +23 -27
  66. data/lib/puppet/provider/package/rug.rb +1 -1
  67. data/lib/puppet/provider/package/sun.rb +5 -3
  68. data/lib/puppet/provider/service/daemontools.rb +1 -1
  69. data/lib/puppet/provider/service/debian.rb +1 -1
  70. data/lib/puppet/provider/service/runit.rb +1 -1
  71. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +2 -1
  72. data/lib/puppet/provider/sshkey/parsed.rb +3 -5
  73. data/lib/puppet/provider/zone/solaris.rb +1 -1
  74. data/lib/puppet/rails.rb +9 -2
  75. data/lib/puppet/rails/benchmark.rb +1 -1
  76. data/lib/puppet/rails/host.rb +2 -7
  77. data/lib/puppet/rails/resource.rb +20 -26
  78. data/lib/puppet/resource/catalog.rb +3 -3
  79. data/lib/puppet/resource/reference.rb +13 -25
  80. data/lib/puppet/ssl/certificate.rb +3 -2
  81. data/lib/puppet/ssl/host.rb +14 -33
  82. data/lib/puppet/sslcertificates.rb +1 -5
  83. data/lib/puppet/sslcertificates/ca.rb +8 -7
  84. data/lib/puppet/transaction.rb +15 -12
  85. data/lib/puppet/type.rb +12 -5
  86. data/lib/puppet/type/file.rb +26 -32
  87. data/lib/puppet/type/file/content.rb +5 -5
  88. data/lib/puppet/type/file/ensure.rb +6 -17
  89. data/lib/puppet/type/file/mode.rb +18 -1
  90. data/lib/puppet/type/file/source.rb +12 -12
  91. data/lib/puppet/type/host.rb +6 -9
  92. data/lib/puppet/type/k5login.rb +1 -1
  93. data/lib/puppet/type/maillist.rb +4 -7
  94. data/lib/puppet/type/port.rb +6 -5
  95. data/lib/puppet/type/resources.rb +12 -12
  96. data/lib/puppet/type/sshkey.rb +5 -5
  97. data/lib/puppet/type/tidy.rb +9 -2
  98. data/lib/puppet/type/yumrepo.rb +3 -1
  99. data/lib/puppet/util.rb +64 -56
  100. data/lib/puppet/util/backups.rb +2 -1
  101. data/lib/puppet/util/filetype.rb +46 -0
  102. data/lib/puppet/util/log.rb +10 -18
  103. data/lib/puppet/util/log_paths.rb +14 -0
  104. data/lib/puppet/util/methodhelper.rb +3 -4
  105. data/lib/puppet/util/monkey_patches.rb +8 -0
  106. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +5 -3
  107. data/lib/puppet/util/rdoc/parser.rb +32 -16
  108. data/lib/puppet/util/reference.rb +6 -3
  109. data/lib/puppet/util/selinux.rb +21 -14
  110. data/lib/puppet/util/settings.rb +30 -25
  111. data/lib/puppet/util/settings/file_setting.rb +7 -4
  112. data/lib/puppet/util/subclass_loader.rb +1 -1
  113. data/lib/puppet/util/suidmanager.rb +11 -1
  114. data/lib/puppet/util/tagging.rb +22 -4
  115. data/man/man8/filebucket.8 +23 -18
  116. data/man/man8/pi.8 +42 -20
  117. data/man/man8/puppet.8 +47 -32
  118. data/man/man8/puppet.conf.8 +807 -764
  119. data/man/man8/puppetca.8 +24 -14
  120. data/man/man8/puppetd.8 +33 -16
  121. data/man/man8/puppetdoc.8 +71 -18
  122. data/man/man8/puppetmasterd.8 +18 -25
  123. data/man/man8/puppetqd.8 +60 -0
  124. data/man/man8/puppetrun.8 +27 -14
  125. data/man/man8/ralsh.8 +33 -40
  126. data/spec/integration/bin/puppetmasterd.rb +3 -2
  127. data/spec/integration/defaults.rb +11 -0
  128. data/spec/integration/file_serving/metadata.rb +1 -0
  129. data/spec/integration/indirector/file_content/file_server.rb +2 -1
  130. data/spec/integration/ssl/certificate_request.rb +2 -0
  131. data/spec/integration/type/file.rb +20 -1
  132. data/spec/shared_behaviours/file_serving.rb +1 -1
  133. data/spec/spec_helper.rb +1 -1
  134. data/spec/unit/application/puppet.rb +11 -30
  135. data/spec/unit/application/puppetd.rb +1 -0
  136. data/spec/unit/application/puppetdoc.rb +13 -4
  137. data/spec/unit/application/puppetmasterd.rb +1 -0
  138. data/spec/unit/application/puppetrun.rb +12 -2
  139. data/spec/unit/application/ralsh.rb +39 -22
  140. data/spec/unit/configurer.rb +6 -0
  141. data/spec/unit/configurer/fact_handler.rb +15 -1
  142. data/spec/unit/file_serving/metadata.rb +128 -16
  143. data/spec/unit/file_serving/mount/file.rb +8 -0
  144. data/spec/unit/indirector/catalog/active_record.rb +20 -1
  145. data/spec/unit/indirector/catalog/compiler.rb +2 -1
  146. data/spec/unit/indirector/indirection.rb +29 -18
  147. data/spec/unit/indirector/node/ldap.rb +20 -6
  148. data/spec/unit/network/authstore.rb +197 -0
  149. data/spec/unit/network/format_handler.rb +28 -8
  150. data/spec/unit/network/formats.rb +31 -0
  151. data/spec/unit/network/http/handler.rb +10 -0
  152. data/spec/unit/network/http/webrick.rb +2 -2
  153. data/spec/unit/network/rest_authconfig.rb +2 -2
  154. data/spec/unit/network/rights.rb +1 -1
  155. data/spec/unit/node/environment.rb +39 -23
  156. data/spec/unit/other/selinux.rb +2 -2
  157. data/spec/unit/parameter.rb +8 -0
  158. data/spec/unit/parser/ast/leaf.rb +9 -0
  159. data/spec/unit/parser/ast/selector.rb +8 -1
  160. data/spec/unit/parser/lexer.rb +1 -1
  161. data/spec/unit/parser/resource.rb +11 -0
  162. data/spec/unit/parser/resource/reference.rb +13 -1
  163. data/spec/unit/property.rb +6 -0
  164. data/spec/unit/provider/mount/parsed.rb +3 -1
  165. data/spec/unit/provider/service/debian.rb +1 -1
  166. data/spec/unit/provider/ssh_authorized_key/parsed.rb +9 -1
  167. data/spec/unit/provider/sshkey/parsed.rb +19 -0
  168. data/spec/unit/rails.rb +22 -9
  169. data/spec/unit/rails/resource.rb +20 -0
  170. data/spec/unit/ssl/host.rb +19 -57
  171. data/spec/unit/transaction.rb +39 -4
  172. data/spec/unit/type.rb +9 -0
  173. data/spec/unit/type/file/content.rb +29 -0
  174. data/spec/unit/type/maillist.rb +42 -0
  175. data/spec/unit/type/resources.rb +66 -1
  176. data/spec/unit/type/tidy.rb +14 -1
  177. data/spec/unit/util/autoload.rb +2 -0
  178. data/spec/unit/util/ldap/connection.rb +1 -1
  179. data/spec/unit/util/log.rb +14 -0
  180. data/spec/unit/util/monkey_patches.rb +103 -0
  181. data/spec/unit/util/queue.rb +10 -2
  182. data/spec/unit/util/selinux.rb +61 -2
  183. data/spec/unit/util/settings.rb +19 -0
  184. data/spec/unit/util/settings/file_setting.rb +25 -0
  185. data/spec/unit/util/tagging.rb +10 -0
  186. data/tasks/rake/changelog.rake +15 -0
  187. data/tasks/rake/ci.rake +22 -0
  188. data/tasks/rake/dailybuild.rake +9 -0
  189. data/tasks/rake/gem.rake +46 -0
  190. data/tasks/rake/git_workflow.rake +121 -0
  191. data/tasks/rake/metrics.rake +6 -0
  192. data/tasks/rake/sign.rake +14 -0
  193. data/tasks/rake/testbranch.rake +16 -0
  194. data/tasks/rake/tracdocs.rake +8 -0
  195. data/test/data/providers/ssh_authorized_key/parsed/authorized_keys +1 -0
  196. metadata +1042 -1288
  197. data/ext/bin/sleeper +0 -67
  198. data/ext/module_puppet +0 -209
@@ -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
- # Hard-code yaml, because I couldn't get marshal to work.
32
- format = :b64_zlib_yaml
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 => :b64_zlib_yaml, :facts => CGI.escape(text)}
38
+ return {:facts_format => format, :facts => CGI.escape(text)}
37
39
  end
38
40
 
39
41
  # Retrieve facts from the central server.
@@ -31,10 +31,10 @@ class Puppet::Daemon
31
31
  $stderr.reopen $stdout
32
32
  Puppet::Util::Log.reopen
33
33
  rescue => detail
34
- File.open("/tmp/daemonout", "w") { |f|
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
@@ -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; wheter or not puppetd should validate the server
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
@@ -48,7 +48,7 @@ module PSON
48
48
  case
49
49
  when c.empty? then p
50
50
  when p.const_defined?(c) then p.const_get(c)
51
- else raise ArgumentError, "can't find const #{path}"
51
+ else raise ArgumentError, "can't find const for unregistered document type #{path}"
52
52
  end
53
53
  end
54
54
  end
@@ -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
- raise MissingUnicodeSupport,
15
- "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
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
- raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
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
@@ -28,3 +28,6 @@ Puppet.features.add(:augeas, :libs => ["augeas"])
28
28
 
29
29
  # We have RRD available
30
30
  Puppet.features.add(:rrd, :libs => ["RRDtool"])
31
+
32
+ # We have OpenSSL
33
+ Puppet.features.add(:openssl, :libs => ["openssl"])
@@ -0,0 +1,3 @@
1
+ require 'puppet/util/feature'
2
+
3
+ Puppet.features.add(:selinux, :libs => ["selinux"])
@@ -0,0 +1,6 @@
1
+ require 'puppet/util/feature'
2
+
3
+ # We want this to load if possible, but it's not automatically
4
+ # required.
5
+ Puppet.features.rubygems?
6
+ Puppet.features.add(:zlib, :libs => %{zlib})
@@ -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
- case ftype
32
- when "file", "directory"; desc << checksum
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(*args)
75
- @checksum_type = "md5"
76
- super
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
- return nil unless FileTest.exist?(file)
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
@@ -6,8 +6,6 @@ module Puppet::Indirector::Envelope
6
6
  attr_accessor :expiration
7
7
 
8
8
  def expired?
9
- return false unless expiration
10
- return false if expiration >= Time.now
11
- return true
9
+ expiration and expiration < Time.now
12
10
  end
13
11
  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 don't actually
165
- # remove it, we expire it and write it back out to disk. This way people
166
- # can still use the expired object if they want.
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
- request = request(:expire, key, *args)
169
-
170
- return nil unless cache?
171
-
172
- return nil unless instance = cache.find(request(:find, key, *args))
173
-
174
- Puppet.info "Expiring the %s cache of %s" % [self.name, instance.name]
175
-
176
- # Set an expiration date in the past
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 %s for %s" % [self.name, request.key]
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
- result[:name] = entry.dn.split(',')[0].split("=")[1]
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
- self.info "defaulting to no access for %s" % name
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 do |ace|
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
- return Thread.current[:declarations] if Thread.current[:declarations]
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 specially.
128
+ # Sort the declarations most specific first.
134
129
  def <=>(other)
135
- # Sort first based on whether the matches are exact.
136
- if r = compare(exact?, other.exact?)
137
- return r
138
- end
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
- self.type == :deny
138
+ type == :deny
168
139
  end
169
140
 
170
- # Are we an exact match?
171
141
  def exact?
172
- self.length.nil?
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
- self.name == :ip
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
- if self.ip?
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
- case @type
203
- when :allow; true
204
- else
205
- false
206
- end
168
+ type == :allow
207
169
  end
208
170
 
209
171
  def to_s
210
- "%s: %s" % [self.type, self.pattern]
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
- unless me and them
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
- return true if self.pattern == name
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 x = name.downcase.split(".",-1).reverse for FQDN support
279
- x = name.downcase.split(".").reverse
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
- # Use the IPAddr class to determine if we've got a
286
- # valid IP address.
287
- @length = Integer($1) if value =~ /\/(\d+)$/
288
- begin
289
- @pattern = IPAddr.new(value)
290
- @name = :ip
291
- rescue ArgumentError => detail
292
- case value
293
- when /^(\d+\.){1,3}\*$/ # an ip address with a '*' at the end
294
- @name = :ip
295
- segments = value.split(".")[0..-2]
296
- @length = 8*segments.length
297
- begin
298
- @pattern = IPAddr.new((segments+[0,0,0])[0,4].join(".") + "/" + @length.to_s)
299
- rescue ArgumentError => detail
300
- raise AuthStoreError, "Invalid IP address pattern %s" % value
301
- end
302
- when /^([a-zA-Z0-9][-\w]*\.)+[-\w]+$/ # a full hostname
303
- # Change to /^([a-zA-Z][-\w]*\.)+[-\w]+\.?$/ for FQDN support
304
- @name = :domain
305
- @pattern = munge_name(value)
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