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