Update stdlib and concat to 6.1.0 both
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / validate_augeas.rb
1 require 'tempfile'
2
3 #
4 # validate_augaes.rb
5 #
6 module Puppet::Parser::Functions
7   newfunction(:validate_augeas, :doc => <<-DOC
8     @summary
9       Perform validation of a string using an Augeas lens
10
11     The first argument of this function should be a string to
12     test, and the second argument should be the name of the Augeas lens to use.
13     If Augeas fails to parse the string with the lens, the compilation will
14     abort with a parse error.
15
16     A third argument can be specified, listing paths which should
17     not be found in the file. The `$file` variable points to the location
18     of the temporary file being tested in the Augeas tree.
19
20     @return
21       validate string using an Augeas lens
22
23     @example **Usage**
24
25       If you want to make sure your passwd content never contains
26       a user `foo`, you could write:
27
28         validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo'])
29
30       If you wanted to ensure that no users used the '/bin/barsh' shell,
31       you could use:
32
33         validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]']
34
35       If a fourth argument is specified, this will be the error message raised and
36       seen by the user.
37
38       A helpful error message can be returned like this:
39
40         validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas')
41
42     DOC
43              ) do |args|
44     unless Puppet.features.augeas?
45       raise Puppet::ParseError, 'validate_augeas(): this function requires the augeas feature. See http://docs.puppetlabs.com/guides/augeas.html#pre-requisites for how to activate it.'
46     end
47
48     if (args.length < 2) || (args.length > 4)
49       raise Puppet::ParseError, "validate_augeas(): wrong number of arguments (#{args.length}; must be 2, 3, or 4)"
50     end
51
52     msg = args[3] || "validate_augeas(): Failed to validate content against #{args[1].inspect}"
53
54     require 'augeas'
55     aug = Augeas.open(nil, nil, Augeas::NO_MODL_AUTOLOAD)
56     begin
57       content = args[0]
58
59       # Test content in a temporary file
60       tmpfile = Tempfile.new('validate_augeas')
61       begin
62         tmpfile.write(content)
63       ensure
64         tmpfile.close
65       end
66
67       # Check for syntax
68       lens = args[1]
69       aug.transform(
70         :lens => lens,
71         :name => 'Validate_augeas',
72         :incl => tmpfile.path,
73       )
74       aug.load!
75
76       unless aug.match("/augeas/files#{tmpfile.path}//error").empty?
77         error = aug.get("/augeas/files#{tmpfile.path}//error/message")
78         msg += " with error: #{error}"
79         raise Puppet::ParseError, msg
80       end
81
82       # Launch unit tests
83       tests = args[2] || []
84       aug.defvar('file', "/files#{tmpfile.path}")
85       tests.each do |t|
86         msg += " testing path #{t}"
87         raise Puppet::ParseError, msg unless aug.match(t).empty?
88       end
89     ensure
90       aug.close
91       tmpfile.unlink
92     end
93   end
94 end