diff --git a/acceptance/tests/external_ca_support/fixtures/auth.conf b/acceptance/tests/external_ca_support/fixtures/auth.conf index 93d949f2f..499c544f6 100644 --- a/acceptance/tests/external_ca_support/fixtures/auth.conf +++ b/acceptance/tests/external_ca_support/fixtures/auth.conf @@ -1,60 +1,60 @@ # Puppet 4.0.0 auth.conf, modified to allow requests from example.org for # external ca testing. # allow nodes to retrieve their own catalog path ~ ^/puppet/v3/catalog/([^/]+)$ method find allow *.example.org allow $1 # allow nodes to retrieve their own node definition path ~ ^/puppet/v3/node/([^/]+)$ method find allow *.example.org allow $1 # allow all nodes to access the certificates services -path /ca/v1/certificate_revocation_list/ca +path /puppet-ca/v1/certificate_revocation_list/ca method find allow * # allow all nodes to store their own reports path ~ ^/puppet/v3/report/([^/]+)$ method save allow *.example.org allow $1 # Allow all nodes to access all file services; this is necessary for # pluginsync, file serving from modules, and file serving from custom # mount points (see fileserver.conf). Note that the `/file` prefix matches # requests to both the file_metadata and file_content paths. See "Examples" # above if you need more granular access control for custom mount points. path /puppet/v3/file allow * ### Unauthenticated ACLs, for clients without valid certificates; authenticated ### clients can also access these paths, though they rarely need to. # allow access to the CA certificate; unauthenticated nodes need this # in order to validate the puppet master's certificate -path /ca/v1/certificate/ca +path /puppet-ca/v1/certificate/ca auth any method find allow * # allow nodes to retrieve the certificate they requested earlier -path /ca/v1/certificate/ +path /puppet-ca/v1/certificate/ auth any method find allow * # allow nodes to request a new certificate -path /ca/v1/certificate_request +path /puppet-ca/v1/certificate_request auth any method find, save allow * # deny everything else; this ACL is not strictly necessary, but # illustrates the default policy. path / auth any diff --git a/conf/auth.conf b/conf/auth.conf index ad6bda42f..a53d9d201 100644 --- a/conf/auth.conf +++ b/conf/auth.conf @@ -1,124 +1,124 @@ # This is the default auth.conf file, which implements the default rules # used by the puppet master. (That is, the rules below will still apply # even if this file is deleted.) # # The ACLs are evaluated in top-down order. More specific stanzas should # be towards the top of the file and more general ones at the bottom; # otherwise, the general rules may "steal" requests that should be # governed by the specific rules. # # See http://docs.puppetlabs.com/guides/rest_auth_conf.html for a more complete # description of auth.conf's behavior. # # Supported syntax: # Each stanza in auth.conf starts with a path to match, followed # by optional modifiers, and finally, a series of allow or deny # directives. # # Example Stanza # --------------------------------- # path /path/to/resource # simple prefix match # # path ~ regex # alternately, regex match # [environment envlist] # [method methodlist] # [auth[enthicated] {yes|no|on|off|any}] # allow [host|backreference|*|regex] # deny [host|backreference|*|regex] # allow_ip [ip|cidr|ip_wildcard|*] # deny_ip [ip|cidr|ip_wildcard|*] # # The path match can either be a simple prefix match or a regular # expression. `path /file` would match both `/file_metadata` and # `/file_content`. Regex matches allow the use of backreferences # in the allow/deny directives. # # The regex syntax is the same as for Ruby regex, and captures backreferences # for use in the `allow` and `deny` lines of that stanza # # Examples: # # path ~ ^/path/to/resource # Equivalent to `path /path/to/resource`. # allow * # Allow all authenticated nodes (since auth # # defaults to `yes`). # # path ~ ^/catalog/([^/]+)$ # Permit nodes to access their own catalog (by # allow $1 # certname), but not any other node's catalog. # # path ~ ^/file_(metadata|content)/extra_files/ # Only allow certain nodes to # auth yes # access the "extra_files" # allow /^(.+)\.example\.com$/ # mount point; note this must # allow_ip 192.168.100.0/24 # go ABOVE the "/file" rule, # # since it is more specific. # # environment:: restrict an ACL to a comma-separated list of environments # method:: restrict an ACL to a comma-separated list of HTTP methods # auth:: restrict an ACL to an authenticated or unauthenticated request # the default when unspecified is to restrict the ACL to authenticated requests # (ie exactly as if auth yes was present). # ### Authenticated ACLs - these rules apply only when the client ### has a valid certificate and is thus authenticated # allow nodes to retrieve their own catalog path ~ ^/puppet/v3/catalog/([^/]+)$ method find allow $1 # allow nodes to retrieve their own node definition path ~ ^/puppet/v3/node/([^/]+)$ method find allow $1 # allow all nodes to access the certificates services -path /ca/v1/certificate_revocation_list/ca +path /puppet-ca/v1/certificate_revocation_list/ca method find allow * # allow all nodes to store their own reports path ~ ^/puppet/v3/report/([^/]+)$ method save allow $1 # Allow all nodes to access all file services; this is necessary for # pluginsync, file serving from modules, and file serving from custom # mount points (see fileserver.conf). Note that the `/file` prefix matches # requests to both the file_metadata and file_content paths. See "Examples" # above if you need more granular access control for custom mount points. path /puppet/v3/file allow * ### Unauthenticated ACLs, for clients without valid certificates; authenticated ### clients can also access these paths, though they rarely need to. # allow access to the CA certificate; unauthenticated nodes need this # in order to validate the puppet master's certificate -path /ca/v1/certificate/ca +path /puppet-ca/v1/certificate/ca auth any method find allow * # allow nodes to retrieve the certificate they requested earlier -path /ca/v1/certificate/ +path /puppet-ca/v1/certificate/ auth any method find allow * # allow nodes to request a new certificate -path /ca/v1/certificate_request +path /puppet-ca/v1/certificate_request auth any method find, save allow * path /puppet/v2.0/environments method find allow * path /puppet/v3/environments method find allow * # deny everything else; this ACL is not strictly necessary, but # illustrates the default policy. path / auth any diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index 27ab3eca0..0c700d630 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,28 +1,28 @@ module Puppet::Network::HTTP HEADER_ENABLE_PROFILING = "X-Puppet-Profiling" HEADER_PUPPET_VERSION = "X-Puppet-Version" MASTER_URL_PREFIX = "/puppet" - CA_URL_PREFIX = "/ca" + CA_URL_PREFIX = "/puppet-ca" require 'puppet/network/authorization' require 'puppet/network/http/issues' require 'puppet/network/http/error' require 'puppet/network/http/route' require 'puppet/network/http/api' require 'puppet/network/http/api/ca' require 'puppet/network/http/api/ca/v1' require 'puppet/network/http/api/master' require 'puppet/network/http/api/master/v2' require 'puppet/network/http/api/master/v3' require 'puppet/network/http/handler' require 'puppet/network/http/response' require 'puppet/network/http/request' require 'puppet/network/http/site' require 'puppet/network/http/session' require 'puppet/network/http/factory' require 'puppet/network/http/nocache_pool' require 'puppet/network/http/pool' require 'puppet/network/http/memory_response' require 'puppet/network/http/compression' end diff --git a/lib/puppet/network/http/api.rb b/lib/puppet/network/http/api.rb index 82e5c6ffa..ff74963e6 100644 --- a/lib/puppet/network/http/api.rb +++ b/lib/puppet/network/http/api.rb @@ -1,26 +1,26 @@ class Puppet::Network::HTTP::API def self.not_found Puppet::Network::HTTP::Route. path(/.*/). any(lambda do |req, res| raise Puppet::Network::HTTP::Error::HTTPNotFoundError.new("No route for #{req.method} #{req.path}", Puppet::Network::HTTP::Issues::HANDLER_NOT_FOUND) end) end def self.master_routes - master_prefix = Regexp.new("^#{Puppet::Network::HTTP::MASTER_URL_PREFIX}") + master_prefix = Regexp.new("^#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/") Puppet::Network::HTTP::Route.path(master_prefix). any. chain(Puppet::Network::HTTP::API::Master::V3.routes, Puppet::Network::HTTP::API::Master::V2.routes, Puppet::Network::HTTP::API.not_found) end def self.ca_routes - ca_prefix = Regexp.new("^#{Puppet::Network::HTTP::CA_URL_PREFIX}") + ca_prefix = Regexp.new("^#{Puppet::Network::HTTP::CA_URL_PREFIX}/") Puppet::Network::HTTP::Route.path(ca_prefix). any. chain(Puppet::Network::HTTP::API::CA::V1.routes, Puppet::Network::HTTP::API.not_found) end end diff --git a/lib/puppet/network/http/api/ca/v1.rb b/lib/puppet/network/http/api/ca/v1.rb index ec2dce37a..15a721eae 100644 --- a/lib/puppet/network/http/api/ca/v1.rb +++ b/lib/puppet/network/http/api/ca/v1.rb @@ -1,11 +1,11 @@ require 'puppet/network/http/api/indirected_routes' class Puppet::Network::HTTP::API::CA::V1 INDIRECTED = Puppet::Network::HTTP::Route. path(/.*/). any(Puppet::Network::HTTP::API::IndirectedRoutes.new) def self.routes - Puppet::Network::HTTP::Route.path(%r{/v1}).any.chain(INDIRECTED) + Puppet::Network::HTTP::Route.path(%r{v1}).any.chain(INDIRECTED) end end diff --git a/lib/puppet/network/http/api/master/v2.rb b/lib/puppet/network/http/api/master/v2.rb index 89f51b92d..c0f86285f 100644 --- a/lib/puppet/network/http/api/master/v2.rb +++ b/lib/puppet/network/http/api/master/v2.rb @@ -1,26 +1,26 @@ module Puppet::Network::HTTP::API::Master::V2 require 'puppet/network/http/api/master/v2/environments' require 'puppet/network/http/api/master/v2/authorization' def self.routes - path(%r{^/v2\.0}). + path(%r{^v2\.0}). get(Authorization.new). chain(ENVIRONMENTS, Puppet::Network::HTTP::API.not_found) end private def self.path(path) Puppet::Network::HTTP::Route.path(path) end def self.provide(&block) lambda do |request, response| block.call.call(request, response) end end ENVIRONMENTS = path(%r{^/environments$}).get(provide do Environments.new(Puppet.lookup(:environments)) end) end diff --git a/lib/puppet/network/http/api/master/v3.rb b/lib/puppet/network/http/api/master/v3.rb index 44e439e39..87afc38f5 100644 --- a/lib/puppet/network/http/api/master/v3.rb +++ b/lib/puppet/network/http/api/master/v3.rb @@ -1,22 +1,22 @@ class Puppet::Network::HTTP::API::Master::V3 require 'puppet/network/http/api/master/v3/authorization' require 'puppet/network/http/api/master/v3/environments' require 'puppet/network/http/api/indirected_routes' AUTHZ = Authorization.new INDIRECTED = Puppet::Network::HTTP::Route. path(/.*/). any(Puppet::Network::HTTP::API::IndirectedRoutes.new) ENVIRONMENTS = Puppet::Network::HTTP::Route. path(%r{^/environments$}).get(AUTHZ.wrap do Environments.new(Puppet.lookup(:environments)) end) def self.routes - Puppet::Network::HTTP::Route.path(%r{/v3}). + Puppet::Network::HTTP::Route.path(%r{v3}). any. chain(ENVIRONMENTS, INDIRECTED) end end diff --git a/spec/unit/network/http/api/ca/v1_spec.rb b/spec/unit/network/http/api/ca/v1_spec.rb index eb301e054..bb6cff664 100644 --- a/spec/unit/network/http/api/ca/v1_spec.rb +++ b/spec/unit/network/http/api/ca/v1_spec.rb @@ -1,26 +1,26 @@ require 'spec_helper' require 'puppet/network/http' describe Puppet::Network::HTTP::API::CA::V1 do let(:response) { Puppet::Network::HTTP::MemoryResponse.new } let(:ca_url_prefix) { "#{Puppet::Network::HTTP::CA_URL_PREFIX}/v1"} let(:ca_routes) { Puppet::Network::HTTP::Route. - path(Regexp.new("#{Puppet::Network::HTTP::CA_URL_PREFIX}")). + path(Regexp.new("#{Puppet::Network::HTTP::CA_URL_PREFIX}/")). any. chain(Puppet::Network::HTTP::API::CA::V1.routes) } it "mounts ca routes" do Puppet::SSL::Certificate.indirection.stubs(:find).returns "foo" request = Puppet::Network::HTTP::Request. from_hash(:path => "#{ca_url_prefix}/certificate/foo", :params => {:environment => "production"}, :headers => {"accept" => "s"}) ca_routes.process(request, response) expect(response.code).to eq(200) end end diff --git a/spec/unit/network/http/api/master/v2_spec.rb b/spec/unit/network/http/api/master/v2_spec.rb index 465f33edf..219276163 100644 --- a/spec/unit/network/http/api/master/v2_spec.rb +++ b/spec/unit/network/http/api/master/v2_spec.rb @@ -1,22 +1,25 @@ require 'spec_helper' require 'puppet/network/http' describe Puppet::Network::HTTP::API::Master::V2 do let(:response) { Puppet::Network::HTTP::MemoryResponse.new } + let(:routes) { Puppet::Network::HTTP::Route.path(Regexp.new("/puppet/")). + any. + chain(Puppet::Network::HTTP::API::Master::V2.routes) } it "mounts the environments endpoint" do - request = Puppet::Network::HTTP::Request.from_hash(:path => "/v2.0/environments") - Puppet::Network::HTTP::API::Master::V2.routes.process(request, response) + request = Puppet::Network::HTTP::Request.from_hash(:path => "/puppet/v2.0/environments") + routes.process(request, response) expect(response.code).to eq(200) end it "responds to unknown paths with a 404" do - request = Puppet::Network::HTTP::Request.from_hash(:path => "/v2.0/unknown") + request = Puppet::Network::HTTP::Request.from_hash(:path => "/puppet/v2.0/unknown") expect do - Puppet::Network::HTTP::API::Master::V2.routes.process(request, response) + routes.process(request, response) end.to raise_error(Puppet::Network::HTTP::Error::HTTPNotFoundError) end end diff --git a/spec/unit/network/http/api/master/v3_spec.rb b/spec/unit/network/http/api/master/v3_spec.rb index 4d91481aa..e249cd731 100755 --- a/spec/unit/network/http/api/master/v3_spec.rb +++ b/spec/unit/network/http/api/master/v3_spec.rb @@ -1,39 +1,39 @@ require 'spec_helper' require 'puppet/network/http' describe Puppet::Network::HTTP::API::Master::V3 do let(:response) { Puppet::Network::HTTP::MemoryResponse.new } let(:master_url_prefix) { "#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/v3" } let(:master_routes) { Puppet::Network::HTTP::Route. - path(Regexp.new("#{Puppet::Network::HTTP::MASTER_URL_PREFIX}")). + path(Regexp.new("#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/")). any. chain(Puppet::Network::HTTP::API::Master::V3.routes) } it "mounts the environments endpoint" do request = Puppet::Network::HTTP::Request.from_hash(:path => "#{master_url_prefix}/environments") master_routes.process(request, response) expect(response.code).to eq(200) end it "mounts indirected routes" do request = Puppet::Network::HTTP::Request. from_hash(:path => "#{master_url_prefix}/node/foo", :params => {:environment => "production"}, :headers => {"accept" => "text/pson"}) master_routes.process(request, response) expect(response.code).to eq(200) end it "responds to unknown paths with a 404" do request = Puppet::Network::HTTP::Request.from_hash(:path => "#{master_url_prefix}/unknown") master_routes.process(request, response) expect(response.code).to eq(404) expect(response.body).to match("Not Found: Could not find indirection 'unknown'") end end