summaryrefslogtreecommitdiffstats
path: root/lib/puppet/resource.rb
blob: db06667e77132257c80012af2b52c25c912dd792 (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
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

    # 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

    # 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
        @parameters.dup
    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.create(self)
        else
            return Puppet::Type::Component.create(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

    # 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

    # Produce a canonical method name.
    def parameter_name(param)
        param.to_s.downcase.to_sym
    end
end