Issue #17133 has been reported by Christopher Layne.
----------------------------------------
Feature #17133: Support validation of file resources via an external command
https://projects.puppetlabs.com/issues/17133
Author: Christopher Layne
Status: Unreviewed
Priority: Normal
Assignee:
Category:
Target version:
Affected Puppet version: 2.7.14
Keywords:
Branch:
Presently, we use quite a few classes which generate config files from
templates that make heavy use of external data. Such templates (and any
template for that matter, really) are prone to generation of content which may
either by syntactically invalid (due to logic issues in the erb-valid template)
or syntactically valid but not parseable/loadable by services dependent on said
content.
Real world examples:
sudoers
sshd_config
httpd.conf
named.conf
my.cnf
Generation of an invalid config file and the associated notify to the service
using said config file results in an outage of said service in the majority of
cases. As a result, we use a simple define called safe_template:
<pre>
# = Class: core::util::safe_template
#
# Manages templates in a safe fashion by running a post-validation command.
#
# = Parameters
#
# Anything normally related to a File resource.
#
# = Actions
#
# Writes out a staging config file, runs a validation command, and if it
passes,
# copies the staging file to the live location and triggers the $notify
passed in.
#
# = Requires
#
# Same parameters as a normal File resource. If no validation key is passed
in,
# it defaults to "/bin/true".
#
# = Sample Usage
#
# core::util::safe_template { "sshd_config":
# path => "/etc/ssh/sshd_config",
# content => template("ssh/sshd_config.erb"),
# validate => "/usr/sbin/sshd -tf",
# }
#
define core::util::safe_template($path = undef,
$owner = undef,
$group = undef,
$ensure = undef,
$mode = undef,
$notify = undef,
$content = undef,
$validate = "/bin/true")
{
# 0. Synthesize the staging file as $name.puppet or $path.puppet
$real_file = $path ? { /^./ => $path, default => $name }
$stage_file = "${real_file}.puppet"
# 1. Get the staging content from the server
file { $name:
path => $stage_file,
owner => $owner,
group => $group,
mode => $mode,
ensure => $ensure,
content => $content,
}
# 2. Do a syntax check on the staging file and update if validation
passed
exec { "${name}_safe_update":
path => "/usr/sbin:/usr/bin:/sbin:/bin",
unless => "cmp -s $stage_file $real_file",
command => "$validate $stage_file && cp -pf $stage_file
$real_file",
require => File[$name],
notify => $notify,
}
}
</pre>
Now, the built-in file type overlaps with quite a bit of behavior above but
lacks the facilities of the exec type (and knowledge of the 'validate'
parameter) for which to take advantage of a similar construct. The feature
request here is for the support of a 'validate' parameter which would run an
external command on the internally generated temp file and fail immediately if
said command returns false. This would cut out the middle man define used above
and provide a language supported facility for doing the same thing naturally
with existing files resources.
It appears the actual method where this could be implemented most sanely is in
the write() method of the file type (type/file.rb). It would need to pull in
functionality from the exec type (particularly the command and path validation
logic). For the majority of commands which are able to validate configs with
some kind of -t (test) and -f (file) or similar flags, implementation for
existing resources is straightforward and easy for the end-user (just add a
'validate' parameter). For commands which require some non-idiomatic usage of
flags for which to validate a given config file, end-users are free to write a
wrapper and require said wrapper as part of a manifest's logic.
I'm not sure how PATH handling should be done (or if supported), but perhaps
use of the standard 'path' param would suffice. Without it users can just call
a fully qualified command.
--
You have received this notification because you have either subscribed to it,
or are involved in it.
To change your notification preferences, please click here:
http://projects.puppetlabs.com/my/account
--
You received this message because you are subscribed to the Google Groups
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-bugs?hl=en.