diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..d77700e3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# editorconfig.org + +# MANAGED BY MODULESYNC + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +tab_width = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..f1f88ccf --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,282 @@ +# Contribution guidelines + +## Table of contents + +* [Contributing](#contributing) +* [Writing proper commits - short version](#writing-proper-commits-short-version) +* [Writing proper commits - long version](#writing-proper-commits-long-version) +* [Dependencies](#dependencies) + * [Note for OS X users](#note-for-os-x-users) +* [The test matrix](#the-test-matrix) +* [Syntax and style](#syntax-and-style) +* [Running the unit tests](#running-the-unit-tests) +* [Unit tests in docker](#unit-tests-in-docker) +* [Integration tests](#integration-tests) + +This module has grown over time based on a range of contributions from +people using it. If you follow these contributing guidelines your patch +will likely make it into a release a little more quickly. + +## Contributing + +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. +[Contributor Code of Conduct](https://voxpupuli.org/coc/). + +* Fork the repo. +* Create a separate branch for your change. +* We only take pull requests with passing tests, and documentation. [travis-ci](http://travis-ci.org) runs the tests for us. You can also execute them locally. This is explained [in a later section](#the-test-matrix). +* Checkout [our docs](https://voxpupuli.org/docs/reviewing_pr/) we use to review a module and the [official styleguide](https://puppet.com/docs/puppet/6.0/style_guide.html). They provide some guidance for new code that might help you before you submit a pull request. +* Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, please add a test. +* Squash your commits down into logical components. Make sure to rebase against our current master. +* Push the branch to your fork and submit a pull request. + +Please be prepared to repeat some of these steps as our contributors review your code. + +Also consider sending in your profile code that calls this component module as an acceptance test or provide it via an issue. This helps reviewers a lot to test your use case and prevents future regressions! + +## Writing proper commits - short version + +* Make commits of logical units. +* Check for unnecessary whitespace with "git diff --check" before committing. +* Commit using Unix line endings (check the settings around "crlf" in git-config(1)). +* Do not check in commented out code or unneeded files. +* The first line of the commit message should be a short description (50 characters is the soft limit, excluding ticket number(s)), and should skip the full stop. +* Associate the issue in the message. The first line should include the issue number in the form "(#XXXX) Rest of message". +* The body should provide a meaningful commit message, which: + *uses the imperative, present tense: `change`, not `changed` or `changes`. + * includes motivation for the change, and contrasts its implementation with the previous behavior. + * Make sure that you have tests for the bug you are fixing, or feature you are adding. + * Make sure the test suites passes after your commit: + * When introducing a new feature, make sure it is properly documented in the README.md + +## Writing proper commits - long version + + 1. Make separate commits for logically separate changes. + + Please break your commits down into logically consistent units + which include new or changed tests relevant to the rest of the + change. The goal of doing this is to make the diff easier to + read for whoever is reviewing your code. In general, the easier + your diff is to read, the more likely someone will be happy to + review it and get it into the code base. + + If you are going to refactor a piece of code, please do so as a + separate commit from your feature or bug fix changes. + + We also really appreciate changes that include tests to make + sure the bug is not re-introduced, and that the feature is not + accidentally broken. + + Describe the technical detail of the change(s). If your + description starts to get too long, that is a good sign that you + probably need to split up your commit into more finely grained + pieces. + + Commits which plainly describe the things which help + reviewers check the patch and future developers understand the + code are much more likely to be merged in with a minimum of + bike-shedding or requested changes. Ideally, the commit message + would include information, and be in a form suitable for + inclusion in the release notes for the version of Puppet that + includes them. + + Please also check that you are not introducing any trailing + whitespace or other "whitespace errors". You can do this by + running "git diff --check" on your changes before you commit. + + 2. Sending your patches + + To submit your changes via a GitHub pull request, we _highly_ + recommend that you have them on a topic branch, instead of + directly on `master`. + It makes things much easier to keep track of, especially if + you decide to work on another thing before your first change + is merged in. + + GitHub has some pretty good + [general documentation](http://help.github.com/) on using + their site. They also have documentation on + [creating pull requests](http://help.github.com/send-pull-requests/). + + In general, after pushing your topic branch up to your + repository on GitHub, you can switch to the branch in the + GitHub UI and click "Pull Request" towards the top of the page + in order to open a pull request. + + + 3. Update the related GitHub issue. + + If there is a GitHub issue associated with the change you + submitted, then you should update the ticket to include the + location of your branch, along with any other commentary you + may wish to make. + +## Dependencies + +The testing and development tools have a bunch of dependencies, +all managed by [bundler](http://bundler.io/) according to the +[Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). + +By default the tests use a baseline version of Puppet. + +If you have Ruby 2.x or want a specific version of Puppet, +you must set an environment variable such as: + +```sh +export PUPPET_VERSION="~> 5.5.6" +``` + +You can install all needed gems for spec tests into the modules directory by +running: + +```sh +bundle install --path .vendor/ --without development system_tests release --jobs "$(nproc)" +``` + +If you also want to run acceptance tests: + +```sh +bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)" +``` + +Our all in one solution if you don't know if you need to install or update gems: + +```sh +bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)"; bundle update; bundle clean +``` + +As an alternative to the `--jobs "$(nproc)` parameter, you can set an +environment variable: + +```sh +BUNDLE_JOBS="$(nproc)" +``` + +### Note for OS X users + +`nproc` isn't a valid command under OS x. As an alternative, you can do: + +```sh +--jobs "$(sysctl -n hw.ncpu)" +``` + +## The test matrix + +### Syntax and style + +The test suite will run [Puppet Lint](http://puppet-lint.com/) and +[Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to +check various syntax and style things. You can run these locally with: + +```sh +bundle exec rake lint +bundle exec rake validate +``` + +It will also run some [Rubocop](http://batsov.com/rubocop/) tests +against it. You can run those locally ahead of time with: + +```sh +bundle exec rake rubocop +``` + +### Running the unit tests + +The unit test suite covers most of the code, as mentioned above please +add tests if you're adding new functionality. If you've not used +[rspec-puppet](http://rspec-puppet.com/) before then feel free to ask +about how best to test your new feature. + +To run the linter, the syntax checker and the unit tests: + +```sh +bundle exec rake test +``` + +To run your all the unit tests + +```sh +bundle exec rake spec +``` + +To run a specific spec test set the `SPEC` variable: + +```sh +bundle exec rake spec SPEC=spec/foo_spec.rb +``` + +#### Unit tests in docker + +Some people don't want to run the dependencies locally or don't want to install +ruby. We ship a Dockerfile that enables you to run all unit tests and linting. +You only need to run: + +```sh +docker build . +``` + +Please ensure that a docker daemon is running and that your user has the +permission to talk to it. You can specify a remote docker host by setting the +`DOCKER_HOST` environment variable. it will copy the content of the module into +the docker image. So it will not work if a Gemfile.lock exists. + +### Integration tests + +The unit tests just check the code runs, not that it does exactly what +we want on a real machine. For that we're using +[beaker](https://github.com/puppetlabs/beaker). + +This fires up a new virtual machine (using vagrant) and runs a series of +simple tests against it after applying the module. You can run this +with: + +```sh +bundle exec rake beaker +``` + +This will run the tests on the module's default nodeset. You can override the +nodeset used, e.g., + +```sh +BEAKER_set=centos-7-x64 bundle exec rake beaker +``` + +There are default rake tasks for the various acceptance test modules, e.g., + +```sh +bundle exec rake beaker:centos-7-x64 +bundle exec rake beaker:ssh:centos-7-x64 +``` + +If you don't want to have to recreate the virtual machine every time you can +use `BEAKER_destroy=no` and `BEAKER_provision=no`. On the first run you will at +least need `BEAKER_provision` set to yes (the default). The Vagrantfile for the +created virtual machines will be in `.vagrant/beaker_vagrant_files`. + +Beaker also supports docker containers. We also use that in our automated CI +pipeline at [travis-ci](http://travis-ci.org). To use that instead of Vagrant: + +```sh +PUPPET_INSTALL_TYPE=agent BEAKER_IS_PE=no BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian10-64{hypervisor=docker} BEAKER_destroy=yes bundle exec rake beaker +``` + +You can replace the string `debian10` with any common operating system. +The following strings are known to work: + +* ubuntu1604 +* ubuntu1804 +* ubuntu2004 +* debian9 +* debian10 +* centos7 +* centos8 + +The easiest way to debug in a docker container is to open a shell: + +```sh +docker exec -it -u root ${container_id_or_name} bash +``` + +The source of this file is in our [modulesync_config](https://github.com/voxpupuli/modulesync_config/blob/master/moduleroot/.github/CONTRIBUTING.md.erb) +repository. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..593e7aa8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,26 @@ + + +## Affected Puppet, Ruby, OS and module versions/distributions + +- Puppet: +- Ruby: +- Distribution: +- Module version: + +## How to reproduce (e.g Puppet code you use) + +## What are you seeing + +## What behaviour did you expect instead + +## Output log + +## Any additional information you'd like to impart diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..342807bc --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,20 @@ + +#### Pull Request (PR) description + + +#### This Pull Request (PR) fixes the following issues + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..cacadf22 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,3 @@ +# Vox Pupuli Security Policy + +Our vulnerabilities reporting process is at https://voxpupuli.org/security/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..ea492ae0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: pull_request + +jobs: + setup_matrix: + name: 'Setup Test Matrix' + runs-on: ubuntu-latest + outputs: + beaker_setfiles: ${{ steps.get-outputs.outputs.beaker_setfiles }} + puppet_major_versions: ${{ steps.get-outputs.outputs.puppet_major_versions }} + puppet_unit_test_matrix: ${{ steps.get-outputs.outputs.puppet_unit_test_matrix }} + env: + BUNDLE_WITHOUT: development:test:release + steps: + - uses: actions/checkout@v2 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Run rake validate + run: bundle exec rake validate + - name: Setup Test Matrix + id: get-outputs + run: bundle exec metadata2gha --use-fqdn --pidfile-workaround false + + unit: + needs: setup_matrix + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: ${{fromJson(needs.setup_matrix.outputs.puppet_unit_test_matrix)}} + env: + BUNDLE_WITHOUT: development:system_tests:release + PUPPET_VERSION: "~> ${{ matrix.puppet }}.0" + name: Puppet ${{ matrix.puppet }} (Ruby ${{ matrix.ruby }}) + steps: + - uses: actions/checkout@v2 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run tests + run: bundle exec rake diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..68b85284 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + tags: + - '*' + +env: + BUNDLE_WITHOUT: development:test:system_tests + +jobs: + deploy: + name: 'deploy to forge' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Build and Deploy + env: + # Configure secrets here: + # https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets + BLACKSMITH_FORGE_USERNAME: '${{ secrets.PUPPET_FORGE_USERNAME }}' + BLACKSMITH_FORGE_API_KEY: '${{ secrets.PUPPET_FORGE_API_KEY }}' + run: bundle exec rake module:push diff --git a/.gitignore b/.gitignore index 43053181..e9b3cf4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,20 @@ -.git/ -.*.sw[op] -.metadata -.yardoc -.yardwarns -*.iml -/.bundle/ -/.idea/ -/.vagrant/ -/coverage/ -/bin/ -/doc/ -/Gemfile.local -/Gemfile.lock -/junit/ -/log/ -/pkg/ -/spec/fixtures/manifests/ -/spec/fixtures/modules/ -/tmp/ -/vendor/ -/convert_report.txt -/update_report.txt -.DS_Store -.project -.envrc -/inventory.yaml +pkg/ +Gemfile.lock +Gemfile.local +vendor/ +.vendor/ +spec/fixtures/manifests/ +spec/fixtures/modules/ +.vagrant/ +.bundle/ .ruby-version +coverage/ +log/ +.idea/ +.dependencies/ +.librarian/ +Puppetfile.lock +*.iml +.*.sw? +.yardoc/ +Guardfile diff --git a/.msync.yml b/.msync.yml new file mode 100644 index 00000000..a0770a83 --- /dev/null +++ b/.msync.yml @@ -0,0 +1,2 @@ +--- +modulesync_config_version: '4.0.0' diff --git a/.overcommit.yml b/.overcommit.yml new file mode 100644 index 00000000..0af0fdc0 --- /dev/null +++ b/.overcommit.yml @@ -0,0 +1,64 @@ +# Managed by https://github.com/voxpupuli/modulesync_configs +# +# Hooks are only enabled if you take action. +# +# To enable the hooks run: +# +# ``` +# bundle exec overcommit --install +# # ensure .overcommit.yml does not harm to you and then +# bundle exec overcommit --sign +# ``` +# +# (it will manage the .git/hooks directory): +# +# Examples howto skip a test for a commit or push: +# +# ``` +# SKIP=RuboCop git commit +# SKIP=PuppetLint git commit +# SKIP=RakeTask git push +# ``` +# +# Don't invoke overcommit at all: +# +# ``` +# OVERCOMMIT_DISABLE=1 git commit +# ``` +# +# Read more about overcommit: https://github.com/brigade/overcommit +# +# To manage this config yourself in your module add +# +# ``` +# .overcommit.yml: +# unmanaged: true +# ``` +# +# to your modules .sync.yml config +--- +PreCommit: + RuboCop: + enabled: true + description: 'Runs rubocop on modified files only' + command: ['bundle', 'exec', 'rubocop'] + PuppetLint: + enabled: true + description: 'Runs puppet-lint on modified files only' + command: ['bundle', 'exec', 'puppet-lint'] + YamlSyntax: + enabled: true + JsonSyntax: + enabled: true + TrailingWhitespace: + enabled: true + +PrePush: + RakeTarget: + enabled: true + description: 'Run rake targets' + targets: + - 'validate' + - 'test' + - 'rubocop' + command: ['bundle', 'exec', 'rake'] diff --git a/.pmtignore b/.pmtignore new file mode 100644 index 00000000..33a8c65d --- /dev/null +++ b/.pmtignore @@ -0,0 +1,34 @@ +docs/ +pkg/ +Gemfile +Gemfile.lock +Gemfile.local +vendor/ +.vendor/ +spec/ +Rakefile +.vagrant/ +.bundle/ +.ruby-version +coverage/ +log/ +.idea/ +.dependencies/ +.github/ +.librarian/ +Puppetfile.lock +*.iml +.editorconfig +.fixtures.yml +.gitignore +.msync.yml +.overcommit.yml +.pmtignore +.rspec +.rspec_parallel +.rubocop.yml +.sync.yml +.*.sw? +.yardoc/ +.yardopts +Dockerfile diff --git a/.rspec b/.rspec index 16f9cdb0..8c18f1ab 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ ---color --format documentation +--color diff --git a/.rspec_parallel b/.rspec_parallel new file mode 100644 index 00000000..e4d136b7 --- /dev/null +++ b/.rspec_parallel @@ -0,0 +1 @@ +--format progress diff --git a/.rubocop.yml b/.rubocop.yml index 5307849e..198a3599 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,137 +1,3 @@ --- -require: -- rubocop-rspec -- rubocop-i18n -AllCops: - DisplayCopNames: true - TargetRubyVersion: '2.1' - Include: - - "./**/*.rb" - Exclude: - - bin/* - - ".vendor/**/*" - - "**/Gemfile" - - "**/Rakefile" - - pkg/**/* - - spec/fixtures/**/* - - vendor/**/* - - "**/Puppetfile" - - "**/Vagrantfile" - - "**/Guardfile" -Metrics/LineLength: - Description: People have wide screens, use them. - Max: 200 -GetText: - Enabled: false -GetText/DecorateString: - Description: We don't want to decorate test output. - Exclude: - - spec/**/* - Enabled: false -RSpec/BeforeAfterAll: - Description: Beware of using after(:all) as it may cause state to leak between tests. - A necessary evil in acceptance testing. - Exclude: - - spec/acceptance/**/*.rb -RSpec/HookArgument: - Description: Prefer explicit :each argument, matching existing module's style - EnforcedStyle: each -Style/BlockDelimiters: - Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to - be consistent then. - EnforcedStyle: braces_for_chaining -Style/BracesAroundHashParameters: - Description: Braces are required by Ruby 2.7. Cop removed from RuboCop v0.80.0. - See https://github.com/rubocop-hq/rubocop/pull/7643 - Enabled: true -Style/ClassAndModuleChildren: - Description: Compact style reduces the required amount of indentation. - EnforcedStyle: compact -Style/EmptyElse: - Description: Enforce against empty else clauses, but allow `nil` for clarity. - EnforcedStyle: empty -Style/FormatString: - Description: Following the main puppet project's style, prefer the % format format. - EnforcedStyle: percent -Style/FormatStringToken: - Description: Following the main puppet project's style, prefer the simpler template - tokens over annotated ones. - EnforcedStyle: template -Style/Lambda: - Description: Prefer the keyword for easier discoverability. - EnforcedStyle: literal -Style/RegexpLiteral: - Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 - EnforcedStyle: percent_r -Style/TernaryParentheses: - Description: Checks for use of parentheses around ternary conditions. Enforce parentheses - on complex expressions for better readability, but seriously consider breaking - it up. - EnforcedStyle: require_parentheses_when_complex -Style/TrailingCommaInArguments: - Description: Prefer always trailing comma on multiline argument lists. This makes - diffs, and re-ordering nicer. - EnforcedStyleForMultiline: comma -Style/TrailingCommaInLiteral: - Description: Prefer always trailing comma on multiline literals. This makes diffs, - and re-ordering nicer. - EnforcedStyleForMultiline: comma -Style/SymbolArray: - Description: Using percent style obscures symbolic intent of array's contents. - EnforcedStyle: brackets -RSpec/MessageSpies: - EnforcedStyle: receive -Style/Documentation: - Exclude: - - lib/puppet/parser/functions/**/* - - spec/**/* -Style/WordArray: - EnforcedStyle: brackets -Style/CollectionMethods: - Enabled: true -Style/MethodCalledOnDoEndBlock: - Enabled: true -Style/StringMethods: - Enabled: true -GetText/DecorateFunctionMessage: - Enabled: false -GetText/DecorateStringFormattingUsingInterpolation: - Enabled: false -GetText/DecorateStringFormattingUsingPercent: - Enabled: false -Layout/EndOfLine: - Enabled: false -Layout/IndentHeredoc: - Enabled: false -Metrics/AbcSize: - Enabled: false -Metrics/BlockLength: - Enabled: false -Metrics/ClassLength: - Enabled: false -Metrics/CyclomaticComplexity: - Enabled: false -Metrics/MethodLength: - Enabled: false -Metrics/ModuleLength: - Enabled: false -Metrics/ParameterLists: - Enabled: false -Metrics/PerceivedComplexity: - Enabled: false -RSpec/DescribeClass: - Enabled: false -RSpec/ExampleLength: - Enabled: false -RSpec/MessageExpectation: - Enabled: false -RSpec/MultipleExpectations: - Enabled: false -RSpec/NestedGroups: - Enabled: false -Style/AsciiComments: - Enabled: false -Style/IfUnlessModifier: - Enabled: false -Style/SymbolProc: - Enabled: false +inherit_gem: + voxpupuli-test: rubocop.yml diff --git a/.sync.yml b/.sync.yml index cc837e26..58037a1a 100644 --- a/.sync.yml +++ b/.sync.yml @@ -1,24 +1,3 @@ --- -.gitignore: - paths: - - .ruby-version - -.gitlab-ci.yml: - override: true - custom: - cache: - paths: - - 'vendor/bundle' - bundler_args: '--without system_tests --path vendor/bundle --jobs $(nproc)' - custom_stages: - - syntax - - unit - ruby_versions: - '2.5': - image: 'registry.code.immerda.ch/immerda/container-images/ruby/devel' - checks: - - 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop' - - 'parallel_spec' - puppet_version: '~> 6' - tags: - - 'container' +spec/spec_helper.rb: + mock_with: ':mocha' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 68d3e967..00000000 --- a/.travis.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -os: linux -dist: xenial -language: ruby -cache: bundler -before_install: - - bundle -v - - rm -f Gemfile.lock - - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner" - - "# See https://github.com/puppetlabs/pdk-templates/commit/705154d5c437796b821691b707156e1b056d244f for an example of how this was used" - - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set" - - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION' - - gem --version - - bundle -v -script: - - 'bundle exec rake $CHECK' -bundler_args: --without system_tests -rvm: - - 2.5.7 -stages: - - static - - spec - - acceptance - - - if: tag =~ ^v\d - name: deploy -jobs: - fast_finish: true - include: - - - env: CHECK="check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop syntax lint metadata_lint" - stage: static - - - env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec - rvm: 2.4.5 - stage: spec - - - env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec - rvm: 2.5.7 - stage: spec - - - env: DEPLOY_TO_FORGE=yes - stage: deploy -branches: - only: - - master - - /^v\d/ -notifications: - email: false diff --git a/.yardopts b/.yardopts index 29c933bc..3687f518 100644 --- a/.yardopts +++ b/.yardopts @@ -1 +1,2 @@ --markup markdown +--output-dir docs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..6fd63422 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM ruby:2.5.3 + +WORKDIR /opt/puppet + +# https://github.com/puppetlabs/puppet/blob/06ad255754a38f22fb3a22c7c4f1e2ce453d01cb/lib/puppet/provider/service/runit.rb#L39 +RUN mkdir -p /etc/sv + +ARG PUPPET_VERSION="~> 6.0" +ARG PARALLEL_TEST_PROCESSORS=4 + +# Cache gems +COPY Gemfile . +RUN bundle install --without system_tests development release --path=${BUNDLE_PATH:-vendor/bundle} + +COPY . . + +RUN bundle install +RUN bundle exec rake release_checks + +# Container should not saved +RUN exit 1 diff --git a/Gemfile b/Gemfile index 8007ad0a..0d0a9fb2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,72 +1,33 @@ -source ENV['GEM_SOURCE'] || 'https://rubygems.org' +source ENV['GEM_SOURCE'] || "https://rubygems.org" -def location_for(place_or_version, fake_version = nil) - git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} - file_url_regex = %r{\Afile:\/\/(?.*)} - - if place_or_version && (git_url = place_or_version.match(git_url_regex)) - [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact - elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) - ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] - else - [place_or_version, { require: false }] - end +group :test do + gem 'voxpupuli-test', '~> 2.1', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false end -ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments -minor_version = ruby_version_segments[0..1].join('.') - group :development do - gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') - gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') - gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') - gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9') - gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "puppet-module-posix-default-r#{minor_version}", '~> 0.4', require: false, platforms: [:ruby] - gem "puppet-module-posix-dev-r#{minor_version}", '~> 0.4', require: false, platforms: [:ruby] - gem "puppet-module-win-default-r#{minor_version}", '~> 0.4', require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "puppet-module-win-dev-r#{minor_version}", '~> 0.4', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem 'guard-rake', :require => false + gem 'overcommit', '>= 0.39.1', :require => false end -puppet_version = ENV['PUPPET_GEM_VERSION'] -facter_version = ENV['FACTER_GEM_VERSION'] -hiera_version = ENV['HIERA_GEM_VERSION'] - -gems = {} - -gems['puppet'] = location_for(puppet_version) - -# If facter or hiera versions have been specified via the environment -# variables - -gems['facter'] = location_for(facter_version) if facter_version -gems['hiera'] = location_for(hiera_version) if hiera_version - -if Gem.win_platform? && puppet_version =~ %r{^(file:///|git://)} - # If we're using a Puppet gem on Windows which handles its own win32-xxx gem - # dependencies (>= 3.5.0), set the maximum versions (see PUP-6445). - gems['win32-dir'] = ['<= 0.4.9', require: false] - gems['win32-eventlog'] = ['<= 0.6.5', require: false] - gems['win32-process'] = ['<= 0.7.5', require: false] - gems['win32-security'] = ['<= 0.2.5', require: false] - gems['win32-service'] = ['0.8.8', require: false] +group :system_tests do + gem 'puppet_metadata', '~> 0.3.0', :require => false + gem 'voxpupuli-acceptance', :require => false end -gems.each do |gem_name, gem_params| - gem gem_name, *gem_params +group :release do + gem 'github_changelog_generator', :require => false, :git => 'https://github.com/voxpupuli/github-changelog-generator', :branch => 'voxpupuli_essential_fixes' + gem 'puppet-blacksmith', :require => false + gem 'voxpupuli-release', :require => false + gem 'puppet-strings', '>= 2.2', :require => false end -# Evaluate Gemfile.local and ~/.gemfile if they exist -extra_gemfiles = [ - "#{__FILE__}.local", - File.join(Dir.home, '.gemfile'), -] +gem 'puppetlabs_spec_helper', '~> 2.0', :require => false +gem 'rake', :require => false +gem 'facter', ENV['FACTER_GEM_VERSION'], :require => false, :groups => [:test] + +puppetversion = ENV['PUPPET_VERSION'] || '~> 6.0' +gem 'puppet', puppetversion, :require => false, :groups => [:test] -extra_gemfiles.each do |gemfile| - if File.file?(gemfile) && File.readable?(gemfile) - eval(File.read(gemfile), binding) - end -end # vim: syntax=ruby diff --git a/Rakefile b/Rakefile index 0a5093b3..d1bf7491 100644 --- a/Rakefile +++ b/Rakefile @@ -1,87 +1,61 @@ -# frozen_string_literal: true - -require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any? -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-syntax/tasks/puppet-syntax' -require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? -require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any? -require 'puppet-strings/tasks' if Bundler.rubygems.find_name('puppet-strings').any? - -def changelog_user - return unless Rake.application.top_level_tasks.include? "changelog" - returnVal = nil || JSON.load(File.read('metadata.json'))['author'] - raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil? - puts "GitHubChangelogGenerator user:#{returnVal}" - returnVal +# Attempt to load voxupuli-test (which pulls in puppetlabs_spec_helper), +# otherwise attempt to load it directly. +begin + require 'voxpupuli/test/rake' +rescue LoadError + require 'puppetlabs_spec_helper/rake_tasks' end -def changelog_project - return unless Rake.application.top_level_tasks.include? "changelog" - - returnVal = nil - returnVal ||= begin - metadata_source = JSON.load(File.read('metadata.json'))['source'] - metadata_source_match = metadata_source && metadata_source.match(%r{.*\/([^\/]*?)(?:\.git)?\Z}) +# load optional tasks for releases +# only available if gem group releases is installed +begin + require 'voxpupuli/release/rake_tasks' +rescue LoadError +end - metadata_source_match && metadata_source_match[1] +desc "Run main 'test' task and report merged results to coveralls" +task test_with_coveralls: [:test] do + if Dir.exist?(File.expand_path('../lib', __FILE__)) + require 'coveralls/rake/task' + Coveralls::RakeTask.new + Rake::Task['coveralls:push'].invoke + else + puts 'Skipping reporting to coveralls. Module has no lib dir' end - - raise "unable to find the changelog_project in .sync.yml or calculate it from the source in metadata.json" if returnVal.nil? - - puts "GitHubChangelogGenerator project:#{returnVal}" - returnVal end -def changelog_future_release - return unless Rake.application.top_level_tasks.include? "changelog" - returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version'] - raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? - puts "GitHubChangelogGenerator future_release:#{returnVal}" - returnVal +desc 'Generate REFERENCE.md' +task :reference, [:debug, :backtrace] do |t, args| + patterns = '' + Rake::Task['strings:generate:reference'].invoke(patterns, args[:debug], args[:backtrace]) end -PuppetLint.configuration.send('disable_relative') - -if Bundler.rubygems.find_name('github_changelog_generator').any? +begin + require 'github_changelog_generator/task' + require 'puppet_blacksmith' GitHubChangelogGenerator::RakeTask.new :changelog do |config| - raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil? - config.user = "#{changelog_user}" - config.project = "#{changelog_project}" - config.future_release = "#{changelog_future_release}" - config.exclude_labels = ['maintenance'] - config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)." - config.add_pr_wo_labels = true - config.issues = false - config.merge_prefix = "### UNCATEGORIZED PRS; LABEL THEM ON GITHUB" - config.configure_sections = { - "Changed" => { - "prefix" => "### Changed", - "labels" => ["backwards-incompatible"], - }, - "Added" => { - "prefix" => "### Added", - "labels" => ["enhancement", "feature"], - }, - "Fixed" => { - "prefix" => "### Fixed", - "labels" => ["bug", "documentation", "bugfix"], - }, - } + version = (Blacksmith::Modulefile.new).version + config.future_release = "v#{version}" if version =~ /^\d+\.\d+.\d+$/ + config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file.\nEach new release typically also includes the latest modulesync defaults.\nThese should not affect the functionality of the module." + config.exclude_labels = %w{duplicate question invalid wontfix wont-fix modulesync skip-changelog} + config.user = 'voxpupuli' + metadata_json = File.join(File.dirname(__FILE__), 'metadata.json') + metadata = JSON.load(File.read(metadata_json)) + config.project = metadata['name'] end -else - desc 'Generate a Changelog from GitHub' - task :changelog do - raise < 1.15' - condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0')" -EOM + + # Workaround for https://github.com/github-changelog-generator/github-changelog-generator/issues/715 + require 'rbconfig' + if RbConfig::CONFIG['host_os'] =~ /linux/ + task :changelog do + puts 'Fixing line endings...' + changelog_file = File.join(__dir__, 'CHANGELOG.md') + changelog_txt = File.read(changelog_file) + new_contents = changelog_txt.gsub(%r{\r\n}, "\n") + File.open(changelog_file, "w") {|file| file.puts new_contents } + end end -end +rescue LoadError +end +# vim: syntax=ruby diff --git a/manifests/bridges.pp b/manifests/bridges.pp index 01ed75e8..cb7f7cb9 100644 --- a/manifests/bridges.pp +++ b/manifests/bridges.pp @@ -1,9 +1,7 @@ # allow forwarding traffic on bridges -class nftables::bridges( - Enum['present','absent'] - $ensure = 'present', - Regexp - $bridgenames = /^br.+/ +class nftables::bridges ( + Enum['present','absent'] $ensure = 'present', + Regexp $bridgenames = /^br.+/ ) { if $ensure == 'present' { $interfaces = keys($facts['networking']['interfaces']) diff --git a/manifests/chain.pp b/manifests/chain.pp index 29bfbfe1..9f633482 100644 --- a/manifests/chain.pp +++ b/manifests/chain.pp @@ -1,19 +1,14 @@ # manage a chain -define nftables::chain( - Pattern[/^(ip|ip6|inet)-[a-zA-Z0-9_]+$/] - $table = 'inet-filter', - Pattern[/^[a-zA-Z0-9_]+$/] - $chain = $title, - Optional[Pattern[/^\d\d-[a-zA-Z0-9_]+$/]] - $inject = undef, - Optional[String] - $inject_iif = undef, - Optional[String] - $inject_oif = undef, -){ +define nftables::chain ( + Pattern[/^(ip|ip6|inet)-[a-zA-Z0-9_]+$/] $table = 'inet-filter', + Pattern[/^[a-zA-Z0-9_]+$/] $chain = $title, + Optional[Pattern[/^\d\d-[a-zA-Z0-9_]+$/]] $inject = undef, + Optional[String] $inject_iif = undef, + Optional[String] $inject_oif = undef, +) { $concat_name = "nftables-${table}-chain-${chain}" - concat{ + concat { $concat_name: path => "/etc/nftables/puppet-preflight/${table}-chain-${chain}.nft", owner => root, @@ -21,16 +16,16 @@ mode => '0640', ensure_newline => true, require => Package['nftables'], - } ~> Exec['nft validate'] -> file{ + } ~> Exec['nft validate'] -> file { "/etc/nftables/puppet/${table}-chain-${chain}.nft": - ensure => file, - source => "/etc/nftables/puppet-preflight/${table}-chain-${chain}.nft", - owner => root, - group => root, - mode => '0640', + ensure => file, + source => "/etc/nftables/puppet-preflight/${table}-chain-${chain}.nft", + owner => root, + group => root, + mode => '0640', } ~> Service['nftables'] - concat::fragment{ + concat::fragment { default: target => $concat_name; "${concat_name}-header": @@ -51,7 +46,7 @@ undef => '', default => "oifname ${inject_oif} ", } - nftables::rule{ "${data[1]}-jump_${chain}": + nftables::rule { "${data[1]}-jump_${chain}": order => $data[0], content => "${iif}${oif}jump ${chain}", } diff --git a/manifests/config.pp b/manifests/config.pp index f07b1f04..f302a471 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -1,26 +1,24 @@ # manage a config snippet -define nftables::config( - Optional[String] - $content = undef, - Optional[Variant[String,Array[String,1]]] - $source = undef, -){ +define nftables::config ( + Optional[String] $content = undef, + Optional[Variant[String,Array[String,1]]] $source = undef, +) { $concat_name = "nftables-${name}" - Package['nftables'] -> concat{ + Package['nftables'] -> concat { $concat_name: path => "/etc/nftables/puppet-preflight/${name}.nft", ensure_newline => true, owner => root, group => root, mode => '0640', - } ~> Exec['nft validate'] -> file{ + } ~> Exec['nft validate'] -> file { "/etc/nftables/puppet/${name}.nft": - ensure => file, - source => "/etc/nftables/puppet-preflight/${name}.nft", - owner => root, - group => root, - mode => '0640', + ensure => file, + source => "/etc/nftables/puppet-preflight/${name}.nft", + owner => root, + group => root, + mode => '0640', } ~> Service['nftables'] $data = split($name, '-') diff --git a/manifests/inet_filter.pp b/manifests/inet_filter.pp index 687e9ed6..133f073b 100644 --- a/manifests/inet_filter.pp +++ b/manifests/inet_filter.pp @@ -1,6 +1,5 @@ # manage basic chains in table inet filter class nftables::inet_filter inherits nftables { - $_reject_rule = epp('nftables/reject_rule.epp', { 'log_prefix' => sprintf($nftables::log_prefix, { 'chain' => '%s', 'comment' => 'Rejected: ' }), @@ -8,12 +7,12 @@ } ) - nftables::config{ + nftables::config { 'inet-filter': source => 'puppet:///modules/nftables/config/puppet-inet-filter.nft'; } - nftables::chain{ + nftables::chain { [ 'INPUT', 'OUTPUT', @@ -21,7 +20,7 @@ ]:; } - nftables::chain{ + nftables::chain { 'default_in': inject => '10-INPUT'; 'default_out': @@ -31,7 +30,7 @@ } # inet-filter-chain-INPUT - nftables::rule{ + nftables::rule { 'INPUT-type': order => '01', content => 'type filter hook input priority 0'; @@ -49,14 +48,14 @@ content => sprintf($_reject_rule, { 'chain' => 'INPUT' }), } if $nftables::reject_with { - nftables::rule{ + nftables::rule { 'INPUT-reject': order => '98', content => "reject with ${$nftables::reject_with}"; } } if $nftables::in_out_conntrack { - nftables::rule{ + nftables::rule { 'INPUT-accept_established_related': order => '05', content => 'ct state established,related accept'; @@ -67,7 +66,7 @@ } # inet-filter-chain-OUTPUT - nftables::rule{ + nftables::rule { 'OUTPUT-type': order => '01', content => 'type filter hook output priority 0'; @@ -85,14 +84,14 @@ content => sprintf($_reject_rule, { 'chain' => 'OUTPUT' }), } if $nftables::reject_with { - nftables::rule{ + nftables::rule { 'OUTPUT-reject': order => '98', content => "reject with ${$nftables::reject_with}"; } } if $nftables::in_out_conntrack { - nftables::rule{ + nftables::rule { 'OUTPUT-accept_established_related': order => '05', content => 'ct state established,related accept'; @@ -103,7 +102,7 @@ } # inet-filter-chain-FORWARD - nftables::rule{ + nftables::rule { 'FORWARD-type': order => '01', content => 'type filter hook forward priority 0'; @@ -118,14 +117,14 @@ content => sprintf($_reject_rule, { 'chain' => 'FORWARD' }); } if $nftables::reject_with { - nftables::rule{ + nftables::rule { 'FORWARD-reject': order => '98', content => "reject with ${$nftables::reject_with}"; } } if $nftables::fwd_conntrack { - nftables::rule{ + nftables::rule { 'FORWARD-accept_established_related': order => '05', content => 'ct state established,related accept'; diff --git a/manifests/init.pp b/manifests/init.pp index a30b4196..01770694 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -80,39 +80,33 @@ # If left unset all tables will be flushed via a `flush ruleset` # class nftables ( - Boolean $in_ssh = true, - Boolean $in_icmp = true, - Boolean $out_ntp = true, - Boolean $out_dns = true, - Boolean $out_http = true, - Boolean $out_https = true, - Boolean $out_icmp = true, - Boolean $out_all = false, - Boolean $in_out_conntrack = true, - Boolean $fwd_conntrack = false, - Boolean $nat = true, - Hash $rules = {}, - Hash $sets = {}, - String $log_prefix = '[nftables] %s %s', - Variant[Boolean[false], String] - $log_limit = '3/minute burst 5 packets', - Variant[Boolean[false], Pattern[ - /icmp(v6|x)? type .+|tcp reset/]] - $reject_with = 'icmpx type port-unreachable', - Variant[Boolean[false], Enum['mask']] - $firewalld_enable = 'mask', - Optional[Array[Pattern[/^(ip|ip6|inet)-[-a-zA-Z0-9_]+$/],1]] - $noflush_tables = undef, + Boolean $in_ssh = true, + Boolean $in_icmp = true, + Boolean $out_ntp = true, + Boolean $out_dns = true, + Boolean $out_http = true, + Boolean $out_https = true, + Boolean $out_icmp = true, + Boolean $out_all = false, + Boolean $in_out_conntrack = true, + Boolean $fwd_conntrack = false, + Boolean $nat = true, + Hash $rules = {}, + Hash $sets = {}, + String $log_prefix = '[nftables] %s %s', + Variant[Boolean[false], String] $log_limit = '3/minute burst 5 packets', + Variant[Boolean[false], Pattern[/icmp(v6|x)? type .+|tcp reset/]] $reject_with = 'icmpx type port-unreachable', + Variant[Boolean[false], Enum['mask']] $firewalld_enable = 'mask', + Optional[Array[Pattern[/^(ip|ip6|inet)-[-a-zA-Z0-9_]+$/],1]] $noflush_tables = undef, ) { - - package{'nftables': + package { 'nftables': ensure => installed, - } -> file_line{ + } -> file_line { 'enable_nftables': line => 'include "/etc/nftables/puppet.nft"', path => '/etc/sysconfig/nftables.conf', notify => Service['nftables'], - } -> file{ + } -> file { default: owner => 'root', group => 'root', @@ -126,11 +120,11 @@ '/etc/nftables/puppet-preflight.nft': ensure => file, content => epp('nftables/config/puppet.nft.epp', { 'nat' => $nat, 'noflush' => $noflush_tables }); - } ~> exec{ + } ~> exec { 'nft validate': refreshonly => true, command => '/usr/sbin/nft -I /etc/nftables/puppet-preflight -c -f /etc/nftables/puppet-preflight.nft || ( /usr/bin/echo "#CONFIG BROKEN" >> /etc/nftables/puppet-preflight.nft && /bin/false)'; - } -> file{ + } -> file { default: owner => 'root', group => 'root', @@ -144,21 +138,21 @@ purge => true, force => true, recurse => true; - } ~> service{'nftables': + } ~> service { 'nftables': ensure => running, enable => true, hasrestart => true, restart => '/usr/bin/systemctl reload nftables', } - systemd::dropin_file{'puppet_nft.conf': + systemd::dropin_file { 'puppet_nft.conf': ensure => present, unit => 'nftables.service', content => epp('nftables/systemd/puppet_nft.conf.epp', { 'noflush' => $noflush_tables }), notify => Service['nftables'], } - service{'firewalld': + service { 'firewalld': ensure => stopped, enable => $firewalld_enable, } @@ -170,17 +164,17 @@ # inject custom rules e.g. from hiera $rules.each |$n,$v| { - nftables::rule{ + nftables::rule { $n: - * => $v + * => $v, } } # inject custom sets e.g. from hiera $sets.each |$n,$v| { - nftables::set{ + nftables::set { $n: - * => $v + * => $v, } } } diff --git a/manifests/ip_nat.pp b/manifests/ip_nat.pp index 022dbc5a..1ff29849 100644 --- a/manifests/ip_nat.pp +++ b/manifests/ip_nat.pp @@ -1,14 +1,13 @@ # manage basic chains in table ip nat class nftables::ip_nat inherits nftables { - - nftables::config{ + nftables::config { 'ip-nat': source => 'puppet:///modules/nftables/config/puppet-ip-nat.nft'; 'ip6-nat': source => 'puppet:///modules/nftables/config/puppet-ip6-nat.nft'; } - nftables::chain{ + nftables::chain { [ 'PREROUTING', 'POSTROUTING', @@ -16,7 +15,7 @@ table => 'ip-nat'; } - nftables::chain{ + nftables::chain { [ 'PREROUTING6', 'POSTROUTING6', @@ -25,7 +24,7 @@ } # ip-nat-chain-PREROUTING - nftables::rule{ + nftables::rule { 'PREROUTING-type': table => 'ip-nat', order => '01', @@ -45,7 +44,7 @@ } # ip-nat-chain-POSTROUTING - nftables::rule{ + nftables::rule { 'POSTROUTING-type': table => 'ip-nat', order => '01', diff --git a/manifests/rule.pp b/manifests/rule.pp index 7a74238d..94c56f38 100644 --- a/manifests/rule.pp +++ b/manifests/rule.pp @@ -1,21 +1,14 @@ # manage a chain rule # Name should be: # CHAIN_NAME-rulename -define nftables::rule( - Enum['present','absent'] - $ensure = 'present', - Pattern[/^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+(-\d+)?$/] - $rulename = $title, - Pattern[/^\d\d$/] - $order = '50', - Optional[String] - $table = 'inet-filter', - Optional[String] - $content = undef, - Optional[Variant[String,Array[String,1]]] - $source = undef, -){ - +define nftables::rule ( + Enum['present','absent'] $ensure = 'present', + Pattern[/^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+(-\d+)?$/] $rulename = $title, + Pattern[/^\d\d$/] $order = '50', + Optional[String] $table = 'inet-filter', + Optional[String] $content = undef, + Optional[Variant[String,Array[String,1]]] $source = undef, +) { if $ensure == 'present' { $data = split($rulename, '-') @@ -25,24 +18,24 @@ $fragment = "nftables-${table}-chain-${data[0]}-rule-${data[1]}" } - concat::fragment{"${fragment}_header": + concat::fragment { "${fragment}_header": content => "# Start of fragment order:${order} rulename:${rulename}", order => "${order}-${fragment}-a", target => "nftables-${table}-chain-${data[0]}", } - concat::fragment{ + concat::fragment { $fragment: order => "${order}-${fragment}-b", target => "nftables-${table}-chain-${data[0]}", } if $content { - Concat::Fragment[$fragment]{ + Concat::Fragment[$fragment] { content => " ${content}", } } else { - Concat::Fragment[$fragment]{ + Concat::Fragment[$fragment] { source => $source, } } diff --git a/manifests/rules/afs3_callback.pp b/manifests/rules/afs3_callback.pp index ead6bdea..075177b9 100644 --- a/manifests/rules/afs3_callback.pp +++ b/manifests/rules/afs3_callback.pp @@ -8,9 +8,7 @@ class nftables::rules::afs3_callback ( Array[Stdlib::IP::Address::V4,1] $saddr = ['0.0.0.0/0'], ) { - - nftables::rule{'default_in-afs3_callback': - content => "ip saddr { ${saddr.join(', ')} } udp dport 7001 accept"; + nftables::rule { 'default_in-afs3_callback': + content => "ip saddr { ${saddr.join(', ')} } udp dport 7001 accept"; } - } diff --git a/manifests/rules/ceph.pp b/manifests/rules/ceph.pp index ccd05c8a..1fc33be3 100644 --- a/manifests/rules/ceph.pp +++ b/manifests/rules/ceph.pp @@ -2,7 +2,7 @@ # Enable this to support Ceph's Object Storage Daemons (OSD), # Metadata Server Daemons (MDS), or Manager Daemons (MGR). class nftables::rules::ceph { - nftables::rule{ + nftables::rule { 'default_in-ceph': content => 'tcp dport 6800-7300 accept comment "Accept Ceph OSD, MDS, MGR"', } diff --git a/manifests/rules/ceph_mon.pp b/manifests/rules/ceph_mon.pp index 1cde9d0c..75494522 100644 --- a/manifests/rules/ceph_mon.pp +++ b/manifests/rules/ceph_mon.pp @@ -1,9 +1,9 @@ # Ceph is a distributed object store and file system. # Enable this option to support Ceph's Monitor Daemon. -class nftables::rules::ceph_mon( +class nftables::rules::ceph_mon ( Array[Integer,1] $ports = [3300, 6789], -){ - nftables::rule{ +) { + nftables::rule { 'default_in-ceph_mon': content => "tcp dport {${$ports.join(', ')}} accept comment \"Accept Ceph MON\"", } diff --git a/manifests/rules/dhcpv6_client.pp b/manifests/rules/dhcpv6_client.pp index a1872128..a7c014c7 100644 --- a/manifests/rules/dhcpv6_client.pp +++ b/manifests/rules/dhcpv6_client.pp @@ -1,5 +1,5 @@ class nftables::rules::dhcpv6_client { - nftables::rule{ + nftables::rule { 'default_in-dhcpv6_client': content => 'ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp sport 547 udp dport 546 accept', } diff --git a/manifests/rules/dnat4.pp b/manifests/rules/dnat4.pp index 46e4fa7a..601ac309 100644 --- a/manifests/rules/dnat4.pp +++ b/manifests/rules/dnat4.pp @@ -1,25 +1,15 @@ # manage a ipv4 dnat rule -define nftables::rules::dnat4( - Pattern[/^[12]?\d{1,2}\.[12]?\d{1,2}\.[12]?\d{1,2}\.[12]?\d{1,2}$/] - $daddr, - Variant[String,Integer[1,65535]] - $port, - Pattern[/^[a-zA-Z0-9_]+$/] - $rulename = $title, - Pattern[/^\d\d$/] - $order = '50', - String[1] - $chain = 'default_fwd', - Optional[String[1]] - $iif = undef, - Enum['tcp','udp'] - $proto = 'tcp', - Optional[Variant[String,Integer[1,65535]]] - $dport = '', - Enum['present','absent'] - $ensure = 'present', +define nftables::rules::dnat4 ( + Pattern[/^[12]?\d{1,2}\.[12]?\d{1,2}\.[12]?\d{1,2}\.[12]?\d{1,2}$/] $daddr, + Variant[String,Integer[1,65535]] $port, + Pattern[/^[a-zA-Z0-9_]+$/] $rulename = $title, + Pattern[/^\d\d$/] $order = '50', + String[1] $chain = 'default_fwd', + Optional[String[1]] $iif = undef, + Enum['tcp','udp'] $proto = 'tcp', + Optional[Variant[String,Integer[1,65535]]] $dport = '', + Enum['present','absent'] $ensure = 'present', ) { - $iifname = $iif ? { undef => '', default => "iifname ${iif} ", @@ -33,7 +23,7 @@ default => ":${dport}", } - nftables::rule{ + nftables::rule { default: ensure => $ensure, order => $order; diff --git a/manifests/rules/dns.pp b/manifests/rules/dns.pp index 144a8cd0..6cfb5ada 100644 --- a/manifests/rules/dns.pp +++ b/manifests/rules/dns.pp @@ -1,9 +1,8 @@ # manage in dns -class nftables::rules::dns( - Array[Integer,1] - $ports = [53], +class nftables::rules::dns ( + Array[Integer,1] $ports = [53], ) { - nftables::rule{ + nftables::rule { 'default_in-dns_tcp': content => "tcp dport {${join($ports,', ')}} accept"; 'default_in-dns_udp': diff --git a/manifests/rules/http.pp b/manifests/rules/http.pp index 73e390b7..2d5d2d47 100644 --- a/manifests/rules/http.pp +++ b/manifests/rules/http.pp @@ -1,6 +1,6 @@ # manage in http class nftables::rules::http { - nftables::rule{ + nftables::rule { 'default_in-http': content => 'tcp dport 80 accept', } diff --git a/manifests/rules/https.pp b/manifests/rules/https.pp index c97e2c73..3834096c 100644 --- a/manifests/rules/https.pp +++ b/manifests/rules/https.pp @@ -1,6 +1,6 @@ # manage in https class nftables::rules::https { - nftables::rule{ + nftables::rule { 'default_in-https': content => 'tcp dport 443 accept', } diff --git a/manifests/rules/icinga2.pp b/manifests/rules/icinga2.pp index cbfc9c42..be6875e3 100644 --- a/manifests/rules/icinga2.pp +++ b/manifests/rules/icinga2.pp @@ -1,9 +1,8 @@ # manage in icinga2 -class nftables::rules::icinga2( - Array[Integer,1] - $ports = [5665], +class nftables::rules::icinga2 ( + Array[Integer,1] $ports = [5665], ) { - nftables::rule{ + nftables::rule { 'default_in-icinga2': content => "tcp dport {${join($ports,', ')}} accept", } diff --git a/manifests/rules/icmp.pp b/manifests/rules/icmp.pp index a699ff83..068d34c6 100644 --- a/manifests/rules/icmp.pp +++ b/manifests/rules/icmp.pp @@ -5,33 +5,33 @@ ) { if $v4_types { $v4_types.each | String $icmp_type | { - nftables::rule{ + nftables::rule { "default_in-accept_icmpv4_${regsubst(split($icmp_type, ' ')[0], '-', '_', 'G')}": content => "ip protocol icmp icmp type ${icmp_type} accept", order => $order, } } } else { - nftables::rule{ + nftables::rule { 'default_in-accept_icmpv4': content => 'ip protocol icmp accept', order => $order, - } + } } if $v6_types { $v6_types.each | String $icmp_type | { - nftables::rule{ + nftables::rule { "default_in-accept_icmpv6_${regsubst(split($icmp_type, ' ')[0], '-', '_', 'G')}": content => "ip6 nexthdr ipv6-icmp icmpv6 type ${icmp_type} accept", order => $order, } } } else { - nftables::rule{ + nftables::rule { 'default_in-accept_icmpv6': content => 'ip6 nexthdr ipv6-icmp accept', order => $order, - } + } } } diff --git a/manifests/rules/masquerade.pp b/manifests/rules/masquerade.pp index 5dfc959d..a2845f13 100644 --- a/manifests/rules/masquerade.pp +++ b/manifests/rules/masquerade.pp @@ -1,25 +1,15 @@ # masquerade all outgoing traffic -define nftables::rules::masquerade( - Pattern[/^[a-zA-Z0-9_]+$/] - $rulename = $title, - Pattern[/^\d\d$/] - $order = '70', - String[1] - $chain = 'POSTROUTING', - Optional[String[1]] - $oif = undef, - Optional[String[1]] - $saddr = undef, - Optional[String[1]] - $daddr = undef, - Optional[Enum['tcp','udp']] - $proto = undef, - Optional[Variant[String,Integer[1,65535]]] - $dport = undef, - Enum['present','absent'] - $ensure = 'present', +define nftables::rules::masquerade ( + Pattern[/^[a-zA-Z0-9_]+$/] $rulename = $title, + Pattern[/^\d\d$/] $order = '70', + String[1] $chain = 'POSTROUTING', + Optional[String[1]] $oif = undef, + Optional[String[1]] $saddr = undef, + Optional[String[1]] $daddr = undef, + Optional[Enum['tcp','udp']] $proto = undef, + Optional[Variant[String,Integer[1,65535]]] $dport = undef, + Enum['present','absent'] $ensure = 'present', ) { - $oifname = $oif ? { undef => '', default => "oifname ${oif} ", @@ -47,7 +37,7 @@ $port = '' } - nftables::rule{ + nftables::rule { "${chain}-${rulename}": ensure => $ensure, table => 'ip-nat', diff --git a/manifests/rules/nfs.pp b/manifests/rules/nfs.pp index 2f001474..868f1dff 100644 --- a/manifests/rules/nfs.pp +++ b/manifests/rules/nfs.pp @@ -1,6 +1,6 @@ # manage in nfs4 class nftables::rules::nfs { - nftables::rule{ + nftables::rule { 'default_in-nfs4': content => 'tcp dport nfs accept comment "Accept NFS4"', } diff --git a/manifests/rules/nfs3.pp b/manifests/rules/nfs3.pp index 30fbe292..446288aa 100644 --- a/manifests/rules/nfs3.pp +++ b/manifests/rules/nfs3.pp @@ -1,6 +1,6 @@ # manage in nfs3 class nftables::rules::nfs3 { - nftables::rule{ + nftables::rule { 'default_in-nfs3': content => 'meta l4proto { tcp, udp } dport nfs accept comment "Accept NFS3"', } diff --git a/manifests/rules/node_exporter.pp b/manifests/rules/node_exporter.pp index 345c1c28..6086183a 100644 --- a/manifests/rules/node_exporter.pp +++ b/manifests/rules/node_exporter.pp @@ -1,28 +1,25 @@ # manage in node exporter -class nftables::rules::node_exporter( - Optional[Variant[String,Array[String,1]]] - $prometheus_server = undef, - Integer - $port = 9100, +class nftables::rules::node_exporter ( + Optional[Variant[String,Array[String,1]]] $prometheus_server = undef, + Integer $port = 9100, ) { if $prometheus_server { any2array($prometheus_server).each |$index,$prom| { - - nftables::rule{ + nftables::rule { "default_in-node_exporter-${index}": } if $prom =~ /:/ { - Nftables::Rule["default_in-node_exporter-${index}"]{ + Nftables::Rule["default_in-node_exporter-${index}"] { content => "ip6 saddr ${prom} tcp dport ${port} accept", } } else { - Nftables::Rule["default_in-node_exporter-${index}"]{ + Nftables::Rule["default_in-node_exporter-${index}"] { content => "ip saddr ${prom} tcp dport ${port} accept", } } } } else { - nftables::rule{ + nftables::rule { 'default_in-node_exporter': content => "tcp dport ${port} accept"; } diff --git a/manifests/rules/ospf.pp b/manifests/rules/ospf.pp index b5effc9a..97b47529 100644 --- a/manifests/rules/ospf.pp +++ b/manifests/rules/ospf.pp @@ -1,6 +1,6 @@ # manage in ospf class nftables::rules::ospf { - nftables::rule{ + nftables::rule { 'default_in-ospf': content => 'ip daddr { 224.0.0.5, 224.0.0.6 } meta l4proto ospf accept', } diff --git a/manifests/rules/ospf3.pp b/manifests/rules/ospf3.pp index 6a755be5..526ad0e0 100644 --- a/manifests/rules/ospf3.pp +++ b/manifests/rules/ospf3.pp @@ -1,6 +1,6 @@ # manage in ospf3 class nftables::rules::ospf3 { - nftables::rule{ + nftables::rule { 'default_in-ospf3': content => 'ip6 saddr fe80::/64 ip6 daddr { ff02::5, ff02::6 } meta l4proto ospf accept', } diff --git a/manifests/rules/out/all.pp b/manifests/rules/out/all.pp index 2ca52aee..37c58a84 100644 --- a/manifests/rules/out/all.pp +++ b/manifests/rules/out/all.pp @@ -1,9 +1,8 @@ # allow all outbound class nftables::rules::out::all { - nftables::rule{ + nftables::rule { 'default_out-all': order => '90', content => 'accept', - } } diff --git a/manifests/rules/out/ceph_client.pp b/manifests/rules/out/ceph_client.pp index 3fc27a21..e30049a2 100644 --- a/manifests/rules/out/ceph_client.pp +++ b/manifests/rules/out/ceph_client.pp @@ -2,10 +2,10 @@ # Enable this to be a client of Ceph's Monitor (MON), # Object Storage Daemons (OSD), Metadata Server Daemons (MDS), # and Manager Daemons (MGR). -class nftables::rules::out::ceph_client( +class nftables::rules::out::ceph_client ( Array[Integer,1] $ports = [3300, 6789], -){ - nftables::rule{ +) { + nftables::rule { 'default_out-ceph_client': content => "tcp dport { ${$ports.join(', ')}, 6800-7300 } accept comment \"Accept Ceph MON, OSD, MDS, MGR\"", } diff --git a/manifests/rules/out/chrony.pp b/manifests/rules/out/chrony.pp index a79568b7..5e856fdc 100644 --- a/manifests/rules/out/chrony.pp +++ b/manifests/rules/out/chrony.pp @@ -1,6 +1,6 @@ # manage out chrony class nftables::rules::out::chrony { - nftables::rule{ + nftables::rule { 'default_out-chrony': content => 'udp dport 123 accept', } diff --git a/manifests/rules/out/dhcp.pp b/manifests/rules/out/dhcp.pp index 90193fd9..c5b6b192 100644 --- a/manifests/rules/out/dhcp.pp +++ b/manifests/rules/out/dhcp.pp @@ -1,6 +1,6 @@ # manage out dhcp class nftables::rules::out::dhcp { - nftables::rule{ + nftables::rule { 'default_out-dhcpc': content => 'udp sport {67, 68} udp dport {67, 68} accept'; } diff --git a/manifests/rules/out/dhcpv6_client.pp b/manifests/rules/out/dhcpv6_client.pp index 5c4f7d2a..dfb88526 100644 --- a/manifests/rules/out/dhcpv6_client.pp +++ b/manifests/rules/out/dhcpv6_client.pp @@ -1,5 +1,5 @@ class nftables::rules::out::dhcpv6_client { - nftables::rule{ + nftables::rule { 'default_out-dhcpv6_client': content => 'ip6 saddr fe80::/10 udp sport 546 udp dport 547 accept', } diff --git a/manifests/rules/out/dns.pp b/manifests/rules/out/dns.pp index 32c3600a..997f29ab 100644 --- a/manifests/rules/out/dns.pp +++ b/manifests/rules/out/dns.pp @@ -1,39 +1,37 @@ # manage out dns class nftables::rules::out::dns ( - Optional[Variant[String,Array[String,1]]] - $dns_server = undef, + Optional[Variant[String,Array[String,1]]] $dns_server = undef, ) { if $dns_server { any2array($dns_server).each |$index,$dns| { - - nftables::rule{ + nftables::rule { "default_out-dnsudp-${index}": } if $dns =~ /:/ { - Nftables::Rule["default_out-dnsudp-${index}"]{ + Nftables::Rule["default_out-dnsudp-${index}"] { content => "ip6 daddr ${dns} udp dport 53 accept", } } else { - Nftables::Rule["default_out-dnsudp-${index}"]{ + Nftables::Rule["default_out-dnsudp-${index}"] { content => "ip daddr ${dns} udp dport 53 accept", } } - nftables::rule{ + nftables::rule { "default_out-dnstcp-${index}": } if $dns =~ /:/ { - Nftables::Rule["default_out-dnstcp-${index}"]{ + Nftables::Rule["default_out-dnstcp-${index}"] { content => "ip6 daddr ${dns} tcp dport 53 accept", } } else { - Nftables::Rule["default_out-dnstcp-${index}"]{ + Nftables::Rule["default_out-dnstcp-${index}"] { content => "ip daddr ${dns} tcp dport 53 accept", } } } } else { - nftables::rule{ + nftables::rule { 'default_out-dnsudp': content => 'udp dport 53 accept'; 'default_out-dnstcp': diff --git a/manifests/rules/out/http.pp b/manifests/rules/out/http.pp index 656a2c6f..6de9eb33 100644 --- a/manifests/rules/out/http.pp +++ b/manifests/rules/out/http.pp @@ -1,6 +1,6 @@ # manage out http class nftables::rules::out::http { - nftables::rule{ + nftables::rule { 'default_out-http': content => 'tcp dport 80 accept'; } diff --git a/manifests/rules/out/https.pp b/manifests/rules/out/https.pp index b5c2734e..84212b3c 100644 --- a/manifests/rules/out/https.pp +++ b/manifests/rules/out/https.pp @@ -1,6 +1,6 @@ # manage out https class nftables::rules::out::https { - nftables::rule{ + nftables::rule { 'default_out-https': content => 'tcp dport 443 accept'; } diff --git a/manifests/rules/out/icmp.pp b/manifests/rules/out/icmp.pp index a67304ac..4d132805 100644 --- a/manifests/rules/out/icmp.pp +++ b/manifests/rules/out/icmp.pp @@ -1,37 +1,37 @@ class nftables::rules::out::icmp ( Optional[Array[String]] $v4_types = undef, Optional[Array[String]] $v6_types = undef, - String $order = '10', + String $order = '10', ) { if $v4_types { $v4_types.each | String $icmp_type | { - nftables::rule{ + nftables::rule { 'default_out-accept_icmpv4': content => "ip protocol icmp icmp type ${icmp_type} accept", order => $order, } } } else { - nftables::rule{ + nftables::rule { 'default_out-accept_icmpv4': content => 'ip protocol icmp accept', order => $order, - } + } } if $v6_types { $v6_types.each | String $icmp_type | { - nftables::rule{ + nftables::rule { 'default_out-accept_icmpv6': content => "ip6 nexthdr ipv6-icmp icmpv6 type ${icmp_type} accept", order => $order, } } } else { - nftables::rule{ + nftables::rule { 'default_out-accept_icmpv6': content => 'ip6 nexthdr ipv6-icmp accept', order => $order, - } + } } } diff --git a/manifests/rules/out/kerberos.pp b/manifests/rules/out/kerberos.pp index f6e1a32f..395b92ce 100644 --- a/manifests/rules/out/kerberos.pp +++ b/manifests/rules/out/kerberos.pp @@ -1,11 +1,9 @@ # @summary allows outbound access for kerberos class nftables::rules::out::kerberos { - - nftables::rule{ + nftables::rule { 'default_out-kerberos_udp': - content => 'udp dport 88 accept'; + content => 'udp dport 88 accept'; 'default_out-kerberos_tcp': - content => 'tcp dport 88 accept'; + content => 'tcp dport 88 accept'; } - } diff --git a/manifests/rules/out/mysql.pp b/manifests/rules/out/mysql.pp index ba39ce75..6cc929db 100644 --- a/manifests/rules/out/mysql.pp +++ b/manifests/rules/out/mysql.pp @@ -1,6 +1,6 @@ # manage out mysql class nftables::rules::out::mysql { - nftables::rule{ + nftables::rule { 'default_out-mysql': content => 'tcp dport 3306 accept'; } diff --git a/manifests/rules/out/nfs.pp b/manifests/rules/out/nfs.pp index e201bc5a..9333339f 100644 --- a/manifests/rules/out/nfs.pp +++ b/manifests/rules/out/nfs.pp @@ -1,6 +1,6 @@ # manage out nfs class nftables::rules::out::nfs { - nftables::rule{ + nftables::rule { 'default_out-nfs4': content => 'tcp dport nfs accept comment "Accept NFS4"', } diff --git a/manifests/rules/out/nfs3.pp b/manifests/rules/out/nfs3.pp index 3a309ac5..8fbbcf5c 100644 --- a/manifests/rules/out/nfs3.pp +++ b/manifests/rules/out/nfs3.pp @@ -1,6 +1,6 @@ # manage out nfs3 class nftables::rules::out::nfs3 { - nftables::rule{ + nftables::rule { 'default_out-nfs3': content => 'meta l4proto { tcp, udp } dport nfs accept comment "Accept NFS3"', } diff --git a/manifests/rules/out/openafs_client.pp b/manifests/rules/out/openafs_client.pp index 97098ea4..a11a170b 100644 --- a/manifests/rules/out/openafs_client.pp +++ b/manifests/rules/out/openafs_client.pp @@ -5,14 +5,12 @@ # # @see https://wiki.openafs.org/devel/AFSServicePorts/ AFS Service Ports # -class nftables::rules::out::openafs_client( +class nftables::rules::out::openafs_client ( Array[Integer,1] $ports = [7000, 7002, 7003], -){ - +) { include nftables::rules::out::kerberos - nftables::rule{'default_out-openafs_client': + nftables::rule { 'default_out-openafs_client': content => "udp dport {${$ports.join(', ')}} accept"; } - } diff --git a/manifests/rules/out/ospf.pp b/manifests/rules/out/ospf.pp index c14a1b33..bb9112c6 100644 --- a/manifests/rules/out/ospf.pp +++ b/manifests/rules/out/ospf.pp @@ -1,6 +1,6 @@ # manage out ospf class nftables::rules::out::ospf { - nftables::rule{ + nftables::rule { 'default_out-ospf': content => 'ip daddr { 224.0.0.5, 224.0.0.6 } meta l4proto ospf accept', } diff --git a/manifests/rules/out/ospf3.pp b/manifests/rules/out/ospf3.pp index ee5d9ba1..a0e5a4ed 100644 --- a/manifests/rules/out/ospf3.pp +++ b/manifests/rules/out/ospf3.pp @@ -1,6 +1,6 @@ # manage out ospf3 class nftables::rules::out::ospf3 { - nftables::rule{ + nftables::rule { 'default_out-ospf3': content => 'ip6 saddr fe80::/64 ip6 daddr { ff02::5, ff02::6 } meta l4proto ospf accept', } diff --git a/manifests/rules/out/postgres.pp b/manifests/rules/out/postgres.pp index 08fd8807..44822532 100644 --- a/manifests/rules/out/postgres.pp +++ b/manifests/rules/out/postgres.pp @@ -1,6 +1,6 @@ # manage out postgres class nftables::rules::out::postgres { - nftables::rule{ + nftables::rule { 'default_out-postgres': content => 'tcp dport 5432 accept'; } diff --git a/manifests/rules/out/puppet.pp b/manifests/rules/out/puppet.pp index 79035e39..1f761917 100644 --- a/manifests/rules/out/puppet.pp +++ b/manifests/rules/out/puppet.pp @@ -1,20 +1,18 @@ # manage outgoing puppet -class nftables::rules::out::puppet( - Variant[String,Array[String,1]] - $puppetmaster, - Integer - $puppetserver_port = 8140, +class nftables::rules::out::puppet ( + Variant[String,Array[String,1]] $puppetmaster, + Integer $puppetserver_port = 8140, ) { any2array($puppetmaster).each |$index,$pm| { - nftables::rule{ + nftables::rule { "default_out-puppet-${index}": } if $pm =~ /:/ { - Nftables::Rule["default_out-puppet-${index}"]{ + Nftables::Rule["default_out-puppet-${index}"] { content => "ip6 daddr ${pm} tcp dport ${puppetserver_port} accept", } } else { - Nftables::Rule["default_out-puppet-${index}"]{ + Nftables::Rule["default_out-puppet-${index}"] { content => "ip daddr ${pm} tcp dport ${puppetserver_port} accept", } } diff --git a/manifests/rules/out/smtp.pp b/manifests/rules/out/smtp.pp index 2988ef5f..2b9a0364 100644 --- a/manifests/rules/out/smtp.pp +++ b/manifests/rules/out/smtp.pp @@ -1,6 +1,6 @@ # manage out smtp class nftables::rules::out::smtp { - nftables::rule{ + nftables::rule { 'default_out-smtp': content => 'tcp dport 25 accept', } diff --git a/manifests/rules/out/ssh.pp b/manifests/rules/out/ssh.pp index e5676d54..632b4b97 100644 --- a/manifests/rules/out/ssh.pp +++ b/manifests/rules/out/ssh.pp @@ -1,6 +1,6 @@ # manage out ssh class nftables::rules::out::ssh { - nftables::rule{ + nftables::rule { 'default_out-ssh': content => 'tcp dport 22 accept', } diff --git a/manifests/rules/out/ssh/remove.pp b/manifests/rules/out/ssh/remove.pp index 2b5bc6f9..35b22cc4 100644 --- a/manifests/rules/out/ssh/remove.pp +++ b/manifests/rules/out/ssh/remove.pp @@ -1,6 +1,6 @@ # disable outgoing ssh class nftables::rules::out::ssh::remove inherits nftables::rules::out::ssh { - Nftables::Rule['default_out-ssh']{ + Nftables::Rule['default_out-ssh'] { ensure => absent, } } diff --git a/manifests/rules/out/tor.pp b/manifests/rules/out/tor.pp index 951f4845..74be3858 100644 --- a/manifests/rules/out/tor.pp +++ b/manifests/rules/out/tor.pp @@ -1,6 +1,6 @@ # manage out tor class nftables::rules::out::tor { - nftables::rule{ + nftables::rule { 'default_out-tor': content => 'tcp dport 9001 accept', } diff --git a/manifests/rules/out/wireguard.pp b/manifests/rules/out/wireguard.pp index bc30bfb8..b8126c43 100644 --- a/manifests/rules/out/wireguard.pp +++ b/manifests/rules/out/wireguard.pp @@ -1,9 +1,8 @@ # manage out wireguard class nftables::rules::out::wireguard ( - Array[Integer,1] - $ports = [51820], + Array[Integer,1] $ports = [51820], ) { - nftables::rule{ + nftables::rule { 'default_out-wireguard': content => "udp dport {${join($ports,', ')}} accept", } diff --git a/manifests/rules/puppet.pp b/manifests/rules/puppet.pp index 2829fa3b..d5347706 100644 --- a/manifests/rules/puppet.pp +++ b/manifests/rules/puppet.pp @@ -1,9 +1,8 @@ # manage in puppet -class nftables::rules::puppet( - Array[Integer,1] - $ports = [8140], +class nftables::rules::puppet ( + Array[Integer,1] $ports = [8140], ) { - nftables::rule{ + nftables::rule { 'default_in-puppet': content => "tcp dport {${join($ports,', ')}} accept", } diff --git a/manifests/rules/smtp.pp b/manifests/rules/smtp.pp index 3088e3e9..76ae429e 100644 --- a/manifests/rules/smtp.pp +++ b/manifests/rules/smtp.pp @@ -1,6 +1,6 @@ # manage in smtp class nftables::rules::smtp { - nftables::rule{ + nftables::rule { 'default_in-smtp': content => 'tcp dport 25 accept', } diff --git a/manifests/rules/smtp_submission.pp b/manifests/rules/smtp_submission.pp index c926030c..5166e47d 100644 --- a/manifests/rules/smtp_submission.pp +++ b/manifests/rules/smtp_submission.pp @@ -1,6 +1,6 @@ # manage in smtp submission class nftables::rules::smtp_submission { - nftables::rule{ + nftables::rule { 'default_in-smtp_submission': content => 'tcp dport 587 accept', } diff --git a/manifests/rules/smtps.pp b/manifests/rules/smtps.pp index 291ae799..e653f9c2 100644 --- a/manifests/rules/smtps.pp +++ b/manifests/rules/smtps.pp @@ -1,6 +1,6 @@ # manage in smtps class nftables::rules::smtps { - nftables::rule{ + nftables::rule { 'default_in-smtps': content => 'tcp dport 465 accept', } diff --git a/manifests/rules/snat4.pp b/manifests/rules/snat4.pp index 3fc85012..8a643932 100644 --- a/manifests/rules/snat4.pp +++ b/manifests/rules/snat4.pp @@ -1,25 +1,15 @@ # manage a ipv4 snat rule -define nftables::rules::snat4( - String[1] - $snat, - Pattern[/^[a-zA-Z0-9_]+$/] - $rulename = $title, - Pattern[/^\d\d$/] - $order = '70', - String[1] - $chain = 'POSTROUTING', - Optional[String[1]] - $oif = undef, - Optional[String[1]] - $saddr = undef, - Optional[Enum['tcp','udp']] - $proto = undef, - Optional[Variant[String,Integer[1,65535]]] - $dport = undef, - Enum['present','absent'] - $ensure = 'present', +define nftables::rules::snat4 ( + String[1] $snat, + Pattern[/^[a-zA-Z0-9_]+$/] $rulename = $title, + Pattern[/^\d\d$/] $order = '70', + String[1] $chain = 'POSTROUTING', + Optional[String[1]] $oif = undef, + Optional[String[1]] $saddr = undef, + Optional[Enum['tcp','udp']] $proto = undef, + Optional[Variant[String,Integer[1,65535]]] $dport = undef, + Enum['present','absent'] $ensure = 'present', ) { - $oifname = $oif ? { undef => '', default => "oifname ${oif} ", @@ -43,7 +33,7 @@ $port = '' } - nftables::rule{ + nftables::rule { "${chain}-${rulename}": ensure => $ensure, table => 'ip-nat', diff --git a/manifests/rules/ssh.pp b/manifests/rules/ssh.pp index 6659e768..2fcb8afc 100644 --- a/manifests/rules/ssh.pp +++ b/manifests/rules/ssh.pp @@ -1,9 +1,8 @@ # manage in ssh -class nftables::rules::ssh( - Array[Integer,1] - $ports = [22], +class nftables::rules::ssh ( + Array[Integer,1] $ports = [22], ) { - nftables::rule{ + nftables::rule { 'default_in-ssh': content => "tcp dport {${join($ports,', ')}} accept", } diff --git a/manifests/rules/tor.pp b/manifests/rules/tor.pp index 0f03129a..6167204f 100644 --- a/manifests/rules/tor.pp +++ b/manifests/rules/tor.pp @@ -1,9 +1,8 @@ # manage in tor -class nftables::rules::tor( - Array[Integer,1] - $ports = [9001], +class nftables::rules::tor ( + Array[Integer,1] $ports = [9001], ) { - nftables::rule{ + nftables::rule { 'default_in-tor': content => "tcp dport {${join($ports,', ')}} accept", } diff --git a/manifests/rules/wireguard.pp b/manifests/rules/wireguard.pp index 38810997..3761a0b8 100644 --- a/manifests/rules/wireguard.pp +++ b/manifests/rules/wireguard.pp @@ -1,9 +1,8 @@ # manage in wireguard -class nftables::rules::wireguard( - Array[Integer,1] - $ports = [51820], +class nftables::rules::wireguard ( + Array[Integer,1] $ports = [51820], ) { - nftables::rule{ + nftables::rule { 'default_in-wireguard': content => "udp dport {${join($ports,', ')}} accept", } diff --git a/manifests/set.pp b/manifests/set.pp index 6437b827..df8d259f 100644 --- a/manifests/set.pp +++ b/manifests/set.pp @@ -1,35 +1,20 @@ # manage a named set -define nftables::set( - Enum['present','absent'] - $ensure = 'present', - Pattern[/^[-a-zA-Z0-9_]+$/] - $setname = $title, - Pattern[/^\d\d$/] - $order = '10', - Optional[Enum['ipv4_addr', 'ipv6_addr', 'ether_addr', 'inet_proto', 'inet_service', 'mark']] - $type = undef, - String - $table = 'inet-filter', - Array[Enum['constant', 'dynamic', 'interval', 'timeout'], 0, 4] - $flags = [], - Optional[Integer] - $timeout = undef, - Optional[Integer] - $gc_interval = undef, - Optional[Array[String]] - $elements = undef, - Optional[Integer] - $size = undef, - Optional[Enum['performance', 'memory']] - $policy = undef, - Boolean - $auto_merge = false, - Optional[String] - $content = undef, - Optional[Variant[String,Array[String,1]]] - $source = undef, -){ - +define nftables::set ( + Enum['present','absent'] $ensure = 'present', + Pattern[/^[-a-zA-Z0-9_]+$/] $setname = $title, + Pattern[/^\d\d$/] $order = '10', + Optional[Enum['ipv4_addr', 'ipv6_addr', 'ether_addr', 'inet_proto', 'inet_service', 'mark']] $type = undef, + String $table = 'inet-filter', + Array[Enum['constant', 'dynamic', 'interval', 'timeout'], 0, 4] $flags = [], + Optional[Integer] $timeout = undef, + Optional[Integer] $gc_interval = undef, + Optional[Array[String]] $elements = undef, + Optional[Integer] $size = undef, + Optional[Enum['performance', 'memory']] $policy = undef, + Boolean $auto_merge = false, + Optional[String] $content = undef, + Optional[Variant[String,Array[String,1]]] $source = undef, +) { if $size and $elements { if length($elements) > $size { fail("Max size of set ${setname} of ${size} is not being respected") @@ -37,25 +22,25 @@ } if $ensure == 'present' { - concat::fragment{ + concat::fragment { "nftables-${table}-set-${setname}": order => $order, target => "nftables-${table}", } if $content { - Concat::Fragment["nftables-${table}-set-${setname}"]{ + Concat::Fragment["nftables-${table}-set-${setname}"] { content => " ${content}", } } elsif $source { - Concat::Fragment["nftables-${table}-set-${setname}"]{ + Concat::Fragment["nftables-${table}-set-${setname}"] { source => $source, } } else { if $type == undef { fail('The way the resource is configured must have a type set') } - Concat::Fragment["nftables-${table}-set-${setname}"]{ + Concat::Fragment["nftables-${table}-set-${setname}"] { content => epp('nftables/set.epp', { 'name' => $setname, diff --git a/metadata.json b/metadata.json index 49fa3bd0..e5115b63 100644 --- a/metadata.json +++ b/metadata.json @@ -1,11 +1,18 @@ { - "name": "duritong-nftables", + "name": "puppet-nftables", "version": "0.1.0", - "author": "duritong", + "author": "Vox Pupuli", "summary": "Puppet nftables module", "license": "Apache-2.0", - "source": "https://code.immerda.ch/immerda/puppet-modules/nftables.git", - "project_page": "https://code.immerda.ch/immerda/puppet-modules/nftables", + "tags": [ + "firewall", + "security", + "nftables", + "iptables" + ], + "source": "https://github.com/voxpupuli/puppet-nftables.git", + "project_page": "https://github.com/voxpupuli/puppet-nftables", + "issues_url": "https://github.com/voxpupuli/puppet-nftables/issues", "dependencies": [ { "name": "puppetlabs/concat", @@ -43,10 +50,7 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 4.10.0 < 7.0.0" + "version_requirement": ">= 5.10.0 < 7.0.0" } - ], - "pdk-version": "1.18.1", - "template-url": "https://github.com/puppetlabs/pdk-templates#1.18.1", - "template-ref": "tags/1.18.1-0-g3d2e75c" + ] } diff --git a/spec/default_facts.yml b/spec/default_facts.yml deleted file mode 100644 index f777abfc..00000000 --- a/spec/default_facts.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Use default_module_facts.yml for module specific facts. -# -# Facts specified here will override the values provided by rspec-puppet-facts. ---- -ipaddress: "172.16.254.254" -ipaddress6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" -is_pe: false -macaddress: "AA:AA:AA:AA:AA:AA" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d3778cac..59041394 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,57 +1,22 @@ -# frozen_string_literal: true +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config -require 'puppetlabs_spec_helper/module_spec_helper' -require 'rspec-puppet-facts' - -require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) - -include RspecPuppetFacts - -default_facts = { - puppetversion: Puppet.version, - facterversion: Facter.version, -} - -default_fact_files = [ - File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), - File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), -] - -default_fact_files.each do |f| - next unless File.exist?(f) && File.readable?(f) && File.size?(f) - - begin - default_facts.merge!(YAML.safe_load(File.read(f), [], [], true)) - rescue => e - RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" - end +RSpec.configure do |c| + c.mock_with :mocha end -# read default_facts and merge them over what is provided by facterdb -default_facts.each do |fact, value| - add_custom_fact fact, value -end +# puppetlabs_spec_helper will set up coverage if the env variable is set. +# We want to do this if lib exists and it hasn't been explicitly set. +ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../../lib', __FILE__)) -RSpec.configure do |c| - c.default_facts = default_facts - c.before :each do - # set to strictest setting for testing - # by default Puppet runs at warning level - Puppet.settings[:strict] = :warning - Puppet.settings[:strict_variables] = true - end - c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] - c.after(:suite) do - end -end +require 'voxpupuli/test/spec_helper' -# Ensures that a module is defined -# @param module_name Name of the module -def ensure_module_defined(module_name) - module_name.split('::').reduce(Object) do |last_module, next_module| - last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) - last_module.const_get(next_module, false) +if File.exist?(File.join(__dir__, 'default_module_facts.yml')) + facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml'))) + if facts + facts.each do |name, value| + add_custom_fact name.to_sym, value + end end end - -# 'spec_overrides' from sync.yml will appear below this line