Issue #17133 has been updated by Charlie Sharpsteen.

Keywords changed from backlog to backlog customer

----------------------------------------
Feature #17133: Support validation of file resources via an external command
https://projects.puppetlabs.com/issues/17133#change-88275

* Author: Christopher Layne
* Status: Accepted
* Priority: Normal
* Assignee: eric sorenson
* Category: 
* Target version: 3.x
* Affected Puppet version: 2.7.14
* Keywords: backlog customer
* 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 unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to