From 5a887e5f2d04236e02b9f2c5ffb704660d476f14 Mon Sep 17 00:00:00 2001
From: Yannick Martin <yannick.martin@ovhcloud.com>
Date: Fri, 20 Aug 2021 13:18:49 +0200
Subject: [PATCH] configure unix socket on ssl vhost

---
 spec/acceptance/nginx_server_spec.rb   | 100 +++++++++++++++++++++++++
 templates/server/server_ssl_header.erb |  18 +++++
 2 files changed, 118 insertions(+)

diff --git a/spec/acceptance/nginx_server_spec.rb b/spec/acceptance/nginx_server_spec.rb
index d1d9c332f..c16665c79 100755
--- a/spec/acceptance/nginx_server_spec.rb
+++ b/spec/acceptance/nginx_server_spec.rb
@@ -247,4 +247,104 @@ class { 'nginx': }
       end
     end
   end
+
+  context 'should run with unix socket' do
+    it 'configures a nginx server' do
+      pp = "
+      class { 'nginx': }
+      nginx::resource::server { 'www.puppetlabs.com':
+        ensure                    => present,
+        www_root                  => '/var/www/www.puppetlabs.com',
+        listen_unix_socket_enable => true,
+        listen_unix_socket        => '/tmp/nginx.sock'
+      }
+      host { 'www.puppetlabs.com': ip => '127.0.0.1', }
+      file { ['/var/www','/var/www/www.puppetlabs.com']: ensure => directory }
+      file { '/var/www/www.puppetlabs.com/index.html': ensure  => file, content => 'Hello from www\n', }
+      "
+
+      apply_manifest(pp, catch_failures: true)
+      apply_manifest(pp, catch_changes: true)
+    end
+
+    describe file('/etc/nginx/sites-available/www.puppetlabs.com.conf') do
+      it { is_expected.to be_file }
+      it { is_expected.to contain 'www.puppetlabs.com' }
+    end
+
+    describe file('/etc/nginx/sites-enabled/www.puppetlabs.com.conf') do
+      it { is_expected.to be_linked_to '/etc/nginx/sites-available/www.puppetlabs.com.conf' }
+    end
+
+    describe service('nginx') do
+      it { is_expected.to be_running }
+    end
+
+    describe port(80) do
+      it { is_expected.to be_listening }
+    end
+
+    describe file('/tmp/nginx.sock') do
+      it { is_expected.to be_socket }
+    end
+
+    it 'answers to www.puppetlabs.com and responds with "Hello from www"' do
+      shell('/usr/bin/curl --unix-socket /tmp/nginx.sock http://www.puppetlabs.com') do |r|
+        expect(r.stdout).to eq("Hello from www\n")
+      end
+    end
+
+    it 'answers to www.puppetlabs.com without error' do
+      shell('/usr/bin/curl --unix-socket /tmp/nginx.sock --fail http://www.puppetlabs.com') do |r|
+        expect(r.exit_code).to be_zero
+      end
+    end
+  end
+
+  context 'should run with unix socket with SSL' do
+    it 'configures a nginx SSL server' do
+      pp = "
+      class { 'nginx': }
+      nginx::resource::server { 'www.puppetlabs.com':
+        ensure                    => present,
+        ssl                       => true,
+        ssl_cert                  => '/etc/pki/tls/certs/blah.cert',
+        ssl_key                   => '/etc/pki/tls/private/blah.key',
+        www_root                  => '/var/www/www.puppetlabs.com',
+        listen_port               => 443,
+        ssl_port                  => 443,
+        listen_unix_socket_enable => true,
+        listen_unix_socket        => '/tmp/nginx.sock'
+
+      }
+      host { 'www.puppetlabs.com': ip => '127.0.0.1', }
+      file { ['/var/www','/var/www/www.puppetlabs.com']: ensure => directory }
+      file { '/var/www/www.puppetlabs.com/index.html': ensure  => file, content => 'Hello from www\n', }
+      "
+
+      apply_manifest(pp, catch_failures: true)
+    end
+
+    describe service('nginx') do
+      it { is_expected.to be_running }
+    end
+
+    describe port(443) do
+      it { is_expected.to be_listening }
+    end
+
+    it 'answers to https://www.puppetlabs.com with "Hello from www"' do
+      # use --insecure because it's a self-signed cert
+      shell('/usr/bin/curl --unix-socket /tmp/nginx.sock --insecure https://www.puppetlabs.com') do |r|
+        expect(r.stdout).to eq("Hello from www\n")
+      end
+    end
+
+    it 'answers to https://www.puppetlabs.com without error' do
+      # use --insecure because it's a self-signed cert
+      shell('/usr/bin/curl --unix-socket /tmp/nginx.sock --fail --insecure https://www.puppetlabs.com') do |r|
+        expect(r.exit_code).to eq(0)
+      end
+    end
+  end
 end
diff --git a/templates/server/server_ssl_header.erb b/templates/server/server_ssl_header.erb
index 973ad9603..d4d42f52f 100644
--- a/templates/server/server_ssl_header.erb
+++ b/templates/server/server_ssl_header.erb
@@ -9,6 +9,15 @@ server {
   <%- else -%>
   listen       <%= @listen_ip %>:<%= @ssl_port %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_options %> <%= @listen_options %><% end %>;
   <%- end -%>
+  <%- if @listen_unix_socket_enable -%>
+    <%- if @listen_unix_socket.is_a?(Array) then -%>
+      <%- @listen_unix_socket.each do |unix_socket| -%>
+  listen unix:<%= unix_socket %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_unix_socket_options %> <%= @listen_unix_socket_options %><% end %>;
+      <%- end -%>
+    <%- else -%>
+  listen unix:<%= @listen_unix_socket %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_unix_socket_options %> <%= @listen_unix_socket_options %><% end %>;
+    <%- end -%>
+  <%- end -%>
 <%= scope.function_template(["nginx/server/server_ssl_ipv6_listen.erb"]) %>
 <%- if @rewrite_www_to_non_www -%>
   server_name  www.<%= s.gsub(/^www\./, '') %>;
@@ -32,6 +41,15 @@ server {
   <%- else -%>
   listen       <%= @listen_ip %>:<%= @ssl_port %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_options %> <%= @listen_options %><% end %>;
   <%- end -%>
+  <%- if @listen_unix_socket_enable -%>
+    <%- if @listen_unix_socket.is_a?(Array) then -%>
+      <%- @listen_unix_socket.each do |unix_socket| -%>
+  listen unix:<%= unix_socket %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_unix_socket_options %> <%= @listen_unix_socket_options %><% end %>;
+      <%- end -%>
+    <%- else -%>
+  listen unix:<%= @listen_unix_socket %> <% if @ssl_listen_option %>ssl<% end %><% if @http2 == 'on' %> http2<% end %><% if @spdy == 'on' %> spdy<% end %><% if @listen_unix_socket_options %> <%= @listen_unix_socket_options %><% end %>;
+    <%- end -%>
+  <%- end -%>
 <%= scope.function_template(["nginx/server/server_ssl_ipv6_listen.erb"]) %>
 <%- if @rewrite_www_to_non_www -%>
   server_name  <%= @server_name.join("  ").gsub(/(^| )(www\.)?(?=[a-z0-9])/, '') %>;