diff --git a/.gitignore b/.gitignore index d3ec1ee..0bbb03c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,122 @@ -pkg/ -metadata.json -*.idea -*.swp -*.tmp -/.project -.kitchen/ +# 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/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..bdae9aa --- /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 0000000..3715677 --- /dev/null +++ b/.salt-lint @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +exclude_paths: [] +rules: {} +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 99ba953..efecce8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,106 @@ -stages: - - test - +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +## Machine config +dist: bionic sudo: required -cache: bundler -language: ruby - services: - docker -install: - - bundle install - -env: - matrix: - - INSTANCE: default-debian-9-2019-2-py3 - - INSTANCE: default-ubuntu-1804-2019-2-py3 - - INSTANCE: default-centos-7-2019-2-py2 +## 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$\|\.tst$' + | xargs 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 i -D @commitlint/config-conventional + @commitlint/travis-cli + - 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-master-py3 + - env: INSTANCE=default-ubuntu-1804-master-py3 + # - env: INSTANCE=default-centos-8-master-py3 + # - env: INSTANCE=default-fedora-31-master-py3 + # - env: INSTANCE=default-opensuse-leap-151-master-py3 + # - env: INSTANCE=default-amazonlinux-2-master-py2 + # - env: INSTANCE=default-arch-base-latest-master-py2 + # - env: INSTANCE=default-debian-10-2019-2-py3 + - env: INSTANCE=default-debian-9-2019-2-py3 + # - env: INSTANCE=default-ubuntu-1804-2019-2-py3 + # - env: INSTANCE=default-centos-8-2019-2-py3 + # - env: INSTANCE=default-fedora-31-2019-2-py3 + - env: INSTANCE=default-opensuse-leap-151-2019-2-py3 + # - env: INSTANCE=default-centos-7-2019-2-py2 + # - env: INSTANCE=default-amazonlinux-2-2019-2-py2 + # - env: INSTANCE=default-arch-base-latest-2019-2-py2 + # - env: INSTANCE=default-fedora-30-2018-3-py3 + # - 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-opensuse-leap-151-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-30-2017-7-py2 + # - env: INSTANCE=default-opensuse-leap-151-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 i -D @semantic-release/changelog@3 + @semantic-release/exec@3 + @semantic-release/git@7 + 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 0000000..740beca --- /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 new file mode 100644 index 0000000..a190ff7 --- /dev/null +++ b/FORMULA @@ -0,0 +1,9 @@ +name: firewalld +os: Debian, Ubuntu, Raspbian, RedHat, Fedora, CentOS, Suse, openSUSE, Gentoo, Funtoo, Arch, Manjaro, Alpine, FreeBSD, OpenBSD, Solaris, SmartOS, Windows, MacOS +os_family: Debian, RedHat, Suse, Gentoo, Arch, Alpine, FreeBSD, OpenBSD, Solaris, Windows, MacOS +version: 0.6.2 +release: 1 +minimum_version: 2017.7 +summary: firewalld formula +description: Set up and configure Firewalld, a dynamically managed firewall +top_level_dir: firewalld diff --git a/Gemfile b/Gemfile index e95eb27..5a232b6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,7 @@ -source "https://rubygems.org" +# frozen_string_literal: true -gem "kitchen-docker", ">= 2.9" -gem "kitchen-salt", ">= 0.6.0" -gem "kitchen-inspec", '>= 1.1' +source 'https://rubygems.org' + +gem 'kitchen-docker', '>= 2.9' +gem 'kitchen-inspec', '>= 1.1' +gem 'kitchen-salt', '>= 0.6.0' diff --git a/README.rst b/README.rst deleted file mode 100644 index 4a5e139..0000000 --- a/README.rst +++ /dev/null @@ -1,72 +0,0 @@ -================= -firewalld-formula -================= - -Salt Stack Formula to set up and configure Firewalld, dynamically managed firewall with support for network/firewall zones to define the trust level of network connections or interfaces - -.. image:: https://travis-ci.org/saltstack-formulas/firewalld-formula.svg?branch=master - -NOTICE BEFORE YOU USE -===================== - -* This formula aims to follow the conventions and recommendations described at http://docs.saltstack.com/topics/conventions/formulas.html - -TODO -==== - -* configure local pre-commit hooks (code syntax check based on file extension, check for ugly *utf-8 mac os white space*) - -Instructions -============ - -1. Add this repository as a `GitFS `_ backend in your Salt master config. - -2. Configure your Pillar top file (``/srv/pillar/top.sls``), see pillar.example - -3. Include this Formula within another Formula or simply define your needed states within the Salt top file (``/srv/salt/top.sls``). - -Available states -================ - -.. contents:: - :local: - -``firewalld`` -------------- -Manage firewalld - -Additional resources -==================== - -None - -Formula Dependencies -==================== - -None - -Contributions -============= - -Contributions are always welcome. All development guidelines you have to know are - -* write clean code (proper YAML+Jinja syntax, no trailing whitespaces, no empty lines with whitespaces, LF only) -* set sane default settings -* test your code -* update README.rst doc - -Salt Compatibility -================== - -Tested with: - -* 2018.3.x (will probably work too with 2017.x.x) - -OS Compatibility -================ - -Tested with: - -* CentOS 7 -* Debian 9 -* Ubuntu 18.04 diff --git a/bin/kitchen b/bin/kitchen new file mode 100755 index 0000000..dcfdb4c --- /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 0000000..2f9d1aa --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; diff --git a/docs/README.rst b/docs/README.rst new file mode 100644 index 0000000..c189eb9 --- /dev/null +++ b/docs/README.rst @@ -0,0 +1,153 @@ +.. _readme: + +firewalld-formula +================= + +|img_travis| |img_sr| + +.. |img_travis| image:: https://travis-ci.com/saltstack-formulas/firewalld-formula.svg?branch=master + :alt: Travis CI Build Status + :scale: 100% + :target: https://travis-ci.com/saltstack-formulas/firewalld-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 + +A SaltStack Formula to set up and configure Firewalld, a dynamically managed firewall with support for network/firewall zones to define the trust level of network connections or interfaces. + +.. 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 `Formula Versioning Section `_ for more details. + +If you need (non-default) configuration, please pay attention to the ``pillar.example`` file and/or `Special notes`_ section. + +Contributing to this repo +------------------------- + +**Commit message formatting is significant!!** + +Please see `How to contribute `_ for more details. + +Special notes +------------- + +None + +TODO +---- + +* configure local pre-commit hooks (code syntax check based on file extension, check for ugly *utf-8 mac os white space*) + +Instructions +------------ + +1. Add this repository as a `GitFS `_ backend in your Salt master config. + +2. Configure your Pillar top file (``/srv/pillar/top.sls``), see pillar.example + +3. Include this Formula within another Formula or simply define your needed states within the Salt top file (``/srv/salt/top.sls``). + +Additional resources +-------------------- + +None + +Formula Dependencies +-------------------- + +None + +Contributions +------------- + +Contributions are always welcome. All development guidelines you have to know are + +* write clean code (proper YAML+Jinja syntax, no trailing whitespaces, no empty lines with whitespaces, LF only) +* set sane default settings +* test your code +* update README.rst doc + +Salt Compatibility +------------------ + +Tested with: + +* 2018.3.x (will probably work too with 2017.x.x) + +OS Compatibility +---------------- + +Tested with: + +* CentOS 7 +* Debian 9 +* Ubuntu 18.04 + +Available states +---------------- + +.. contents:: + :local: + +``firewalld`` +^^^^^^^^^^^^^ + +Manage firewalld + +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 ``firewalld`` 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/firewalld/defaults.yaml b/firewalld/defaults.yaml index 1334058..bbabd6e 100644 --- a/firewalld/defaults.yaml +++ b/firewalld/defaults.yaml @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # vim: ft=yaml +--- firewalld: enabled: true package: firewalld diff --git a/firewalld/map.jinja b/firewalld/map.jinja index e510183..8a8a394 100644 --- a/firewalld/map.jinja +++ b/firewalld/map.jinja @@ -1,25 +1,25 @@ # -*- coding: utf-8 -*- # vim: ft=jinja -{## Start with defaults from defaults.yaml ##} +{#- Start with defaults from defaults.yaml #} {% import_yaml "firewalld/defaults.yaml" as default_settings %} -{## +{#- Setup variable using grains['os_family'] based logic, only add key:values here that differ from whats in defaults.yaml -##} +#} {% set os_family_map = salt['grains.filter_by']({ 'Debian': {}, 'RedHat': {}, 'Arch': {}, 'Suse': {}, - }, grain='os_family', merge=salt['pillar.get']('firewalld:lookup')) + }, grain='os_family', merge=salt['pillar.get']('firewalld:lookup')) %} -{## Merge the flavor_map to the default settings ##} +{#- Merge the flavor_map to the default settings #} {% do default_settings.firewalld.update(os_family_map) %} -{## Merge in salt:lookup pillar ##} +{#- Merge in salt:lookup pillar #} {% set firewalld = salt['pillar.get']( 'firewalld', default=default_settings.firewalld, diff --git a/kitchen.yml b/kitchen.yml index 62ec15f..8f51070 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -1,57 +1,194 @@ # -*- coding: utf-8 -*- # vim: ft=yaml --- +# For help on this file's format, see https://kitchen.ci/ driver: name: docker - -driver_config: use_sudo: false privileged: true run_command: /lib/systemd/systemd - pid_one_command: /usr/lib/systemd/systemd +# Make sure the platforms listed below match up with +# the `env.matrix` instances defined in `.travis.yml` platforms: - - name: centos-7-2019-2-py2 + ## SALT `master` + - name: debian-10-master-py3 driver: - image: netmanagers/salt-2019.2-py2:centos-7 - platform: rhel + image: netmanagers/salt-master-py3:debian-10 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git master + - name: ubuntu-1804-master-py3 + driver: + image: netmanagers/salt-master-py3:ubuntu-18.04 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git master + - name: centos-8-master-py3 + driver: + image: netmanagers/salt-master-py3:centos-8 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git master + - name: fedora-31-master-py3 + driver: + image: netmanagers/salt-master-py3:fedora-31 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git master + - name: opensuse-leap-151-master-py3 + driver: + image: netmanagers/salt-master-py3:opensuse-leap-15.1 + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python3 git master + run_command: /usr/lib/systemd/systemd + # Workaround to avoid intermittent failures on `opensuse-leap-15.1`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + # Use the `develop` image temporarily until the `master` image is available + # Not changing the name to minimise disruption across all of the formulas + - name: amazonlinux-2-master-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-master-py2 + driver: + image: netmanagers/salt-master-py2:arch-base-latest + provision_command: + - curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com + - sh bootstrap-salt.sh -XdPbfrq -x python2 git master + run_command: /usr/lib/systemd/systemd + + ## SALT `2019.2` + - name: debian-10-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:debian-10 - name: debian-9-2019-2-py3 driver: image: netmanagers/salt-2019.2-py3:debian-9 - platform: debian - name: ubuntu-1804-2019-2-py3 driver: image: netmanagers/salt-2019.2-py3:ubuntu-18.04 - platform: ubuntu + - name: centos-8-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:centos-8 + - name: fedora-31-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:fedora-31 + - name: opensuse-leap-151-2019-2-py3 + driver: + image: netmanagers/salt-2019.2-py3:opensuse-leap-15.1 + run_command: /usr/lib/systemd/systemd + # Workaround to avoid intermittent failures on `opensuse-leap-15.1`: + # => SCP did not finish successfully (255): (Net::SCP::Error) + transport: + max_ssh_sessions: 1 + - name: centos-7-2019-2-py2 + driver: + image: netmanagers/salt-2019.2-py2:centos-7 + - 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: fedora-30-2018-3-py3 + driver: + image: netmanagers/salt-2018.3-py3:fedora-30 + - 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: opensuse-leap-151-2018-3-py2 + driver: + image: netmanagers/salt-2018.3-py2:opensuse-leap-15.1 + run_command: /usr/lib/systemd/systemd + # Workaround to avoid intermittent failures on `opensuse-leap-15.1`: + # => 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-30-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:fedora-30 + - name: opensuse-leap-151-2017-7-py2 + driver: + image: netmanagers/salt-2017.7-py2:opensuse-leap-15.1 + run_command: /usr/lib/systemd/systemd + # Workaround to avoid intermittent failures on `opensuse-leap-15.1`: + # => 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: info - require_chef: false + log_level: debug salt_install: none + require_chef: false formula: firewalld salt_copy_filter: - .kitchen - .git - pillars_from_files: - firewalld.sls: pillar.example - pillars: - top.sls: - base: - '*': - - firewalld - state_top: - base: - '*': - - firewalld verifier: + # https://www.inspec.io/ name: inspec sudo: true + # cli, documentation, html, progress, json, json-min, json-rspec, junit reporter: - cli - inspec_tests: - - path: test/integration/default suites: - name: default + provisioner: + state_top: + base: + '*': + - firewalld + pillars: + top.sls: + base: + '*': + - firewalld + pillars_from_files: + firewalld.sls: pillar.example + verifier: + inspec_tests: + - path: test/integration/default diff --git a/pillar.example b/pillar.example index 0969b97..6d78533 100644 --- a/pillar.example +++ b/pillar.example @@ -1,6 +1,9 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- # FirewallD pillar examples: firewalld: - enabled: True + enabled: true IndividualCalls: 'no' LogDenied: 'off' AutomaticHelpers: 'system' @@ -9,25 +12,30 @@ firewalld: RFC3964_IPv4: 'yes' ipset: - manage: True + manage: true pkg: ipset - # ipset: # Deprecated. Support for this format will be removed in future releases - # ipsetpackag: ipset # Deprecated. Will be removed in future releases + # ipset: # Deprecated. Will be removed in future releases + # ipsetpackag: ipset # Deprecated. Will be removed in future releases backend: - manage: True + manage: true pkg: nftables - # installbackend: True # Deprecated. Will be removed in future releases - # backendpackage: nftables # Deprecated. Will be removed in future releases + # installbackend: true # Deprecated. Will be removed in future releases + # backendpackage: nftables # Deprecated. Will be removed in future releases default_zone: public services: sshcustom: short: sshcustom - description: SSH on port 3232 and 5252. Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful. + description: >- + SSH on port 3232 and 5252. Secure Shell (SSH) is a protocol for logging + into and executing commands on remote machines. It provides secure + encrypted communications. If you plan on accessing your machine + remotely via SSH over a firewalled interface, enable this option. You + need the openssh-server package installed for this option to be useful. ports: tcp: - 3232 @@ -93,7 +101,10 @@ firewalld: zones: public: short: Public - description: "For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted." + description: >- + For use in public areas. You do not trust the other computers on + networks to not harm your computer. Only selected incoming connections + are accepted. services: - http - zabbixcustom @@ -105,7 +116,7 @@ firewalld: rich_rules: - family: ipv4 source: - address: 8.8.8.8/24 + address: 8.8.8.8/24 accept: true - family: ipv4 ipset: @@ -113,14 +124,14 @@ firewalld: reject: type: icmp-port-unreachable ports: -{% if grains['id'] == 'salt.example.com' %} + # {%- if grains['id'] == 'salt.example.com' %} - comment: salt-master port: 4505 protocol: tcp - comment: salt-python port: 4506 protocol: tcp -{% endif %} + # {%- endif %} - comment: zabbix-agent port: 10050 protocol: tcp @@ -149,8 +160,17 @@ firewalld: table: filter chain: FORWARD priority: "0" - args: "-i iintern -o iextern -s 192.168.1.0/24 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT" + args: >- + -i iintern + -o iextern + -s 192.168.1.0/24 + -m conntrack + --ctstate NEW,RELATED,ESTABLISHED + -j ACCEPT passthrough: MYPASSTHROUGH: ipv: ipv4 - args: "-t raw -A MYCHAIN -j DROP" + args: >- + -t raw + -A MYCHAIN + -j DROP diff --git a/pre-commit_semantic-release.sh b/pre-commit_semantic-release.sh new file mode 100755 index 0000000..9d34d74 --- /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 0000000..c63c850 --- /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 0000000..6af7aa8 --- /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.shortHash = 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 0000000..37cf963 --- /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/backend_spec.rb b/test/integration/default/controls/backend_spec.rb similarity index 67% rename from test/integration/default/backend_spec.rb rename to test/integration/default/controls/backend_spec.rb index f27673a..0c8e4d9 100644 --- a/test/integration/default/backend_spec.rb +++ b/test/integration/default/controls/backend_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe package('nftables') do it { should be_installed } end diff --git a/test/integration/default/firewalld_spec.rb b/test/integration/default/controls/firewalld_spec.rb similarity index 92% rename from test/integration/default/firewalld_spec.rb rename to test/integration/default/controls/firewalld_spec.rb index ef81e55..99b9861 100644 --- a/test/integration/default/firewalld_spec.rb +++ b/test/integration/default/controls/firewalld_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe package('firewalld') do it { should be_installed } end diff --git a/test/integration/default/ipset_spec.rb b/test/integration/default/controls/ipset_spec.rb similarity index 66% rename from test/integration/default/ipset_spec.rb rename to test/integration/default/controls/ipset_spec.rb index 3a45f32..7ee5022 100644 --- a/test/integration/default/ipset_spec.rb +++ b/test/integration/default/controls/ipset_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe package('ipset') do it { should be_installed } end diff --git a/test/integration/default/inspec.yml b/test/integration/default/inspec.yml new file mode 100644 index 0000000..70dafa1 --- /dev/null +++ b/test/integration/default/inspec.yml @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +name: default +title: firewalld formula +maintainer: SaltStack Formulas +license: Apache-2.0 +summary: Verify that the firewalld 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