1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
require 'puppet'
require 'puppet/parser/ast/branch'
require 'puppet/parser/collector'
# An object that collects stored objects from the central cache and returns
# them to the current host, yo.
class Puppet::Parser::AST
class CollExpr < AST::Branch
attr_accessor :test1, :test2, :oper, :form, :type, :parens
# We return an object that does a late-binding evaluation.
def evaluate(scope)
# Make sure our contained expressions have all the info they need.
[@test1, @test2].each do |t|
if t.is_a?(self.class)
t.form ||= self.form
t.type ||= self.type
end
end
# The code is only used for virtual lookups
str1, code1 = @test1.safeevaluate scope
str2, code2 = @test2.safeevaluate scope
# First build up the virtual code.
# If we're a conjunction operator, then we're calling code. I did
# some speed comparisons, and it's at least twice as fast doing these
# case statements as doing an eval here.
code = proc do |resource|
case @oper
when "and"; code1.call(resource) and code2.call(resource)
when "or"; code1.call(resource) or code2.call(resource)
when "=="
if str1 == "tag"
resource.tagged?(str2)
else
if resource[str1].is_a?(Array)
resource[str1].include?(str2)
else
resource[str1] == str2
end
end
when "!="; resource[str1] != str2
end
end
# Now build up the rails conditions code
if self.parens and self.form == :exported
Puppet.warning "Parentheses are ignored in Rails searches"
end
case @oper
when "and", "or"
if form == :exported
raise Puppet::ParseError, "Puppet does not currently support collecting exported resources with more than one condition"
end
oper = @oper.upcase
when "=="; oper = "="
else
oper = @oper
end
if oper == "=" or oper == "!="
# Add the rails association info where necessary
case str1
when "title"
str = "title #{oper} '#{str2}'"
when "tag"
str = "puppet_tags.name #{oper} '#{str2}'"
else
str = "param_values.value #{oper} '#{str2}' and param_names.name = '#{str1}'"
end
else
str = "(#{str1}) #{oper} (#{str2})"
end
return str, code
end
def initialize(hash = {})
super
raise ArgumentError, "Invalid operator #{@oper}" unless %w{== != and or}.include?(@oper)
end
end
end
|