~ubuntu-branches/ubuntu/lucid/puppet/lucid-security

« back to all changes in this revision

Viewing changes to lib/puppet/indirector/indirection.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
require 'puppet/util/docs'
2
2
require 'puppet/indirector/envelope'
3
3
require 'puppet/indirector/request'
 
4
require 'puppet/util/cacher'
4
5
 
5
6
# The class that connects functional classes with their different collection
6
7
# back-ends.  Each indirection has a set of associated terminus classes,
7
8
# each of which is a subclass of Puppet::Indirector::Terminus.
8
9
class Puppet::Indirector::Indirection
 
10
    include Puppet::Util::Cacher
9
11
    include Puppet::Util::Docs
10
12
 
11
13
    @@indirections = []
12
14
 
13
 
    # Clear all cached termini from all indirections.
14
 
    def self.clear_cache
15
 
        @@indirections.each { |ind| ind.clear_cache }
16
 
    end
17
 
 
18
15
    # Find an indirection by name.  This is provided so that Terminus classes
19
16
    # can specifically hook up with the indirections they are associated with.
20
17
    def self.instance(name)
26
23
    def self.instances
27
24
        @@indirections.collect { |i| i.name }
28
25
    end
29
 
    
 
26
 
30
27
    # Find an indirected model by name.  This is provided so that Terminus classes
31
28
    # can specifically hook up with the indirections they are associated with.
32
29
    def self.model(name)
33
30
        return nil unless match = @@indirections.find { |i| i.name == name }
34
31
        match.model
35
32
    end
36
 
    
 
33
 
37
34
    attr_accessor :name, :model
38
35
 
39
36
    # Create and return our cache terminus.
50
47
    attr_reader :cache_class
51
48
    # Define a terminus class to be used for caching.
52
49
    def cache_class=(class_name)
53
 
        validate_terminus_class(class_name)
 
50
        validate_terminus_class(class_name) if class_name
54
51
        @cache_class = class_name
55
52
    end
56
53
 
57
 
    # Clear our cached list of termini, and reset the cache name
58
 
    # so it's looked up again.
59
 
    # This is only used for testing.
60
 
    def clear_cache
61
 
        @termini.clear
62
 
    end
63
 
 
64
54
    # This is only used for testing.
65
55
    def delete
66
56
        @@indirections.delete(self) if @@indirections.include?(self)
104
94
        @model = model
105
95
        @name = name
106
96
 
107
 
        @termini = {}
108
97
        @cache_class = nil
109
98
        @terminus_class = nil
110
99
 
137
126
        unless terminus_name ||= terminus_class
138
127
            raise Puppet::DevError, "No terminus specified for %s; cannot redirect" % self.name
139
128
        end
140
 
        
141
 
        return @termini[terminus_name] ||= make_terminus(terminus_name)
 
129
 
 
130
        return termini[terminus_name] ||= make_terminus(terminus_name)
142
131
    end
143
132
 
144
133
    # This can be used to select the terminus class.
196
185
        request = request(:find, key, *args)
197
186
        terminus = prepare(request)
198
187
 
199
 
        # See if our instance is in the cache and up to date.
200
 
        if cache? and cached = cache.find(request)
201
 
            if cached.expired?
202
 
                Puppet.info "Not using expired %s for %s from cache; expired at %s" % [self.name, request.key, cached.expiration]
203
 
            else
204
 
                Puppet.debug "Using cached %s for %s" % [self.name, request.key]
205
 
                return cached
 
188
        begin
 
189
            if result = find_in_cache(request)
 
190
                return result
206
191
            end
 
192
        rescue => detail
 
193
            puts detail.backtrace if Puppet[:trace]
 
194
            Puppet.err "Cached %s for %s failed: %s" % [self.name, request.key, detail]
207
195
        end
208
196
 
209
197
        # Otherwise, return the result from the terminus, caching if appropriate.
210
 
        if result = terminus.find(request)
 
198
        if ! request.ignore_terminus? and result = terminus.find(request)
211
199
            result.expiration ||= self.expiration
212
 
            if cache?
 
200
            if cache? and request.use_cache?
213
201
                Puppet.info "Caching %s for %s" % [self.name, request.key]
214
202
                cache.save request(:save, result, *args)
215
203
            end
216
204
 
217
 
            return result
 
205
            return terminus.respond_to?(:filter) ? terminus.filter(result) : result
218
206
        end
219
207
 
220
208
        return nil
221
209
    end
222
210
 
 
211
    def find_in_cache(request)
 
212
        # See if our instance is in the cache and up to date.
 
213
        return nil unless cache? and ! request.ignore_cache? and cached = cache.find(request)
 
214
        if cached.expired?
 
215
            Puppet.info "Not using expired %s for %s from cache; expired at %s" % [self.name, request.key, cached.expiration]
 
216
            return nil
 
217
        end
 
218
 
 
219
        Puppet.debug "Using cached %s for %s" % [self.name, request.key]
 
220
        return cached
 
221
    end
 
222
 
223
223
    # Remove something via the terminus.
224
224
    def destroy(key, *args)
225
225
        request = request(:destroy, key, *args)
255
255
        request = request(:save, instance, *args)
256
256
        terminus = prepare(request)
257
257
 
 
258
        result = terminus.save(request)
 
259
 
258
260
        # If caching is enabled, save our document there
259
261
        cache.save(request) if cache?
260
 
        terminus.save(request)
 
262
 
 
263
        result
261
264
    end
262
265
 
263
266
    private
273
276
        return unless terminus.respond_to?(:authorized?)
274
277
 
275
278
        unless terminus.authorized?(request)
276
 
            raise ArgumentError, "Not authorized to call %s on %s with %s" % [request.method, request.key, request.options.inspect]
 
279
            msg = "Not authorized to call %s on %s" % [request.method, request.to_s]
 
280
            unless request.options.empty?
 
281
                msg += " with %s" % request.options.inspect
 
282
            end
 
283
            raise ArgumentError, msg
277
284
        end
278
285
    end
279
286
 
281
288
    def prepare(request)
282
289
        # Pick our terminus.
283
290
        if respond_to?(:select_terminus)
284
 
            terminus_name = select_terminus(request)
 
291
            unless terminus_name = select_terminus(request)
 
292
                raise ArgumentError, "Could not determine appropriate terminus for %s" % request
 
293
            end
285
294
        else
286
295
            terminus_name = terminus_class
287
296
        end
288
297
 
289
 
        check_authorization(request, terminus(terminus_name))
 
298
        dest_terminus = terminus(terminus_name)
 
299
        check_authorization(request, dest_terminus)
290
300
 
291
 
        return terminus(terminus_name)
 
301
        return dest_terminus
292
302
    end
293
303
 
294
304
    # Create a new terminus instance.
299
309
        end
300
310
        return klass.new
301
311
    end
 
312
 
 
313
    # Cache our terminus instances indefinitely, but make it easy to clean them up.
 
314
    cached_attr(:termini) { Hash.new }
302
315
end