more cool stuff and more docs
This commit is contained in:
parent
710831190d
commit
5f2652af73
33
README.md
33
README.md
@ -1,33 +0,0 @@
|
|||||||
# Apache Config Generator
|
|
||||||
|
|
||||||
Programmatically construct your Apache configuration using a powerful DSL built in Ruby.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
`gem install apache-config-generator`
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Run `apache-configurator <directory>` to create a new directory to hold your config files.
|
|
||||||
A Rakefile and config.yml file will also be generated.
|
|
||||||
|
|
||||||
## Building a config file
|
|
||||||
|
|
||||||
Configs center around the Apache::Config.build method:
|
|
||||||
|
|
||||||
Apache::Config.build('sites-available/my-site.conf') do
|
|
||||||
server_name 'my-cool-website.cool.wow'
|
|
||||||
document_root '/var/www/my-cool-website'
|
|
||||||
|
|
||||||
directory '/' do
|
|
||||||
options :follow_sym_links, :indexes
|
|
||||||
allow_from_all
|
|
||||||
end
|
|
||||||
|
|
||||||
location_match %r{^/secret} do
|
|
||||||
deny_from_all
|
|
||||||
|
|
||||||
basic_authentication "My secret", '/etc/apache2/users/global.users', :user => :john
|
|
||||||
satisfy :any
|
|
||||||
end
|
|
||||||
end
|
|
34
README.rdoc
Normal file
34
README.rdoc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
= Apache Config Generator
|
||||||
|
|
||||||
|
Programmatically construct your Apache configuration using a powerful DSL built in Ruby.
|
||||||
|
|
||||||
|
== Installation
|
||||||
|
|
||||||
|
<tt>gem install apache-config-generator</tt>
|
||||||
|
|
||||||
|
== Usage
|
||||||
|
|
||||||
|
Run <tt>apache-configurator <directory></tt> to create a new directory to hold your config files.
|
||||||
|
A Rakefile and config.yml file will also be generated.
|
||||||
|
|
||||||
|
== Building a config file
|
||||||
|
|
||||||
|
Configs center around the Apache::Config.build method:
|
||||||
|
|
||||||
|
Apache::Config.build('sites-available/my-site.conf') do
|
||||||
|
server_name 'my-cool-website.cool.wow'
|
||||||
|
document_root '/var/www/my-cool-website'
|
||||||
|
|
||||||
|
directory '/' do
|
||||||
|
options :follow_sym_links, :indexes
|
||||||
|
allow_from_all
|
||||||
|
end
|
||||||
|
|
||||||
|
location_match %r{^/secret} do
|
||||||
|
deny_from_all
|
||||||
|
|
||||||
|
basic_authentication "My secret", '/etc/apache2/users/global.users', :user => :john
|
||||||
|
satisfy :any
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
4
Rakefile
4
Rakefile
@ -20,6 +20,7 @@ Echoe.new('apache-config-generator') do |p|
|
|||||||
p.summary = "A Ruby DSL for programmatically generating Apache configs"
|
p.summary = "A Ruby DSL for programmatically generating Apache configs"
|
||||||
p.ignore_pattern = [ 'spec/**/*', 'test/**/*', 'docs/**/*' ]
|
p.ignore_pattern = [ 'spec/**/*', 'test/**/*', 'docs/**/*' ]
|
||||||
p.executable_pattern = [ 'bin/**/*' ]
|
p.executable_pattern = [ 'bin/**/*' ]
|
||||||
|
p.runtime_dependencies = [ 'rainbow' ]
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :spec do
|
namespace :spec do
|
||||||
@ -34,6 +35,7 @@ end
|
|||||||
|
|
||||||
Rake::RDocTask.new do |rdoc|
|
Rake::RDocTask.new do |rdoc|
|
||||||
rdoc.template = 'direct'
|
rdoc.template = 'direct'
|
||||||
rdoc.rdoc_files.add('lib')
|
rdoc.rdoc_files.add('lib', 'README.rdoc')
|
||||||
|
rdoc.main = 'README.rdoc'
|
||||||
rdoc.rdoc_dir = 'docs'
|
rdoc.rdoc_dir = 'docs'
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
require 'rainbow'
|
||||||
|
|
||||||
Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f }
|
Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f }
|
||||||
|
|
||||||
@ -124,7 +125,9 @@ module Apache
|
|||||||
def apachify(name)
|
def apachify(name)
|
||||||
case name
|
case name
|
||||||
when String, Symbol
|
when String, Symbol
|
||||||
name.to_s.split("_").collect(&:capitalize).join.gsub('Ssl', 'SSL').gsub('Cgi', 'CGI').gsub('Ldap', 'LDAP').gsub('Url', 'URL')
|
name.to_s.split("_").collect(&:capitalize).join.gsub('Ssl', 'SSL').
|
||||||
|
gsub('Cgi', 'CGI').gsub('Ldap', 'LDAP').gsub('Url', 'URL').
|
||||||
|
gsub('Etag', 'ETag')
|
||||||
when Array
|
when Array
|
||||||
name.collect { |n| apachify(n) }
|
name.collect { |n| apachify(n) }
|
||||||
end
|
end
|
||||||
@ -230,17 +233,21 @@ module Apache
|
|||||||
"|#{@rotate_logs_path} #{path} #{time}"
|
"|#{@rotate_logs_path} #{path} #{time}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def warn_msg(from, color = :red)
|
||||||
|
"[warn::#{from}]".foreground(color)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def writable?(path)
|
def writable?(path)
|
||||||
puts "[warn] #{path} may not be writable!" if !File.directory? File.split(path).first
|
puts " #{warn_msg('writable?')} #{path.foreground(:yellow)} may not be writable!" if !File.directory? File.split(path).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def directory?(path)
|
def directory?(path)
|
||||||
puts "[warn] #{path} does not exist!" if !File.directory? path
|
puts " #{warn_msg('directory?')} #{path.foreground(:yellow)} does not exist!" if !File.directory? path
|
||||||
end
|
end
|
||||||
|
|
||||||
def exist?(path)
|
def exist?(path)
|
||||||
puts "[warn] #{path} does not exist!" if !File.exist?(path)
|
puts " #{warn_msg('exist?')} #{path.foreground(:yellow)} does not exist!" if !File.exist?(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -8,6 +8,11 @@ module Apache
|
|||||||
@config += Modules.build(*modules, &block)
|
@config += Modules.build(*modules, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def listen(*opt)
|
||||||
|
opt.each { |o| self << "Listen #{quoteize(o)}" }
|
||||||
|
end
|
||||||
|
alias :listen! :listen
|
||||||
|
|
||||||
# Add a User/Group block
|
# Add a User/Group block
|
||||||
# runner('www', 'www-data') #=>
|
# runner('www', 'www-data') #=>
|
||||||
# User www
|
# User www
|
||||||
|
@ -85,7 +85,7 @@ module Apache
|
|||||||
# Create an Apache require directive.
|
# Create an Apache require directive.
|
||||||
# Used to get around Ruby reserved word.
|
# Used to get around Ruby reserved word.
|
||||||
def apache_require(*opts)
|
def apache_require(*opts)
|
||||||
self << "Require #{opts * " "}"
|
self << "Require #{opts.compact * " "}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,7 @@ require 'fileutils'
|
|||||||
require 'apache/config'
|
require 'apache/config'
|
||||||
require 'apache/rake/create'
|
require 'apache/rake/create'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
require 'rainbow'
|
||||||
|
|
||||||
namespace :apache do
|
namespace :apache do
|
||||||
desc "Create all defined configs for the specified environment"
|
desc "Create all defined configs for the specified environment"
|
||||||
@ -19,7 +20,7 @@ namespace :apache do
|
|||||||
Dir.chdir CONFIG[:dest_path]
|
Dir.chdir CONFIG[:dest_path]
|
||||||
|
|
||||||
Dir[File.join(CONFIG[:source_path], '**', '*.rb')].each do |file|
|
Dir[File.join(CONFIG[:source_path], '**', '*.rb')].each do |file|
|
||||||
puts file
|
puts file.foreground(:green)
|
||||||
require file
|
require file
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -21,11 +21,15 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Pass the block to RewriteManager.build
|
# Pass the block to RewriteManager.build
|
||||||
def rewrites(&block)
|
def rewrites(*opt, &block)
|
||||||
self + indent(RewriteManager.build(&block))
|
self + indent(RewriteManager.build(*opt, &block))
|
||||||
self << ''
|
self << ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def rewrite(*opt, &block)
|
||||||
|
raise "You probably want rewrites #{quoteize(*opt) * " "} do" if block
|
||||||
|
end
|
||||||
|
|
||||||
# Create a permanent Redirect
|
# Create a permanent Redirect
|
||||||
#
|
#
|
||||||
# r301 '/here', '/there' #=> Redirect permanent "/here" "/there"
|
# r301 '/here', '/there' #=> Redirect permanent "/here" "/there"
|
||||||
@ -45,12 +49,27 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Build rewritable things from the provided block
|
# Build rewritable things from the provided block
|
||||||
def build(&block)
|
def build(*opt, &block)
|
||||||
reset!
|
reset!
|
||||||
|
|
||||||
|
@any_tests = false
|
||||||
|
@needs_tests = false
|
||||||
self.instance_eval(&block)
|
self.instance_eval(&block)
|
||||||
|
|
||||||
@rewrites.collect(&:to_a).flatten
|
name = opt.first || (@rewrites.empty? ? 'unnamed block' : "#{@rewrites.first.from} => #{@rewrites.first.to}")
|
||||||
|
|
||||||
|
if !@any_tests && !@rewrites.empty?
|
||||||
|
puts " [#{"rewrite".foreground(:blue)}] no tests found for #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if @needs_tests
|
||||||
|
puts " [#{"rewrite".foreground(:blue)}] #{name} needs more tests"
|
||||||
|
end
|
||||||
|
|
||||||
|
output = @rewrites.collect(&:to_a).flatten
|
||||||
|
output.unshift("# #{name}") if opt.first
|
||||||
|
|
||||||
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
# Commit the latest rewritable thing to the list of rewrites
|
# Commit the latest rewritable thing to the list of rewrites
|
||||||
@ -98,21 +117,49 @@ module Apache
|
|||||||
|
|
||||||
# Test the rewritable things defined in this block
|
# Test the rewritable things defined in this block
|
||||||
def rewrite_test(from, to, opts = {})
|
def rewrite_test(from, to, opts = {})
|
||||||
|
@any_tests = true
|
||||||
orig_from = from.dup
|
orig_from = from.dup
|
||||||
@rewrites.each do |r|
|
@rewrites.each do |r|
|
||||||
pre_from = from.dup
|
pre_from = from.dup
|
||||||
if r.match?(from, opts)
|
if r.match?(from, opts)
|
||||||
from = r.test(from, opts)
|
from = r.test(from, opts)
|
||||||
from = pre_from if (from == '-')
|
from = pre_from if (r.to == '-')
|
||||||
|
from = :http_forbidden if (r.forbidden?)
|
||||||
break if r.stop_if_match?
|
break if r.stop_if_match?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if from != to
|
if from != to
|
||||||
puts "[warn] #{orig_from} >> #{to} failed!"
|
puts " [#{"rewrite".foreground(:blue)}] #{orig_from} >> #{to} failed!"
|
||||||
puts "[warn] Result: #{from}"
|
puts " [#{"rewrite".foreground(:blue)}] Result: #{from}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def needs_tests
|
||||||
|
@needs_tests = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def cond_not_a_file(opts = {})
|
||||||
|
cond_file_flag '!-f', opts
|
||||||
|
end
|
||||||
|
|
||||||
|
def cond_is_a_file(opts = {})
|
||||||
|
cond_file_flag '-f', opts
|
||||||
|
end
|
||||||
|
|
||||||
|
def cond_not_a_directory(opts = {})
|
||||||
|
cond_file_flag '!-d', opts
|
||||||
|
end
|
||||||
|
|
||||||
|
def cond_is_a_directory(opts = {})
|
||||||
|
cond_file_flag '-d', opts
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def cond_file_flag(flag, opts)
|
||||||
|
cond opts[:filename_only] ? "%{REQUEST_FILENAME}" : "%{DOCUMENT_ROOT}%{REQUEST_FILENAME}", flag
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -144,6 +191,8 @@ module Apache
|
|||||||
class MatchableThing
|
class MatchableThing
|
||||||
include Apache::Quoteize
|
include Apache::Quoteize
|
||||||
|
|
||||||
|
attr_reader :from, :to
|
||||||
|
|
||||||
# The Apache directive tag for this thing
|
# The Apache directive tag for this thing
|
||||||
def tag; raise 'Override this method'; end
|
def tag; raise 'Override this method'; end
|
||||||
|
|
||||||
@ -166,6 +215,7 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
def stop_if_match?; false; end
|
def stop_if_match?; false; end
|
||||||
|
def forbidden?; false; end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A RewriteRule definition
|
# A RewriteRule definition
|
||||||
@ -195,12 +245,18 @@ module Apache
|
|||||||
case key
|
case key
|
||||||
when :last
|
when :last
|
||||||
'L'
|
'L'
|
||||||
|
when :forbidden
|
||||||
|
'F'
|
||||||
|
when :no_escape
|
||||||
|
'NE'
|
||||||
when :redirect
|
when :redirect
|
||||||
'R'
|
(value == true) ? 'R' : "R=#{value}"
|
||||||
when :pass_through
|
when :pass_through
|
||||||
'PT'
|
'PT'
|
||||||
when :preserve_query_string
|
when :preserve_query_string
|
||||||
'QSA'
|
'QSA'
|
||||||
|
when :env
|
||||||
|
"E=#{value}"
|
||||||
end
|
end
|
||||||
end.compact.sort
|
end.compact.sort
|
||||||
|
|
||||||
@ -220,11 +276,12 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
def to_a
|
def to_a
|
||||||
[ @conditions.collect(&:to_s), super ].flatten
|
[ ('' if !@conditions.empty?), @conditions.collect(&:to_s), super ].flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
# Test this RewriteRule, ensuring the RewriteConds also match
|
# Test this RewriteRule, ensuring the RewriteConds also match
|
||||||
def test(from, opts = {})
|
def test(from, opts = {})
|
||||||
|
opts[:request_uri] = from
|
||||||
result = from
|
result = from
|
||||||
|
|
||||||
result = super(from, opts) if match?(from, opts)
|
result = super(from, opts) if match?(from, opts)
|
||||||
@ -233,6 +290,7 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
def match?(from, opts = {})
|
def match?(from, opts = {})
|
||||||
|
opts[:request_uri] = from
|
||||||
ok = true
|
ok = true
|
||||||
|
|
||||||
@conditions.each do |c|
|
@conditions.each do |c|
|
||||||
@ -249,6 +307,10 @@ module Apache
|
|||||||
def stop_if_match?
|
def stop_if_match?
|
||||||
@input_options[:last]
|
@input_options[:last]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def forbidden?
|
||||||
|
@input_options[:forbidden]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A permanent RedirectMatch
|
# A permanent RedirectMatch
|
||||||
@ -313,20 +375,26 @@ module Apache
|
|||||||
super(from, opts)
|
super(from, opts)
|
||||||
source = replace_placeholders(@from, opts)
|
source = replace_placeholders(@from, opts)
|
||||||
|
|
||||||
|
to = @to
|
||||||
|
reverse = false
|
||||||
|
|
||||||
|
if @to[0..0] == '!'
|
||||||
|
reverse = true
|
||||||
|
to = @to[1..-1]
|
||||||
|
end
|
||||||
|
|
||||||
result = false
|
result = false
|
||||||
case @to[0..0]
|
case to[0..0]
|
||||||
when '!'
|
|
||||||
result = !source[Regexp.new(@to[1..-1])]
|
|
||||||
when '-'
|
when '-'
|
||||||
case @to
|
case to
|
||||||
when '-f'
|
when '-f'
|
||||||
result = opts[:files].include? source if opts[:files]
|
result = opts[:files].include? source if opts[:files]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result = source[Regexp.new(@to)]
|
result = source[Regexp.new(to)]
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
reverse ? !result : result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,7 +26,7 @@ describe Apache::Config, "rewrites" do
|
|||||||
rule %r{^/$}, '/test'
|
rule %r{^/$}, '/test'
|
||||||
end
|
end
|
||||||
apache.to_a.should == [
|
apache.to_a.should == [
|
||||||
'RewriteRule "^/$" "/test"', ''
|
'', 'RewriteRule "^/$" "/test"', ''
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -46,6 +46,7 @@ describe Apache::RewriteManager, "specific rewrite rules" do
|
|||||||
rewrite_test '/fail', '/test'
|
rewrite_test '/fail', '/test'
|
||||||
rewrite_test '/%{REQUEST_FILENAME}', '/test', :request_filename => 'success'
|
rewrite_test '/%{REQUEST_FILENAME}', '/test', :request_filename => 'success'
|
||||||
end.should == [
|
end.should == [
|
||||||
|
'',
|
||||||
'RewriteCond "%{REQUEST_FILENAME}" "test"',
|
'RewriteCond "%{REQUEST_FILENAME}" "test"',
|
||||||
'RewriteRule "^/$" "/test"',
|
'RewriteRule "^/$" "/test"',
|
||||||
'RedirectMatch permanent "^/success$" "/test"'
|
'RedirectMatch permanent "^/success$" "/test"'
|
||||||
@ -79,6 +80,7 @@ describe Apache::RewriteRule, "a RewriteRule" do
|
|||||||
|
|
||||||
its(:to_s) { should == 'RewriteRule "^/test$" "/test2" [L,QSA]' }
|
its(:to_s) { should == 'RewriteRule "^/test$" "/test2" [L,QSA]' }
|
||||||
its(:to_a) { should == [
|
its(:to_a) { should == [
|
||||||
|
'',
|
||||||
'RewriteCond "/%{REQUEST_FILENAME}" "^/test$"',
|
'RewriteCond "/%{REQUEST_FILENAME}" "^/test$"',
|
||||||
'RewriteRule "^/test$" "/test2" [L,QSA]'
|
'RewriteRule "^/test$" "/test2" [L,QSA]'
|
||||||
] }
|
] }
|
||||||
|
Loading…
Reference in New Issue
Block a user