Skip to content

Commit c3c7462

Browse files
pcarlislenicklewis
authored andcommitted
Add Selector terminus for file_content/file_metadata
This terminus is now the default, and encapsulates the behavior that was previously in the IndirectionHooks. That is, we dynamically select the terminus to use for a file request based on the key. However, for the puppet master, we instead explicitly always use the FileServer terminus, so that *all* requests for files from the master will go through the file server. This ensures that we will never accidentally serve local files on the puppet master.
1 parent d174a9f commit c3c7462

File tree

11 files changed

+78
-31
lines changed

11 files changed

+78
-31
lines changed

Diff for: lib/puppet/application/master.rb

+3
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ def setup
141141
# Cache our nodes in yaml. Currently not configurable.
142142
Puppet::Node.cache_class = :yaml
143143

144+
Puppet::FileServing::Content.indirection.terminus_class = :file_server
145+
Puppet::FileServing::Metadata.indirection.terminus_class = :file_server
146+
144147
# Configure all of the SSL stuff.
145148
if Puppet::SSL::CertificateAuthority.ca?
146149
Puppet::SSL::Host.ca_location = :local

Diff for: lib/puppet/file_serving/configuration.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def split_path(request)
7070

7171
mount_name, path = request.key.split(File::Separator, 2)
7272

73-
raise(ArgumentError, "Cannot find file: Invalid path '#{mount_name}'") unless mount_name =~ %r{^[-\w]+$}
73+
raise(ArgumentError, "Cannot find file: Invalid mount '#{mount_name}'") unless mount_name =~ %r{^[-\w]+$}
7474

7575
return nil unless mount = find_mount(mount_name, request.environment)
7676
if mount.name == "modules" and mount_name != "modules"

Diff for: lib/puppet/file_serving/content.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
require 'puppet/indirector'
66
require 'puppet/file_serving'
77
require 'puppet/file_serving/base'
8-
require 'puppet/file_serving/indirection_hooks'
98

109
# A class that handles retrieving file contents.
1110
# It only reads the file when its content is specifically
1211
# asked for.
1312
class Puppet::FileServing::Content < Puppet::FileServing::Base
1413
extend Puppet::Indirector
15-
indirects :file_content, :extend => Puppet::FileServing::IndirectionHooks
14+
indirects :file_content, :terminus_class => :selector
1615

1716
attr_writer :content
1817

Diff for: lib/puppet/file_serving/metadata.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
require 'puppet/file_serving'
88
require 'puppet/file_serving/base'
99
require 'puppet/util/checksums'
10-
require 'puppet/file_serving/indirection_hooks'
1110

1211
# A class that handles retrieving file metadata.
1312
class Puppet::FileServing::Metadata < Puppet::FileServing::Base
1413

1514
include Puppet::Util::Checksums
1615

1716
extend Puppet::Indirector
18-
indirects :file_metadata, :extend => Puppet::FileServing::IndirectionHooks
17+
indirects :file_metadata, :terminus_class => :selector
1918

2019
attr_reader :path, :owner, :group, :mode, :checksum_type, :checksum, :ftype, :destination
2120

Diff for: lib/puppet/file_serving/indirection_hooks.rb renamed to lib/puppet/file_serving/terminus_selector.rb

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
# This module is used to pick the appropriate terminus
99
# in file-serving indirections. This is necessary because
1010
# the terminus varies based on the URI asked for.
11-
module Puppet::FileServing::IndirectionHooks
11+
module Puppet::FileServing::TerminusSelector
1212
PROTOCOL_MAP = {"puppet" => :rest, "file" => :file}
1313

14-
# Pick an appropriate terminus based on the protocol.
15-
def select_terminus(request)
14+
def select(request)
1615
# We rely on the request's parsing of the URI.
1716

1817
# Short-circuit to :file if it's a fully-qualified path or specifies a 'file' protocol.

Diff for: lib/puppet/indirector/file_content/selector.rb

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'puppet/indirector/file_content'
2+
require 'puppet/indirector/code'
3+
require 'puppet/file_serving/terminus_selector'
4+
5+
class Puppet::Indirector::FileContent::Selector < Puppet::Indirector::Code
6+
desc "Select the terminus based on the request"
7+
include Puppet::FileServing::TerminusSelector
8+
9+
def get_terminus(request)
10+
indirection.terminus(select(request))
11+
end
12+
13+
def find(request)
14+
get_terminus(request).find(request)
15+
end
16+
17+
def search(request)
18+
get_terminus(request).search(request)
19+
end
20+
21+
def authorized?(request)
22+
terminus = get_terminus(request)
23+
if terminus.respond_to?(:authorized?)
24+
terminus.authorized?(request)
25+
else
26+
true
27+
end
28+
end
29+
end

Diff for: lib/puppet/indirector/file_metadata/selector.rb

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'puppet/indirector/file_metadata'
2+
require 'puppet/indirector/code'
3+
require 'puppet/file_serving/terminus_selector'
4+
5+
class Puppet::Indirector::FileMetadata::Selector < Puppet::Indirector::Code
6+
desc "Select the terminus based on the request"
7+
include Puppet::FileServing::TerminusSelector
8+
9+
def get_terminus(request)
10+
indirection.terminus(select(request))
11+
end
12+
13+
def find(request)
14+
get_terminus(request).find(request)
15+
end
16+
17+
def search(request)
18+
get_terminus(request).search(request)
19+
end
20+
21+
def authorized?(request)
22+
terminus = get_terminus(request)
23+
if terminus.respond_to?(:authorized?)
24+
terminus.authorized?(request)
25+
else
26+
true
27+
end
28+
end
29+
end

Diff for: spec/shared_behaviours/file_serving.rb

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99

1010
# It appears that the mocking somehow interferes with the caching subsystem.
1111
# This mock somehow causes another terminus to get generated.
12-
term = @indirection.terminus(:rest)
13-
@indirection.stubs(:terminus).with(:rest).returns term
14-
term.expects(:find)
12+
@indirection.terminus(:rest).expects(:find)
1513
@test_class.find(uri)
1614
end
1715

Diff for: spec/unit/file_serving/content_spec.rb

-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
Puppet::FileServing::Content.indirection.name.should == :file_content
1414
end
1515

16-
it "should should include the IndirectionHooks module in its indirection" do
17-
Puppet::FileServing::Content.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
18-
end
19-
2016
it "should only support the raw format" do
2117
Puppet::FileServing::Content.supported_formats.should == [:raw]
2218
end

Diff for: spec/unit/file_serving/metadata_spec.rb

-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
Puppet::FileServing::Metadata.indirection.name.should == :file_metadata
1414
end
1515

16-
it "should should include the IndirectionHooks module in its indirection" do
17-
Puppet::FileServing::Metadata.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
18-
end
19-
2016
it "should have a method that triggers attribute collection" do
2117
Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:collect)
2218
end

Diff for: spec/unit/file_serving/indirection_hooks_spec.rb renamed to spec/unit/file_serving/terminus_selector_spec.rb

+11-12
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,30 @@
55

66
require File.dirname(__FILE__) + '/../../spec_helper'
77

8-
require 'puppet/file_serving/indirection_hooks'
8+
require 'puppet/file_serving/terminus_selector'
99

10-
describe Puppet::FileServing::IndirectionHooks do
10+
describe Puppet::FileServing::TerminusSelector do
1111
before do
1212
@object = Object.new
13-
@object.extend(Puppet::FileServing::IndirectionHooks)
13+
@object.extend(Puppet::FileServing::TerminusSelector)
1414

1515
@request = stub 'request', :key => "mymod/myfile", :options => {:node => "whatever"}, :server => nil, :protocol => nil
1616
end
1717

1818
describe "when being used to select termini" do
1919
it "should return :file if the request key is fully qualified" do
20-
@request.expects(:key).returns "#{File::SEPARATOR}foo"
21-
@object.select_terminus(@request).should == :file
20+
@request.expects(:key).returns File.expand_path('/foo')
21+
@object.select(@request).should == :file
2222
end
2323

2424
it "should return :file if the URI protocol is set to 'file'" do
2525
@request.expects(:protocol).returns "file"
26-
@object.select_terminus(@request).should == :file
26+
@object.select(@request).should == :file
2727
end
2828

2929
it "should fail when a protocol other than :puppet or :file is used" do
3030
@request.stubs(:protocol).returns "http"
31-
proc { @object.select_terminus(@request) }.should raise_error(ArgumentError)
31+
proc { @object.select(@request) }.should raise_error(ArgumentError)
3232
end
3333

3434
describe "and the protocol is 'puppet'" do
@@ -39,24 +39,23 @@
3939
it "should choose :rest when a server is specified" do
4040
@request.stubs(:protocol).returns "puppet"
4141
@request.expects(:server).returns "foo"
42-
@object.select_terminus(@request).should == :rest
42+
@object.select(@request).should == :rest
4343
end
4444

4545
# This is so a given file location works when bootstrapping with no server.
4646
it "should choose :rest when the Settings name isn't 'puppet'" do
4747
@request.stubs(:protocol).returns "puppet"
48-
@request.stubs(:server).returns "foo"
48+
# We have to stub this because we can't set name
4949
Puppet.settings.stubs(:value).with(:name).returns "foo"
50-
@object.select_terminus(@request).should == :rest
50+
@object.select(@request).should == :rest
5151
end
5252

5353
it "should choose :file_server when the settings name is 'puppet' and no server is specified" do
5454
modules = mock 'modules'
5555

5656
@request.expects(:protocol).returns "puppet"
5757
@request.expects(:server).returns nil
58-
Puppet.settings.expects(:value).with(:name).returns "puppet"
59-
@object.select_terminus(@request).should == :file_server
58+
@object.select(@request).should == :file_server
6059
end
6160
end
6261
end

0 commit comments

Comments
 (0)