summaryrefslogtreecommitdiffstats
path: root/lib/puppet/resource.rb
blob: add32b7cf5a74b2fcafaa20b58cae4ef0ab19829 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
require 'puppet'
require 'puppet/util/tagging'
require 'puppet/resource/reference'

# The simplest resource class.  Eventually it will function as the
# base class for all resource-like behaviour.
class Puppet::Resource
    include Puppet::Util::Tagging
    include Enumerable
    attr_accessor :type, :title, :file, :line, :catalog, :implicit

    # Proxy these methods to the parameters hash.  It's likely they'll
    # be overridden at some point, but this works for now.
    %w{has_key? keys length delete empty? <<}.each do |method|
        define_method(method) do |*args|
            @parameters.send(method, *args)
        end
    end

    # Set a given parameter.  Converts all passed names
    # to lower-case symbols.
    def []=(param, value)
        @parameters[parameter_name(param)] = value
    end

    # Return a given parameter's value.  Converts all passed names
    # to lower-case symbols.
    def [](param)
        @parameters[parameter_name(param)]
    end

    # Compatibility method.
    def builtin?
        builtin_type?
    end

    # Is this a builtin resource type?
    def builtin_type?
        @reference.builtin_type?
    end

    # Iterate over each param/value pair, as required for Enumerable.
    def each
        @parameters.each { |p,v| yield p, v }
    end

    # Create our resource.
    def initialize(type, title, parameters = {})
        @reference = Puppet::Resource::Reference.new(type, title)
        @parameters = {}

        parameters.each do |param, value|
            self[param] = value
        end

        tag(@reference.type)
        tag(@reference.title) if valid_tag?(@reference.title)
    end

    # Provide a reference to our resource in the canonical form.
    def ref
        @reference.to_s
    end

    # Get our title information from the reference, since it will canonize it for us.
    def title
        @reference.title
    end

    # Get our type information from the reference, since it will canonize it for us.
    def type
        @reference.type
    end

    # Produce a simple hash of our parameters.
    def to_hash
        result = @parameters.dup
        unless result.include?(namevar)
            result[namevar] = title
        end
        if result.has_key?(nil)
            raise "wtf? %s" % namevar.inspect
        end
        result
    end

    def to_s
        return ref
    end

    # Convert our resource to Puppet code.
    def to_manifest
        "%s { '%s':\n%s\n}" % [self.type.to_s.downcase, self.title,
             @parameters.collect { |p, v|
                 if v.is_a? Array
                     "    #{p} => [\'#{v.join("','")}\']"
                 else
                     "    #{p} => \'#{v}\'"
                 end
             }.join(",\n")
            ]
    end

    def to_ref
        ref
    end

    # Convert our resource to a RAL resource instance.  Creates component
    # instances for resource types that don't exist.
    def to_ral
        if typeklass = Puppet::Type.type(self.type)
            return typeklass.new(self)
        else
            return Puppet::Type::Component.new(self)
        end
    end

    # Translate our object to a backward-compatible transportable object.
    def to_trans
        if @reference.builtin_type?
            result = to_transobject
        else
            result = to_transbucket
        end

        result.file = self.file
        result.line = self.line

        return result
    end

    # Create an old-style TransObject instance, for builtin resource types.
    def to_transobject
        # Now convert to a transobject
        result = Puppet::TransObject.new(@reference.title, @reference.type)
        to_hash.each do |p, v|
            if v.is_a?(Puppet::Resource::Reference)
                v = v.to_trans_ref
            elsif v.is_a?(Array)
                v = v.collect { |av|
                    if av.is_a?(Puppet::Resource::Reference)
                        av = av.to_trans_ref
                    end
                    av
                }
            end

            # If the value is an array with only one value, then
            # convert it to a single value.  This is largely so that
            # the database interaction doesn't have to worry about
            # whether it returns an array or a string.
            result[p.to_s] = if v.is_a?(Array) and v.length == 1
                              v[0]
                          else
                              v
                          end
        end

        result.tags = self.tags

        return result
    end

    private

    # Produce a canonical method name.
    def parameter_name(param)
        param = param.to_s.downcase.to_sym
        if param == :name and n = namevar()
            param = namevar
        end
        param
    end

    # The namevar for our resource type. If the type doesn't exist,
    # always use :name.
    def namevar
        if t = resource_type
            t.namevar
        else
            :name
        end
    end

    # Retrieve the resource type.
    def resource_type
        Puppet::Type.type(type)
    end

    # Create an old-style TransBucket instance, for non-builtin resource types.
    def to_transbucket
        bucket = Puppet::TransBucket.new([])

        bucket.type = self.type
        bucket.name = self.title

        # TransBuckets don't support parameters, which is why they're being deprecated.
        return bucket
    end
end