diff --git a/manifests/init.pp b/manifests/init.pp index 288430f..eb095d0 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,382 +1,387 @@ # A class for installing the Cassandra package and manipulate settings in the # configuration file. # # @param baseline_settings [hash] If set, this is a baseline of settings that # are merged with the `settings` hash. The values of the `settings` # hash overriding the values in this hash. This is most useful when used # with hiera. # @param cassandra_2356_sleep_seconds [boolean] # This will provide a workaround for # [CASSANDRA-2356](https://issues.apache.org/jira/browse/CASSANDRA-2356) by # sleeping for the specifed number of seconds after an event involving the # Cassandra package. This option is silently ignored on the Red Hat family # of operating systems as this bug only affects Debian systems. # @param cassandra_9822 [boolean] If set to true, this will apply a patch to the init # file for the Cassandra service as a workaround for # [CASSANDRA-9822](https://issues.apache.org/jira/browse/CASSANDRA-9822). # This this bug only affects Debian systems. # @param cassandra_yaml_tmpl [string] The path to the Puppet template for the # Cassandra configuration file. This allows the user to supply their own # customized template.` # @param commitlog_directory [string] The path to the commitlog directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param commitlog_directory_mode [string] The mode for the # `commitlog_directory` is ignored unless `commitlog_directory` is # specified. +# @param manage_config_file [boolean] Whether or not to manage the cassandra configuration +# file. # @param config_file_mode [string] The permissions mode of the cassandra configuration # file. # @param config_path [string] The path to the cassandra configuration file. # @param data_file_directories [array] The path(s) to the date directory or # directories. # If set, the directories will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param data_file_directories_mode [string] The mode for the # `data_file_directories` is ignored unless `data_file_directories` is # specified. # @param dc [string] Sets the value for dc in *config_path*/*snitch_properties_file* # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. # @param dc_suffix [string] Sets the value for dc_suffix in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. If the value is *undef* then no change will be made to # the snitch properties file for this setting. # @param fail_on_non_supported_os [boolean] A flag that dictates if the module should # fail if it is not RedHat or Debian. If you set this option to false then # you must also at least set the `config_path` attribute as well. # @param hints_directory [string] The path to the hints directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. Do not set this option in Cassandra versions before 3.0.0. # @param hints_directory_mode [string] The mode for the # `hints_directory` is ignored unless `hints_directory` is # specified. # @param package_ensure [present|latest|string] The status of the package specified in # **package_name**. Can be *present*, *latest* or a specific version # number. # @param package_name [string] The name of the Cassandra package which must be available # from a repository. # @param prefer_local [boolean] Sets the value for prefer_local in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. Valid values are true, false or *undef*. If the value # is *undef* then change will be made to the snitch properties file for # this setting. # @param rack [string] Sets the value for rack in # *config_path*/*snitch_properties_file* see # http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureSnitchesAbout_c.html # for more details. # @param rackdc_tmpl [string] The template for creating the snitch properties file. # @param saved_caches_directory [string] The path to the saved caches directory. # If set, the directory will be managed as a Puppet resource. Do not # specify a value here and in the `settings` hash as they are mutually # exclusive. # @param saved_caches_directory_mode [string] The mode for the # `saved_caches_directory` is ignored unless `saved_caches_directory` is # specified. # @param service_enable [boolean] enable the Cassandra service to start at boot time. # @param service_ensure [string] Ensure the Cassandra service is running. Valid values # are running or stopped. # @param service_name [string] The name of the service that runs the Cassandra software. # @param service_provider [string] The name of the provider that runs the service. # If left as *undef* then the OS family specific default will # be used, otherwise the specified value will be used instead. # @param service_refresh [boolean] If set to true, changes to the Cassandra config file # or the data directories will ensure that Cassandra service is refreshed # after the changes. Setting this flag to false will disable this # behaviour, therefore allowing the changes to be made but allow the user # to control when the service is restarted. # @param settings [hash] A hash that is passed to `to_yaml` which dumps the results # to the Cassandra configuring file. The minimum required settings for # Cassandra 2.X are as follows: # # ```puppet # { # 'authenticator' => 'PasswordAuthenticator', # 'cluster_name' => 'MyCassandraCluster', # 'commitlog_directory' => '/var/lib/cassandra/commitlog', # 'commitlog_sync' => 'periodic', # 'commitlog_sync_period_in_ms' => 10000, # 'data_file_directories' => ['/var/lib/cassandra/data'], # 'endpoint_snitch' => 'GossipingPropertyFileSnitch', # 'listen_address' => $::ipaddress, # 'partitioner' => 'org.apache.cassandra.dht.Murmur3Partitioner', # 'saved_caches_directory' => '/var/lib/cassandra/saved_caches', # 'seed_provider' => [ # { # 'class_name' => 'org.apache.cassandra.locator.SimpleSeedProvider', # 'parameters' => [ # { # 'seeds' => $::ipaddress, # }, # ], # }, # ], # 'start_native_transport' => true, # } # ``` # For Cassandra 3.X you will also need to specify the `hints_directory` # attribute. # @param snitch_properties_file [string] The name of the snitch properties file. The # full path name would be *config_path*/*snitch_properties_file*. # @param systemctl [string] The full path to the systemctl command. Only # needed when the package is installed. Will silently continue if the # executable does not exist. class cassandra ( $baseline_settings = {}, $cassandra_2356_sleep_seconds = 5, $cassandra_9822 = false, $cassandra_yaml_tmpl = 'cassandra/cassandra.yaml.erb', $commitlog_directory = undef, $commitlog_directory_mode = '0750', + Boolean $manage_config_file = true, $config_file_mode = '0644', $config_path = $::cassandra::params::config_path, $data_file_directories = undef, $data_file_directories_mode = '0750', $dc = 'DC1', $dc_suffix = undef, $fail_on_non_supported_os = true, $hints_directory = undef, $hints_directory_mode = '0750', $package_ensure = 'present', $package_name = $::cassandra::params::cassandra_pkg, $prefer_local = undef, $rack = 'RAC1', $rackdc_tmpl = 'cassandra/cassandra-rackdc.properties.erb', $saved_caches_directory = undef, $saved_caches_directory_mode = '0750', $service_enable = true, $service_ensure = undef, $service_name = 'cassandra', $service_provider = undef, $service_refresh = true, $settings = {}, $snitch_properties_file = 'cassandra-rackdc.properties', $systemctl = $::cassandra::params::systemctl, ) inherits cassandra::params { if $service_provider != undef { Service { provider => $service_provider, } } $config_file = "${config_path}/cassandra.yaml" $dc_rack_properties_file = "${config_path}/${snitch_properties_file}" case $::osfamily { 'RedHat': { $config_file_require = Package['cassandra'] $config_file_before = [] $config_path_require = Package['cassandra'] $dc_rack_properties_file_require = Package['cassandra'] $dc_rack_properties_file_before = [] $data_dir_require = Package['cassandra'] $data_dir_before = [] if $::operatingsystemmajrelease == '7' and $::cassandra::service_provider == 'init' { exec { "/sbin/chkconfig --add ${service_name}": unless => "/sbin/chkconfig --list ${service_name}", require => Package['cassandra'], before => Service['cassandra'], } } } 'Debian': { $config_file_require = [ User['cassandra'], File[$config_path] ] $config_file_before = Package['cassandra'] $config_path_require = [] $dc_rack_properties_file_require = [ User['cassandra'], File[$config_path] ] $dc_rack_properties_file_before = Package['cassandra'] $data_dir_require = File[$config_file] $data_dir_before = Package['cassandra'] if $cassandra_9822 { file { '/etc/init.d/cassandra': source => 'puppet:///modules/cassandra/CASSANDRA-9822/cassandra', mode => '0555', before => Package['cassandra'], } } # Sleep after package install and before service resource to prevent # possible duplicate processes arising from CASSANDRA-2356. exec { 'CASSANDRA-2356 sleep': command => "/bin/sleep ${cassandra_2356_sleep_seconds}", refreshonly => true, user => 'root', subscribe => Package['cassandra'], before => Service['cassandra'], } group { 'cassandra': ensure => present, } $user = 'cassandra' user { $user: ensure => present, comment => 'Cassandra database,,,', gid => 'cassandra', home => '/var/lib/cassandra', shell => '/bin/false', managehome => true, require => Group['cassandra'], } # End of CASSANDRA-2356 specific resources. } default: { $config_file_before = [ Package['cassandra'] ] $config_file_require = [] $config_path_require = [] $dc_rack_properties_file_require = Package['cassandra'] $dc_rack_properties_file_before = [] if $fail_on_non_supported_os { fail("OS family ${::osfamily} not supported") } else { warning("OS family ${::osfamily} not supported") } } } package { 'cassandra': ensure => $package_ensure, name => $package_name, notify => Exec['cassandra_reload_systemctl'], } exec { 'cassandra_reload_systemctl': command => "${systemctl} daemon-reload", onlyif => "test -x ${systemctl}", path => ['/usr/bin', '/bin'], refreshonly => true, } - file { $config_path: - ensure => directory, - group => 'cassandra', - owner => 'cassandra', - mode => '0755', - require => $config_path_require, + if $manage_config_file { + file { $config_path: + ensure => directory, + group => 'cassandra', + owner => 'cassandra', + mode => '0755', + require => $config_path_require, + } } if $commitlog_directory { file { $commitlog_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $commitlog_directory_mode, require => $data_dir_require, before => $data_dir_before, } $commitlog_directory_settings = merge($settings, { 'commitlog_directory' => $commitlog_directory, }) } else { $commitlog_directory_settings = $settings } if is_array($data_file_directories) { file { $data_file_directories: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $data_file_directories_mode, require => $data_dir_require, before => $data_dir_before, } $data_file_directories_settings = merge($settings, { 'data_file_directories' => $data_file_directories, }) } else { $data_file_directories_settings = $settings } if $hints_directory { file { $hints_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $hints_directory_mode, require => $data_dir_require, before => $data_dir_before, } $hints_directory_settings = merge($settings, { 'hints_directory' => $hints_directory, }) } else { $hints_directory_settings = $settings } if $saved_caches_directory { file { $saved_caches_directory: ensure => directory, owner => 'cassandra', group => 'cassandra', mode => $saved_caches_directory_mode, require => $data_dir_require, before => $data_dir_before, } $saved_caches_directory_settings = merge($settings, { 'saved_caches_directory' => $saved_caches_directory, }) } else { $saved_caches_directory_settings = $settings } $merged_settings = merge($baseline_settings, $settings, $commitlog_directory_settings, $data_file_directories_settings, $hints_directory_settings, $saved_caches_directory_settings) file { $config_file: ensure => present, owner => 'cassandra', group => 'cassandra', content => template($cassandra_yaml_tmpl), mode => $config_file_mode, require => $config_file_require, before => $config_file_before, } file { $dc_rack_properties_file: ensure => file, content => template($rackdc_tmpl), owner => 'cassandra', group => 'cassandra', mode => '0644', require => $dc_rack_properties_file_require, before => $dc_rack_properties_file_before, } if $package_ensure != 'absent' and $package_ensure != 'purged' { if $service_refresh { service { 'cassandra': ensure => $service_ensure, name => $service_name, enable => $service_enable, subscribe => [ File[$config_file], File[$dc_rack_properties_file], Package['cassandra'], ], } } else { service { 'cassandra': ensure => $service_ensure, name => $service_name, enable => $service_enable, require => [ File[$config_file], File[$dc_rack_properties_file], Package['cassandra'], ], } } } } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index da810f1..e5a01bd 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,388 +1,389 @@ require 'spec_helper' describe 'cassandra' do context 'On an unknown OS with defaults for all parameters' do let :facts do { operatingsystemmajrelease: '10', osfamily: 'Darwin' } end it { is_expected.to raise_error(Puppet::Error) } end context 'Test the default parameters (RedHat)' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7' } end it do is_expected.to contain_package('cassandra').with( ensure: 'present', name: 'cassandra22' ).that_notifies('Exec[cassandra_reload_systemctl]') is_expected.to contain_exec('cassandra_reload_systemctl').only_with( command: '/usr/bin/systemctl daemon-reload', onlyif: 'test -x /usr/bin/systemctl', path: ['/usr/bin', '/bin'], refreshonly: true ) is_expected.to contain_file('/etc/cassandra/default.conf').with( ensure: 'directory', group: 'cassandra', owner: 'cassandra', mode: '0755' ).that_requires('Package[cassandra]') is_expected.to contain_file('/etc/cassandra/default.conf/cassandra.yaml'). with( ensure: 'present', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_requires('Package[cassandra]') is_expected.to contain_class('cassandra').only_with( baseline_settings: {}, cassandra_2356_sleep_seconds: 5, cassandra_9822: false, cassandra_yaml_tmpl: 'cassandra/cassandra.yaml.erb', commitlog_directory_mode: '0750', + manage_config_file: true, config_file_mode: '0644', config_path: '/etc/cassandra/default.conf', data_file_directories_mode: '0750', dc: 'DC1', fail_on_non_supported_os: true, hints_directory_mode: '0750', package_ensure: 'present', package_name: 'cassandra22', rack: 'RAC1', rackdc_tmpl: 'cassandra/cassandra-rackdc.properties.erb', saved_caches_directory_mode: '0750', service_enable: true, service_name: 'cassandra', service_provider: nil, service_refresh: true, settings: {}, systemctl: '/usr/bin/systemctl' ) end end context 'On RedHat 7 with data directories specified.' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7' } end let :params do { commitlog_directory: '/var/lib/cassandra/commitlog', data_file_directories: ['/var/lib/cassandra/data'], hints_directory: '/var/lib/cassandra/hints', saved_caches_directory: '/var/lib/cassandra/saved_caches', settings: { 'cluster_name' => 'MyCassandraCluster' } } end it do is_expected.to have_resource_count(10) is_expected.to contain_file('/var/lib/cassandra/commitlog') is_expected.to contain_file('/var/lib/cassandra/data') is_expected.to contain_file('/var/lib/cassandra/hints') is_expected.to contain_file('/var/lib/cassandra/saved_caches') end end context 'On RedHat 7 with service provider set to init.' do let :facts do { osfamily: 'RedHat', operatingsystemmajrelease: '7' } end let :params do { service_provider: 'init' } end it do is_expected.to have_resource_count(7) is_expected.to contain_exec('/sbin/chkconfig --add cassandra').with( unless: '/sbin/chkconfig --list cassandra' ). that_requires('Package[cassandra]'). that_comes_before('Service[cassandra]') end end context 'On a Debian OS with defaults for all parameters' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian' } end it do is_expected.to contain_class('cassandra') is_expected.to contain_group('cassandra').with_ensure('present') is_expected.to contain_package('cassandra').with( ensure: 'present', name: 'cassandra' ).that_notifies('Exec[cassandra_reload_systemctl]') is_expected.to contain_exec('cassandra_reload_systemctl').only_with( command: '/bin/systemctl daemon-reload', onlyif: 'test -x /bin/systemctl', path: ['/usr/bin', '/bin'], refreshonly: true ) is_expected.to contain_service('cassandra').with( ensure: nil, name: 'cassandra', enable: 'true' ) is_expected.to contain_exec('CASSANDRA-2356 sleep'). with( command: '/bin/sleep 5', refreshonly: true, user: 'root' ). that_subscribes_to('Package[cassandra]'). that_comes_before('Service[cassandra]') is_expected.to contain_user('cassandra'). with( ensure: 'present', comment: 'Cassandra database,,,', gid: 'cassandra', home: '/var/lib/cassandra', shell: '/bin/false', managehome: true ). that_requires('Group[cassandra]') is_expected.to contain_file('/etc/cassandra').with( ensure: 'directory', group: 'cassandra', owner: 'cassandra', mode: '0755' ) is_expected.to contain_file('/etc/cassandra/cassandra.yaml'). with( ensure: 'present', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_comes_before('Package[cassandra]'). that_requires(['User[cassandra]', 'File[/etc/cassandra]']) is_expected.to contain_file('/etc/cassandra/cassandra-rackdc.properties'). with( ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_requires(['File[/etc/cassandra]', 'User[cassandra]']). that_comes_before('Package[cassandra]') is_expected.to contain_service('cassandra'). that_subscribes_to( [ 'File[/etc/cassandra/cassandra.yaml]', 'File[/etc/cassandra/cassandra-rackdc.properties]', 'Package[cassandra]' ] ) end end context 'CASSANDRA-9822 activated on Debian' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'Debian', lsbdistid: 'Ubuntu', lsbdistrelease: '14.04' } end let :params do { cassandra_9822: true } end it do is_expected.to contain_file('/etc/init.d/cassandra').with( source: 'puppet:///modules/cassandra/CASSANDRA-9822/cassandra', mode: '0555' ).that_comes_before('Package[cassandra]') end end context 'Install DSE on a Red Hat family OS.' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat' } end let :params do { package_ensure: '4.7.0-1', package_name: 'dse-full', config_path: '/etc/dse/cassandra', service_name: 'dse' } end it do is_expected.to contain_file('/etc/dse/cassandra/cassandra.yaml').that_notifies('Service[cassandra]') is_expected.to contain_file('/etc/dse/cassandra') is_expected.to contain_file('/etc/dse/cassandra/cassandra-rackdc.properties'). with( ensure: 'file', owner: 'cassandra', group: 'cassandra', mode: '0644' ). that_notifies('Service[cassandra]') is_expected.to contain_package('cassandra').with( ensure: '4.7.0-1', name: 'dse-full' ) is_expected.to contain_service('cassandra').with_name('dse') end end context 'On an unsupported OS pleading tolerance' do let :facts do { operatingsystemmajrelease: '10', osfamily: 'Darwin' } end let :params do { config_file_mode: '0755', config_path: '/etc/cassandra', fail_on_non_supported_os: false, package_name: 'cassandra', service_provider: 'base', systemctl: '/bin/true' } end it do is_expected.to contain_file('/etc/cassandra/cassandra.yaml').with('mode' => '0755') is_expected.to contain_service('cassandra').with(provider: 'base') is_expected.to have_resource_count(6) end end context 'Ensure cassandra service can be stopped and disabled.' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian' } end let :params do { service_ensure: 'stopped', service_enable: 'false' } end it do is_expected.to contain_service('cassandra'). with(ensure: 'stopped', name: 'cassandra', enable: 'false') end end context 'Test the dc and rack properties with defaults (Debian).' do let :facts do { operatingsystemmajrelease: '8', osfamily: 'Debian' } end it do is_expected.to contain_file('/etc/cassandra/cassandra-rackdc.properties'). with_content(%r{^dc=DC1}). with_content(%r{^rack=RAC1$}). with_content(%r{^#dc_suffix=$}). with_content(%r{^# prefer_local=true$}) end end context 'Test the dc and rack properties with defaults (RedHat).' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat' } end it do is_expected.to contain_file('/etc/cassandra/default.conf/cassandra-rackdc.properties'). with_content(%r{^dc=DC1}). with_content(%r{^rack=RAC1$}). with_content(%r{^#dc_suffix=$}). with_content(%r{^# prefer_local=true$}) end end context 'Test the dc and rack properties.' do let :facts do { operatingsystemmajrelease: '7', osfamily: 'RedHat' } end let :params do { snitch_properties_file: 'cassandra-topology.properties', dc: 'NYC', rack: 'R101', dc_suffix: '_1_cassandra', prefer_local: 'true' } end it do is_expected.to contain_file('/etc/cassandra/default.conf/cassandra-topology.properties'). with_content(%r{^dc=NYC$}). with_content(%r{^rack=R101$}). with_content(%r{^dc_suffix=_1_cassandra$}). with_content(%r{^prefer_local=true$}) end end end