diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/transaction/change.rb | 16 | ||||
-rw-r--r-- | lib/puppet/transaction/event.rb | 2 | ||||
-rw-r--r-- | lib/puppet/transaction/resource_harness.rb | 31 | ||||
-rw-r--r-- | lib/puppet/type.rb | 82 |
4 files changed, 86 insertions, 45 deletions
diff --git a/lib/puppet/transaction/change.rb b/lib/puppet/transaction/change.rb index 6ecb93c37..605457a21 100644 --- a/lib/puppet/transaction/change.rb +++ b/lib/puppet/transaction/change.rb @@ -4,7 +4,11 @@ require 'puppet/transaction/event' # Handle all of the work around performing an actual change, # including calling 'sync' on the properties and producing events. class Puppet::Transaction::Change - attr_accessor :is, :should, :property, :proxy + attr_accessor :is, :should, :property, :proxy, :auditing + + def auditing? + auditing + end # Create our event object. def event @@ -24,6 +28,7 @@ class Puppet::Transaction::Change end def apply + return audit_event if auditing? return noop_event if noop? property.sync @@ -63,6 +68,15 @@ class Puppet::Transaction::Change private + def audit_event + # This needs to store the appropriate value, and then produce a new event + result = event + result.message = "audit change: previously recorded value #{property.should_to_s(should)} has been changed to #{property.is_to_s(is)}" + result.status = "audit" + result.send_log + return result + end + def noop_event result = event result.message = "is #{property.is_to_s(is)}, should be #{property.should_to_s(should)} (noop)" diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb index b962149cf..bc589fe84 100644 --- a/lib/puppet/transaction/event.rb +++ b/lib/puppet/transaction/event.rb @@ -13,7 +13,7 @@ class Puppet::Transaction::Event attr_accessor :time attr_reader :default_log_level - EVENT_STATUSES = %w{noop success failure} + EVENT_STATUSES = %w{noop success failure audit} def initialize(*args) options = args.last.is_a?(Hash) ? args.pop : ATTRIBUTES.inject({}) { |hash, attr| hash[attr] = args.pop; hash } diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb index 17e8dfa79..ae38bcb66 100644 --- a/lib/puppet/transaction/resource_harness.rb +++ b/lib/puppet/transaction/resource_harness.rb @@ -19,6 +19,10 @@ class Puppet::Transaction::ResourceHarness def apply_changes(status, changes) changes.each do |change| status << change.apply + + if change.auditing? + cache(change.property.resource, change.property.name, change.is) + end end status.changed = true end @@ -40,6 +44,8 @@ class Puppet::Transaction::ResourceHarness return [] if ! allow_changes?(resource) + audited = copy_audited_parameters(resource, current) + if param = resource.parameter(:ensure) return [] if absent_and_not_being_created?(current, param) return [Puppet::Transaction::Change.new(param, current[:ensure])] unless ensure_is_insync?(current, param) @@ -47,12 +53,33 @@ class Puppet::Transaction::ResourceHarness end resource.properties.reject { |p| p.name == :ensure }.reject do |param| - param.should.nil? + param.should.nil? end.reject do |param| param_is_insync?(current, param) end.collect do |param| - Puppet::Transaction::Change.new(param, current[param.name]) + change = Puppet::Transaction::Change.new(param, current[param.name]) + change.auditing = true if audited.include?(param.name) + change + end + end + + def copy_audited_parameters(resource, current) + return [] unless audit = resource[:audit] + audit = Array(audit).collect { |p| p.to_sym } + audited = [] + audit.find_all do |param| + next if resource[param] + + if value = cached(resource, param) + resource[param] = value + audited << param + else + resource.notice "Storing newly-audited value #{current[param]} for #{param}" + cache(resource, param, current[param]) + end end + + audited end def evaluate(resource) diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index fc6161735..17d6b2a10 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -1020,55 +1020,55 @@ class Type configuration before objects that use it." end - newmetaparam(:check) do - desc "Properties which should have their values retrieved - but which should not actually be modified. This is currently used - internally, but will eventually be used for querying, so that you - could specify that you wanted to check the install state of all - packages, and then query the Puppet client daemon to get reports - on all packages." - - munge do |args| - # If they've specified all, collect all known properties - if args == :all - args = @resource.class.properties.find_all do |property| - # Only get properties supported by our provider - if @resource.provider - @resource.provider.class.supports_parameter?(property) - else - true - end - end.collect do |property| - property.name + newmetaparam(:audit) do + desc "Audit specified attributes of resources over time, and report if any have changed. + This attribute can be used to track changes to any resource over time, and can + provide an audit trail of every change that happens on any given machine. + + Note that you cannot both audit and manage an attribute - managing it guarantees + the value, and any changes already get logged." + + validate do |list| + list = Array(list) + unless list == [:all] + list.each do |param| + next if @resource.class.validattr?(param) + fail "Cannot audit #{param}: not a valid attribute for #{resource}" end end + end - unless args.is_a?(Array) - args = [args] + munge do |args| + properties_to_audit(args).each do |param| + next unless resource.class.validproperty?(param) + resource.newattr(param) end + end - unless defined? @resource - self.devfail "No parent for %s, %s?" % - [self.class, self.name] + def all_properties + resource.class.properties.find_all do |property| + resource.provider.nil? or resource.provider.class.supports_parameter?(property) + end.collect do |property| + property.name + end + end + + def properties_to_audit(list) + if list == :all + list = all_properties() if list == :all + else + list = Array(list).collect { |p| p.to_sym } end + end + end - args.each { |property| - unless property.is_a?(Symbol) - property = property.intern - end - next if @resource.propertydefined?(property) + newmetaparam(:check) do + desc "Audit specified attributes of resources over time, and report if any have changed. + This parameter has been deprecated in favor of 'audit'." - unless propertyklass = @resource.class.validproperty?(property) - if @resource.class.validattr?(property) - next - else - raise Puppet::Error, "%s is not a valid attribute for %s" % - [property, self.class.name] - end - end - next unless propertyklass.checkable? - @resource.newattr(property) - } + munge do |args| + resource.warning "'check' attribute is deprecated; use 'audit' instead" + resource[:audit] = args end end |