diff --git a/.gitignore b/.gitignore index 49fe372..c023fa3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,17 @@ .bundle/ .idea/ .project .travis/secrets.tar .vagrant/ .yardoc/ *.iml *.swn *.swo *.swp Gemfile.lock coverage/ -docs/ +doc/ pkg/ spec/fixtures/ vendor/ log/ diff --git a/.yardopts b/.yardopts index a5f7e83..b6bedde 100644 --- a/.yardopts +++ b/.yardopts @@ -1,5 +1,4 @@ ---output-dir docs --markup markdown --tag caveats:"Caveats:" --tag resolution:"Resolution:" - CONTRIBUTING.md LICENSE README.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 794dc1a..0d1e9ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,1047 +1,1066 @@ # Change Log for Puppet Module locp-cassandra +##2016-12-01 - Release 2.2.0 ([diff](https://github.com/locp/cassandra/compare/2.1.2...2.2.0)) + +### Summary + +At long last we have a defined type for handling permissions (something that +we have been promising since May). Added some more facts for assisting +in JVM tuning. Also fixed an error that was happening when attempting to +build the project. + +### Features + +* Added the `permissions` attribute to the `cassandra::schema` class. +* Added the `cassandra::schema::permission` + +### Bugfixes + +* Some refactoring of the ruby code since the release of Rubocop 0.46.0 which + was failing code that previously had passed OK. + ##2016-11-02 - Release 2.1.2 ([diff](https://github.com/locp/cassandra/compare/2.1.1...2.1.2)) ### Summary Basically a non-functional release to reduce some of the technical debt from the 2.0.0 release. Also some minor improvements to the documentation. ##2016-11-19 - Release 1.26.1 ([diff](https://github.com/locp/cassandra/compare/1.26.0...1.26.1)) ### Summary Retro-fitted a bug that was fixed in 2.1.1 into the 1.X.Y version of the module. ### Bugfixes * A hotfix for a bug in `cassandra::schema` that has been around since version 1.18.0 of this module. ##2016-11-02 - Release 2.1.1 ([diff](https://github.com/locp/cassandra/compare/2.1.0...2.1.1)) ### Summary A hotfix for a bug in `cassandra::schema` that has been around since version 1.18.0 of this module. ### Bugfixes * Fixed a bug where cql_types would not be created unless keyspaces were also provided. * Fixed a minor typo in the README. ##2016-10-29 - Release 2.1.0 ([diff](https://github.com/locp/cassandra/compare/2.0.2...2.1.0)) ### Summary A mixture of new features, a new style of documentation and other improvements. Also ran the [Sonar-Puppet](https://github.com/iwarapter/sonar-puppet) plugin against the code to improve the code quality. ### Features * The following facts are now available: * cassandramajorversion * cassandraminorversion * cassandrapatchversion * cassandrarelease * The following attributes are now available: * cassandra::commitlog_directory * cassandra::commitlog_directory_mode * cassandra::data_file_directories * cassandra::data_file_directories_mode * cassandra::hints_directory * cassandra::hints_directory_mode * cassandra::saved_caches_directory * cassandra::saved_caches_directory_mode * cassandra::systemctl ### Bugfixes * Resolved all issues identified by Sonar-Puppet from 38 (2 major, 36 minor). In doing so, this reduced the technical debt ration from 0.9% to 0.0%. ### Improvements * The reference documentation is now processed via http://locp.github.io/cassandra * Made a start on refactoring the spec/unit tests so that there is less duplication of code. ##2016-10-12 - Release 2.0.2 ([diff](https://github.com/locp/cassandra/compare/2.0.1...2.0.2)) ### Summary This is a non-functional patch release that fixes some issues in documentation, and fixes some bugs and makes some improvements in our testing framework. ### Improvements * Ensure there is a framework for supporting the legacy 1.X.Y. module until the end of 2016. * A more obvious test rig for the beaker/acceptance tests on TravisCI. ### Bugfixes * Corrected misleading documentation. * Ensure legacy test builds still work against Ruby 1.9.3. * Corrected deprecated tags in the module metadata. ##2016-10-08 - Release 1.26.0 ([diff](https://github.com/locp/cassandra/compare/1.25.2...1.26.0)) ### Improvements * The `cassandra::seeds` paramater can now be provided as an array or as a string. # Bugfixes * Ensure legacy builds still work on TravisCI. ##2016-10-01 - Release 2.0.1 ([diff](https://github.com/locp/cassandra/compare/2.0.0...2.0.1)) ### Summary A non-functional release containing some improvements and documentation corrections. ### Improvements * Corrected some out of date documentation. * Removed some deprecated files. * Regained 100% spec test coverage. ##2016-09-29 - Release 2.0.0 ([diff](https://github.com/locp/cassandra/compare/1.26.0...2.0.0)) ### Summary This is a major release and will more than likely break your existing manifest until you alter your code. Please see the [Upgrading](https://github.com/locp/cassandra/tree/release/274/v2.0.0#upgrading) section of the README for further details. * The method of passing parameters to Cassandra has been made more flexible. * Support for Ubuntu 16.04. * Changes to how `service_ensure` is handled. * `cassandra::file` is now a define, not a class (as it should have been). ##2016-09-03 - Release 1.25.2 ([diff](https://github.com/locp/cassandra/compare/1.25.1...1.25.2)) ### Summary The `service_systemd` attribute is now deprecated for the `cassandra`, `cassandra::datastax_agent` and `cassandra::opscenter` classes. See https://github.com/locp/cassandra/wiki/DEP-020 for more details. ##2016-08-14 - Release 1.25.1 ([diff](https://github.com/locp/cassandra/compare/1.25.0...1.25.1)) ### Summary Bugfix to ensure that the name of the PID file for the DataStax Agent service matches with the service name. ##2016-07-17 - Release 1.25.0 ([diff](https://github.com/locp/cassandra/compare/1.24.3...1.25.0)) ### Summary A feature release. ### Features * The `cassandra` class now has a `disk_access_mode` attribute. ##2016-06-26 - Release 1.24.3 ([diff](https://github.com/locp/cassandra/compare/1.24.2...1.24.3)) ### Summary A couple of non-functional bug fixes. ### Bugfixes * The new version of RuboCop flagged code changes required in the Vagrantfile. * The new version of Puppet Lint flagged code changes required in cassandra::java. ##2016-06-20 - Release 1.24.2 ([diff](https://github.com/locp/cassandra/compare/1.24.1...1.24.2)) ### Summary A non-functional bug fix. ### Bugfixes * The release of the specinfra gem (2.59.1) caused problems with our build. Pinned now to 2.59.0. ##2016-06-18 - Release 1.24.1 ([diff](https://github.com/locp/cassandra/compare/1.24.0...1.24.1)) ### Summary Really only affects CentOS 7 as all the other supported operating systems do not require the systemd file to be installed. ### Bugfixes * Change the way that systemd shuts Cassandra down. ##2015-05-25 - Release 1.24.0 ([diff](https://github.com/locp/cassandra/compare/1.23.1...1.24.0)) ### Summary A Debian-centric release. Debian 8 is now supported and a workaround for [CASSANDRA-2356](https://issues.apache.org/jira/browse/CASSANDRA-2356) (which only affects Debian. ### Features * New attributes to the `::cassandra` class are: * cassandra_2356_sleep_seconds * config_path_parents * rackdc_tmpl ### Bugfixes * CASSANDRA-2356 ### Improvements * Debian 8 is now part of the acceptance testing release process. ##2016-05-10 - Release 1.23.1 ([diff](https://github.com/locp/cassandra/compare/1.23.0...1.23.1)) ### Summary A minor bugfix that fixes a problem that would only affect module developers, not users of the module. ### Bugfixes * Rubocop 0.4.0 is stricter so implemented changes that were flagged by it. ##2016-05-07 - Release 1.23.0 ([diff](https://github.com/locp/cassandra/compare/1.22.1...1.23.0)) ### Summary A couple of new features, a non-functional improvement and a bugfix. ### Features * Added the cassandra::file class. * Added the following attributes to the cassandra::schema class: * cqlsh_client_tmpl * cqlsh_client_config ### Bugfixes * Fixed a daft error that stopped beaker tests running on CentOS 7. ### Improvements * Improved how fast the beaker/acceptance tests are run from TravisCI. ##2016-05-03 - Release 1.22.1 ([diff](https://github.com/locp/cassandra/compare/1.22.0...1.22.1)) ### Summary A non-functional release for a minor improvement and a bug fix. ### Bugfixes * Fixes a problem with resource ordering if the service_refresh attribute is set to false. ### Improvements * Test coverage in Coveralls is now back at 100% (https://coveralls.io/github/locp/cassandra). ##2016-04-25 - Release 1.22.0 ([diff](https://github.com/locp/cassandra/compare/1.21.0...1.22.0)) ### Summary Two new features. ### Features * Allow the creation and dropping of users with the following: * A new defined type cassandra::schema::user * The new attribute cassandra::schema::users * Allow the manipulation of the environment file with the new class cassandra::env. ##2016-04-20 - Release 1.21.0 ([diff](https://github.com/locp/cassandra/compare/1.20.0...1.21.0)) ### Summary Some minor bug fixes. Also some features and improvements that allow acceptance tests to be run against Cassandra 3. ### Features * Added the following attributes to cassandra::java: * aptkey * aptsource * yumrepo ### Bugfixes * Corrected some errors in the README and CHANGELOG. * Fixed problems with TravisCI builds. * Fixed problems with CircleCI builds. ### Improvements * Acceptance testing of Cassandra 3. ##2016-04-13 - Release 1.20.0 ([diff](https://github.com/locp/cassandra/compare/1.19.0...1.20.0)) ### Summary A minor release for client requirements. ### Features * Added the compaction_large_partition_warning_threshold_mb and memtable_allocation_type attributes to the cassandra class. ##2016-04-06 - Release 1.19.0 ([diff](https://github.com/locp/cassandra/compare/1.18.1...1.19.0)) ### Summary A new template attribute and a couple of bug fixes. ### Features * The hints_directory attribute has been added to the cassandra class for placing into the template. ### Bugfixes * Some documentation errors that had been identified have been resolved. * A problem with OpsCenter and systemd has been resolved. So far only CentOS 7 from the supported operating systems has been identified as being required to use systemd. ##2016-03-27 - Release 1.18.1 ([diff](https://github.com/locp/cassandra/compare/1.18.0...1.18.1)) ### Summary Bug fixes and some minor and non-functional improvements. ### Bugfixes * Resource ordering clarified in the cassandra::schema class. * The cqlsh command now attempts to connect to rpc_address, not the listen_address. ### Improvements * Optimised the CircleCI build process. * Made some changes to the documentation to better reflect the new functionality delivered in 1.18.0. ##2016-03-26 - Release 1.18.0 ([diff](https://github.com/locp/cassandra/compare/1.17.0...1.18.0)) ### Summary Some more functionality and sub-classes for cassandra::schema. Also some code and pipe-line improvements and a couple of bug fixes. ### Features * The cassandra::schema class now has the following additional attributes: * cql_types * indexes * tables There are also corresponting defined types for those attributes: * cassandra::schema::cql_type * cassandra::schema::index * cassandra::schema::table * The cassandra::opscenter class now has a new attribute called ldap_group_search_filter_with_dn. ### Bugfixes * In the firewalls class, an OpsCenter server also needs to connect to the Cassandra node it is monitoring as a client. The ports have been adjusted to allow this to happen. * rspec-puppet version 2.4.0 was breaking our builds so pegged ourselves to 2.3.2. ### Improvements * Some minor and non-functional improvements to the build pipe-line. * Carried out an audit using the Puppet plugin for SonarQube. The number of issues has been reduced from 227 (13 major, 214 minor) to 4 major issues of which 2 are false positives. The remaining issues will be resolved in 2.0.0. ##2016-03-22 - Release 1.17.0 ([diff](https://github.com/locp/cassandra/compare/1.16.0...1.17.0)) ### Summary Another small change that is an emergency requirement for a client. ### Features * Added the `storage_keyspace` attribute to the cassandra::datastax_agent class. ##2016-03-15 - Release 1.16.0 ([diff](https://github.com/locp/cassandra/compare/1.15.1...1.16.0)) ### Summary A smaller release than usual, but containing changes required for a client. ### Features * Added the `hosts` attribute to the cassandra::datastax_agent class. ### Bugfixes * The **address.yaml** file for the DataStax agent is now owned by the cassandra user. ##2016-03-11 - Release 1.15.1 ([diff](https://github.com/locp/cassandra/compare/1.15.0...1.15.1)) ### Summary A small improvement. ### Improvements * Clarified CQL and Python versions. ##2016-03-10 - Release 1.15.0 ([diff](https://github.com/locp/cassandra/compare/1.14.2...1.15.0)) ### Summary A rather large release. Minor (non-functional) fixes to the production pipeline and new features. ### Features * A new class `cassandra::schema` allows the creation and dropping of keyspaces. * Added the `additional_lines` attribute to the `cassandra` class. * Added the `service_systemd` attribute to the `cassandra::opscenter` class. * Allow the systemd template sources to be specified by the user. This is with the `service_systemd_tmpl` attribute to the following classes: * cassandra * cassandra::datastax_agent * cassandra::opscenter * Added another template file for `cassandra` => `service_systemd_tmpl` that is suitable for Cassandra 2.0. ### Bugfixes * Worked around a problem with rake-11 in the Gemfile. * Fixed a problem in the CircleCI configuration. ### Improvements * Renamed the `ensure` attribute to `package_ensure` so that it is more in line with how it's called in other modules. This was done on the the following classes: * cassandra::optutils * cassandra::opscenter * cassandra::opscenter::pycrypto * cassandra::java * Updated the AWS AMI for the TravisCI/AWS acceptance testing to hopefully speed up builds a bit. ##2016-02-29 - Release 1.14.2 ([diff](https://github.com/locp/cassandra/compare/1.14.1...1.14.2)) ### Summary A small bugfix release. ### Bugfixes * Removed `Restart=always` from the Systemd configuration files. ##2016-02-27 - Release 1.14.1 ([diff](https://github.com/locp/cassandra/compare/1.14.0...1.14.1)) ### Summary A non-functional release of improvements and a bugfix. ### Bugfixes * If a systemd service file is created or updated, then systemctl daemon-reload is now be executed. ### Improvements * The workflow for building the module has been improved to include: * Automatic integration of improvements and bugfixes into release candidates. * Testing of release candidates includes acceptance (beaker) as well as unit (spec) tests. * The refactoring of the majority of the Ruby code used to test and build this module so that it is hopefully more readable and easier to maintain. * The automation of what had previously been manual steps when building a release. ##2016-02-19 - Release 1.14.0 ([diff](https://github.com/locp/cassandra/compare/1.13.0...1.14.0)) ### Summary A minor release with one of each of a feature, bug fix and improvement. ### Features * Added the orbited_longpoll attribute to the cassandra::opscenter class. ### Bugfixes * Fixed a problem with the DataStax agent and systemd. ### Improvements * Refactored the contributors section of the README. ##2016-02-14 - Release 1.13.0 ([diff](https://github.com/locp/cassandra/compare/1.12.2...1.13.0)) ### Summary A mixed back of new features in the shape of attributes for the cassandra, cassandra::datastax_agent and cassandra::opscenter classes. A couple of bug fixes and some non-functional improvements. ### Features * Added the thrift_framed_transport_size_in_mb attribute to ::cassandra. * Added the following attributes to ::cassandra::datastax_agent: * async_pool_size * async_queue_size * service_systemd * Added the config_purge attribute to ::cassandra::opscenter. ### Bugfixes * Removed incorrect puppet code from the README examples. * Fixed a problem with the beaker 2.34.0 gem which was causing problems during automated acceptance testing. ### Improvements * Changed the AWS instance type used by the TravisCI triggered acceptance tests from a c3.xlarge to c4.xlarge. * Merged the acceptance tests virtual nodes into family specific node sets. * Refactored the Gemfile. * Changed references in the documentation to parameters to refer to attributes as that is more Puppet-like. * Changed the format of the contributers section. ##2016-02-12 - Release 1.12.2 ([diff](https://github.com/locp/cassandra/compare/1.12.1...1.12.2)) ### Summary More bug fixes. ### Bugfixes * Fixed a problem with the Red Hat family and systemd not starting the service and reporting all service stops as failures, regardless of if they were or not. ##2016-02-08 - Release 1.12.1 ([diff](https://github.com/locp/cassandra/compare/1.12.0...1.12.1)) ### Summary This is a non-functional release. Some bug fixes and release improvements. ### Bugfixes * Completed documentation for attributes. This was missing for the `inter_dc_stream_throughput_outbound_megabits_per_sec` and `stream_throughput_outbound_megabits_per_sec` options. * Corrected the ownership and directories for the OpsCenter configuration. ### Improvements * Nightly build created so that issues similar to those found in issues #136 and #157 can be caught quicker. ##2016-01-27 - Release 1.12.0 ([diff](https://github.com/locp/cassandra/compare/1.11.0...1.12.0)) ### Summary A new feature in the cassandra::datastax_agent class, a minor bug fix and integration with CircleCI. ### Features * There is now an agent_alias attribute for the cassandra::datastax_agent class. ### Bugfixes * Unit tests were failing due to problems with the puppet-3.8.5 gem. ### Improvements * In addition to TravisCI, the build process is now integrated with [CircleCI](https://circleci.com/gh/locp/cassandra). ##2016-01-01 - Release 1.11.0 ([diff](https://github.com/locp/cassandra/compare/1.10.0...1.11.0)) ### Summary New features added to the main class. Also some non-functional improvements. ### Features * The addition of the listen_interface and rpc_interface attributes to the main class. ### Improvements * Added more detail to the attributes to the main class in the README. * Improved the module metadata. * Clarified private defined types with the private subclass. * The test coverage in release 1.10.0 dropped to 99.09%. Got it back to 100% in this release. ##2015-12-19 - Release 1.10.0 ([diff](https://github.com/locp/cassandra/compare/1.9.2...1.10.0)) ### Summary A feature release with minor improvements. ### Features * Added the ability to allow setting the local_interface for the DataStax agent configuration. * Allow the service provider to be specified for the Cassandra, DataStax agent and OpsCenter services with the service_provider attribute. * Optionally allow a systemd system file be inserted with the cassandra::service_systemd attribute. ### Improvements * Allow the files resources specified with in the cassandra attributes: * commitlog_directory * data_file_directories * saved_caches_directory To co-exist with file resources with the same name. ##2015-11-21 - Release 1.9.2 ([diff](https://github.com/locp/cassandra/compare/1.9.1...1.9.2)) ### Summary A bug fix release that deals with some problems with Cassandra 3. ### Bugfixes * Attempt to mitigate against problems with Debian attempting to install Cassandra 3 when installing the dsc22 package. * Also reverted the project home to the GitHub project page. ##2015-11-09 - Release 1.9.1 ([diff](https://github.com/locp/cassandra/compare/1.9.0...1.9.1)) ### Summary A bug fix release. ### Bugfixes * The default value for the permissions mode of the Cassandra configuration file were far too open. Changed from 0666 to 0644. ##2015-10-25 - Release 1.9.0 ([diff](https://github.com/locp/cassandra/compare/1.8.1...1.9.0)) ### Summary Added more features for the configuration of Cassandra, some improvements to the testing carried out before a release and a minor correction to the change log documentation. ### Features * The following attributes have been added to the ::cassandra class to be configured into the configuration file: * client_encryption_algorithm * client_encryption_cipher_suites * client_encryption_protocol * client_encryption_require_client_auth * client_encryption_store_type * client_encryption_truststore * client_encryption_truststore_password * counter_cache_size_in_mb * index_summary_capacity_in_mb * key_cache_save_period * key_cache_keys_to_save * seed_provider_class_name * server_encryption_algorithm * server_encryption_cipher_suites * server_encryption_protocol * server_encryption_require_client_auth * server_encryption_store_type Please see the README file for more details. ### Bugfixes * Corrected an incorrect date (typo) in this document. ### Improvements * There is now an automated test to mitigate the risk of unnecessarily refreshes of the Cassandra service due to non-functional changes to the configuration file. ##2015-10-14 - Release 1.8.1 ([diff](https://github.com/locp/cassandra/compare/1.8.0...1.8.1)) ### Summary A minor bug fix. ### Bugfixes * Fixed an edge case issue concerning users that may have been using the fail_on_non_supported_os before it was fixed in 1.8.0. ##2015-10-06 - Release 1.8.0 ([diff](https://github.com/locp/cassandra/compare/1.7.1...1.8.0)) ### Summary Some new features a minor bug fix and some non-functional improvements. ### Features * Added the service_refresh and config_file_mode attributes to the Cassandra class. ### Bugfixes * The name of the fail_on_non_supported_os attribute has been corrected. ### Improvements * Automated acceptance tests in preparation for a release now run faster. ##1015-10-01 - Release 1.7.1 ([diff](https://github.com/locp/cassandra/compare/1.7.0...1.7.1)) ### Summary A minor bug fix that incorrctly gave a failed build status for the module. ### Bugfixes * Fixed a problem that was showing the status of the module build as an error since the release of the fog-google gem version 0.1.1. ##2015-10-01 - Release 1.7.0 ([diff](https://github.com/locp/cassandra/compare/1.6.0...1.7.0)) ### Summary * Corrected a bug in how commitlog_sync has handled by Cassandra. * Some non-functional improvements * Additional features for the cassandra::datastax_repo class. ### Features * Added the commitlog_segment_size_in_mb attribute to the cassandra class. * Added the following fields to the cassandra::datastax_repo class: * descr * key_id * key_url * pkg_url * release This should make the configuring of repositories more flexible. ### Bugfixes * Fixed a bug in how the commitlog_sync and the attributes that are associated with it are handled ### Improvements The following non-functional improvements were implemented: * Added tags to the module metadata. * Migrated the acceptance tests from Vagrant to Docker. The associated improvements to performance means that more rigorous acceptance tests can be applied in a shorter time. For the first time as well, they are visible on Travis. ##2015-09-23 - Release 1.6.0 ([diff](https://github.com/locp/cassandra/compare/1.5.0...1.6.0)) ### Summary More attributes for ::cassandra and ::cassandra::datastax_agent. Also some non-functional improvements in the automated unit tests. ### Features * The JAVA_HOME can now be set for the datastax_agent (see the cassandra::datastax_agent => java_home attribute). * The file mode for the directories can now be specified for the commitlog_directory, data_file_directories and the saved_caches_directory in the cassandra class. ### Improvements * Uncovered resources in the unit testing are now tested. ##2015-09-21 - Release 1.5.0 ([diff](https://github.com/locp/cassandra/compare/1.4.2...1.5.0)) ### Summary More attributes have been added that can be configured into the cassandra.yaml file. ### Features * The following attributes to the cassandra class can be configured into the cassandra configuration: * broadcast_address * broadcast_rpc_address * commitlog_sync * commitlog_sync_batch_window_in_ms * commitlog_total_space_in_mb * concurrent_compactors * counter_cache_keys_to_save * file_cache_size_in_mb * initial_token * inter_dc_stream_throughput_outbound_megabits_per_sec * internode_authenticator * internode_recv_buff_size_in_bytes * internode_send_buff_size_in_bytes * memory_allocator * memtable_cleanup_threshold * memtable_flush_writers * memtable_heap_space_in_mb * memtable_offheap_space_in_mb * native_transport_max_concurrent_connections * native_transport_max_concurrent_connections_per_ip * native_transport_max_frame_size_in_mb * native_transport_max_threads * permissions_update_interval_in_ms * phi_convict_threshold * request_scheduler_options_default_weight * request_scheduler_options_throttle_limit * row_cache_keys_to_save * rpc_max_threads * rpc_min_threads * rpc_recv_buff_size_in_bytes * rpc_send_buff_size_in_bytes * streaming_socket_timeout_in_ms * stream_throughput_outbound_megabits_per_sec ### Improvements * Clarity of changes per release in the change log (this document). ##2015-09-15 - Release 1.4.2 ([diff](https://github.com/locp/cassandra/compare/1.4.1...1.4.2)) ### Summary Fixed a problem identified whilst releasing 1.4.1 and a bug fixed by a contributed pull request. ### Features * n/a ### Bugfixes * Fixed a problem with the acceptance tests. * The datastax-agent service is restarted if the package is updated. ### Improvements * n/a ##2015-09-15 - Release 1.4.1 ([diff](https://github.com/locp/cassandra/compare/1.4.0...1.4.1)) ### Summary This release fixes a minor bug (possibly better described as a typing mistake) and makes some non-functional improvements. It also allows the user to override the default behaviour of failing on a non-supported operating system. ### Features * A new flag called `fail_on_non_suppoted_os` has been added to the `cassandra` class and can be set to **false** so that an attempt can be made to use this module on an operating system that is not in the Debian or Red Hat families. ### Bugfixes * Changed the default value for the `package_name` of the `cassandra::optutils` class from `'undef'` to *undef*. ### Improvements * Clarified the expectations of submitted contributions. * Unit test improvements. ##2015-09-10 - Release 1.4.0 ([diff](https://github.com/locp/cassandra/compare/1.3.7...1.4.0)) * Ensured that directories specified in the directory attributes are controlled with file resources. * Added the following attributes to the cassandra.yml file: * batchlog_replay_throttle_in_kb * cas_contention_timeout_in_ms * column_index_size_in_kb * commit_failure_policy * compaction_throughput_mb_per_sec * counter_cache_save_period * counter_write_request_timeout_in_ms * cross_node_timeout * dynamic_snitch_badness_threshold * dynamic_snitch_reset_interval_in_ms * dynamic_snitch_update_interval_in_ms * hinted_handoff_throttle_in_kb * index_summary_resize_interval_in_minutes * inter_dc_tcp_nodelay * max_hints_delivery_threads * max_hint_window_in_ms * permissions_validity_in_ms * range_request_timeout_in_ms * read_request_timeout_in_ms * request_scheduler * request_timeout_in_ms * row_cache_save_period * row_cache_size_in_mb * sstable_preemptive_open_interval_in_mb * tombstone_failure_threshold * tombstone_warn_threshold * trickle_fsync * trickle_fsync_interval_in_kb * truncate_request_timeout_in_ms * write_request_timeout_in_ms ##2015-09-08 - Release 1.3.7 ([diff](https://github.com/locp/cassandra/compare/1.3.6...1.3.7)) * Made the auto_bootstrap attribute available. ##2015-09-03 - Release 1.3.6 ([diff](https://github.com/locp/cassandra/compare/1.3.5...1.3.6)) * Fixed a bug, now allowing the user to set the enabled state of the Cassandra service. * More cleaning up of the README and more links in that file to allow faster navigation. ##2015-09-01 - Release 1.3.5 ([diff](https://github.com/locp/cassandra/compare/1.3.4...1.3.5)) * Fixed a bug, now allowing the user to set the running state of the Cassandra service. * More automated testing with spec tests. * A refactoring of the README. ##2015-08-28 - Release 1.3.4 ([diff](https://github.com/locp/cassandra/compare/1.3.3...1.3.4)) * Minor corrections to the README. * The addition of the storage_cassandra_seed_hosts attribute to cassandra::opscenter::cluster_name which is part of a bigger part of work but is urgently require by a client. ##2015-08-27 - Release 1.3.3 ([diff](https://github.com/locp/cassandra/compare/1.3.2...1.3.3)) * Corrected dependency version for puppetlabs-apt. ##2015-08-26 - Release 1.3.2 ([diff](https://github.com/locp/cassandra/compare/1.3.1...1.3.2)) * Fixed bug in cassandra::opscenter::cluster_name. * Fixed code in cassandra::firewall_ports::rule to avoid deprecation warnings concerning the use of puppetlabs-firewall => port. * Added more examples to the README ##2015-08-22 - Release 1.3.1 ([diff](https://github.com/locp/cassandra/compare/1.3.0...1.3.1)) This was mainly a non-functional change. The biggest thing to say is that Debian 7 is now supported. ##2015-08-19 - Release 1.3.0 ([diff](https://github.com/locp/cassandra/compare/1.2.0...1.3.0)) * Allow additional TCP ports to be specified for the host based firewall. * Fixed a problem where the client subnets were ignored by the firewall. * Added more automated testing. * Continued work on an ongoing improvement of the documentation. * Added the ability to set the DC and RACK in the snitch properties. ##2015-08-10 - Release 1.2.0 ([diff](https://github.com/locp/cassandra/compare/1.1.0...1.2.0)) * Added the installation of Java Native Access (JNA) to cassandra::java * For DataStax Enterprise, allow the remote storage of metric data with cassandra::opscenter::cluster_name. ##2015-08-03 - Release 1.1.0 ([diff](https://github.com/locp/cassandra/compare/1.0.1...1.1.0)) * Provided the cassandra::firewall_ports class. * All OpsCenter options are now configurable in opscenterd.conf. * ssl_storage_port is now configurable. ##2015-07-27 - Release 1.0.1 ([diff](https://github.com/locp/cassandra/compare/1.0.0...1.0.1)) * Provided a workaround for [CASSANDRA-9822](https://issues.apache.org/jira/browse/CASSANDRA-9822). ##2015-07-25 - Release 1.0.0 ([diff](https://github.com/locp/cassandra/compare/0.4.3...1.0.0)) * Changed the default installation from Cassandra 2.1 to 2.2. * Fixed a bug that arose when the cassandra config_path was set. * Created a workaround for [PUP-3829](https://tickets.puppetlabs.com/browse/PUP-3829). * Minor changes to the API (see the Upgrading section of the README). * Allow a basic installation of OpsCenter. ##2015-07-18 - Release 0.4.3 ([diff](https://github.com/locp/cassandra/compare/0.4.2...0.4.3)) * Module dependency metadata was too strict. ##2015-07-16 - Release 0.4.2 ([diff](https://github.com/locp/cassandra/compare/0.4.1...0.4.2)) * Some minor documentation changes. * Fixed a problem with the module metadata that caused Puppetfile issues. * Integrated with Coveralls (https://coveralls.io/github/locp/cassandra). * Removed the deprecated config and install classes. These were private so there is no change to the API. ##2015-07-14 - Release 0.4.1 ([diff](https://github.com/locp/cassandra/compare/0.4.0...0.4.1)) * Fixed a resource ordering problem in the cassandra::datastax class. * Tidied up the documentation a bit. * Some refactoring of the spec tests. ##2015-07-12 - Release 0.4.0 ([diff](https://github.com/locp/cassandra/compare/0.3.0...0.4.0)) ### Summary * Some major changes to the API on how Java, the optional Cassandra tools and the DataStax agent are installed. See the Upgrading section of the README file. * Allowed the setting of the *stomp_interface* for the DataStax agent. * Non-functionally, we have integrated with Travis CI (see https://travis-ci.org/locp/cassandra for details) and thanks to those guys for providing such a neat service. * More spec tests. ##2015-06-27 - Release 0.3.0 ([diff](https://github.com/locp/cassandra/compare/0.2.2...0.3.0)) ### Summary * Slight changes to the API. See the Upgrading section of the README file for full details. * Allow for the installation of the DataStax Agent. * Improved automated testing (and fixed some bugs along the way). * Confirmed Ubuntu 12.04 works OK with this module. * A Cassandra 1.X template has been provided. * Some smarter handling of the differences between Ubuntu/Debian and RedHat derivatives. ##2015-06-17 - Release 0.2.2 ([diff](https://github.com/locp/cassandra/compare/0.2.1...0.2.2)) ### Summary A non-functional change to change the following: * Split the single manifest into multiple files. * Implement automated testing. * Test on additional operating systems. ##2015-05-28 - Release 0.2.1 ([diff](https://github.com/locp/cassandra/compare/0.2.0...0.2.1)) ### Summary A non-functional change to fix puppet-lint problems identified by Puppet Forge. ##2015-05-28 - Release 0.2.0 ([diff](https://github.com/locp/cassandra/compare/0.1.0...0.2.0)) ### Summary Added more attributes and improved the module metadata. ##2015-05-26 - Release 0.1.0 ### Summary An initial release with **VERY** limited options. diff --git a/Gemfile b/Gemfile index 20f83c9..69e4aa1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,56 +1,55 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' def gem_env_ver(gemname) environment_var = gemname.upcase + '_GEM_VERSION' environment_var = environment_var.tr('-', '_') gemversion = ENV[environment_var] if gemversion gem gemname, gemversion, require: false else gem gemname, require: false end end gem_env_ver('addressable') gem_env_ver('json_pure') gem_env_ver('net-http-persistent') gem_env_ver('net-ssh') gem_env_ver('puppet') gem_env_ver('tins') group :test do gem 'coveralls', require: false gem 'facter', '>= 1.7.0' gem 'hiera', require: false gem 'metadata-json-lint', require: false gem 'puppet-blacksmith', require: false gem 'puppet-lint', require: false gem 'puppet-strings', require: false gem 'puppetlabs_spec_helper', require: false gem 'rake', require: false - gem 'rspec_junit_formatter', require: false gem 'rspec-puppet', '>= 2.3.2' gem 'rspec-puppet-utils', require: false - gem 'rubocop', '0.41.2' if RUBY_VERSION < '2.0.0' - gem 'rubocop' if RUBY_VERSION >= '2.0.0' - gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' + gem 'rspec_junit_formatter', require: false + gem 'rubocop' if RUBY_VERSION >= '2.0.0' + gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' gem 'travis', require: false gem 'travis-lint', require: false gem 'yard', require: false end group :acceptance do gem 'aws-sdk-core' - gem 'beaker-rspec' gem 'beaker-puppet_install_helper' + gem 'beaker-rspec' gem 'git', '1.3.0' gem 'httparty' gem 'pry' gem 'retries' end group :development do gem 'notes', '~> 0.1.2' end diff --git a/README.md b/README.md index 81606d3..9626893 100644 --- a/README.md +++ b/README.md @@ -1,565 +1,600 @@ # Cassandra [![Puppet Forge](http://img.shields.io/puppetforge/v/locp/cassandra.svg)](https://forge.puppetlabs.com/locp/cassandra) [![Github Tag](https://img.shields.io/github/tag/locp/cassandra.svg)](https://github.com/locp/cassandra) [![Build Status](https://travis-ci.org/locp/cassandra.png?branch=master)](https://travis-ci.org/locp/cassandra) [![Coverage Status](https://coveralls.io/repos/locp/cassandra/badge.svg?branch=master&service=github)](https://coveralls.io/github/locp/cassandra?branch=master) [![Join the chat at https://gitter.im/locp/cassandra](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/locp/cassandra?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![CircleCI](https://circleci.com/gh/locp/cassandra.svg?style=svg)](https://circleci.com/gh/locp/cassandra) [![Puppet Forge Downloads](http://img.shields.io/puppetforge/dt/locp/cassandra.svg)](https://forge.puppetlabs.com/locp/cassandra) [![Puppet Forge Endorsement](https://img.shields.io/puppetforge/e/locp/cassandra.svg)](https://forge.puppetlabs.com/locp/cassandra) ## Table of Contents 1. [Overview](#overview) 1. [Setup - The basics of getting started with Cassandra](#setup) * [What Cassandra affects](#what-cassandra-affects) * [Upgrading](#upgrading) * [Beginning with Cassandra](#beginning-with-cassandra) 1. [Usage - Configuration options and additional functionality](#usage) * [Setup a keyspace and users](#setup-a-keyspace-and-users) * [Create a Cluster in a Single Data Center](#create-a-cluster-in-a-single-data-center) * [Create a Cluster in Multiple Data Centers](#create-a-cluster-in-multiple-data-centers) * [DataStax Enterprise](#datastax-enterprise) 1. [Reference](#reference) 1. [Limitations - OS compatibility, etc.](#limitations) 1. [Development](#development) ## Overview A Puppet module to install and manage Cassandra, DataStax Agent & OpsCenter ## Setup ### What Cassandra affects #### What the Cassandra class affects * Installs the Cassandra package (default **cassandra22** on Red Hat and **cassandra** on Debian). * Configures settings in `${config_path}/cassandra.yaml`. * On CentOS 7 if the `init` service provider is used, then cassandra is added as a system service. * Optionally ensures that the Cassandra service is enabled and running. * On Debian systems: * Optionally replace ```/etc/init.d/cassandra``` with a workaround for [CASSANDRA-9822](https://issues.apache.org/jira/browse/CASSANDRA-9822). #### What the cassandra::datastax_agent class affects * Optionally installs the DataStax agent. * Optionally sets JAVA_HOME in **/etc/default/datastax-agent**. #### What the cassandra::datastax_repo class affects * Optionally configures a Yum repository to install the Cassandra packages from (on Red Hat). * Optionally configures an Apt repository to install the Cassandra packages from (on Debian). #### What the cassandra::firewall_ports class affects * Optionally configures the firewall for the Cassandra related network ports. #### What the cassandra::java class affects * Optionally installs a JRE/JDK package (e.g. java-1.7.0-openjdk) and the Java Native Access (JNA). #### What the cassandra::optutils class affects * Optionally installs the Cassandra support tools (e.g. cassandra22-tools). ### Upgrading We follow [SemVer Versioning](http://semver.org/) and an update of the major release (i.e. from 1.*Y*.*Z* to 2.*Y*.*Z*) will indicate a significant change to the API which will most probably require a change to your manifest. #### Changes in 2.0.0 This is a major change to the API and you will more than likely need to change your manifest to accomodate these changes. The `service_ensure` attribute of the cassandra class now defaults to *undef*, users who do want to manage service status in Puppet can still set it to true. If leaving the value at the default and setting `service_refresh` and `service_enable` to false will mean that the user and not Puppet running will control the running state of Cassandra. This currently works OK on the Red Hat family, but has issues on Debian due to [CASSANDRA-2356](https://issues.apache.org/jira/browse/CASSANDRA-2356) during an initial install or package upgrade. All the functionality relating to OpsCenter has been divested to the [locp/opscenter](https://forge.puppet.com/locp/opscenter) module on Puppet Forge. It should also be noted that the module no longer creates directories for the `data`, `commitlog`, `saved_caches` and for Cassandra 3 the `hints` directory. These resources will now need to be defined in your manifest/profile. For a list of features that have been deprecated in this release, please see https://github.com/locp/cassandra/wiki/Deprecations For details on migrating from the version 1.X.X attributes to the `settings` hash, see https://github.com/locp/cassandra/wiki/Version-1.X.Y-Template-Defaults-Shown-As-2.X.Y-Hash Please also see the notes for 2.0.0 in the [CHANGELOG](https://forge.puppet.com/locp/cassandra/changelog). #### Changes in 1.19.0 The hints_directory documentation will cause a change in the cassandra.yaml file regardless of the value you set it to. If you do not wish this to result in a refesh of the Cassandra service, please set service_refresh to false. #### Changes in 1.9.2 Now that Cassandra 3 is available from the DataStax repositories, there is a problem (especially on Debian) with the operating system package manager attempting to install Cassandra 3. This can be mitigated against using something similar to the code in this modules acceptance test. Please note that the default Cassandra package name has now been changed from 'dsc'. See the documentation for cassandra::package_name below for details. ```puppet if $::osfamily == 'RedHat' { $version = '2.2.4-1' } else { $version = '2.2.4' } class { 'cassandra': package_ensure => $version, } ``` #### Changes in 1.8.0 A somewhat embarrassing correction to the spelling of the cassandra::fail_on_non_suppoted_os to cassandra::fail_on_non_supported_os. #### Issues when Upgrading to 1.4.0 Unfortunately both releases 1.3.7 and 1.4.0 have subsequently been found to call a refresh service even when no changes had been made to the underlying configuration. In release 1.8.0 (somewhat belatedly) the service_refresh flag has been introduced to mitigate against similar problems. #### Issues When Upgrading to 1.3.7 * Please see the notes for 1.4.0. #### Changes in 1.0.0 * cassandra::cassandra_package_ensure has been renamed to cassandra::package_ensure. * cassandra::cassandra_package_name has been renamed to cassandra::package_name. #### Changes in 0.4.0 There is now a cassandra::datastax_agent class, therefore: * cassandra::datastax_agent_package_ensure has now been replaced with cassandra::datastax_agent::package_ensure. * cassandra::datastax_agent_service_enable has now been replaced with cassandra::datastax_agent::service_enable. * cassandra::datastax_agent_service_ensure has now been replaced with cassandra::datastax_agent::service_ensure. * cassandra::datastax_agent_package_name has now been replaced with cassandra::datastax_agent::package_name. * cassandra::datastax_agent_service_name has now been replaced with cassandra::datastax_agent::service_name. Likewise now there is a new class for handling the installation of Java: * cassandra::java_package_ensure has now been replaced with cassandra::java::ensure. * cassandra::java_package_name has now been replaced with cassandra::java::package_name. Also there is now a class for installing the optional utilities: * cassandra::cassandra_opt_package_ensure has now been replaced with cassandra::optutils:ensure. * cassandra::cassandra_opt_package_name has now been replaced with cassandra::optutils:package_name. #### Changes in 0.3.0 * cassandra_opt_package_ensure changed from 'present' to undef. * The manage_service option has been replaced with service_enable and service_ensure. ### Beginning with Cassandra Create a Cassandra 2.X cluster called MyCassandraCluster which uses the GossipingPropertyFileSnitch and password authentication. In this very basic example the node itself becomes a seed for the cluster and the credentials will default to a user called cassandra with a password called of cassandra.. ```puppet # Cassandra pre-requisites include cassandra::datastax_repo include cassandra::java class { 'cassandra': settings => { '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, }, require => Class['cassandra::datastax_repo', 'cassandra::java'], } ``` For this code to run with version 3.X of Cassandra, the `hints_directory` will also need to be specified: ```puppet ... class { 'cassandra': settings => { ... 'hints_directory' => '/var/lib/cassandra/hints', ... }, require => Class['cassandra::datastax_repo', 'cassandra::java'], } ``` ## Usage ### Setup a keyspace and users We assume that authentication has been enabled for the cassandra cluster and we are connecting with the default user name and password ('cassandra/cassandra'). In this example, we create a keyspace (mykeyspace) with a table called 'users' and an index called 'users_lname_idx'. We also add three users (to Cassandra, not the mykeyspace.users table) called spillman, akers and boone while ensuring that a user called lucan is absent. ```puppet class { 'cassandra': ... } class { 'cassandra::schema': cqlsh_password => 'cassandra', cqlsh_user => 'cassandra', cqlsh_host => $::ipaddress, indexes => { 'users_lname_idx' => { table => 'users', keys => 'lname', keyspace => 'mykeyspace', }, }, keyspaces => { 'mykeyspace' => { durable_writes => false, replication_map => { keyspace_class => 'SimpleStrategy', replication_factor => 1, }, } }, + permissions => { + 'Grant select permissions to spillman to all keyspaces' => { + permission_name => 'SELECT', + user_name => 'spillman', + }, + 'Grant modify to to keyspace mykeyspace to akers' => { + keyspace_name => 'mykeyspace', + permission_name => 'MODIFY', + user_name => 'akers', + }, + 'Grant alter permissions to mykeyspace to boone' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + user_name => 'boone', + }, + 'Grant ALL permissions to mykeyspace.users to gbennet' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + table_name => 'users', + user_name => 'gbennet', + }, + }, tables => { 'users' => { columns => { user_id => 'int', fname => 'text', lname => 'text', 'PRIMARY KEY' => '(user_id)', }, keyspace => 'mykeyspace', }, }, users => { 'spillman' => { password => 'Niner27', }, 'akers' => { password => 'Niner2', superuser => true, }, 'boone' => { password => 'Niner75', }, + 'gbennet' => { + 'password' => 'foobar', + }, 'lucan' => { 'ensure' => absent }, }, } ``` ### Create a Cluster in a Single Data Center In the DataStax documentation _Initializing a multiple node cluster (single data center)_ there is a basic example of a six node cluster with two seeds to be created in a single data center spanning two racks. The nodes in the cluster are: **Node Name** | **IP Address** | ---------------|----------------| node0 (seed 1) | 110.82.155.0 | node1 | 110.82.155.1 | node2 | 110.82.155.2 | node3 (seed 2) | 110.82.156.3 | node4 | 110.82.156.4 | node5 | 110.82.156.5 | Each node is configured to use the GossipingPropertyFileSnitch and 256 virtual nodes (vnodes). The name of the cluster is _MyCassandraCluster_. Also, while building the initial cluster, we are setting the auto_bootstrap to false. In this initial example, we are going to expand the example by: * Ensuring that the software is installed via the DataStax Community repository by including `cassandra::datastax_repo`. This needs to be executed before the Cassandra package is installed. * That a suitable Java Runtime environment (JRE) is installed with Java Native Access (JNA) by including `cassandra::java`. This need to be executed before the Cassandra service is started. ```puppet node /^node\d+$/ { class { 'cassandra::datastax_repo': before => Class['cassandra'] } class { 'cassandra::java': before => Class['cassandra'] } class { 'cassandra': settings => { 'authenticator' => 'AllowAllAuthenticator', 'auto_bootstrap' => false, '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', 'hints_directory' => '/var/lib/cassandra/hints', 'listen_interface' => 'eth1', 'num_tokens' => 256, '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' => '110.82.155.0,110.82.156.3', }, ], }, ], 'start_native_transport' => true, }, } } ``` The default value for the num_tokens is already 256, but it is included in the example for clarity. Do not forget to either set auto_bootstrap to true or not set the attribute at all after initializing the cluster. ### Create a Cluster in Multiple Data Centers To continue with the examples provided by DataStax, we look at the example for a cluster across multiple data centers . **Node Name** | **IP Address** | **Data Center** | **Rack** | ---------------|----------------|-----------------|----------| node0 (seed 1) | 10.168.66.41 | DC1 | RAC1 | node1 | 10.176.43.66 | DC1 | RAC1 | node2 | 10.168.247.41 | DC1 | RAC1 | node3 (seed 2) | 10.176.170.59 | DC2 | RAC1 | node4 | 10.169.61.170 | DC2 | RAC1 | node5 | 10.169.30.138 | DC2 | RAC1 | For the sake of simplicity, we will confine this example to the nodes: ```puppet node /^node[012]$/ { class { 'cassandra': dc => 'DC1', settings => { 'authenticator' => 'AllowAllAuthenticator', 'auto_bootstrap' => false, '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', 'hints_directory' => '/var/lib/cassandra/hints', 'listen_interface' => 'eth1', 'num_tokens' => 256, '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' => '110.82.155.0,110.82.156.3', }, ], }, ], 'start_native_transport' => true, }, } } node /^node[345]$/ { class { 'cassandra': dc => 'DC2', settings => { 'authenticator' => 'AllowAllAuthenticator', 'auto_bootstrap' => false, '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', 'hints_directory' => '/var/lib/cassandra/hints', 'listen_interface' => 'eth1', 'num_tokens' => 256, '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' => '110.82.155.0,110.82.156.3', }, ], }, ], 'start_native_transport' => true, }, } } ``` We don't need to specify the rack name (with the rack attribute) as RAC1 is the default value. Again, do not forget to either set auto_bootstrap to true or not set the attribute at all after initializing the cluster. ## Reference ### Public Classes * [cassandra](http://locp.github.io/cassandra/puppet_classes/cassandra.html) * [cassandra::datastax_agent] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Adatastax_agent.html) * [cassandra::datastax_repo] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Adatastax_repo.html) * [cassandra::firewall_ports] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Afirewall_ports.html) * [cassandra::java] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Ajava.html) * [cassandra::optutils] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Aoptutils.html) * [cassandra::schema] (http://locp.github.io/cassandra/puppet_classes/cassandra_3A_3Aschema.html) ### Public Defined Types * [cassandra::file] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Afile.html) * [cassandra::schema::cql_type] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Acql_type.html) * [cassandra::schema::index] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Aindex.html) * [cassandra::schema::keyspace] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Akeyspace.html) +* [cassandra::schema::permission] + (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Apermission.html) * [cassandra::schema::table] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Atable.html) * [cassandra::schema::user] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aschema_3A_3Auser.html) ### Private Defined Types * [cassandra::private::firewall_ports::rule] (http://locp.github.io/cassandra/puppet_defined_types/cassandra_3A_3Aprivate_3A_3Afirewall_ports_3A_3Arule.html) ### Facts +* [cassandracmsheapnewsize] + (http://locp.github.io/cassandra/top-level-namespace.html#cassandracmsheapnewsize-instance_method) +* [cassandracmsmaxheapsize] + (http://locp.github.io/cassandra/top-level-namespace.html#cassandracmsmaxheapsize-instance_method) +* [cassandraheapnewsize] + (http://locp.github.io/cassandra/top-level-namespace.html#cassandraheapnewsize-instance_method) * [cassandramajorversion] (http://locp.github.io/cassandra/top-level-namespace.html#cassandramajorversion-instance_method) +* [cassandramaxheapsize] + (http://locp.github.io/cassandra/top-level-namespace.html#cassandramaxheapsize-instance_method) * [cassandraminorversion] (http://locp.github.io/cassandra/top-level-namespace.html#cassandraminorversion-instance_method) * [cassandrapatchversion] (http://locp.github.io/cassandra/top-level-namespace.html#cassandrapatchversion-instance_method) * [cassandrarelease] (http://locp.github.io/cassandra/top-level-namespace.html#cassandrarelease-instance_method) ## Limitations When using a Ruby version before 1.9.0, the contents of the Cassandra configuration file may change order of elements due to a problem with to_yaml in earlier versions of Ruby. When creating key spaces, indexes, cql_types and users the settings will only be used to create a new resource if it does not currently exist. If a change is made to the Puppet manifest but the resource already exits, this change will not be reflected. ## Development Contributions will be gratefully accepted. Please go to the project page, fork the project, make your changes locally and then raise a pull request. Details on how to do this are available at https://guides.github.com/activities/contributing-to-open-source. Please also see the [CONTRIBUTING.md](https://github.com/locp/cassandra/blob/master/CONTRIBUTING.md) page for project specific requirements. ### Additional Contributers For a list of contributers see [CONTRIBUTING.md](https://github.com/locp/cassandra/blob/master/CONTRIBUTING.md) and https://github.com/locp/cassandra/graphs/contributors diff --git a/Rakefile b/Rakefile index 3884284..81e2732 100644 --- a/Rakefile +++ b/Rakefile @@ -1,14 +1,14 @@ require 'metadata-json-lint/rake_task' require 'puppet_blacksmith/rake_tasks' require 'puppet-strings/tasks' require 'puppetlabs_spec_helper/rake_tasks' -require 'rubocop/rake_task' +require 'rubocop/rake_task' if RUBY_VERSION >= '2.0.0' require 'rubygems' # TravisCI does not require the extra module tasks. require_relative 'rake/rake_tasks' unless ENV['TRAVIS'] == 'true' # Use a custom pattern with git tag. %s is replaced with the version number. Blacksmith::RakeTask.new do |t| t.tag_pattern = '%s' end diff --git a/examples/getting_started.pp b/examples/getting_started.pp index eb601b3..31d61d8 100644 --- a/examples/getting_started.pp +++ b/examples/getting_started.pp @@ -1,165 +1,191 @@ ############################################################################# # This is for placing in the getting started section of the README file. ############################################################################# # Install Cassandra 2.2.5 onto a system and create a basic keyspace, table # and index. The node itself becomes a seed for the cluster. # # Tested on CentOS 7 ############################################################################# # Cassandra pre-requisites include cassandra::datastax_repo include cassandra::java # Create a cluster called MyCassandraCluster which uses the # GossipingPropertyFileSnitch. In this very basic example # the node itself becomes a seed for the cluster. class { 'cassandra': commitlog_directory => '/var/lib/cassandra/commitlog', data_file_directories => ['/var/lib/cassandra/data'], hints_directory => '/var/lib/cassandra/hints', package_name => 'cassandra30', saved_caches_directory => '/var/lib/cassandra/saved_caches', settings => { 'authenticator' => 'PasswordAuthenticator', + 'authorizer' => 'CassandraAuthorizer', 'cluster_name' => 'MyCassandraCluster', 'commitlog_sync' => 'periodic', 'commitlog_sync_period_in_ms' => 10000, 'endpoint_snitch' => 'GossipingPropertyFileSnitch', 'listen_address' => $::ipaddress, 'partitioner' => 'org.apache.cassandra.dht.Murmur3Partitioner', 'seed_provider' => [ { 'class_name' => 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters' => [ { 'seeds' => $::ipaddress, }, ], }, ], 'start_native_transport' => true, }, service_ensure => running, require => Class['cassandra::datastax_repo', 'cassandra::java'], } class { 'cassandra::datastax_agent': settings => { 'agent_alias' => { 'setting' => 'agent_alias', 'value' => 'foobar', }, 'stomp_interface' => { 'setting' => 'stomp_interface', 'value' => 'localhost', }, 'async_pool_size' => { 'ensure' => absent, }, }, require => Class['cassandra'], } class { 'cassandra::optutils': package_name => 'cassandra30-tools', require => Class['cassandra'], } class { 'cassandra::schema': cqlsh_password => 'cassandra', cqlsh_user => 'cassandra', cqlsh_host => $::ipaddress, indexes => { 'users_lname_idx' => { table => 'users', keys => 'lname', keyspace => 'mykeyspace', }, }, keyspaces => { 'mykeyspace' => { durable_writes => false, replication_map => { keyspace_class => 'SimpleStrategy', replication_factor => 1, }, }, }, + permissions => { + 'Grant select permissions to spillman to all keyspaces' => { + permission_name => 'SELECT', + user_name => 'spillman', + }, + 'Grant modify to to keyspace mykeyspace to akers' => { + keyspace_name => 'mykeyspace', + permission_name => 'MODIFY', + user_name => 'akers', + }, + 'Grant alter permissions to mykeyspace to boone' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + user_name => 'boone', + }, + 'Grant ALL permissions to mykeyspace.users to gbennet' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + table_name => 'users', + user_name => 'gbennet', + }, + }, tables => { 'users' => { columns => { user_id => 'int', fname => 'text', lname => 'text', 'PRIMARY KEY' => '(user_id)', }, keyspace => 'mykeyspace', }, }, users => { 'spillman' => { password => 'Niner27', }, 'akers' => { password => 'Niner2', superuser => true, }, 'boone' => { password => 'Niner75', }, + 'gbennet' => { + 'password' => 'foobar', + }, 'lucan' => { 'ensure' => absent, }, }, } 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', require => Package['cassandra'], } cassandra::file { 'Set java.io.tmpdir': file => 'jvm.options', file_lines => { 'java.io.tmpdir' => { line => "-Djava.io.tmpdir=${tmpdir}", }, }, require => File[$tmpdir], } diff --git a/lib/facter/cassandra.rb b/lib/facter/cassandra.rb deleted file mode 100644 index 0a673be..0000000 --- a/lib/facter/cassandra.rb +++ /dev/null @@ -1,50 +0,0 @@ -# Extract the release string from the running Cassandra instance. -# -# @resolution -# Runs the command "nodetool version". -# @caveats -# The Cassandra service needs to be running, otherwise the fact will be -# undefined. -# @return [string] The version string (e.g. 3.0.1). -Facter.add('cassandrarelease') do - setcode do - version = Facter::Util::Resolution.exec('nodetool version') - version.match(/\d+\.\d+\.\d+/).to_s if version && version != '' - end -end - -# Extract the major version from the cassandrarelease fact. -# @caveats -# Requires that the cassandrarelease has been successfully retrieved. -# @return [integer] The major version of the Cassandra instance. -# @see cassandrarelease -Facter.add('cassandramajorversion') do - setcode do - release = Facter.value(:cassandrarelease) - release.split('.')[0].to_i if release - end -end - -# Extract the minor version from the cassandrarelease fact. -# @caveats -# Requires that the cassandrarelease has been successfully retrieved. -# @return [integer] The minor version of the Cassandra instance. -# @see cassandrarelease -Facter.add('cassandraminorversion') do - setcode do - release = Facter.value(:cassandrarelease) - release.split('.')[1].to_i if release - end -end - -# Extract the patch version from the cassandrarelease fact. -# @caveats -# Requires that the cassandrarelease has been successfully retrieved. -# @return [integer] The patch version of the Cassandra instance. -# @see cassandrarelease -Facter.add('cassandrapatchversion') do - setcode do - release = Facter.value(:cassandrarelease) - release.split('.')[2].to_i if release - end -end diff --git a/lib/facter/cassandracmsheapnewsize.rb b/lib/facter/cassandracmsheapnewsize.rb new file mode 100644 index 0000000..5a8b210 --- /dev/null +++ b/lib/facter/cassandracmsheapnewsize.rb @@ -0,0 +1,18 @@ +# Returns a value (MB) that might be suitable to set the HEAP_NEWSIZE when using +# the Concurrent Mark Sweep (CMS) Collector. +# See [Tuning Java resources] +# (https://docs.datastax.com/en/cassandra/2.1/cassandra/operations/ops_tune_jvm_c.html) +# for more details. +# +# @return [integer] min(100 times the number of cores, 1/4 CMS MAX_HEAP_SIZE) +# @see cassandracmsmaxheapsize +# @see cassandramaxheapsize +# @see cassandracmsheapnewsize +Facter.add('cassandracmsheapnewsize') do + setcode do + maxheapsize = Facter.value(:cassandracmsmaxheapsize).to_f + processorcount = Facter.value(:processorcount).to_f + heapnewsize = [100 * processorcount, maxheapsize * 0.25].min + heapnewsize.round + end +end diff --git a/lib/facter/cassandracmsmaxheapsize.rb b/lib/facter/cassandracmsmaxheapsize.rb new file mode 100644 index 0000000..9c90482 --- /dev/null +++ b/lib/facter/cassandracmsmaxheapsize.rb @@ -0,0 +1,19 @@ +# Returns a value (MB) that might be suitable to set the MAX_HEAP_SIZE when using +# the Concurrent Mark Sweep (CMS) Collector. +# See [Tuning Java resources] +# (https://docs.datastax.com/en/cassandra/2.1/cassandra/operations/ops_tune_jvm_c.html) +# for more details. +# +# @return [integer] max(min(1/2 ram, 1024), min(1/4 ram, 14336) +# @see cassandracmsheapnewsize +# @see cassandraheapnewsize +# @see cassandramaxheapsize +Facter.add('cassandracmsmaxheapsize') do + setcode do + memorysize_mb = Facter.value(:memorysize_mb).to_f + calc1 = [memorysize_mb * 0.5, 1024].min + calc2 = [memorysize_mb * 0.25, 14_336].min + maxheapsize = [calc1, calc2].max + maxheapsize.round + end +end diff --git a/lib/facter/cassandraheapnewsize.rb b/lib/facter/cassandraheapnewsize.rb new file mode 100644 index 0000000..d98bfab --- /dev/null +++ b/lib/facter/cassandraheapnewsize.rb @@ -0,0 +1,17 @@ +# Returns a value (MB) that might be suitable to set the HEAP_NEWSIZE. +# See [Tuning Java resources] +# (https://docs.datastax.com/en/cassandra/2.1/cassandra/operations/ops_tune_jvm_c.html) +# for more details. +# +# @return [integer] min(100 times the number of cores, 1/4 MAX_HEAP_SIZE) +# @see cassandracmsheapnewsize +# @see cassandracmsmaxheapsize +# @see cassandramaxheapsize +Facter.add('cassandraheapnewsize') do + setcode do + maxheapsize = Facter.value(:cassandramaxheapsize).to_f + processorcount = Facter.value(:processorcount).to_f + heapnewsize = [100 * processorcount, maxheapsize * 0.25].min + heapnewsize.round + end +end diff --git a/lib/facter/cassandramajorversion.rb b/lib/facter/cassandramajorversion.rb new file mode 100644 index 0000000..a4e7962 --- /dev/null +++ b/lib/facter/cassandramajorversion.rb @@ -0,0 +1,11 @@ +# Extract the major version from the cassandrarelease fact. +# @caveats +# Requires that the cassandrarelease has been successfully retrieved. +# @return [integer] The major version of the Cassandra instance. +# @see cassandrarelease +Facter.add('cassandramajorversion') do + setcode do + release = Facter.value(:cassandrarelease) + release.split('.')[0].to_i if release + end +end diff --git a/lib/facter/cassandramaxheapsize.rb b/lib/facter/cassandramaxheapsize.rb new file mode 100644 index 0000000..1126adb --- /dev/null +++ b/lib/facter/cassandramaxheapsize.rb @@ -0,0 +1,18 @@ +# Returns a value (MB) that might be suitable to set the MAX_HEAP_SIZE. +# See [Tuning Java resources] +# (https://docs.datastax.com/en/cassandra/2.1/cassandra/operations/ops_tune_jvm_c.html) +# for more details. +# +# @return [integer] max(min(1/2 ram, 1024), min(1/4 ram, 8192) +# @see cassandracmsheapnewsize +# @see cassandracmsmaxheapsize +# @see cassandraheapnewsize +Facter.add('cassandramaxheapsize') do + setcode do + memorysize_mb = Facter.value(:memorysize_mb).to_f + calc1 = [memorysize_mb * 0.5, 1024].min + calc2 = [memorysize_mb * 0.25, 8192].min + maxheapsize = [calc1, calc2].max + maxheapsize.round + end +end diff --git a/lib/facter/cassandraminorversion.rb b/lib/facter/cassandraminorversion.rb new file mode 100644 index 0000000..35f2418 --- /dev/null +++ b/lib/facter/cassandraminorversion.rb @@ -0,0 +1,11 @@ +# Extract the minor version from the cassandrarelease fact. +# @caveats +# Requires that the cassandrarelease has been successfully retrieved. +# @return [integer] The minor version of the Cassandra instance. +# @see cassandrarelease +Facter.add('cassandraminorversion') do + setcode do + release = Facter.value(:cassandrarelease) + release.split('.')[1].to_i if release + end +end diff --git a/lib/facter/cassandrapatchversion.rb b/lib/facter/cassandrapatchversion.rb new file mode 100644 index 0000000..6339a94 --- /dev/null +++ b/lib/facter/cassandrapatchversion.rb @@ -0,0 +1,11 @@ +# Extract the patch version from the cassandrarelease fact. +# @caveats +# Requires that the cassandrarelease has been successfully retrieved. +# @return [integer] The patch version of the Cassandra instance. +# @see cassandrarelease +Facter.add('cassandrapatchversion') do + setcode do + release = Facter.value(:cassandrarelease) + release.split('.')[2].to_i if release + end +end diff --git a/lib/facter/cassandrarelease.rb b/lib/facter/cassandrarelease.rb new file mode 100644 index 0000000..78ba9f9 --- /dev/null +++ b/lib/facter/cassandrarelease.rb @@ -0,0 +1,14 @@ +# Extract the release string from the running Cassandra instance. +# +# @resolution +# Runs the command "nodetool version". +# @caveats +# The Cassandra service needs to be running, otherwise the fact will be +# undefined. +# @return [string] The version string (e.g. 3.0.1). +Facter.add('cassandrarelease') do + setcode do + version = Facter::Util::Resolution.exec('nodetool version') + version.match(/\d+\.\d+\.\d+/).to_s if version && version != '' + end +end diff --git a/manifests/schema.pp b/manifests/schema.pp index 0e2673a..da37de0 100644 --- a/manifests/schema.pp +++ b/manifests/schema.pp @@ -1,117 +1,128 @@ # 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 = {}, ) inherits cassandra::params { require '::cassandra' if $cqlsh_client_config != undef { file { $cqlsh_client_config : ensure => file, group => $::gid, mode => '0600', owner => $::id, 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 = "${cqlsh_opts} -e 'DESC KEYSPACES' ${cqlsh_conn}" 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) } # manage cql_types if present if $cql_types { create_resources('cassandra::schema::cql_type', $cql_types) } # manage tables if present if $tables { create_resources('cassandra::schema::table', $tables) } # manage indexes if present if $indexes { create_resources('cassandra::schema::index', $indexes) } # manage users if present if $users { create_resources('cassandra::schema::user', $users) } + # manage permissions if present + if $permissions { + create_resources('cassandra::schema::permission', $permissions) + } + # 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/permission.pp b/manifests/schema/permission.pp new file mode 100644 index 0000000..1dfbea3 --- /dev/null +++ b/manifests/schema/permission.pp @@ -0,0 +1,127 @@ +# 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, + ){ + include 'cassandra::schema' + + 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 = "${::cassandra::schema::cqlsh_opts} -e \"${read_script}\" ${::cassandra::schema::cqlsh_conn} | grep '${pattern}'" + + 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, + } + + cassandra::schema::permission { "${title} - AUTHORIZE": + ensure => $ensure, + user_name => $user_name, + keyspace_name => $keyspace_name, + permission_name => 'AUTHORIZE', + table_name => $table_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, + } + } + + cassandra::schema::permission { "${title} - DROP": + ensure => $ensure, + user_name => $user_name, + keyspace_name => $keyspace_name, + permission_name => 'DROP', + table_name => $table_name, + } + + cassandra::schema::permission { "${title} - MODIFY": + ensure => $ensure, + user_name => $user_name, + keyspace_name => $keyspace_name, + permission_name => 'MODIFY', + table_name => $table_name, + } + + cassandra::schema::permission { "${title} - SELECT": + ensure => $ensure, + user_name => $user_name, + keyspace_name => $keyspace_name, + permission_name => 'SELECT', + table_name => $table_name, + } + } elsif $ensure == present { + $create_script = "GRANT ${permission_name} ON ${resource} TO ${user_name}" + $create_command = "${::cassandra::schema::cqlsh_opts} -e \"${create_script}\" ${::cassandra::schema::cqlsh_conn +}" + + 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 = "${::cassandra::schema::cqlsh_opts} -e \"${delete_script}\" ${::cassandra::schema::cqlsh_conn}" + + 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/metadata.json b/metadata.json index 7568075..b051a56 100644 --- a/metadata.json +++ b/metadata.json @@ -1,91 +1,91 @@ { "name": "locp-cassandra", - "version": "2.1.2", + "version": "2.2.0", "author": "locp", "summary": "Installs Cassandra, DataStax Agent & OpsCenter on RHEL/Ubuntu/Debian.", "license": "Apache-2.0", "source": "https://github.com/locp/cassandra", "project_page": "https://github.com/locp/cassandra", "issues_url": "https://github.com/locp/cassandra/issues", "tags": [ "cassandra", "cluster", "database", "datastax", "datastax-agent", "nosql" ], "requirements": [ { "name": "pe", "version_requirement": ">= 3.7.0 < 2015.4.0" }, { "name": "puppet", "version_requirement": ">= 3.0.0 < 5.0.0" } ], "dependencies": [ { "name": "puppetlabs-apt", "version_requirement": ">= 2.0.0 < 3.0.0" }, { "name": "puppetlabs-firewall", "version_requirement": ">= 1.0.0 < 2.0.0" }, { "name": "puppetlabs-inifile", "version_requirement": ">= 1.5.0 < 2.0.0" }, { "name": "puppetlabs-stdlib", "version_requirement": ">= 3.0.0 < 5.0.0" } ], "operatingsystem_support": [ { "operatingsystem": "CentOS", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "OracleLinux", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "RedHat", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "7", "8" ] }, { "operatingsystem": "Scientific", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "12.04", "14.04", "16.04" ] } ] } diff --git a/spec/acceptance/bootstrap_spec.rb b/spec/acceptance/bootstrap_spec.rb index 0ba8308..47be7d9 100644 --- a/spec/acceptance/bootstrap_spec.rb +++ b/spec/acceptance/bootstrap_spec.rb @@ -1,67 +1,71 @@ require 'spec_helper_acceptance' describe 'Bootstrap' do whoami_pp = <<-EOS notify { "operatingsystem: ${::operatingsystem}": } -> - notify { "operatingsystemmajrelease: ${::operatingsystemmajrelease}": } + notify { "operatingsystemmajrelease: ${::operatingsystemmajrelease}": } -> + notify { "cassandramaxheapsize: ${::cassandramaxheapsize}": } -> + notify { "cassandracmsmaxheapsize: ${::cassandracmsmaxheapsize}": } -> + notify { "cassandraheapnewsize: ${::cassandraheapnewsize}": } -> + notify { "cassandracmsheapnewsize: ${::cassandracmsheapnewsize}": } EOS describe '########### Identify the node.' do it 'should work with no errors' do apply_manifest(whoami_pp, catch_failures: true) end end bootstrap_pp = <<-EOS case downcase($::operatingsystem) { 'centos': { if $::operatingsystemmajrelease == 6 { package {'yum-utils': } -> package {'centos-release-scl': } -> exec { '/usr/bin/yum-config-manager --enable rhel-server-rhscl-7-rpms': } -> package {'ruby200': } -> exec { '/bin/cp /opt/rh/ruby200/enable /etc/profile.d/ruby.sh': } -> exec { '/bin/rm /usr/bin/ruby /usr/bin/gem': } -> exec { '/usr/sbin/alternatives --install /usr/bin/ruby ruby /opt/rh/ruby200/root/usr/bin/ruby 1000': } -> exec { '/usr/sbin/alternatives --install /usr/bin/gem gem /opt/rh/ruby200/root/usr/bin/gem 1000': } } } 'ubuntu': { if $::operatingsystemmajrelease == 12.04 { package {'python-software-properties':} -> exec {'/usr/bin/apt-add-repository ppa:brightbox/ruby-ng':} -> exec {'/usr/bin/apt-get update': } -> package {'ruby2.0': } -> exec { '/bin/rm /usr/bin/ruby': } -> exec { '/usr/sbin/update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby2.0 1000': } } elsif $::operatingsystemmajrelease == 16.04 { package { 'locales-all': } -> package { 'net-tools': } -> package { 'sudo': } -> package { 'ufw': } -> package { 'wget': } -> package { 'ntp': } -> package { 'python-pip': } -> package { 'python-minimal': } -> exec { '/bin/rm -f /usr/sbin/policy-rc.d': } -> exec { '/usr/bin/wget http://launchpadlibrarian.net/109052632/python-support_1.0.15_all.deb': cwd => '/var/tmp', creates => '/var/tmp/python-support_1.0.15_all.deb', } ~> exec { '/usr/bin/dpkg -i /var/tmp/python-support_1.0.15_all.deb': } -> package { 'cassandra-driver': provider => 'pip', } } } } EOS describe '########### Node specific manifest.' do it 'should work with no errors' do apply_manifest(bootstrap_pp, catch_failures: true) shell('[ -d /opt/rh/ruby200 ] && /usr/bin/gem install puppet -v 3.8.7 --no-rdoc --no-ri; true') end end end diff --git a/spec/acceptance/cassandra2_spec.rb b/spec/acceptance/cassandra2_spec.rb index 0005b72..17e0fb5 100644 --- a/spec/acceptance/cassandra2_spec.rb +++ b/spec/acceptance/cassandra2_spec.rb @@ -1,387 +1,475 @@ require 'spec_helper_acceptance' describe 'cassandra2', unless: CASSANDRA2_UNSUPPORTED_PLATFORMS.include?(fact('lsbdistrelease')) do cassandra_install_pp = <<-EOS include cassandra::datastax_repo include cassandra::java $run_schema_tests = hiera('cassandra::run_schema_tests', true) $version = '2.2.8' if $::osfamily == 'RedHat' { $package_ensure = "${version}-1" $cassandra_optutils_package = 'cassandra22-tools' $cassandra_package = 'cassandra22' } else { $package_ensure = $version $cassandra_optutils_package = 'cassandra-tools' $cassandra_package = 'cassandra' exec { '/bin/chown root:root /etc/apt/sources.list.d/datastax.list': unless => '/usr/bin/test -O /etc/apt/sources.list.d/datastax.list', require => Class['cassandra::datastax_agent'] } } $settings = { 'authenticator' => 'PasswordAuthenticator', + 'authorizer' => 'CassandraAuthorizer', '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, } if versioncmp($::rubyversion, '1.9.0') < 0 { $service_refresh = false } else { $service_refresh = true } class { 'cassandra': package_ensure => $package_ensure, package_name => $cassandra_package, service_refresh => $service_refresh, settings => $settings, require => Class['cassandra::datastax_repo', 'cassandra::java'] } class { 'cassandra::optutils': package_ensure => $package_ensure, package_name => $cassandra_optutils_package, require => Class['cassandra'] } class { 'cassandra::datastax_agent': require => Class['cassandra'] } # This really sucks but Docker, CentOS 6 and iptables don't play nicely # together. Therefore we can't test the firewall on this platform :-( if $::operatingsystem != CentOS and $::operatingsystemmajrelease != 6 { include '::cassandra::firewall_ports' } EOS describe '########### Cassandra installation.' do it 'should work with no errors' do apply_manifest(cassandra_install_pp, catch_failures: true) end it 'check code is idempotent' do expect(apply_manifest(cassandra_install_pp, catch_failures: true).exit_code).to be_zero end end schema_testing_create_pp = <<-EOS #{cassandra_install_pp} if $run_schema_tests { $cql_types = { 'fullname' => { 'keyspace' => 'mykeyspace', 'fields' => { 'fname' => 'text', 'lname' => 'text', }, }, } $keyspaces = { 'mykeyspace' => { ensure => present, replication_map => { keyspace_class => 'SimpleStrategy', replication_factor => 1, }, durable_writes => false, }, } class { 'cassandra::schema': cql_types => $cql_types, cqlsh_host => $::ipaddress, cqlsh_password => 'cassandra', cqlsh_user => 'cassandra', indexes => { 'users_lname_idx' => { keyspace => 'mykeyspace', table => 'users', keys => 'lname', }, }, keyspaces => $keyspaces, tables => { 'users' => { 'keyspace' => 'mykeyspace', 'columns' => { 'userid' => 'int', 'fname' => 'text', 'lname' => 'text', 'PRIMARY KEY' => '(userid)', }, }, }, - users => { - 'spillman' => { - password => 'Niner27', + permissions => { + 'Grant select permissions to spillman to all keyspaces' => { + permission_name => 'SELECT', + user_name => 'spillman', + }, + 'Grant modify to to keyspace mykeyspace to akers' => { + keyspace_name => 'mykeyspace', + permission_name => 'MODIFY', + user_name => 'akers', + }, + 'Grant alter permissions to mykeyspace to boone' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + user_name => 'boone', + }, + 'Grant ALL permissions to mykeyspace.users to gbennet' => { + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + table_name => 'users', + user_name => 'gbennet', }, + }, + users => { 'akers' => { password => 'Niner2', superuser => true, }, 'boone' => { password => 'Niner75', }, + 'gbennet' => { + password => 'Strewth', + }, + 'spillman' => { + password => 'Niner27', + }, }, } } EOS describe '########### Schema create.' do it 'should work with no errors' do apply_manifest(schema_testing_create_pp, catch_failures: true) end it 'check code is idempotent' do expect(apply_manifest(schema_testing_create_pp, catch_failures: true).exit_code).to be_zero end end - schema_testing_drop_type_pp = <<-EOS + schema_drop_type_pp = <<-EOS #{cassandra_install_pp} $cql_types = { 'fullname' => { 'keyspace' => 'mykeyspace', 'ensure' => 'absent' } } if $run_schema_tests { class { 'cassandra::schema': cql_types => $cql_types, cqlsh_host => $::ipaddress, cqlsh_user => 'akers', cqlsh_password => 'Niner2', } } EOS describe '########### Schema drop type.' do it 'should work with no errors' do - apply_manifest(schema_testing_drop_type_pp, catch_failures: true) + apply_manifest(schema_drop_type_pp, catch_failures: true) + end + + it 'check code is idempotent' do + expect(apply_manifest(schema_drop_type_pp, catch_failures: true).exit_code).to be_zero + end + end + + permissions_revoke_pp = <<-EOS + #{cassandra_install_pp} + + if $run_schema_tests { + class { 'cassandra::schema': + cqlsh_password => 'Niner2', + cqlsh_host => $::ipaddress, + cqlsh_user => 'akers', + cqlsh_client_config => '/root/.puppetcqlshrc', + permissions => { + 'Revoke select permissions to spillman to all keyspaces' => { + ensure => absent, + permission_name => 'SELECT', + user_name => 'spillman', + }, + 'Revoke modify to to keyspace mykeyspace to akers' => { + ensure => absent, + keyspace_name => 'mykeyspace', + permission_name => 'MODIFY', + user_name => 'akers', + }, + 'Revoke alter permissions to mykeyspace to boone' => { + ensure => absent, + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + user_name => 'boone', + }, + 'Revoke ALL permissions to mykeyspace.users to gbennet' => { + ensure => absent, + keyspace_name => 'mykeyspace', + permission_name => 'ALTER', + table_name => 'users', + user_name => 'gbennet', + }, + }, + } + } + EOS + + describe '########### Revoke permissions.' do + it 'should work with no errors' do + apply_manifest(permissions_revoke_pp, catch_failures: true) end it 'check code is idempotent' do - expect(apply_manifest(schema_testing_drop_type_pp, catch_failures: true).exit_code).to be_zero + expect(apply_manifest(permissions_revoke_pp, catch_failures: true).exit_code).to be_zero end end - schema_testing_drop_user_pp = <<-EOS + schema_drop_user_pp = <<-EOS #{cassandra_install_pp} if $run_schema_tests { class { 'cassandra::schema': cqlsh_password => 'Niner2', cqlsh_host => $::ipaddress, cqlsh_user => 'akers', cqlsh_client_config => '/root/.puppetcqlshrc', users => { 'boone' => { ensure => absent, }, }, } } - EOS + EOS describe '########### Drop the boone user.' do it 'should work with no errors' do - apply_manifest(schema_testing_drop_user_pp, catch_failures: true) + apply_manifest(schema_drop_user_pp, catch_failures: true) end it 'check code is idempotent' do - expect(apply_manifest(schema_testing_drop_user_pp, catch_failures: true).exit_code).to be_zero + expect(apply_manifest(schema_drop_user_pp, catch_failures: true).exit_code).to be_zero end end schema_testing_drop_index_pp = <<-EOS #{cassandra_install_pp} if $run_schema_tests { class { 'cassandra::schema': cqlsh_host => $::ipaddress, cqlsh_user => 'akers', cqlsh_password => 'Niner2', indexes => { 'users_lname_idx' => { ensure => absent, keyspace => 'mykeyspace', table => 'users', }, }, } } EOS describe '########### Schema drop index.' do it 'should work with no errors' do apply_manifest(schema_testing_drop_index_pp, catch_failures: true) end it 'check code is idempotent' do expect(apply_manifest(schema_testing_drop_index_pp, catch_failures: true).exit_code).to be_zero end end schema_testing_drop_pp = <<-EOS #{cassandra_install_pp} if $run_schema_tests { class { 'cassandra::schema': cqlsh_host => $ipaddress, cqlsh_password => 'Niner2', cqlsh_user => 'akers', tables => { 'users' => { ensure => absent, keyspace => 'mykeyspace', }, }, } } EOS describe '########### Schema drop (table).' do it 'should work with no errors' do apply_manifest(schema_testing_drop_pp, catch_failures: true) end it 'check code is idempotent' do expect(apply_manifest(schema_testing_drop_pp, catch_failures: true).exit_code).to be_zero end end schema_testing_drop_pp = <<-EOS #{cassandra_install_pp} $keyspaces = { 'mykeyspace' => { ensure => absent, } } if $run_schema_tests { class { 'cassandra::schema': cqlsh_host => $::ipaddress, cqlsh_password => 'Niner2', cqlsh_user => 'akers', keyspaces => $keyspaces, } } EOS describe '########### Schema drop (Keyspaces).' do it 'should work with no errors' do apply_manifest(schema_testing_drop_pp, catch_failures: true) end it 'check code is idempotent' do expect(apply_manifest(schema_testing_drop_pp, catch_failures: true).exit_code).to be_zero end end describe service('cassandra') do it do is_expected.to be_running is_expected.to be_enabled end end describe service('datastax-agent') do it do is_expected.to be_running is_expected.to be_enabled end end facts_testing_pp = <<-EOS #{cassandra_install_pp} if $::cassandrarelease != $version { fail("Test1: ${version} != ${::cassandrarelease}") } $assembled_version = "${::cassandramajorversion}.${::cassandraminorversion}.${::cassandrapatchversion}" if $version != $assembled_version { fail("Test2: ${version} != ${::assembled_version}") } + + if $::cassandramaxheapsize <= 0 { + fail('cassandramaxheapsize is not set.') + } + if $::cassandracmsmaxheapsize <= 0 { + fail('cassandracmsmaxheapsize is not set.') + } + if $::cassandraheapnewsize <= 0 { + fail('cassandraheapnewsize is not set.') + } + if $::cassandracmsheapnewsize <= 0 { + fail('cassandracmsheapnewsize is not set.') + } EOS describe '########### Facts Tests.' do it 'should work with no errors' do apply_manifest(facts_testing_pp, catch_failures: true) end end describe '########### Gather service information (when in debug mode).' do it 'Show the cassandra system log.' do shell("grep -v -e '^INFO' -e '^\s*INFO' /var/log/cassandra/system.log") end end cassandra_uninstall_pp = <<-EOS Exec { path => [ '/usr/local/bin', '/opt/local/bin', '/usr/bin', '/usr/sbin', '/bin', '/sbin'], logoutput => true, } if $::osfamily == 'RedHat' { $cassandra_optutils_package = 'cassandra22-tools' $cassandra_package = 'cassandra22' } else { $cassandra_optutils_package = 'cassandra-tools' $cassandra_package = 'cassandra' } service { 'cassandra': ensure => stopped, } -> package { $cassandra_optutils_package: ensure => absent } -> package { $cassandra_package: ensure => absent } -> exec { 'rm -rf /var/lib/cassandra/*/* /var/log/cassandra/*': } EOS describe '########### Uninstall Cassandra 2.' do it 'should work with no errors' do apply_manifest(cassandra_uninstall_pp, catch_failures: true) end end end diff --git a/spec/defines/schema/permission_spec.rb b/spec/defines/schema/permission_spec.rb new file mode 100644 index 0000000..bcf71d6 --- /dev/null +++ b/spec/defines/schema/permission_spec.rb @@ -0,0 +1,180 @@ +require 'spec_helper' + +describe 'cassandra::schema::permission' do + let(:pre_condition) do + [ + 'define ini_setting($ensure = nil, + $path, + $section, + $key_val_separator = nil, + $setting, + $value = nil) {}' + ] + end + + context 'Set ensure to latest' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'foobar' } + let(:params) do + { + user_name: 'foobar' + } + end + + it { should raise_error(Puppet::Error) } + end + + context 'Set ensure to latest' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'foobar' } + let(:params) do + { + ensure: 'latest' + } + end + + it { should raise_error(Puppet::Error) } + end + + context 'spillman:SELECT:ALL' do + let(:title) { 'spillman:SELECT:ALL' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + user_name: 'spillman', + permission_name: 'SELECT' + } + end + + it do + should have_resource_count(9) + should contain_exec('GRANT SELECT ON ALL KEYSPACES TO spillman') + end + end + + context 'akers:modify:field' do + let(:title) { 'akers:modify:field' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + user_name: 'akers', + keyspace_name: 'field', + permission_name: 'MODIFY' + } + end + + it do + should have_resource_count(9) + should contain_exec('GRANT MODIFY ON KEYSPACE field TO akers') + end + end + + context 'boone:alter:forty9ers' do + let(:title) { 'boone:alter:forty9ers' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + user_name: 'boone', + keyspace_name: 'forty9ers', + permission_name: 'ALTER' + } + end + + it do + should have_resource_count(9) + should contain_exec('GRANT ALTER ON KEYSPACE forty9ers TO boone') + end + end + + context 'boone:ALL:ravens.plays' do + let(:title) { 'boone:ALL:ravens.plays' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + user_name: 'boone', + keyspace_name: 'ravens', + table_name: 'plays' + } + end + + it do + should have_resource_count(18) + should contain_cassandra__schema__permission('boone:ALL:ravens.plays - ALTER').with( + ensure: 'present', + user_name: 'boone', + keyspace_name: 'ravens', + permission_name: 'ALTER', + table_name: 'plays' + ) + should contain_cassandra__schema__permission('boone:ALL:ravens.plays - AUTHORIZE') + should contain_cassandra__schema__permission('boone:ALL:ravens.plays - DROP') + should contain_cassandra__schema__permission('boone:ALL:ravens.plays - MODIFY') + should contain_cassandra__schema__permission('boone:ALL:ravens.plays - SELECT') + should contain_exec('GRANT ALTER ON TABLE ravens.plays TO boone') + should contain_exec('GRANT AUTHORIZE ON TABLE ravens.plays TO boone') + should contain_exec('GRANT DROP ON TABLE ravens.plays TO boone') + should contain_exec('GRANT MODIFY ON TABLE ravens.plays TO boone') + should contain_exec('GRANT SELECT ON TABLE ravens.plays TO boone') + end + end + + context 'REVOKE boone:SELECT:ravens.plays' do + let(:title) { 'REVOKE boone:SELECT:ravens.plays' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + ensure: 'absent', + user_name: 'boone', + keyspace_name: 'forty9ers', + permission_name: 'SELECT' + } + end + + it do + should have_resource_count(9) + should contain_exec('REVOKE SELECT ON KEYSPACE forty9ers FROM boone') + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f650464..386a427 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,141 +1,154 @@ require 'rubygems' require 'rspec-puppet' require 'rspec-puppet-utils' require 'puppetlabs_spec_helper/module_spec_helper' require 'simplecov' require 'coveralls' fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) RSpec.configure do |config| config.module_path = File.join(fixture_path, 'modules') config.manifest_dir = File.join(fixture_path, 'manifests') config.tty = true config.mock_with :rspec config.raise_errors_for_deprecations! config.before(:each) do MockFunction.new('concat') do |f| f.stubbed.returns([8888, 22]) f.stubbed.with([], '/etc/cassandra') .returns(['/etc/cassandra']) f.stubbed.with([], '/etc/cassandra/default.conf') .returns(['/etc/cassandra/default.conf']) f.stubbed.with(['/etc/cassandra'], '/etc/cassandra/default.conf') .returns(['/etc/cassandra', '/etc/cassandra/default.conf']) end MockFunction.new('count') do |f| f.stubbed.with( [ 'COMPACT STORAGE', 'ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'' ] ).returns(2) end MockFunction.new('create_ini_settings', type: :statement) do |f| end MockFunction.new('delete') do |f| f.stubbed.with( { 'keyspace_class' => 'NetworkTopologyStrategy', 'dc1' => '3', 'dc2' => '2' }, 'keyspace_class' ).returns('dc1' => '3', 'dc2' => '2') f.stubbed.with('userid text, username FROZEN, emails set, top_scores list, todo map, COLLECTION-TYPE tuple, PRIMARY KEY (userid)', 'COLLECTION-TYPE ').returns('userid text, username FROZEN, emails set, top_scores list, todo map, tuple, PRIMARY KEY (userid)') end MockFunction.new('is_array') do |f| f.stubbed.with('').returns(false) f.stubbed.with(['/var/lib/cassandra/data']).returns(true) end MockFunction.new('join') do |f| f.stubbed.with(['firstname text', 'lastname text'], ', ') .returns('firstname text, lastname text') f.stubbed.with( { '\'dc1\': ' => '3', '\'dc2\': ' => '2' }, ', ' ).returns('\'dc1\': 3, \'dc2\': 2') f.stubbed.with( [ 'COMPACT STORAGE', 'ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'' ], ' AND ' ).returns("COMPACT STORAGE AND ID='5a1c395e-b41f-11e5-9f22-ba0be0483c18'") f.stubbed.with( [ 'userid text', 'username FROZEN', 'emails set', 'top_scores list', 'todo map', 'COLLECTION-TYPE tuple', 'PRIMARY KEY (userid)' ], ', ' ).returns('userid text, username FROZEN, emails set, top_scores list, todo map, COLLECTION-TYPE tuple, PRIMARY KEY (userid)') end MockFunction.new('join_keys_to_values') do |f| f.stubbed.with({ 'firstname' => 'text', 'lastname' => 'text' }, ' ') .returns(['firstname text', 'lastname text']) f.stubbed.with( { '\'dc1' => '3', '\'dc2' => '2' }, '\': ' ).returns('\'dc1\': ' => '3', '\'dc2\': ' => '2') f.stubbed.with( { 'userid' => 'text', 'username' => 'FROZEN', 'emails' => 'set', 'top_scores' => 'list', 'todo' => 'map', 'COLLECTION-TYPE' => 'tuple', 'PRIMARY KEY' => '(userid)' }, ' ' ).returns( [ 'userid text', 'username FROZEN', 'emails set', 'top_scores list', 'todo map', 'COLLECTION-TYPE tuple', 'PRIMARY KEY (userid)' ] ) end MockFunction.new('merge') do |f| end MockFunction.new('prefix') do |f| f.stubbed.with(['0.0.0.0/0'], '200_Public_').returns('200_Public_0.0.0.0/0') f.stubbed.with(['0.0.0.0/0'], '210_InterNode_').returns('210_InterNode__0.0.0.0/0') f.stubbed.with(['0.0.0.0/0'], '220_Client_').returns('220_Client__0.0.0.0/0') f.stubbed.with( { 'dc1' => '3', 'dc2' => '2' }, '\'' ).returns('\'dc1' => '3', '\'dc2' => '2') end + MockFunction.new('upcase') do |f| + f.stubbed.with('ALL').returns('ALL') + f.stubbed.with('ALTER').returns('ALTER') + f.stubbed.with('AUTHORIZE').returns('AUTHORIZE') + f.stubbed.with('CREATE').returns('CREATE') + f.stubbed.with('DROP').returns('DROP') + f.stubbed.with('MODIFY').returns('MODIFY') + f.stubbed.with('SELECT').returns('SELECT') + f.stubbed.with('field').returns('FIELD') + f.stubbed.with('forty9ers').returns('FORTY9ERS') + f.stubbed.with('ravens').returns('ravens') + end + MockFunction.new('size') do |f| f.stubbed.returns(42) end MockFunction.new('strftime') do |f| f.stubbed.with('/var/lib/cassandra-%F') .returns('/var/lib/cassandra-YYYY-MM-DD') end MockFunction.new('validate_hash', type: :statement) do |f| end end end Coveralls.wear! at_exit { RSpec::Puppet::Coverage.report! } diff --git a/spec/unit/facter/cassandracmsheapnewsize_spec.rb b/spec/unit/facter/cassandracmsheapnewsize_spec.rb new file mode 100644 index 0000000..710d020 --- /dev/null +++ b/spec/unit/facter/cassandracmsheapnewsize_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe 'Facter::Util::Fact' do + before do + Facter.clear + end + + describe 'cassandrarelease DSE' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('2.1.11.969') + expect(Facter.fact(:cassandrarelease).value).to eql('2.1.11') + expect(Facter.fact(:cassandramajorversion).value).to eql(2) + expect(Facter.fact(:cassandraminorversion).value).to eql(1) + expect(Facter.fact(:cassandrapatchversion).value).to eql(11) + end + end + + describe 'cassandrarelease DDC' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('3.0.1') + expect(Facter.fact(:cassandrarelease).value).to eql('3.0.1') + expect(Facter.fact(:cassandramajorversion).value).to eql(3) + expect(Facter.fact(:cassandraminorversion).value).to eql(0) + expect(Facter.fact(:cassandrapatchversion).value).to eql(1) + end + end + + describe 'Cassandra not installed or not running' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('') + expect(Facter.fact(:cassandrarelease).value).to eql(nil) + expect(Facter.fact(:cassandramajorversion).value).to eql(nil) + expect(Facter.fact(:cassandraminorversion).value).to eql(nil) + expect(Facter.fact(:cassandrapatchversion).value).to eql(nil) + end + end + + describe 'Heap settings' do + context 'Rasberry Pi 3' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('1024') + Facter.fact(:processorcount).stubs(:value).returns('4') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eq(512) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(512) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(128) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(128) + end + end + + context 'm4.large' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('8191.9') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'm4.xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('16384') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'c4.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('15360') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + + context 'i2.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('62464') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(8192) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(14_336) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + end +end diff --git a/spec/unit/facter/cassandracmsmaxheapsize_spec.rb b/spec/unit/facter/cassandracmsmaxheapsize_spec.rb new file mode 100644 index 0000000..710d020 --- /dev/null +++ b/spec/unit/facter/cassandracmsmaxheapsize_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe 'Facter::Util::Fact' do + before do + Facter.clear + end + + describe 'cassandrarelease DSE' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('2.1.11.969') + expect(Facter.fact(:cassandrarelease).value).to eql('2.1.11') + expect(Facter.fact(:cassandramajorversion).value).to eql(2) + expect(Facter.fact(:cassandraminorversion).value).to eql(1) + expect(Facter.fact(:cassandrapatchversion).value).to eql(11) + end + end + + describe 'cassandrarelease DDC' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('3.0.1') + expect(Facter.fact(:cassandrarelease).value).to eql('3.0.1') + expect(Facter.fact(:cassandramajorversion).value).to eql(3) + expect(Facter.fact(:cassandraminorversion).value).to eql(0) + expect(Facter.fact(:cassandrapatchversion).value).to eql(1) + end + end + + describe 'Cassandra not installed or not running' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('') + expect(Facter.fact(:cassandrarelease).value).to eql(nil) + expect(Facter.fact(:cassandramajorversion).value).to eql(nil) + expect(Facter.fact(:cassandraminorversion).value).to eql(nil) + expect(Facter.fact(:cassandrapatchversion).value).to eql(nil) + end + end + + describe 'Heap settings' do + context 'Rasberry Pi 3' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('1024') + Facter.fact(:processorcount).stubs(:value).returns('4') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eq(512) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(512) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(128) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(128) + end + end + + context 'm4.large' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('8191.9') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'm4.xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('16384') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'c4.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('15360') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + + context 'i2.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('62464') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(8192) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(14_336) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + end +end diff --git a/spec/unit/facter/cassandraheapnewsize_spec.rb b/spec/unit/facter/cassandraheapnewsize_spec.rb new file mode 100644 index 0000000..710d020 --- /dev/null +++ b/spec/unit/facter/cassandraheapnewsize_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe 'Facter::Util::Fact' do + before do + Facter.clear + end + + describe 'cassandrarelease DSE' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('2.1.11.969') + expect(Facter.fact(:cassandrarelease).value).to eql('2.1.11') + expect(Facter.fact(:cassandramajorversion).value).to eql(2) + expect(Facter.fact(:cassandraminorversion).value).to eql(1) + expect(Facter.fact(:cassandrapatchversion).value).to eql(11) + end + end + + describe 'cassandrarelease DDC' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('3.0.1') + expect(Facter.fact(:cassandrarelease).value).to eql('3.0.1') + expect(Facter.fact(:cassandramajorversion).value).to eql(3) + expect(Facter.fact(:cassandraminorversion).value).to eql(0) + expect(Facter.fact(:cassandrapatchversion).value).to eql(1) + end + end + + describe 'Cassandra not installed or not running' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('') + expect(Facter.fact(:cassandrarelease).value).to eql(nil) + expect(Facter.fact(:cassandramajorversion).value).to eql(nil) + expect(Facter.fact(:cassandraminorversion).value).to eql(nil) + expect(Facter.fact(:cassandrapatchversion).value).to eql(nil) + end + end + + describe 'Heap settings' do + context 'Rasberry Pi 3' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('1024') + Facter.fact(:processorcount).stubs(:value).returns('4') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eq(512) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(512) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(128) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(128) + end + end + + context 'm4.large' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('8191.9') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'm4.xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('16384') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'c4.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('15360') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + + context 'i2.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('62464') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(8192) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(14_336) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + end +end diff --git a/spec/unit/facter/cassandra_spec.rb b/spec/unit/facter/cassandramajorversion_spec.rb similarity index 100% copy from spec/unit/facter/cassandra_spec.rb copy to spec/unit/facter/cassandramajorversion_spec.rb diff --git a/spec/unit/facter/cassandramaxheapsize_spec.rb b/spec/unit/facter/cassandramaxheapsize_spec.rb new file mode 100644 index 0000000..710d020 --- /dev/null +++ b/spec/unit/facter/cassandramaxheapsize_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe 'Facter::Util::Fact' do + before do + Facter.clear + end + + describe 'cassandrarelease DSE' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('2.1.11.969') + expect(Facter.fact(:cassandrarelease).value).to eql('2.1.11') + expect(Facter.fact(:cassandramajorversion).value).to eql(2) + expect(Facter.fact(:cassandraminorversion).value).to eql(1) + expect(Facter.fact(:cassandrapatchversion).value).to eql(11) + end + end + + describe 'cassandrarelease DDC' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('3.0.1') + expect(Facter.fact(:cassandrarelease).value).to eql('3.0.1') + expect(Facter.fact(:cassandramajorversion).value).to eql(3) + expect(Facter.fact(:cassandraminorversion).value).to eql(0) + expect(Facter.fact(:cassandrapatchversion).value).to eql(1) + end + end + + describe 'Cassandra not installed or not running' do + it do + allow(Facter::Util::Resolution) + .to receive(:exec).with('nodetool version') + .and_return('') + expect(Facter.fact(:cassandrarelease).value).to eql(nil) + expect(Facter.fact(:cassandramajorversion).value).to eql(nil) + expect(Facter.fact(:cassandraminorversion).value).to eql(nil) + expect(Facter.fact(:cassandrapatchversion).value).to eql(nil) + end + end + + describe 'Heap settings' do + context 'Rasberry Pi 3' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('1024') + Facter.fact(:processorcount).stubs(:value).returns('4') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eq(512) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(512) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(128) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(128) + end + end + + context 'm4.large' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('8191.9') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(2048) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'm4.xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('16384') + Facter.fact(:processorcount).stubs(:value).returns('2') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(4096) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(200) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(200) + end + end + + context 'c4.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('15360') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(3840) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + + context 'i2.2xlarge' do + before :each do + Facter.fact(:memorysize_mb).stubs(:value).returns('62464') + Facter.fact(:processorcount).stubs(:value).returns('8') + end + + it do + expect(Facter.fact(:cassandramaxheapsize).value).to eql(8192) + expect(Facter.fact(:cassandracmsmaxheapsize).value).to eql(14_336) + expect(Facter.fact(:cassandraheapnewsize).value).to eql(800) + expect(Facter.fact(:cassandracmsheapnewsize).value).to eql(800) + end + end + end +end diff --git a/spec/unit/facter/cassandra_spec.rb b/spec/unit/facter/cassandraminorversion_spec.rb similarity index 100% copy from spec/unit/facter/cassandra_spec.rb copy to spec/unit/facter/cassandraminorversion_spec.rb diff --git a/spec/unit/facter/cassandra_spec.rb b/spec/unit/facter/cassandrapatchversion_spec.rb similarity index 100% copy from spec/unit/facter/cassandra_spec.rb copy to spec/unit/facter/cassandrapatchversion_spec.rb diff --git a/spec/unit/facter/cassandra_spec.rb b/spec/unit/facter/cassandrarelease_spec.rb similarity index 100% rename from spec/unit/facter/cassandra_spec.rb rename to spec/unit/facter/cassandrarelease_spec.rb