diff --git a/README.md b/README.md index 5066caac99..2f405c6c93 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,16 @@ apache::vhost { 'ip.example.com': } ~~~ +It is also possible to configure more than one IP address per vhost by using an array of IP addresses for the [`ip`][] parameter: + +~~~ puppet +apache::vhost { 'ip.example.com': + ip => ['127.0.0.1','169.254.1.1'], + port => '80', + docroot => '/var/www/ip', +} +~~~ + To configure a virtual host with [aliased servers][], refer to the aliases using the [`serveraliases`][] parameter: ~~~ puppet diff --git a/manifests/vhost.pp b/manifests/vhost.pp index 25530bccb8..fed1da2046 100644 --- a/manifests/vhost.pp +++ b/manifests/vhost.pp @@ -338,23 +338,24 @@ } if $ip { + $_ip = any2array($ip) if $port { - $listen_addr_port = "${ip}:${port}" - $nvh_addr_port = "${ip}:${port}" + $listen_addr_port = parseyaml(inline_template('<% res="" %><% @_ip.each { |a_ip| res = res + "#{a_ip}:#{@port}," } %><%= res.split(",").to_yaml -%>')) + $nvh_addr_port = $listen_addr_port } else { $listen_addr_port = undef - $nvh_addr_port = $ip + $nvh_addr_port = $_ip if ! $servername and ! $ip_based { fail("Apache::Vhost[${name}]: must pass 'ip' and/or 'port' parameters for name-based vhosts") } } } else { if $port { - $listen_addr_port = $port - $nvh_addr_port = "${vhost_name}:${port}" + $listen_addr_port = any2array($port) + $nvh_addr_port = any2array("${vhost_name}:${port}") } else { $listen_addr_port = undef - $nvh_addr_port = $name + $nvh_addr_port = any2array($name) if ! $servername { fail("Apache::Vhost[${name}]: must pass 'ip' and/or 'port' parameters, and/or 'servername' parameter") } @@ -364,13 +365,13 @@ if $ip and defined(Apache::Listen["${port}"]) { fail("Apache::Vhost[${name}]: Mixing IP and non-IP Listen directives is not possible; check the add_listen parameter of the apache::vhost define to disable this") } - if ! defined(Apache::Listen["${listen_addr_port}"]) and $listen_addr_port and $ensure == 'present' { - ::apache::listen { "${listen_addr_port}": } + if $listen_addr_port and $ensure == 'present' { + ensure_resource('apache::listen', $listen_addr_port) } } if ! $ip_based { - if ! defined(Apache::Namevirtualhost[$nvh_addr_port]) and $ensure == 'present' and (versioncmp($apache_version, '2.4') < 0) { - ::apache::namevirtualhost { $nvh_addr_port: } + if $ensure == 'present' and (versioncmp($apache_version, '2.4') < 0) { + ensure_resource('apache::namevirtualhost', $nvh_addr_port) } } diff --git a/spec/acceptance/vhost_spec.rb b/spec/acceptance/vhost_spec.rb index b5d51e91f4..5c967209cf 100644 --- a/spec/acceptance/vhost_spec.rb +++ b/spec/acceptance/vhost_spec.rb @@ -190,6 +190,59 @@ class { 'apache': } end end + context 'new vhost with multiple IP addresses on port 80' do + it 'should configure one apache vhost with 2 ip addresses' do + pp = <<-EOS + class { 'apache': + default_vhost => false, + } + apache::vhost { 'example.com': + port => '80', + ip => ['127.0.0.1','::1'], + ip_based => true, + docroot => '/var/www/html', + } + host { 'ipv4.example.com': ip => '127.0.0.1', } + host { 'ipv6.example.com': ip => '::1', } + file { '/var/www/html/index.html': + ensure => file, + content => "Hello from vhost\\n", + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + describe service($service_name) do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end + + describe file("#{$vhost_dir}/25-example.com.conf") do + it { is_expected.to contain '' } + it { is_expected.to contain "ServerName example.com" } + end + + describe file($ports_file) do + it { is_expected.to be_file } + it { is_expected.to contain 'Listen 127.0.0.1:80' } + it { is_expected.to contain 'Listen ::1:80' } + it { is_expected.not_to contain 'NameVirtualHost 127.0.0.1:80' } + it { is_expected.not_to contain 'NameVirtualHost ::1:80' } + end + + it 'should answer to ipv4.example.com' do + shell("/usr/bin/curl ipv4.example.com:80", {:acceptable_exit_codes => 0}) do |r| + expect(r.stdout).to eq("Hello from vhost\n") + end + end + + it 'should answer to ipv6.example.com' do + shell("/usr/bin/curl ipv6.example.com:80", {:acceptable_exit_codes => 0}) do |r| + expect(r.stdout).to eq("Hello from vhost\n") + end + end + end + context 'apache_directories' do describe 'readme example, adapted' do it 'should configure a vhost with Files' do diff --git a/spec/defines/vhost_spec.rb b/spec/defines/vhost_spec.rb index 6fd59f9157..0a86963364 100644 --- a/spec/defines/vhost_spec.rb +++ b/spec/defines/vhost_spec.rb @@ -459,6 +459,40 @@ it { is_expected.to contain_concat__fragment('rspec.example.com-limits').with( :content => /^\s+LimitRequestFieldSize\s54321$/)} end + context 'vhost with multiple ip addresses' do + let :params do + { + 'port' => '80', + 'ip' => ['127.0.0.1','::1'], + 'ip_based' => true, + 'servername' => 'example.com', + 'docroot' => '/var/www/html', + 'add_listen' => true, + 'ensure' => 'present' + } + end + let :facts do + { + :osfamily => 'RedHat', + :operatingsystemrelease => '7', + :concat_basedir => '/dne', + :operatingsystem => 'RedHat', + :id => 'root', + :kernel => 'Linux', + :path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + :kernelversion => '3.6.2', + :is_pe => false, + } + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('rspec.example.com-apache-header').with( + :content => /[.\/m]*[.\/m]*$/ ) } + it { is_expected.to contain_concat__fragment('Listen 127.0.0.1:80') } + it { is_expected.to contain_concat__fragment('Listen ::1:80') } + it { is_expected.to_not contain_concat__fragment('NameVirtualHost 127.0.0.1:80') } + it { is_expected.to_not contain_concat__fragment('NameVirtualHost ::1:80') } + end context 'set only aliases' do let :params do { diff --git a/templates/vhost/_file_header.erb b/templates/vhost/_file_header.erb index e6f2f95e76..40e6e2d961 100644 --- a/templates/vhost/_file_header.erb +++ b/templates/vhost/_file_header.erb @@ -3,7 +3,7 @@ # Managed by Puppet # ************************************ -> +> ServerName <%= @servername %> <% if @serveradmin -%> ServerAdmin <%= @serveradmin %>