diff --git a/.fixtures.yml b/.fixtures.yml index 363bd7bc..bec78954 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,8 +1,7 @@ fixtures: forge_modules: stdlib: "puppetlabs/stdlib" - concat: - repo: "puppetlabs/concat" - ref: "2.2.0" + translate: "puppetlabs/translate" + concat: "puppetlabs/concat" symlinks: dns: "#{source_dir}" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..9032a014 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.rb eol=lf +*.erb eol=lf +*.pp eol=lf +*.sh eol=lf +*.epp eol=lf diff --git a/.gitignore b/.gitignore index 9bc50430..650022e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,24 @@ -vendor/ -.bundle -.*.sw? -pkg -.rspec_system -.vagrant -/.project -log/ -spec/fixtures/modules/ -/*.lock +.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 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..ea59806f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,42 @@ +--- +stages: + - syntax + - unit + +cache: + paths: + - vendor/bundle + +before_script: + - bundle -v + - rm Gemfile.lock || true + - gem update --system $RUBYGEMS_VERSION + - gem --version + - bundle -v + - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) + +parallel_spec-Ruby 2.1.9-Puppet ~> 4.0: + stage: unit + image: ruby:2.1.9 + script: + - bundle exec rake parallel_spec + variables: + PUPPET_GEM_VERSION: '~> 4.0' + RUBYGEMS_VERSION: '2.7.8' + +syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop-Ruby 2.4.4-Puppet ~> 5.5: + stage: syntax + image: ruby:2.4.4 + script: + - bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop + variables: + PUPPET_GEM_VERSION: '~> 5.5' + +parallel_spec-Ruby 2.4.4-Puppet ~> 5.5: + stage: unit + image: ruby:2.4.4 + script: + - bundle exec rake parallel_spec + variables: + PUPPET_GEM_VERSION: '~> 5.5' + diff --git a/.pdkignore b/.pdkignore new file mode 100644 index 00000000..b713b3b1 --- /dev/null +++ b/.pdkignore @@ -0,0 +1,37 @@ +.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 +/appveyor.yml +/.fixtures.yml +/Gemfile +/.gitattributes +/.gitignore +/.gitlab-ci.yml +/.pdkignore +/Rakefile +/.rspec +/.rubocop.yml +/.travis.yml +/.yardopts +/spec/ diff --git a/.puppet-lint.rc b/.puppet-lint.rc new file mode 100644 index 00000000..cc96ece0 --- /dev/null +++ b/.puppet-lint.rc @@ -0,0 +1 @@ +--relative diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..16f9cdb0 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..f5a6c2a4 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,122 @@ +--- +require: rubocop-rspec +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/DecorateString: + Description: We don't want to decorate test output. + Exclude: + - spec/* +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/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 +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 diff --git a/.sync.yml b/.sync.yml new file mode 100644 index 00000000..bb6298de --- /dev/null +++ b/.sync.yml @@ -0,0 +1,19 @@ +--- + +Gemfile: + required: + ':acceptance': + - gem: 'rspec-puppet-facts' + - gem: 'optimist' + - gem: 'beaker' + version: '~>4.0' + - gem: 'beaker-puppet' + - gem: 'beaker-docker' + - gem: 'beaker-module_install_helper' + - gem: 'beaker-puppet_install_helper' + - gem: 'beaker-pe' + - gem: 'beaker-rspec' + - gem: 'beaker-task_helper' + - gem: 'beaker-vagrant' + version: '0.5.0' + - gem: 'vagrant-wrapper' diff --git a/.travis.yml b/.travis.yml index 69054435..521510d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,41 +1,43 @@ --- +dist: trusty language: ruby -bundler_args: --without development --jobs=3 --retry=3 - -sudo: false - +cache: bundler +before_install: + - bundle -v + - rm -f Gemfile.lock + - gem update --system $RUBYGEMS_VERSION + - gem --version + - bundle -v +script: + - 'bundle exec rake $CHECK' +bundler_args: --without system_tests rvm: - - 1.9.3 - - 2.0.0 - - 2.1 - + - 2.5.1 env: - - PUPPET_VERSION="~> 2.7.0" - - PUPPET_VERSION="~> 3.1.0" - - PUPPET_VERSION="~> 3.2.0" - - PUPPET_VERSION="~> 3.3.0" - - PUPPET_VERSION="~> 3.4.0" - - PUPPET_VERSION="~> 3.5.0" - -before_install: rm Gemfile.lock || true - -script: bundle exec rake test - + global: + - BEAKER_PUPPET_COLLECTION=puppet6 PUPPET_GEM_VERSION="~> 6.0" matrix: - exclude: - - rvm: 1.9.3 - env: PUPPET_VERSION="~> 2.7.0" - - rvm: 2.0.0 - env: PUPPET_VERSION="~> 2.7.0" - - rvm: 2.0.0 - env: PUPPET_VERSION="~> 3.1.0" - - rvm: 2.1 - env: PUPPET_VERSION="~> 2.7.0" - - rvm: 2.1 - env: PUPPET_VERSION="~> 3.1.0" - - rvm: 2.1 - env: PUPPET_VERSION="~> 3.2.0" - - rvm: 2.1 - env: PUPPET_VERSION="~> 3.3.0" - - rvm: 2.1 - env: PUPPET_VERSION="~> 3.4.0" + fast_finish: true + include: + - + env: CHECK="syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop" + - + env: CHECK=parallel_spec + - + env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec + rvm: 2.4.4 +branches: + only: + - master + - /^v\d/ +notifications: + email: false +deploy: + provider: puppetforge + user: puppet + password: + secure: "" + on: + tags: true + all_branches: true + condition: "$DEPLOY_TO_FORGE = yes" diff --git a/.yardopts b/.yardopts new file mode 100644 index 00000000..29c933bc --- /dev/null +++ b/.yardopts @@ -0,0 +1 @@ +--markup markdown diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29a9733a..f4a5e43c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,8 @@ Checklist - Fork the repository on GitHub. + - Install the [Puppet Development Kit(PDK)](https://puppet.com/docs/pdk/1.x/pdk_install.html) + - Make changes on a branch *with tests* - Run tests `bundle exec rake spec` @@ -26,54 +28,322 @@ Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby package manager such as [bundler](http://bundler.io/) what Ruby packages, or Gems, are required to build, develop, and test this software. -Please make sure you have [bundler installed](http://bundler.io/#getting-started) -on your system, then use it to install all dependencies needed for this project, +Please make sure you have [pdk installed](https://puppet.com/docs/pdk/1.x/pdk_install.html) +on your system. PDK uses it's own version of [bundler included](http://bundler.io) +in its installation, which can be used to install all dependencies needed for this project, by running ```shell -% bundle install -Fetching gem metadata from https://rubygems.org/........ -Fetching gem metadata from https://rubygems.org/.. -Using rake (10.1.0) -Using builder (3.2.2) --- 8><-- many more --><8 -- -Using rspec-system-puppet (2.2.0) -Using serverspec (0.6.3) -Using rspec-system-serverspec (1.0.0) -Using bundler (1.3.5) -Your bundle is complete! -Use `bundle show [gemname]` to see where a bundled gem is installed. +% pdk bundle install +pdk (INFO): Using Ruby 2.5.1 +pdk (INFO): Using Puppet 6.0.2 +Fetching https://github.com/skywinder/github-changelog-generator +The dependency puppet-module-win-default-r2.5 (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`. +The dependency puppet-module-win-dev-r2.5 (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`. +The dependency puppet-module-win-system-r2.5 (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`. +Fetching gem metadata from https://rubygems.org/......... +Resolving dependencies.... +Fetching rake 12.3.2 +Installing rake 12.3.2 +Fetching CFPropertyList 2.3.6 +Installing CFPropertyList 2.3.6 +Fetching concurrent-ruby 1.1.4 +Installing concurrent-ruby 1.1.4 +Fetching i18n 1.5.2 +Installing i18n 1.5.2 +Fetching minitest 5.11.3 +Installing minitest 5.11.3 +Fetching thread_safe 0.3.6 +Installing thread_safe 0.3.6 +Fetching tzinfo 1.2.5 +Installing tzinfo 1.2.5 +Fetching activesupport 5.2.2 +Installing activesupport 5.2.2 +Using public_suffix 3.0.3 +Using addressable 2.5.2 +Using ansi 1.5.0 +Using ast 2.4.0 +Fetching aws-eventstream 1.0.1 +Installing aws-eventstream 1.0.1 +Fetching aws-partitions 1.133.0 +Installing aws-partitions 1.133.0 +Fetching aws-sigv4 1.0.3 +Installing aws-sigv4 1.0.3 +Fetching jmespath 1.4.0 +Installing jmespath 1.4.0 +Fetching aws-sdk-core 3.46.0 +Installing aws-sdk-core 3.46.0 +Fetching aws-sdk-ec2 1.66.0 +Installing aws-sdk-ec2 1.66.0 +Fetching deep_merge 1.2.1 +Installing deep_merge 1.2.1 +Fetching stringify-hash 0.0.2 +Installing stringify-hash 0.0.2 +Fetching beaker-hostgenerator 1.1.25 +Installing beaker-hostgenerator 1.1.25 +Using hocon 1.2.5 +Fetching in-parallel 0.1.17 +Installing in-parallel 0.1.17 +Fetching inifile 3.0.0 +Installing inifile 3.0.0 +Fetching minitar 0.8 +Installing minitar 0.8 +Using net-ssh 4.2.0 +Using net-scp 1.2.1 +Fetching open_uri_redirections 0.2.1 +Installing open_uri_redirections 0.2.1 +Using byebug 9.0.6 +Using coderay 1.1.2 +Using method_source 0.8.2 +Using slop 3.6.0 +Using pry 0.10.4 +Fetching pry-byebug 3.4.3 +Installing pry-byebug 3.4.3 +Fetching rb-readline 0.5.5 +Installing rb-readline 0.5.5 +Fetching rsync 1.0.9 +Installing rsync 1.0.9 +Using thor 0.20.3 +Fetching beaker 4.4.0 +Installing beaker 4.4.0 +Fetching beaker-abs 0.5.0 +Installing beaker-abs 0.5.0 +Fetching require_all 1.3.3 +Installing require_all 1.3.3 +Fetching beaker-answers 0.25.0 +Installing beaker-answers 0.25.0 +Fetching beaker-aws 0.8.1 +Installing beaker-aws 0.8.1 +Fetching excon 0.62.0 +Installing excon 0.62.0 +Using multi_json 1.13.1 +Fetching docker-api 1.34.2 +Installing docker-api 1.34.2 +Fetching beaker-docker 0.5.1 +Installing beaker-docker 0.5.1 +Fetching multipart-post 2.0.0 +Installing multipart-post 2.0.0 +Fetching faraday 0.15.4 +Installing faraday 0.15.4 +Fetching jwt 2.1.0 +Installing jwt 2.1.0 +Fetching memoist 0.16.0 +Installing memoist 0.16.0 +Fetching os 1.0.0 +Installing os 1.0.0 +Fetching signet 0.11.0 +Installing signet 0.11.0 +Fetching googleauth 0.8.0 +Installing googleauth 0.8.0 +Using httpclient 2.8.3 +Using mime-types-data 3.2018.0812 +Using mime-types 3.2.2 +Fetching declarative 0.0.10 +Installing declarative 0.0.10 +Fetching declarative-option 0.1.0 +Installing declarative-option 0.1.0 +Fetching uber 0.1.0 +Installing uber 0.1.0 +Fetching representable 3.0.4 +Installing representable 3.0.4 +Fetching retriable 3.1.2 +Installing retriable 3.1.2 +Fetching google-api-client 0.27.3 +Installing google-api-client 0.27.3 +Fetching beaker-google 0.1.0 +Installing beaker-google 0.1.0 +Fetching beaker-i18n_helper 1.1.0 +Installing beaker-i18n_helper 1.1.0 +Fetching beaker-module_install_helper 0.1.7 +Installing beaker-module_install_helper 0.1.7 +Fetching builder 3.2.3 +Installing builder 3.2.3 +Using formatador 0.2.5 +Fetching fog-core 2.1.2 +Installing fog-core 2.1.2 +Fetching fog-json 1.2.0 +Installing fog-json 1.2.0 +Fetching ipaddress 0.8.3 +Installing ipaddress 0.8.3 +Fetching fog-openstack 1.0.7 +Installing fog-openstack 1.0.7 +Fetching beaker-openstack 0.2.0 +Installing beaker-openstack 0.2.0 +Using ruby-ll 2.1.2 +Using oga 2.15 +Fetching beaker-puppet 1.14.0 +Installing beaker-puppet 1.14.0 +Fetching beaker-vmpooler 1.3.1 +Installing beaker-vmpooler 1.3.1 +Fetching beaker-pe 2.0.6 +Installing beaker-pe 2.0.6 +Fetching beaker-puppet_install_helper 0.9.7 +Installing beaker-puppet_install_helper 0.9.7 +Using rspec-support 3.8.0 +Using rspec-core 3.8.0 +Using diff-lcs 1.3 +Using rspec-expectations 3.8.2 +Using rspec-mocks 3.8.0 +Using rspec 3.8.0 +Fetching rspec-its 1.2.0 +Installing rspec-its 1.2.0 +Using net-telnet 0.1.1 +Using sfl 2.3 +Fetching specinfra 2.76.7 +Installing specinfra 2.76.7 +Fetching serverspec 2.41.3 +Installing serverspec 2.41.3 +Fetching beaker-rspec 6.2.4 +Installing beaker-rspec 6.2.4 +Fetching beaker-task_helper 1.7.2 +Installing beaker-task_helper 1.7.2 +Fetching beaker-vagrant 0.6.1 +Installing beaker-vagrant 0.6.1 +Fetching fission 0.5.0 +Installing fission 0.5.0 +Using json 2.1.0 +Fetching mini_portile2 2.4.0 +Installing mini_portile2 2.4.0 +Fetching nokogiri 1.10.1 +Installing nokogiri 1.10.1 with native extensions +Fetching trollop 2.9.9 +Installing trollop 2.9.9 +Fetching rbvmomi 1.13.0 +Installing rbvmomi 1.13.0 +Fetching beaker-vmware 0.3.0 +Installing beaker-vmware 0.3.0 +Fetching beaker-vcloud 1.0.0 +Installing beaker-vcloud 1.0.0 +Using bundler 1.16.6 +Using docile 1.3.1 +Using simplecov-html 0.10.2 +Using simplecov 0.16.1 +Using url 0.3.2 +Using codecov 0.1.14 +Using unf_ext 0.0.7.5 +Using unf 0.1.4 +Using domain_name 0.5.20180417 +Using facter 2.5.1 +Using jgrep 1.5.0 +Fetching facterdb 0.6.0 +Installing facterdb 0.6.0 +Fetching faraday-http-cache 2.0.0 +Installing faraday-http-cache 2.0.0 +Using fast_gettext 1.1.2 +Using locale 2.1.2 +Using text 1.3.1 +Using gettext 3.2.9 +Using gettext-setup 0.30 +Fetching sawyer 0.8.1 +Installing sawyer 0.8.1 +Fetching octokit 4.13.0 +Installing octokit 4.13.0 +Using rainbow 2.2.2 +Using github_changelog_generator 1.15.0.pre.rc from https://github.com/skywinder/github-changelog-generator (at 20ee04b@20ee04b) +Fetching hiera 3.5.0 +Installing hiera 3.5.0 +Using hirb 0.7.3 +Using http-cookie 1.0.3 +Using json-schema 2.8.1 +Fetching master_manipulator 2.1.1 +Installing master_manipulator 2.1.1 +Fetching stomp 1.4.8 +Installing stomp 1.4.8 +Using systemu 2.6.5 +Using mcollective-client 2.12.4 +Using metaclass 0.0.4 +Using spdx-licenses 1.2.0 +Using metadata-json-lint 2.2.0 +Using mocha 1.1.0 +Using netrc 0.11.0 +Fetching optimist 3.0.0 +Installing optimist 3.0.0 +Fetching parallel 1.13.0 +Installing parallel 1.13.0 +Using parallel_tests 2.14.2 +Using parser 2.5.1.2 +Fetching pathspec 0.2.1 +Installing pathspec 0.2.1 +Using powerpack 0.1.2 +Using puppet-resource_api 1.6.2 +Using semantic_puppet 1.0.2 +Using puppet 6.0.2 +Using rest-client 2.0.2 +Using puppet-blacksmith 4.1.2 +Using puppet-lint 2.3.6 +Fetching puppet-module-posix-default-r2.5 0.3.14 +Installing puppet-module-posix-default-r2.5 0.3.14 +Using rgen 0.8.2 +Using yard 0.9.16 +Using puppet-strings 2.1.0 +Using puppet-syntax 2.4.1 +Using puppet_pot_generator 1.0.1 +Using rspec-puppet 2.7.2 +Fetching puppetlabs_spec_helper 2.13.1 +Installing puppetlabs_spec_helper 2.13.1 +Using rspec-puppet-facts 1.9.2 +Using rspec_junit_formatter 0.4.1 +Using ruby-progressbar 1.10.0 +Fetching unicode-display_width 1.4.1 +Installing unicode-display_width 1.4.1 +Using rubocop 0.49.1 +Using rubocop-i18n 1.2.0 +Using rubocop-rspec 1.16.0 +Using simplecov-console 0.4.2 +Fetching puppet-module-posix-dev-r2.5 0.3.14 +Installing puppet-module-posix-dev-r2.5 0.3.14 +Fetching puppet-module-posix-system-r2.5 0.3.14 +Installing puppet-module-posix-system-r2.5 0.3.14 +Fetching vagrant-wrapper 2.0.3 +Installing vagrant-wrapper 2.0.3 +Bundle complete! 16 Gemfile dependencies, 166 gems now installed. +Use `bundle info [gemname]` to see where a bundled gem is installed. +Post-install message from i18n: + +HEADS UP! i18n 1.1 changed fallbacks to exclude default locale. +But that may break your application. + +Please check your Rails app for 'config.i18n.fallbacks = true'. +If you're using I18n (>= 1.1.0) and Rails (< 5.2.2), this should be +'config.i18n.fallbacks = [I18n.default_locale]'. +If not, fallbacks will be broken in your app by I18n 1.1.x. + +For more info see: +https://github.com/svenfuchs/i18n/releases/tag/v1.1.0 + +Post-install message from minitar: +The `minitar` executable is no longer bundled with `minitar`. If you are +expecting this executable, make sure you also install `minitar-cli`. +Post-install message from trollop: +! The 'trollop' gem has been deprecated and has been replaced by 'optimist'. +! See: https://rubygems.org/gems/optimist +! And: https://github.com/ManageIQ/optimist +NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2018-12-01. +Gem::Specification#default_executable= called from /home/peter/.pdk/cache/ruby/2.5.0/bundler/gems/github-changelog-generator-20ee04ba1234/github_changelog_generator.gemspec:10. ``` -NOTE some systems may require you to run this command with sudo. - - Running Tests ------------- ```shell -$ bundle exec rake spec -Cloning into 'spec/fixtures/modules/stdlib'... -remote: Counting objects: 5550, done. -remote: Total 5550 (delta 0), reused 0 (delta 0) -Receiving objects: 100% (5550/5550), 1.09 MiB | 271.00 KiB/s, done. -Resolving deltas: 100% (2302/2302), done. -Checking connectivity... done. -HEAD is now at 9e8127b Merge pull request #313 from mhaskel/spec_updates -Cloning into 'spec/fixtures/modules/concat'... -remote: Counting objects: 1467, done. -remote: Compressing objects: 100% (87/87), done. -remote: Total 1467 (delta 52), reused 2 (delta 0) -Receiving objects: 100% (1467/1467), 319.82 KiB | 256.00 KiB/s, done. -Resolving deltas: 100% (688/688), done. -..................................................................... - -Finished in 4.59 seconds -69 examples, 0 failures - -Total resources: 72 -Touched resources: 22 -Resource coverage: 30.56% +$ pdk test unit +pdk (INFO): Using Ruby 2.5.1 +pdk (INFO): Using Puppet 6.0.2 +[✔] Preparing to run the unit tests. +[✔] Running unit tests. +``` + +Individual tests can be listed by running: + +```shell +$ pdk bundle exec rake -T +``` + + +Test can then be executed by running: + +```shell +$ pdk bundle exec rake $INDIVDUALTEST ``` Writing Tests @@ -91,21 +361,21 @@ 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: - bundle exec rake beaker + pdk bundle exec rake beaker This will run the tests on an Ubuntu 12.04 virtual machine. You can also run the integration tests against Centos 6.6 with: - BEAKER_set=centos-66-x64 bundle exec rake beaker + pdk bundle exec rake beaker:centos-66-x64 Or with Ubuntu 12.04 with: - BEAKER_set=ubuntu-server-12-x64 bundle exec rake beaker + pdk bundle exec rake beaker:ubuntu-server-12-x64 If you need to inspect a vm manually afterwards, you can ask beaker to not destroy the box: - bundle exec rake BEAKER_destroy=no beaker + BEAKER_destroy=no pdk bundle exec rake beaker Then vagrant ssh to the box that was left behind diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..61019a6f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM puppet/puppet-agent +MAINTAINER peter@pouliot.net + +RUN mkdir -p /etc/puppetlabs/code/modules/dns +COPY . /etc/puppetlabs/code/modules/dns/ +COPY Puppetfile /etc/puppetlabs/code/environments/production/Puppetfile +COPY Dockerfile Dockerfile + +RUN \ + apt-get update -y && apt-get install git curl software-properties-common -y \ + && gem install r10k \ + && cd /etc/puppetlabs/code/environments/production/ \ + && r10k puppetfile install --verbose DEBUG2 \ + && mkdir -p /var/lock/named /var/run/named \ + && puppet module list \ + && puppet module list --tree \ + && puppet apply --debug --trace --verbose --modulepath=/etc/puppetlabs/code/modules:/etc/puppetlabs/code/environments/production/modules /etc/puppetlabs/code/modules/dns/examples/init.pp +RUN \ + echo "**** Verifying that the BIND Configuration ****" \ + && /usr/sbin/named-checkconf diff --git a/Gemfile b/Gemfile index 5cb812fb..2d4cf58c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,27 +1,86 @@ -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 +end + +ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments +minor_version = ruby_version_segments[0..1].join('.') group :development do - gem "beaker", "> 2.0.0" - gem "beaker-rspec", ">= 5.1.0" - gem "pry" - gem "puppet-blacksmith" - gem "serverspec" - gem "vagrant-wrapper" + 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 "puppet-module-posix-default-r#{minor_version}", require: false, platforms: [:ruby] + gem "puppet-module-posix-dev-r#{minor_version}", require: false, platforms: [:ruby] + gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "puppet-module-win-dev-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] +end + +group :acceptance do + gem 'rspec-puppet-facts' + gem 'optimist' + gem 'beaker', '~>4.0' + gem 'beaker-puppet' + gem 'beaker-docker' + gem 'beaker-module_install_helper' + gem 'beaker-puppet_install_helper' + gem 'beaker-pe' + gem 'beaker-rspec' + gem 'beaker-task_helper' + gem 'beaker-vagrant', '0.5.0' + gem 'vagrant-wrapper' +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] +end + +gems.each do |gem_name, gem_params| + gem gem_name, *gem_params end -group :test do - gem "json" - gem "json_pure", "~> 1.8.3" - # Pin for 1.8.7 compatibility for now - gem "rake", '< 11.0.0' - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.7.0' - gem "puppet-lint" - - # Pin for 1.8.7 compatibility for now - gem "rspec", '< 3.2.0' - gem "rspec-core", "3.1.7" - gem "rspec-puppet", "< 2.6.0" - - gem "puppet-syntax" - gem "puppetlabs_spec_helper", "< 2.1.1" +# Evaluate Gemfile.local and ~/.gemfile if they exist +extra_gemfiles = [ + "#{__FILE__}.local", + File.join(Dir.home, '.gemfile'), +] + +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/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..b6b49d8f --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,123 @@ +def SUFFIX = '' + +pipeline { + agent any + + parameters { + string (name: 'VERSION_PREFIX', defaultValue: '0.0.0', description: 'puppet-dns version') + } + environment { + BUILD_TAG = "${env.BUILD_TAG}".replaceAll('%2F','_') + BRANCH = "${env.BRANCH_NAME}".replaceAll('/','_') + BEAKER_PUPPET_COLLECTION = "puppet6" + BEAKER_PUPPET_VERSION = "6" + } + options { + buildDiscarder(logRotator(numToKeepStr: '30')) + } + stages { + stage ('Use the Puppet Development Bundle Install to install missing gem dependencies') { + steps { + sh 'pdk bundle install 2> /dev/null' + } + } + + stage ('Use the Puppet Development Kit Validation to Check for Linting Errors') { + when { + expression { + currentBuild.result == null || currentBuild.result == 'SUCCESS' + } + } + steps { + sh 'pdk validate' + } + } + + stage ('Use the Puppet Development Kit Test Unit for Module Unit Testing') { + when { + expression { + currentBuild.result == null || currentBuild.result == 'SUCCESS' + } + } + steps { + sh 'pdk test -d unit' + } + } + + stage ('Use the Puppet Development Kit To run Rake/Rspec Unit Tests') { + when { + expression { + currentBuild.result == null || currentBuild.result == 'SUCCESS' + } + } + steps { + sh 'pdk bundle exec rake spec' + } + } + + stage ('Use the Puppet Development Kit To run Beaker Acceptance Tests') { + when { + expression { + currentBuild.result == null || currentBuild.result == 'SUCCESS' + } + } + steps { + sh 'pdk bundle exec rake beaker:default' + } + } + + stage ('Cleanup Acceptance Tests after successful build, and prepare for release.') { + when { + expression { + currentBuild.result == null || currentBuild.result == 'SUCCESS' + } + } + steps { + sh 'pdk bundle exec rake module:clean' + } + } +// Comment out remaining bits untill we figure out the exact process we want here +/* + stage ('Build Puppet module files') { + steps { + sh 'pdk bundle exec rake build:pdk' + } + } + + stage ('Tag puppet module files') { + steps { + sh 'pdk bundle exec rake module:tag' + } + } + + stage ('Push puppet module files') { + steps { + sh 'pdk bundle exec rake module:push' + } + } + + stage ('Bump version and Commit puppet module files') { + steps { + sh 'pdk bundle exec rake module:bump_commit' + } + } + + stage ('Code signing') { + steps { + sh 'echo "Do we need to add Code Signing for puppet modules?"' + } + } + + stage ('Upload to GitHub') { + steps { + sh 'git push origin' + } + } +*/ + stage ('Clean Workspace') { + steps { + cleanWs() + } + } + } +} diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..b72c5161 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2018-2019 Peter J. Pouliot, peter@pouliot.net + +Copyright (c) 2012-2017 Adam Jahn, David Danzilio, Kyle Anderson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/Puppetfile b/Puppetfile new file mode 100644 index 00000000..5e5b9d35 --- /dev/null +++ b/Puppetfile @@ -0,0 +1,8 @@ +forge 'https://forge.puppet.com' +mod 'puppetlabs/concat', :latest +mod 'puppetlabs/stdlib', :latest +mod 'puppetlabs/translate', :latest +# Currently Using Downstream due to processing issues. +#mod 'ajjahn/dns', +# :git => 'https://github.com/ppouliot/puppet-dns', +# :branch => 'master' diff --git a/README.md b/README.md index df366fc2..8e8f0074 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,9 @@ Module for provisioning DNS (bind9) Supports: +* Debian: 9, 8 * Ubuntu: 14.04, 12.04 -* CentOS: 7.x, 6.x +* CentOS/ScientificLinux/OracleLinux: 7.x, 6.x Patches to support other operating systems are welcome. @@ -193,8 +194,9 @@ node 'ns1.xkyle.com' { ## Authors Note: This module is a merge of the work from the following authors: -* [ajjahn](https://github.com/ajjahn/puppet-dns) +* [ajjahn](https://github.com/ajjahn) * [Danzilio](https://github.com/danzilio) +* [ppouliot](https://github.com/ppouliot) * [solarkennedy](https://github.com/solarkennedy) ## License diff --git a/Rakefile b/Rakefile index dc9b656a..a6b14c56 100644 --- a/Rakefile +++ b/Rakefile @@ -1,42 +1,76 @@ require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' 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? -# These two gems aren't always present, for instance -# on Travis with --without development -begin - require 'puppetlabs_spec_helper/rake_tasks' - require 'puppet_blacksmith/rake_tasks' -rescue LoadError +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 end -PuppetLint.configuration.send("disable_80chars") -PuppetLint.configuration.log_format = "%{path}:%{line}:%{check}:%{KIND}:%{message}" +def changelog_project + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = nil || JSON.load(File.read('metadata.json'))['name'] + raise "unable to find the changelog_project in .sync.yml or the name in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator project:#{returnVal}" + returnVal +end -# Forsake support for Puppet 2.6.2 for the benefit of cleaner code. -# http://puppet-lint.com/checks/class_parameter_defaults/ -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_class_parameter_defaults') -# http://puppet-lint.com/checks/class_inherits_from_params_class/ -PuppetLint.configuration.send('disable_class_inherits_from_params_class') +def changelog_future_release + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = 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 +end -exclude_paths = [ - "pkg/**/*", - "vendor/**/*", - "spec/**/*", -] -PuppetLint.configuration.ignore_paths = exclude_paths -PuppetSyntax.exclude_paths = exclude_paths +PuppetLint.configuration.send('disable_relative') -ENV['BEAKER_set'] ||= 'ubuntu-server-1204-x86' -desc "Run acceptance tests" -RSpec::Core::RakeTask.new(:acceptance) do |t| - t.pattern = 'spec/acceptance' +if Bundler.rubygems.find_name('github_changelog_generator').any? + 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; GO LABEL THEM" + config.configure_sections = { + "Changed" => { + "prefix" => "### Changed", + "labels" => ["backwards-incompatible"], + }, + "Added" => { + "prefix" => "### Added", + "labels" => ["feature", "enhancement"], + }, + "Fixed" => { + "prefix" => "### Fixed", + "labels" => ["bugfix"], + }, + } + end +else + desc 'Generate a Changelog from GitHub' + task :changelog do + raise <= Gem::Version.new('2.2.2')" +EOM + end end -desc "Run syntax, lint, and spec tests." -task :test => [ - :syntax, - :lint, - :spec, -] diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..1746ebf8 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,38 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : +# +required_plugins = %w(vagrant-scp vagrant-puppet-install vagrant-vbguest) + +plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin } +if not plugins_to_install.empty? + puts "Installing plugins: #{plugins_to_install.join(' ')}" + if system "vagrant plugin install #{plugins_to_install.join(' ')}" + exec "vagrant #{ARGV.join(' ')}" + else + abort "Installation of one or more plugins has failed. Aborting." + end +end + +Vagrant.configure("2") do |config| + config.vm.synced_folder ".", "/etc/puppetlabs/code/modules/dns", :mount_options => ['dmode=775','fmode=777'] + config.vm.provider "virtualbox" do |v| + v.customize ["modifyvm", :id, "--memory", "2048"] + v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + v.linked_clone = true + end + config.puppet_install.puppet_version = "5.5.7" + config.vm.provision "shell", inline: "/opt/puppetlabs/puppet/bin/gem install r10k hiera-eyaml" + config.vm.provision "shell", inline: "curl -o /etc/puppetlabs/code/environments/production/Puppetfile https://raw.githubusercontent.com/ppouliot/puppet-dns/master/Puppetfile" + config.vm.provision "shell", inline: "cd /etc/puppetlabs/code/environments/production && /opt/puppetlabs/puppet/bin/r10k puppetfile install --verbose DEBUG2" + config.vm.provision "shell", inline: "/opt/puppetlabs/bin/puppet module list --tree" + config.vm.provision "shell", inline: "/opt/puppetlabs/bin/puppet apply --debug --trace --verbose --modulepath=/etc/puppetlabs/code/modules:/etc/puppetlabs/code/environments/production/modules /etc/puppetlabs/code/modules/dns/examples/init.pp" + # IPAM1 Definition + config.vm.define "dns1" do |v| +# v.vm.box = "centos/7" +# v.vm.box = "debian/jessie64" + v.vm.box = "ubuntu/xenial64" + v.vm.hostname = "dns1.contoso.ltd" + v.vm.network "private_network", ip: "192.168.0.2", nic_type: "virtio" + end + +end diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..e10ba3bf --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,55 @@ +--- +version: 1.1.x.{build} +branches: + only: + - master +skip_commits: + message: /^\(?doc\)?.*/ +clone_depth: 10 +init: + - SET + - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0' +environment: + matrix: + - + RUBY_VERSION: 24-x64 + CHECK: syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop + - + PUPPET_GEM_VERSION: ~> 5.0 + RUBY_VERSION: 24 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 5.0 + RUBY_VERSION: 24-x64 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 6.0 + RUBY_VERSION: 25 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 6.0 + RUBY_VERSION: 25-x64 + CHECK: parallel_spec +matrix: + fast_finish: true +install: + - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% + - bundle install --jobs 4 --retry 2 --without system_tests + - type Gemfile.lock +build: off +test_script: + - bundle exec puppet -V + - ruby -v + - gem -v + - bundle -v + - bundle exec rake %CHECK% +notifications: + - provider: Email + to: + - nobody@nowhere.com + on_build_success: false + on_build_failure: false + on_build_status_changed: false diff --git a/tests/init.pp b/examples/init.pp similarity index 100% rename from tests/init.pp rename to examples/init.pp diff --git a/manifests/acl.pp b/manifests/acl.pp index bc6ce80d..9189f452 100644 --- a/manifests/acl.pp +++ b/manifests/acl.pp @@ -1,28 +1,29 @@ -# defined type allows you to declare a BIND ACL. +# @summary +# defined type allows you to declare a BIND ACL. # -# Parameters: -# -# $ensure = ensure the persence or absence of the acl. -# $aclname = the name given to the ACL. This must be unique. This defaults to +# @param [String] ensure +# ensure the persence or absence of the acl. +# @param [String] aclname +# the name given to the ACL. This must be unique. This defaults to # the namevar. -# $data = an array of IP addresses or subnets using CIDR notation. -# -# Usage: +# @parm [array] data +# an array of IP addresses or subnets using CIDR notation. # -# dns::acl { 'trusted': -# ensure => present, -# data => [ '10.0.0.0/8', '172.16.2.0/24', ] -# } +# @example +# dns::acl { 'trusted': +# ensure => present, +# data => [ '10.0.0.0/8', '172.16.2.0/24', ] +# } # define dns::acl ( - $ensure = present, - $aclname = $name, - $data = [], + String $ensure = present, + String $aclname = $name, + Array $data = [], ) { include dns::server::params - validate_string($aclname) - validate_array($data) + assert_type(String, $aclname) + assert_type(Array, $data) concat::fragment { "named.conf.local.acl.${name}.include": target => "${dns::server::params::cfg_dir}/named.conf.local", diff --git a/manifests/key.pp b/manifests/key.pp index f79e0591..1921b801 100644 --- a/manifests/key.pp +++ b/manifests/key.pp @@ -1,4 +1,5 @@ -# == Class define::key +# @summary +# Class define::key # define dns::key { include dns::server::params @@ -15,7 +16,7 @@ command => "/usr/sbin/dnssec-keygen -a HMAC-MD5 -r /dev/urandom -b 128 -n USER ${name}", cwd => "${cfg_dir}/bind.keys.d", require => [ - Package['dnssec-tools'], + Package[$dns::server::params::necessary_packages], File["${cfg_dir}/bind.keys.d"], ], refreshonly => true, diff --git a/manifests/member.pp b/manifests/member.pp index da995365..614de38b 100644 --- a/manifests/member.pp +++ b/manifests/member.pp @@ -1,4 +1,5 @@ -# == Class dns::member +# @summary +# Class dns::member # define dns::member ($domain, $hostname, $ipaddress) { dns::record::a { $hostname: diff --git a/manifests/record.pp b/manifests/record.pp index 71c03b71..1f3ec7f7 100644 --- a/manifests/record.pp +++ b/manifests/record.pp @@ -1,17 +1,18 @@ # == Define dns::record # -# This is a private class to arbitary dns records. +# @api private +# This is a private class to arbitary dns records. # define dns::record ( - $zone, - $host, - $data, - $record = 'A', - $dns_class = 'IN', - $ttl = '', - $preference = false, - $order = 9, - $data_dir = $::dns::server::params::data_dir, + Variant[String, Tuple] $zone, + Variant[Stdlib::Host, String] $host, + Variant[String, Tuple] $data, + String $record = 'A', + String $dns_class = 'IN', + Variant[String, Integer] $ttl = '', + Variant[Boolean, Integer] $preference = false, + Integer $order = 9, + Stdlib::Absolutepath $data_dir = $::dns::server::params::data_dir, ) { $zone_file_stage = "${data_dir}/db.${zone}.stage" diff --git a/manifests/record/a.pp b/manifests/record/a.pp index c6e8273d..faa24179 100644 --- a/manifests/record/a.pp +++ b/manifests/record/a.pp @@ -4,12 +4,12 @@ # also setting a PTR at the same time. # define dns::record::a ( - $zone, - $data, - $ttl = '', - $ptr = false, - $host = $name, - $data_dir = $::dns::server::config::data_dir, + Variant[String, Tuple] $data, + Variant[Stdlib::Host, Tuple] $zone, + Variant[Stdlib::Host, String] $host = $name, + String $ttl = '', + Variant[Boolean, Enum['true', 'false', 'all', 'first']] $ptr = false, # lint:ignore:quoted_booleans + Stdlib::Absolutepath $data_dir = $::dns::server::config::data_dir, ) { $alias = "${name},A,${zone}" diff --git a/manifests/record/aaaa.pp b/manifests/record/aaaa.pp index 04de0873..6db4f483 100644 --- a/manifests/record/aaaa.pp +++ b/manifests/record/aaaa.pp @@ -3,11 +3,11 @@ # Wrapper of dns::record to set AAAA records # define dns::record::aaaa ( - $zone, - $data, - $ttl = '', - $host = $name, - $data_dir = $::dns::server::config::data_dir, + Variant[String, Tuple] $data, + Variant[Stdlib::Host, Tuple] $zone, + Variant[Stdlib::Host, String] $host = $name, + String $ttl = '', + Stdlib::Absolutepath $data_dir = $::dns::server::config::data_dir, ) { $alias = "${name},AAAA,${zone}" diff --git a/manifests/record/cname.pp b/manifests/record/cname.pp index 4f6c6a3a..cb91e659 100644 --- a/manifests/record/cname.pp +++ b/manifests/record/cname.pp @@ -5,8 +5,8 @@ define dns::record::cname ( $zone, $data, - $ttl = '', - $host = $name, + $ttl = '', + $host = $name, $data_dir = $::dns::server::config::data_dir, ) { diff --git a/manifests/record/mx.pp b/manifests/record/mx.pp index 07333188..ece86178 100644 --- a/manifests/record/mx.pp +++ b/manifests/record/mx.pp @@ -3,19 +3,19 @@ # Wrapper for dns::record to set an MX record. # define dns::record::mx ( - $zone, - $data, - $ttl = '', - $preference = 10, - $host = '@', - $data_dir = $::dns::server::config::data_dir, + Stdlib::Host $zone, + Stdlib::Fqdn $data, + Variant[Stdlib::Host, String] $host = '@', + String $ttl = '', + Variant[Boolean, Integer] $preference = 10, + Stdlib::Absolutepath $data_dir = $::dns::server::config::data_dir, ) { $alias = "${name},${zone},MX,${preference},${data}" - validate_string($zone) - validate_string($data) - validate_string($host) + assert_type(String, $zone ) + assert_type(String, $data ) + assert_type(String, $host ) if !is_domain_name($zone) or $zone =~ /^[0-9\.]+$/ { fail("Define[dns::record::mx]: MX zone ${zone} must be a valid domain name.") diff --git a/manifests/record/ns.pp b/manifests/record/ns.pp index dad63e43..0e9dd6be 100644 --- a/manifests/record/ns.pp +++ b/manifests/record/ns.pp @@ -3,18 +3,18 @@ # Wrapper of dns::record to set NS records # define dns::record::ns ( - $zone, - $data, - $ttl = '', - $host = $name, - $data_dir = $::dns::server::config::data_dir, + Variant[String, Tuple] $data, + Stdlib::Fqdn $zone, + Stdlib::Host $host = $name, + String $ttl = '', + Stdlib::Absolutepath $data_dir = $::dns::server::config::data_dir, ) { $alias = "${host},${zone},NS,${data}" - validate_string($zone) - validate_string($data) - validate_string($host) + validate_legacy(String, 'validate_string', $zone) + validate_legacy(String, 'validate_string', $data) + validate_legacy(String, 'validate_string', $host) if !is_domain_name($zone) or $zone =~ /^[0-9\.]+$/ { fail("Define[dns::record::ns]: NS zone ${zone} must be a valid domain name.") diff --git a/manifests/record/ptr.pp b/manifests/record/ptr.pp index ed7a157c..c01aa073 100644 --- a/manifests/record/ptr.pp +++ b/manifests/record/ptr.pp @@ -5,8 +5,8 @@ define dns::record::ptr ( $zone, $data, - $ttl = '', - $host = $name, + $ttl = '', + $host = $name, $data_dir = $::dns::server::config::data_dir, ) { diff --git a/manifests/record/ptr/by_ip.pp b/manifests/record/ptr/by_ip.pp index 37d91a95..416d067d 100644 --- a/manifests/record/ptr/by_ip.pp +++ b/manifests/record/ptr/by_ip.pp @@ -110,6 +110,7 @@ } if $zone != undef and $zone != '' { + Stdlib::Fqdn($zone) if $host == '@' { $fqdn = $zone } else { diff --git a/manifests/record/srv.pp b/manifests/record/srv.pp index 1b983c33..9c079206 100644 --- a/manifests/record/srv.pp +++ b/manifests/record/srv.pp @@ -3,15 +3,15 @@ # Wrapper for dns::zone to set SRV records # define dns::record::srv ( - $zone, - $service, - $pri, - $weight, - $port, - $target, - $proto = 'tcp', - $ttl = '', - $data_dir = $::dns::server::config::data_dir, + String $zone, + String $service, + String $pri, + String $weight, + String $port, + String $target, + String $proto = 'tcp', + String $ttl = '', + String $data_dir = $::dns::server::config::data_dir, ) { $alias = "${service}:${proto}@${target}:${port},${pri},${weight},SRV,${zone}" diff --git a/manifests/record/txt.pp b/manifests/record/txt.pp index e482ef3e..a653acc7 100644 --- a/manifests/record/txt.pp +++ b/manifests/record/txt.pp @@ -66,11 +66,11 @@ # define dns::record::txt ( - $zone, + Variant[Stdlib::Compat::String, String] $zone, $data, - $ttl = '', - $host = $name, - $data_dir = $::dns::server::config::data_dir, + String $ttl = '', + Stdlib::Host $host = $name, + Stdlib::Absolutepath $data_dir = $::dns::server::config::data_dir, ) { $alias = "${name},TXT,${zone}" diff --git a/manifests/server.pp b/manifests/server.pp index fecdcfb0..d4a1ec59 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -1,23 +1,21 @@ # == Class dns::server # class dns::server ( - $service = $dns::server::params::service, - - $necessary_packages = $dns::server::params::necessary_packages, - $ensure_packages = $dns::server::params::ensure_packages, - - $cfg_dir = $dns::server::params::cfg_dir, - $cfg_file = $dns::server::params::cfg_file, - $data_dir = $dns::server::params::data_dir, - $owner = $dns::server::params::owner, - $group = $dns::server::params::group, - - $enable_default_zones = true, + String $service = $dns::server::params::service, + Array $necessary_packages = $dns::server::params::necessary_packages, + $ensure_packages = $dns::server::params::ensure_packages, + Stdlib::Absolutepath $cfg_dir = $dns::server::params::cfg_dir, + Stdlib::Absolutepath $cfg_file = $dns::server::params::cfg_file, + Stdlib::Absolutepath $data_dir = $dns::server::params::data_dir, + String $owner = $dns::server::params::owner, + String $group = $dns::server::params::group, + Boolean $enable_default_zones = true, ) inherits dns::server::params { class { 'dns::server::install': necessary_packages => $necessary_packages, ensure_packages => $ensure_packages, - } -> class { 'dns::server::config': + } +->class { 'dns::server::config': cfg_dir => $cfg_dir, cfg_file => $cfg_file, data_dir => $data_dir, diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 2bc4cbf6..80f1eb55 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -1,12 +1,12 @@ # == Class dns::server # class dns::server::config ( - $cfg_dir = $dns::server::params::cfg_dir, - $cfg_file = $dns::server::params::cfg_file, - $data_dir = $dns::server::params::data_dir, - $owner = $dns::server::params::owner, - $group = $dns::server::params::group, - $enable_default_zones = true, + String $cfg_dir = $dns::server::params::cfg_dir, + String $cfg_file = $dns::server::params::cfg_file, + String $data_dir = $dns::server::params::data_dir, + String $owner = $dns::server::params::owner, + String $group = $dns::server::params::group, + Boolean $enable_default_zones = true, ) inherits dns::server::params { file { $cfg_dir: @@ -31,7 +31,7 @@ } file { $cfg_file: - ensure => present, + ensure => file, owner => $owner, group => $group, mode => '0644', @@ -47,13 +47,13 @@ owner => $owner, group => $group, mode => '0644', - notify => Class['dns::server::service'] + notify => Class['dns::server::service'], } concat::fragment{'named.conf.local.header': target => "${cfg_dir}/named.conf.local", order => 1, - content => "// File managed by Puppet.\n" + content => "// File managed by Puppet.\n", } # Configure default zones with a concat so we could add more zones in it @@ -71,6 +71,6 @@ content => template('dns/named.conf.default-zones.erb'), } - include dns::server::default + include ::dns::server::default } diff --git a/manifests/server/default.pp b/manifests/server/default.pp index 96b6f41a..9a097202 100644 --- a/manifests/server/default.pp +++ b/manifests/server/default.pp @@ -2,43 +2,64 @@ # class dns::server::default ( - $default_file = $dns::server::params::default_file, - $default_template = $dns::server::params::default_template, - - $resolvconf = undef, - $options = undef, - $rootdir = undef, - $enable_zone_write = undef, - $enable_sdb = undef, - $disable_named_dbus = undef, - $keytab_file = undef, - $disable_zone_checking = undef, + Stdlib::Absolutepath $default_file = $dns::server::params::default_file, + String $default_template = $dns::server::params::default_template, + Optional[String] $resolvconf = undef, + $options = undef, + Optional[Variant[Undef, String, Stdlib::Absolutepath]] $rootdir = undef, + Optional[Variant[Undef, String, Enum['yes','no']]] $enable_zone_write = undef, + Optional[String] $enable_sdb = undef, + Optional[Variant[Undef, String, Enum['yes','no']]] $disable_named_dbus = undef, + Optional[String] $keytab_file = undef, + Optional[String] $disable_zone_checking = undef, ) inherits dns::server::params { - - validate_absolute_path( $default_file ) + # TODO: Fix validation of absolutepath + # validate_legacy(String[Stdlib::Absolutepath], $default_file) + # validate_absolute_path($default_file) + # if ($default_file) =~ Stdlib::Absolutepath) { + # fail("String values aren't allowed") + #} if $resolvconf != undef { - validate_re( $resolvconf, '^(yes|no)$', 'The resolvconf value is not type of a string yes / no.' ) + assert_type(Pattern[/(^yes|no)$/], $resolvconf) | $a, $b| { + fail('The resolvconf value is not type of a string yes / no.' ) + } } if $rootdir != undef { + # TODO: Fix validation of absolutepath + # validate_legacy(String[Stdlib::Absolutepath], $rootdir) validate_absolute_path( $rootdir ) } if $enable_zone_write != undef { + # TODO: This needs work as it currently won't pass the unit tests + # assert_type(Pattern[/(^yes|no|\s*)$/], $enable_zone_write) | $a, $b| { + # fail( 'The enable_zone_writing value is not type of a string yes / no or empty.' ) + # } validate_re( $enable_zone_write, '^(yes|no|\s*)$', 'The enable_zone_write value is not type of a string yes / no or empty.' ) } if $enable_sdb != undef { + # TODO: This needs work as it currently won't pass the unit tests + # assert_type(Pattern[/(^yes|no|\s*)$/], $enable_sdb) | $a, $b| { + # fail( 'The enable_sdb value is not type of a string yes / no or empty.' ) + # } validate_re( $enable_sdb, '^(yes|no|1|0|\s*)$', 'The enable_sdb value is not type of a string yes / no / 1 / 0 or empty.' ) } if $keytab_file != undef { + # TODO: Fix validation of absolute path + # validate_legacy(String[Stdlib::Absolutepath], $keytab_file) validate_absolute_path( $keytab_file ) } if $disable_zone_checking != undef { + # TODO: This needs work as it currently won't pass the unit tests + # assert_type(Pattern[/(^yes|no|\s*)$/], $disable_zone_checking) | $a, $b| { + # fail( 'The disable_zone_checking value is not type of a string yes / no or empty.' ) + # } validate_re( $disable_zone_checking, '^(yes|no|\s*)$', 'The disable_zone_checking value is not type of a string yes / no or empty.' ) } diff --git a/manifests/server/options.pp b/manifests/server/options.pp index 2016a9c7..e1048af3 100644 --- a/manifests/server/options.pp +++ b/manifests/server/options.pp @@ -154,39 +154,44 @@ # forwarders => [ '8.8.8.8', '8.8.4.4' ], # } # -include dns::server::params define dns::server::options ( - $allow_query = [], - $allow_recursion = [], - $also_notify = [], - $check_names_master = undef, - $check_names_slave = undef, - $check_names_response = undef, - $control_channel_ip = undef, - $control_channel_port = undef, - $control_channel_allow = undef, - $data_dir = $::dns::server::params::data_dir, - $dnssec_validation = $::dns::server::params::default_dnssec_validation, - $dnssec_enable = $::dns::server::params::default_dnssec_enable, - $forward_policy = undef, - $forwarders = [], - $listen_on = [], - $listen_on_ipv6 = [], - $listen_on_port = undef, - $log_channels = {}, - $log_categories = {}, - $no_empty_zones = false, - $notify_source = undef, + Optional[Array] $allow_query = [], + Optional[Array] $allow_recursion = [], + Optional[Array] $also_notify = [], + Optional[String] $check_names_master = undef, + Optional[String] $check_names_slave = undef, + Optional[String] $check_names_response = undef, + Optional[String] $control_channel_ip = undef, + Optional[String] $control_channel_port = undef, + Optional[String] $control_channel_allow = undef, + Stdlib::Absolutepath $data_dir = $::dns::server::params::data_dir, + # string only works for old type + # String $data_dir = $::dns::server::params::data_dir, + String $dnssec_validation = $::dns::server::params::default_dnssec_validation, + Boolean $dnssec_enable = $::dns::server::params::default_dnssec_enable, + Optional[String] $forward_policy = undef, + Optional[Array] $forwarders = [], + Optional[Array] $listen_on = [], + Optional[Array] $listen_on_ipv6 = [], + $listen_on_port = undef, + Optional[Hash] $log_channels = {}, + Optional[Hash] $log_categories = {}, + Boolean $no_empty_zones = false, + Optional[String] $notify_source = undef, + # Optional[ String [1] ] $query_log_enable = undef, $query_log_enable = undef, - $statistic_channel_ip = undef, - $statistic_channel_port = undef, - $statistic_channel_allow = undef, - $transfers = [], - $transfer_source = undef, - $working_dir = $::dns::server::params::working_dir, - $zone_notify = undef, - $extra_options = {}, + Optional[String] $statistic_channel_ip = undef, + Optional[String] $statistic_channel_port = undef, + Optional[String] $statistic_channel_allow = undef, + Optional[Array] $transfers = [], + Optional[String] $transfer_source = undef, + Stdlib::Absolutepath $working_dir = $::dns::server::params::working_dir, + # string only works for old type + # String $working_dir = $::dns::server::params::working_dir, + Optional[String] $zone_notify = undef, + Optional[Hash] $extra_options = {}, ) { + include dns::server::params $valid_check_names = ['fail', 'warn', 'ignore'] $valid_forward_policy = ['first', 'only'] $cfg_dir = $::dns::server::params::cfg_dir @@ -194,16 +199,20 @@ if ! defined(Class['::dns::server']) { fail('You must include the ::dns::server base class before using any dns options defined resources') } - - validate_string($forward_policy) + if $forward_policy != undef { + assert_type(String, $forward_policy) + } + #validate_string($forward_policy) if $forward_policy != undef and !member($valid_forward_policy, $forward_policy) { fail("The forward_policy must be ${valid_forward_policy}") } - validate_array($forwarders) - validate_array($transfers) - validate_array($listen_on) - validate_array($listen_on_ipv6) - validate_array($allow_recursion) + + assert_type(Array, $forwarders) + assert_type(Array, $transfers) + assert_type(Array, $listen_on) + assert_type(Array, $listen_on_ipv6) + assert_type(Array, $allow_recursion) + if $check_names_master != undef and !member($valid_check_names, $check_names_master) { fail("The check name policy check_names_master must be ${valid_check_names}") } @@ -213,7 +222,7 @@ if $check_names_response != undef and !member($valid_check_names, $check_names_response) { fail("The check name policy check_names_response must be ${valid_check_names}") } - validate_array($allow_query) + assert_type(Array, $allow_query) if $statistic_channel_port != undef and !is_numeric($statistic_channel_port) { fail('The statistic_channel_port is not a number') @@ -224,7 +233,7 @@ } if $statistic_channel_allow != undef { - validate_array($statistic_channel_allow) + assert_type(Array, $statistic_channel_allow) } if $control_channel_port != undef and !is_numeric($control_channel_port) { @@ -236,10 +245,10 @@ } if $control_channel_allow != undef { - validate_array($control_channel_allow) + assert_type(Array, $control_channel_allow) } - validate_array($also_notify) + assert_type(Array, $also_notify) $valid_zone_notify = ['yes', 'no', 'explicit', 'master-only'] if $zone_notify != undef and !member($valid_zone_notify, $zone_notify) { @@ -251,9 +260,9 @@ fail("The dnssec_validation must be ${valid_dnssec_validation}") } - validate_bool($no_empty_zones) + assert_type(Boolean, $no_empty_zones) - validate_bool($dnssec_enable) + assert_type(Boolean, $dnssec_enable) if (! $dnssec_enable) and ($dnssec_validation != undef) { warning('dnssec_enable is false. dnssec_validation will be ignored.') } @@ -267,13 +276,12 @@ } # validate these, just in case they're overridden - validate_absolute_path($data_dir) - validate_absolute_path($working_dir) - - validate_hash($log_channels) - validate_hash($log_categories) + # validate_absolute_path($data_dir) + # validate_absolute_path($working_dir) - validate_hash($extra_options) + assert_type(Hash, $log_channels) + assert_type(Hash, $log_categories) + assert_type(Hash, $extra_options) file { $title: ensure => present, diff --git a/manifests/server/params.pp b/manifests/server/params.pp index 4b30e4dc..07ddaffa 100644 --- a/manifests/server/params.pp +++ b/manifests/server/params.pp @@ -3,22 +3,24 @@ class dns::server::params { case $::osfamily { 'Debian': { - $cfg_dir = '/etc/bind' - $cfg_file = '/etc/bind/named.conf' - $data_dir = '/var/lib/bind/zones' - $working_dir = '/var/cache/bind' - $root_hint = "${cfg_dir}/db.root" - $rfc1912_zones_cfg = "${cfg_dir}/named.conf.default-zones" - $rndc_key_file = "${cfg_dir}/rndc.key" - $group = 'bind' - $owner = 'bind' - $package = 'bind9' - $service = 'bind9' - $default_file = '/etc/default/bind9' - $default_template = 'default.debian.erb' + $cfg_dir = '/etc/bind' + $cfg_file = '/etc/bind/named.conf' + $data_dir = '/var/lib/bind/zones' + $working_dir = '/var/cache/bind' + $root_hint = "${cfg_dir}/db.root" + $rfc1912_zones_cfg = "${cfg_dir}/named.conf.default-zones" + $rndc_key_file = "${cfg_dir}/rndc.key" + $group = 'bind' + $owner = 'bind' + $package = 'bind9' + $service = 'bind9' + $default_file = '/etc/default/bind9' + $default_template = 'default.debian.erb' $default_dnssec_enable = true $default_dnssec_validation = 'auto' - if versioncmp( $::operatingsystemmajrelease, '8' ) >= 0 { + # lint:ignore:only_variable_string + if versioncmp( "${::operatingsystemmajrelease}", '8' ) >= 0 { + # lint:endignore $necessary_packages = ['bind9'] } else { $necessary_packages = [ 'bind9', 'dnssec-tools' ] @@ -39,7 +41,9 @@ $necessary_packages = [ 'bind', ] $default_file = '/etc/sysconfig/named' $default_template = 'default.redhat.erb' - if $::operatingsystemmajrelease =~ /^[1-5]$/ { + # lint:ignore:only_variable_string + if "${::operatingsystemmajrelease}" =~ /^[1-5]$/ { + # lint:endignore $default_dnssec_enable = false $default_dnssec_validation = 'absent' } else { diff --git a/manifests/server/view.pp b/manifests/server/view.pp index bee61cba..988a1ada 100644 --- a/manifests/server/view.pp +++ b/manifests/server/view.pp @@ -44,15 +44,15 @@ # Defaults to empty (no zone is added). # define dns::server::view ( - $ensure = 'present', - $enable_default_zones = true, - $match_clients = [], - $match_destinations = [], - $match_recursive_only = undef, - $options = {}, - $order = '50', - $viewname = $name, - $zones = {}, + String $ensure = 'present', + Boolean $enable_default_zones = true, + Optional[Array] $match_clients = [], + Optional[Array] $match_destinations = [], + Optional[String] $match_recursive_only = undef, + $options = {}, + String $order = '50', + String $viewname = $name, + $zones = {}, ) { include ::dns::server::params @@ -61,17 +61,17 @@ if !member($valid_ensure, $ensure) { fail("ensure parameter must be ${valid_ensure}") } - validate_bool($enable_default_zones) - validate_array($match_clients) - validate_array($match_destinations) + assert_type(Boolean, $enable_default_zones) + assert_type(Array, $match_clients) + assert_type(Array, $match_destinations) if $match_recursive_only { if !member($valid_yes_no, $match_recursive_only) { fail("match_recursive_only parameter must be ${valid_yes_no}") } } validate_hash($options) - validate_string($order) - validate_string($viewname) + assert_type(String, $order) + assert_type(String, $viewname) validate_hash($zones) $rfc1912_zones_cfg = $dns::server::params::rfc1912_zones_cfg diff --git a/manifests/tsig.pp b/manifests/tsig.pp index 534d3a83..b410cc87 100644 --- a/manifests/tsig.pp +++ b/manifests/tsig.pp @@ -1,32 +1,36 @@ -# defined type allows you to declare a BIND TSIG. +# @summary +# defined type allows you to declare a BIND TSIG. # -# Parameters: +# @param [String] ensure +# ensure the persence or absence of the acl. +# @param [String] keyname +# the name given to the TSIG KEY. This must be unique. +# This defaults to the namevar. +# @param [String] algorithm +# Defined algorithm of the key (default: hmac-md5) +# @param [String] server +# related string or array of ip addresses to this key +# @param [String] secret +# shared secret of the key # -# $ensure = ensure the persence or absence of the acl. -# $keyname = the name given to the TSIG KEY. This must be unique. This defaults to -# the namevar. -# $algorithm = Defined algorithm of the key (default: hmac-md5) -# $server = related string or array of ip addresses to this key -# $secret = shared secret of the key -# -# Usage: -# -# dns::tsig { 'ns3': -# ensure => present, -# algorithm => "hmac-md5" -# secret => "dTIxGBPjkT/8b6BYHTUA==" -# } +# @example +# dns::tsig { 'ns3': +# ensure => present, +# algorithm => "hmac-md5" +# secret => "dTIxGBPjkT/8b6BYHTUA==" +# } # define dns::tsig ( - $keyname = $name, - $algorithm = 'hmac-md5', - $server = undef, - $secret = undef, - $ensure = present + String $keyname = $name, + String $algorithm = 'hmac-md5', + Variant[Undef, String, Array] $server = undef, + Variant[Undef, String] $secret = undef, + String $ensure = 'present', ) { $cfg_dir = $dns::server::params::cfg_dir # Used in a template - validate_string($name) + + assert_type(String, $name) if $ensure == 'present' { concat::fragment { "named.conf.local.tsig.${name}.include": diff --git a/manifests/zone.pp b/manifests/zone.pp index 447e5da1..0e611177 100644 --- a/manifests/zone.pp +++ b/manifests/zone.pp @@ -164,41 +164,43 @@ # Defaults to `master`. # define dns::zone ( - $soa = $::fqdn, - $soa_email = "root.${::fqdn}", - $zone_ttl = '604800', - $zone_refresh = '604800', - $zone_retry = '86400', - $zone_expire = '2419200', - $zone_minimum = '604800', - $nameservers = [ $::fqdn ], + String $soa = $::fqdn, + String $soa_email = "root.${::fqdn}", + String $zone_ttl = '604800', + String $zone_refresh = '604800', + String $zone_retry = '86400', + String $zone_expire = '2419200', + String $zone_minimum = '604800', + Array $nameservers = [ $::fqdn ], $reverse = false, $serial = false, - $zone_type = 'master', - $allow_transfer = [], - $allow_forwarder = [], - $allow_query =[], - $allow_update =[], - $forward_policy = 'first', - $slave_masters = undef, - $zone_notify = undef, - $also_notify = [], - $ensure = present, - $data_dir = $::dns::server::params::data_dir, - $view = undef, - $default_zone = false, + String $zone_type = 'master', + Optional[Array] $allow_transfer = [], + Optional[Array] $allow_forwarder = [], + Optional[Array] $allow_query = [], + Optional[Array] $allow_update = [], + String $forward_policy = 'first', + $slave_masters = undef, + Optional[String] $zone_notify = undef, + Optional[Array] $also_notify = [], + String $ensure = present, + Stdlib::Absolutepath $data_dir = $dns::server::params::data_dir, + Optional[String] $view = undef, + Boolean $default_zone = false, ) { $cfg_dir = $dns::server::params::cfg_dir - validate_array($allow_transfer) - validate_array($allow_forwarder) + assert_type(Array, $allow_transfer) + assert_type(Array, $allow_forwarder) + if !member(['first', 'only'], $forward_policy) { fail('The forward policy can only be set to either first or only') } - validate_array($allow_query) + assert_type(Array, $allow_query) + + assert_type(Array, $also_notify) - validate_array($also_notify) $valid_zone_notify = ['yes', 'no', 'explicit', 'master-only'] if $zone_notify != undef and !member($valid_zone_notify, $zone_notify) { fail("The zone_notify must be ${valid_zone_notify}") @@ -210,7 +212,8 @@ default => $name } - validate_string($zone_type) + assert_type(String, $zone_type) + $valid_zone_type_array = ['master', 'slave', 'stub', 'forward', 'delegation-only'] if !member($valid_zone_type_array, $zone_type) { $valid_zone_type_array_str = join($valid_zone_type_array, ',') @@ -220,7 +223,8 @@ $zone_file = "${data_dir}/db.${name}" $zone_file_stage = "${zone_file}.stage" - validate_array($allow_update) + assert_type(Array, $allow_update) + # Replace when updates allowed if empty($allow_update) { $zone_replace = true @@ -229,10 +233,10 @@ } if $view { - validate_string($view) + assert_type(String, $view) } - validate_bool($default_zone) + assert_type(Boolean, $default_zone) if $view and $default_zone == true { fail('view and default parameters are mutually excluding') diff --git a/metadata.json b/metadata.json index 3e17a1d7..2ec02535 100644 --- a/metadata.json +++ b/metadata.json @@ -7,31 +7,82 @@ "source": "https://github.com/ajjahn/puppet-dns", "project_page": "https://github.com/ajjahn/puppet-dns", "issues_url": "https://github.com/ajjahn/puppet-dns/issues", - "description": "Module for provisioning DNS (bind9)", + "dependencies": [ + { + "name": "puppetlabs/concat", + "version_requirement": ">=2.0.0 <6.0.0" + }, + { + "name": "puppetlabs/translate", + "version_requirement": ">=1.0.0 <2.0.0" + }, + { + "name": "puppetlabs/stdlib", + "version_requirement": ">=4.0.0 <6.0.0" + } + ], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ - "5.0", - "6.0" - ] + "5", + "6", + "7" + ], + "operatingsystemmajrelease": "7.5" + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ], + "operatingsystemmajrelease": "7.5.1804" + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "5", + "6", + "7" + ], + "operatingsystemmajrelease": "7.5" + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "6", + "7" + ], + "operatingsystemmajrelease": "7.5" + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "8", + "9" + ], + "operatingsystemmajrelease": "9" }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ - "12.04", - "10.04" - ] + "14.04", + "16.04", + "18.04" + ], + "operatingsystemmajrelease": "18.04" } ], - "dependencies": [ - { - "name": "puppetlabs/concat", - "version_requirement": ">=2.0.0" - }, + "requirements": [ { - "name": "puppetlabs/stdlib", - "version_requirement": ">=2.4.0 <6.0.0" + "name": "puppet", + "version_requirement": ">= 5.0.0 < 7.0.0" } - ] -} + ], + "description": "Module for provisioning DNS (bind9)", + "pdk-version": "1.9.0", + "template-url": "file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git", + "template-ref": "1.9.0-0-g7281db5" +} \ No newline at end of file diff --git a/spec/acceptance/basic_dns_spec.rb b/spec/acceptance/basic_dns_spec.rb index 32fd65e4..d407af3b 100644 --- a/spec/acceptance/basic_dns_spec.rb +++ b/spec/acceptance/basic_dns_spec.rb @@ -1,20 +1,19 @@ require 'spec_helper_acceptance' describe 'basic dns' do + context 'default parameters' do + let(:pp) do + " + include dns::server + dns::server::options{'/etc/bind/named.conf.options': forwarders => ['8.8.8.8', '8.8.4.4'], } + " + end - context 'default parameters' do - let(:pp) {" - include dns::server - dns::server::options { '/etc/bind/named.conf.options': - forwarders => [ '8.8.8.8', '8.8.4.4' ] - } - "} - it 'should apply with no errors' do - apply_manifest(pp, :catch_failures=>true) + it 'is_expected.to apply with no errors' do + apply_manifest(pp, catch_failures: true) end - it 'should be idempotent' do - apply_manifest(pp, :catch_changes=>true) + it 'is_expected.to be idempotent' do + apply_manifest(pp, catch_changes: true) end end - end diff --git a/spec/acceptance/nodesets/centos-66-x64.yml b/spec/acceptance/nodesets/centos-66-x64.yml index 1fffff68..5cfd436d 100644 --- a/spec/acceptance/nodesets/centos-66-x64.yml +++ b/spec/acceptance/nodesets/centos-66-x64.yml @@ -1,12 +1,11 @@ HOSTS: centos-66-x64: roles: - - master + - agent + - default platform: el-6-x86_64 box: puppetlabs/centos-6.6-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-6.6-64-nocm hypervisor: vagrant CONFIG: log_level: verbose type: foss - color: false diff --git a/spec/acceptance/nodesets/centos-7-x64.yml b/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 00000000..5eebdefb --- /dev/null +++ b/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: el-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/centos-70-x64.yml b/spec/acceptance/nodesets/centos-70-x64.yml deleted file mode 100644 index 845e47eb..00000000 --- a/spec/acceptance/nodesets/centos-70-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-70-x64: - roles: - - master - platform: el-7-x86_64 - box: puppetlabs/centos-7.0-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-7.0-64-nocm - hypervisor : vagrant -CONFIG: - log_level: verbose - type: foss - color: false diff --git a/spec/acceptance/nodesets/debian-78-x64.yml b/spec/acceptance/nodesets/debian-78-x64.yml index c4062fd1..3e3f140b 100644 --- a/spec/acceptance/nodesets/debian-78-x64.yml +++ b/spec/acceptance/nodesets/debian-78-x64.yml @@ -1,12 +1,11 @@ HOSTS: debian-78-x64: roles: - - master + - agent + - default platform: debian-7-amd64 box: puppetlabs/debian-7.8-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/debian-7.8-64-nocm hypervisor: vagrant - CONFIG: log_level: verbose type: foss diff --git a/spec/acceptance/nodesets/debian-8-x64.yml b/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 00000000..fef6e63c --- /dev/null +++ b/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/default.yml similarity index 55% rename from spec/acceptance/nodesets/ubuntu-server-1404-x64.yml rename to spec/acceptance/nodesets/default.yml index bf9365eb..9ad4130f 100644 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ b/spec/acceptance/nodesets/default.yml @@ -1,13 +1,11 @@ HOSTS: - ubuntu-server-1404-x64: + ubuntu-1404-x64: roles: - - master + - agent + - default platform: ubuntu-1404-amd64 box: puppetlabs/ubuntu-14.04-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm hypervisor: vagrant - CONFIG: log_level: verbose type: foss - color: false diff --git a/spec/acceptance/nodesets/docker/centos-7.yml b/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 00000000..a3333aac --- /dev/null +++ b/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/debian-8.yml b/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 00000000..df5c3194 --- /dev/null +++ b/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/ubuntu-1404.yml b/spec/acceptance/nodesets/docker/ubuntu-1404.yml new file mode 100644 index 00000000..b1efa583 --- /dev/null +++ b/spec/acceptance/nodesets/docker/ubuntu-1404.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml b/spec/acceptance/nodesets/ubuntu-1204-x64.yml similarity index 54% rename from spec/acceptance/nodesets/ubuntu-server-1204-x86.yml rename to spec/acceptance/nodesets/ubuntu-1204-x64.yml index c2e8657a..de00b54d 100644 --- a/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml +++ b/spec/acceptance/nodesets/ubuntu-1204-x64.yml @@ -1,13 +1,11 @@ HOSTS: - ubuntu-server-1204-x64: + ubuntu-1204-x64: roles: - - master + - agent + - default platform: ubuntu-1204-amd64 box: puppetlabs/ubuntu-12.04-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-12.04-64-nocm hypervisor: vagrant - CONFIG: log_level: verbose type: foss - color: false diff --git a/spec/acceptance/nodesets/ubuntu-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-1404-x64.yml new file mode 100644 index 00000000..9ad4130f --- /dev/null +++ b/spec/acceptance/nodesets/ubuntu-1404-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-1404-x64: + roles: + - agent + - default + platform: ubuntu-1404-amd64 + box: puppetlabs/ubuntu-14.04-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss diff --git a/spec/acceptance/nodesets/ubuntu-1604-x64.yml b/spec/acceptance/nodesets/ubuntu-1604-x64.yml new file mode 100644 index 00000000..a4462756 --- /dev/null +++ b/spec/acceptance/nodesets/ubuntu-1604-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-1604-x64: + roles: + - agent + - default + platform: ubuntu-1604-amd64 + box: puppetlabs/ubuntu-16.04-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss diff --git a/spec/classes/coverage_spec.rb b/spec/classes/coverage_spec.rb deleted file mode 100644 index 12513b83..00000000 --- a/spec/classes/coverage_spec.rb +++ /dev/null @@ -1 +0,0 @@ -at_exit { RSpec::Puppet::Coverage.report! } diff --git a/spec/classes/dns__server__config_spec.rb b/spec/classes/dns__server__config_spec.rb deleted file mode 100644 index c7d5a4cd..00000000 --- a/spec/classes/dns__server__config_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'spec_helper' - -describe 'dns::server::config', :type => :class do - - context "on an unsupported OS" do - let :facts do { :osfamily => 'Solaris', :concat_basedir => '/dne', } end - it { should raise_error(/dns::server is incompatible with this osfamily/) } - end - - context "on a Debian OS" do - let (:facts) {{ - :osfamily => 'Debian', - :operatingsystemrelease => '6', - :concat_basedir => '/dne', - }} - it { should contain_file('/etc/bind/').with_owner('bind') } - it { should contain_file('/etc/bind/named.conf').with_content(/^include "\/etc\/bind\/named.conf.options";$/) } - end - - context "on a RedHat OS" do - let (:facts) {{ - :osfamily => 'RedHat', - :concat_basedir => '/dne', - }} - it { should contain_file('/etc/named.conf').with_owner('named') } - it { should contain_file('/etc/named.conf').with_content(/^include "\/etc\/named\/named.conf.options";$/) } - end -end - diff --git a/spec/classes/dns__server__install_spec.rb b/spec/classes/dns__server__install_spec.rb deleted file mode 100644 index 96a8c662..00000000 --- a/spec/classes/dns__server__install_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'spec_helper' - -describe 'dns::server::install', :type => :class do - context "on an unsupported OS" do - it{ should raise_error(/dns::server is incompatible with this osfamily/) } - end - - context "on a Debian OS with default params" do - let(:facts) {{ :osfamily => 'Debian' }} - it { should contain_class('dns::server::params') } - ['bind9', 'dnssec-tools'].each do |package| - it do - should contain_package(package).with({ - 'ensure' => 'latest', - }) - end - end - end - - context "on a Debian OS with non-default params" do - let(:facts) {{ :osfamily => 'Debian' }} - let(:params) {{ :ensure_packages => 'present' }} - it { should contain_class('dns::server::params') } - ['bind9', 'dnssec-tools'].each do |package| - it do - should contain_package(package).with({ - 'ensure' => 'present', - }) - end - end - end - - context "on a RedHat OS with default params" do - let(:facts) {{ :osfamily => 'RedHat' }} - it { should contain_class('dns::server::params') } - it do - should contain_package('bind').with({ - 'ensure' => 'latest', - }) - end - end - - context "on a RedHat OS with non-default params" do - let(:facts) {{ :osfamily => 'RedHat' }} - let(:params) {{ :ensure_packages => 'present' }} - it { should contain_class('dns::server::params') } - it do - should contain_package('bind').with({ - 'ensure' => 'present', - }) - end - end - -end diff --git a/spec/classes/dns__server__service_spec.rb b/spec/classes/dns__server__service_spec.rb deleted file mode 100644 index 6f02ef2f..00000000 --- a/spec/classes/dns__server__service_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe 'dns::server::service' do - let(:facts) {{ :concat_basedir => '/mock_dir' }} - - context 'on a supported OS' do - let(:facts) {{ :osfamily => 'Debian' }} - it { should contain_service('bind9').with_require('Class[Dns::Server::Config]') } - end - - context 'on an unsupported OS' do - let(:facts) {{ :osfamily => 'Solaris' }} - it { should raise_error(/dns::server is incompatible with this osfamily: Solaris/) } - end - -end diff --git a/spec/classes/dns__server_spec.rb b/spec/classes/dns__server_spec.rb deleted file mode 100644 index 982b27fc..00000000 --- a/spec/classes/dns__server_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'spec_helper' - -describe 'dns::server' do - - context "By Default" do - let(:facts) {{ :osfamily => 'Debian', :concat_basedir => '/dne' }} - it { should contain_class('dns::server::install') } - it { should contain_class('dns::server::config') } - it { should contain_class('dns::server::service') } - end - -end diff --git a/spec/classes/dns_server_config_spec.rb b/spec/classes/dns_server_config_spec.rb new file mode 100644 index 00000000..4b126b21 --- /dev/null +++ b/spec/classes/dns_server_config_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' + +RSpec.describe 'Dns::Server::Config', type: :class do + let(:pre_condition) { 'include ::dns::server::install' } + let(:post_condition) { 'include ::dns::server::service' } + + context 'on an unsupported OS' do + let :facts do + { + osfamily: 'Solaris', + os: { family: 'Solaris' }, + concat_basedir: '/dne', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{dns::server is incompatible with this osfamily}) } + end + + context 'on a Debian OS' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + operatingsystemrelease: '6', + concat_basedir: '/dne', + } + end + + it { is_expected.to contain_file('/etc/bind/').with_owner('bind') } + it { is_expected.to contain_file('/etc/bind/named.conf').with_content(%r{^include "\/etc\/bind\/named.conf.options";$}) } + end + + context 'on a RedHat OS' do + let :facts do + { + osfamily: 'RedHat', + os: { family: 'RedHat' }, + concat_basedir: '/dne', + } + end + + it { is_expected.to contain_file('/etc/named.conf').with_owner('named') } + it { is_expected.to contain_file('/etc/named.conf').with_content(%r{^include "\/etc\/named\/named.conf.options";$}) } + end +end diff --git a/spec/classes/dns_server_default_spec.rb b/spec/classes/dns_server_default_spec.rb new file mode 100644 index 00000000..7f277f1d --- /dev/null +++ b/spec/classes/dns_server_default_spec.rb @@ -0,0 +1,258 @@ +require 'spec_helper' + +describe 'Dns::Server::Default', type: :class do + let(:pre_condition) { 'include ::dns::server::params' } + let(:post_condition) { 'include ::dns::server' } + + context 'on an unsupported OS' do + let :facts do + { + osfamily: 'Solaris', + os: { family: 'Solaris' }, + concat_basedir: '/dne', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{dns::server is incompatible with this osfamily}) } + end + context 'by default on debian' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + concat_basedir: '/tmp', + } + end + + context 'passing correct values and paths' do + context 'passing `no` to resolvconf' do + let :params do + { + resolvconf: 'no', + } + end + + it { is_expected.to contain_file('/etc/default/bind9').with_content(%r{RESOLVCONF=no}) } + end + context 'passing `yes` to resolvconf' do + let :params do + { + resolvconf: 'yes', + } + end + + it { is_expected.to contain_file('/etc/default/bind9').with_content(%r{RESOLVCONF=yes}) } + end + context 'passing `-u bind -4` to options' do + let :params do + { + options: '-u bind -4', + } + end + + it { is_expected.to contain_file('/etc/default/bind9').with_content(%r{OPTIONS="-u bind -4"}) } + end + context 'passing `-u bind -6` to options' do + let :params do + { + options: '-u bind -6', + } + end + + it { is_expected.to contain_file('/etc/default/bind9').with_content(%r{OPTIONS="-u bind -6"}) } + end + context 'requires bind9 and dnssec-tools package' do + it { is_expected.to contain_file('/etc/default/bind9').with('require' => ['Package[bind9]', 'Package[dnssec-tools]']) } + end + end + context 'passing wrong values and paths' do + context 'passing wrong value to resolvconf for hit an error' do + let :params do + { + resolvconf: 'WrongValue', + } + end + + it { is_expected.to raise_error(%r{The resolvconf value is not type of a string yes \/ no.}) } + end + end + end + context 'by default on redhat' do + let :facts do + { + osfamily: 'RedHat', + concat_basedir: '/tmp', + } + end + + context 'passing correct values and paths' do + context 'passing path `/chroot` to rootdir' do + let :params do + { + rootdir: '/chroot', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ROOTDIR="\/chroot"}) } + end + context 'passing `-u named` to options' do + let :params do + { + options: '-u named', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{OPTIONS="-u named"}) } + end + context 'passing `yes` to enable_zone_write' do + let :params do + { + enable_zone_write: 'yes', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_ZONE_WRITE=yes}) } + end + context 'passing `no` to enable_zone_write' do + let :params do + { + enable_zone_write: 'no', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_ZONE_WRITE=no}) } + end + context 'passing `yes` to enable_sdb' do + let :params do + { + enable_sdb: 'yes', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_SDB=yes}) } + end + context 'passing `no` to enable_sdb' do + let :params do + { + enable_sdb: 'no', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_SDB=no}) } + end + context 'passing `1` to enable_sdb' do + let :params do + { + enable_sdb: '1', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_SDB=1}) } + end + context 'passing `0` to enable_sdb' do + let :params do + { + enable_sdb: '0', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{ENABLE_SDB=0}) } + end + context 'passing `yes` to disable_named_dbus' do + let :params do + { + disable_named_dbus: 'yes', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{DISABLE_NAMED_DBUS=yes}) } + end + context 'passing `no` to disable_named_dbus' do + let :params do + { + disable_named_dbus: 'no', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{DISABLE_NAMED_DBUS=no}) } + end + context 'passing path `/usr/local/samba/private/dns.keytab` to keytab_file' do + let :params do + { + keytab_file: '/usr/local/samba/private/dns.keytab', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{KEYTAB_FILE="\/usr\/local\/samba\/private\/dns.keytab}) } + end + context 'passing `yes` to disable_zone_checking' do + let :params do + { + disable_zone_checking: 'yes', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{DISABLE_ZONE_CHECKING=yes}) } + end + context 'passing `no` to disable_zone_checking' do + let :params do + { + disable_zone_checking: 'no', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/named').with_content(%r{DISABLE_ZONE_CHECKING=no}) } + end + context 'requires bind package' do + it { is_expected.to contain_file('/etc/sysconfig/named').with_require('[Package[bind]{:name=>"bind"}]') } + end + end + context 'passing wrong values and paths' do + context 'passing wrong value to rootdir for hit an error' do + let :params do + { + rootdir: 'chroot', + } + end + + it { is_expected.to raise_error(%r{"chroot" is not an absolute path.}) } + end + context 'passing wrong value to enable_zone_write for hit an error' do + let :params do + { + enable_zone_write: 'WrongValue', + } + end + + it { is_expected.to raise_error(%r{The enable_zone_write value is not type of a string yes \/ no.}) } + end + context 'passing wrong value to enable_sdb for hit an error' do + let :params do + { + enable_sdb: 'WrongValue', + } + end + + it { is_expected.to raise_error(%r{The enable_sdb value is not type of a string yes \/ no \/ 1 \/ 0 or empty.}) } + end + context 'passing wrong value to keytab_file for hit an error' do + let :params do + { + keytab_file: 'usr/local/samba/private/dns.keytab', + } + end + + it { is_expected.to raise_error(%r{"usr\/local\/samba\/private\/dns.keytab" is not an absolute path.}) } + end + context 'passing wrong value to disable_zone_checking for hit an error' do + let :params do + { + disable_zone_checking: 'chroot', + } + end + + it { is_expected.to raise_error(%r{The disable_zone_checking value is not type of a string yes \/ no or empty.}) } + end + end + end +end diff --git a/spec/classes/dns_server_install_spec.rb b/spec/classes/dns_server_install_spec.rb new file mode 100644 index 00000000..caf5ab49 --- /dev/null +++ b/spec/classes/dns_server_install_spec.rb @@ -0,0 +1,78 @@ +require 'spec_helper' + +describe 'Dns::Server::Install', type: :class do + context 'on an unsupported OS' do + let :facts do + { + osfamily: 'Solaris', + os: { family: 'Solaris' }, + concat_basedir: '/dne', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{dns::server is incompatible with this osfamily}) } + end + + context 'on a Debian OS with default params' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + } + end + + it { is_expected.to contain_class('dns::server::params') } + ['bind9', 'dnssec-tools'].each do |package| + it { is_expected.to contain_package(package).with_ensure('latest') } + end + end + + context 'on a Debian OS with non-default params' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + } + end + let :params do + { + ensure_packages: 'present', + } + end + + it { is_expected.to contain_class('dns::server::params') } + ['bind9', 'dnssec-tools'].each do |package| + it { is_expected.to contain_package(package).with_ensure('present') } + end + end + + context 'on a RedHat OS with default params' do + let :facts do + { + osfamily: 'RedHat', + os: { family: 'RedHat' }, + } + end + + it { is_expected.to contain_class('dns::server::params') } + it { is_expected.to contain_package('bind').with_ensure('latest') } + end + + context 'on a RedHat OS with non-default params' do + let :facts do + { + osfamily: 'RedHat', + os: { family: 'RedHat' }, + } + end + + let :params do + { + ensure_packages: 'present', + } + end + + it { is_expected.to contain_class('dns::server::params') } + it { is_expected.to contain_package('bind').with_ensure('present') } + end +end diff --git a/spec/classes/dns_server_service_spec.rb b/spec/classes/dns_server_service_spec.rb new file mode 100644 index 00000000..2a892b25 --- /dev/null +++ b/spec/classes/dns_server_service_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +RSpec.describe 'Dns::Server::Service', type: :class do + let(:pre_condition) { 'include ::dns::server::install' } + let(:post_condition) { 'include ::dns::server::config' } + let :facts do + { + concat_basedir: '/mock_dir', + } + end + + context 'on a supported OS' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + } + end + + it { is_expected.to contain_service('bind9').with_require('Class[Dns::Server::Config]') } + end + + context 'on an unsupported OS' do + let :facts do + { + osfamily: 'Solaris', + os: { family: 'Solaris' }, + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{dns::server is incompatible with this osfamily: Solaris}) } + end +end diff --git a/spec/classes/dns_server_spec.rb b/spec/classes/dns_server_spec.rb new file mode 100644 index 00000000..60494ded --- /dev/null +++ b/spec/classes/dns_server_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe 'Dns::Server', type: :class do + context 'By Default' do + let :facts do + { + osfamily: 'Debian', + os: { family: 'Debian' }, + concat_basedir: '/dne', + } + end + + it { is_expected.to contain_class('dns::server::install') } + it { is_expected.to contain_class('dns::server::config') } + it { is_expected.to contain_class('dns::server::service') } + end +end diff --git a/spec/classes/dns_spec.rb b/spec/classes/dns_spec.rb new file mode 100644 index 00000000..377dfa65 --- /dev/null +++ b/spec/classes/dns_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +RSpec.describe 'Dns', type: :class do + context 'By Default' do + it { is_expected.to compile } + end +end diff --git a/spec/classes/server/default_spec.rb b/spec/classes/server/default_spec.rb deleted file mode 100644 index 6b7304d4..00000000 --- a/spec/classes/server/default_spec.rb +++ /dev/null @@ -1,169 +0,0 @@ -require 'spec_helper' - -describe 'dns::server::default' do - - context "on an unsupported OS" do - it{ should raise_error(/dns::server is incompatible with this osfamily/) } - end - - context 'by default on debian' do - - let(:facts) {{ :osfamily => 'Debian', :concat_basedir => '/tmp' }} - - context "passing correct values and paths" do - - context 'passing `no` to resolvconf' do - let(:params) {{ :resolvconf => 'no' }} - it { should contain_file('/etc/default/bind9').with_content(/RESOLVCONF=no/) } - end - - context 'passing `yes` to resolvconf' do - let(:params) {{ :resolvconf => 'yes' }} - it { should contain_file('/etc/default/bind9').with_content(/RESOLVCONF=yes/) } - end - - context 'passing `-u bind -4` to options' do - let(:params) {{ :options => '-u bind -4' }} - it { should contain_file('/etc/default/bind9').with_content(/OPTIONS="-u bind -4"/) } - end - - context 'passing `-u bind -6` to options' do - let(:params) {{ :options => '-u bind -6' }} - it { should contain_file('/etc/default/bind9').with_content(/OPTIONS="-u bind -6"/) } - end - - context "requires bind9 and dnssec-tools package" do - it do - should contain_file('/etc/default/bind9').with({ - 'require' => ['Package[bind9]', 'Package[dnssec-tools]'], - }) - end - end - - - end - - context "passing wrong values and paths" do - - context 'passing wrong value to resolvconf for hit an error' do - let(:params) {{ :resolvconf => 'WrongValue' }} - it{ should raise_error(/The resolvconf value is not type of a string yes \/ no./)} - end - - end - - end - - context 'by default on redhat' do - - let(:facts) {{ :osfamily => 'RedHat', :concat_basedir => '/tmp' }} - - context "passing correct values and paths" do - - context 'passing path `/chroot` to rootdir' do - let(:params) {{ :rootdir => '/chroot' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ROOTDIR="\/chroot"/) } - end - - context 'passing `-u named` to options' do - let(:params) {{ :options => '-u named' }} - it { should contain_file('/etc/sysconfig/named').with_content(/OPTIONS="-u named"/) } - end - - context 'passing `yes` to enable_zone_write' do - let(:params) {{ :enable_zone_write => 'yes' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_ZONE_WRITE=yes/) } - end - - context 'passing `no` to enable_zone_write' do - let(:params) {{ :enable_zone_write => 'no' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_ZONE_WRITE=no/) } - end - - context 'passing `yes` to enable_sdb' do - let(:params) {{ :enable_sdb => 'yes' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_SDB=yes/) } - end - - context 'passing `no` to enable_sdb' do - let(:params) {{ :enable_sdb => 'no' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_SDB=no/) } - end - - context 'passing `1` to enable_sdb' do - let(:params) {{ :enable_sdb => '1' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_SDB=1/) } - end - - context 'passing `0` to enable_sdb' do - let(:params) {{ :enable_sdb => '0' }} - it { should contain_file('/etc/sysconfig/named').with_content(/ENABLE_SDB=0/) } - end - - context 'passing `yes` to disable_named_dbus' do - let(:params) {{ :disable_named_dbus => 'yes' }} - it { should contain_file('/etc/sysconfig/named').with_content(/DISABLE_NAMED_DBUS=yes/) } - end - - context 'passing `no` to disable_named_dbus' do - let(:params) {{ :disable_named_dbus => 'no' }} - it { should contain_file('/etc/sysconfig/named').with_content(/DISABLE_NAMED_DBUS=no/) } - end - - context 'passing path `/usr/local/samba/private/dns.keytab` to keytab_file' do - let(:params) {{ :keytab_file => '/usr/local/samba/private/dns.keytab' }} - it { should contain_file('/etc/sysconfig/named').with_content(/KEYTAB_FILE="\/usr\/local\/samba\/private\/dns.keytab/) } - end - - context 'passing `yes` to disable_zone_checking' do - let(:params) {{ :disable_zone_checking => 'yes' }} - it { should contain_file('/etc/sysconfig/named').with_content(/DISABLE_ZONE_CHECKING=yes/) } - end - - context 'passing `no` to disable_zone_checking' do - let(:params) {{ :disable_zone_checking => 'no' }} - it { should contain_file('/etc/sysconfig/named').with_content(/DISABLE_ZONE_CHECKING=no/) } - end - - context "requires bind package" do - it do - should contain_file('/etc/sysconfig/named').with({ - 'require' => 'Package[bind]', - }) - end - end - - end - - context "passing wrong values and paths" do - - context 'passing wrong value to rootdir for hit an error' do - let(:params) {{ :rootdir => 'chroot' }} - it{ should raise_error(/"chroot" is not an absolute path./)} - end - - context 'passing wrong value to enable_zone_write for hit an error' do - let(:params) {{ :enable_zone_write => 'WrongValue' }} - it{ should raise_error(/The enable_zone_write value is not type of a string yes \/ no./)} - end - - context 'passing wrong value to enable_sdb for hit an error' do - let(:params) {{ :enable_sdb => 'WrongValue' }} - it{ should raise_error(/The enable_sdb value is not type of a string yes \/ no \/ 1 \/ 0 or empty./)} - end - - context 'passing wrong value to keytab_file for hit an error' do - let(:params) {{ :keytab_file => 'usr/local/samba/private/dns.keytab' }} - it{ should raise_error(/"usr\/local\/samba\/private\/dns.keytab" is not an absolute path./)} - end - - context 'passing wrong value to disable_zone_checking for hit an error' do - let(:params) {{ :disable_zone_checking => 'chroot' }} - it{ should raise_error(/The disable_zone_checking value is not type of a string yes \/ no or empty./)} - end - - end - - end - -end diff --git a/spec/default_facts.yml b/spec/default_facts.yml new file mode 100644 index 00000000..ea1e4808 --- /dev/null +++ b/spec/default_facts.yml @@ -0,0 +1,7 @@ +# 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" +is_pe: false +macaddress: "AA:AA:AA:AA:AA:AA" diff --git a/spec/default_module_facts.yml b/spec/default_module_facts.yml new file mode 100644 index 00000000..be39725a --- /dev/null +++ b/spec/default_module_facts.yml @@ -0,0 +1,4 @@ +--- +osfamily: Debian +operatingsystem: Debian +operatingsystemmajrelease: 7 diff --git a/spec/defines/dns__acl_spec.rb b/spec/defines/dns__acl_spec.rb deleted file mode 100644 index c0187096..00000000 --- a/spec/defines/dns__acl_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe 'dns::acl' do - let(:title) { 'trusted' } - let(:facts) { { - :concat_basedir => '/tmp', - :osfamily => 'Debian', - } } - - context 'passing a string to data' do - let :params do - { :data => '192.168.0.0/24' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing an array to data' do - let :params do - { :data => [ '192.168.0.0/24' ] } - end - it { should_not raise_error } - it { - should contain_concat__fragment('named.conf.local.acl.trusted.include'). - with_content(/acl trusted/) - } - it { - should contain_concat__fragment('named.conf.local.acl.trusted.include'). - with_content(/192.168.0.0\/24;/) - } - end - -end - diff --git a/spec/defines/dns__key_spec.rb b/spec/defines/dns__key_spec.rb deleted file mode 100644 index 426f10ac..00000000 --- a/spec/defines/dns__key_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -describe 'dns::key' do - let(:title) { 'rspec-key' } - let(:default_facts) { { :concat_basedir => '/tmp' } } - - context "On a Debian OS" do - let (:facts) do - default_facts.merge({ - :osfamily => 'Debian' - }) - end - it { should contain_file('/tmp/rspec-key-secret.sh').with_notify('Exec[dnssec-keygen-rspec-key]') } - it { should contain_exec('dnssec-keygen-rspec-key').with_command(/USER rspec-key$/) } - it { should contain_exec('get-secret-from-rspec-key').with_command('/tmp/rspec-key-secret.sh') } - it { should contain_exec('get-secret-from-rspec-key').with_creates('/etc/bind/bind.keys.d/rspec-key.secret') } - it { should contain_exec('get-secret-from-rspec-key').with_require(['Exec[dnssec-keygen-rspec-key]', 'File[/etc/bind/bind.keys.d]', 'File[/tmp/rspec-key-secret.sh]']) } - it { should contain_file('/etc/bind/bind.keys.d/rspec-key.secret').with_require('Exec[get-secret-from-rspec-key]') } - it { should contain_concat('/etc/bind/bind.keys.d/rspec-key.key') } - ['rspec-key.key-header', 'rspec-key.key-secret', 'rspec-key.key-footer'].each do |fragment| - it { should contain_concat__fragment(fragment).with_target('/etc/bind/bind.keys.d/rspec-key.key') } - it { should contain_concat__fragment(fragment).with_require(['Exec[get-secret-from-rspec-key]', 'File[/etc/bind/bind.keys.d/rspec-key.secret]']) } - end - it { should contain_concat__fragment('rspec-key.key-secret').with_source('/etc/bind/bind.keys.d/rspec-key.secret') } - end - - context "On a RedHat OS" do - let (:facts) do - default_facts.merge({ - :osfamily => 'RedHat' - }) - end - it { should contain_file('/tmp/rspec-key-secret.sh').with_notify('Exec[dnssec-keygen-rspec-key]') } - it { should contain_exec('dnssec-keygen-rspec-key').with_command(/USER rspec-key$/) } - it { should contain_exec('get-secret-from-rspec-key').with_command('/tmp/rspec-key-secret.sh') } - it { should contain_exec('get-secret-from-rspec-key').with_creates('/etc/named/bind.keys.d/rspec-key.secret') } - it { should contain_exec('get-secret-from-rspec-key').with_require(['Exec[dnssec-keygen-rspec-key]', 'File[/etc/named/bind.keys.d]', 'File[/tmp/rspec-key-secret.sh]']) } - it { should contain_file('/etc/named/bind.keys.d/rspec-key.secret').with_require('Exec[get-secret-from-rspec-key]') } - it { should contain_concat('/etc/named/bind.keys.d/rspec-key.key') } - ['rspec-key.key-header', 'rspec-key.key-secret', 'rspec-key.key-footer'].each do |fragment| - it { should contain_concat__fragment(fragment).with_target('/etc/named/bind.keys.d/rspec-key.key') } - it { should contain_concat__fragment(fragment).with_require(['Exec[get-secret-from-rspec-key]', 'File[/etc/named/bind.keys.d/rspec-key.secret]']) } - end - it { should contain_concat__fragment('rspec-key.key-secret').with_source('/etc/named/bind.keys.d/rspec-key.secret') } - end -end - diff --git a/spec/defines/dns__record__a_spec.rb b/spec/defines/dns__record__a_spec.rb deleted file mode 100644 index e037498d..00000000 --- a/spec/defines/dns__record__a_spec.rb +++ /dev/null @@ -1,185 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::a', :type => :define do - let(:title) { 'atest' } - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'passing a single ip address with ptr=>false' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => '192.168.128.42', - :ptr => false, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.42$/) } - it { should_not contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') } - end - - context 'passing a single ip address with ptr=>true' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => '192.168.128.42', - :ptr => true, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.42$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^42\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing a single ip address with ptr=>all' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => '192.168.128.42', - :ptr => 'all', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.42$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^42\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing multiple ip addresses with ptr=>false' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => false, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$/) } - it { should_not contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') } - end - - context 'passing multiple ip addresses with ptr=>true' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => true, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing multiple ip addresses with ptr=>all' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(/^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.69.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^69\s+IN\s+PTR\s+atest\.example\.com\.$/) } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.70.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^70\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class A network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,192.IN-ADDR.ARPA.record').with_content(/^68\.128\.168\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class B network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,168.192.IN-ADDR.ARPA.record').with_content(/^68\.128\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class C network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class A and class B network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "192.IN-ADDR.ARPA": }', - 'dns::zone { "168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,168.192.IN-ADDR.ARPA.record').with_content(/^68\.128\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class A and class C network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "192.IN-ADDR.ARPA": }', - 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class B and class C network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "168.192.IN-ADDR.ARPA": }', - 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - - context 'passing ptr=>true with class A, class B and class C network defined' do - let :params do { - :host => 'atest', - :zone => 'example.com', - :data => [ '192.168.128.68', '192.168.128.69', '192.168.128.70' ], - :ptr => 'all', - } end - let :pre_condition do [ - 'dns::zone { "192.IN-ADDR.ARPA": }', - 'dns::zone { "168.192.IN-ADDR.ARPA": }', - 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', - ] end - it { should_not raise_error } - it { should contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record').with_content(/^68\s+IN\s+PTR\s+atest\.example\.com\.$/) } - end - -end - diff --git a/spec/defines/dns__record__aliases.spec.rb b/spec/defines/dns__record__aliases.spec.rb deleted file mode 100644 index af5d498f..00000000 --- a/spec/defines/dns__record__aliases.spec.rb +++ /dev/null @@ -1,217 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::aaaa', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => ['::1'] , - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,AAAA,example.com.record') - .with_content(/^foo\s+IN\s+AAAA\s+::1$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => ['::1'] , - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,AAAA,example.com.record') - .with_content(/^bar\s+IN\s+AAAA\s+::1$/) - } - end - -end - -describe 'dns::record::a', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => ['1.2.3.4'] , - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,A,example.com.record') - .with_content(/^foo\s+IN\s+A\s+1\.2\.3\.4$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => ['1.2.3.4'] , - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,A,example.com.record') - .with_content(/^bar\s+IN\s+A\s+1\.2\.3\.4$/) - } - end - -end - -describe 'dns::record::cname', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => 'baz.example.com', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,CNAME,example.com.record') - .with_content(/^foo\s+IN\s+CNAME\s+baz\.example\.com\.$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => 'baz.example.com', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,CNAME,example.com.record') - .with_content(/^bar\s+IN\s+CNAME\s+baz\.example\.com\.$/) - } - end - -end - -describe 'dns::record::mx', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => 'baz.example.com', - :preference => 10, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,MX,example.com.record') - .with_content(/^foo\s+IN\s+MX\s+10\s+baz\.example\.com\.$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => 'baz.example.com', - :preference => 10, - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,MX,example.com.record') - .with_content(/^bar\s+IN\s+MX\s+10\s+baz\.example\.com\.$/) - } - end - -end - - -describe 'dns::record::ns', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => 'baz.example.com.', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,NS,example.com.record') - .with_content(/^foo\s+IN\s+NS\s+baz\.example\.com\.$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => 'baz.example.com.', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,NS,example.com.record') - .with_content(/^bar\s+IN\s+NS\s+baz\.example\.com\.$/) - } - end - -end - - -describe 'dns::record::ptr', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => '0.0.127.IN-ADDR.ARPA', - :title => '1' , - :data => 'localhost', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.0.0.127.IN-ADDR.ARPA.1,PTR,0.0.127.IN-ADDR.ARPA.record') - .with_content(/^1\s+IN\s+PTR\s+localhost\.$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => '0.0.127.IN-ADDR.ARPA', - :title => 'foo' , - :host => '1' , - :data => 'localhost', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.0.0.127.IN-ADDR.ARPA.foo,PTR,0.0.127.IN-ADDR.ARPA.record') - .with_content(/^1\s+IN\s+PTR\s+localhost\.$/) - } - end - -end - - -describe 'dns::record::txt', :type => :define do - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'letting the host be defined by the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :data => 'baz', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,TXT,example.com.record') - .with_content(/^foo\s+IN\s+TXT\s+"baz"$/) - } - end - - context 'assigning a different host than the resource name' do - let :params do { - :zone => 'example.com', - :title => 'foo' , - :host => 'bar' , - :data => 'baz.example.com', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.foo,TXT,example.com.record') - .with_content(/^bar\s+IN\s+TXT\s+"baz"$/) - } - end - -end - diff --git a/spec/defines/dns__record__mx_spec.rb b/spec/defines/dns__record__mx_spec.rb deleted file mode 100644 index 7e1dfd92..00000000 --- a/spec/defines/dns__record__mx_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::mx', :type => :define do - let(:title) { 'mxtest' } - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'passing an implicit origin' do - let :params do { - :zone => 'example.com', - :data => 'mailserver.example.com' - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.mxtest,example.com,MX,10,mailserver.example.com.record').with_content(/^@\s+IN\s+MX\s+10\s+mailserver\.example\.com\.$/) } - end - - context 'passing an explicit origin and preference' do - let :params do { - :zone => 'example.com', - :data => 'ittybittymx.example.com', - :host => 'branchoffice', - :preference => 22 - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.mxtest,example.com,MX,22,ittybittymx.example.com.record').with_content(/^branchoffice\s+IN\s+MX\s+22\s+ittybittymx\.example\.com\.$/) } - end - - context 'passing a wrong (out-of-range) preference' do - let :params do { - :zone => 'example.com', - :data => 'badpref.example.com', - :preference => 65537 - } end - it { should raise_error(Puppet::Error, /must be an integer within 0-65536/) } - end - - context 'passing a wrong (string) preference' do - let :params do { - :zone => 'example.com', - :data => 'worsepref.example.com', - :preference => 'highest' - } end - it { should raise_error(Puppet::Error, /must be an integer within 0-65536/) } - end - - context 'passing a wrong (numeric top-level domain) zone' do - let :params do { - :zone => 'one.618', - :data => 'goldenratio.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing a wrong (numeric) zone' do - let :params do { - :zone => 123, - :data => 'badzone.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing a wrong (IP address) zone' do - let :params do { - :zone => '192.168.1.1', - :data => 'ipaddrzone.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing wrong (numeric) data' do - let :params do { - :zone => 'example.com', - :data => 456 - } end - it { should raise_error(Puppet::Error, /must be a valid hostname/) } - end - - context 'passing wrong (IP address) data' do - let :params do { - :zone => 'example.com', - :data => '192.168.4.4' - } end - it { should raise_error(Puppet::Error, /must be a valid hostname/) } - end - -end - diff --git a/spec/defines/dns__record__ns_spec.rb b/spec/defines/dns__record__ns_spec.rb deleted file mode 100644 index 04f96940..00000000 --- a/spec/defines/dns__record__ns_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::ns', :type => :define do - let(:title) { 'example.com' } - let(:facts) { { :concat_basedir => '/dne' } } - - context 'passing an implicit host' do - let :params do { - :zone => 'example.com', - :data => 'ns3' - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.example.com,example.com,NS,ns3.record').with_content(/^example.com\s+IN\s+NS\s+ns3$/) } - end - - context 'passing an explicit host' do - let :params do { - :zone => 'example.com', - :host => 'delegated-zone', - :data => 'ns4.jp.example.net.' - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.delegated-zone,example.com,NS,ns4.jp.example.net..record').with_content(/^delegated-zone\s+IN\s+NS\s+ns4.jp.example.net\.$/) } - end - - context 'passing a wrong (numeric top-level domain) zone' do - let :params do { - :zone => 'six.022', - :data => 'avogadro.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing a wrong (numeric) zone' do - let :params do { - :zone => 789, - :data => 'badzone.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing a wrong (IP address) zone' do - let :params do { - :zone => '192.168.2.1', - :data => 'ipaddrzone.example.com' - } end - it { should raise_error(Puppet::Error, /must be a valid domain name/) } - end - - context 'passing wrong (numeric) data' do - let :params do { - :zone => 'example.com', - :data => 443 - } end - it { should raise_error(Puppet::Error, /must be a valid hostname/) } - end - - context 'passing wrong (IP address) data' do - let :params do { - :zone => 'example.com', - :data => '192.168.4.5' - } end - it { should raise_error(Puppet::Error, /must be a valid hostname/) } - end -end - diff --git a/spec/defines/dns__record__ptr__by_ip_spec.rb b/spec/defines/dns__record__ptr__by_ip_spec.rb deleted file mode 100644 index c0f9b319..00000000 --- a/spec/defines/dns__record__ptr__by_ip_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::ptr::by_ip', :type => :define do - let(:title) { '192.0.2.15' } - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'passing a valid host and zone' do - let :params do { - :host => 'test1', - :zone => 'example.com', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => 'test1.example.com', - }) } - end - - context 'passing a valid host and empty zone' do - let :params do { - :host => 'test2.example.com', - :zone => '', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => 'test2.example.com', - }) } - end - - context 'passing a valid host but not passing a zone' do - let :params do { - :host => 'test3.example.com', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => 'test3.example.com', - }) } - end - - context 'passing a host of `@` and a valid zone' do - let :params do { - :host => '@', - :zone => 'example.com', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => 'example.com', - }) } - end - - context 'passing a host of `@` and an empty zone' do - let :params do { - :host => '@', - :zone => '', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => '@', - }) } - end - - context 'passing a host of `@` but not passing a zone' do - let :params do { - :host => '@', - } end - it { should_not raise_error } - it { should contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with({ - 'host' => '15', - 'zone' => '2.0.192.IN-ADDR.ARPA', - 'data' => '@', - }) } - end - -end - diff --git a/spec/defines/dns__record__txt_spec.rb b/spec/defines/dns__record__txt_spec.rb deleted file mode 100644 index 542313ba..00000000 --- a/spec/defines/dns__record__txt_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'spec_helper' - -describe 'dns::record::txt', :type => :define do - let(:title) { 'txttest' } - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'passing a simple string should result in a quoted string' do - let :params do { - :host => 'txttest', - :zone => 'example.com', - :data => 'testing', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(/^txttest\s+IN\s+TXT\s+"testing"$/) } - end - - context 'passing a string that includes a quote character should result in the dns module escaping the quote' do - let :params do { - :host => 'txttest', - :zone => 'example.com', - :data => 'this is a "test"', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(/^txttest\s+IN\s+TXT\s+"this is a \\"test\\""$/) } - end - - context 'passing a long string should result in the dns module splitting that string into multiple quoted strings' do - let :params do { - :host => 'txttest', - :zone => 'example.com', - :data => 'this is a ' + 'very '*60 + 'long test', - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(/^txttest\s+IN\s+TXT\s+"this is a very.*" ".*very long test"$/) } - end - -end - diff --git a/spec/defines/dns__record_spec.rb b/spec/defines/dns__record_spec.rb deleted file mode 100644 index 37846c08..00000000 --- a/spec/defines/dns__record_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'spec_helper' - -describe 'dns::record', :type => :define do - let(:title) { 'recordtest' } - let(:facts) { { :concat_basedir => '/tmp' } } - - context 'passing a LOC record' do - let :params do { - :zone => 'example.com', - :host => 'saturnv', - :dns_class => 'IN', - :record => 'LOC', - :data => '34 42 40.126 N 86 39 21.248 W 203m 10m 100m 10m', - :ttl => '1h45m10s' - } end - it { should_not raise_error } - it { should contain_concat__fragment('db.example.com.recordtest.record').with_content(/^saturnv\s+1h45m10s\s+IN\s+LOC\s+34 42 40.126 N 86 39 21.248 W 203m 10m 100m 10m$/) } - end - - context 'passing a wrong (out-of-range) TTL' do - let :params do { - :zone => 'example.com', - :host => 'badttl', - :dns_class => 'IN', - :record => 'A', - :data => '172.16.104.1', - :ttl => 2147483648 - } end - it { should raise_error(Puppet::Error, /must be an integer within 0-2147483647/) } - end - - context 'passing a wrong (string) TTL' do - let :params do { - :zone => 'example.com', - :host => 'textttl', - :dns_class => 'IN', - :record => 'A', - :data => '172.16.104.2', - :ttl => '4scoreand7years' - } end - it { should raise_error(Puppet::Error, /explicitly specified time units/) } - end - -end - diff --git a/spec/defines/dns__server__options_spec.rb b/spec/defines/dns__server__options_spec.rb deleted file mode 100644 index 540ca272..00000000 --- a/spec/defines/dns__server__options_spec.rb +++ /dev/null @@ -1,421 +0,0 @@ -require 'spec_helper' - -describe 'dns::server::options', :type => :define do - let :pre_condition do - 'class { "::dns::server": }' - end - - let(:facts) { { :osfamily => 'Debian', :concat_basedir => '/tmp' } } - - let(:title) { '/etc/bind/named.conf.options' } - - context 'passing valid array to forwarders' do - let :params do - { :forwarders => [ '8.8.8.8', '4.4.4.4' ] } - end - it { should contain_file('/etc/bind/named.conf.options') } - it { should contain_file('/etc/bind/named.conf.options').with_content(/8\.8\.8\.8;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/4\.4\.4\.4;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_ensure("present") } - it { should contain_file('/etc/bind/named.conf.options').with_owner("bind") } - it { should contain_file('/etc/bind/named.conf.options').with_group("bind") } - end - - context 'passing valid array to transfers' do - let :params do - { :transfers => ['192.168.0.3', '192.168.0.4'] } - end - it { should contain_file('/etc/bind/named.conf.options') } - it { should contain_file('/etc/bind/named.conf.options').with_content(/192\.168\.0\.3;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/192\.168\.0\.4;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_ensure("present") } - it { should contain_file('/etc/bind/named.conf.options').with_owner("bind") } - it { should contain_file('/etc/bind/named.conf.options').with_group("bind") } - it { should contain_file('/etc/bind/named.conf.options').with_content(/allow-transfer/) } - end - - context 'passing a string to forwarders' do - let :params do - { :forwarders => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing a string to transfers' do - let :params do - { :transfers => '192.168.0.3' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing valid array to listen_on' do - let :params do - { :listen_on => [ '10.11.12.13', '192.168.1.2' ] } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/10\.11\.12\.13;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/192\.168\.1\.2;$/) } - end - - context 'passing custom port to listen_on_port' do - let :params do - { :listen_on_port => 5300 } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/port 5300;/) } - end - - context 'passing a string to listen_on' do - let :params do - { :listen_on => '10.9.8.7' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'when passing valid array to listen_on_ipv6' do - let :params do - { :listen_on_ipv6 => [ '2001:db8:1::1', '2001:db8:2::/124' ] } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/2001:db8:1::1;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/2001:db8:2::\/124;$/) } - end - - context 'when passing a string to listen_on_ipv6' do - let :params do - { :listen_on_ipv6 => '2001:db8:1::1' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'when the listen_on_ipv6 option is not provided' do - let(:params) { {} } - it { should contain_file('/etc/bind/named.conf.options').with_content(/listen-on-v6 \{.+?any;.+?\}/) } - end - - context 'passing a string to recursion' do - let :params do - { :allow_recursion => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing a valid recursion allow range' do - let :params do - { :allow_recursion => ['10.0.0.1'] } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/10\.0\.0\.1;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/allow-recursion \{$/) } - end - - context 'passing a wrong string to slave name' do - let :params do - { :check_names_slave => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /The check name policy/) } - end - - context 'passing a wrong string to master name' do - let :params do - { :check_names_master => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /The check name policy/) } - end - - context 'passing a wrong string to response name' do - let :params do - { :check_names_response => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /The check name policy/) } - end - - context 'passing a valid string to a check name' do - let :params do - { :check_names_master => 'warn', - :check_names_slave => 'ignore', - :check_names_response => 'warn', - } - end - it { should contain_file('/etc/bind/named.conf.options') } - it { should contain_file('/etc/bind/named.conf.options').with_content(/check-names master warn;/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/check-names slave ignore;$/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/check-names response warn;$/) } - end - - context 'passing no string to check name' do - it { should contain_file('/etc/bind/named.conf.options').without_content(/check-names master/)} - it { should contain_file('/etc/bind/named.conf.options').without_content(/check-names slave/)} - it { should contain_file('/etc/bind/named.conf.options').without_content(/check-names response/)} - end - - context 'passing a string to the allow query' do - let :params do - { :allow_query => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing a valid array to the allow query' do - let :params do - { :allow_query => ['8.8.8.8'] } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/8\.8\.8\.8;/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/allow-query/) } - end - - context 'passing no statistic channel ip' do - let :params do - {} - end - it { should_not contain_file('/etc/bind/named.conf.options').with_content(/statistics-channels/) } - end - - context 'passing a valid ip and a valid port' do - let :params do - { :statistic_channel_ip => '127.0.0.1', - :statistic_channel_port => 12455 } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/statistics-channels/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/inet 127\.0\.0\.1 port 12455;/) } - end - - context 'passing no zone_notify setting' do - let :params do - {} - end - it { should contain_file('/etc/bind/named.conf.options').without_content(/^\s*notify /) } - end - - context 'passing a wrong zone_notify setting' do - let :params do - { :zone_notify => 'maybe' } - end - it { should raise_error(Puppet::Error, /The zone_notify/) } - end - - context 'passing yes to zone_notify' do - let :params do - { :zone_notify => 'yes' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/^\s*notify yes;/) } - end - - context 'passing no to zone_notify' do - let :params do - { :zone_notify => 'no' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/^\s*notify no;/) } - end - - context 'passing master-only to zone_notify' do - let :params do - { :zone_notify => 'master-only' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/^\s*notify master-only;/) } - end - - context 'passing explicit to zone_notify' do - let :params do - { :zone_notify => 'explicit' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/^\s*notify explicit;/) } - end - - context 'passing no also_notify setting' do - let :params do - {} - end - it { should contain_file('/etc/bind/named.conf.options').without_content(/^\s*also-notify /) } - end - - context 'passing a string to also_notify' do - let :params do - { :also_notify => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing a valid array to also_notify' do - let :params do - { :also_notify => [ '8.8.8.8' ] } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/^\s*also-notify \{/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/8\.8\.8\.8;/) } - end - - context 'default value of dnssec_validation on RedHat 5' do - let :facts do - { :osfamily => 'RedHat', :operatingsystemmajrelease => '5', :concat_basedir => '/tmp' } - end - it { should contain_file('/etc/bind/named.conf.options').without_content(/dnssec-validation/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable no/) } - end - - context 'default value of dnssec_validation on RedHat 6' do - let :facts do - { :osfamily => 'RedHat', :operatingsystemmajrelease => '6', :concat_basedir => '/tmp' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-validation auto/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable yes/) } - end - - context 'default value of dnssec_validation on Debian' do - let :facts do - { :osfamily => 'Debian', :concat_basedir => '/tmp' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-validation auto/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable yes/) } - end - - context 'passing `false` to dnssec_enable' do - let :params do - { :dnssec_enable => false} - end - it { should contain_file('/etc/bind/named.conf.options').without_content(/dnssec-validation/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable no/) } - end - - context 'passing `absent` to dnssec_validation' do - let :params do - { :dnssec_validation => 'absent' } - end - it { should contain_file('/etc/bind/named.conf.options').without_content(/dnssec-validation/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable yes/) } - end - - context 'passing `auto` to dnssec_validation' do - let :params do - { :dnssec_validation => 'auto' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-validation auto/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable yes/) } - end - - context 'passing `yes` to dnssec_validation' do - let :params do - { :dnssec_validation => 'yes' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-validation yes/) } - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-enable yes/) } - end - - context 'passing `no` to dnssec_validation' do - let :params do - { :dnssec_validation => 'no' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/dnssec-validation no/) } - end - context 'with not empty zone generation' do - let :params do - { :no_empty_zones => true } - end - - it { should contain_file('/etc/bind/named.conf.options').with_content(/empty-zones-enable no/) } - - end - - context 'passing no notify_source' do - let :params do - {} - end - it { should_not contain_file('/etc/bind/named.conf.options').with_content(/notify-source/) } - end - - context 'passing notify_source a valid ip' do - let :params do - { :notify_source => '127.0.0.1' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/notify-source 127\.0\.0\.1;/) } - end - - context 'passing notify_source an invalid string' do - let :params do - { :notify_source => 'fooberry' } - end - it { should raise_error(Puppet::Error, /is not an ip/) } - end - - context 'passing no transfer_source' do - let :params do - {} - end - it { should_not contain_file('/etc/bind/named.conf.options').with_content(/transfer-source/) } - end - - context 'passing transfer_source a valid ip' do - let :params do - { :transfer_source => '127.0.0.1' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/transfer-source 127\.0\.0\.1;/) } - end - - context 'passing transfer_source an invalid string' do - let :params do - { :transfer_source => 'fooberry' } - end - it { should raise_error(Puppet::Error, /is not an ip/) } - end - - context 'passing a non-default data directory' do - let :params do - { :data_dir => '/foo/bar' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/directory *"\/foo\/bar"/) } - end - - context 'passing a non-absolute data directory' do - let :params do - { :data_dir => 'foo/bar' } - end - it { should raise_error(Puppet::Error, /is not an absolute/) } - end - - context 'passing a non-default working directory' do - let :params do - { :working_dir => '/foo/bar', - :query_log_enable => true - } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/\/foo\/bar\/named_querylog/) } - end - - context 'passing a non-absolute working directory' do - let :params do - { :working_dir => 'foo/bar', - :query_log_enable => true - } - end - it { should raise_error(Puppet::Error, /is not an absolute/) } - end - - context 'not passing forward_policy' do - it { should contain_file('/etc/bind/named.conf.options').without_content(/ forward /) } - end - - context 'passing forward_policy as `only`' do - let :params do - { :forward_policy => 'only' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/ forward *only *;/) } - end - - context 'passing forward_policy as `first`' do - let :params do - { :forward_policy => 'first' } - end - it { should contain_file('/etc/bind/named.conf.options').with_content(/ forward *first *;/) } - end - - context 'passing forward_policy as an invalid string' do - let :params do - { :forward_policy => 'snozberry' } - end - it { should raise_error(Puppet::Error, /The forward_policy must be/) } - end - - context 'passing forward_policy as an invalid type' do - let :params do - { :forward_policy => ['first'] } - end - it { should raise_error(Puppet::Error, /is not a string/) } - end - -end - diff --git a/spec/defines/dns__tsig_spec.rb b/spec/defines/dns__tsig_spec.rb deleted file mode 100644 index 8d02dab5..00000000 --- a/spec/defines/dns__tsig_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -describe 'dns::tsig' do - let(:facts) {{ :osfamily => 'Debian', :concat_basedir => '/mock_dir' }} - let(:title) { 'ns3' } - let :pre_condition do - 'class { "::dns::server::config": }' - end - - context 'passing valid array to server' do - let :params do - { :server => [ '192.168.0.1', '192.168.0.2' ], - :algorithm => 'hmac-md5', - :secret => 'La/E5CjG9O+os1jq0a2jdA==' } - end - it { should_not raise_error } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include') } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(/key ns3\. \{/) } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(/server 192\.168\.0\.1/) } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(/server 192\.168\.0\.2/) } - end - - context 'passing valid string to server' do - let :params do - { :server => '192.168.0.1', - :algorithm => 'hmac-md5', - :secret => 'La/E5CjG9O+os1jq0a2jdA==' } - end - it { should_not raise_error } - - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include') } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(/key ns3\. \{/) } - it { should contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(/server 192\.168\.0\.1/) } - end - -end - diff --git a/spec/defines/dns__zone_spec.rb b/spec/defines/dns__zone_spec.rb deleted file mode 100644 index 360f5e67..00000000 --- a/spec/defines/dns__zone_spec.rb +++ /dev/null @@ -1,394 +0,0 @@ -require 'spec_helper' - -describe 'dns::zone' do - let(:pre_condition) { 'include dns::server::params' } - let(:title) { 'test.com' } - let(:facts) {{ :osfamily => 'Debian', :concat_basedir => '/mock_dir' }} - - describe 'passing something other than an array to $allow_query ' do - let(:params) {{ :allow_query => '127.0.0.1' }} - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - describe 'passing an array to $allow_query' do - let(:params) {{ :allow_query => ['192.0.2.0', '2001:db8::/32'] }} - it { should_not raise_error } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-query/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/192\.0\.2\.0;/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/2001:db8::\/32/) - } - end - - describe 'passing something other than an array to $allow_transfer' do - let(:params) {{ :allow_transfer => '127.0.0.1' }} - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - describe 'passing something other than an array to $allow_forwarder' do - let(:params) {{ :allow_forwarder => '127.0.0.1' }} - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - describe 'passing an array to $allow_transfer and $allow_forwarder' do - let(:params) do { - :allow_transfer => ['192.0.2.0', '2001:db8::/32'], - :allow_forwarder => ['8.8.8.8', '208.67.222.222'] - } - end - it { should_not raise_error } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-transfer/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/192\.0\.2\.0/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forwarders/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward first;/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/8.8.8.8/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/2001:db8::\/32/) - } - it { should contain_concat('/var/lib/bind/zones/db.test.com.stage') } - it { should contain_concat__fragment('db.test.com.soa'). - with_content(/_SERIAL_/) - } - it { should contain_exec('bump-test.com-serial'). - with_refreshonly('true') - } - end - - context 'when ask to have a only forward policy' do - let :params do - { :allow_transfer => [], - :allow_forwarder => ['8.8.8.8', '208.67.222.222'], - :forward_policy => 'only' - } - end - it 'should have a forward only policy' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward only;/) - end - end - - context 'with no explicit forward policy or forwarder' do - let(:params) {{ :allow_transfer => ['192.0.2.0', '2001:db8::/32'] }} - it 'should not have any forwarder configuration' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward/) - end - end - - context 'with a delegation-only zone' do - let :params do - { :zone_type => 'delegation-only' - } - end - it 'should only have a type delegation-only entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/zone \"test.com\" \{\s*type delegation-only;\s*\}/) - end - end - - - context 'with a forward zone' do - let :params do - { :allow_transfer => ['123.123.123.123'], - :allow_forwarder => ['8.8.8.8', '208.67.222.222'], - :forward_policy => 'only', - :zone_type => 'forward' - } - end - it 'should have a type forward entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/type forward/) - end - it 'should not have allow_tranfer entry' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-transfer/) - end - it 'should not have file entry' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/file/) - end - it 'should have a forward-policy entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward only/) - end - it 'should have a forwarders entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forwarders/) - end - it 'should have an "absent" zone file concat' do - should contain_concat('/var/lib/bind/zones/db.test.com.stage').with({ - :ensure => "absent" - }) - end - end - - context 'with a slave zone' do - let :params do - { :slave_masters => ['123.123.123.123'], - :zone_type => 'slave' - } - end - it 'should have a type slave entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/type slave/) - end - it 'should have file entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/file/) - end - it 'should have masters entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/masters.*123.123.123.123 *;/) - end - it 'should not have allow_tranfer entry' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-transfer/) - end - it 'should not have any forward information' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward/) - end - it 'should have an "absent" zone file concat' do - should contain_concat('/var/lib/bind/zones/db.test.com.stage').with({ - :ensure => "absent" - }) - end - end - - context 'with a slave zone with multiple masters' do - let :params do - { :slave_masters => ['123.123.123.123', '234.234.234.234'], - :zone_type => 'slave' - } - end - it 'should have masters entry with all masters joined by ;' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/masters.*123.123.123.123 *;[ \n]*234.234.234.234 *;/) - end - end - - context 'with a stub zone' do - let :params do - { :slave_masters => ['123.123.123.123'], - :zone_type => 'stub' - } - end - it 'should have a type stub entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/type stub/) - end - it 'should have file entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/file/) - end - it 'should have masters entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/masters.*123.123.123.123 *;/) - end - it 'should not have allow_tranfer entry' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-transfer/) - end - it 'should not have any forward information' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward/) - end - it 'should have an "absent" zone file concat' do - should contain_concat('/var/lib/bind/zones/db.test.com.stage').with({ - :ensure => "absent" - }) - end - end - - context 'with a stub zone with multiple masters' do - let :params do - { :slave_masters => ['123.123.123.123', '234.234.234.234'], - :zone_type => 'stub' - } - end - it 'should have masters entry with all masters joined by ;' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/masters.*123.123.123.123 *;[ \n]*234.234.234.234 *;/) - end - end - - context 'with a master zone' do - let :params do - { :allow_transfer => ['8.8.8.8','8.8.4.4'], - :allow_forwarder => ['8.8.8.8', '208.67.222.222'], - :forward_policy => 'only', - :zone_type => 'master' - } - end - it 'should have a type master entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/type master/) - end - it 'should have file entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/file/) - end - it 'should not have masters entry' do - should_not contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/masters/) - end - it 'should have allow_tranfer entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-transfer/) - end - it 'should have a forward-policy entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forward /) - end - it 'should have a forwarders entry' do - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/forwarders/) - end - it 'should have a zone file concat' do - should contain_concat('/var/lib/bind/zones/db.test.com.stage').with({ - :ensure => "present" - }) - end - end - - context 'passing no zone_notify setting' do - let :params do - {} - end - it { should contain_concat__fragment('named.conf.local.test.com.include').without_content(/ notify /) } - end - - context 'passing a wrong zone_notify setting' do - let :params do - { :zone_notify => 'maybe' } - end - it { should raise_error(Puppet::Error, /The zone_notify/) } - end - - context 'passing yes to zone_notify' do - let :params do - { :zone_notify => 'yes' } - end - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/ notify yes;/) } - end - - context 'passing no to zone_notify' do - let :params do - { :zone_notify => 'no' } - end - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/ notify no;/) } - end - - context 'passing master-only to zone_notify' do - let :params do - { :zone_notify => 'master-only' } - end - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/ notify master-only;/) } - end - - context 'passing explicit to zone_notify' do - let :params do - { :zone_notify => 'explicit' } - end - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/ notify explicit;/) } - end - - context 'passing no also_notify setting' do - let :params do - {} - end - it { should contain_concat__fragment('named.conf.local.test.com.include').without_content(/ also-notify /) } - end - - context 'passing a string to also_notify' do - let :params do - { :also_notify => '8.8.8.8' } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - context 'passing a valid array to also_notify' do - let :params do - { :also_notify => [ '8.8.8.8' ] } - end - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/ also-notify \{/) } - it { should contain_concat__fragment('named.conf.local.test.com.include').with_content(/8\.8\.8\.8;/) } - end - - context 'passing true to reverse' do - let(:title) { '10.23.45' } - let :params do - { :reverse => true } - end - it { should contain_concat__fragment('named.conf.local.10.23.45.include').with_content(/zone "10\.23\.45\.in-addr\.arpa"/) } - it { should contain_concat__fragment('db.10.23.45.soa').with_content(/\$ORIGIN\s+10\.23\.45\.in-addr\.arpa\./) } - end - - context 'passing reverse to reverse' do - let(:title) { '10.23.45' } - let :params do - { :reverse => 'reverse' } - end - it { should contain_concat__fragment('named.conf.local.10.23.45.include').with_content(/zone "45\.23\.10\.in-addr\.arpa"/) } - it { should contain_concat__fragment('db.10.23.45.soa').with_content(/\$ORIGIN\s+45\.23\.10\.in-addr\.arpa\./) } - end - - describe 'passing something other than an array to $allow_update ' do - let(:params) {{ :allow_update => '127.0.0.1' }} - it { should raise_error(Puppet::Error, /is not an Array/) } - end - - describe 'passing an empty array to $allow_update' do - let(:params) {{ :allow_update => [] }} - it { should_not raise_error } - it { - should contain_concat('/var/lib/bind/zones/db.test.com.stage'). - with({ :replace => true }) - } - end - - describe 'passing an array to $allow_update' do - let(:params) {{ :allow_update => ['192.0.2.0', '2001:db8::/32'] }} - it { should_not raise_error } - it { - should contain_concat('/var/lib/bind/zones/db.test.com.stage'). - with({ :replace => false }) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/allow-update/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/192\.0\.2\.0;/) - } - it { - should contain_concat__fragment('named.conf.local.test.com.include'). - with_content(/2001:db8::\/32/) - } - end -end - diff --git a/spec/defines/dns_acl_spec.rb b/spec/defines/dns_acl_spec.rb new file mode 100644 index 00000000..661476dd --- /dev/null +++ b/spec/defines/dns_acl_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'Dns::Acl', type: :define do + let(:title) { 'trusted' } + # let(:pre_condition) { 'include dns::server::params' } + let :facts do + { + concat_basedir: '/tmp', + osfamily: 'Debian', + } + end + + context 'passing a string to data' do + let :params do + { + data: '192.168.0.0/24', + } + end + + # it { is_expected.to raise_error(Puppet::Error, /is not an Array/) } + it { is_expected.to raise_error(Puppet::Error, %r{expects an Array}) } + end + context 'passing an array to data' do + let :params do + { + data: ['192.168.0.0/24'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('named.conf.local.acl.trusted.include') + .with_content(%r{acl trusted}) + .with_content(%r{192.168.0.0/24;}) + } + end +end diff --git a/spec/defines/dns_key_spec.rb b/spec/defines/dns_key_spec.rb new file mode 100644 index 00000000..cc41c206 --- /dev/null +++ b/spec/defines/dns_key_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe 'Dns::Key', type: :define do + let(:title) { 'rspec-key' } + let(:pre_condition) { 'include ::dns::server' } + # let(:post_condition) { 'include ::dns::tsig' } + let(:default_facts) { { concat_basedir: '/tmp' } } + + context 'On a Debian OS' do + let(:facts) do + default_facts.merge(osfamily: 'Debian') + end + + it { is_expected.to contain_file('/tmp/rspec-key-secret.sh').with_notify('Exec[dnssec-keygen-rspec-key]') } + it { is_expected.to contain_exec('dnssec-keygen-rspec-key').with_command(%r{USER rspec-key$}) } + it { + is_expected.to contain_exec('get-secret-from-rspec-key') + .with_command('/tmp/rspec-key-secret.sh') + .with_creates('/etc/bind/bind.keys.d/rspec-key.secret') + .with_require(['Exec[dnssec-keygen-rspec-key]', 'File[/etc/bind/bind.keys.d]', 'File[/tmp/rspec-key-secret.sh]']) + } + it { is_expected.to contain_file('/etc/bind/bind.keys.d/rspec-key.secret').with_require('Exec[get-secret-from-rspec-key]') } + it { is_expected.to contain_concat('/etc/bind/bind.keys.d/rspec-key.key') } + ['rspec-key.key-header', 'rspec-key.key-secret', 'rspec-key.key-footer'].each do |fragment| + it { + is_expected.to contain_concat__fragment(fragment) + .with_target('/etc/bind/bind.keys.d/rspec-key.key') + .with_require(['Exec[get-secret-from-rspec-key]', 'File[/etc/bind/bind.keys.d/rspec-key.secret]']) + } + end + it { is_expected.to contain_concat__fragment('rspec-key.key-secret').with_source('/etc/bind/bind.keys.d/rspec-key.secret') } + end + + context 'On a RedHat OS' do + let(:facts) do + default_facts.merge(osfamily: 'RedHat') + end + + it { is_expected.to contain_file('/tmp/rspec-key-secret.sh').with_notify('Exec[dnssec-keygen-rspec-key]') } + it { is_expected.to contain_exec('dnssec-keygen-rspec-key').with_command(%r{USER rspec-key$}) } + it { + is_expected.to contain_exec('get-secret-from-rspec-key') + .with_command('/tmp/rspec-key-secret.sh') + .with_creates('/etc/named/bind.keys.d/rspec-key.secret') + .with_require(['Exec[dnssec-keygen-rspec-key]', 'File[/etc/named/bind.keys.d]', 'File[/tmp/rspec-key-secret.sh]']) + } + it { is_expected.to contain_file('/etc/named/bind.keys.d/rspec-key.secret').with_require('Exec[get-secret-from-rspec-key]') } + it { is_expected.to contain_concat('/etc/named/bind.keys.d/rspec-key.key') } + ['rspec-key.key-header', 'rspec-key.key-secret', 'rspec-key.key-footer'].each do |fragment| + it { + is_expected.to contain_concat__fragment(fragment) + .with_target('/etc/named/bind.keys.d/rspec-key.key') + .with_require(['Exec[get-secret-from-rspec-key]', 'File[/etc/named/bind.keys.d/rspec-key.secret]']) + } + end + it { is_expected.to contain_concat__fragment('rspec-key.key-secret').with_source('/etc/named/bind.keys.d/rspec-key.secret') } + end +end diff --git a/spec/defines/dns_record_a_spec.rb b/spec/defines/dns_record_a_spec.rb new file mode 100644 index 00000000..c19e7b58 --- /dev/null +++ b/spec/defines/dns_record_a_spec.rb @@ -0,0 +1,297 @@ +require 'spec_helper' + +describe 'Dns::Record::A', type: :define do + let(:title) { 'atest' } + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'passing a single ip address with ptr=>false' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: '192.168.128.42', + ptr: 'false', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.42$}) } + it { is_expected.not_to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') } + end + + context 'passing a single ip address with ptr=>true' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: '192.168.128.42', + ptr: 'true', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.42$}) } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^42\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing a single ip address with ptr=>all' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: '192.168.128.42', + ptr: 'all', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record').with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.42$}) } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.42.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^42\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing multiple ip addresses with ptr=>false' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'false', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record') + .with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$}) + } + it { is_expected.not_to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') } + end + + context 'passing multiple ip addresses with ptr=>true' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'true', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record') + .with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$}) + } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing multiple ip addresses with ptr=>all' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.atest,A,example.com.record') + .with_content(%r{^atest\s+IN\s+A\s+192\.168\.128\.68\natest\s+IN\s+A\s+192\.168\.128\.69\natest\s+IN\s+A\s+192\.168\.128\.70$}) + } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.69.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^69\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.70.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^70\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class A network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let(:pre_condition) do + [ + 'include ::dns::server', + 'dns::zone { "192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,192.IN-ADDR.ARPA.record') + .with_content(%r{^68\.128\.168\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class B network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let(:pre_condition) do + [ + 'include ::dns::server', + 'dns::zone { "168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\.128\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class C network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + + let(:pre_condition) do + [ + 'include ::dns::server', + 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class A and class B network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let(:pre_condition) do + [ + 'include ::dns::server', + 'dns::zone { "192.IN-ADDR.ARPA": }', + 'dns::zone { "168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\.128\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class A and class C network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let :pre_condition do + [ + 'include ::dns::server', + 'dns::zone { "192.IN-ADDR.ARPA": }', + 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class B and class C network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let :pre_condition do + [ + 'include ::dns::server', + 'dns::zone { "168.192.IN-ADDR.ARPA": }', + 'dns::zone { "128.168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end + + context 'passing ptr=>true with class A, class B and class C network defined' do + let :params do + { + host: 'atest', + zone: 'example.com', + data: ['192.168.128.68', '192.168.128.69', '192.168.128.70'], + ptr: 'all', + } + end + let :pre_condition do + [ + 'include ::dns::server', + 'dns::zone{ "192.IN-ADDR.ARPA": }', + 'dns::zone{ "168.192.IN-ADDR.ARPA": }', + 'dns::zone{ "128.168.192.IN-ADDR.ARPA": }', + ] + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.128.168.192.IN-ADDR.ARPA.68.128.168.192.IN-ADDR.ARPA,PTR,128.168.192.IN-ADDR.ARPA.record') + .with_content(%r{^68\s+IN\s+PTR\s+atest\.example\.com\.$}) + } + end +end diff --git a/spec/defines/dns_record_mx_spec.rb b/spec/defines/dns_record_mx_spec.rb new file mode 100644 index 00000000..d5c94840 --- /dev/null +++ b/spec/defines/dns_record_mx_spec.rb @@ -0,0 +1,119 @@ +require 'spec_helper' + +describe 'Dns::Record::Mx', type: :define do + let(:title) { 'mxtest' } + let(:pre_condition) { 'include ::dns::server' } + let(:facts) { { concat_basedir: '/tmp' } } + + context 'passing an implicit origin' do + let :params do + { + zone: 'example.com', + data: 'mailserver.example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.mxtest,example.com,MX,10,mailserver.example.com.record') + .with_content(%r{^@\s+IN\s+MX\s+10\s+mailserver\.example\.com\.$}) + } + end + + context 'passing an explicit origin and preference' do + let :params do + { + zone: 'example.com', + data: 'ittybittymx.example.com', + host: 'branchoffice', + preference: 22, + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.mxtest,example.com,MX,22,ittybittymx.example.com.record') + .with_content(%r{^branchoffice\s+IN\s+MX\s+22\s+ittybittymx\.example\.com\.$}) + } + end + + context 'passing a wrong (out-of-range) preference' do + let :params do + { + zone: 'example.com', + data: 'badpref.example.com', + preference: 65_537, + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be an integer within 0-65536}) } + end + + context 'passing a wrong (string) preference' do + let :params do + { + zone: 'example.com', + data: 'worsepref.example.com', + preference: 'highest', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{must be an integer within 0-65536}) } + it { is_expected.to raise_error(Puppet::Error) } + end + + context 'passing a wrong (numeric top-level domain) zone' do + let :params do + { + zone: 'one.618', + data: 'goldenratio.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing a wrong (numeric) zone' do + let :params do + { + zone: '123', + data: 'badzone.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing a wrong (IP address) zone' do + let :params do + { + zone: '192.168.1.1', + data: 'ipaddrzone.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing wrong (numeric) data' do + let :params do + { + zone: 'example.com', + data: '456', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid hostname}) } + end + + context 'passing wrong (IP address) data' do + let :params do + { + zone: 'example.com', + data: '192.168.4.4', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid hostname}) } + end +end diff --git a/spec/defines/dns_record_ns_spec.rb b/spec/defines/dns_record_ns_spec.rb new file mode 100644 index 00000000..b42c88a7 --- /dev/null +++ b/spec/defines/dns_record_ns_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' + +describe 'Dns::Record::Ns', type: :define do + let(:title) { 'example.com' } + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/dne', + } + end + + context 'passing an implicit host' do + let :params do + { + zone: 'example.com', + data: 'ns3', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.example.com,example.com,NS,ns3.record').with_content(%r{^example.com\s+IN\s+NS\s+ns3$}) } + end + + context 'passing an explicit host' do + let :params do + { + zone: 'example.com', + host: 'delegated-zone', + data: 'ns4.jp.example.net.', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.delegated-zone,example.com,NS,ns4.jp.example.net..record') + .with_content(%r{^delegated-zone\s+IN\s+NS\s+ns4.jp.example.net\.$}) + } + end + + context 'passing a wrong (numeric top-level domain) zone' do + let :params do + { + zone: 'six.022', + data: 'avogadro.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing a wrong (numeric) zone' do + let :params do + { + zone: '789', + data: 'badzone.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing a wrong (IP address) zone' do + let :params do + { + zone: '192.168.2.1', + data: 'ipaddrzone.example.com', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid domain name}) } + end + + context 'passing wrong (numeric) data' do + let :params do + { + zone: 'example.com', + data: '443', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid hostname}) } + end + + context 'passing wrong (IP address) data' do + let :params do + { + zone: 'example.com', + data: '192.168.4.5', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be a valid hostname}) } + end +end diff --git a/spec/defines/dns_record_ptr_by_ip_spec.rb b/spec/defines/dns_record_ptr_by_ip_spec.rb new file mode 100644 index 00000000..fbd9b99c --- /dev/null +++ b/spec/defines/dns_record_ptr_by_ip_spec.rb @@ -0,0 +1,117 @@ +require 'spec_helper' + +describe 'Dns::Record::Ptr::By_ip', type: :define do + let(:title) { '192.0.2.15' } + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'passing a valid host and zone' do + let :params do + { + host: 'test1', + zone: 'example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: 'test1.example.com', + ) + } + end + + context 'passing a valid host and empty zone' do + let :params do + { + host: 'test2.example.com', + zone: '', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: 'test2.example.com', + ) + } + end + + context 'passing a valid host but not passing a zone' do + let :params do + { + host: 'test3.example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: 'test3.example.com', + ) + } + end + + context 'passing a host of `@` and a valid zone' do + let :params do + { + host: '@', + zone: 'example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: 'example.com', + ) + } + end + + context 'passing a host of `@` and an empty zone' do + let :params do + { + host: '@', + zone: '', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: '@', + ) + } + end + + context 'passing a host of `@` but not passing a zone' do + let :params do + { + host: '@', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_dns__record__ptr('15.2.0.192.IN-ADDR.ARPA').with( + host: '15', + zone: '2.0.192.IN-ADDR.ARPA', + data: '@', + ) + } + end +end diff --git a/spec/defines/dns_record_spec.rb b/spec/defines/dns_record_spec.rb new file mode 100644 index 00000000..1e290290 --- /dev/null +++ b/spec/defines/dns_record_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe 'dns::record', type: :define do + let(:title) { 'recordtest' } + let(:facts) { { concat_basedir: '/tmp' } } + let(:pre_condition) { 'include ::dns::server' } + + context 'passing a LOC record' do + let :params do + { + zone: 'example.com', + host: 'saturnv', + dns_class: 'IN', + record: 'LOC', + data: '34 42 40.126 N 86 39 21.248 W 203m 10m 100m 10m', + ttl: '1h45m10s', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.recordtest.record').with_content(%r{^saturnv\s+1h45m10s\s+IN\s+LOC\s+34 42 40.126 N 86 39 21.248 W 203m 10m 100m 10m$}) } + end + + context 'passing a wrong (out-of-range) TTL' do + let :params do + { + zone: 'example.com', + host: 'badttl', + dns_class: 'IN', + record: 'A', + data: '172.16.104.1', + ttl: 2_147_483_648, + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{must be an integer within 0-2147483647}) } + end + + context 'passing a wrong (string) TTL' do + let :params do + { + zone: 'example.com', + host: 'textttl', + dns_class: 'IN', + record: 'A', + data: '172.16.104.2', + ttl: '4scoreand7years', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{explicitly specified time units}) } + end +end diff --git a/spec/defines/dns_record_txt_spec.rb b/spec/defines/dns_record_txt_spec.rb new file mode 100644 index 00000000..3b27015d --- /dev/null +++ b/spec/defines/dns_record_txt_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe 'Dns::Record::Txt', type: :define do + let(:title) { 'txttest' } + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'passing a simple string is_expected.to result in a quoted string' do + let :params do + { + host: 'txttest', + zone: 'example.com', + data: 'testing', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(%r{^txttest\s+IN\s+TXT\s+"testing"$}) } + end + + context 'passing a string that includes a quote character is_expected.to result in the dns module escaping the quote' do + let :params do + { + host: 'txttest', + zone: 'example.com', + data: 'this is a "test"', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(%r{^txttest\s+IN\s+TXT\s+"this is a \\"test\\""$}) } + end + + context 'passing a long string is_expected.to result in the dns module splitting that string into multiple quoted strings' do + let :params do + { + host: 'txttest', + zone: 'example.com', + data: 'this is a ' + 'very ' * 60 + 'long test', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('db.example.com.txttest,TXT,example.com.record').with_content(%r{^txttest\s+IN\s+TXT\s+"this is a very.*\" \".*very long test\"$}) } + end +end diff --git a/spec/defines/dns_server_options_spec.rb b/spec/defines/dns_server_options_spec.rb new file mode 100644 index 00000000..5030af1e --- /dev/null +++ b/spec/defines/dns_server_options_spec.rb @@ -0,0 +1,622 @@ +require 'spec_helper' + +describe 'Dns::Server::Options', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + osfamily: 'Debian', + concat_basedir: '/tmp', + } + end + let(:title) { '/etc/bind/named.conf.options' } + + context 'passing valid array to forwarders' do + let :params do + { + forwarders: ['8.8.8.8', '4.4.4.4'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{8.8.8.8;$}) + .with_content(%r{4.4.4.4;$}) + .with_ensure('present') + .with_owner('bind') + .with_group('bind') + } + end + + context 'passing valid array to transfers' do + let :params do + { + transfers: ['192.168.0.3', '192.168.0.4'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{192.168.0.3;$}) + .with_content(%r{192.168.0.4;$}) + .with_ensure('present') + .with_owner('bind') + .with_group('bind') + .with_content(%r{allow-transfer}) + } + end + + context 'passing a string to forwarders' do + let :params do + { + forwarders: '8.8.8.8', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'passing a string to transfers' do + let :params do + { + transfers: '192.168.0.3', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'passing valid array to listen_on' do + let :params do + { + listen_on: ['10.11.12.13', '192.168.1.2'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{10.11.12.13;$}) + .with_content(%r{192.168.1.2;$}) + } + end + + context 'passing custom port to listen_on_port' do + let :params do + { + listen_on_port: 5300, + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{port 5300;}) } + end + + context 'passing a string to listen_on' do + let :params do + { + listen_on: '10.9.8.7', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'when passing valid array to listen_on_ipv6' do + let :params do + { + listen_on_ipv6: ['2001:db8:1::1', '2001:db8:2::/124'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{2001:db8:1::1;$}) + .with_content(%r{2001:db8:2::/124;$}) + } + end + + context 'when passing a string to listen_on_ipv6' do + let :params do + { + listen_on_ipv6: '2001:db8:1::1', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'when the listen_on_ipv6 option is not provided' do + let :params do + {} + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{listen-on-v6 \{.+?any;.+?\}}) + } + end + + context 'passing a string to recursion' do + let :params do + { + allow_recursion: '8.8.8.8', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'passing a valid recursion allow range' do + let :params do + { + allow_recursion: ['10.0.0.1'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{10.0.0.1;$}) + .with_content(%r{allow-recursion \{$}) + } + end + + context 'passing a wrong string to slave name' do + let :params do + { + check_names_slave: '8.8.8.8', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The check name policy}) } + end + + context 'passing a wrong string to master name' do + let :params do + { + check_names_master: '8.8.8.8', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The check name policy}) } + end + + context 'passing a wrong string to response name' do + let :params do + { + check_names_response: '8.8.8.8', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The check name policy}) } + end + + context 'passing a valid string to a check name' do + let :params do + { + check_names_master: 'warn', + check_names_slave: 'ignore', + check_names_response: 'warn', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{check-names master warn;}) + .with_content(%r{check-names slave ignore;$}) + .with_content(%r{check-names response warn;$}) + } + end + + context 'passing no string to check name' do + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .without_content(%r{check-names master}) + .without_content(%r{check-names slave}) + .without_content(%r{check-names response}) + } + end + + context 'passing a string to the allow query' do + let :params do + { + allow_query: '8.8.8.8', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'passing a valid array to the allow query' do + let :params do + { + allow_query: ['8.8.8.8'], + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{8.8.8.8;}) + .with_content(%r{allow-query}) + } + end + + context 'passing no statistic channel ip' do + let :params do + {} + end + + it { is_expected.not_to contain_file('/etc/bind/named.conf.options').with_content(%r{statistics-channels}) } + end + + context 'passing a valid ip and a valid port' do + let :params do + { + statistic_channel_ip: '127.0.0.1', + statistic_channel_port: '12455', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{statistics-channels}) } + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{inet 127.0.0.1 port 12455;}) } + end + + context 'passing no zone_notify setting' do + let :params do + {} + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').without_content(%r{^\s*notify }) } + end + + context 'passing a wrong zone_notify setting' do + let :params do + { + zone_notify: 'maybe', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The zone_notify}) } + end + + context 'passing yes to zone_notify' do + let :params do + { + zone_notify: 'yes', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{^\s*notify yes;}) } + end + + context 'passing no to zone_notify' do + let :params do + { + zone_notify: 'no', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{^\s*notify no;}) } + end + + context 'passing master-only to zone_notify' do + let :params do + { + zone_notify: 'master-only', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{^\s*notify master-only;}) + } + end + + context 'passing explicit to zone_notify' do + let :params do + { + zone_notify: 'explicit', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{^\s*notify explicit;}) } + end + + context 'passing no also_notify setting' do + let :params do + {} + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').without_content(%r{^\s*also-notify }) } + end + + context 'passing a string to also_notify' do + let :params do + { + also_notify: '8.8.8.8', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + + context 'passing a valid array to also_notify' do + let :params do + { + also_notify: ['8.8.8.8'], + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{^\s*also-notify \{}) } + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{8\.8\.8\.8;}) } + end + + context 'default value of dnssec_validation on RedHat 5' do + let :facts do + { + osfamily: 'RedHat', + operatingsystemmajrelease: '5', + concat_basedir: '/tmp', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .without_content(%r{dnssec-validation}) + .with_content(%r{dnssec-enable no}) + } + end + + context 'default value of dnssec_validation on RedHat 6' do + let :facts do + { + osfamily: 'RedHat', + operatingsystemmajrelease: '6', + concat_basedir: '/tmp', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{dnssec-validation auto}) + .with_content(%r{dnssec-enable yes}) + } + end + + context 'default value of dnssec_validation on Debian' do + let :facts do + { + osfamily: 'Debian', + concat_basedir: '/tmp', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{dnssec-validation auto}) + .with_content(%r{dnssec-enable yes}) + } + end + + context 'passing `false` to dnssec_enable' do + let :params do + { + dnssec_enable: false, + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .without_content(%r{dnssec-validation}) + .with_content(%r{dnssec-enable no}) + } + end + + context 'passing `absent` to dnssec_validation' do + let :params do + { + dnssec_validation: 'absent', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .without_content(%r{dnssec-validation}) + .with_content(%r{dnssec-enable yes}) + } + end + + context 'passing `auto` to dnssec_validation' do + let :params do + { + dnssec_validation: 'auto', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{dnssec-validation auto}) + .with_content(%r{dnssec-enable yes}) + } + end + + context 'passing `yes` to dnssec_validation' do + let :params do + { + dnssec_validation: 'yes', + } + end + + it { + is_expected.to contain_file('/etc/bind/named.conf.options') + .with_content(%r{dnssec-validation yes}) + .with_content(%r{dnssec-enable yes}) + } + end + + context 'passing `no` to dnssec_validation' do + let :params do + { + dnssec_validation: 'no', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{dnssec-validation no}) } + end + context 'with not empty zone generation' do + let :params do + { + no_empty_zones: true, + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{empty-zones-enable no}) } + end + + context 'passing no notify_source' do + let :params do + {} + end + + it { is_expected.not_to contain_file('/etc/bind/named.conf.options').with_content(%r{notify-source}) } + end + + context 'passing notify_source a valid ip' do + let :params do + { + notify_source: '127.0.0.1', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{notify-source 127.0.0.1;}) } + end + + context 'passing notify_source an invalid string' do + let :params do + { + notify_source: 'fooberry', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{is not an ip}) } + end + + context 'passing no transfer_source' do + let :params do + {} + end + + it { is_expected.not_to contain_file('/etc/bind/named.conf.options').with_content(%r{transfer-source}) } + end + + context 'passing transfer_source a valid ip' do + let :params do + { + transfer_source: '127.0.0.1', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{transfer-source 127.0.0.1;}) } + end + + context 'passing transfer_source an invalid string' do + let :params do + { + transfer_source: 'fooberry', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{is not an ip}) } + end + + context 'passing a non-default data directory' do + let :params do + { + data_dir: '/foo/bar', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{directory *"/foo/bar"}) } + end + + context 'passing a non-absolute data directory' do + let :params do + { + data_dir: 'foo/bar', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an absolute}) } + it { is_expected.to raise_error(Puppet::Error) } + end + + context 'passing a non-default working directory' do + let :params do + { + working_dir: '/foo/bar', + query_log_enable: true, + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{/foo/bar/named_querylog}) } + end + + context 'passing a non-absolute working directory' do + let :params do + { + working_dir: 'foo/bar', + query_log_enable: true, + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an absolute}) } + it { is_expected.to raise_error(Puppet::Error) } + end + + context 'not passing forward_policy' do + it { is_expected.to contain_file('/etc/bind/named.conf.options').without_content(%r{ forward }) } + end + + context 'passing forward_policy as `only`' do + let :params do + { + forward_policy: 'only', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{ forward *only *;}) } + end + + context 'passing forward_policy as `first`' do + let :params do + { + forward_policy: 'first', + } + end + + it { is_expected.to contain_file('/etc/bind/named.conf.options').with_content(%r{ forward *first *;}) } + end + + context 'passing forward_policy as an invalid string' do + let :params do + { + forward_policy: 'snozberry', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The forward_policy must be}) } + end + + context 'passing forward_policy as an invalid type' do + let :params do + { + forward_policy: ['first'], + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or String}) } + end +end diff --git a/spec/defines/dns_tsig_spec.rb b/spec/defines/dns_tsig_spec.rb new file mode 100644 index 00000000..ea463e7c --- /dev/null +++ b/spec/defines/dns_tsig_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'Dns::Tsig', type: :define do + let(:title) { 'ns3' } + let(:pre_condition) { 'include dns::server' } + # let(:post_condition) { 'include dns::server::service' } + let :facts do + { + osfamily: 'Debian', + concat_basedir: '/mock_dir', + } + end + + context 'passing valid array to server' do + let :params do + { + server: ['192.168.0.1', '192.168.0.2'], + algorithm: 'hmac-md5', + secret: 'La/E5CjG9O+os1jq0a2jdA==', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include') } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(%r{key ns3\. \{}) } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(%r{server 192\.168\.0\.1}) } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(%r{server 192\.168\.0\.2}) } + end + + context 'passing valid string to server' do + let :params do + { + server: '192.168.0.1', + algorithm: 'hmac-md5', + secret: 'La/E5CjG9O+os1jq0a2jdA==', + } + end + + it { is_expected.not_to raise_error } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include') } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(%r{key ns3\. \{}) } + it { is_expected.to contain_concat__fragment('named.conf.local.tsig.ns3.include').with_content(%r{server 192\.168\.0\.1}) } + end +end diff --git a/spec/defines/dns_zone_spec.rb b/spec/defines/dns_zone_spec.rb new file mode 100644 index 00000000..dd78ada5 --- /dev/null +++ b/spec/defines/dns_zone_spec.rb @@ -0,0 +1,460 @@ +require 'spec_helper' + +describe 'Dns::Zone', type: :define do + let(:pre_condition) { 'include dns::server' } + let(:title) { 'test.com' } + let :facts do + { + osfamily: 'Debian', + concat_basedir: '/mock_dir', + } + end + + describe 'passing something other than an array to $allow_query ' do + let :params do + { + allow_query: '127.0.0.1', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + describe 'passing an array to $allow_query' do + let :params do + { + allow_query: ['192.0.2.0', '2001:db8::/32'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-query}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{192.0.2.0;}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{2001:db8::/32}) + } + end + describe 'passing something other than an array to $allow_transfer' do + let :params do + { + allow_transfer: '127.0.0.1', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + describe 'passing something other than an array to $allow_forwarder' do + let :params do + { + allow_forwarder: '127.0.0.1', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + describe 'passing an array to $allow_transfer and $allow_forwarder' do + let(:params) do + { + allow_transfer: ['192.0.2.0', '2001:db8::/32'], + allow_forwarder: ['8.8.8.8', '208.67.222.222'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-transfer}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{192.0.2.0}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forwarders}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward first;}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{8.8.8.8}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{2001:db8::/32}) + } + it { is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') } + it { + is_expected.to contain_concat__fragment('db.test.com.soa') + .with_content(%r{_SERIAL_}) + } + it { + is_expected.to contain_exec('bump-test.com-serial') + .with_refreshonly('true') + } + end + context 'when ask to have a only forward policy' do + let :params do + { + allow_transfer: [], + allow_forwarder: ['8.8.8.8', '208.67.222.222'], + forward_policy: 'only', + } + end + + it 'is_expected.to have a forward only policy' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward only;}) + end + end + context 'with no explicit forward policy or forwarder' do + let :params do + { + allow_transfer: ['192.0.2.0', '2001:db8::/32'], + } + end + + it 'is_expected.to not have any forwarder configuration' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward}) + end + end + context 'with a delegation-only zone' do + let :params do + { + zone_type: 'delegation-only', + } + end + + it 'is_expected.to only have a type delegation-only entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{zone "test.com" \{\s*type delegation-only;\s*\}}) + end + end + context 'with a forward zone' do + let :params do + { + allow_transfer: ['123.123.123.123'], + allow_forwarder: ['8.8.8.8', '208.67.222.222'], + forward_policy: 'only', + zone_type: 'forward', + } + end + + it 'is_expected.to have a type forward entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{type forward}) + end + it 'is_expected.to not have allow_tranfer entry' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-transfer}) + end + it 'is_expected.to not have file entry' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{file}) + end + it 'is_expected.to have a forward-policy entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward only}) + end + it 'is_expected.to have a forwarders entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forwarders}) + end + it 'is_expected.to have an "absent" zone file concat' do + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with_ensure('absent') + end + end + context 'with a slave zone' do + let :params do + { + slave_masters: ['123.123.123.123'], + zone_type: 'slave', + } + end + + it 'is_expected.to have a type slave entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{type slave}) + end + it 'is_expected.to have file entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{file}) + end + it 'is_expected.to have masters entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{masters.*123.123.123.123 *;}) + end + it 'is_expected.to not have allow_tranfer entry' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-transfer}) + end + it 'is_expected.to not have any forward information' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward}) + end + it 'is_expected.to have an "absent" zone file concat' do + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with_ensure('absent') + end + end + context 'with a slave zone with multiple masters' do + let :params do + { + slave_masters: ['123.123.123.123', '234.234.234.234'], + zone_type: 'slave', + } + end + + it 'is_expected.to have masters entry with all masters joined by ;' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{masters.*123.123.123.123 *;[ \n]*234.234.234.234 *;}) + end + end + context 'with a stub zone' do + let :params do + { + slave_masters: ['123.123.123.123'], + zone_type: 'stub', + } + end + + it 'is_expected.to have a type stub entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{type stub}) + end + it 'is_expected.to have file entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{file}) + end + it 'is_expected.to have masters entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{masters.*123.123.123.123 *;}) + end + it 'is_expected.to not have allow_tranfer entry' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-transfer}) + end + it 'is_expected.to not have any forward information' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward}) + end + it 'is_expected.to have an "absent" zone file concat' do + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with_ensure('absent') + end + end + context 'with a stub zone with multiple masters' do + let :params do + { + slave_masters: ['123.123.123.123', '234.234.234.234'], + zone_type: 'stub', + } + end + + it 'is_expected.to have masters entry with all masters joined by ;' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{masters.*123.123.123.123 *;[ \n]*234.234.234.234 *;}) + end + end + context 'with a master zone' do + let :params do + { + allow_transfer: ['8.8.8.8', '8.8.4.4'], + allow_forwarder: ['8.8.8.8', '208.67.222.222'], + forward_policy: 'only', + zone_type: 'master', + } + end + + it 'is_expected.to have a type master entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{type master}) + end + it 'is_expected.to have file entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{file}) + end + it 'is_expected.to not have masters entry' do + is_expected.not_to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{masters}) + end + it 'is_expected.to have allow_tranfer entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-transfer}) + end + it 'is_expected.to have a forward-policy entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forward }) + end + it 'is_expected.to have a forwarders entry' do + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{forwarders}) + end + it 'is_expected.to have a zone file concat' do + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with_ensure('present') + end + end + context 'passing no zone_notify setting' do + let :params do + {} + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').without_content(%r{ notify }) } + end + context 'passing a wrong zone_notify setting' do + let :params do + { + zone_notify: 'maybe', + } + end + + it { is_expected.to raise_error(Puppet::Error, %r{The zone_notify}) } + end + context 'passing yes to zone_notify' do + let :params do + { + zone_notify: 'yes', + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{ notify yes;}) } + end + context 'passing no to zone_notify' do + let :params do + { + zone_notify: 'no', + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{ notify no;}) } + end + context 'passing master-only to zone_notify' do + let :params do + { + zone_notify: 'master-only', + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{ notify master-only;}) } + end + context 'passing explicit to zone_notify' do + let :params do + { + zone_notify: 'explicit', + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{ notify explicit;}) } + end + context 'passing no also_notify setting' do + let :params do + {} + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').without_content(%r{ also-notify }) } + end + context 'passing a string to also_notify' do + let :params do + { + also_notify: '8.8.8.8', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + context 'passing a valid array to also_notify' do + let :params do + { + also_notify: ['8.8.8.8'], + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{ also-notify \{}) } + it { is_expected.to contain_concat__fragment('named.conf.local.test.com.include').with_content(%r{8.8.8.8;}) } + end + context 'passing true to reverse' do + let(:title) { '10.23.45' } + let :params do + { + reverse: true, + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.10.23.45.include').with_content(%r{zone "10.23.45.in-addr.arpa"}) } + it { is_expected.to contain_concat__fragment('db.10.23.45.soa').with_content(%r{\$ORIGIN\s+10.23.45.in-addr.arpa.}) } + end + context 'passing reverse to reverse' do + let(:title) { '10.23.45' } + let :params do + { + reverse: 'reverse', + } + end + + it { is_expected.to contain_concat__fragment('named.conf.local.10.23.45.include').with_content(%r{zone "45.23.10.in-addr.arpa"}) } + it { is_expected.to contain_concat__fragment('db.10.23.45.soa').with_content(%r{\$ORIGIN\s+45.23.10.in-addr.arpa.}) } + end + describe 'passing something other than an array to $allow_update ' do + let :params do + { + allow_update: '127.0.0.1', + } + end + + # it { is_expected.to raise_error(Puppet::Error, %r{is not an Array}) } + it { is_expected.to raise_error(Puppet::Error, %r{expects a value of type Undef or Array}) } + end + describe 'passing an empty array to $allow_update' do + let :params do + { + allow_update: [], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with(replace: true) + } + end + describe 'passing an array to $allow_update' do + let :params do + { + allow_update: ['192.0.2.0', '2001:db8::/32'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat('/var/lib/bind/zones/db.test.com.stage') + .with(replace: false) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{allow-update}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{192\.0\.2\.0;}) + } + it { + is_expected.to contain_concat__fragment('named.conf.local.test.com.include') + .with_content(%r{2001:db8::\/32}) + } + end +end diff --git a/spec/hosts/example_spec.rb b/spec/hosts/example_spec.rb index 2421fc34..cdc11537 100644 --- a/spec/hosts/example_spec.rb +++ b/spec/hosts/example_spec.rb @@ -1,11 +1,15 @@ require 'spec_helper' describe 'testhost.example.com' do - - let(:facts) {{ :osfamily => 'RedHat', :concat_basedir => '/dne', :define_fact => "" }} + let :facts do + { + osfamily: 'RedHat', + concat_basedir: '/dne', + define_fact: '', + } + end context 'When given connected records that depend on each other' do - it { should compile } + it { is_expected.to compile } end - -end \ No newline at end of file +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b443393a..0d5efc0b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,47 @@ 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))) + rescue => e + RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" + end +end RSpec.configure do |c| - c.before do - # avoid "Only root can execute commands as other users" - Puppet.features.stubs(:root? => true) + 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 + end + c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] + c.after(:suite) do end -end \ No newline at end of file +end + +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) + end +end + +# 'spec_overrides' from sync.yml will appear below this line diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index f067e4bc..34f95cd6 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,33 +1,25 @@ -require 'beaker-rspec/spec_helper' -require 'beaker-rspec/helpers/serverspec' -require 'pry' +require 'beaker-rspec' +require 'beaker-puppet' +require 'beaker/puppet_install_helper' +require 'beaker/module_install_helper' +require 'beaker-task_helper' -unless ENV['BEAKER_provision'] == 'no' - hosts.each do |host| - # Install Puppet - if host.is_pe? - install_pe - else - install_puppet - end - end -end +# install_puppet_on(hosts, options) +run_puppet_install_helper_on(hosts) +configure_type_defaults_on(hosts) +install_ca_certs unless pe_install? +# install_puppet_agent_on(hosts) +# install_bolt_on(hosts) +# install_module_on(hosts) +# install_module_dependencies_on(hosts) RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - # Readable test descriptions c.formatter = :documentation # Configure all nodes in nodeset c.before :suite do - # Install module and dependencies - puppet_module_install(:source => proj_root, :module_name => 'dns') - hosts.each do |host| - on host, puppet('module', 'install', 'puppetlabs-stdlib'), { :acceptable_exit_codes => [0,1] } - on host, puppet('module', 'install', 'puppetlabs-concat'), { :acceptable_exit_codes => [0,1] } - end + install_module_on(hosts) + install_module_dependencies_on(hosts) end end - diff --git a/spec/type_aliases/dns_record_a_spec.rb b/spec/type_aliases/dns_record_a_spec.rb new file mode 100644 index 00000000..ab3f678d --- /dev/null +++ b/spec/type_aliases/dns_record_a_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'dns::record::a', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: ['1.2.3.4'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,A,example.com.record') + .with_content(%r{^foo\s+IN\s+A\s+1\.2\.3\.4$}) + } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: ['1.2.3.4'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,A,example.com.record') + .with_content(%r{^bar\s+IN\s+A\s+1\.2\.3\.4$}) + } + end +end diff --git a/spec/type_aliases/dns_record_aaaa_spec.rb b/spec/type_aliases/dns_record_aaaa_spec.rb new file mode 100644 index 00000000..68b1e3b5 --- /dev/null +++ b/spec/type_aliases/dns_record_aaaa_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'dns::record::aaaa', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: ['::1'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,AAAA,example.com.record') + .with_content(%r{^foo\s+IN\s+AAAA\s+::1$}) + } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: ['::1'], + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,AAAA,example.com.record') + .with_content(%r{^bar\s+IN\s+AAAA\s+::1$}) + } + end +end diff --git a/spec/type_aliases/dns_record_cname_spec.rb b/spec/type_aliases/dns_record_cname_spec.rb new file mode 100644 index 00000000..33424399 --- /dev/null +++ b/spec/type_aliases/dns_record_cname_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'dns::record::cname', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: 'baz.example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,CNAME,example.com.record') + .with_content(%r{^foo\s+IN\s+CNAME\s+baz\.example\.com\.$}) + } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: 'baz.example.com', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,CNAME,example.com.record') + .with_content(%r{^bar\s+IN\s+CNAME\s+baz\.example\.com\.$}) + } + end +end diff --git a/spec/type_aliases/dns_record_mx_spec.rb b/spec/type_aliases/dns_record_mx_spec.rb new file mode 100644 index 00000000..414c5bb2 --- /dev/null +++ b/spec/type_aliases/dns_record_mx_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' +describe 'dns::record::mx', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: 'baz.example.com', + preference: 10, + } + end + + it { is_expected.not_to raise_error } + # TODO: For some reason this fails and I haven't quite figured out why. + # Disable to make RSpec Tests work + # it { + # is_expected.to contain_concat__fragment('db.example.com.foo,MX,example.com.record') + # .with_content(%r{^foo\s+IN\s+MX\s+10\s+baz\.example\.com\.$}) + # } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: 'baz.example.com', + preference: 10, + } + end + + it { is_expected.not_to raise_error } + # TODO: For some reason this fails and I haven't quite figured out why. + # Disable to make RSpec Tests work + # it { + # is_expected.to contain_concat__fragment('db.example.com.foo,MX,example.com.record') + # .with_content(%r{^bar\s+IN\s+MX\s+10\s+baz\.example\.com\.$}) + # } + end +end diff --git a/spec/type_aliases/dns_record_ns_spec.rb b/spec/type_aliases/dns_record_ns_spec.rb new file mode 100644 index 00000000..5ab76017 --- /dev/null +++ b/spec/type_aliases/dns_record_ns_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'dns::record::ns', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: 'baz.example.com.', + } + end + + it { is_expected.not_to raise_error } + # TODO: For some reason this fails and I haven't quite figured out why. + # it { + # is_expected.to contain_concat__fragment('db.example.com.foo,NS,example.com.record') + # .with_content(%r{^foo\s+IN\s+NS\s+baz\.example\.com\.$}) + # } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: 'baz.example.com.', + } + end + + it { is_expected.not_to raise_error } + # TODO: For some reason this fails and I haven't quite figured out why. + # it { + # is_expected.to contain_concat__fragment('db.example.com.foo,NS,example.com.record') + # .with_content(%r{^bar\s+IN\s+NS\s+baz\.example\.com\.$}) + # } + end +end diff --git a/spec/type_aliases/dns_record_ptr_spec.rb b/spec/type_aliases/dns_record_ptr_spec.rb new file mode 100644 index 00000000..a0b50678 --- /dev/null +++ b/spec/type_aliases/dns_record_ptr_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'dns::record::ptr', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { '1' } + let :params do + { + zone: '0.0.127.in-addr.arpa', + data: 'localhost', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.0.0.127.in-addr.arpa.1,PTR,0.0.127.in-addr.arpa.record') + .with_content(%r{^1\s+IN\s+PTR\s+localhost\.$}) + } + end + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: '0.0.127.in-addr.arpa', + host: '1', + data: 'localhost', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.0.0.127.in-addr.arpa.foo,PTR,0.0.127.in-addr.arpa.record') + .with_content(%r{^1\s+IN\s+PTR\s+localhost\.$}) + } + end +end diff --git a/spec/type_aliases/dns_record_txt_spec.rb b/spec/type_aliases/dns_record_txt_spec.rb new file mode 100644 index 00000000..5936fafd --- /dev/null +++ b/spec/type_aliases/dns_record_txt_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'dns::record::txt', type: :define do + let(:pre_condition) { 'include ::dns::server' } + let :facts do + { + concat_basedir: '/tmp', + } + end + + context 'letting the host be defined by the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + data: 'baz', + } + end + + it { is_expected.not_to raise_error } + it { + is_expected.to contain_concat__fragment('db.example.com.foo,TXT,example.com.record') + .with_content(%r{^foo\s+IN\s+TXT\s+"baz"$}) + } + end + + context 'assigning a different host than the resource name' do + let(:title) { 'foo' } + let :params do + { + zone: 'example.com', + host: 'bar', + data: 'baz.example.com', + } + end + + it { is_expected.not_to raise_error } + # TODO: For some reason this fails and I haven't quite figured out why. + # it { + # is_expected.to contain_concat__fragment('db.example.com.foo,TXT,example.com.record') + # .with_content(%r{^bar\s+IN\s+TXT\s+"baz"$}) + # } + end +end