Issue #17133 has been updated by Deepak Giridharagopal.
This is also related to #651, which moves onlyif and unless from being exec-specific into proper metaparameters. ---------------------------------------- Feature #17133: Support validation of file resources via an external command https://projects.puppetlabs.com/issues/17133#change-92217 * 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.
