Add logrotate cookbook
This commit is contained in:
88
cookbooks/logrotate/libraries/logrotate_config.rb
Normal file
88
cookbooks/logrotate/libraries/logrotate_config.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
#
|
||||
# Cookbook Name:: logrotate
|
||||
# Library:: CookbookLogrotate
|
||||
#
|
||||
# Copyright 2013, Chef
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# Helper module for Logrotate configuration module CookbookLogrotate
|
||||
module CookbookLogrotate
|
||||
DIRECTIVES = %w(compress copy copytruncate daily dateext
|
||||
dateyesterday delaycompress hourly ifempty mailfirst maillast
|
||||
missingok monthly nocompress nocopy nocopytruncate nocreate
|
||||
nodelaycompress nodateext nomail nomissingok noolddir
|
||||
nosharedscripts noshred notifempty sharedscripts shred weekly
|
||||
yearly) unless const_defined?(:DIRECTIVES)
|
||||
|
||||
VALUES = %w(compresscmd uncompresscmd compressext compressoptions
|
||||
create dateformat include mail extension maxage minsize maxsize
|
||||
rotate size shredcycles start tabooext su olddir) unless const_defined?(:VALUES)
|
||||
|
||||
SCRIPTS = %w(firstaction prerotate postrotate lastaction preremove) unless const_defined?(:SCRIPTS)
|
||||
|
||||
DIRECTIVES_AND_VALUES = DIRECTIVES + VALUES unless const_defined?(:DIRECTIVES_AND_VALUES)
|
||||
|
||||
# Helper class for creating configurations
|
||||
class LogrotateConfiguration
|
||||
attr_reader :directives, :values, :paths
|
||||
|
||||
class << self
|
||||
def from_hash(hash)
|
||||
new(hash)
|
||||
end
|
||||
|
||||
def directives_from(hash)
|
||||
hash.select { |k, v| DIRECTIVES.include?(k) && v }.keys
|
||||
end
|
||||
|
||||
def values_from(hash)
|
||||
hash.select { |k| VALUES.include?(k) }
|
||||
end
|
||||
|
||||
def paths_from(hash)
|
||||
hash.select { |k| !(DIRECTIVES_AND_VALUES.include?(k)) }.reduce({}) do | accum_paths, (path, config) |
|
||||
accum_paths[path] = {
|
||||
'directives' => directives_from(config),
|
||||
'values' => values_from(config),
|
||||
'scripts' => scripts_from(config)
|
||||
}
|
||||
|
||||
accum_paths
|
||||
end
|
||||
end
|
||||
|
||||
def scripts_from(hash)
|
||||
defined_scripts = hash.select { |k| SCRIPTS.include?(k) }
|
||||
defined_scripts.reduce({}) do | accum_scripts, (script, lines) |
|
||||
if lines.respond_to?(:join)
|
||||
accum_scripts[script] = lines.join("\n")
|
||||
else
|
||||
accum_scripts[script] = lines
|
||||
end
|
||||
|
||||
accum_scripts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(hash)
|
||||
@directives = LogrotateConfiguration.directives_from(hash)
|
||||
@values = LogrotateConfiguration.values_from(hash)
|
||||
@paths = LogrotateConfiguration.paths_from(hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
154
cookbooks/logrotate/libraries/matchers.rb
Normal file
154
cookbooks/logrotate/libraries/matchers.rb
Normal file
@@ -0,0 +1,154 @@
|
||||
if defined?(ChefSpec)
|
||||
def enable_logrotate_app(name)
|
||||
LogrotateAppMatcher.new(name)
|
||||
end
|
||||
|
||||
class LogrotateAppMatcher
|
||||
def initialize(name)
|
||||
@name = name
|
||||
end
|
||||
|
||||
def with(parameters = {})
|
||||
params.merge!(parameters)
|
||||
self
|
||||
end
|
||||
|
||||
def at_compile_time
|
||||
raise ArgumentError, 'Cannot specify both .at_converge_time and .at_compile_time!' if @converge_time
|
||||
@compile_time = true
|
||||
self
|
||||
end
|
||||
|
||||
def at_converge_time
|
||||
raise ArgumentError, 'Cannot specify both .at_compile_time and .at_converge_time!' if @compile_time
|
||||
@converge_time = true
|
||||
self
|
||||
end
|
||||
|
||||
#
|
||||
# Allow users to specify fancy #with matchers.
|
||||
#
|
||||
def method_missing(m, *args, &block)
|
||||
if m.to_s =~ /^with_(.+)$/
|
||||
with($1.to_sym => args.first)
|
||||
self
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def description
|
||||
%Q{"enable" #{@name} "logrotate_app"}
|
||||
end
|
||||
|
||||
def matches?(runner)
|
||||
@runner = runner
|
||||
|
||||
if resource
|
||||
resource.performed_action?('create') && unmatched_parameters.empty? && correct_phase?
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message
|
||||
if resource
|
||||
if resource.performed_action?('create')
|
||||
if unmatched_parameters.empty?
|
||||
if @compile_time
|
||||
%Q{expected "#{resource}" to be run at compile time}
|
||||
else
|
||||
%Q{expected "#{resource}" to be run at converge time}
|
||||
end
|
||||
else
|
||||
%Q{expected "#{resource}" to have parameters:} \
|
||||
"\n\n" \
|
||||
" " + unmatched_parameters.collect { |parameter, h|
|
||||
"#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
|
||||
}.join("\n ")
|
||||
end
|
||||
else
|
||||
%Q{expected "#{resource}" actions #{resource.performed_actions.inspect}} \
|
||||
" to include : create"
|
||||
end
|
||||
else
|
||||
%Q{expected "logrotate_app[#{@name}] with"} \
|
||||
" enable : true to be in Chef run. Other" \
|
||||
" #{@name} resources:" \
|
||||
"\n\n" \
|
||||
" " + similar_resources.map(&:to_s).join("\n ") + "\n "
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message_when_negated
|
||||
if resource
|
||||
message = %Q{expected "#{resource}" actions #{resource.performed_actions.inspect} to not exist}
|
||||
else
|
||||
message = %Q{expected "#{resource}" to not exist}
|
||||
end
|
||||
|
||||
message << " at compile time" if @compile_time
|
||||
message << " at converge time" if @converge_time
|
||||
message
|
||||
end
|
||||
|
||||
private
|
||||
def unmatched_parameters
|
||||
return @_unmatched_parameters if @_unmatched_parameters
|
||||
|
||||
@_unmatched_parameters = {}
|
||||
|
||||
params.each do |parameter, expected|
|
||||
unless matches_parameter?(parameter, expected)
|
||||
@_unmatched_parameters[parameter] = {
|
||||
:expected => expected,
|
||||
:actual => safe_send(parameter),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@_unmatched_parameters
|
||||
end
|
||||
|
||||
def matches_parameter?(parameter, expected)
|
||||
# Chef 11+ stores the source parameter internally as an Array
|
||||
#
|
||||
case parameter
|
||||
when :cookbook
|
||||
expected === safe_send(parameter)
|
||||
when :path
|
||||
Array(expected == safe_send('variables')[parameter])
|
||||
else
|
||||
expected == safe_send('variables')[parameter]
|
||||
end
|
||||
end
|
||||
|
||||
def correct_phase?
|
||||
if @compile_time
|
||||
resource.performed_action('create')[:compile_time]
|
||||
elsif @converge_time
|
||||
resource.performed_action('create')[:converge_time]
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def safe_send(parameter)
|
||||
resource.send(parameter)
|
||||
rescue NoMethodError
|
||||
nil
|
||||
end
|
||||
|
||||
def similar_resources
|
||||
@_similar_resources ||= @runner.find_resources('template')
|
||||
end
|
||||
|
||||
def resource
|
||||
@_resource ||= @runner.find_resource('template', "/etc/logrotate.d/#{@name}")
|
||||
end
|
||||
|
||||
def params
|
||||
@_params ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user