diff --git a/manifests/schema.pp b/manifests/schema.pp index 0de2e53..342222d 100644 --- a/manifests/schema.pp +++ b/manifests/schema.pp @@ -1,147 +1,153 @@ # 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 = {}, $use_scl = $::cassandra::params::use_scl, $scl_name = $::cassandra::params::scl_name, ) inherits cassandra::params { require '::cassandra' # Test that the SCL is valid if $use_scl { exec { "test ${scl_name} SCL": command => "/usr/bin/scl enable ${scl_name} \"echo test\"", } $scl_require = Exec["test ${scl_name} SCL"] } else { $scl_require = undef } # Pass the SCL info to create_resources below as a hash $scl = { 'use_scl' => $use_scl, 'scl_name' => $scl_name, } if $cqlsh_client_config != undef { file { $cqlsh_client_config : ensure => file, group => $::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}" + $connection_test_tmp = "${cqlsh_opts} -e 'DESC KEYSPACES' ${cqlsh_conn}" + if $use_scl { + $connection_test = "/usr/bin/scl enable ${scl_name} \"${connection_test_tmp}\"" + } else { + $connection_test = $connection_test_tmp + } + exec { '::cassandra::schema connection test': command => $connection_test, returns => 0, tries => $connection_tries, try_sleep => $connection_try_sleep, unless => $connection_test, require => $scl_require, } # manage keyspaces if present if $keyspaces { create_resources('cassandra::schema::keyspace', $keyspaces, $scl) } # manage cql_types if present if $cql_types { create_resources('cassandra::schema::cql_type', $cql_types, $scl) } # manage tables if present if $tables { create_resources('cassandra::schema::table', $tables, $scl) } # manage indexes if present if $indexes { create_resources('cassandra::schema::index', $indexes, $scl) } # manage users if present if $users { create_resources('cassandra::schema::user', $users, $scl) } # manage permissions if present if $permissions { create_resources('cassandra::schema::permission', $permissions, $scl) } # Resource Ordering Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Cql_type <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Cql_type <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Index <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Index <| |> -> Cassandra::Schema::User <| |> Cassandra::Schema::User <| |> -> Cassandra::Schema::Permission <| |> } diff --git a/spec/classes/schema_spec.rb b/spec/classes/schema_spec.rb index 61a6400..b9a90a6 100644 --- a/spec/classes/schema_spec.rb +++ b/spec/classes/schema_spec.rb @@ -1,135 +1,173 @@ require 'spec_helper' describe 'cassandra::schema' do context 'Ensure that a connection test is made.' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end it do is_expected.to contain_class('cassandra::schema'). with(connection_tries: 6, connection_try_sleep: 30, cqlsh_additional_options: '', cqlsh_command: '/usr/bin/cqlsh', cqlsh_host: 'localhost', cqlsh_password: nil, cqlsh_port: 9042, cqlsh_user: 'cassandra') read_command = '/usr/bin/cqlsh -e \'DESC KEYSPACES\' localhost 9042' is_expected.to contain_exec('::cassandra::schema connection test'). only_with(command: read_command, returns: 0, tries: 6, try_sleep: 30, unless: read_command) end end + context 'Ensure that a connection test is made with SCL.' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let :params do + { + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to contain_class('cassandra::schema'). + with(connection_tries: 6, + connection_try_sleep: 30, + cqlsh_additional_options: '', + cqlsh_command: '/usr/bin/cqlsh', + cqlsh_host: 'localhost', + cqlsh_password: nil, + cqlsh_port: 9042, + cqlsh_user: 'cassandra') + + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \'DESC KEYSPACES\' localhost 9042"' + + is_expected.to contain_exec('::cassandra::schema connection test'). + only_with(command: read_command, + returns: 0, + tries: 6, + try_sleep: 30, + unless: read_command, + require: 'Exec[test testscl SCL]') + end + end + context 'Test that users can specify a credentials file.' do let :facts do { id: 'root', gid: 'root', operatingsystemmajrelease: 7, osfamily: 'Debian' } end let :params do { cqlsh_client_config: '/root/.puppetcqlshrc', use_scl: false, scl_name: 'nodefault' } end it do is_expected.to contain_file('/root/.puppetcqlshrc').with( ensure: 'file', group: 'root', mode: '0600', owner: 'root', content: %r{username = cassandra} ).that_comes_before('Exec[::cassandra::schema connection test]') read_command = "/usr/bin/cqlsh --cqlshrc=/root/.puppetcqlshrc -e 'DESC KEYSPACES' localhost 9042" is_expected.to contain_exec('::cassandra::schema connection test'). only_with(command: read_command, returns: 0, tries: 6, try_sleep: 30, unless: read_command) end end context 'Test that users can specify a credentials file and password.' do let :facts do { id: 'root', gid: 'root', operatingsystemmajrelease: 7, osfamily: 'Debian' } end let :params do { cqlsh_client_config: '/root/.puppetcqlshrc', cqlsh_password: 'topsecret', use_scl: false, scl_name: 'nodefault' } end it do is_expected.to contain_file('/root/.puppetcqlshrc').with( ensure: 'file', group: 'root', mode: '0600', owner: 'root', content: %r{password = topsecret} ) read_command = "/usr/bin/cqlsh --cqlshrc=/root/.puppetcqlshrc -e 'DESC KEYSPACES' localhost 9042" is_expected.to contain_exec('::cassandra::schema connection test'). only_with(command: read_command, returns: 0, tries: 6, try_sleep: 30, unless: read_command) end end context 'Test that users can specify a password.' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'Redhat' } end let :params do { cqlsh_password: 'topsecret' } end it do read_command = "/usr/bin/cqlsh -u cassandra -p topsecret -e 'DESC KEYSPACES' localhost 9042" is_expected.to contain_exec('::cassandra::schema connection test'). only_with(command: read_command, returns: 0, tries: 6, try_sleep: 30, unless: read_command) end end end