Merge pull request #269 from netmanagers/master

Check nginx config before deploying & various passenger fixes
This commit is contained in:
Javier Bértoli 2021-03-11 14:09:15 -03:00 committed by GitHub
commit a30001da35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 286 additions and 12 deletions

View File

@ -14,7 +14,7 @@ ignore: |
.cache/
.git/
node_modules/
test/**/states/**/*.sls
test/salt/**/*.sls
.kitchen/
yaml-files:

View File

@ -31,3 +31,6 @@ nginx_config:
- context:
config: {{ nginx.server.config|json(sort_keys=False) }}
{% endif %}
{% if nginx.check_config_before_apply %}
- check_cmd: /usr/sbin/nginx -t -c
{% endif %}

View File

@ -9,7 +9,7 @@
'Debian': {
'package': 'nginx',
'passenger_package': 'passenger',
'passenger_config_file': '/etc/nginx/conf.d/passenger.conf',
'passenger_config_file': '/etc/nginx/conf.d/mod-http-passenger.conf',
'service': 'nginx',
'webuser': 'www-data',
'conf_file': '/etc/nginx/nginx.conf',
@ -112,6 +112,7 @@
'install_from_ppa': False,
'install_from_repo': False,
'install_from_phusionpassenger': False,
'check_config_before_apply': False,
'ppa_version': 'stable',
'source_version': '1.10.0',
'source_hash': '8ed647c3dd65bc4ced03b0e0f6bf9e633eff6b01bac772bcf97077d58bc2be4d',

View File

@ -25,6 +25,7 @@ passenger_install:
- pkg: nginx_install
- require_in:
- service: nginx_service
- file: nginx_config
/etc/nginx/passenger.conf:
file.absent:
@ -46,6 +47,7 @@ passenger_config:
- service: nginx_service
- require_in:
- service: nginx_service
- file: nginx_config
- require:
- file: /etc/nginx/passenger.conf
- pkg: passenger_install

View File

@ -163,7 +163,7 @@ nginx_phusionpassenger_yum_repo:
- baseurl: 'https://oss-binaries.phusionpassenger.com/yum/passenger/el/$releasever/$basearch'
- repo_gpgcheck: 1
- gpgcheck: 0
- gpgkey: 'https://packagecloud.io/gpg.key'
- gpgkey: 'https://oss-binaries.phusionpassenger.com/yum/definitions/RPM-GPG-KEY.asc'
- enabled: True
- sslverify: 1
- sslcacert: /etc/pki/tls/certs/ca-bundle.crt

View File

@ -28,4 +28,9 @@ nginx_snippet_{{ snippet }}:
- context:
config: {{ config|json() }}
nginx: {{ _nginx|json() }}
- require:
- file: nginx_snippets_dir
- require_in:
- file: nginx_config
- service: nginx_service
{% endfor %}

View File

@ -28,6 +28,17 @@ nginx:
source_version: '1.10.0'
source_hash: ''
# Check the configuration before applying:
# To prevent applying a configuration that might break nginx, set this
# parameter to true so the configuration is checked BEFORE applying. If
# the check fails, the state will fail and it won't be deployed.
# CAVEAT: As the configuration file is created in a temp dir, it can't
# have relative references or it will fail to check. You'll need to
# specify full paths where required (ie, `include`, `load_module`,
# `snippets`, etc.0
# Defaults to false
check_config_before_apply: false
# These are usually set by grains in map.jinja
# Typically you can comment these out.
lookup:

View File

@ -1,11 +1,13 @@
# frozen_string_literal: true
# Set defaults, use debian as base
server_available = '/etc/nginx/sites-available'
server_enabled = '/etc/nginx/sites-enabled'
server_enabled = '/etc/nginx/sites-enabled'
# Override by platform family
case platform[:family]
when 'redhat','fedora'
when 'redhat', 'fedora'
server_available = '/etc/nginx/conf.d'
server_enabled = '/etc/nginx/conf.d'
when 'suse'
@ -22,9 +24,13 @@ control 'Nginx configuration' do
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
its('mode') { should cmp '0644' }
its('content') { should include %Q[ log_format main '$remote_addr - $remote_user [$time_local] $status '
its('content') do
# rubocop:disable Metrics/LineLength
should include %( log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';] }
'"$http_user_agent" "$http_x_forwarded_for"';)
# rubocop:enable Metrics/LineLength
end
end
# snippets configuration
@ -40,12 +46,11 @@ control 'Nginx configuration' do
# sites configuration
[server_available, server_enabled].each do |dir|
describe file ("#{dir}/default") do
it { should_not exist }
describe file "#{dir}/default" do
it { should_not exist }
end
describe file ("#{dir}/mysite") do
describe file "#{dir}/mysite" do
it { should be_file }
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
@ -57,6 +62,5 @@ control 'Nginx configuration' do
its('content') { should include 'try_files $uri $uri/ =404;' }
its('content') { should include 'include snippets/letsencrypt.conf;' }
end
end
end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
control 'Nginx package' do
title 'should be installed'

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
control 'Nginx service' do
title 'should be running and enabled'

View File

@ -0,0 +1,50 @@
# InSpec Profile: `passenger`
This shows the implementation of the `passenger` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md).
## Verify a profile
InSpec ships with built-in features to verify a profile structure.
```bash
$ inspec check passenger
Summary
-------
Location: passenger
Profile: profile
Controls: 4
Timestamp: 2019-06-24T23:09:01+00:00
Valid: true
Errors
------
Warnings
--------
```
## Execute a profile
To run all **supported** controls on a local machine use `inspec exec /path/to/profile`.
```bash
$ inspec exec passenger
..
Finished in 0.0025 seconds (files took 0.12449 seconds to load)
8 examples, 0 failures
```
## Execute a specific control from a profile
To run one control from the profile use `inspec exec /path/to/profile --controls name`.
```bash
$ inspec exec passenger --controls package
.
Finished in 0.0025 seconds (files took 0.12449 seconds to load)
1 examples, 0 failures
```
See an [example control here](https://github.com/inspec/inspec/blob/master/examples/profile/controls/example.rb).

View File

@ -0,0 +1,58 @@
# frozen_string_literal: true
# Set defaults, use debian as base
# Override by OS Family
case platform[:family]
when 'redhat', 'centos', 'fedora'
server_available = '/etc/nginx/conf.d'
server_enabled = '/etc/nginx/conf.d'
passenger_mod = '/usr/lib64/nginx/modules/ngx_http_passenger_module.so'
passenger_root = '/usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini'
passenger_config_file = '/etc/nginx/conf.d/passenger.conf'
should_not_exist_file = '/etc/nginx/conf.d/mod-http-passenger.conf'
when 'debian', 'ubuntu'
server_available = '/etc/nginx/sites-available'
server_enabled = '/etc/nginx/sites-enabled'
passenger_mod = '/usr/lib/nginx/modules/ngx_http_passenger_module.so'
passenger_root = '/usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini'
passenger_config_file = '/etc/nginx/conf.d/mod-http-passenger.conf'
should_not_exist_file = '/etc/nginx/conf.d/passenger.conf'
end
control 'Passenger configuration' do
title 'should match desired lines'
# main configuration
describe file('/etc/nginx/nginx.conf') do
its('content') { should include "load_module #{passenger_mod}" }
end
describe file(passenger_config_file) do
it { should be_file }
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
its('mode') { should cmp '0644' }
its('content') { should include "passenger_root #{passenger_root};" }
its('content') { should include 'passenger_ruby /usr/bin/ruby;' }
end
describe file(should_not_exist_file) do
it { should_not exist }
end
# sites configuration
[server_available, server_enabled].each do |dir|
describe file "#{dir}/default" do
it { should_not exist }
end
describe file "#{dir}/mysite" do
it { should be_file }
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
its('mode') { should cmp '0644' }
its('content') { should include 'passenger_enabled on;' }
end
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
control 'Nginx package' do
title 'should be installed'
describe package('nginx') do
it { should be_installed }
end
end
control 'Passenger packages' do
title 'should be installed'
# Override by OS Family
passenger_mod_pkg = case platform[:family]
when 'redhat', 'centos', 'fedora'
'nginx-mod-http-passenger'
when 'debian', 'ubuntu'
'libnginx-mod-http-passenger'
end
describe package('passenger') do
it { should be_installed }
end
describe package(passenger_mod_pkg) do
it { should be_installed }
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
control 'Nginx service' do
title 'should be running and enabled'
describe service('nginx') do
it { should be_enabled }
it { should be_running }
end
end
control 'Passenger module' do
title 'should be running and enabled'
describe 'Passenger engine' do
it 'passenger-config should say configuration "looks good"' do
expect(command(
'/usr/bin/passenger-config validate-install --auto'
).stdout).to match(/looks good/)
end
it 'passenger-memory-stats should return Passenger stats' do
expect(command('/usr/sbin/passenger-memory-stats').stdout).to match(
%r{nginx: master process /usr/sbin/nginx.*Passenger watchdog.*Passenger core.*}m
)
end
end
end

View File

@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# vim: ft=yaml
---
name: default
title: nginx formula
maintainer: SaltStack Formulas
license: Apache-2.0
summary: Verify that the nginx formula is setup and configured correctly
supports:
- platform-name: debian
- platform-name: ubuntu
- platform-name: centos

View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# vim: ft=yaml
---
# Simple pillar setup
# - snippet letsencrypt
# - remove 'default' site
# - create 'mysite' site
{%- if grains.os_family in ('RedHat',) %}
{%- set passenger_pkg = 'nginx-mod-http-passenger' %}
{%- set passenger_mod = '/usr/lib64/nginx/modules/ngx_http_passenger_module.so' %}
{%- else %}
{%- set passenger_pkg = 'libnginx-mod-http-passenger' %}
{%- set passenger_mod = '/usr/lib/nginx/modules/ngx_http_passenger_module.so' %}
{%- endif %}
nginx:
check_config_before_apply: true
install_from_phusionpassenger: true
lookup:
passenger_package: {{ passenger_pkg }}
snippets:
letsencrypt.conf:
- location ^~ /.well-known/acme-challenge/:
- proxy_pass: http://localhost:9999
server:
config:
# This is required to get the passenger module loaded
# In Debian it can be done with this
# include: 'modules-enabled/*.conf'
load_module: {{ passenger_mod }}
worker_processes: 4
http:
### module ngx_http_log_module example
log_format: |-
main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
include:
- /etc/nginx/mime.types
- /etc/nginx/conf.d/*.conf
- /etc/nginx/sites-enabled/*
servers:
managed:
default:
deleted: true
enabled: false
config: {}
mysite:
enabled: true
config:
- server:
- passenger_enabled: 'on'
- server_name: localhost
- listen:
- '80 default_server'
- index: 'index.html index.htm'
- location ~ .htm:
- try_files: '$uri $uri/ =404'
# - include: '/etc/nginx/snippets/letsencrypt.conf'
- include: 'snippets/letsencrypt.conf'