diff --git a/.nodeset.yml b/.nodeset.yml new file mode 100644 index 0000000..cbd0d57 --- /dev/null +++ b/.nodeset.yml @@ -0,0 +1,35 @@ +--- +default_set: 'centos-64-x64' +sets: + 'centos-59-x64': + nodes: + "main.foo.vm": + prefab: 'centos-59-x64' + 'centos-64-x64': + nodes: + "main.foo.vm": + prefab: 'centos-64-x64' + 'fedora-18-x64': + nodes: + "main.foo.vm": + prefab: 'fedora-18-x64' + 'debian-607-x64': + nodes: + "main.foo.vm": + prefab: 'debian-607-x64' + 'debian-70rc1-x64': + nodes: + "main.foo.vm": + prefab: 'debian-70rc1-x64' + 'ubuntu-server-10044-x64': + nodes: + "main.foo.vm": + prefab: 'ubuntu-server-10044-x64' + 'ubuntu-server-12042-x64': + nodes: + "main.foo.vm": + prefab: 'ubuntu-server-12042-x64' + 'sles-11sp1-x64': + nodes: + "main.foo.vm": + prefab: 'sles-11sp1-x64' diff --git a/Gemfile b/Gemfile index d53195d..722e7fa 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,7 @@ group :rake do gem 'puppetlabs_spec_helper' gem 'puppet-blacksmith' gem 'librarian-puppet-maestrodev' + gem 'rspec-system-puppet', :require => false + gem 'serverspec', :require => false + gem 'rspec-system-serverspec', :require => false end diff --git a/Rakefile b/Rakefile index 5a41ab3..e0913e5 100644 --- a/Rakefile +++ b/Rakefile @@ -7,6 +7,7 @@ CLOBBER.include('.tmp', '.librarian') require 'puppetlabs_spec_helper/rake_tasks' require 'puppet_blacksmith/rake_tasks' +require 'rspec-system/rake_task' # use librarian-puppet to manage fixtures instead of .fixtures.yml # offers more possibilities like explicit version management, forge downloads,... diff --git a/manifests/init.pp b/manifests/init.pp index 73079e6..febff76 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -31,6 +31,7 @@ class nginx ( $worker_processes = $nginx::params::nx_worker_processes, $worker_connections = $nginx::params::nx_worker_connections, + $package_ensure = $nginx::params::package_ensure, $proxy_set_header = $nginx::params::nx_proxy_set_header, $proxy_http_version = $nginx::params::nx_proxy_http_version, $confd_purge = $nginx::params::nx_confd_purge, diff --git a/manifests/package/debian.pp b/manifests/package/debian.pp index ab68598..983d182 100644 --- a/manifests/package/debian.pp +++ b/manifests/package/debian.pp @@ -17,7 +17,7 @@ class nginx::package::debian { $operatingsystem_lowercase = inline_template('<%= @operatingsystem.downcase %>') package { 'nginx': - ensure => present, + ensure => $nginx::package_ensure, require => Anchor['nginx::apt_repo'], } diff --git a/manifests/package/redhat.pp b/manifests/package/redhat.pp index 8ee8ed7..266f891 100644 --- a/manifests/package/redhat.pp +++ b/manifests/package/redhat.pp @@ -62,7 +62,7 @@ class nginx::package::redhat { } package { $redhat_packages: - ensure => present, + ensure => $nginx::package_ensure, } } diff --git a/manifests/package/suse.pp b/manifests/package/suse.pp index e874848..5b9a727 100644 --- a/manifests/package/suse.pp +++ b/manifests/package/suse.pp @@ -24,6 +24,6 @@ class nginx::package::suse { ] package { $suse_packages: - ensure => present, + ensure => $nginx::package_ensure, } } diff --git a/manifests/params.pp b/manifests/params.pp index 4e3bf0b..2b19b3b 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -84,4 +84,6 @@ class nginx::params { $nx_http_cfg_append = false + $package_ensure = 'present' + } diff --git a/manifests/resource/location.pp b/manifests/resource/location.pp index 8f2c7c8..3018dcb 100644 --- a/manifests/resource/location.pp +++ b/manifests/resource/location.pp @@ -6,6 +6,8 @@ # [*ensure*] - Enables or disables the specified location (present|absent) # [*vhost*] - Defines the default vHost for this location entry to include with # [*location*] - Specifies the URI associated with this location entry +# [*location_allow*] - Array: Locations to allow connections from. +# [*location_deny*] - Array: Locations to deny connections from. # [*www_root*] - Specifies the location on disk for files to be read from. Cannot be set in conjunction with $proxy # [*index_files*] - Default index files for NGINX to read when traversing a directory # [*proxy*] - Proxy server(s) for a location to connect to. Accepts a single value, can be used in conjunction @@ -82,6 +84,8 @@ define nginx::resource::location ( $ssl = false, $ssl_only = false, $location_alias = undef, + $location_allow = undef, + $location_deny = undef, $option = undef, $stub_status = undef, $location_custom_cfg = undef, diff --git a/manifests/resource/vhost.pp b/manifests/resource/vhost.pp index f5005d0..dab55ca 100644 --- a/manifests/resource/vhost.pp +++ b/manifests/resource/vhost.pp @@ -7,6 +7,8 @@ # [*listen_ip*] - Default IP Address for NGINX to listen with this vHost on. Defaults to all interfaces (*) # [*listen_port*] - Default IP Port for NGINX to listen with this vHost on. Defaults to TCP 80 # [*listen_options*] - Extra options for listen directive like 'default' to catchall. Undef by default. +# [*location_allow*] - Array: Locations to allow connections from. +# [*location_deny*] - Array: Locations to deny connections from. # [*ipv6_enable*] - BOOL value to enable/disable IPv6 support (false|true). Module will check to see if IPv6 # support exists on your system before enabling. # [*ipv6_listen_ip*] - Default IPv6 Address for NGINX to listen with this vHost on. Defaults to all interfaces (::) @@ -64,6 +66,8 @@ define nginx::resource::vhost ( $listen_ip = '*', $listen_port = '80', $listen_options = undef, + $location_allow = [], + $location_deny = [], $ipv6_enable = false, $ipv6_listen_ip = '::', $ipv6_listen_port = '80', @@ -101,6 +105,9 @@ define nginx::resource::vhost ( $include_files = undef ) { + validate_array($location_allow) + validate_array($location_deny) + File { ensure => $ensure ? { 'absent' => absent, @@ -144,23 +151,25 @@ define nginx::resource::vhost ( # Create the default location reference for the vHost nginx::resource::location {"${name}-default": - ensure => $ensure, - vhost => $name, - ssl => $ssl, - ssl_only => $ssl_only, - location => '/', - proxy => $proxy, - proxy_read_timeout => $proxy_read_timeout, - proxy_cache => $proxy_cache, - proxy_cache_valid => $proxy_cache_valid, - fastcgi => $fastcgi, - fastcgi_params => $fastcgi_params, - fastcgi_script => $fastcgi_script, - try_files => $try_files, - www_root => $www_root, - index_files => $index_files, - location_custom_cfg => $location_custom_cfg, - notify => Class['nginx::service'], + ensure => $ensure, + vhost => $name, + ssl => $ssl, + ssl_only => $ssl_only, + location => '/', + location_allow => $location_allow, + location_deny => $location_deny, + proxy => $proxy, + proxy_read_timeout => $proxy_read_timeout, + proxy_cache => $proxy_cache, + proxy_cache_valid => $proxy_cache_valid, + fastcgi => $fastcgi, + fastcgi_params => $fastcgi_params, + fastcgi_script => $fastcgi_script, + try_files => $try_files, + www_root => $www_root, + index_files => $index_files, + location_custom_cfg => $location_custom_cfg, + notify => Class['nginx::service'], } # Support location_cfg_prepend and location_cfg_append on default location created by vhost diff --git a/spec/classes/nginx_spec.rb b/spec/classes/nginx_spec.rb index 8ef3df5..aac7fcc 100644 --- a/spec/classes/nginx_spec.rb +++ b/spec/classes/nginx_spec.rb @@ -22,4 +22,15 @@ describe 'nginx' do it_behaves_like 'linux', 'debian', 'www-data' end + describe 'installs the requested package version' do + let(:facts) {{ :kernel => 'linux', :operatingsystem => 'redhat', :osfamily => 'redhat' }} + let(:params) {{ :package_ensure => '3.0.0' }} + + it 'installs 3.0.0 exactly' do + should contain_package('nginx').with({ + 'ensure' => '3.0.0' + }) + end + end + end diff --git a/spec/defines/nginx__resource__vhost_spec.rb b/spec/defines/nginx__resource__vhost_spec.rb new file mode 100644 index 0000000..ff17db7 --- /dev/null +++ b/spec/defines/nginx__resource__vhost_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe 'nginx::resource::vhost' do + + describe 'applies allow and deny rules' do + let (:title) { 'test' } + let (:params) {{ + :www_root => '/var/www/nginx', + :location_allow => ['10.0.0.1', 'host1'], + :location_deny => ['host2', '10.0.0.2'] + }} + + it 'applies location_allow rules' do + should contain_file('/nginx.d/test-500-test-default').with({ + 'content' => /allow 10.0.0.1\n allow host1/ + }) + end + it 'applies location_deny rules' do + should contain_file('/nginx.d/test-500-test-default').with({ + 'content' => /deny host2\n deny 10.0.0.2/ + }) + end + end + +end diff --git a/spec/spec_helper_system.rb b/spec/spec_helper_system.rb new file mode 100644 index 0000000..0c5eeb9 --- /dev/null +++ b/spec/spec_helper_system.rb @@ -0,0 +1,27 @@ +require 'rspec-system/spec_helper' +require 'rspec-system-puppet/helpers' +require 'rspec-system-serverspec/helpers' +include Serverspec::Helper::RSpecSystem +include Serverspec::Helper::DetectOS +include RSpecSystemPuppet::Helpers + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Enable colour + c.tty = true + + c.include RSpecSystemPuppet::Helpers + + # This is where we 'setup' the nodes before running our tests + c.before :suite do + # Install puppet + puppet_install + + # Install modules and dependencies + puppet_module_install(:source => proj_root, :module_name => 'nginx') + shell('puppet module install puppetlabs-apt') + shell('puppet module install puppetlabs-stdlib') + end +end diff --git a/spec/system/basic_spec.rb b/spec/system/basic_spec.rb new file mode 100644 index 0000000..216f0c7 --- /dev/null +++ b/spec/system/basic_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper_system' + +# Here we put the more basic fundamental tests, ultra obvious stuff. +describe "basic tests:" do + context 'make sure we have copied the module across' do + # No point diagnosing any more if the module wasn't copied properly + context shell 'ls /etc/puppet/modules/nginx' do + its(:stdout) { should =~ /Modulefile/ } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end +end diff --git a/spec/system/class_spec.rb b/spec/system/class_spec.rb new file mode 100644 index 0000000..ca58d3f --- /dev/null +++ b/spec/system/class_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper_system' + +describe "nginx class:" do + context 'should run successfully' do + pp = "class { 'nginx': }" + + context puppet_apply(pp) do + its(:stderr) { should be_empty } + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + describe service('nginx') do + it { should be_running } + end + +end diff --git a/spec/system/nginx_mail_spec.rb b/spec/system/nginx_mail_spec.rb new file mode 100644 index 0000000..22d9257 --- /dev/null +++ b/spec/system/nginx_mail_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper_system' + +describe "nginx::resource::mailhost define:" do + context 'should run successfully' do + + pp = " + class { 'nginx': + mail => true, + } + nginx::resource::vhost { 'www.puppetlabs.com': + ensure => present, + www_root => '/var/www/www.puppetlabs.com', + } + nginx::resource::mailhost { 'domain1.example': + ensure => present, + auth_http => 'localhost/cgi-bin/auth', + protocol => 'smtp', + listen_port => 587, + ssl_port => 465, + xclient => 'off', + } + " + + context puppet_apply(pp) do + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + # Not until deprecated variables fixed. + #its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + describe file('/etc/nginx/conf.mail.d/vhost_autogen.conf') do + it { should be_file } + it { should contain "auth_http localhost/cgi-bin/auth;" } + end + +end diff --git a/spec/system/nginx_proxy_spec.rb b/spec/system/nginx_proxy_spec.rb new file mode 100644 index 0000000..9081eaa --- /dev/null +++ b/spec/system/nginx_proxy_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper_system' + +describe "nginx::resource::upstream define:" do + context 'should run successfully' do + + pp = " + class { 'nginx': } + nginx::resource::upstream { 'puppet_rack_app': + ensure => present, + members => [ + 'localhost:3000', + 'localhost:3001', + 'localhost:3002', + ], + } + nginx::resource::vhost { 'rack.puppetlabs.com': + ensure => present, + proxy => 'http://puppet_rack_app', + } + " + + context puppet_apply(pp) do + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + describe file('/etc/nginx/conf.d/puppet_rack_app-upstream.conf') do + it { should be_file } + it { should contain "server localhost:3000" } + it { should contain "server localhost:3001" } + it { should contain "server localhost:3002" } + it { should_not contain "server localhost:3003" } + end + + describe file('/etc/nginx/conf.d/vhost_autogen.conf') do + it { should be_file } + it { should contain "proxy_pass http://puppet_rack_app;" } + end + +end diff --git a/spec/system/nginx_vhost_spec.rb b/spec/system/nginx_vhost_spec.rb new file mode 100644 index 0000000..f1865ed --- /dev/null +++ b/spec/system/nginx_vhost_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper_system' + +describe "nginx::resource::vhost define:" do + context 'should run successfully' do + + pp = " + class { 'nginx': } + nginx::resource::vhost { 'www.puppetlabs.com': + ensure => present, + www_root => '/var/www/www.puppetlabs.com', + } + " + + context puppet_apply(pp) do + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + describe file('/etc/nginx/conf.d/vhost_autogen.conf') do + it { should be_file } + it { should contain "www.puppetlabs.com" } + end + +end diff --git a/templates/vhost/vhost_location_directory.erb b/templates/vhost/vhost_location_directory.erb index 61705d3..09aa209 100644 --- a/templates/vhost/vhost_location_directory.erb +++ b/templates/vhost/vhost_location_directory.erb @@ -1,4 +1,10 @@ location <%= @location %> { +<% if @location_allow -%><% @location_allow.each do |allow_rule| -%> + allow <%= allow_rule %> +<% end -%><% end -%> +<% if @location_deny -%><% @location_deny.each do |deny_rule| -%> + deny <%= deny_rule %> +<% end -%><% end -%> <% if @location_cfg_prepend -%><% @location_cfg_prepend.sort_by {|k,v| k}.each do |key,value| -%> <%= key %> <%= value %>; <% end -%><% end -%>