diff --git a/.gitignore b/.gitignore index 7cc873fb..0bbb03cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,122 @@ -*.swp +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a packager +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ .kitchen +.kitchen.local.yml +kitchen.local.yml +junit-*.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Bundler +Gemfile.lock + +# copied `.md` files used for conversion to `.rst` using `m2r` +docs/*.md + +# Vim +*.sw? + +## Collected when centralising formulas (check and sort) +# `collectd-formula` +.pytest_cache/ +/.idea/ +Dockerfile.*_* +ignore/ +tmp/ diff --git a/.kitchen.yml b/.kitchen.yml deleted file mode 100644 index 8bbeb2a2..00000000 --- a/.kitchen.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -driver: - name: docker - use_sudo: false - privileged: true - require_chef_omnibus: false - -platforms: - - name: centos-7 - - name: ubuntu-16.04 - - name: debian-9 - -provisioner: - name: salt_solo - formula: apache - require_chef: false - data_path: test/shared - pillars: - top.sls: - base: - '*': - - apache - apache.sls: - apache: - manage_service_states: False - mod_security: - crs_install: True - manage_config: True - sec_rule_engine: 'On' - sec_request_body_access: 'On' - sec_request_body_limit: '14000000' - sec_request_body_no_files_limit: '114002' - sec_request_body_in_memory_limit: '114002' - sec_request_body_limit_action: 'Reject' - sec_pcre_match_limit: '15000' - sec_pcre_match_limit_recursion: '15000' - sec_debug_log_level: '3' - -suites: - - name: default - provisioner: - state_top: - base: - '*': - - apache - - apache.mod_security - - name: apache_norestart - provisioner: - state_top: - base: - '*': - - apache - pillars: - apache.sls: - apache: - manage_service_states: False diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..bdae9aa9 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +# General overrides used across formulas in the org +Metrics/LineLength: + # Increase from default of `80` + # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`) + Max: 88 + +# Any offenses that should be fixed, e.g. collected via. `rubocop --auto-gen-config` diff --git a/.salt-lint b/.salt-lint new file mode 100644 index 00000000..bea98c9c --- /dev/null +++ b/.salt-lint @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +exclude_paths: + # Violation: [203] Most files should not contain tabs + # Violation: [204] Lines should be no longer that 160 chars + - apache/files/Debian/apache-2.4.config.jinja # 203 + - apache/files/Debian/mpm/mpm_event.conf.jinja # 203 + - apache/files/Debian/mpm/mpm_prefork.conf.jinja # 203 + - apache/files/Debian/mpm/mpm_worker.conf.jinja # 203 + - apache/files/Debian/ssl.conf.jinja # 203,204 + - apache/files/FreeBSD/mod_cgi.conf.jinja # 203 + - apache/files/FreeBSD/mod_ssl.conf.jinja # 203,204 + - apache/files/RedHat/conf.modules.d/00-mpm.conf.jinja # 203 + - apache/files/RedHat/modsecurity.conf.jinja # 203 + - apache/files/tls-defaults.conf.jinja # 204 + - apache/logrotate.sls # 203 +skip_list: + # Using `salt-lint` for linting other files as well, such as Jinja macros/templates + - 205 # Use ".sls" as a Salt State file extension + # Skipping `207` and `208` because `210` is sufficient, at least for the time-being + # I.e. Allows 3-digit unquoted codes to still be used, such as `644` and `755` + - 207 # File modes should always be encapsulated in quotation marks + - 208 # File modes should always contain a leading zero +tags: [] +verbosity: 1 diff --git a/.travis.yml b/.travis.yml index a7f3e521..8c0af61d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,104 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +## Machine config +dist: bionic sudo: required -language: python -services: +services: - docker -before_install: - - bundle install - -env: - matrix: - - INSTANCE: default-centos-7 - - INSTANCE: default-ubuntu-1604 - - INSTANCE: default-debian-9 +## Language and cache config +language: ruby +cache: bundler +## Script to run for the test stage script: - - bundle exec kitchen verify ${INSTANCE} + - bin/kitchen verify "${INSTANCE}" + +## Stages and jobs matrix +stages: + - test + - name: release + if: branch = master AND type != pull_request +jobs: + include: + ## Define the test stage that runs the linters (and testing matrix, if applicable) + + # Run all of the linters in a single job + - language: node_js + node_js: lts/* + env: Lint + name: 'Lint: salt-lint, yamllint, rubocop & commitlint' + before_install: skip + script: + # Install and run `salt-lint` + - pip install --user salt-lint + - git ls-files | grep '\.sls$\|\.jinja$\|\.j2$\|\.tmpl$' + | xargs -I {} salt-lint {} + # Install and run `yamllint` + # Need at least `v1.17.0` for the `yaml-files` setting + - pip install --user yamllint>=1.17.0 + - yamllint -s . + # Install and run `rubocop` + - gem install rubocop + - rubocop -d + # Install and run `commitlint` + - npm install @commitlint/config-conventional -D + - npm install @commitlint/travis-cli -D + - commitlint-travis + + ## Define the rest of the matrix based on Kitchen testing + # Make sure the instances listed below match up with + # the `platforms` defined in `kitchen.yml` + - env: INSTANCE=default-debian-10-develop-py3 + # - env: INSTANCE=default-ubuntu-1804-develop-py3 + # - env: INSTANCE=default-centos-7-develop-py3 + # - env: INSTANCE=default-fedora-30-develop-py3 + # - env: INSTANCE=default-opensuse-leap-15-develop-py3 + # - env: INSTANCE=default-amazonlinux-2-develop-py2 + # - env: INSTANCE=default-arch-base-latest-develop-py2 + # - env: INSTANCE=default-debian-9-2019-2-py3 + - env: INSTANCE=default-ubuntu-1804-2019-2-py3 + # - env: INSTANCE=default-centos-7-2019-2-py3 + # - env: INSTANCE=default-fedora-30-2019-2-py3 + # - env: INSTANCE=default-opensuse-leap-15-2019-2-py3 + - env: INSTANCE=default-amazonlinux-2-2019-2-py2 + # - env: INSTANCE=default-arch-base-latest-2019-2-py2 + # - env: INSTANCE=default-debian-9-2018-3-py2 + # - env: INSTANCE=default-ubuntu-1604-2018-3-py2 + # - env: INSTANCE=default-centos-7-2018-3-py2 + - env: INSTANCE=default-fedora-29-2018-3-py2 + # - env: INSTANCE=default-opensuse-leap-15-2018-3-py2 + # - env: INSTANCE=default-amazonlinux-2-2018-3-py2 + # - env: INSTANCE=default-arch-base-latest-2018-3-py2 + # - env: INSTANCE=default-debian-8-2017-7-py2 + # - env: INSTANCE=default-ubuntu-1604-2017-7-py2 + - env: INSTANCE=default-centos-6-2017-7-py2 + # - env: INSTANCE=default-fedora-29-2017-7-py2 + # - env: INSTANCE=default-opensuse-leap-15-2017-7-py2 + # - env: INSTANCE=default-amazonlinux-2-2017-7-py2 + # - env: INSTANCE=default-arch-base-latest-2017-7-py2 + + ## Define the release stage that runs `semantic-release` + - stage: release + language: node_js + node_js: lts/* + env: Release + name: 'Run semantic-release inc. file updates to AUTHORS, CHANGELOG & FORMULA' + before_install: skip + script: + # Update `AUTHORS.md` + - export MAINTAINER_TOKEN=${GH_TOKEN} + - go get github.com/myii/maintainer + - maintainer contributor + + # Install all dependencies required for `semantic-release` + - npm install @semantic-release/changelog@3 -D + - npm install @semantic-release/exec@3 -D + - npm install @semantic-release/git@7 -D + deploy: + provider: script + skip_cleanup: true + script: + # Run `semantic-release` + - npx semantic-release@15 diff --git a/.yamllint b/.yamllint new file mode 100644 index 00000000..740beca0 --- /dev/null +++ b/.yamllint @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +# Extend the `default` configuration provided by `yamllint` +extends: default + +# Files to ignore completely +# 1. All YAML files under directory `node_modules/`, introduced during the Travis run +# 2. Any SLS files under directory `test/`, which are actually state files +# 3. Any YAML files under directory `.kitchen/`, introduced during local testing +ignore: | + node_modules/ + test/**/states/**/*.sls + .kitchen/ + +yaml-files: + # Default settings + - '*.yaml' + - '*.yml' + - .salt-lint + - .yamllint + # SaltStack Formulas additional settings + - '*.example' + - test/**/*.sls + +rules: + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + line-length: + # Increase from default of `80` + # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`) + max: 88 + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true diff --git a/FORMULA b/FORMULA index f8988c0f..315d8e3b 100644 --- a/FORMULA +++ b/FORMULA @@ -1,8 +1,9 @@ name: apache -os: RedHat, Debian, Ubuntu, Suse, FreeBSD +os: RedHat, Fedora, CentOS, Debian, Ubuntu, Suse, FreeBSD os_family: RedHat, Debian, Suse, FreeBSD -version: 201507 +version: 0.37.4 release: 1 minimum_version: 2015.8 summary: Formula for installing Apache description: Formula for installing Apache web server +top_level_dir: apache diff --git a/Gemfile b/Gemfile index 5c8e03f9..5a232b61 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ -source "https://rubygems.org" +# frozen_string_literal: true -gem "test-kitchen", '>=1.2.1' -gem "kitchen-docker" -gem "kitchen-salt", ">=0.0.11" -gem "kitchen-inspec" +source 'https://rubygems.org' + +gem 'kitchen-docker', '>= 2.9' +gem 'kitchen-inspec', '>= 1.1' +gem 'kitchen-salt', '>= 0.6.0' diff --git a/apache/defaults.yaml b/apache/defaults.yaml index e0799e86..2dc0d664 100644 --- a/apache/defaults.yaml +++ b/apache/defaults.yaml @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- # vim: ft=yaml - +--- apache: - manage_service_states: True + manage_service_states: true service_state: running - service_enable: True + service_enable: true mod_security: - crs_install: False - manage_config: False + crs_install: false + manage_config: false diff --git a/apache/files/Debian/apache-2.2.config.jinja b/apache/files/Debian/apache-2.2.config.jinja index 358f0437..2e60b135 100644 --- a/apache/files/Debian/apache-2.2.config.jinja +++ b/apache/files/Debian/apache-2.2.config.jinja @@ -8,7 +8,7 @@ # # Do NOT simply read the instructions in here without understanding # what they do. They're here only as hints or reminders. If you are unsure -# consult the online docs. You have been warned. +# consult the online docs. You have been warned. # # The configuration directives are grouped into three basic sections: # 1. Directives that control the operation of the Apache server process as a @@ -87,7 +87,7 @@ KeepAliveTimeout 5 ## ## Server-Pool Size Regulation (MPM specific) -## +## # prefork MPM # StartServers: number of server processes to start @@ -116,7 +116,7 @@ KeepAliveTimeout 5 StartServers 2 MinSpareThreads 25 - MaxSpareThreads 75 + MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxClients 150 @@ -133,7 +133,7 @@ KeepAliveTimeout 5 StartServers 2 MinSpareThreads 25 - MaxSpareThreads 75 + MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxClients 150 @@ -153,8 +153,8 @@ Group ${APACHE_RUN_GROUP} AccessFileName .htaccess # -# The following lines prevent .htaccess and .htpasswd files from being -# viewed by Web clients. +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. # Order allow,deny diff --git a/apache/files/FreeBSD/apache-2.4.config.jinja b/apache/files/FreeBSD/apache-2.4.config.jinja index 0d9d19af..5c0100ca 100644 --- a/apache/files/FreeBSD/apache-2.4.config.jinja +++ b/apache/files/FreeBSD/apache-2.4.config.jinja @@ -2,20 +2,20 @@ # This is the main Apache HTTP server configuration file. It contains the # configuration directives that give the server its instructions. # See for detailed information. -# In particular, see +# In particular, see # # for a discussion of each configuration directive. # # Do NOT simply read the instructions in here without understanding # what they do. They're here only as hints or reminders. If you are unsure -# consult the online docs. You have been warned. +# consult the online docs. You have been warned. # # Configuration and logfile names: If the filenames you specify for many # of the server's control files begin with "/" (or "drive:/" for Win32), the # server will use that explicit path. If the filenames do *not* begin # with "/", the value of ServerRoot is prepended -- so "logs/access_log" # with ServerRoot set to "/usr/local/apache2" will be interpreted by the -# server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" +# server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" # will be interpreted as '/logs/access_log'. # @@ -168,13 +168,13 @@ LoadModule alias_module libexec/apache24/mod_alias.so # Third party modules IncludeOptional etc/apache24/modules.d/[0-9][0-9][0-9]_*.conf - + Include {{ apache.portsfile }} # # If you wish httpd to run as a different user or group, you must run -# httpd as root initially and it will switch. +# httpd as root initially and it will switch. # # User/Group: The name (or #number) of the user/group to run httpd as. # It is usually good practice to create a dedicated user and group for @@ -215,7 +215,7 @@ ServerAdmin root@localhost # # Deny access to the entirety of your server's filesystem. You must -# explicitly permit access to web content directories in other +# explicitly permit access to web content directories in other # blocks below. # @@ -279,8 +279,8 @@ DocumentRoot "{{ apache.global_document_root }}" # -# The following lines prevent .htaccess and .htpasswd files from being -# viewed by Web clients. +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. # Require all denied @@ -333,8 +333,8 @@ LogLevel warn # - # Redirect: Allows you to tell clients about documents that used to - # exist in your server's namespace, but do not anymore. The client + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client # will make a new request for the document at its new location. # Example: # Redirect permanent /foo http://www.example.com/bar @@ -351,7 +351,7 @@ LogLevel warn # the filesystem path. # - # ScriptAlias: This controls which directories contain server scripts. + # ScriptAlias: This controls which directories contain server scripts. # ScriptAliases are essentially the same as Aliases, except that # documents in the target directory are treated as applications and # run by the server when requested rather than as documents sent to the @@ -454,10 +454,10 @@ LogLevel warn #MaxRanges unlimited # -# EnableMMAP and EnableSendfile: On systems that support it, +# EnableMMAP and EnableSendfile: On systems that support it, # memory-mapping or the sendfile syscall may be used to deliver # files. This usually improves server performance, but must -# be turned off when serving from networked-mounted +# be turned off when serving from networked-mounted # filesystems or if support for these functions is otherwise # broken on your system. # Defaults: EnableMMAP On, EnableSendfile Off @@ -467,9 +467,9 @@ LogLevel warn # Supplemental configuration # -# The configuration files in the etc/apache24/extra/ directory can be -# included to add extra features or to modify the default configuration of -# the server, or you may simply copy their contents here and change as +# The configuration files in the etc/apache24/extra/ directory can be +# included to add extra features or to modify the default configuration of +# the server, or you may simply copy their contents here and change as # necessary. # Server-pool management (MPM specific) diff --git a/apache/files/RedHat/modsecurity.conf.jinja b/apache/files/RedHat/modsecurity.conf.jinja index c41baf1b..2fa04c6c 100644 --- a/apache/files/RedHat/modsecurity.conf.jinja +++ b/apache/files/RedHat/modsecurity.conf.jinja @@ -23,7 +23,7 @@ LoadModule security2_module modules/mod_security2.so # ModSecurity Core Rules Set configuration Include modsecurity.d/*.conf Include modsecurity.d/activated_rules/*.conf - + # Default recommended configuration SecRuleEngine {{ sec_rule_engine }} SecRequestBodyAccess {{ sec_request_body_access }} diff --git a/apache/flags.sls b/apache/flags.sls index 4d6f1e02..4f9f6020 100644 --- a/apache/flags.sls +++ b/apache/flags.sls @@ -4,7 +4,7 @@ include: - apache - + {% for flag in salt['pillar.get']('apache:flags:enabled', []) %} a2enflag {{ flag }}: cmd.run: diff --git a/apache/init.sls b/apache/init.sls index bbe1d7dc..744d6f20 100644 --- a/apache/init.sls +++ b/apache/init.sls @@ -12,7 +12,7 @@ apache: - system: True {# By default run apache service states (unless pillar is false) #} {% if salt['pillar.get']('apache:manage_service_states', True) %} - service.{{apache.service_state}}: + service.{{ apache.service_state }}: - name: {{ apache.service }} {% if apache.service_state in [ 'running', 'dead' ] %} - enable: True @@ -27,7 +27,7 @@ apache-reload: - m_name: {{ apache.service }} {% else %} - name: cmd.run - - cmd: {{apache.custom_reload_command|default('apachectl graceful')}} + - cmd: {{ apache.custom_reload_command|default('apachectl graceful') }} - python_shell: True {% endif %} @@ -38,7 +38,7 @@ apache-restart: - m_name: {{ apache.service }} {% else %} - name: cmd.run - - cmd: {{apache.custom_reload_command|default('apachectl graceful')}} + - cmd: {{ apache.custom_reload_command|default('apachectl graceful') }} - python_shell: True {% endif %} diff --git a/apache/map.jinja b/apache/map.jinja index 0d56fb92..7bc5dd4a 100644 --- a/apache/map.jinja +++ b/apache/map.jinja @@ -1,12 +1,12 @@ -{# vi: set ft=jinja: #} +{#- vi: set ft=jinja: #} -{% import_yaml "apache/defaults.yaml" as default_settings %} -{% import_yaml "apache/osfamilymap.yaml" as osfamilymap %} -{% import_yaml "apache/oscodenamemap.yaml" as oscodenamemap %} -{% import_yaml "apache/osfingermap.yaml" as osfingermap %} -{% import_yaml "apache/modsecurity.yaml" as modsec %} +{%- import_yaml "apache/defaults.yaml" as default_settings %} +{%- import_yaml "apache/osfamilymap.yaml" as osfamilymap %} +{%- import_yaml "apache/oscodenamemap.yaml" as oscodenamemap %} +{%- import_yaml "apache/osfingermap.yaml" as osfingermap %} +{%- import_yaml "apache/modsecurity.yaml" as modsec %} -{% set defaults = salt['grains.filter_by'](default_settings, +{%- set defaults = salt['grains.filter_by'](default_settings, default='apache', merge=salt['grains.filter_by'](modsec, grain='os_family', merge=salt['grains.filter_by'](osfamilymap, grain='os_family', @@ -19,5 +19,5 @@ ) ) %} -{## Merge the apache pillar ##} -{% set apache = salt['pillar.get']('apache', default=defaults, merge=True) %} +{#- Merge the apache pillar #} +{%- set apache = salt['pillar.get']('apache', default=defaults, merge=True) %} diff --git a/apache/mod_geoip.sls b/apache/mod_geoip.sls index aaa5c738..4adba670 100644 --- a/apache/mod_geoip.sls +++ b/apache/mod_geoip.sls @@ -27,7 +27,7 @@ geoip conf: - user: root - group: root - mode: 644 - - source: + - source: - salt://apache/files/{{ salt['grains.get']('os_family') }}/geoip.conf geoip database: diff --git a/apache/modsecurity.yaml b/apache/modsecurity.yaml index 2a089fef..858d6ff7 100644 --- a/apache/modsecurity.yaml +++ b/apache/modsecurity.yaml @@ -1,25 +1,25 @@ # -*- coding: utf-8 -*- -# vim: ft=yam - +# vim: ft=yaml +--- Debian: mod_security: - crs_install: False - manage_config: False + crs_install: false + manage_config: false package: libapache2-mod-security2 crs_package: modsecurity-crs config_file: /etc/modsecurity/modsecurity.conf-recommended RedHat: mod_security: - crs_install: False - manage_config: False + crs_install: false + manage_config: false package: mod_security crs_package: mod_security_crs config_file: /etc/httpd/conf.d/mod_security.conf Suse: mod_security: - crs_install: False - manage_config: False + crs_install: false + manage_config: false package: apache2-mod_security2 config_file: /etc/apache2/conf.d/mod_security2.conf diff --git a/apache/modules.sls b/apache/modules.sls index 2b8d64f0..8f497405 100644 --- a/apache/modules.sls +++ b/apache/modules.sls @@ -46,7 +46,7 @@ a2dismod -f {{ module }}: include: - apache - + {% for module in salt['pillar.get']('apache:modules:enabled', []) %} find /etc/httpd/ -name '*.conf' -type f -exec sed -i -e 's/\(^#\)\(\s*LoadModule.{{ module }}_module\)/\2/g' {} \;: cmd.run: @@ -81,7 +81,7 @@ find /etc/httpd/ -name '*.conf' -type f -exec sed -i -e 's/\(^\s*LoadModule.{{ m include: - apache - + {% for module in salt['pillar.get']('apache:modules:enabled', []) %} a2enmod {{ module }}: cmd.run: diff --git a/apache/oscodenamemap.yaml b/apache/oscodenamemap.yaml index 09494921..690abe4f 100644 --- a/apache/oscodenamemap.yaml +++ b/apache/oscodenamemap.yaml @@ -1,53 +1,53 @@ # -*- coding: utf-8 -*- # vim: ft=yaml - -trusty: +--- +trusty: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -utopic: +utopic: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -vivid: +vivid: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -wily: +wily: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -xenial: +xenial: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -yakkety: +yakkety: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -zesty: +zesty: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -artful: +artful: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -jessie: +jessie: wwwdir: /var/www confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf -stretch: +stretch: wwwdir: /var/www confext: .conf default_site: 000-default.conf @@ -58,4 +58,3 @@ buster: confext: .conf default_site: 000-default.conf default_site_ssl: default-ssl.conf - diff --git a/apache/osfamilymap.yaml b/apache/osfamilymap.yaml index 16328cc2..0a2fe883 100644 --- a/apache/osfamilymap.yaml +++ b/apache/osfamilymap.yaml @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # vim: ft=yaml - +--- Debian: server: apache2 service: apache2 @@ -13,6 +13,7 @@ Debian: mod_php5: libapache2-mod-php5 mod_perl2: libapache2-mod-perl2 mod_fcgid: libapache2-mod-fcgid + # yamllint disable-line rule:line-length mod_pagespeed_source: https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb mod_xsendfile: libapache2-mod-xsendfile mod_fastcgi: libapache2-mod-fastcgi @@ -40,6 +41,7 @@ RedHat: conf_mod_wsgi: /etc/httpd/conf.d/wsgi.conf mod_php5: php mod_fcgid: mod_fcgid + # yamllint disable-line rule:line-length mod_pagespeed_source: https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_x86_64.rpm mod_geoip: mod_geoip mod_geoip_database: GeoIP @@ -53,7 +55,7 @@ RedHat: logrotatedir: /etc/logrotate.d/httpd wwwdir: /var/www default_charset: UTF-8 - use_require: False + use_require: false moddir: /etc/httpd/conf.modules.d Gentoo: @@ -111,7 +113,7 @@ FreeBSD: modulesdir: /usr/local/etc/apache24/modules.d global_document_root: /usr/local/www/apache24/data - confext: + confext: '' default_site: default default_site_ssl: default-ssl logdir: /var/log/ diff --git a/apache/osfingermap.yaml b/apache/osfingermap.yaml index d7c688bd..ce48e8cf 100644 --- a/apache/osfingermap.yaml +++ b/apache/osfingermap.yaml @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # vim: ft=yaml +--- default: version: '2.4' Ubuntu-12.04: diff --git a/apache/server_status.sls b/apache/server_status.sls index c5168eea..dc8169f2 100644 --- a/apache/server_status.sls +++ b/apache/server_status.sls @@ -4,7 +4,7 @@ include: - apache - apache.config -{{apache.confdir}}/server-status{{apache.confext}}: +{{ apache.confdir }}/server-status{{ apache.confext }}: file.managed: - source: salt://apache/files/server-status.conf.jinja - template: jinja diff --git a/apache/uninstall.sls b/apache/uninstall.sls index cc24fbca..65683f0e 100644 --- a/apache/uninstall.sls +++ b/apache/uninstall.sls @@ -1,5 +1,5 @@ {% from "apache/map.jinja" import apache with context %} - + apache-uninstall: service.dead: - name: {{ apache.service }} diff --git a/apache/vhosts/cleanup.sls b/apache/vhosts/cleanup.sls index e6b3decb..25260cbe 100644 --- a/apache/vhosts/cleanup.sls +++ b/apache/vhosts/cleanup.sls @@ -26,7 +26,7 @@ include: a2dissite {{ filename }}: cmd.run: - - onlyif: "test -L {{ dirpath}}/{{ filename }} || test -f {{ dirpath}}/{{ filename }}" + - onlyif: "test -L {{ dirpath }}/{{ filename }} || test -f {{ dirpath }}/{{ filename }}" - watch_in: - module: apache-reload - require_in: diff --git a/apache/vhosts/minimal.tmpl b/apache/vhosts/minimal.tmpl index 11ca0c4d..00b9a170 100644 --- a/apache/vhosts/minimal.tmpl +++ b/apache/vhosts/minimal.tmpl @@ -22,7 +22,7 @@ 'DocumentRoot': site.get('DocumentRoot', '{0}/{1}'.format(map.wwwdir, sitename)) } -%} - + ServerName {{ vals.ServerName }} {% if site.get('ServerAlias') != False %}ServerAlias {{ vals.ServerAlias }}{% endif %} {% if site.get('ServerAdmin') != False %}ServerAdmin {{ vals.ServerAdmin }}{% endif %} diff --git a/apache/vhosts/proxy.tmpl b/apache/vhosts/proxy.tmpl index 4f45ecfe..6511b513 100644 --- a/apache/vhosts/proxy.tmpl +++ b/apache/vhosts/proxy.tmpl @@ -35,7 +35,7 @@ 'Require': 'all granted', }, } %} - + ServerName {{ vals.ServerName }} {% if site.get('ServerAlias') != False %}ServerAlias {{ vals.ServerAlias }}{% endif %} {% if site.get('ServerAdmin') != False %}ServerAdmin {{ vals.ServerAdmin }}{% endif %} @@ -50,7 +50,7 @@ {% if site.get('SSLCertificateFile') %}SSLEngine on SSLCertificateFile {{ site.SSLCertificateFile }} {% if site.get('SSLCertificateKeyFile') %}SSLCertificateKeyFile {{ site.SSLCertificateKeyFile }}{% endif %} - {% if site.get('SSLCertificateChainFile') %}SSLCertificateChainFile {{ site.SSLCertificateChainFile}}{% endif %} + {% if site.get('SSLCertificateChainFile') %}SSLCertificateChainFile {{ site.SSLCertificateChainFile }}{% endif %} {% endif %} {% if site.get('Rewrite') %}RewriteEngine on {{ site.Rewrite }} @@ -82,7 +82,7 @@ } %} {% if apache.version == '2.4' %} - {%- if lvals.get('Require') != False %}Require {{lvals.Require}}{% endif %} + {%- if lvals.get('Require') != False %}Require {{ lvals.Require }}{% endif %} {% else %} {%- if lvals.get('Order') != False %}Order {{ lvals.Order }}{% endif %} {%- if lvals.get('Allow') != False %}Allow {{ lvals.Allow }}{% endif %} @@ -99,7 +99,7 @@ } %} {% if apache.version == '2.4' %} - {%- if lmvals.get('Require') != False %}Require {{lmvals.Require}}{% endif %} + {%- if lmvals.get('Require') != False %}Require {{ lmvals.Require }}{% endif %} {% else %} {%- if lmvals.get('Order') != False %}Order {{ lmvals.Order }}{% endif %} {%- if lmvals.get('Allow') != False %}Allow {{ lmvals.Allow }}{% endif %} diff --git a/apache/vhosts/redirect.tmpl b/apache/vhosts/redirect.tmpl index 3a3759ce..0811ac3b 100644 --- a/apache/vhosts/redirect.tmpl +++ b/apache/vhosts/redirect.tmpl @@ -20,12 +20,12 @@ 'ErrorLog': site.get('ErrorLog', '{0}/{1}-error.log'.format(map.logdir, sitename)), 'LogFormat': site.get('LogFormat', '"%h %l %u %t \\\"%r\\\" %>s %O"'), 'CustomLog': site.get('CustomLog', '{0}/{1}-access.log'.format(map.logdir, sitename)), - + 'RedirectSource': site.get('RedirectSource', '/'), 'RedirectTarget': site.get('RedirectTarget', 'https://{0}/'.format(sitename)), } %} - + ServerName {{ vals.ServerName }} {% if site.get('ServerAlias') != False %}ServerAlias {{ vals.ServerAlias }}{% endif %} @@ -44,7 +44,7 @@ {% else %} Redirect {{ vals.RedirectSource }} {{ vals.RedirectTarget }} {% endif %} - + {% if site.get('Formula_Append') %} {{ site.Formula_Append|indent(4) }} {% endif %} diff --git a/apache/vhosts/standard.tmpl b/apache/vhosts/standard.tmpl index ff79e1f3..ed662df2 100644 --- a/apache/vhosts/standard.tmpl +++ b/apache/vhosts/standard.tmpl @@ -43,7 +43,7 @@ }, } -%} - + ServerName {{ vals.ServerName }} {% if site.get('ServerAlias') != False %}ServerAlias {{ vals.ServerAlias }}{% endif %} @@ -67,9 +67,9 @@ {% if site.get('SSLCertificateFile') %}SSLEngine on SSLCertificateFile {{ site.SSLCertificateFile }} {% if site.get('SSLCertificateKeyFile') %}SSLCertificateKeyFile {{ site.SSLCertificateKeyFile }}{% endif %} - {% if site.get('SSLCertificateChainFile') %}SSLCertificateChainFile {{ site.SSLCertificateChainFile}}{% endif %} + {% if site.get('SSLCertificateChainFile') %}SSLCertificateChainFile {{ site.SSLCertificateChainFile }}{% endif %} {% endif %} - + {% if site.get('Rewrite') %}RewriteEngine on {{ site.Rewrite }} {% endif %} @@ -93,7 +93,7 @@ {% if dvals.get('Options') != False %}Options {{ dvals.Options }}{% endif %} {% if map.version == '2.4' %} - {% if dvals.get('Require') != False %}Require {{dvals.Require}}{% endif %} + {% if dvals.get('Require') != False %}Require {{ dvals.Require }}{% endif %} {% else %} {% if dvals.get('Order') != False %}Order {{ dvals.Order }}{% endif %} {% if dvals.get('Allow') != False %}Allow {{ dvals.Allow }}{% endif %} @@ -117,7 +117,7 @@ {% if map.version == '2.4' %} - {%- if lvals.get('Require') != False %}Require {{lvals.Require}}{% endif %} + {%- if lvals.get('Require') != False %}Require {{ lvals.Require }}{% endif %} {% else %} {%- if lvals.get('Order') != False %}Order {{ lvals.Order }}{% endif %} {%- if lvals.get('Allow') != False %}Allow {{ lvals.Allow }}{% endif %} diff --git a/bin/kitchen b/bin/kitchen new file mode 100755 index 00000000..dcfdb4ca --- /dev/null +++ b/bin/kitchen @@ -0,0 +1,32 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'kitchen' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path('bundle', __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort( + 'Your `bin/bundle` was not generated by Bundler, '\ + 'so this binstub cannot run. Replace `bin/bundle` by running '\ + '`bundle binstubs bundler --force`, then run this command again.' + ) + end +end + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('test-kitchen', 'kitchen') diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 00000000..2f9d1aa0 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; diff --git a/README.rst b/docs/README.rst similarity index 60% rename from README.rst rename to docs/README.rst index 0e8b4b54..6a2ae5d6 100644 --- a/README.rst +++ b/docs/README.rst @@ -1,122 +1,152 @@ -====== +.. _readme: + apache ====== +|img_travis| |img_sr| + +.. |img_travis| image:: https://travis-ci.com/saltstack-formulas/apache-formula.svg?branch=master + :alt: Travis CI Build Status + :scale: 100% + :target: https://travis-ci.com/saltstack-formulas/apache-formula +.. |img_sr| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg + :alt: Semantic Release + :scale: 100% + :target: https://github.com/semantic-release/semantic-release + Formulas to set up and configure the Apache HTTP server. -.. note:: +.. contents:: **Table of Contents** + +General notes +------------- + +See the full `SaltStack Formulas installation and usage instructions +`_. + +If you are interested in writing or contributing to formulas, please pay attention to the `Writing Formula Section +`_. + +If you want to use this formula, please pay attention to the ``FORMULA`` file and/or ``git tag``, +which contains the currently released version. This formula is versioned according to `Semantic Versioning `_. - See the full `Salt Formulas installation and usage instructions - `_. +See `Formula Versioning Section `_ for more details. + +Contributing to this repo +------------------------- + +**Commit message formatting is significant!!** + +Please see `How to contribute `_ for more details. Available states -================ +---------------- .. contents:: - :local: + :local: ``apache`` ----------- +^^^^^^^^^^ Installs the Apache package and starts the service. ``apache.config`` ------------------ +^^^^^^^^^^^^^^^^^ Configures apache based on os_family ``apache.certificates`` ------------------ +^^^^^^^^^^^^^^^^^^^^^^^ Deploy SSL certificates from pillars ``apache.mod_mpm`` ------------------- +^^^^^^^^^^^^^^^^^^ Configures the apache mpm modules on Debian ``mpm_prefork``, ``mpm_worker`` or ``mpm_event`` (Debian Only) ``apache.modules`` ------------------- +^^^^^^^^^^^^^^^^^^ Enables and disables Apache modules. ``apache.mod_rewrite`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Enabled the Apache module mod_rewrite (Debian and FreeBSD only) ``apache.mod_proxy`` -------------------- +^^^^^^^^^^^^^^^^^^^^ Enables the Apache module mod_proxy. (Debian and FreeBSD only) ``apache.mod_proxy_http`` -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ Enables the Apache module mod_proxy_http and requires the Apache module mod_proxy to be enabled. (Debian Only) ``apache.mod_proxy_fcgi`` -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ Enables the Apache module mod_proxy_fcgi and requires the Apache module mod_proxy to be enabled. (Debian Only) ``apache.mod_wsgi`` -------------------- +^^^^^^^^^^^^^^^^^^^ Installs the mod_wsgi package and enables the Apache module. ``apache.mod_actions`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Enables the Apache module mod_actions. (Debian Only) ``apache.mod_headers`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Enables the Apache module mod_headers. (Debian Only) ``apache.mod_pagespeed`` ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ Installs and Enables the mod_pagespeed module. (Debian and RedHat Only) ``apache.mod_perl2`` -------------------- +^^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_perl2 module (Debian and FreeBSD only) ``apache.mod_geoip`` -------------------- +^^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_geoIP (RedHat only) ``apache.mod_php5`` -------------------- +^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_php5 module ``apache.mod_cgi`` ---------------------- +^^^^^^^^^^^^^^^^^^ Enables mod_cgi. (FreeBSD only) ``apache.mod_fcgid`` --------------------- +^^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_fcgid module (Debian only) ``apache.mod_fastcgi`` --------------------- +^^^^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_fastcgi module ``apache.mod_dav_svn`` --------------------- +^^^^^^^^^^^^^^^^^^^^^^ Installs and enables the mod_dav_svn module (Debian only) ``apache.mod_security`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^^ Installs an enables the `Apache mod_security2 WAF``_ using data from Pillar. (Debian and RedHat Only) @@ -124,53 +154,53 @@ using data from Pillar. (Debian and RedHat Only) Allows you to install the basic Core Rules (CRS) and some basic configuration for mod_security2 ``apache.mod_security.rules`` ------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This state can create symlinks based on basic Core Rules package. (Debian only) Or it can distribute a mod_security rule file and place it /etc/modsecurity/ ``apache.mod_socache_shmcb`` ---------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Enables mod_socache_shmcb. (FreeBSD only) ``apache.mod_ssl`` ----------------------- +^^^^^^^^^^^^^^^^^^ Installs and enables the mod_ssl module (Debian, RedHat and FreeBSD only) ``apache.mod_suexec`` ---------------------- +^^^^^^^^^^^^^^^^^^^^^ Enables mod_suexec. (FreeBSD only) ``apache.mod_vhost_alias`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ Enables the Apache module vhost_alias (Debian Only) ``apache.mod_remoteip`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^^ Enables and configures the Apache module mod_remoteip using data from Pillar. (Debian Only) ``apache.mod_xsendfile`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ Installs and enables mod_xsendfile module. (Debian Only) ``apache.own_default_vhost`` --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Replace default vhost with own version. By default, it's 503 code. (Debian Only) ``apache.no_default_vhost`` --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the default vhost. (Debian Only) ``apache.vhosts.standard`` --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ Configures Apache name-based virtual hosts and creates virtual host directories using data from Pillar. @@ -194,22 +224,22 @@ of interfaces to bind to. For example, to bind both IPv4 and IPv6: interface: '1.2.3.4 [2001:abc:def:100::3]' ``apache.manage_security`` --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ Configures Apache's security.conf options by reassinging them using data from Pillar. ``apache.server_status`` --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ Configures Apache's server_status handler for localhost ``apache.debian_full`` ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Installs and configures Apache on Debian and Ubuntu systems. ``apache.uninstall`` ----------- +^^^^^^^^^^^^^^^^^^^^ Stops the Apache service and uninstalls the package. @@ -238,3 +268,48 @@ Example Pillar: name: 'my name' path: 'salt://path/to/sites-available/conf/file' state: 'enabled' + +Testing +------- + +Linux testing is done with ``kitchen-salt``. + +Requirements +^^^^^^^^^^^^ + +* Ruby +* Docker + +.. code-block:: bash + + $ gem install bundler + $ bundle install + $ bin/kitchen test [platform] + +Where ``[platform]`` is the platform name defined in ``kitchen.yml``, +e.g. ``debian-9-2019-2-py3``. + +``bin/kitchen converge`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Creates the docker instance and runs the ``template`` main state, ready for testing. + +``bin/kitchen verify`` +^^^^^^^^^^^^^^^^^^^^^^ + +Runs the ``inspec`` tests on the actual instance. + +``bin/kitchen destroy`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Removes the docker instance. + +``bin/kitchen test`` +^^^^^^^^^^^^^^^^^^^^ + +Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``. + +``bin/kitchen login`` +^^^^^^^^^^^^^^^^^^^^^ + +Gives you SSH access to the instance for manual testing. diff --git a/kitchen.yml b/kitchen.yml new file mode 100644 index 00000000..8b86b6b3 --- /dev/null +++ b/kitchen.yml @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +# For help on this file's format, see https://kitchen.ci/ +driver: + name: docker + use_sudo: false + privileged: true + run_command: /lib/systemd/systemd + +# Make sure the platforms listed below match up with +# the `env.matrix` instances defined in `.travis.yml` +platforms: + ## SALT `develop` + - name: debian-10-develop-py3 + driver: + image: netmanagers/salt-develop-py3:debian-10 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git develop + - name: ubuntu-1804-develop-py3 + driver: + image: netmanagers/salt-develop-py3:ubuntu-18.04 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git develop + - name: centos-7-develop-py3 + driver: + image: netmanagers/salt-develop-py3:centos-7 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git develop + - name: fedora-30-develop-py3 + driver: + image: netmanagers/salt-develop-py3:fedora-30 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git develop + - name: opensuse-leap-15-develop-py3 + driver: + image: opensuse/leap:15 + provision_command: + # yamllint disable-line rule:line-length + - zypper install -y glibc-locale net-tools net-tools-deprecated python-xml python3-pip + - systemctl enable sshd.service + run_command: /usr/lib/systemd/systemd + provisioner: + salt_bootstrap_options: -XdPfrq -x python3 git develop + salt_install: bootstrap + # Workaround to avoid intermittent failures on `opensuse-leap-15`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + - name: amazonlinux-2-develop-py2 + driver: + image: netmanagers/salt-develop-py2:amazonlinux-2 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python2 git develop + - name: arch-base-latest-develop-py2 + driver: + image: netmanagers/salt-develop-py2:arch-base-latest + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python2 git develop + run_command: /usr/lib/systemd/systemd + + ## SALT `2019.2` + - name: debian-9-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:debian-9 + - name: ubuntu-1804-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:ubuntu-18.04 + - name: centos-7-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:centos-7 + - name: fedora-30-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:fedora-30 + - name: opensuse-leap-15-2019-2-py3 + driver: + image: opensuse/leap:15 + provision_command: + # yamllint disable-line rule:line-length + - zypper install -y glibc-locale net-tools net-tools-deprecated python-xml python3-pip + - systemctl enable sshd.service + run_command: /usr/lib/systemd/systemd + provisioner: + salt_bootstrap_options: -XdPfrq -x python3 git 2019.2 + salt_install: bootstrap + # Workaround to avoid intermittent failures on `opensuse-leap-15`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + - name: amazonlinux-2-2019-2-py2 + driver: + image: netmanagers/salt-2019.2-py2:amazonlinux-2 + - name: arch-base-latest-2019-2-py2 + driver: + image: netmanagers/salt-2019.2-py2:arch-base-latest + run_command: /usr/lib/systemd/systemd + + ## SALT `2018.3` + - name: debian-9-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:debian-9 + - name: ubuntu-1604-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:ubuntu-16.04 + - name: centos-7-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:centos-7 + - name: fedora-29-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:fedora-29 + - name: opensuse-leap-15-2018-3-py2 + driver: + image: opensuse/leap:15 + provision_command: + # yamllint disable-line rule:line-length + - zypper install -y glibc-locale net-tools net-tools-deprecated python-xml python2-pip + - systemctl enable sshd.service + run_command: /usr/lib/systemd/systemd + provisioner: + salt_bootstrap_options: -XdPfrq -x python2 git 2018.3 + salt_install: bootstrap + # Workaround to avoid intermittent failures on `opensuse-leap-15`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + - name: amazonlinux-2-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:amazonlinux-2 + - name: arch-base-latest-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:arch-base-latest + run_command: /usr/lib/systemd/systemd + + ## SALT `2017.7` + - name: debian-8-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:debian-8 + - name: ubuntu-1604-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:ubuntu-16.04 + - name: centos-6-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:centos-6 + run_command: /sbin/init + - name: fedora-29-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:fedora-29 + - name: opensuse-leap-15-2017-7-py2 + driver: + image: opensuse/leap:15 + provision_command: + # yamllint disable-line rule:line-length + - zypper install -y glibc-locale net-tools net-tools-deprecated python-xml python2-pip + - systemctl enable sshd.service + run_command: /usr/lib/systemd/systemd + provisioner: + salt_bootstrap_options: -XdPfrq -x python2 git 2017.7 + salt_install: bootstrap + # Workaround to avoid intermittent failures on `opensuse-leap-15`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + - name: amazonlinux-2-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:amazonlinux-2 + - name: arch-base-latest-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:arch-base-latest + run_command: /usr/lib/systemd/systemd + +provisioner: + name: salt_solo + log_level: debug + salt_install: none + require_chef: false + formula: apache + salt_copy_filter: + - .kitchen + - .git + +verifier: + # https://www.inspec.io/ + name: inspec + sudo: true + # cli, documentation, html, progress, json, json-min, json-rspec, junit + reporter: + - cli + +suites: + - name: default + provisioner: + state_top: + base: + '*': + - apache + - apache.mod_security + pillars: + top.sls: + base: + '*': + - apache + pillars_from_files: + apache.sls: test/salt/pillar/default.sls + verifier: + inspec_tests: + - path: test/integration/default diff --git a/pillar.example b/pillar.example index f3039fd0..4d1443a3 100644 --- a/pillar.example +++ b/pillar.example @@ -1,8 +1,11 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- # ``apache`` formula configuration: apache: # By default apache restart/reload states run (false skips) - manage_service_states: True + manage_service_states: true # lookup section overrides ``map.jinja`` values lookup: @@ -47,9 +50,10 @@ apache: example.net: template_file: salt://apache/vhosts/minimal.tmpl - example.com: # must be unique; used as an ID declaration in Salt. - enabled: True - template_file: salt://apache/vhosts/standard.tmpl # or minimal.tmpl or redirect.tmpl or proxy.tmpl + example.com: # must be unique; used as an ID declaration in Salt. + enabled: true + # or minimal.tmpl or redirect.tmpl or proxy.tmpl + template_file: salt://apache/vhosts/standard.tmpl ####################### DEFAULT VALUES BELOW ############################ # NOTE: the values below are simply default settings that *can* be @@ -64,42 +68,51 @@ apache: interface: '*' port: '80' - exclude_listen_directive: True # Do not add a Listen directive in httpd.conf + exclude_listen_directive: true # Do not add a Listen directive in httpd.conf - ServerName: example.com # uses the unique ID above unless specified - #ServerAlias: www.example.com # Do not add ServerAlias unless defined + ServerName: example.com # uses the unique ID above unless specified + # ServerAlias: www.example.com # Do not add ServerAlias unless defined ServerAdmin: webmaster@example.com LogLevel: warn - ErrorLog: /path/to/logs/example.com-error.log # E.g.: /var/log/apache2/example.com-error.log - CustomLog: /path/to/logs/example.com-access.log # E.g.: /var/log/apache2/example.com-access.log - - DocumentRoot: /path/to/www/dir/example.com # E.g., /var/www/example.com - DocumentRootUser: null # do not enforce user, defaults to lookup:document_root_user - DocumentRootGroup: www-data # Force group, defaults to lookup:document_root_group - - SSLCertificateFile: /etc/ssl/mycert.pem # if ssl is desired - SSLCertificateKeyFile: /etc/ssl/mycert.pem.key # if key for cert is needed or in an extra file - SSLCertificateChainFile: /etc/ssl/mycert.chain.pem # if you require a chain of server certificates file + # E.g.: /var/log/apache2/example.com-error.log + ErrorLog: /path/to/logs/example.com-error.log + # E.g.: /var/log/apache2/example.com-access.log + CustomLog: /path/to/logs/example.com-access.log + + # E.g., /var/www/example.com + DocumentRoot: /path/to/www/dir/example.com + # do not enforce user, defaults to lookup:document_root_user + DocumentRootUser: null + # Force group, defaults to lookup:document_root_group + DocumentRootGroup: www-data + + # if ssl is desired + SSLCertificateFile: /etc/ssl/mycert.pem + # if key for cert is needed or in an extra file + SSLCertificateKeyFile: /etc/ssl/mycert.pem.key + # if you require a chain of server certificates file + SSLCertificateChainFile: /etc/ssl/mycert.chain.pem Directory: # "default" is a special case; uses DocumentRoot value # E.g.: /var/www/example.com default: Options: -Indexes +FollowSymLinks - Order: allow,deny # For Apache < 2.4 - Allow: from all # For apache < 2.4 - Require: all granted # For apache > 2.4. + Order: allow,deny # For Apache < 2.4 + Allow: from all # For apache < 2.4 + Require: all granted # For apache > 2.4. AllowOverride: None Formula_Append: | Additional config as a multi-line string here redirectmatch.com: - # Use RedirectMatch Directive https://httpd.apache.org/docs/2.4/fr/mod/mod_alias.html#redirectmatch - # Require module mod_alias - enabled: True + # Use RedirectMatch Directive + # - https://httpd.apache.org/docs/2.4/fr/mod/mod_alias.html#redirectmatch + # Require module mod_alias + enabled: true template_file: salt://apache/vhosts/redirect.tmpl ServerName: www.redirectmatch.com ServerAlias: www.redirectmatch.com @@ -228,7 +241,7 @@ apache: Location: /: - Require: False + Require: false Formula_Append: | SecRuleRemoveById 981231 SecRuleRemoveById 981173 @@ -237,27 +250,27 @@ apache: Require: 'all granted' /docs: - Order: allow,deny # For Apache < 2.4 - Allow: from all # For apache < 2.4 - Require: all granted # For apache > 2.4. + Order: allow,deny # For Apache < 2.4 + Allow: from all # For apache < 2.4 + Require: all granted # For apache > 2.4. Formula_Append: | Additional config as a multi-line string here LocationMatch: '^[.\\/]+([Ww][Ee][Bb][Mm][Aa][Ii][Ll])[.\\/]': - Require: False + Require: false Formula_Append: | RequestHeader set Host mail.example.com '^[.\\/]+([Ss][Vv][Cc])[.\\/]': - Require: False + Require: false Formula_Append: | Require ip 123.123.13.6 84.24.25.74 Proxy_control: '*': - AllowAll: False + AllowAll: false AllowCountry: - DE AllowIP: @@ -280,21 +293,21 @@ apache: path: 'salt://path/to/sites-available/conf/file' state: 'enabled' # Optional - use managed file as Jinja Template - #template: true - #defaults: - # custom_var: "default value" + # template: true + # defaults: + # custom_var: "default value" modules: - enabled: # List modules to enable + enabled: # List modules to enable - ldap - ssl disabled: # List modules to disable - rewrite flags: - enabled: # List server flags to enable + enabled: # List server flags to enable - SSL - disabled: # List server flags to disable + disabled: # List server flags to disable - status # KeepAlive: Whether or not to allow persistent connections (more than @@ -325,9 +338,9 @@ apache: # ``apache.mod_security`` formula additional configuration: mod_security: - crs_install: True + crs_install: true # If not set, default distro's configuration is installed as is - manage_config: True + manage_config: true sec_rule_engine: 'On' sec_request_body_access: 'On' sec_request_body_limit: '14000000' @@ -339,33 +352,36 @@ apache: sec_debug_log_level: '3' rules: - enabled: + enabled: ~ modsecurity_crs_10_setup.conf: rule_set: '' - enabled: True + enabled: true modsecurity_crs_20_protocol_violations.conf: rule_set: 'base_rules' - enabled: False + enabled: false custom_rule_files: # any name as an array index, and you can duplicate this section UNIQUE_VALUE_HERE: file: 'my name' path: 'salt://path/to/modsecurity/custom/file' - enabled: True + enabled: true mod_ssl: - # set this to True if you want to override your distributions default TLS configuration - manage_tls_defaults: False - # This stuff is deliberately not configured via map.jinja resp. apache:lookup. - # We're unable to know sane defaults for each release of every distribution. - # See https://github.com/saltstack-formulas/openssh-formula/issues/102 for a related discussion - # Have a look at bettercrypto.org for up-to-date settings. + # set this to true if you want to override your distributions default TLS + # configuration + manage_tls_defaults: false + # This stuff is deliberately not configured via map.jinja resp. + # apache:lookup. We're unable to know sane defaults for each release of + # every distribution. + # See https://github.com/saltstack-formulas/openssh-formula/issues/102 for + # a related discussion Have a look at bettercrypto.org for up-to-date + # settings. # These are default values: + # yamllint disable-line rule:line-length SSLCipherSuite: EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA # Mitigate the CRIME attack - SSLCompression: Off + SSLCompression: 'Off' SSLProtocol: all -SSLv2 -SSLv3 -TLSv1 - SSLHonorCipherOrder: On + SSLHonorCipherOrder: 'On' SSLOptions: "+StrictRequire" - diff --git a/pre-commit_semantic-release.sh b/pre-commit_semantic-release.sh new file mode 100755 index 00000000..9d34d74c --- /dev/null +++ b/pre-commit_semantic-release.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +############################################################################### +# (A) Update `FORMULA` with `${nextRelease.version}` +############################################################################### +sed -i -e "s_^\(version:\).*_\1 ${1}_" FORMULA + + +############################################################################### +# (B) Use `m2r` to convert automatically produced `.md` docs to `.rst` +############################################################################### + +# Install `m2r` +sudo -H pip install m2r + +# Copy and then convert the `.md` docs +cp *.md docs/ +cd docs/ +m2r --overwrite *.md + +# Change excess `H1` headings to `H2` in converted `CHANGELOG.rst` +sed -i -e '/^=.*$/s/=/-/g' CHANGELOG.rst +sed -i -e '1,4s/-/=/g' CHANGELOG.rst + +# Use for debugging output, when required +# cat AUTHORS.rst +# cat CHANGELOG.rst + +# Return back to the main directory +cd .. diff --git a/release-rules.js b/release-rules.js new file mode 100644 index 00000000..c63c850d --- /dev/null +++ b/release-rules.js @@ -0,0 +1,18 @@ +// No release is triggered for the types commented out below. +// Commits using these types will be incorporated into the next release. +// +// NOTE: Any changes here must be reflected in `CONTRIBUTING.md`. +module.exports = [ + {breaking: true, release: 'major'}, + // {type: 'build', release: 'patch'}, + // {type: 'chore', release: 'patch'}, + // {type: 'ci', release: 'patch'}, + {type: 'docs', release: 'patch'}, + {type: 'feat', release: 'minor'}, + {type: 'fix', release: 'patch'}, + {type: 'perf', release: 'patch'}, + {type: 'refactor', release: 'patch'}, + {type: 'revert', release: 'patch'}, + {type: 'style', release: 'patch'}, + {type: 'test', release: 'patch'}, +]; diff --git a/release.config.js b/release.config.js new file mode 100644 index 00000000..afa0cb11 --- /dev/null +++ b/release.config.js @@ -0,0 +1,106 @@ +module.exports = { + branch: 'master', + plugins: [ + ['@semantic-release/commit-analyzer', { + preset: 'angular', + releaseRules: './release-rules.js', + }], + '@semantic-release/release-notes-generator', + ['@semantic-release/changelog', { + changelogFile: 'CHANGELOG.md', + changelogTitle: '# Changelog', + }], + ['@semantic-release/exec', { + prepareCmd: 'sh ./pre-commit_semantic-release.sh ${nextRelease.version}', + }], + ['@semantic-release/git', { + assets: ['*.md', 'docs/*.rst', 'FORMULA'], + }], + '@semantic-release/github', + ], + generateNotes: { + preset: 'angular', + writerOpts: { + // Required due to upstream bug preventing all types being displayed. + // Bug: https://github.com/conventional-changelog/conventional-changelog/issues/317 + // Fix: https://github.com/conventional-changelog/conventional-changelog/pull/410 + transform: (commit, context) => { + const issues = [] + + commit.notes.forEach(note => { + note.title = `BREAKING CHANGES` + }) + + // NOTE: Any changes here must be reflected in `CONTRIBUTING.md`. + if (commit.type === `feat`) { + commit.type = `Features` + } else if (commit.type === `fix`) { + commit.type = `Bug Fixes` + } else if (commit.type === `perf`) { + commit.type = `Performance Improvements` + } else if (commit.type === `revert`) { + commit.type = `Reverts` + } else if (commit.type === `docs`) { + commit.type = `Documentation` + } else if (commit.type === `style`) { + commit.type = `Styles` + } else if (commit.type === `refactor`) { + commit.type = `Code Refactoring` + } else if (commit.type === `test`) { + commit.type = `Tests` + } else if (commit.type === `build`) { + commit.type = `Build System` + // } else if (commit.type === `chore`) { + // commit.type = `Maintenance` + } else if (commit.type === `ci`) { + commit.type = `Continuous Integration` + } else { + return + } + + if (commit.scope === `*`) { + commit.scope = `` + } + + if (typeof commit.hash === `string`) { + commit.hash = commit.hash.substring(0, 7) + } + + if (typeof commit.subject === `string`) { + let url = context.repository + ? `${context.host}/${context.owner}/${context.repository}` + : context.repoUrl + if (url) { + url = `${url}/issues/` + // Issue URLs. + commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => { + issues.push(issue) + return `[#${issue}](${url}${issue})` + }) + } + if (context.host) { + // User URLs. + commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => { + if (username.includes('/')) { + return `@${username}` + } + + return `[@${username}](${context.host}/${username})` + }) + } + } + + // remove references that already appear in the subject + commit.references = commit.references.filter(reference => { + if (issues.indexOf(reference.issue) === -1) { + return true + } + + return false + }) + + return commit + }, + }, + }, +}; diff --git a/test/integration/default/README.md b/test/integration/default/README.md new file mode 100644 index 00000000..37cf963c --- /dev/null +++ b/test/integration/default/README.md @@ -0,0 +1,50 @@ +# InSpec Profile: `default` + +This shows the implementation of the `default` 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 default +Summary +------- +Location: default +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 default +.. + +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 default --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). diff --git a/test/integration/default/controls/mod_security_spec.rb b/test/integration/default/controls/mod_security_spec.rb new file mode 100644 index 00000000..1e59ed2e --- /dev/null +++ b/test/integration/default/controls/mod_security_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +control 'Apache mod_security configuration' do + title 'should match desired lines' + + modspec_file = + case platform[:family] + when 'redhat', 'fedora' + '/etc/httpd/conf.d/mod_security.conf' + when 'debian' + '/etc/modsecurity/modsecurity.conf-recommended' + end + + describe file(modspec_file) do + it { should be_file } + its('mode') { should cmp '0644' } + its('owner') { should eq 'root' } + its('group') { should eq 'root' } + its('content') { should match(/SecRuleEngine On/) } + its('content') { should match(/SecRequestBodyAccess On/) } + its('content') { should match(/SecRequestBodyLimit 14000000/) } + its('content') { should match(/SecRequestBodyNoFilesLimit 114002/) } + its('content') { should match(/SecRequestBodyInMemoryLimit 114002/) } + its('content') { should match(/SecRequestBodyLimitAction Reject/) } + its('content') { should match(/SecPcreMatchLimit 15000/) } + its('content') { should match(/SecPcreMatchLimitRecursion 15000/) } + its('content') { should match(/SecDebugLogLevel 3/) } + end +end diff --git a/test/integration/default/inspec.yml b/test/integration/default/inspec.yml new file mode 100644 index 00000000..c0831529 --- /dev/null +++ b/test/integration/default/inspec.yml @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +name: default +title: apache formula +maintainer: SaltStack Formulas +license: Apache-2.0 +summary: Verify that the apache formula is setup and configured correctly +supports: + - platform-name: debian + - platform-name: ubuntu + - platform-name: centos + - platform-name: fedora + - platform-name: opensuse + - platform-name: suse + - platform-name: freebsd + - platform-name: amazon + - platform-name: arch diff --git a/test/integration/mod_security/serverspec/mod_security_spec.rb b/test/integration/mod_security/serverspec/mod_security_spec.rb deleted file mode 100644 index ae5c0c0f..00000000 --- a/test/integration/mod_security/serverspec/mod_security_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require_relative '../../../kitchen/data/spec_helper' - -describe 'apache.mod_security' do - - case os[:family] - when 'redhat' - modspec_file = '/etc/httpd/conf.d/mod_security.conf' - when 'debian', 'ubuntu' - modspec_file = '/etc/modsecurity/modsecurity.conf-recommended' - else - # No other supported ATM - end - - describe file(modspec_file) do - it { should exist } - it { should be_mode 644 } - it { should be_owned_by 'root' } - it { should be_grouped_into 'root' } - its(:content) { should match /SecRuleEngine On/ } - its(:content) { should match /SecRequestBodyAccess On/ } - its(:content) { should match /SecRequestBodyLimit 14000000/ } - its(:content) { should match /SecRequestBodyNoFilesLimit 114002/ } - its(:content) { should match /SecRequestBodyInMemoryLimit 114002/ } - its(:content) { should match /SecRequestBodyLimitAction Reject/ } - its(:content) { should match /SecPcreMatchLimit 15000/ } - its(:content) { should match /SecPcreMatchLimitRecursion 15000/ } - its(:content) { should match /SecDebugLogLevel 3/ } - end -end diff --git a/test/salt/pillar/default.sls b/test/salt/pillar/default.sls new file mode 100644 index 00000000..2701fa13 --- /dev/null +++ b/test/salt/pillar/default.sls @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +apache: + manage_service_states: false + mod_security: + crs_install: true + manage_config: true + sec_rule_engine: 'On' + sec_request_body_access: 'On' + sec_request_body_limit: '14000000' + sec_request_body_no_files_limit: '114002' + sec_request_body_in_memory_limit: '114002' + sec_request_body_limit_action: 'Reject' + sec_pcre_match_limit: '15000' + sec_pcre_match_limit_recursion: '15000' + sec_debug_log_level: '3' diff --git a/test/shared/spec_helper.rb b/test/shared/spec_helper.rb deleted file mode 100644 index d62fc6df..00000000 --- a/test/shared/spec_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "serverspec" -require "pathname" - -# Set backend type -set :backend, :exec - -RSpec.configure do |c| - c.path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -end