diff --git a/manifests/schema/keyspace.pp b/manifests/schema/keyspace.pp index 2e5bcde..b783a35 100644 --- a/manifests/schema/keyspace.pp +++ b/manifests/schema/keyspace.pp @@ -1,78 +1,98 @@ # Create or drop keyspaces within the schema. # @param ensure [present|absent] Create or drop the keyspace. # @param durable_writes [boolean] When set to false, data written to the # keyspace bypasses the commit log. Be careful using this option # because you risk losing data. Set this attribute to false on a keyspace # using the SimpleStrategy. # @param keyspace_name [string] The name of the keyspace to be created. # @param replication_map [hash] Needed if the keyspace is to be present. # Optional if it is to be absent. # @example # $network_topology_strategy = { # keyspace_class => 'NetworkTopologyStrategy', # dc1 => 3, # dc2 => 2 # } # @example # cassandra::schema::keyspace { 'mykeyspace': # replication_map => { # keyspace_class => 'SimpleStrategy', # replication_factor => 1, # }, # durable_writes => false, # } define cassandra::schema::keyspace( $ensure = present, $durable_writes = true, $keyspace_name = $title, $replication_map = {}, $use_scl = $::cassandra::params::use_scl, $scl_name = $::cassandra::params::scl_name, ) { include 'cassandra::schema' + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + $read_script = "DESC KEYSPACE ${keyspace_name}" - $read_command = "${::cassandra::schema::cqlsh_opts} -e \"${read_script}\" ${::cassandra::schema::cqlsh_conn}" + $read_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${::cassandra::schema::cqlsh_conn}" + if $use_scl { + $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" + } else { + $read_command = $read_command_tmp + } if $ensure == present { $keyspace_class = $replication_map[keyspace_class] case $keyspace_class { 'SimpleStrategy': { $replication_factor = $replication_map[replication_factor] $map_str = "{ 'class' : 'SimpleStrategy', 'replication_factor' : ${replication_factor} }" } 'NetworkTopologyStrategy': { $map_str1 = "{ 'class' : 'NetworkTopologyStrategy'" $new_map = prefix(delete($replication_map, 'keyspace_class'), "'") $map_str2 = join(join_keys_to_values($new_map, "': "), ', ') $map_str = "${map_str1}, ${map_str2} }" } default: { $msg_part1 = "Invalid or no class (${keyspace_class}) specified for" $msg_part2 = "keyspace ${keyspace_name}." fail("${msg_part1} ${msg_part2}") } } $create_script1 = "CREATE KEYSPACE IF NOT EXISTS ${keyspace_name}" $create_script2 = "WITH REPLICATION = ${map_str}" $create_script3 = "AND DURABLE_WRITES = ${durable_writes}" $create_script = "${create_script1} ${create_script2} ${create_script3}" - $create_command = "${::cassandra::schema::cqlsh_opts} -e \"${create_script}\" ${::cassandra::schema::cqlsh_conn}" - + $create_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${create_script}${quote} ${::cassandra::schema::cqlsh_conn}" + if $use_scl { + $create_command = "/usr/bin/scl enable ${scl_name} \"${create_command_tmp}\"" + } else { + $create_command = $create_command_tmp + } exec { $create_command: unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { $delete_script = "DROP KEYSPACE ${keyspace_name}" - $delete_command = "${::cassandra::schema::cqlsh_opts} -e \"${delete_script}\" ${::cassandra::schema::cqlsh_conn}" + $delete_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${::cassandra::schema::cqlsh_conn}" + if $use_scl { + $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" + } else { + $delete_command = $delete_command_tmp + } exec { $delete_command: onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/spec/defines/schema/keyspace_spec.rb b/spec/defines/schema/keyspace_spec.rb index 83130d3..616f8c2 100644 --- a/spec/defines/schema/keyspace_spec.rb +++ b/spec/defines/schema/keyspace_spec.rb @@ -1,105 +1,219 @@ require 'spec_helper' describe 'cassandra::schema::keyspace' do context 'Set ensure to present (SimpleStrategy)' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'foobar' } let(:params) do { ensure: 'present', replication_map: { 'keyspace_class' => 'SimpleStrategy', 'replication_factor' => 3 }, use_scl: false, scl_name: 'nodefault' } end it do is_expected.to compile is_expected.to contain_class('cassandra::schema') - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = { \'class\' : \'SimpleStrategy\', \'replication_factor\' : 3 } AND DURABLE_WRITES = true" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC KEYSPACE foobar" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = ' + exec_command += '{ \'class\' : \'SimpleStrategy\', \'replication_factor\' : 3 } ' + exec_command += 'AND DURABLE_WRITES = true" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Set ensure to present (SimpleStrategy) with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'foobar' } + + let(:params) do + { + ensure: 'present', + replication_map: + { + 'keyspace_class' => 'SimpleStrategy', + 'replication_factor' => 3 + }, + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to compile + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC KEYSPACE foobar\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = ' + exec_command += '{ \'class\' : \'SimpleStrategy\', \'replication_factor\' : 3 } ' + exec_command += 'AND DURABLE_WRITES = true\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Set ensure to present (NetworkTopologyStrategy)' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'foobar' } let(:params) do { ensure: 'present', replication_map: { 'keyspace_class' => 'NetworkTopologyStrategy', 'dc1' => '3', 'dc2' => '2' }, use_scl: false, scl_name: 'nodefault' } end it do is_expected.to contain_cassandra__schema__keyspace('foobar') - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = { \'class\' : \'NetworkTopologyStrategy\', \'dc1\': 3, \'dc2\': 2 } AND DURABLE_WRITES = true" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC KEYSPACE foobar" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = ' + exec_command += '{ \'class\' : \'NetworkTopologyStrategy\', \'dc1\': 3, \'dc2\': 2 } ' + exec_command += 'AND DURABLE_WRITES = true" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Set ensure to present (NetworkTopologyStrategy) with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'foobar' } + + let(:params) do + { + ensure: 'present', + replication_map: + { + 'keyspace_class' => 'NetworkTopologyStrategy', + 'dc1' => '3', + 'dc2' => '2' + }, + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to contain_cassandra__schema__keyspace('foobar') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC KEYSPACE foobar\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE KEYSPACE IF NOT EXISTS foobar WITH REPLICATION = ' + exec_command += '{ \'class\' : \'NetworkTopologyStrategy\', \'dc1\': 3, \'dc2\': 2 } ' + exec_command += 'AND DURABLE_WRITES = true\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Set ensure to absent' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'foobar' } let(:params) do { ensure: 'absent', use_scl: false, scl_name: 'nodefault' } end it do is_expected.to compile - is_expected.to contain_exec('/usr/bin/cqlsh -e "DROP KEYSPACE foobar" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC KEYSPACE foobar" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "DROP KEYSPACE foobar" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Set ensure to absent with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'foobar' } + let(:params) do + { + ensure: 'absent', + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to compile + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC KEYSPACE foobar\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP KEYSPACE foobar\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') end 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 { is_expected.to raise_error(Puppet::Error) } end end