diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2240a97..a6b64e0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,281 +1,283 @@ # Contribution guidelines ## Table of contents * [Contributing](#contributing) * [Writing proper commits - short version](#writing-proper-commits-short-version) * [Writing proper commits - long version](#writing-proper-commits-long-version) * [Dependencies](#dependencies) * [Note for OS X users](#note-for-os-x-users) * [The test matrix](#the-test-matrix) * [Syntax and style](#syntax-and-style) * [Running the unit tests](#running-the-unit-tests) * [Unit tests in docker](#unit-tests-in-docker) * [Integration tests](#integration-tests) This module has grown over time based on a range of contributions from people using it. If you follow these contributing guidelines your patch will likely make it into a release a little more quickly. ## Contributing Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. [Contributor Code of Conduct](https://voxpupuli.org/coc/). * Fork the repo. * Create a separate branch for your change. * We only take pull requests with passing tests, and documentation. [travis-ci](http://travis-ci.org) runs the tests for us. You can also execute them locally. This is explained [in a later section](#the-test-matrix). * Checkout [our docs](https://voxpupuli.org/docs/reviewing_pr/) we use to review a module and the [official styleguide](https://puppet.com/docs/puppet/6.0/style_guide.html). They provide some guidance for new code that might help you before you submit a pull request. * Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, please add a test. * Squash your commits down into logical components. Make sure to rebase against our current master. * Push the branch to your fork and submit a pull request. Please be prepared to repeat some of these steps as our contributors review your code. +Also consider sending in your profile code that calls this component module as an acceptance test or provide it via an issue. This helps reviewers a lot to test your use case and prevents future regressions! + ## Writing proper commits - short version * Make commits of logical units. * Check for unnecessary whitespace with "git diff --check" before committing. * Commit using Unix line endings (check the settings around "crlf" in git-config(1)). * Do not check in commented out code or unneeded files. * The first line of the commit message should be a short description (50 characters is the soft limit, excluding ticket number(s)), and should skip the full stop. * Associate the issue in the message. The first line should include the issue number in the form "(#XXXX) Rest of message". * The body should provide a meaningful commit message, which: *uses the imperative, present tense: `change`, not `changed` or `changes`. * includes motivation for the change, and contrasts its implementation with the previous behavior. * Make sure that you have tests for the bug you are fixing, or feature you are adding. * Make sure the test suites passes after your commit: * When introducing a new feature, make sure it is properly documented in the README.md ## Writing proper commits - long version 1. Make separate commits for logically separate changes. Please break your commits down into logically consistent units which include new or changed tests relevant to the rest of the change. The goal of doing this is to make the diff easier to read for whoever is reviewing your code. In general, the easier your diff is to read, the more likely someone will be happy to review it and get it into the code base. If you are going to refactor a piece of code, please do so as a separate commit from your feature or bug fix changes. We also really appreciate changes that include tests to make sure the bug is not re-introduced, and that the feature is not accidentally broken. Describe the technical detail of the change(s). If your description starts to get too long, that is a good sign that you probably need to split up your commit into more finely grained pieces. Commits which plainly describe the things which help reviewers check the patch and future developers understand the code are much more likely to be merged in with a minimum of bike-shedding or requested changes. Ideally, the commit message would include information, and be in a form suitable for inclusion in the release notes for the version of Puppet that includes them. Please also check that you are not introducing any trailing whitespace or other "whitespace errors". You can do this by running "git diff --check" on your changes before you commit. 2. Sending your patches To submit your changes via a GitHub pull request, we _highly_ recommend that you have them on a topic branch, instead of directly on `master`. It makes things much easier to keep track of, especially if you decide to work on another thing before your first change is merged in. GitHub has some pretty good [general documentation](http://help.github.com/) on using their site. They also have documentation on [creating pull requests](http://help.github.com/send-pull-requests/). In general, after pushing your topic branch up to your repository on GitHub, you can switch to the branch in the GitHub UI and click "Pull Request" towards the top of the page in order to open a pull request. 3. Update the related GitHub issue. If there is a GitHub issue associated with the change you submitted, then you should update the ticket to include the location of your branch, along with any other commentary you may wish to make. ## Dependencies The testing and development tools have a bunch of dependencies, all managed by [bundler](http://bundler.io/) according to the [Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). By default the tests use a baseline version of Puppet. If you have Ruby 2.x or want a specific version of Puppet, you must set an environment variable such as: ```sh export PUPPET_VERSION="~> 5.5.6" ``` You can install all needed gems for spec tests into the modules directory by running: ```sh bundle install --path .vendor/ --without development system_tests release --jobs "$(nproc)" ``` If you also want to run acceptance tests: ```sh bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)" ``` Our all in one solution if you don't know if you need to install or update gems: ```sh bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)"; bundle update; bundle clean ``` As an alternative to the `--jobs "$(nproc)` parameter, you can set an environment variable: ```sh BUNDLE_JOBS="$(nproc)" ``` ### Note for OS X users `nproc` isn't a valid command under OS x. As an alternative, you can do: ```sh --jobs "$(sysctl -n hw.ncpu)" ``` ## The test matrix ### Syntax and style The test suite will run [Puppet Lint](http://puppet-lint.com/) and [Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to check various syntax and style things. You can run these locally with: ```sh bundle exec rake lint bundle exec rake validate ``` It will also run some [Rubocop](http://batsov.com/rubocop/) tests against it. You can run those locally ahead of time with: ```sh bundle exec rake rubocop ``` ### Running the unit tests The unit test suite covers most of the code, as mentioned above please add tests if you're adding new functionality. If you've not used [rspec-puppet](http://rspec-puppet.com/) before then feel free to ask about how best to test your new feature. To run the linter, the syntax checker and the unit tests: ```sh bundle exec rake test ``` To run your all the unit tests ```sh bundle exec rake spec ``` To run a specific spec test set the `SPEC` variable: ```sh bundle exec rake spec SPEC=spec/foo_spec.rb ``` #### Unit tests in docker Some people don't want to run the dependencies locally or don't want to install ruby. We ship a Dockerfile that enables you to run all unit tests and linting. You only need to run: ```sh docker build . ``` Please ensure that a docker daemon is running and that your user has the permission to talk to it. You can specify a remote docker host by setting the `DOCKER_HOST` environment variable. it will copy the content of the module into the docker image. So it will not work if a Gemfile.lock exists. ### Integration tests The unit tests just check the code runs, not that it does exactly what we want on a real machine. For that we're using [beaker](https://github.com/puppetlabs/beaker). This fires up a new virtual machine (using vagrant) and runs a series of simple tests against it after applying the module. You can run this with: ```sh bundle exec rake acceptance ``` This will run the tests on the module's default nodeset. You can override the nodeset used, e.g., ```sh BEAKER_set=centos-7-x64 bundle exec rake acceptance ``` There are default rake tasks for the various acceptance test modules, e.g., ```sh bundle exec rake beaker:centos-7-x64 bundle exec rake beaker:ssh:centos-7-x64 ``` If you don't want to have to recreate the virtual machine every time you can use `BEAKER_destroy=no` and `BEAKER_provision=no`. On the first run you will at least need `BEAKER_provision` set to yes (the default). The Vagrantfile for the created virtual machines will be in `.vagrant/beaker_vagrant_files`. Beaker also supports docker containers. We also use that in our automated CI pipeline at [travis-ci](http://travis-ci.org). To use that instead of Vagrant: ```sh PUPPET_INSTALL_TYPE=agent BEAKER_IS_PE=no BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian10-64{hypervisor=docker} BEAKER_destroy=yes bundle exec rake beaker ``` You can replace the string `debian10` with any common operating system. The following strings are known to work: * ubuntu1604 * ubuntu1804 * debian8 * debian9 * debian10 * centos6 * centos7 * centos8 The easiest way to debug in a docker container is to open a shell: ```sh docker exec -it -u root ${container_id_or_name} bash ``` The source of this file is in our [modulesync_config](https://github.com/voxpupuli/modulesync_config/blob/master/moduleroot/.github/CONTRIBUTING.md.erb) repository. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..cacadf2 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,3 @@ +# Vox Pupuli Security Policy + +Our vulnerabilities reporting process is at https://voxpupuli.org/security/ diff --git a/.msync.yml b/.msync.yml index 8864fc0..4c7999c 100644 --- a/.msync.yml +++ b/.msync.yml @@ -1 +1 @@ -modulesync_config_version: '2.12.0' +modulesync_config_version: '3.0.0' diff --git a/.rubocop.yml b/.rubocop.yml index c2ebc88..c0fd488 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,546 +1,2 @@ -require: rubocop-rspec -AllCops: -# Puppet Server 5 defaults to jruby 1.7 so TargetRubyVersion must stay at 1.9 until we drop support for puppet 5 - TargetRubyVersion: 1.9 - Include: - - ./**/*.rb - Exclude: - - files/**/* - - vendor/**/* - - .vendor/**/* - - pkg/**/* - - spec/fixtures/**/* - - Gemfile - - Rakefile - - Guardfile - - Vagrantfile -Lint/ConditionPosition: - Enabled: True - -Lint/ElseLayout: - Enabled: True - -Lint/UnreachableCode: - Enabled: True - -Lint/UselessComparison: - Enabled: True - -Lint/EnsureReturn: - Enabled: True - -Lint/HandleExceptions: - Enabled: True - -Lint/LiteralInCondition: - Enabled: True - -Lint/ShadowingOuterLocalVariable: - Enabled: True - -Lint/LiteralInInterpolation: - Enabled: True - -Style/HashSyntax: - Enabled: True - -Style/RedundantReturn: - Enabled: True - -Layout/EndOfLine: - Enabled: False - -Lint/AmbiguousOperator: - Enabled: True - -Lint/AssignmentInCondition: - Enabled: True - -Layout/SpaceBeforeComment: - Enabled: True - -Style/AndOr: - Enabled: True - -Style/RedundantSelf: - Enabled: True - -Metrics/BlockLength: - Enabled: False - -# Method length is not necessarily an indicator of code quality -Metrics/MethodLength: - Enabled: False - -# Module length is not necessarily an indicator of code quality -Metrics/ModuleLength: - Enabled: False - -Style/WhileUntilModifier: - Enabled: True - -Lint/AmbiguousRegexpLiteral: - Enabled: True - -Security/Eval: - Enabled: True - -Lint/BlockAlignment: - Enabled: True - -Lint/DefEndAlignment: - Enabled: True - -Lint/EndAlignment: - Enabled: True - -Lint/DeprecatedClassMethods: - Enabled: True - -Lint/Loop: - Enabled: True - -Lint/ParenthesesAsGroupedExpression: - Enabled: True - -Lint/RescueException: - Enabled: True - -Lint/StringConversionInInterpolation: - Enabled: True - -Lint/UnusedBlockArgument: - Enabled: True - -Lint/UnusedMethodArgument: - Enabled: True - -Lint/UselessAccessModifier: - Enabled: True - -Lint/UselessAssignment: - Enabled: True - -Lint/Void: - Enabled: True - -Layout/AccessModifierIndentation: - Enabled: True - -Style/AccessorMethodName: - Enabled: True - -Style/Alias: - Enabled: True - -Layout/AlignArray: - Enabled: True - -Layout/AlignHash: - Enabled: True - -Layout/AlignParameters: - Enabled: True - -Metrics/BlockNesting: - Enabled: True - -Style/AsciiComments: - Enabled: True - -Style/Attr: - Enabled: True - -Style/BracesAroundHashParameters: - Enabled: True - -Style/CaseEquality: - Enabled: True - -Layout/CaseIndentation: - Enabled: True - -Style/CharacterLiteral: - Enabled: True - -Style/ClassAndModuleCamelCase: - Enabled: True - -Style/ClassAndModuleChildren: - Enabled: False - -Style/ClassCheck: - Enabled: True - -# Class length is not necessarily an indicator of code quality -Metrics/ClassLength: - Enabled: False - -Style/ClassMethods: - Enabled: True - -Style/ClassVars: - Enabled: True - -Style/WhenThen: - Enabled: True - -Style/WordArray: - Enabled: True - -Style/UnneededPercentQ: - Enabled: True - -Layout/Tab: - Enabled: True - -Layout/SpaceBeforeSemicolon: - Enabled: True - -Layout/TrailingBlankLines: - Enabled: True - -Layout/SpaceInsideBlockBraces: - Enabled: True - -Layout/SpaceInsideBrackets: - Enabled: True - -Layout/SpaceInsideHashLiteralBraces: - Enabled: True - -Layout/SpaceInsideParens: - Enabled: True - -Layout/LeadingCommentSpace: - Enabled: True - -Layout/SpaceBeforeFirstArg: - Enabled: True - -Layout/SpaceAfterColon: - Enabled: True - -Layout/SpaceAfterComma: - Enabled: True - -Layout/SpaceAfterMethodName: - Enabled: True - -Layout/SpaceAfterNot: - Enabled: True - -Layout/SpaceAfterSemicolon: - Enabled: True - -Layout/SpaceAroundEqualsInParameterDefault: - Enabled: True - -Layout/SpaceAroundOperators: - Enabled: True - -Layout/SpaceBeforeBlockBraces: - Enabled: True - -Layout/SpaceBeforeComma: - Enabled: True - -Style/CollectionMethods: - Enabled: True - -Layout/CommentIndentation: - Enabled: True - -Style/ColonMethodCall: - Enabled: True - -Style/CommentAnnotation: - Enabled: True - -# 'Complexity' is very relative -Metrics/CyclomaticComplexity: - Enabled: False - -Style/ConstantName: - Enabled: True - -Style/Documentation: - Enabled: False - -Style/DefWithParentheses: - Enabled: True - -Style/PreferredHashMethods: - Enabled: True - -Layout/DotPosition: - EnforcedStyle: trailing - -Style/DoubleNegation: - Enabled: True - -Style/EachWithObject: - Enabled: True - -Layout/EmptyLineBetweenDefs: - Enabled: True - -Layout/IndentArray: - Enabled: True - -Layout/IndentHash: - Enabled: True - -Layout/IndentationConsistency: - Enabled: True - -Layout/IndentationWidth: - Enabled: True - -Layout/EmptyLines: - Enabled: True - -Layout/EmptyLinesAroundAccessModifier: - Enabled: True - -Style/EmptyLiteral: - Enabled: True - -# Configuration parameters: AllowURI, URISchemes. -Metrics/LineLength: - Enabled: False - -Style/MethodCallWithoutArgsParentheses: - Enabled: True - -Style/MethodDefParentheses: - Enabled: True - -Style/LineEndConcatenation: - Enabled: True - -Layout/TrailingWhitespace: - Enabled: True - -Style/StringLiterals: - Enabled: True - -Style/TrailingCommaInArguments: - Enabled: True - -Style/TrailingCommaInLiteral: - Enabled: True - -Style/GlobalVars: - Enabled: True - -Style/GuardClause: - Enabled: True - -Style/IfUnlessModifier: - Enabled: True - -Style/MultilineIfThen: - Enabled: True - -Style/NegatedIf: - Enabled: True - -Style/NegatedWhile: - Enabled: True - -Style/Next: - Enabled: True - -Style/SingleLineBlockParams: - Enabled: True - -Style/SingleLineMethods: - Enabled: True - -Style/SpecialGlobalVars: - Enabled: True - -Style/TrivialAccessors: - Enabled: True - -Style/UnlessElse: - Enabled: True - -Style/VariableInterpolation: - Enabled: True - -Style/VariableName: - Enabled: True - -Style/WhileUntilDo: - Enabled: True - -Style/EvenOdd: - Enabled: True - -Style/FileName: - Enabled: True - -Style/For: - Enabled: True - -Style/Lambda: - Enabled: True - -Style/MethodName: - Enabled: True - -Style/MultilineTernaryOperator: - Enabled: True - -Style/NestedTernaryOperator: - Enabled: True - -Style/NilComparison: - Enabled: True - -Style/FormatString: - Enabled: True - -Style/MultilineBlockChain: - Enabled: True - -Style/Semicolon: - Enabled: True - -Style/SignalException: - Enabled: True - -Style/NonNilCheck: - Enabled: True - -Style/Not: - Enabled: True - -Style/NumericLiterals: - Enabled: True - -Style/OneLineConditional: - Enabled: True - -Style/OpMethod: - Enabled: True - -Style/ParenthesesAroundCondition: - Enabled: True - -Style/PercentLiteralDelimiters: - Enabled: True - -Style/PerlBackrefs: - Enabled: True - -Style/PredicateName: - Enabled: True - -Style/RedundantException: - Enabled: True - -Style/SelfAssignment: - Enabled: True - -Style/Proc: - Enabled: True - -Style/RaiseArgs: - Enabled: True - -Style/RedundantBegin: - Enabled: True - -Style/RescueModifier: - Enabled: True - -# based on https://github.com/voxpupuli/modulesync_config/issues/168 -Style/RegexpLiteral: - EnforcedStyle: percent_r - Enabled: True - -Lint/UnderscorePrefixedVariableName: - Enabled: True - -Metrics/ParameterLists: - Enabled: False - -Lint/RequireParentheses: - Enabled: True - -Style/ModuleFunction: - Enabled: True - -Lint/Debugger: - Enabled: True - -Style/IfWithSemicolon: - Enabled: True - -Style/Encoding: - Enabled: True - -Style/BlockDelimiters: - Enabled: True - -Layout/MultilineBlockLayout: - Enabled: True - -# 'Complexity' is very relative -Metrics/AbcSize: - Enabled: False - -# 'Complexity' is very relative -Metrics/PerceivedComplexity: - Enabled: False - -Lint/UselessAssignment: - Enabled: True - -Layout/ClosingParenthesisIndentation: - Enabled: True - -# RSpec - -RSpec/BeforeAfterAll: - Exclude: - - spec/acceptance/**/* - -# We don't use rspec in this way -RSpec/DescribeClass: - Enabled: False - -# Example length is not necessarily an indicator of code quality -RSpec/ExampleLength: - Enabled: False - -RSpec/NamedSubject: - Enabled: False - -# disabled for now since they cause a lot of issues -# these issues aren't easy to fix -RSpec/RepeatedDescription: - Enabled: False - -RSpec/NestedGroups: - Enabled: False - -# this is broken on ruby1.9 -Layout/IndentHeredoc: - Enabled: False - -# disable Yaml safe_load. This is needed to support ruby2.0.0 development envs -Security/YAMLLoad: - Enabled: false - -# This affects hiera interpolation, as well as some configs that we push. -Style/FormatStringToken: - Enabled: false - -# This is useful, but sometimes a little too picky about where unit tests files -# are located. -RSpec/FilePath: - Enabled: false +inherit_gem: + voxpupuli-test: rubocop.yml diff --git a/.travis.yml b/.travis.yml index cbdb295..189fc4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,47 +1,48 @@ --- -dist: bionic +os: linux +dist: focal language: ruby cache: bundler before_install: - yes | gem update --system - bundle --version script: - 'bundle exec rake $CHECK' -matrix: +jobs: fast_finish: true include: - rvm: 2.4.4 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 5.0" CHECK=test - rvm: 2.5.3 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 6.0" CHECK=test_with_coveralls - rvm: 2.5.3 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 6.0" CHECK=rubocop - rvm: 2.4.4 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 5.0" CHECK=build DEPLOY_TO_FORGE=yes branches: only: - master - /^v\d/ notifications: email: false webhooks: https://voxpupu.li/incoming/travis irc: on_success: always on_failure: always channels: - "chat.freenode.org#voxpupuli-notifications" deploy: provider: puppetforge - user: puppet + username: puppet password: secure: "I/IK9bG88UOVll0hpuxluGp6IY5gicLaDHug/jGwfuWlN4R3coPAqWO/sGOyaEMbc9V5/Fw0H0ThQdYY3eI3rW5M4a1r9TSg/Z9d46JximPat/XvcpLvUc0G+QxCVhTRmYqD7u0wuX5VSric0PQU6KSjH84ZbKgAA8l04NGObgUI6ugjaNBhkaoIP3glYcHY1fgn5vwER2T/iiXZ5q3qDtYboR2GWLUODLWSpXWZRy7oYvp/RGTSe1fKjDwkbtrZiFvRoyzQvDhEAr+0MFDxJiOLdoKJFeBs6BrF2lyUJ6udlOmEYV94DfKoxEhhlZbxkPCh4SedT79i3c3xkKlf9wfAsEyGSTfc9OtyYBfoHcE9GMRZIvLf2Jn2mpHMO2694Fil4d7JdhLYQ/9Gv9VgFrYosQdVlDh+RxE2CXzrO39LhA1GeOY/n1r+DdvuCJs1fZfBZ1ORb7eQNp1BknurJ8FoYCKlEgihS223IJEnGueDdYkchMSRjS6C3a/HIzBz0RvEDGXD3WgrY5edRIaGziSoSr5eXzumK7N1FFBlpfY/7j38zI1ibWN4PRakmZppeeWOb1xiuVS5JkngCLoYerxLJEEjt8+klXhwnqqJukFuObaVsyprSWp+aAu/UHD/4w/6/lC6Elv+VzccLpITOR5b7VdAuCttQ5PGse6fits=" on: tags: true # all_branches is required to use tags all_branches: true # Only publish the build marked with "DEPLOY_TO_FORGE" condition: "$DEPLOY_TO_FORGE = yes" diff --git a/Gemfile b/Gemfile index caeef40..2fce93c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,68 +1,48 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" def location_for(place, fake_version = nil) if place =~ /^(git[:@][^#]*)#(.*)/ [fake_version, { :git => $1, :branch => $2, :require => false }].compact elsif place =~ /^file:\/\/(.*)/ ['>= 0', { :path => File.expand_path($1), :require => false }] else [place, { :require => false }] end end group :test do - gem 'voxpupuli-test', '>= 1.4.0', :require => false - gem 'coveralls', :require => false - gem 'simplecov-console', :require => false + gem 'voxpupuli-test', '~> 2.1', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false end group :development do gem 'travis', :require => false gem 'travis-lint', :require => false gem 'guard-rake', :require => false gem 'overcommit', '>= 0.39.1', :require => false end group :system_tests do - gem 'winrm', :require => false - if beaker_version = ENV['BEAKER_VERSION'] - gem 'beaker', *location_for(beaker_version) - else - gem 'beaker', '>= 4.2.0', :require => false - end - if beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] - gem 'beaker-rspec', *location_for(beaker_rspec_version) - else - gem 'beaker-rspec', :require => false - end - gem 'serverspec', :require => false - gem 'beaker-hostgenerator', '>= 1.1.22', :require => false - gem 'beaker-docker', :require => false - gem 'beaker-puppet', :require => false - gem 'beaker-puppet_install_helper', :require => false - gem 'beaker-module_install_helper', :require => false - gem 'rbnacl', '>= 4', :require => false - gem 'rbnacl-libsodium', :require => false - gem 'bcrypt_pbkdf', :require => false - gem 'ed25519', :require => false + gem 'voxpupuli-acceptance', :require => false end group :release do gem 'github_changelog_generator', :require => false, :git => 'https://github.com/voxpupuli/github-changelog-generator', :branch => 'voxpupuli_essential_fixes' gem 'puppet-blacksmith', :require => false gem 'voxpupuli-release', :require => false gem 'puppet-strings', '>= 2.2', :require => false end if facterversion = ENV['FACTER_GEM_VERSION'] gem 'facter', facterversion.to_s, :require => false, :groups => [:test] else gem 'facter', :require => false, :groups => [:test] end ENV['PUPPET_VERSION'].nil? ? puppetversion = '~> 6.0' : puppetversion = ENV['PUPPET_VERSION'].to_s gem 'puppet', puppetversion, :require => false, :groups => [:test] # vim: syntax=ruby diff --git a/examples/default_template_settings.pp b/examples/default_template_settings.pp index 932916f..a8dcf3a 100644 --- a/examples/default_template_settings.pp +++ b/examples/default_template_settings.pp @@ -1,97 +1,101 @@ # The defaults as set by the 1.Y.Z template. # Cassandra pre-requisites include cassandra::datastax_repo include cassandra::java class { 'cassandra': settings => { 'authenticator' => 'AllowAllAuthenticator', 'authorizer' => 'AllowAllAuthorizer', 'auto_snapshot' => true, 'batch_size_warn_threshold_in_kb' => 5, 'batchlog_replay_throttle_in_kb' => 1024, 'cas_contention_timeout_in_ms' => 1000, 'client_encryption_options' => { 'enabled' => false, 'keystore' => 'conf/.keystore', 'keystore_password' => 'cassandra', }, 'cluster_name' => 'Test Cluster', 'column_index_size_in_kb' => 64, 'commit_failure_policy' => 'stop', 'commitlog_directory' => '/var/lib/cassandra/commitlog', 'commitlog_segment_size_in_mb' => 32, 'commitlog_sync' => 'periodic', 'commitlog_sync_period_in_ms' => 10000, 'compaction_throughput_mb_per_sec' => 16, 'concurrent_counter_writes' => 32, 'concurrent_reads' => 32, 'concurrent_writes' => 32, 'counter_cache_save_period' => 7200, 'counter_cache_size_in_mb' => '', 'counter_write_request_timeout_in_ms' => 5000, 'cross_node_timeout' => false, 'data_file_directories' => ['/var/lib/cassandra/data'], 'disk_failure_policy' => 'stop', 'dynamic_snitch_badness_threshold' => 0.1, 'dynamic_snitch_reset_interval_in_ms' => 600000, 'dynamic_snitch_update_interval_in_ms' => 100, 'endpoint_snitch' => 'SimpleSnitch', 'hinted_handoff_enabled' => true, 'hinted_handoff_throttle_in_kb' => 1024, 'incremental_backups' => false, 'index_summary_capacity_in_mb' => '', 'index_summary_resize_interval_in_minutes' => 60, 'inter_dc_tcp_nodelay' => false, 'internode_compression' => 'all', 'key_cache_save_period' => 14400, 'key_cache_size_in_mb' => '', 'listen_address' => 'localhost', 'max_hint_window_in_ms' => 10800000, 'max_hints_delivery_threads' => 2, 'memtable_allocation_type' => 'heap_buffers', 'native_transport_port' => 9042, 'num_tokens' => 256, 'partitioner' => 'org.apache.cassandra.dht.Murmur3Partitioner', 'permissions_validity_in_ms' => 2000, 'range_request_timeout_in_ms' => 10000, 'read_request_timeout_in_ms' => 5000, 'request_scheduler' => 'org.apache.cassandra.scheduler.NoScheduler', 'request_timeout_in_ms' => 10000, 'row_cache_save_period' => 0, 'row_cache_size_in_mb' => 0, 'rpc_address' => 'localhost', 'rpc_keepalive' => true, 'rpc_port' => 9160, 'rpc_server_type' => 'sync', 'saved_caches_directory' => '/var/lib/cassandra/saved_caches', - 'seed_provider' => [{ - 'class_name' => 'org.apache.cassandra.locator.SimpleSeedProvider', - 'parameters' => [{ - 'seeds' => '127.0.0.1', - }], - }], + 'seed_provider' => [ + { + 'class_name' => 'org.apache.cassandra.locator.SimpleSeedProvider', + 'parameters' => [ + { + 'seeds' => '127.0.0.1', + }, + ], + } + ], 'server_encryption_options' => { 'internode_encryption' => 'none', 'keystore' => 'conf/.keystore', 'keystore_password' => 'cassandra', 'truststore' => 'conf/.truststore', 'truststore_password' => 'cassandra', }, 'snapshot_before_compaction' => false, 'ssl_storage_port' => 7001, 'sstable_preemptive_open_interval_in_mb' => 50, 'start_native_transport' => true, 'start_rpc' => true, 'storage_port' => 7000, 'thrift_framed_transport_size_in_mb' => 15, 'tombstone_failure_threshold' => 100000, 'tombstone_warn_threshold' => 1000, 'trickle_fsync' => false, 'trickle_fsync_interval_in_kb' => 10240, 'truncate_request_timeout_in_ms' => 60000, 'write_request_timeout_in_ms' => 2000, }, require => Class['cassandra::datastax_repo', 'cassandra::java'], } diff --git a/manifests/apache_repo.pp b/manifests/apache_repo.pp index b25595c..54773b7 100644 --- a/manifests/apache_repo.pp +++ b/manifests/apache_repo.pp @@ -1,85 +1,85 @@ # An optional class that will allow a suitable repository to be configured # from which packages for Apache Cassandra can be downloaded. # @param descr [string] On the Red Hat family, this is passed as the `descr` # attribute to a `yumrepo` resource. On the Debian family, it is passed as # the `comment` attribute to an `apt::source` resource. # @param key_id [string] On the Debian family, this is passed as the `id` # attribute to an `apt::key` resource. On the Red Hat family, it is # ignored. # @param key_url [string] On the Debian family, this is passed as the # `source` attribute to an `apt::key` resource. On the Red Hat family, # it is set to the `gpgkey` attribute on the `yumrepo` resource. # @param pkg_url [string] On the Red Hat family, leaving this as default will # set the `baseurl` on the `yumrepo` resource to # 'http://www.apache.org/dist/cassandra/redhat' with whatever is set in the # 'release' attribute appended. # On the Debian family, leaving this as the default # will set the `location` attribute on an `apt::source` to # 'http://www.apache.org/dist/cassandra/debian'. # @param release [string] On the Debian family, this is passed as the `release` # attribute to an `apt::source` resource. On the Red Hat family, it is the # major version number of Cassandra, without dot, and with an appended 'x' # (e.g. '311x') class cassandra::apache_repo ( $descr = 'Repo for Apache Cassandra', $key_id = 'A26E528B271F19B9E5D8E19EA278B781FE4B2BDA', $key_url = 'https://www.apache.org/dist/cassandra/KEYS', $pkg_url = undef, $release = 'main', - ) { +) { case $facts['os']['family'] { 'RedHat': { if $pkg_url != undef { $baseurl = $pkg_url } else { $url = 'http://www.apache.org/dist/cassandra/redhat' $baseurl = "${url}/${release}" } yumrepo { 'cassandra_apache': ensure => present, descr => $descr, baseurl => $baseurl, enabled => 1, gpgcheck => 1, gpgkey => $key_url, } } 'Debian': { include apt include apt::update - apt::key {'apache.cassandra': + apt::key { 'apache.cassandra': id => $key_id, source => $key_url, before => Apt::Source['cassandra.sources'], } if $pkg_url != undef { $location = $pkg_url } else { $location = 'http://www.apache.org/dist/cassandra/debian' } - apt::source {'cassandra.sources': + apt::source { 'cassandra.sources': location => $location, comment => $descr, release => $release, include => { 'src' => false, }, notify => Exec['update-apache-cassandra-repo'], } # Required to wrap apt_update - exec {'update-apache-cassandra-repo': + exec { 'update-apache-cassandra-repo': refreshonly => true, command => '/bin/true', require => Exec['apt_update'], } } default: { warning("OS family ${facts['os']['family']} not supported") } } } diff --git a/manifests/datastax_agent.pp b/manifests/datastax_agent.pp index 8343d47..cdfa383 100644 --- a/manifests/datastax_agent.pp +++ b/manifests/datastax_agent.pp @@ -1,120 +1,120 @@ # A class for installing the DataStax Agent and to point it at an OpsCenter # instance. # # @param address_config_file The full path to the address config file. # @param defaults_file The full path name to the file where `java_home` is set. # @param java_home If the value of this variable is left as *undef*, no # action is taken. Otherwise the value is set as JAVA_HOME in # `defaults_file`. # @param package_ensure Is passed to the package reference. Valid values are # **present** or a version number. # @param package_name Is passed to the package reference. # @param service_ensure Is passed to the service reference. # @param service_enable Is passed to the service reference. # @param service_name Is passed to the service reference. # @param service_provider The name of the provider that runs the service. # If left as *undef* then the OS family specific default will be used, # otherwise the specified value will be used instead. # @param settings A hash that is passed to # [create_ini_settings] # (https://github.com/puppetlabs/puppetlabs-inifile#function-create_ini_settings) # with the following additional defaults: # # ```puppet # { # path => $address_config_file, # key_val_separator => ': ', # require => Package[$package_name], # notify => Service['datastax-agent'], # } # ``` # # @example Set agent_alias to foobar, stomp_interface to localhost and ensure that async_pool_size is absent from the file. # class { 'cassandra::datastax_agent': # settings => { # 'agent_alias' => { # 'setting' => 'agent_alias', # 'value' => 'foobar', # }, # 'stomp_interface' => { # 'setting' => 'stomp_interface', # 'value' => 'localhost', # }, # 'async_pool_size' => { # 'ensure' => absent, # }, # }, # } class cassandra::datastax_agent ( $address_config_file = '/var/lib/datastax-agent/conf/address.yaml', $defaults_file = '/etc/default/datastax-agent', $java_home = undef, $package_ensure = 'present', $package_name = 'datastax-agent', $service_ensure = 'running', $service_enable = true, $service_name = 'datastax-agent', $service_provider = undef, $settings = {}, - ) inherits cassandra::params { +) inherits cassandra::params { require 'cassandra' if $service_provider != undef { System { provider => $service_provider, } } package { $package_name: ensure => $package_ensure, require => Class['cassandra'], notify => Exec['datastax_agent_reload_systemctl'], } exec { 'datastax_agent_reload_systemctl': command => "${cassandra::params::systemctl} daemon-reload", onlyif => "test -x ${cassandra::params::systemctl}", path => ['/usr/bin', '/bin'], refreshonly => true, notify => Service['datastax-agent'], } file { $address_config_file: owner => 'cassandra', group => 'cassandra', mode => '0644', require => Package[$package_name], } if $java_home != undef { ini_setting { 'java_home': ensure => present, path => $defaults_file, section => '', key_val_separator => '=', setting => 'JAVA_HOME', value => $java_home, notify => Service['datastax-agent'], } } service { 'datastax-agent': ensure => $service_ensure, enable => $service_enable, name => $service_name, } if $settings { $defaults = { path => $address_config_file, key_val_separator => ': ', require => Package[$package_name], notify => Service['datastax-agent'], } $full_settings = { '' => $settings, } create_ini_settings($full_settings, $defaults) } } diff --git a/manifests/datastax_repo.pp b/manifests/datastax_repo.pp index 729df81..d10e50b 100644 --- a/manifests/datastax_repo.pp +++ b/manifests/datastax_repo.pp @@ -1,82 +1,82 @@ # An optional class that will allow a suitable repository to be configured # from which packages for DataStax Community can be downloaded. Changing # the defaults will allow any Debian Apt or Red Hat Yum repository to be # configured. # @param descr [string] On the Red Hat family, this is passed as the `descr` # attribute to a `yumrepo` resource. On the Debian family, it is passed as # the `comment` attribute to an `apt::source` resource. # @param key_id [string] On the Debian family, this is passed as the `id` # attribute to an `apt::key` resource. On the Red Hat family, it is # ignored. # @param key_url [string] On the Debian family, this is passed as the # `source` attribute to an `apt::key` resource. On the Red Hat family, # it is ignored. # @param pkg_url [string] If left as the default, this will set the `baseurl` # to 'http://rpm.datastax.com/community' on a `yumrepo` resource # on the Red Hat family. On the Debian family, leaving this as the default # will set the `location` attribute on an `apt::source` to # 'http://debian.datastax.com/community'. # @param release [string] On the Debian family, this is passed as the `release` # attribute to an `apt::source` resource. On the Red Hat family, it is # ignored. class cassandra::datastax_repo ( $descr = 'DataStax Repo for Apache Cassandra', $key_id = '7E41C00F85BFC1706C4FFFB3350200F2B999A372', $key_url = 'http://debian.datastax.com/debian/repo_key', $pkg_url = undef, $release = 'stable', - ) { +) { case $facts['os']['family'] { 'RedHat': { if $pkg_url != undef { $baseurl = $pkg_url } else { $baseurl = 'http://rpm.datastax.com/community' } yumrepo { 'datastax': ensure => present, descr => $descr, baseurl => $baseurl, enabled => 1, gpgcheck => 0, } } 'Debian': { include apt include apt::update - apt::key {'datastaxkey': + apt::key { 'datastaxkey': id => $key_id, source => $key_url, before => Apt::Source['datastax'], } if $pkg_url != undef { $location = $pkg_url } else { $location = 'http://debian.datastax.com/community' } - apt::source {'datastax': + apt::source { 'datastax': location => $location, comment => $descr, release => $release, include => { 'src' => false, }, notify => Exec['update-cassandra-repos'], } # Required to wrap apt_update - exec {'update-cassandra-repos': + exec { 'update-cassandra-repos': refreshonly => true, command => '/bin/true', require => Exec['apt_update'], } } default: { warning("OS family ${facts['os']['family']} not supported") } } } diff --git a/manifests/dse.pp b/manifests/dse.pp index 54de2e8..2853a00 100644 --- a/manifests/dse.pp +++ b/manifests/dse.pp @@ -1,85 +1,85 @@ # A class for configuring DataStax Enterprise (DSE) specific settings. # # @param config_file [string] The full path to the DSE configuration file. # @param config_file_mode [string] The mode for the DSE configuration file. # @param dse_yaml_tmpl [string] A path to a template for the `dse.yaml` file. # @param file_lines [hash] A hash of values that are passed to # `create_resources` as a `file_line` resource. # @param service_refresh [boolean] Whether or not the Cassandra service # should be refreshed if the DSE configuration files are changed. # @param settings [hash] Unless this attribute is set to a hash (which is # then placed as YAML inside `dse.yaml`) then the `dse.yaml` is left # unchanged. # @example Configure a cluster with LDAP authentication # class { 'cassandra::dse': # file_lines => { # 'Set HADOOP_LOG_DIR directory' => { # ensure => present, # path => '/etc/dse/dse-env.sh', # line => 'export HADOOP_LOG_DIR=/var/log/hadoop', # match => '^# export HADOOP_LOG_DIR=', # }, # 'Set DSE_HOME' => { # ensure => present, # path => '/etc/dse/dse-env.sh', # line => 'export DSE_HOME=/usr/share/dse', # match => '^#export DSE_HOME', # }, # }, # settings => { # ldap_options => { # server_host => localhost, # server_port => 389, # search_dn => 'cn=Admin', # search_password => secret, # use_ssl => false, # use_tls => false, # truststore_type => jks, # user_search_base => 'ou=users,dc=example,dc=com', # user_search_filter => '(uid={0})', # credentials_validity_in_ms => 0, # connection_pool => { # max_active => 8, # max_idle => 8, # } # } # } # } class cassandra::dse ( $config_file = '/etc/dse/dse.yaml', $config_file_mode = '0644', $dse_yaml_tmpl = 'cassandra/dse.yaml.erb', $file_lines = undef, $service_refresh = true, $settings = undef, - ) { +) { include cassandra include stdlib if $service_refresh { $notifications = Service['cassandra'] } else { $notifications = [] } if is_hash($file_lines) { $default_file_line = { require => Package['cassandra'], notify => $notifications, } create_resources(file_line, $file_lines, $default_file_line) } if is_hash($settings) { file { $config_file: - ensure => present, + ensure => file, owner => 'cassandra', group => 'cassandra', content => template($dse_yaml_tmpl), mode => $config_file_mode, require => Package['cassandra'], notify => $notifications, } } } diff --git a/manifests/file.pp b/manifests/file.pp index 0a6698d..b5f771a 100644 --- a/manifests/file.pp +++ b/manifests/file.pp @@ -1,85 +1,85 @@ # A defined type for altering files relative to the configuration directory. # @param file [string] The name of the file relative to the `config_path`. # @param config_path [string] The path to the configuration directory. # @param file_lines [string] If set, then the [create_resources] # (https://docs.puppet.com/puppet/latest/reference/function.html#createresources) # will be used to create an array of [file_line] # (https://forge.puppet.com/puppetlabs/stdlib#file_line) resources. # @param service_refresh [boolean] Is the Cassandra service is to be notified # if the environment file is changed. # @example # if $::memorysize_mb < 24576.0 { # $max_heap_size_in_mb = floor($::memorysize_mb / 2) # } elsif $::memorysize_mb < 8192.0 { # $max_heap_size_in_mb = floor($::memorysize_mb / 4) # } else { # $max_heap_size_in_mb = 8192 # } # # $heap_new_size = $::processorcount * 100 # # cassandra::file { "Set Java/Cassandra max heap size to ${max_heap_size_in_mb}.": # file => 'cassandra-env.sh', # file_lines => { # 'MAX_HEAP_SIZE' => { # line => "MAX_HEAP_SIZE='${max_heap_size_in_mb}M'", # match => '^#?MAX_HEAP_SIZE=.*', # }, # } # } # # cassandra::file { "Set Java/Cassandra heap new size to ${heap_new_size}.": # file => 'cassandra-env.sh', # file_lines => { # 'HEAP_NEWSIZE' => { # line => "HEAP_NEWSIZE='${heap_new_size}M'", # match => '^#?HEAP_NEWSIZE=.*', # } # } # } # $tmpdir = '/var/lib/cassandra/tmp' # # file { $tmpdir: # ensure => directory, # owner => 'cassandra', # group => 'cassandra', # } # # cassandra::file { 'Set java.io.tmpdir': # file => 'jvm.options', # file_lines => { # 'java.io.tmpdir' => { # line => "-Djava.io.tmpdir=${tmpdir}", # }, # }, # require => File[$tmpdir], # } -define cassandra::file( +define cassandra::file ( $file = $title, $config_path = $cassandra::config_path, $file_lines = undef, $service_refresh = true, - ) { +) { include cassandra include cassandra::params include stdlib $path = "${config_path}/${file}" if $file_lines != undef { if $service_refresh { $default_file_line = { path => $path, require => Package['cassandra'], notify => Service['cassandra'], } } else { $default_file_line = { path => $path, require => Package['cassandra'], } } create_resources(file_line, $file_lines, $default_file_line) } } diff --git a/manifests/firewall_ports.pp b/manifests/firewall_ports.pp index 68be1ff..6408b41 100644 --- a/manifests/firewall_ports.pp +++ b/manifests/firewall_ports.pp @@ -1,76 +1,74 @@ # An optional class to configure incoming network ports on the host that are # relevant to the Cassandra installation. If firewalls are being managed # already, simply do not include this module in your manifest. # # IMPORTANT: The full list of which ports should be configured is assessed at # evaluation time of the configuration. Therefore if one is to use this class, # it must be the final cassandra class included in the manifest. # @param client_ports [array] Only has any effect if the `cassandra` class is defined on the node. # Allow these TCP ports to be opened for traffic coming from the client # subnets. # @param client_subnets [array] Only has any effect if the `cassandra` class is defined on the node. # An array of the list of subnets that are to allowed connection to # cassandra::native_transport_port and cassandra::rpc_port. # @param inter_node_ports [array] Only has any effect if the `cassandra` class is defined on the node. # Allow these TCP ports to be opened for traffic between the Cassandra nodes. # @param inter_node_subnets [array] Only has any effect if the `cassandra` class is defined on the node. # An array of the list of subnets that are to allowed connection to # `cassandra::storage_port`, `cassandra::ssl_storage_port` and port 7199 # for cassandra JMX monitoring. # @param public_ports [array] Allow these TCP ports to be opened for traffic # coming from public subnets the port specified in `$ssh_port` will be # appended to this list. # @param public_subnets [array] An array of the list of subnets that are to allowed connection to # cassandra::firewall_ports::ssh_port. # @param ssh_port [integer] Which port does SSH operate on. # @param opscenter_ports [array] Only has any effect if the `cassandra::datastax_agent` is defined. # Allow these TCP ports to be opened for traffic coming to or from OpsCenter # appended to this list. # @param opscenter_subnets [array] A list of subnets that are to be allowed connection to # port 61621 for nodes built with cassandra::datastax_agent. class cassandra::firewall_ports ( $client_ports = [9042, 9160], $client_subnets = ['0.0.0.0/0'], $inter_node_ports = [7000, 7001, 7199], $inter_node_subnets = ['0.0.0.0/0'], $public_ports = [8888], $public_subnets = ['0.0.0.0/0'], $ssh_port = 22, $opscenter_ports = [9042, 9160, 61620, 61621], $opscenter_subnets = ['0.0.0.0/0'], - ) { +) { # Public connections on any node. $public_subnets_array = prefix($public_subnets, '200_Public_') cassandra::private::firewall_ports::rule { $public_subnets_array: ports => concat($public_ports, [$ssh_port]), } # If this is a Cassandra node. - if defined ( Class['::cassandra'] ) { + if defined ( Class['::cassandra']) { # Inter-node connections for Cassandra - $inter_node_subnets_array = prefix($inter_node_subnets, - '210_InterNode_') + $inter_node_subnets_array = prefix($inter_node_subnets, '210_InterNode_') cassandra::private::firewall_ports::rule { $inter_node_subnets_array: ports => $inter_node_ports, } # Client connections for Cassandra $client_subnets_array = prefix($client_subnets, '220_Client_') - cassandra::private::firewall_ports::rule {$client_subnets_array: + cassandra::private::firewall_ports::rule { $client_subnets_array: ports => $client_ports, } } # Connections for DataStax Agent - if defined ( Class['::cassandra::datastax_agent'] ) or defined ( Class['::cassandra::opscenter'] ) { - $opscenter_subnets_opc_agent = prefix($opscenter_subnets, - '230_OpsCenter_') + if defined ( Class['::cassandra::datastax_agent']) or defined ( Class['::cassandra::opscenter']) { + $opscenter_subnets_opc_agent = prefix($opscenter_subnets, '230_OpsCenter_') cassandra::private::firewall_ports::rule { $opscenter_subnets_opc_agent: ports => $opscenter_ports, } } } diff --git a/manifests/init.pp b/manifests/init.pp index 820f795..9c2bc3f 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,390 +1,385 @@ # A class for installing the Cassandra package and manipulate settings in the # configuration file. # # @param baseline_settings [hash] If set, this is a baseline of settings that # are merged with the `settings` hash. The values of the `settings` # hash overriding the values in this hash. This is most useful when used # with hiera. # @param cassandra_2356_sleep_seconds [boolean] # This will provide a workaround for # [CASSANDRA-2356](https://issues.apache.org/jira/browse/CASSANDRA-2356) by # sleeping for the specifed number of seconds after an event involving the # Cassandra package. This option is silently ignored on the Red Hat family # of operating systems as this bug only affects Debian systems. # @param cassandra_9822 [boolean] If set to true, this will apply a patch to the init # file for the Cassandra service as a workaround for # [CASSANDRA-9822](https://issues.apache.org/jira/browse/CASSANDRA-9822). # This this bug only affects Debian systems. # @param cassandra_yaml_tmpl [string] The path to the Puppet template for the # Cassandra configuration file. This allows the user to supply their own # customized template.` # @param commitlog_directory [string] The path to the commitlog directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param commitlog_directory_mode [string] The mode for the # `commitlog_directory` is ignored unless `commitlog_directory` is # specified. # @param manage_config_file [boolean] Whether or not to manage the cassandra configuration # file. # @param config_file_mode [string] The permissions mode of the cassandra configuration # file. # @param config_path [string] The path to the cassandra configuration file. # @param data_file_directories [array] The path(s) to the date directory or # directories. # If set, the directories will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param data_file_directories_mode [string] The mode for the # `data_file_directories` is ignored unless `data_file_directories` is # specified. # @param dc [string] Sets the value for dc in *config_path*/*snitch_properties_file* # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. # @param dc_suffix [string] Sets the value for dc_suffix in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. If the value is *undef* then no change will be made to # the snitch properties file for this setting. # @param fail_on_non_supported_os [boolean] A flag that dictates if the module should # fail if it is not RedHat or Debian. If you set this option to false then # you must also at least set the `config_path` attribute as well. # @param hints_directory [string] The path to the hints directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. Do not set this option in Cassandra versions before 3.0.0. # @param hints_directory_mode [string] The mode for the # `hints_directory` is ignored unless `hints_directory` is # specified. # @param package_ensure [present|latest|string] The status of the package specified in # **package_name**. Can be *present*, *latest* or a specific version # number. # @param package_name [string] The name of the Cassandra package which must be available # from a repository. # @param prefer_local [boolean] Sets the value for prefer_local in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. Valid values are true, false or *undef*. If the value # is *undef* then change will be made to the snitch properties file for # this setting. # @param rack [string] Sets the value for rack in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. # @param rackdc_tmpl [string] The template for creating the snitch properties file. # @param saved_caches_directory [string] The path to the saved caches directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param saved_caches_directory_mode [string] The mode for the # `saved_caches_directory` is ignored unless `saved_caches_directory` is # specified. # @param service_enable [boolean] enable the Cassandra service to start at boot time. # @param service_ensure [string] Ensure the Cassandra service is running. Valid values # are running or stopped. # @param service_name [string] The name of the service that runs the Cassandra software. # @param service_provider [string] The name of the provider that runs the service. # If left as *undef* then the OS family specific default will # be used, otherwise the specified value will be used instead. # @param service_refresh [boolean] If set to true, changes to the Cassandra config file # or the data directories will ensure that Cassandra service is refreshed # after the changes. Setting this flag to false will disable this # behaviour, therefore allowing the changes to be made but allow the user # to control when the service is restarted. # @param settings [hash] A hash that is passed to `to_yaml` which dumps the results # to the Cassandra configuring file. The minimum required settings for # Cassandra 2.X are as follows: # # ```puppet # { # 'authenticator' => 'PasswordAuthenticator', # 'cluster_name' => 'MyCassandraCluster', # 'commitlog_directory' => '/var/lib/cassandra/commitlog', # 'commitlog_sync' => 'periodic', # 'commitlog_sync_period_in_ms' => 10000, # 'data_file_directories' => ['/var/lib/cassandra/data'], # 'endpoint_snitch' => 'GossipingPropertyFileSnitch', # 'listen_address' => $::ipaddress, # 'partitioner' => 'org.apache.cassandra.dht.Murmur3Partitioner', # 'saved_caches_directory' => '/var/lib/cassandra/saved_caches', # 'seed_provider' => [ # { # 'class_name' => 'org.apache.cassandra.locator.SimpleSeedProvider', # 'parameters' => [ # { # 'seeds' => $::ipaddress, # }, # ], # }, # ], # 'start_native_transport' => true, # } # ``` # For Cassandra 3.X you will also need to specify the `hints_directory` # attribute. # @param snitch_properties_file [string] The name of the snitch properties file. The # full path name would be *config_path*/*snitch_properties_file*. # @param systemctl [string] The full path to the systemctl command. Only # needed when the package is installed. Will silently continue if the # executable does not exist. class cassandra ( $baseline_settings = {}, $cassandra_2356_sleep_seconds = 5, $cassandra_9822 = false, $cassandra_yaml_tmpl = 'cassandra/cassandra.yaml.erb', $commitlog_directory = undef, $commitlog_directory_mode = '0750', Boolean $manage_config_file = true, $config_file_mode = '0644', $config_path = $cassandra::params::config_path, $data_file_directories = undef, $data_file_directories_mode = '0750', $dc = 'DC1', $dc_suffix = undef, $fail_on_non_supported_os = true, $hints_directory = undef, $hints_directory_mode = '0750', $package_ensure = 'present', $package_name = $cassandra::params::cassandra_pkg, $prefer_local = undef, $rack = 'RAC1', $rackdc_tmpl = 'cassandra/cassandra-rackdc.properties.erb', $saved_caches_directory = undef, $saved_caches_directory_mode = '0750', $service_enable = true, $service_ensure = undef, $service_name = 'cassandra', $service_provider = undef, $service_refresh = true, $settings = {}, $snitch_properties_file = 'cassandra-rackdc.properties', $systemctl = $cassandra::params::systemctl, - ) inherits cassandra::params { +) inherits cassandra::params { if $service_provider != undef { Service { provider => $service_provider, } } $config_file = "${config_path}/cassandra.yaml" $dc_rack_properties_file = "${config_path}/${snitch_properties_file}" case $facts['os']['family'] { 'RedHat': { $config_file_require = Package['cassandra'] $config_file_before = [] $config_path_require = Package['cassandra'] $dc_rack_properties_file_require = Package['cassandra'] $dc_rack_properties_file_before = [] $data_dir_require = Package['cassandra'] $data_dir_before = [] if $facts['os']['release']['major'] == '7' and $cassandra::service_provider == 'init' { exec { "/sbin/chkconfig --add ${service_name}": unless => "/sbin/chkconfig --list ${service_name}", require => Package['cassandra'], before => Service['cassandra'], } } } 'Debian': { - $config_file_require = [ User['cassandra'], File[$config_path] ] + $config_file_require = [User['cassandra'], File[$config_path]] $config_file_before = Package['cassandra'] $config_path_require = [] - $dc_rack_properties_file_require = [ User['cassandra'], File[$config_path] ] + $dc_rack_properties_file_require = [User['cassandra'], File[$config_path]] $dc_rack_properties_file_before = Package['cassandra'] $data_dir_require = File[$config_file] $data_dir_before = Package['cassandra'] if $cassandra_9822 { file { '/etc/init.d/cassandra': source => 'puppet:///modules/cassandra/CASSANDRA-9822/cassandra', mode => '0555', before => Package['cassandra'], } } # Sleep after package install and before service resource to prevent # possible duplicate processes arising from CASSANDRA-2356. exec { 'CASSANDRA-2356 sleep': command => "/bin/sleep ${cassandra_2356_sleep_seconds}", refreshonly => true, user => 'root', subscribe => Package['cassandra'], before => Service['cassandra'], } group { 'cassandra': ensure => present, } $user = 'cassandra' user { $user: ensure => present, comment => 'Cassandra database,,,', gid => 'cassandra', home => '/var/lib/cassandra', shell => '/bin/false', managehome => true, require => Group['cassandra'], } # End of CASSANDRA-2356 specific resources. } default: { - $config_file_before = [ Package['cassandra'] ] + $config_file_before = [Package['cassandra']] $config_file_require = [] $config_path_require = [] $dc_rack_properties_file_require = Package['cassandra'] $dc_rack_properties_file_before = [] if $fail_on_non_supported_os { fail("OS family ${facts['os']['family']} not supported") } else { warning("OS family ${facts['os']['family']} not supported") } } } package { 'cassandra': ensure => $package_ensure, name => $package_name, notify => Exec['cassandra_reload_systemctl'], } exec { 'cassandra_reload_systemctl': command => "${systemctl} daemon-reload", onlyif => "test -x ${systemctl}", path => ['/usr/bin', '/bin'], refreshonly => true, } file { $config_path: ensure => directory, group => 'cassandra', owner => 'cassandra', mode => '0755', require => $config_path_require, } if $commitlog_directory { file { $commitlog_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $commitlog_directory_mode, require => $data_dir_require, before => $data_dir_before, } - $commitlog_directory_settings = merge($settings, - { 'commitlog_directory' => $commitlog_directory, }) + $commitlog_directory_settings = merge($settings, { 'commitlog_directory' => $commitlog_directory, }) } else { $commitlog_directory_settings = $settings } if is_array($data_file_directories) { file { $data_file_directories: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $data_file_directories_mode, require => $data_dir_require, before => $data_dir_before, } - $data_file_directories_settings = merge($settings, { - 'data_file_directories' => $data_file_directories, - }) + $data_file_directories_settings = merge($settings, { 'data_file_directories' => $data_file_directories, }) } else { $data_file_directories_settings = $settings } if $hints_directory { file { $hints_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $hints_directory_mode, require => $data_dir_require, before => $data_dir_before, } - $hints_directory_settings = merge($settings, - { 'hints_directory' => $hints_directory, }) + $hints_directory_settings = merge($settings, { 'hints_directory' => $hints_directory, }) } else { $hints_directory_settings = $settings } if $saved_caches_directory { file { $saved_caches_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $saved_caches_directory_mode, require => $data_dir_require, before => $data_dir_before, } - $saved_caches_directory_settings = merge($settings, - { 'saved_caches_directory' => $saved_caches_directory, }) + $saved_caches_directory_settings = merge($settings, { 'saved_caches_directory' => $saved_caches_directory, }) } else { $saved_caches_directory_settings = $settings } $merged_settings = merge($baseline_settings, $settings, $commitlog_directory_settings, $data_file_directories_settings, $hints_directory_settings, - $saved_caches_directory_settings) + $saved_caches_directory_settings) if $manage_config_file { file { $config_file: - ensure => present, + ensure => file, owner => 'cassandra', group => 'cassandra', content => template($cassandra_yaml_tmpl), mode => $config_file_mode, require => $config_file_require, before => $config_file_before, } $service_dependencies = [ - File[$config_file], - File[$dc_rack_properties_file], - Package['cassandra'], - ] + File[$config_file], + File[$dc_rack_properties_file], + Package['cassandra'], + ] } else { $service_dependencies = [ - File[$dc_rack_properties_file], - Package['cassandra'], - ] + File[$dc_rack_properties_file], + Package['cassandra'], + ] } file { $dc_rack_properties_file: ensure => file, content => template($rackdc_tmpl), owner => 'cassandra', group => 'cassandra', mode => '0644', require => $dc_rack_properties_file_require, before => $dc_rack_properties_file_before, } if $package_ensure != 'absent' and $package_ensure != 'purged' { if $service_refresh { service { 'cassandra': ensure => $service_ensure, name => $service_name, enable => $service_enable, subscribe => $service_dependencies, } } else { service { 'cassandra': ensure => $service_ensure, name => $service_name, enable => $service_enable, require => $service_dependencies, } } } } diff --git a/manifests/java.pp b/manifests/java.pp index 78fe95c..e6831c9 100644 --- a/manifests/java.pp +++ b/manifests/java.pp @@ -1,67 +1,67 @@ # A class to install Java and JNA packages. # @param aptkey [hash] If supplied, this should be a hash of `apt::key` # resources that will be passed to the create_resources function. # This is ignored on non-Debian systems. # @param aptsource [hash] If supplied, this should be a hash of # `apt::source` resources that will be passed to the create_resources # function. This is ignored on non-Red Hat` # @param jna_ensure [string] Is passed to the package reference for the JNA # package. Valid values are `present` or a version number. # @param jna_package_name [string] The name of the JNA package. # @param package_ensure [string] Is passed to the package reference for the JRE/JDK # package. Valid values are `present` or a version number. # @param package_name [string] The name of the Java package to be installed. # @param yumrepo [hash] If supplied, this should be a hash of *yumrepo* # resources that will be passed to the create_resources function. # This is ignored on non-Red Hat systems. class cassandra::java ( $aptkey = undef, $aptsource = undef, $jna_ensure = present, $jna_package_name = $cassandra::params::jna_package_name, $package_ensure = present, $package_name = $cassandra::params::java_package, $yumrepo = undef, - ) inherits cassandra::params { +) inherits cassandra::params { if $facts['os']['family'] == 'RedHat' and $yumrepo != undef { $yumrepo_defaults = { 'before' => Package[$package_name], } create_resources(yumrepo, $yumrepo, $yumrepo_defaults) } if $facts['os']['family'] == 'Debian' { if $aptkey != undef { $aptkey_defaults = { 'before' => Package[$package_name], } include apt create_resources(apt::key, $aptkey, $aptkey_defaults) } if $aptsource != undef { exec { 'cassandra::java::apt_update': refreshonly => true, command => '/bin/true', require => Exec['apt_update'], before => Package[$package_name], } $aptsource_defaults = { 'notify' => Exec['cassandra::java::apt_update'], } create_resources(apt::source, $aptsource, $aptsource_defaults) } } package { $package_name: ensure => $package_ensure, } package { $jna_package_name: ensure => $jna_ensure, } } diff --git a/manifests/optutils.pp b/manifests/optutils.pp index 3895c4e..07308ec 100644 --- a/manifests/optutils.pp +++ b/manifests/optutils.pp @@ -1,16 +1,16 @@ # A class to install the optional Cassandra tools package. # @param package_ensure [string] Can be `present`, `latest` or a specific # version number. # @param package_name [string] The name of the optional utilities package to # be installed. class cassandra::optutils ( $package_ensure = 'present', $package_name = $cassandra::params::optutils_package_name, - ) inherits cassandra::params { +) inherits cassandra::params { include 'cassandra' package { $package_name: ensure => $package_ensure, require => Class['cassandra'], } } diff --git a/manifests/private/firewall_ports/rule.pp b/manifests/private/firewall_ports/rule.pp index ab37241..fa1d767 100644 --- a/manifests/private/firewall_ports/rule.pp +++ b/manifests/private/firewall_ports/rule.pp @@ -1,22 +1,22 @@ # A defined type to be used as a macro for setting host based firewall # rules. This is not intended to be used by a user (who should use the # API provided by cassandra::firewall_ports instead) but is documented # here for completeness. # @param ports [integer] The number(s) of the port(s) to be opened. -define cassandra::private::firewall_ports::rule( - $ports, - ) { +define cassandra::private::firewall_ports::rule ( + $ports, +) { $array_var1 = split($title, '_') $rule_number = $array_var1[0] $rule_description = $array_var1[1] $source = $array_var1[2] if size($ports) > 0 { firewall { "${rule_number} - Cassandra (${rule_description}) - ${source}": action => 'accept', dport => $ports, proto => 'tcp', source => $source, } } } diff --git a/manifests/schema.pp b/manifests/schema.pp index 988ec1a..cedc811 100644 --- a/manifests/schema.pp +++ b/manifests/schema.pp @@ -1,142 +1,142 @@ # # @summary A class to maintain the database schema. Please note that cqlsh expects Python 2.7 to be installed. This may be a problem of older distributions (CentOS 6 for example). # # @param connection_tries [integer] How many times do try to connect to # Cassandra. See also `connection_try_sleep`. # @param connection_try_sleep [integer] How much time to allow between the # number of tries specified in `connection_tries`. # @param cql_types [hash] Creates new `cassandra::schema::cql_type` resources. # @param cqlsh_additional_options [string] Any additional options to be passed # to the `cqlsh` command. # @param cqlsh_client_config [string] Set this to a file name # (e.g. '/root/.puppetcqlshrc') that will then be used to contain the # the credentials for connecting to Cassandra. This is a more secure option # than having the credentials appearing on the command line. This option # is only available in Cassandra >= 2.1. # @param cqlsh_client_tmpl [string] The location of the template for configuring # the credentials for the cqlsh client. This is ignored unless # `cqlsh_client_config` is set. # @param cqlsh_command [string] The full path to the `cqlsh` command. # @param cqlsh_host [string] The host for the `cqlsh` command to connect to. # See also `cqlsh_port`. # @param cqlsh_password [string] If credentials are require for connecting, # specify the password here. See also `cqlsh_user`, `cqlsh_client_config`. # @param cqlsh_port [integer] The host for the `cqlsh` command to connect to. # See also `cqlsh_host`. # @param cqlsh_user [string] If credentials are required for connecting, # specify the password here. See also `cqlsh_password`, # `cqlsh_client_config` # @param indexes [hash] Creates new `cassandra::schema::index` resources. # @param keyspaces [hash] Creates new `cassandra::schema::keyspace` resources. # @param permissions [hash] Creates new `cassandra::schema::permission` # resources. # @param tables [hash] Creates new `cassandra::schema::table` resources. # @param users [hash] Creates new `cassandra::schema::user` resources. class cassandra::schema ( $connection_tries = 6, $connection_try_sleep = 30, $cql_types = {}, $cqlsh_additional_options = '', $cqlsh_client_config = undef, $cqlsh_client_tmpl = 'cassandra/cqlshrc.erb', $cqlsh_command = '/usr/bin/cqlsh', $cqlsh_host = 'localhost', $cqlsh_password = undef, $cqlsh_port = 9042, $cqlsh_user = 'cassandra', $indexes = {}, $keyspaces = {}, $permissions = {}, $tables = {}, $users = {}, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ) inherits cassandra::params { +) inherits cassandra::params { require 'cassandra' # Pass the SCL info to create_resources below as a hash $scl = { 'use_scl' => $use_scl, 'scl_name' => $scl_name, } if $cqlsh_client_config != undef { file { $cqlsh_client_config : ensure => file, group => $facts['identity']['gid'], mode => '0600', owner => $facts['identity']['uid'], content => template( $cqlsh_client_tmpl ), before => Exec['::cassandra::schema connection test'], } $cmdline_login = "--cqlshrc=${cqlsh_client_config}" } else { if $cqlsh_password != undef { warning('You may want to consider using the cqlsh_client_config attribute') $cmdline_login = "-u ${cqlsh_user} -p ${cqlsh_password}" } else { $cmdline_login = '' } } $cqlsh_opts = "${cqlsh_command} ${cmdline_login} ${cqlsh_additional_options}" $cqlsh_conn = "${cqlsh_host} ${cqlsh_port}" # See if we can make a connection to Cassandra. Try $connection_tries # number of times with $connection_try_sleep in seconds between each try. $connection_test_tmp = "${cqlsh_opts} -e 'DESC KEYSPACES' ${cqlsh_conn}" if $use_scl { $connection_test = "/usr/bin/scl enable ${scl_name} \"${connection_test_tmp}\"" } else { $connection_test = $connection_test_tmp } exec { '::cassandra::schema connection test': command => $connection_test, returns => 0, tries => $connection_tries, try_sleep => $connection_try_sleep, unless => $connection_test, } # manage keyspaces if present if $keyspaces { create_resources('cassandra::schema::keyspace', $keyspaces, $scl) } # manage cql_types if present if $cql_types { create_resources('cassandra::schema::cql_type', $cql_types, $scl) } # manage tables if present if $tables { create_resources('cassandra::schema::table', $tables, $scl) } # manage indexes if present if $indexes { create_resources('cassandra::schema::index', $indexes, $scl) } # manage users if present if $users { create_resources('cassandra::schema::user', $users, $scl) } # manage permissions if present if $permissions { create_resources('cassandra::schema::permission', $permissions, $scl) } # Resource Ordering Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Cql_type <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Cql_type <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Index <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Index <| |> -> Cassandra::Schema::User <| |> Cassandra::Schema::User <| |> -> Cassandra::Schema::Permission <| |> } diff --git a/manifests/schema/cql_type.pp b/manifests/schema/cql_type.pp index 0e8bd0a..075d81f 100644 --- a/manifests/schema/cql_type.pp +++ b/manifests/schema/cql_type.pp @@ -1,67 +1,67 @@ # Create or drop user defined data types within the schema. # @param keyspace [string] The name of the keyspace that the data type is to be associated with. # @param ensure [present|absent] ensure the data type is created, or is dropped. # @param fields [hash] A hash of the fields that will be components for the data type. # @param cql_type_name [string] The name of the CQL type to be created. # @example # cassandra::schema::cql_type { 'fullname': # keyspace => 'mykeyspace', # fields => { # 'fname' => 'text', # 'lname' => 'text', # }, # } define cassandra::schema::cql_type ( $keyspace, $ensure = present, $fields = {}, $cql_type_name = $title, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ){ +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } $read_script = "DESC TYPE ${keyspace}.${cql_type_name}" $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if $ensure == present { $create_script1 = "CREATE TYPE IF NOT EXISTS ${keyspace}.${cql_type_name}" $create_script2 = join(join_keys_to_values($fields, ' '), ', ') $create_script = "${create_script1} (${create_script2})" $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { $create_command: unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "DROP type ${keyspace}.${cql_type_name}" $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { $delete_command: onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/schema/index.pp b/manifests/schema/index.pp index ee47cbd..9ef7ca7 100644 --- a/manifests/schema/index.pp +++ b/manifests/schema/index.pp @@ -1,90 +1,89 @@ # Create or drop indexes within the schema. # @param ensure [present|absent] Create or dro[ the index. # @param class_name [string] The name of the class to be associated with an # index when creating a custom index. # @param index [string] The name of the index. Defaults to the name of the # resource. # @param keys [string] The columns that the index is being created on. # @param keyspace [string] The name the keyspace that the index is to be associated # with. # @param options [string] Any options to be added to the index. # @param table [string] The name of the table that the index is to be associated with. -define cassandra::schema::index( +define cassandra::schema::index ( $keyspace, $table, $ensure = present, $class_name = undef, $index = $title, $keys = undef, $options = undef, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ) { +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } # Fully qualified index name. $fqin = "${keyspace}.${index}" # Fully qualified table name. $fqtn = "${keyspace}.${table}" $read_script = "DESC INDEX ${fqin}" $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if $ensure == present { if $class_name != undef { $create_part1 = "CREATE CUSTOM INDEX IF NOT EXISTS ${index} ON ${keyspace}.${table}" } else { $create_part1 = "CREATE INDEX IF NOT EXISTS ${index} ON ${keyspace}.${table}" } if $class_name != undef { $create_part2 = "${create_part1} (${keys}) USING '${class_name}'" } else { $create_part2 = "${create_part1} (${keys})" } if $options != undef { $create_script = "${create_part2} WITH OPTIONS = ${options}" } else { $create_script = $create_part2 } $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { $create_command: unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "DROP INDEX ${fqin}" $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { $delete_command: onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } - diff --git a/manifests/schema/keyspace.pp b/manifests/schema/keyspace.pp index 8e784ee..5168186 100644 --- a/manifests/schema/keyspace.pp +++ b/manifests/schema/keyspace.pp @@ -1,98 +1,98 @@ # Create or drop keyspaces within the schema. # @param ensure [present|absent] Create or drop the keyspace. # @param durable_writes [boolean] When set to false, data written to the # keyspace bypasses the commit log. Be careful using this option # because you risk losing data. Set this attribute to false on a keyspace # using the SimpleStrategy. # @param keyspace_name [string] The name of the keyspace to be created. # @param replication_map [hash] Needed if the keyspace is to be present. # Optional if it is to be absent. # @example # $network_topology_strategy = { # keyspace_class => 'NetworkTopologyStrategy', # dc1 => 3, # dc2 => 2 # } # @example # cassandra::schema::keyspace { 'mykeyspace': # replication_map => { # keyspace_class => 'SimpleStrategy', # replication_factor => 1, # }, # durable_writes => false, # } -define cassandra::schema::keyspace( +define cassandra::schema::keyspace ( $ensure = present, $durable_writes = true, $keyspace_name = $title, $replication_map = {}, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ) { +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } $read_script = "DESC KEYSPACE ${keyspace_name}" $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if $ensure == present { $keyspace_class = $replication_map[keyspace_class] case $keyspace_class { 'SimpleStrategy': { $replication_factor = $replication_map[replication_factor] $map_str = "{ 'class' : 'SimpleStrategy', 'replication_factor' : ${replication_factor} }" } 'NetworkTopologyStrategy': { $map_str1 = "{ 'class' : 'NetworkTopologyStrategy'" $new_map = prefix(delete($replication_map, 'keyspace_class'), "'") $map_str2 = join(join_keys_to_values($new_map, "': "), ', ') $map_str = "${map_str1}, ${map_str2} }" } default: { $msg_part1 = "Invalid or no class (${keyspace_class}) specified for" $msg_part2 = "keyspace ${keyspace_name}." fail("${msg_part1} ${msg_part2}") } } $create_script1 = "CREATE KEYSPACE IF NOT EXISTS ${keyspace_name}" $create_script2 = "WITH REPLICATION = ${map_str}" $create_script3 = "AND DURABLE_WRITES = ${durable_writes}" $create_script = "${create_script1} ${create_script2} ${create_script3}" $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { $create_command: unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "DROP KEYSPACE ${keyspace_name}" $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { $delete_command: onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/schema/permission.pp b/manifests/schema/permission.pp index b98291d..e5efa10 100644 --- a/manifests/schema/permission.pp +++ b/manifests/schema/permission.pp @@ -1,161 +1,161 @@ # Grant or revoke permissions. # To use this class, a suitable `authenticator` (e.g. PasswordAuthenticator) # and `authorizer` (e.g. CassandraAuthorizer) must be set in the Cassandra # class. # # WARNING: Specifying keyspace 'ALL' and 'ALL' for permissions at the same # time is not currently supported by this module. # # @param user_name [string] The name of the user who is to be granted or # revoked. # @param ensure [ present | absent ] Set to present to grant a permission or # absent to revoke it. # @param keyspace_name [string] The name of the keyspace to grant/revoke the # permissions on. If set to 'ALL' then the permission will be applied to # all of the keyspaces. # @param permission_name [string] Can be one of the following: # # * 'ALTER' - ALTER KEYSPACE, ALTER TABLE, CREATE INDEX, DROP INDEX. # * 'AUTHORIZE' - GRANT, REVOKE. # * 'CREATE' - CREATE KEYSPACE, CREATE TABLE. # * 'DROP' - DROP KEYSPACE, DROP TABLE. # * 'MODIFY' - INSERT, DELETE, UPDATE, TRUNCATE. # * 'SELECT' - SELECT. # # If the permission_name is set to 'ALL', this will set all of the specific # permissions listed. # @param table_name [string] The name of a table within the specified # keyspace. If left unspecified, the procedure will be applied to all # tables within the keyspace. define cassandra::schema::permission ( $user_name, $ensure = present, $keyspace_name = 'ALL', $permission_name = 'ALL', $table_name = undef, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ){ +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } if upcase($keyspace_name) == 'ALL' and upcase($permission_name) == 'ALL' { fail('"ALL" keyspaces AND "ALL" permissions are mutually exclusive.') } elsif $table_name { $resource = "TABLE ${keyspace_name}.${table_name}" } elsif upcase($keyspace_name) == 'ALL' { $resource = 'ALL KEYSPACES' } else { $resource = "KEYSPACE ${keyspace_name}" } $read_script = "LIST ALL PERMISSIONS ON ${resource}" $upcase_permission_name = upcase($permission_name) $pattern = "\s${user_name} |\s*${user_name} |\s.*\s${upcase_permission_name}$" $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn} | grep '${pattern}'" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if upcase($permission_name) == 'ALL' { cassandra::schema::permission { "${title} - ALTER": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'ALTER', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } cassandra::schema::permission { "${title} - AUTHORIZE": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'AUTHORIZE', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } # The CREATE permission is not relevant to tables. if !$table_name { cassandra::schema::permission { "${title} - CREATE": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'CREATE', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } } cassandra::schema::permission { "${title} - DROP": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'DROP', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } cassandra::schema::permission { "${title} - MODIFY": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'MODIFY', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } cassandra::schema::permission { "${title} - SELECT": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'SELECT', table_name => $table_name, use_scl => $use_scl, scl_name => $scl_name, } } elsif $ensure == present { $create_script = "GRANT ${permission_name} ON ${resource} TO ${user_name}" $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { $create_script: command => $create_command, unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "REVOKE ${permission_name} ON ${resource} FROM ${user_name}" $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { $delete_script: command => $delete_command, onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/schema/table.pp b/manifests/schema/table.pp index 02eb21b..9e9beb5 100644 --- a/manifests/schema/table.pp +++ b/manifests/schema/table.pp @@ -1,81 +1,81 @@ # Create or drop tables within the schema. # @param keyspace [string] The name of the keyspace. # @param columns [hash] A hash of the columns to be placed in the table. # Optional if the table is to be absent. # @param ensure [present|absent] Ensure a keyspace is created or dropped. # @param options [array] Options to be added to the table creation. # @param table [string] The name of the table. Defaults to the name of the # resource. # @example # cassandra::schema::table { 'users': # keyspace => 'mykeyspace', # columns => { # 'userid' => 'int', # 'fname' => 'text', # 'lname' => 'text', # 'PRIMARY KEY' => '(userid)', # }, # } define cassandra::schema::table ( $keyspace, $ensure = present, $columns = {}, $options = [], $table = $title, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ){ +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } $read_script = "DESC TABLE ${keyspace}.${table}" $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if $ensure == present { $create_script1 = "CREATE TABLE IF NOT EXISTS ${keyspace}.${table}" $cols_def = join(join_keys_to_values($columns, ' '), ', ') $cols_def_rm_collection_type = delete($cols_def, 'COLLECTION-TYPE ') if count($options) > 0 { $options_def = join($options, ' AND ') $create_script = "${create_script1} (${cols_def_rm_collection_type}) WITH ${options_def}" } else { $create_script = "${create_script1} (${cols_def_rm_collection_type})" } $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { $create_command: unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "DROP TABLE IF EXISTS ${keyspace}.${table}" $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { $delete_command: onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/schema/user.pp b/manifests/schema/user.pp index f6e292a..8233961 100644 --- a/manifests/schema/user.pp +++ b/manifests/schema/user.pp @@ -1,137 +1,137 @@ # Create or drop users. # To use this class, a suitable `authenticator` (e.g. PasswordAuthenticator) # must be set in the Cassandra class. # @param ensure [ present | absent ] Valid values can be **present** to # ensure a user is created, or **absent** to remove the user if it exists. # @param password [string] A password for the user. # @param superuser [boolean] If the user is to be a super-user on the system. # @param login [boolean] Allows the role to log in. # @param user_name [string] The name of the user. # @example # cassandra::schema::user { 'akers': # password => 'Niner2', # superuser => true, # } # # cassandra::schema::user { 'lucan': # ensure => absent, # } define cassandra::schema::user ( $ensure = present, $login = true, $password = undef, $superuser = false, $user_name = $title, Boolean $use_scl = $cassandra::params::use_scl, String[1] $scl_name = $cassandra::params::scl_name, - ){ +) { include 'cassandra::schema' if $use_scl { $quote = '\"' } else { $quote = '"' } if $::cassandrarelease != undef { if versioncmp($::cassandrarelease, '2.2') < 0 { $operate_with_roles = false } else { $operate_with_roles = true } } else { $operate_with_roles = false } if $operate_with_roles { $read_script = 'LIST ROLES' } else { $read_script = 'LIST USERS' } $str_match = '\s' $read_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${cassandra::schema::cqlsh_conn} | grep '${str_match}*${user_name} |'" if $use_scl { $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" } else { $read_command = $read_command_tmp } if $ensure == present { if $operate_with_roles { # we are running cassandra > 2.2 $create_script1 = "CREATE ROLE IF NOT EXISTS ${user_name}" if $password != undef { $create_script2 = "${create_script1} WITH PASSWORD = '${password}'" } else { $create_script2 = $create_script1 } if $superuser { if $password != undef { $create_script3 = "${create_script2} AND SUPERUSER = true" } else { $create_script3 = "${create_script2} WITH SUPERUSER = true" } } else { $create_script3 = $create_script2 } if $login { if $superuser or $password != undef { $create_script = "${create_script3} AND LOGIN = true" } else { $create_script = "${create_script3} WITH LOGIN = true" } } else { $create_script = $create_script3 } } else { $create_script1 = "CREATE USER IF NOT EXISTS ${user_name}" if $password != undef { $create_script2 = "${create_script1} WITH PASSWORD '${password}'" } else { $create_script2 = $create_script1 } if $superuser { $create_script = "${create_script2} SUPERUSER" } else { $create_script = "${create_script2} NOSUPERUSER" } } $create_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" } else { $create_command = $create_command_tmp } exec { "Create user (${user_name})": command => $create_command, unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { if $operate_with_roles { $delete_script = "DROP ROLE ${user_name}" } else { $delete_script = "DROP USER ${user_name}" } $delete_command_tmp = "${cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${cassandra::schema::cqlsh_conn}" if $use_scl { $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" } else { $delete_command = $delete_command_tmp } exec { "Delete user (${user_name})": command => $delete_command, onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/system/swapoff.pp b/manifests/system/swapoff.pp index a2244ea..b5df092 100644 --- a/manifests/system/swapoff.pp +++ b/manifests/system/swapoff.pp @@ -1,27 +1,27 @@ # Disable swap on the node as suggested at # http://docs.datastax.com/en/landing_page/doc/landing_page/recommendedSettingsLinux.html # @param device [string] If provided a mount resource will be created to # ensure that the device is absent from /etc/fstab to permanently disable swap. # @param mount [string] The name of the swap mount point. Ignored unless # `device` has been set. # @param path [string] The full path to the file to check if swap is enabled. # @see cassandra::params -class cassandra::system::swapoff( +class cassandra::system::swapoff ( $device = undef, $mount = 'swap', $path = '/proc/swaps', - ) { +) { exec { 'Disable Swap': command => 'swapoff --all', onlyif => "grep -q '^/' ${path}", - path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin' ], + path => ['/bin', '/sbin', '/usr/bin', '/usr/sbin'], } if $device { mount { $mount: ensure => absent, device => $device, fstype => 'swap', } } } diff --git a/manifests/system/sysctl.pp b/manifests/system/sysctl.pp index c226d8a..0884b70 100644 --- a/manifests/system/sysctl.pp +++ b/manifests/system/sysctl.pp @@ -1,113 +1,112 @@ # Set Sysctl (kernel runtime parameters) as suggested in # http://docs.datastax.com/en/landing_page/doc/landing_page/recommendedSettingsLinux.html # # If any of the values is set into the target file, the sysctl command will # be called with the provided file name as an argument. # # @example Basic requirement # require cassandra::system::sysctl # # @param sysctl_args [string] Passed to the `sysctl` command # @param sysctl_file [string] Path to the file to insert the settings into. # @param net_core_optmem_max [integer] The value to set for # net.core.optmem_max # @param net_core_rmem_default [integer] The value to set for # net.core.rmem_default. # @param net_core_rmem_max [integer] The value to set for net_core_rmem_max. # @param net_core_wmem_default [integer] The value to set for # net.core.wmem_default. # @param net_core_wmem_max [integer] The value to set for net.core.wmem_max. # @param net_ipv4_tcp_rmem [string] The value to set for net.ipv4.tcp_rmem. # @param net_ipv4_tcp_wmem [string] The value to set for net.ipv4.tcp_wmem. # @param vm_max_map_count [integer] The value to set for vm.max_map_count. # @see cassandra::params -class cassandra::system::sysctl( +class cassandra::system::sysctl ( $sysctl_args = '-p', $sysctl_file = $cassandra::params::sysctl_file, $net_core_optmem_max = 40960, $net_core_rmem_default = 16777216, $net_core_rmem_max = 16777216, $net_core_wmem_default = 16777216, $net_core_wmem_max = 16777216, $net_ipv4_tcp_rmem = $cassandra::params::net_ipv4_tcp_rmem, $net_ipv4_tcp_wmem = $cassandra::params::net_ipv4_tcp_wmem, $vm_max_map_count = 1048575, - ) inherits cassandra::params { - +) inherits cassandra::params { ini_setting { "net.core.rmem_max = ${net_core_rmem_max}": ensure => present, path => $sysctl_file, section => '', setting => 'net.core.rmem_max', value => $net_core_rmem_max, notify => Exec['Apply sysctl changes'], } ini_setting { "net.core.wmem_max = ${net_core_wmem_max}": ensure => present, path => $sysctl_file, section => '', setting => 'net.core.wmem_max', value => $net_core_wmem_max, notify => Exec['Apply sysctl changes'], } ini_setting { "net.core.rmem_default = ${net_core_rmem_default}": ensure => present, path => $sysctl_file, section => '', setting => 'net.core.rmem_default', value => $net_core_rmem_default, notify => Exec['Apply sysctl changes'], } ini_setting { "net.core.wmem_default = ${net_core_wmem_default}": ensure => present, path => $sysctl_file, section => '', setting => 'net.core.wmem_default', value => $net_core_wmem_default, notify => Exec['Apply sysctl changes'], } ini_setting { "net.core.optmem_max = ${net_core_optmem_max}": ensure => present, path => $sysctl_file, section => '', setting => 'net.core.optmem_max', value => $net_core_optmem_max, notify => Exec['Apply sysctl changes'], } ini_setting { "net.ipv4.tcp_rmem = ${net_ipv4_tcp_rmem}": ensure => present, path => $sysctl_file, section => '', setting => 'net.ipv4.tcp_rmem', value => $net_ipv4_tcp_rmem, notify => Exec['Apply sysctl changes'], } ini_setting { "net.ipv4.tcp_wmem = ${net_ipv4_tcp_wmem}": ensure => present, path => $sysctl_file, section => '', setting => 'net.ipv4.tcp_wmem', value => $net_ipv4_tcp_wmem, notify => Exec['Apply sysctl changes'], } ini_setting { "vm.max_map_count = ${vm_max_map_count}": ensure => present, path => $sysctl_file, section => '', setting => 'vm.max_map_count', value => $vm_max_map_count, notify => Exec['Apply sysctl changes'], } exec { 'Apply sysctl changes': command => "/sbin/sysctl ${sysctl_args} ${sysctl_file}", refreshonly => true, } } diff --git a/manifests/system/transparent_hugepage.pp b/manifests/system/transparent_hugepage.pp index 90b23c5..43f05a5 100644 --- a/manifests/system/transparent_hugepage.pp +++ b/manifests/system/transparent_hugepage.pp @@ -1,14 +1,14 @@ # Disable Transparant Huge Pages as suggested in # http://docs.datastax.com/en/landing_page/doc/landing_page/recommendedSettingsLinux.html. # @param path [string] The full path to the file for checking/setting # if Transparent Hugepages is enabled. # @see cassandra::params class cassandra::system::transparent_hugepage ( $path = '/sys/kernel/mm/transparent_hugepage/defrag', - ) inherits cassandra::params { +) inherits cassandra::params { exec { 'Disable Java Hugepages': command => "/bin/echo never > ${path}", - path => [ '/bin', '/usr/bin' ], + path => ['/bin', '/usr/bin'], unless => "grep -q '\\[never\\]' ${path}", } } diff --git a/spec/acceptance/nodesets/archlinux-2-x64.yml b/spec/acceptance/nodesets/archlinux-2-x64.yml new file mode 100644 index 0000000..89b6300 --- /dev/null +++ b/spec/acceptance/nodesets/archlinux-2-x64.yml @@ -0,0 +1,13 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +HOSTS: + archlinux-2-x64: + roles: + - master + platform: archlinux-2-x64 + box: archlinux/archlinux + hypervisor: vagrant +CONFIG: + type: foss diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index c9476b1..2540280 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,487 +1,487 @@ require 'spec_helper' describe 'cassandra' do context 'On an unknown OS with defaults for all parameters' do let :facts do { operatingsystemmajrelease: '16', osfamily: 'Darwin', os: { 'family' => 'Darwin', 'release' => { 'full' => '16.0.0', 'major' => '16', 'minor' => '0' } } } end it { is_expected.to raise_error(Puppet::Error) } end context 'Test the default parameters (RedHat)' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7', os: { 'family' => 'RedHat', 'name' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end it do is_expected.to contain_package('cassandra').with( ensure: 'present', name: 'cassandra22' ).that_notifies('Exec[cassandra_reload_systemctl]') is_expected.to contain_exec('cassandra_reload_systemctl').only_with( command: '/usr/bin/systemctl daemon-reload', onlyif: 'test -x /usr/bin/systemctl', path: ['/usr/bin', '/bin'], refreshonly: true ) is_expected.to contain_file('/etc/cassandra/default.conf').with( ensure: 'directory', group: 'cassandra', owner: 'cassandra', mode: '0755' ).that_requires('Package[cassandra]') is_expected.to contain_file('/etc/cassandra/default.conf/cassandra.yaml'). with( - ensure: 'present', + ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_requires('Package[cassandra]') is_expected.to contain_class('cassandra').only_with( baseline_settings: {}, cassandra_2356_sleep_seconds: 5, cassandra_9822: false, cassandra_yaml_tmpl: 'cassandra/cassandra.yaml.erb', commitlog_directory_mode: '0750', manage_config_file: true, config_file_mode: '0644', config_path: '/etc/cassandra/default.conf', data_file_directories_mode: '0750', dc: 'DC1', fail_on_non_supported_os: true, hints_directory_mode: '0750', package_ensure: 'present', package_name: 'cassandra22', rack: 'RAC1', rackdc_tmpl: 'cassandra/cassandra-rackdc.properties.erb', saved_caches_directory_mode: '0750', service_enable: true, service_name: 'cassandra', service_provider: nil, service_refresh: true, settings: {}, snitch_properties_file: 'cassandra-rackdc.properties', systemctl: '/usr/bin/systemctl' ) end end context 'On RedHat 7 with data directories specified.' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7', os: { 'family' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end let :params do { commitlog_directory: '/var/lib/cassandra/commitlog', data_file_directories: ['/var/lib/cassandra/data'], hints_directory: '/var/lib/cassandra/hints', saved_caches_directory: '/var/lib/cassandra/saved_caches', settings: { 'cluster_name' => 'MyCassandraCluster' } } end it do is_expected.to have_resource_count(10) is_expected.to contain_file('/var/lib/cassandra/commitlog') is_expected.to contain_file('/var/lib/cassandra/data') is_expected.to contain_file('/var/lib/cassandra/hints') is_expected.to contain_file('/var/lib/cassandra/saved_caches') end end context 'On RedHat 7 with service provider set to init.' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7', os: { 'family' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end let :params do { service_provider: 'init' } end it do is_expected.to have_resource_count(7) is_expected.to contain_exec('/sbin/chkconfig --add cassandra').with( unless: '/sbin/chkconfig --list cassandra' ). that_requires('Package[cassandra]'). that_comes_before('Service[cassandra]') end end context 'On a Debian OS with defaults for all parameters' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian', os: { 'family' => 'Debian', 'release' => { 'full' => '8.11', 'major' => '8', 'minor' => '11' } } } end it do is_expected.to contain_class('cassandra') is_expected.to contain_group('cassandra').with_ensure('present') is_expected.to contain_package('cassandra').with( ensure: 'present', name: 'cassandra' ).that_notifies('Exec[cassandra_reload_systemctl]') is_expected.to contain_exec('cassandra_reload_systemctl').only_with( command: '/bin/systemctl daemon-reload', onlyif: 'test -x /bin/systemctl', path: ['/usr/bin', '/bin'], refreshonly: true ) is_expected.to contain_service('cassandra').with( ensure: nil, name: 'cassandra', enable: 'true' ) is_expected.to contain_exec('CASSANDRA-2356 sleep'). with( command: '/bin/sleep 5', refreshonly: true, user: 'root' ). that_subscribes_to('Package[cassandra]'). that_comes_before('Service[cassandra]') is_expected.to contain_user('cassandra'). with( ensure: 'present', comment: 'Cassandra database,,,', gid: 'cassandra', home: '/var/lib/cassandra', shell: '/bin/false', managehome: true ). that_requires('Group[cassandra]') is_expected.to contain_file('/etc/cassandra').with( ensure: 'directory', group: 'cassandra', owner: 'cassandra', mode: '0755' ) is_expected.to contain_file('/etc/cassandra/cassandra.yaml'). with( - ensure: 'present', + ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_comes_before('Package[cassandra]'). that_requires(['User[cassandra]', 'File[/etc/cassandra]']) is_expected.to contain_file('/etc/cassandra/cassandra-rackdc.properties'). with( ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_requires(['File[/etc/cassandra]', 'User[cassandra]']). that_comes_before('Package[cassandra]') is_expected.to contain_service('cassandra'). that_subscribes_to( [ 'File[/etc/cassandra/cassandra.yaml]', 'File[/etc/cassandra/cassandra-rackdc.properties]', 'Package[cassandra]' ] ) end end context 'CASSANDRA-9822 activated on Ubuntu 16.04' do let :facts do { operatingsystemmajrelease: '16.04', osfamily: 'Debian', lsbdistid: 'Ubuntu', lsbdistrelease: '16.04', os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'full' => '16.04', 'major' => '16.04' } } } end let :params do { cassandra_9822: true } end it do is_expected.to contain_file('/etc/init.d/cassandra').with( source: 'puppet:///modules/cassandra/CASSANDRA-9822/cassandra', mode: '0555' ).that_comes_before('Package[cassandra]') end end context 'Install DSE on a Red Hat family OS.' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat', os: { 'family' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end let :params do { package_ensure: '4.7.0-1', package_name: 'dse-full', config_path: '/etc/dse/cassandra', service_name: 'dse' } end it do is_expected.to contain_file('/etc/dse/cassandra/cassandra.yaml').that_notifies('Service[cassandra]') is_expected.to contain_file('/etc/dse/cassandra') is_expected.to contain_file('/etc/dse/cassandra/cassandra-rackdc.properties'). with( ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_notifies('Service[cassandra]') is_expected.to contain_package('cassandra').with( ensure: '4.7.0-1', name: 'dse-full' ) is_expected.to contain_service('cassandra').with_name('dse') end end context 'On an unsupported OS pleading tolerance' do let :facts do { operatingsystemmajrelease: '16', osfamily: 'Darwin', os: { 'family' => 'Darwin', 'release' => { 'full' => '16.0.0', 'major' => '16', 'minor' => '0' } } } end let :params do { config_file_mode: '0755', config_path: '/etc/cassandra', fail_on_non_supported_os: false, package_name: 'cassandra', service_provider: 'base', systemctl: '/bin/true' } end it do is_expected.to contain_file('/etc/cassandra/cassandra.yaml').with('mode' => '0755') is_expected.to contain_service('cassandra').with(provider: 'base') is_expected.to have_resource_count(6) end end context 'Ensure cassandra service can be stopped and disabled.' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian', os: { 'family' => 'Debian', 'release' => { 'full' => '8.11', 'major' => '8', 'minor' => '11' } } } end let :params do { service_ensure: 'stopped', service_enable: 'false' } end it do is_expected.to contain_service('cassandra'). with(ensure: 'stopped', name: 'cassandra', enable: 'false') end end context 'Test the dc and rack properties with defaults (Debian).' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian', os: { 'family' => 'Debian', 'release' => { 'full' => '8.11', 'major' => '8', 'minor' => '11' } } } end it do is_expected.to contain_file('/etc/cassandra/cassandra-rackdc.properties'). with_content(%r{^dc=DC1}). with_content(%r{^rack=RAC1$}). with_content(%r{^#dc_suffix=$}). with_content(%r{^# prefer_local=true$}) end end context 'Test the dc and rack properties with defaults (RedHat).' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat', os: { 'family' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end it do is_expected.to contain_file('/etc/cassandra/default.conf/cassandra-rackdc.properties'). with_content(%r{^dc=DC1}). with_content(%r{^rack=RAC1$}). with_content(%r{^#dc_suffix=$}). with_content(%r{^# prefer_local=true$}) end end context 'Test the dc and rack properties.' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat', os: { 'family' => 'RedHat', 'release' => { 'full' => '7.6.1810', 'major' => '7', 'minor' => '6' } } } end let :params do { snitch_properties_file: 'cassandra-topology.properties', dc: 'NYC', rack: 'R101', dc_suffix: '_1_cassandra', prefer_local: 'true' } end it do is_expected.to contain_file('/etc/cassandra/default.conf/cassandra-topology.properties'). with_content(%r{^dc=NYC$}). with_content(%r{^rack=R101$}). with_content(%r{^dc_suffix=_1_cassandra$}). with_content(%r{^prefer_local=true$}) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0fb7a79..5904139 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,22 +1,22 @@ # This file is managed via modulesync # https://github.com/voxpupuli/modulesync # https://github.com/voxpupuli/modulesync_config RSpec.configure do |c| c.mock_with :mocha end # puppetlabs_spec_helper will set up coverage if the env variable is set. # We want to do this if lib exists and it hasn't been explicitly set. ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../../lib', __FILE__)) require 'voxpupuli/test/spec_helper' if File.exist?(File.join(__dir__, 'default_module_facts.yml')) - facts = YAML.load(File.read(File.join(__dir__, 'default_module_facts.yml'))) + facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml'))) if facts facts.each do |name, value| add_custom_fact name.to_sym, value end end end