Merge pull request #337 from rabbitt/master
add ability to define geo and map mappings
This commit is contained in:
commit
03094eabe5
8 changed files with 449 additions and 0 deletions
|
@ -83,6 +83,8 @@ class nginx (
|
||||||
$worker_connections = $nginx::params::nx_worker_connections,
|
$worker_connections = $nginx::params::nx_worker_connections,
|
||||||
$worker_processes = $nginx::params::nx_worker_processes,
|
$worker_processes = $nginx::params::nx_worker_processes,
|
||||||
$worker_rlimit_nofile = $nginx::params::nx_worker_rlimit_nofile,
|
$worker_rlimit_nofile = $nginx::params::nx_worker_rlimit_nofile,
|
||||||
|
$geo_mappings = {},
|
||||||
|
$string_mappings = {},
|
||||||
) inherits nginx::params {
|
) inherits nginx::params {
|
||||||
|
|
||||||
include stdlib
|
include stdlib
|
||||||
|
@ -159,6 +161,9 @@ class nginx (
|
||||||
validate_string($proxy_headers_hash_bucket_size)
|
validate_string($proxy_headers_hash_bucket_size)
|
||||||
validate_bool($super_user)
|
validate_bool($super_user)
|
||||||
|
|
||||||
|
validate_hash($string_mappings)
|
||||||
|
validate_hash($geo_mappings)
|
||||||
|
|
||||||
class { 'nginx::package':
|
class { 'nginx::package':
|
||||||
package_name => $package_name,
|
package_name => $package_name,
|
||||||
package_source => $package_source,
|
package_source => $package_source,
|
||||||
|
@ -221,6 +226,8 @@ class nginx (
|
||||||
create_resources('nginx::resource::vhost', $nginx_vhosts)
|
create_resources('nginx::resource::vhost', $nginx_vhosts)
|
||||||
create_resources('nginx::resource::location', $nginx_locations)
|
create_resources('nginx::resource::location', $nginx_locations)
|
||||||
create_resources('nginx::resource::mailhost', $nginx_mailhosts)
|
create_resources('nginx::resource::mailhost', $nginx_mailhosts)
|
||||||
|
create_resources('nginx::resource::map', $string_mappings)
|
||||||
|
create_resources('nginx::resource::geo', $geo_mappings)
|
||||||
|
|
||||||
# Allow the end user to establish relationships to the "main" class
|
# Allow the end user to establish relationships to the "main" class
|
||||||
# and preserve the relationship to the implementation classes through
|
# and preserve the relationship to the implementation classes through
|
||||||
|
|
90
manifests/resource/geo.pp
Normal file
90
manifests/resource/geo.pp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# define: nginx::resource::geo
|
||||||
|
#
|
||||||
|
# This definition creates a new geo mapping entry for NGINX
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# [*networks*] - Hash of geo lookup keys and resultant values
|
||||||
|
# [*default*] - Sets the resulting value if the source value fails to
|
||||||
|
# match any of the variants.
|
||||||
|
# [*ensure*] - Enables or disables the specified location
|
||||||
|
# [*ranges*] - Indicates that lookup keys (network addresses) are
|
||||||
|
# specified as ranges.
|
||||||
|
# [*address*] - Nginx defaults to using $remote_addr for testing.
|
||||||
|
# This allows you to override that with another variable
|
||||||
|
# name (automatically prefixed with $)
|
||||||
|
# [*delete*] - deletes the specified network (see: geo module docs)
|
||||||
|
# [*proxy_recursive*] - Changes the behavior of address acquisition when
|
||||||
|
# specifying trusted proxies via 'proxies' directive
|
||||||
|
# [*proxies*] - Hash of network->value mappings.
|
||||||
|
|
||||||
|
# Actions:
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
#
|
||||||
|
# Sample Usage:
|
||||||
|
#
|
||||||
|
# nginx::resource::geo { 'client_network':
|
||||||
|
# ensure => present,
|
||||||
|
# ranges => false,
|
||||||
|
# default => extra,
|
||||||
|
# proxy_recursive => false,
|
||||||
|
# proxies => [ '192.168.99.99' ],
|
||||||
|
# networks => {
|
||||||
|
# '10.0.0.0/8' => 'intra',
|
||||||
|
# '172.16.0.0/12' => 'intra',
|
||||||
|
# '192.168.0.0/16' => 'intra',
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Sample Hiera usage:
|
||||||
|
#
|
||||||
|
# nginx::geos:
|
||||||
|
# client_network:
|
||||||
|
# ensure: present
|
||||||
|
# ranges: false
|
||||||
|
# default: 'extra'
|
||||||
|
# proxy_recursive: false
|
||||||
|
# proxies:
|
||||||
|
# - 192.168.99.99
|
||||||
|
# networks:
|
||||||
|
# '10.0.0.0/8': 'intra'
|
||||||
|
# '172.16.0.0/12': 'intra'
|
||||||
|
# '192.168.0.0/16': 'intra'
|
||||||
|
|
||||||
|
|
||||||
|
define nginx::resource::geo (
|
||||||
|
$networks,
|
||||||
|
$default = undef,
|
||||||
|
$ensure = 'present',
|
||||||
|
$ranges = false,
|
||||||
|
$address = undef,
|
||||||
|
$delete = undef,
|
||||||
|
$proxies = undef,
|
||||||
|
$proxy_recursive = undef
|
||||||
|
) {
|
||||||
|
|
||||||
|
validate_hash($networks)
|
||||||
|
validate_bool($ranges)
|
||||||
|
validate_re($ensure, '^(present|absent)$',
|
||||||
|
"Invalid ensure value '${ensure}'. Expected 'present' or 'absent'")
|
||||||
|
if ($default != undef) { validate_string($default) }
|
||||||
|
if ($address != undef) { validate_string($address) }
|
||||||
|
if ($delete != undef) { validate_string($delete) }
|
||||||
|
if ($proxies != undef) { validate_array($proxies) }
|
||||||
|
if ($proxy_recursive != undef) { validate_bool($proxy_recursive) }
|
||||||
|
|
||||||
|
File {
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0644',
|
||||||
|
}
|
||||||
|
|
||||||
|
file { "${nginx::params::nx_conf_dir}/conf.d/${name}-geo.conf":
|
||||||
|
ensure => $ensure ? {
|
||||||
|
'absent' => absent,
|
||||||
|
default => 'file',
|
||||||
|
},
|
||||||
|
content => template('nginx/conf.d/geo.erb'),
|
||||||
|
notify => Class['nginx::service'],
|
||||||
|
}
|
||||||
|
}
|
74
manifests/resource/map.pp
Normal file
74
manifests/resource/map.pp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# define: nginx::resource::map
|
||||||
|
#
|
||||||
|
# This definition creates a new mapping entry for NGINX
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# [*ensure*] - Enables or disables the specified location (present|absent)
|
||||||
|
# [*default*] - Sets the resulting value if the source values fails to
|
||||||
|
# match any of the variants.
|
||||||
|
# [*string*] - Source string or variable to provide mapping for
|
||||||
|
# [*mappings*] - Hash of map lookup keys and resultant values
|
||||||
|
# [*hostnames*] - Indicates that source values can be hostnames with a
|
||||||
|
# prefix or suffix mask.
|
||||||
|
|
||||||
|
# Actions:
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
#
|
||||||
|
# Sample Usage:
|
||||||
|
#
|
||||||
|
# nginx::resource::map { 'backend_pool':
|
||||||
|
# ensure => present,
|
||||||
|
# hostnames => true,
|
||||||
|
# default => 'ny-pool-1,
|
||||||
|
# string => '$http_host',
|
||||||
|
# mappings => {
|
||||||
|
# '*.nyc.example.com' => 'ny-pool-1',
|
||||||
|
# '*.sf.example.com' => 'sf-pool-1',
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Sample Hiera usage:
|
||||||
|
#
|
||||||
|
# nginx::maps:
|
||||||
|
# client_network:
|
||||||
|
# ensure: present
|
||||||
|
# hostnames: true
|
||||||
|
# default: 'ny-pool-1'
|
||||||
|
# string: $http_host
|
||||||
|
# mappings:
|
||||||
|
# '*.nyc.example.com': 'ny-pool-1'
|
||||||
|
# '*.sf.example.com': 'sf-pool-1'
|
||||||
|
|
||||||
|
|
||||||
|
define nginx::resource::map (
|
||||||
|
$string,
|
||||||
|
$mappings,
|
||||||
|
$default = undef,
|
||||||
|
$ensure = 'present',
|
||||||
|
$hostnames = false
|
||||||
|
) {
|
||||||
|
validate_string($string)
|
||||||
|
validate_re($string, '^.{2,}$',
|
||||||
|
"Invalid string value [${string}]. Expected a minimum of 2 characters.")
|
||||||
|
validate_hash($mappings)
|
||||||
|
validate_bool($hostnames)
|
||||||
|
validate_re($ensure, '^(present|absent)$',
|
||||||
|
"Invalid ensure value '${ensure}'. Expected 'present' or 'absent'")
|
||||||
|
if ($default != undef) { validate_string($default) }
|
||||||
|
|
||||||
|
File {
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0644',
|
||||||
|
}
|
||||||
|
|
||||||
|
file { "${nginx::params::nx_conf_dir}/conf.d/${name}-map.conf":
|
||||||
|
ensure => $ensure ? {
|
||||||
|
'absent' => absent,
|
||||||
|
default => 'file',
|
||||||
|
},
|
||||||
|
content => template('nginx/conf.d/map.erb'),
|
||||||
|
notify => Class['nginx::service'],
|
||||||
|
}
|
||||||
|
}
|
|
@ -194,6 +194,8 @@ define nginx::resource::vhost (
|
||||||
$log_by_lua_file = undef,
|
$log_by_lua_file = undef,
|
||||||
$use_default_location = true,
|
$use_default_location = true,
|
||||||
$rewrite_rules = [],
|
$rewrite_rules = [],
|
||||||
|
$string_mappings = {},
|
||||||
|
$geo_mappings = {},
|
||||||
) {
|
) {
|
||||||
|
|
||||||
validate_re($ensure, '^(present|absent)$',
|
validate_re($ensure, '^(present|absent)$',
|
||||||
|
@ -332,6 +334,8 @@ define nginx::resource::vhost (
|
||||||
}
|
}
|
||||||
validate_bool($use_default_location)
|
validate_bool($use_default_location)
|
||||||
validate_array($rewrite_rules)
|
validate_array($rewrite_rules)
|
||||||
|
validate_hash($string_mappings)
|
||||||
|
validate_hash($geo_mappings)
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
$vhost_dir = "${nginx::config::conf_dir}/sites-available"
|
$vhost_dir = "${nginx::config::conf_dir}/sites-available"
|
||||||
|
@ -555,4 +559,7 @@ define nginx::resource::vhost (
|
||||||
require => Concat[$config_file],
|
require => Concat[$config_file],
|
||||||
notify => Service['nginx'],
|
notify => Service['nginx'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_resources('nginx::resource::map', $string_mappings)
|
||||||
|
create_resources('nginx::resource::geo', $geo_mappings)
|
||||||
}
|
}
|
||||||
|
|
128
spec/defines/resource_geo_spec.rb
Normal file
128
spec/defines/resource_geo_spec.rb
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'nginx::resource::geo' do
|
||||||
|
let :title do
|
||||||
|
'client_network'
|
||||||
|
end
|
||||||
|
|
||||||
|
let :default_params do
|
||||||
|
{
|
||||||
|
:default => 'extra',
|
||||||
|
:networks => {
|
||||||
|
'172.16.0.0/12' => 'intra',
|
||||||
|
'192.168.0.0/16' => 'intra',
|
||||||
|
'10.0.0.0/8' => 'intra',
|
||||||
|
},
|
||||||
|
:proxies => [ '1.2.3.4', '4.3.2.1' ]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let :facts do
|
||||||
|
{
|
||||||
|
:osfamily => 'RedHat',
|
||||||
|
:operatingsystem => 'CentOS',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let :pre_condition do
|
||||||
|
[
|
||||||
|
'include ::nginx::params',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'os-independent items' do
|
||||||
|
describe 'basic assumptions' do
|
||||||
|
let :params do default_params end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-geo.conf").with(
|
||||||
|
{
|
||||||
|
'owner' => 'root',
|
||||||
|
'group' => 'root',
|
||||||
|
'mode' => '0644',
|
||||||
|
'ensure' => 'file',
|
||||||
|
'content' => /geo \$#{title}/,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "geo.conf template content" do
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:title => 'should set address',
|
||||||
|
:attr => 'address',
|
||||||
|
:value => '$remote_addr',
|
||||||
|
:match => 'geo $remote_addr $client_network {'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set ranges',
|
||||||
|
:attr => 'ranges',
|
||||||
|
:value => true,
|
||||||
|
:match => ' ranges;'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set default',
|
||||||
|
:attr => 'default',
|
||||||
|
:value => 'extra',
|
||||||
|
:match => [ ' default extra;' ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should contain ordered network directives',
|
||||||
|
:attr => 'networks',
|
||||||
|
:value => {
|
||||||
|
'192.168.0.0/16' => 'intra',
|
||||||
|
'172.16.0.0/12' => 'intra',
|
||||||
|
'10.0.0.0/8' => 'intra',
|
||||||
|
},
|
||||||
|
:match => [
|
||||||
|
' 10.0.0.0/8 intra;',
|
||||||
|
' 172.16.0.0/12 intra;',
|
||||||
|
' 192.168.0.0/16 intra;',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set multiple proxies',
|
||||||
|
:attr => 'proxies',
|
||||||
|
:value => [ '1.2.3.4', '4.3.2.1' ],
|
||||||
|
:match => [
|
||||||
|
' proxy 1.2.3.4;',
|
||||||
|
' proxy 4.3.2.1;'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set proxy_recursive',
|
||||||
|
:attr => 'proxy_recursive',
|
||||||
|
:value => true,
|
||||||
|
:match => ' proxy_recursive;'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set delete',
|
||||||
|
:attr => 'delete',
|
||||||
|
:value => '192.168.0.0/16',
|
||||||
|
:match => ' delete 192.168.0.0/16;'
|
||||||
|
},
|
||||||
|
].each do |param|
|
||||||
|
context "when #{param[:attr]} is #{param[:value]}" do
|
||||||
|
let :params do default_params.merge({ param[:attr].to_sym => param[:value] }) end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-geo.conf").with_mode('0644') }
|
||||||
|
it param[:title] do
|
||||||
|
verify_contents(subject, "/etc/nginx/conf.d/#{title}-geo.conf", Array(param[:match]))
|
||||||
|
Array(param[:notmatch]).each do |item|
|
||||||
|
should contain_file("/etc/nginx/conf.d/#{title}-geo.conf").without_content(item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when ensure => absent' do
|
||||||
|
let :params do default_params.merge(
|
||||||
|
{
|
||||||
|
:ensure => 'absent'
|
||||||
|
}
|
||||||
|
) end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-geo.conf").with_ensure('absent') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
101
spec/defines/resource_map_spec.rb
Normal file
101
spec/defines/resource_map_spec.rb
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'nginx::resource::map' do
|
||||||
|
let :title do
|
||||||
|
'backend_pool'
|
||||||
|
end
|
||||||
|
|
||||||
|
let :default_params do
|
||||||
|
{
|
||||||
|
:string => '$uri',
|
||||||
|
:default => 'pool_a',
|
||||||
|
:mappings => {
|
||||||
|
'foo' => 'pool_b',
|
||||||
|
'bar' => 'pool_c',
|
||||||
|
'baz' => 'pool_d',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let :facts do
|
||||||
|
{
|
||||||
|
:osfamily => 'RedHat',
|
||||||
|
:operatingsystem => 'CentOS',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let :pre_condition do
|
||||||
|
[
|
||||||
|
'include ::nginx::params',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'os-independent items' do
|
||||||
|
describe 'basic assumptions' do
|
||||||
|
let :params do default_params end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-map.conf").with(
|
||||||
|
{
|
||||||
|
'owner' => 'root',
|
||||||
|
'group' => 'root',
|
||||||
|
'mode' => '0644',
|
||||||
|
'ensure' => 'file',
|
||||||
|
'content' => /map \$uri \$#{title}/,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "map.conf template content" do
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:title => 'should set hostnames',
|
||||||
|
:attr => 'hostnames',
|
||||||
|
:value => true,
|
||||||
|
:match => ' hostnames;'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should set default',
|
||||||
|
:attr => 'default',
|
||||||
|
:value => 'pool_a',
|
||||||
|
:match => [ ' default pool_a;' ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:title => 'should contain ordered mappings',
|
||||||
|
:attr => 'mappings',
|
||||||
|
:value => {
|
||||||
|
'foo' => 'pool_b',
|
||||||
|
'bar' => 'pool_c',
|
||||||
|
'baz' => 'pool_d',
|
||||||
|
},
|
||||||
|
:match => [
|
||||||
|
' bar pool_c;',
|
||||||
|
' baz pool_d;',
|
||||||
|
' foo pool_b;',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
].each do |param|
|
||||||
|
context "when #{param[:attr]} is #{param[:value]}" do
|
||||||
|
let :params do default_params.merge({ param[:attr].to_sym => param[:value] }) end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-map.conf").with_mode('0644') }
|
||||||
|
it param[:title] do
|
||||||
|
verify_contents(subject, "/etc/nginx/conf.d/#{title}-map.conf", Array(param[:match]))
|
||||||
|
Array(param[:notmatch]).each do |item|
|
||||||
|
should contain_file("/etc/nginx/conf.d/#{title}-map.conf").without_content(item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when ensure => absent' do
|
||||||
|
let :params do default_params.merge(
|
||||||
|
{
|
||||||
|
:ensure => 'absent'
|
||||||
|
}
|
||||||
|
) end
|
||||||
|
|
||||||
|
it { should contain_file("/etc/nginx/conf.d/#{title}-map.conf").with_ensure('absent') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
templates/conf.d/geo.erb
Normal file
29
templates/conf.d/geo.erb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<%
|
||||||
|
# sorting ip addresses in ascending order is more efficient for nginx - so we need
|
||||||
|
# to convert them to numbers first via IPAddr
|
||||||
|
require 'ipaddr'
|
||||||
|
-%>
|
||||||
|
geo <%= @address ? "#{@address} " : '' %>$<%= @name %> {
|
||||||
|
<% if @ranges -%>
|
||||||
|
ranges;
|
||||||
|
<% end -%>
|
||||||
|
<% if @default -%>
|
||||||
|
default <%= @default %>;
|
||||||
|
<% end -%>
|
||||||
|
<% if @delete -%>
|
||||||
|
delete <%= @delete %>;
|
||||||
|
<% end -%>
|
||||||
|
<% if @proxies -%>
|
||||||
|
<%- [@proxies].flatten.each do |proxy| -%>
|
||||||
|
proxy <%= proxy %>;
|
||||||
|
<%- end -%>
|
||||||
|
<% end -%>
|
||||||
|
<% if @proxy_recursive && @proxies -%>
|
||||||
|
proxy_recursive;
|
||||||
|
<% end -%>
|
||||||
|
<% if @networks -%>
|
||||||
|
<%- @networks.sort_by{|k,v| IPAddr.new(k.split('-').first).to_i }.each do |key,value| -%>
|
||||||
|
<%= key %> <%= value %>;
|
||||||
|
<%- end -%>
|
||||||
|
<% end -%>
|
||||||
|
}
|
13
templates/conf.d/map.erb
Normal file
13
templates/conf.d/map.erb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
map <%= @string %> $<%= @name %> {
|
||||||
|
<% if @hostnames -%>
|
||||||
|
hostnames;
|
||||||
|
<% end -%>
|
||||||
|
<% if @default -%>
|
||||||
|
default <%= @default %>;
|
||||||
|
<% end -%>
|
||||||
|
<% if @mappings -%>
|
||||||
|
<%- @mappings.sort_by{|k,v| k}.each do |key,value| -%>
|
||||||
|
<%= key %> <%= value %>;
|
||||||
|
<%- end -%>
|
||||||
|
<% end -%>
|
||||||
|
}
|
Loading…
Reference in a new issue