diff --git a/manifests/params.pp b/manifests/params.pp index fb461de..c94f127 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,58 +1,60 @@ # This class is meant to be called from the locp-cassandra module. # It sets variables according to platform. class cassandra::params { case $::osfamily { 'Debian': { case $::operatingsystemmajrelease { '12.04': { $net_ipv4_tcp_rmem = '4096 87380 16777216' $net_ipv4_tcp_wmem = '4096 65536 16777216' $java_package = 'openjdk-7-jre-headless' } '18.04': { $net_ipv4_tcp_rmem = '4096 87380 16777216' $net_ipv4_tcp_wmem = '4096 65536 16777216' $java_package = 'openjdk-8-jre-headless' } # non-Ubuntu Debian is just... Debian default: { $net_ipv4_tcp_rmem = '4096, 87380, 16777216' $net_ipv4_tcp_wmem = '4096, 65536, 16777216' $java_package = 'openjdk-7-jre-headless' } } $cassandra_pkg = 'cassandra' $config_path = '/etc/cassandra' $jna_package_name = 'libjna-java' $optutils_package_name = 'cassandra-tools' $sysctl_file = '/etc/sysctl.d/10-cassandra.conf' $systemctl = '/bin/systemctl' } 'RedHat': { case $::operatingsystemmajrelease { 6: { $net_ipv4_tcp_rmem = '4096 87380 16777216' $net_ipv4_tcp_wmem = '4096 65536 16777216' $sysctl_file = '/etc/sysctl.conf' } 7: { $net_ipv4_tcp_rmem = '4096, 87380, 16777216' $net_ipv4_tcp_wmem = '4096, 65536, 16777216' $sysctl_file = '/etc/sysctl.d/10-cassandra.conf' } default: {} } $cassandra_pkg = 'cassandra22' $config_path = '/etc/cassandra/default.conf' $java_package = 'java-1.8.0-openjdk-headless' $jna_package_name = 'jna' $optutils_package_name = 'cassandra22-tools' $systemctl = '/usr/bin/systemctl' + $use_scl = false + $scl_name = 'nodefault' } default: { $config_path_parents = [] } } } diff --git a/manifests/schema.pp b/manifests/schema.pp index da37de0..94ee13f 100644 --- a/manifests/schema.pp +++ b/manifests/schema.pp @@ -1,128 +1,142 @@ # A class to maintain the database schema. Please note that cqlsh expects # Python 2.7 to be installed. This may be a problem of older distributions # (CentOS 6 for example). # @param connection_tries [integer] How many times do try to connect to # Cassandra. See also `connection_try_sleep`. # @param connection_try_sleep [integer] How much time to allow between the # number of tries specified in `connection_tries`. # @param cql_types [hash] Creates new `cassandra::schema::cql_type` resources. # @param cqlsh_additional_options [string] Any additional options to be passed # to the `cqlsh` command. # @param cqlsh_client_config [string] Set this to a file name # (e.g. '/root/.puppetcqlshrc') that will then be used to contain the # the credentials for connecting to Cassandra. This is a more secure option # than having the credentials appearing on the command line. This option # is only available in Cassandra >= 2.1. # @param cqlsh_client_tmpl [string] The location of the template for configuring # the credentials for the cqlsh client. This is ignored unless # `cqlsh_client_config` is set. # @param cqlsh_command [string] The full path to the `cqlsh` command. # @param cqlsh_host [string] The host for the `cqlsh` command to connect to. # See also `cqlsh_port`. # @param cqlsh_password [string] If credentials are require for connecting, # specify the password here. See also `cqlsh_user`, `cqlsh_client_config`. # @param cqlsh_port [integer] The host for the `cqlsh` command to connect to. # See also `cqlsh_host`. # @param cqlsh_user [string] If credentials are required for connecting, # specify the password here. See also `cqlsh_password`, # `cqlsh_client_config` # @param indexes [hash] Creates new `cassandra::schema::index` resources. # @param keyspaces [hash] Creates new `cassandra::schema::keyspace` resources. # @param permissions [hash] Creates new `cassandra::schema::permission` # resources. # @param tables [hash] Creates new `cassandra::schema::table` resources. # @param users [hash] Creates new `cassandra::schema::user` resources. class cassandra::schema ( $connection_tries = 6, $connection_try_sleep = 30, $cql_types = {}, $cqlsh_additional_options = '', $cqlsh_client_config = undef, $cqlsh_client_tmpl = 'cassandra/cqlshrc.erb', $cqlsh_command = '/usr/bin/cqlsh', $cqlsh_host = 'localhost', $cqlsh_password = undef, $cqlsh_port = 9042, $cqlsh_user = 'cassandra', $indexes = {}, $keyspaces = {}, $permissions = {}, $tables = {}, $users = {}, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ) inherits cassandra::params { require '::cassandra' + # Pass the SCL info to create_resources below as a hash + $scl = { + 'use_scl' => $use_scl, + 'scl_name' => $scl_name, + } + if $cqlsh_client_config != undef { file { $cqlsh_client_config : ensure => file, group => $::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, } # manage keyspaces if present if $keyspaces { - create_resources('cassandra::schema::keyspace', $keyspaces) + create_resources('cassandra::schema::keyspace', $keyspaces, $scl) } # manage cql_types if present if $cql_types { - create_resources('cassandra::schema::cql_type', $cql_types) + create_resources('cassandra::schema::cql_type', $cql_types, $scl) } # manage tables if present if $tables { - create_resources('cassandra::schema::table', $tables) + create_resources('cassandra::schema::table', $tables, $scl) } # manage indexes if present if $indexes { - create_resources('cassandra::schema::index', $indexes) + create_resources('cassandra::schema::index', $indexes, $scl) } # manage users if present if $users { - create_resources('cassandra::schema::user', $users) + create_resources('cassandra::schema::user', $users, $scl) } # manage permissions if present if $permissions { - create_resources('cassandra::schema::permission', $permissions) + create_resources('cassandra::schema::permission', $permissions, $scl) } # Resource Ordering Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Cql_type <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Keyspace <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Cql_type <| |> -> Cassandra::Schema::Table <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Index <| |> Cassandra::Schema::Table <| |> -> Cassandra::Schema::Permission <| |> Cassandra::Schema::Index <| |> -> Cassandra::Schema::User <| |> Cassandra::Schema::User <| |> -> Cassandra::Schema::Permission <| |> } diff --git a/manifests/schema/cql_type.pp b/manifests/schema/cql_type.pp index 961986a..043bbc1 100644 --- a/manifests/schema/cql_type.pp +++ b/manifests/schema/cql_type.pp @@ -1,43 +1,67 @@ # Create or drop user defined data types within the schema. # @param keyspace [string] The name of the keyspace that the data type is to be associated with. # @param ensure [present|absent] ensure the data type is created, or is dropped. # @param fields [hash] A hash of the fields that will be components for the data type. # @param cql_type_name [string] The name of the CQL type to be created. # @example # cassandra::schema::cql_type { 'fullname': # keyspace => 'mykeyspace', # fields => { # 'fname' => 'text', # 'lname' => 'text', # }, # } define cassandra::schema::cql_type ( $keyspace, $ensure = present, $fields = {}, $cql_type_name = $title, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ){ include 'cassandra::schema' + + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + $read_script = "DESC TYPE ${keyspace}.${cql_type_name}" - $read_command = "${::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 { $create_script1 = "CREATE TYPE IF NOT EXISTS ${keyspace}.${cql_type_name}" $create_script2 = join(join_keys_to_values($fields, ' '), ', ') $create_script = "${create_script1} (${create_script2})" - $create_command = "${::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 type ${keyspace}.${cql_type_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/manifests/schema/index.pp b/manifests/schema/index.pp index c5efce1..897f45b 100644 --- a/manifests/schema/index.pp +++ b/manifests/schema/index.pp @@ -1,67 +1,90 @@ # Create or drop indexes within the schema. # @param ensure [present|absent] Create or dro[ the index. # @param class_name [string] The name of the class to be associated with an # index when creating a custom index. # @param index [string] The name of the index. Defaults to the name of the # resource. # @param keys [string] The columns that the index is being created on. # @param keyspace [string] The name the keyspace that the index is to be associated # with. # @param options [string] Any options to be added to the index. # @param table [string] The name of the table that the index is to be associated with. define cassandra::schema::index( $keyspace, $table, $ensure = present, $class_name = undef, $index = $title, $keys = undef, $options = undef, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ) { include 'cassandra::schema' + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + # Fully qualified index name. $fqin = "${keyspace}.${index}" # Fully qualified table name. $fqtn = "${keyspace}.${table}" $read_script = "DESC INDEX ${fqin}" - $read_command = "${::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 { if $class_name != undef { $create_part1 = "CREATE CUSTOM INDEX IF NOT EXISTS ${index} ON ${keyspace}.${table}" } else { $create_part1 = "CREATE INDEX IF NOT EXISTS ${index} ON ${keyspace}.${table}" } if $class_name != undef { $create_part2 = "${create_part1} (${keys}) USING '${class_name}'" } else { $create_part2 = "${create_part1} (${keys})" } if $options != undef { $create_script = "${create_part2} WITH OPTIONS = ${options}" } else { $create_script = $create_part2 } - $create_command = "${::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 INDEX ${fqin}" - $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/manifests/schema/keyspace.pp b/manifests/schema/keyspace.pp index f42e637..87ec12e 100644 --- a/manifests/schema/keyspace.pp +++ b/manifests/schema/keyspace.pp @@ -1,76 +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 = {}, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ) { include 'cassandra::schema' + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + $read_script = "DESC KEYSPACE ${keyspace_name}" - $read_command = "${::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/manifests/schema/permission.pp b/manifests/schema/permission.pp index 1dfbea3..d2415da 100644 --- a/manifests/schema/permission.pp +++ b/manifests/schema/permission.pp @@ -1,127 +1,161 @@ # Grant or revoke permissions. # To use this class, a suitable `authenticator` (e.g. PasswordAuthenticator) # and `authorizer` (e.g. CassandraAuthorizer) must be set in the Cassandra # class. # # WARNING: Specifying keyspace 'ALL' and 'ALL' for permissions at the same # time is not currently supported by this module. # # @param user_name [string] The name of the user who is to be granted or # revoked. # @param ensure [ present | absent ] Set to present to grant a permission or # absent to revoke it. # @param keyspace_name [string] The name of the keyspace to grant/revoke the # permissions on. If set to 'ALL' then the permission will be applied to # all of the keyspaces. # @param permission_name [string] Can be one of the following: # # * 'ALTER' - ALTER KEYSPACE, ALTER TABLE, CREATE INDEX, DROP INDEX. # * 'AUTHORIZE' - GRANT, REVOKE. # * 'CREATE' - CREATE KEYSPACE, CREATE TABLE. # * 'DROP' - DROP KEYSPACE, DROP TABLE. # * 'MODIFY' - INSERT, DELETE, UPDATE, TRUNCATE. # * 'SELECT' - SELECT. # # If the permission_name is set to 'ALL', this will set all of the specific # permissions listed. # @param table_name [string] The name of a table within the specified # keyspace. If left unspecified, the procedure will be applied to all # tables within the keyspace. define cassandra::schema::permission ( $user_name, $ensure = present, $keyspace_name = 'ALL', $permission_name = 'ALL', $table_name = undef, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ){ include 'cassandra::schema' + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + if upcase($keyspace_name) == 'ALL' and upcase($permission_name) == 'ALL' { fail('"ALL" keyspaces AND "ALL" permissions are mutually exclusive.') } elsif $table_name { $resource = "TABLE ${keyspace_name}.${table_name}" } elsif upcase($keyspace_name) == 'ALL' { $resource = 'ALL KEYSPACES' } else { $resource = "KEYSPACE ${keyspace_name}" } $read_script = "LIST ALL PERMISSIONS ON ${resource}" $upcase_permission_name = upcase($permission_name) $pattern = "\s${user_name} |\s*${user_name} |\s.*\s${upcase_permission_name}$" - $read_command = "${::cassandra::schema::cqlsh_opts} -e \"${read_script}\" ${::cassandra::schema::cqlsh_conn} | grep '${pattern}'" + $read_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${::cassandra::schema::cqlsh_conn} | grep '${pattern}'" + if $use_scl { + $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" + } else { + $read_command = $read_command_tmp + } if upcase($permission_name) == 'ALL' { cassandra::schema::permission { "${title} - ALTER": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'ALTER', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } cassandra::schema::permission { "${title} - AUTHORIZE": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'AUTHORIZE', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } # The CREATE permission is not relevant to tables. if !$table_name { cassandra::schema::permission { "${title} - CREATE": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'CREATE', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } } cassandra::schema::permission { "${title} - DROP": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'DROP', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } cassandra::schema::permission { "${title} - MODIFY": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'MODIFY', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } cassandra::schema::permission { "${title} - SELECT": ensure => $ensure, user_name => $user_name, keyspace_name => $keyspace_name, permission_name => 'SELECT', table_name => $table_name, + use_scl => $use_scl, + scl_name => $scl_name, } } elsif $ensure == present { $create_script = "GRANT ${permission_name} ON ${resource} TO ${user_name}" - $create_command = "${::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_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}" + $delete_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${delete_script}${quote} ${::cassandra::schema::cqlsh_conn}" + if $use_scl { + $delete_command = "/usr/bin/scl enable ${scl_name} \"${delete_command_tmp}\"" + } else { + $delete_command = $delete_command_tmp + } exec { $delete_script: command => $delete_command, onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/manifests/schema/table.pp b/manifests/schema/table.pp index b59f5cd..279d3f5 100644 --- a/manifests/schema/table.pp +++ b/manifests/schema/table.pp @@ -1,57 +1,81 @@ # Create or drop tables within the schema. # @param keyspace [string] The name of the keyspace. # @param columns [hash] A hash of the columns to be placed in the table. # Optional if the table is to be absent. # @param ensure [present|absent] Ensure a keyspace is created or dropped. # @param options [array] Options to be added to the table creation. # @param table [string] The name of the table. Defaults to the name of the # resource. # @example # cassandra::schema::table { 'users': # keyspace => 'mykeyspace', # columns => { # 'userid' => 'int', # 'fname' => 'text', # 'lname' => 'text', # 'PRIMARY KEY' => '(userid)', # }, # } define cassandra::schema::table ( $keyspace, $ensure = present, $columns = {}, $options = [], $table = $title, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ){ include 'cassandra::schema' + + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + $read_script = "DESC TABLE ${keyspace}.${table}" - $read_command = "${::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 { $create_script1 = "CREATE TABLE IF NOT EXISTS ${keyspace}.${table}" $cols_def = join(join_keys_to_values($columns, ' '), ', ') $cols_def_rm_collection_type = delete($cols_def, 'COLLECTION-TYPE ') if count($options) > 0 { $options_def = join($options, ' AND ') $create_script = "${create_script1} (${cols_def_rm_collection_type}) WITH ${options_def}" } else { $create_script = "${create_script1} (${cols_def_rm_collection_type})" } - $create_command = "${::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 TABLE IF EXISTS ${keyspace}.${table}" - $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/manifests/schema/user.pp b/manifests/schema/user.pp index 00a4ce6..a2216bc 100644 --- a/manifests/schema/user.pp +++ b/manifests/schema/user.pp @@ -1,115 +1,137 @@ # Create or drop users. # To use this class, a suitable `authenticator` (e.g. PasswordAuthenticator) # must be set in the Cassandra class. # @param ensure [ present | absent ] Valid values can be **present** to # ensure a user is created, or **absent** to remove the user if it exists. # @param password [string] A password for the user. # @param superuser [boolean] If the user is to be a super-user on the system. # @param login [boolean] Allows the role to log in. # @param user_name [string] The name of the user. # @example # cassandra::schema::user { 'akers': # password => 'Niner2', # superuser => true, # } # # cassandra::schema::user { 'lucan': # ensure => absent, # } define cassandra::schema::user ( $ensure = present, $login = true, $password = undef, $superuser = false, $user_name = $title, + Boolean $use_scl = $cassandra::params::use_scl, + String[1] $scl_name = $cassandra::params::scl_name, ){ include 'cassandra::schema' + if $use_scl { + $quote = '\"' + } else { + $quote = '"' + } + if $::cassandrarelease != undef { if versioncmp($::cassandrarelease, '2.2') < 0 { $operate_with_roles = false } else { $operate_with_roles = true } } else { $operate_with_roles = false } if $operate_with_roles { $read_script = 'LIST ROLES' } else { $read_script = 'LIST USERS' } - $read_command = "${::cassandra::schema::cqlsh_opts} -e \"${read_script}\" ${::cassandra::schema::cqlsh_conn} | grep '\s*${user_name} |'" + $str_match = '\s' + $read_command_tmp = "${::cassandra::schema::cqlsh_opts} -e ${quote}${read_script}${quote} ${::cassandra::schema::cqlsh_conn} | grep '${str_match}*${user_name} |'" + if $use_scl { + $read_command = "/usr/bin/scl enable ${scl_name} \"${read_command_tmp}\"" + } else { + $read_command = $read_command_tmp + } if $ensure == present { if $operate_with_roles { # we are running cassandra > 2.2 $create_script1 = "CREATE ROLE IF NOT EXISTS ${user_name}" if $password != undef { $create_script2 = "${create_script1} WITH PASSWORD = '${password}'" } else { $create_script2 = $create_script1 } if $superuser { if $password != undef { $create_script3 = "${create_script2} AND SUPERUSER = true" } else { $create_script3 = "${create_script2} WITH SUPERUSER = true" } } else { $create_script3 = $create_script2 } if $login { if $superuser or $password != undef { $create_script = "${create_script3} AND LOGIN = true" } else { $create_script = "${create_script3} WITH LOGIN = true" } } else { $create_script = $create_script3 } } else { $create_script1 = "CREATE USER IF NOT EXISTS ${user_name}" if $password != undef { $create_script2 = "${create_script1} WITH PASSWORD '${password}'" } else { $create_script2 = $create_script1 } if $superuser { $create_script = "${create_script2} SUPERUSER" } else { $create_script = "${create_script2} NOSUPERUSER" } } - $create_command = "${::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 user (${user_name})": command => $create_command, unless => $read_command, require => Exec['::cassandra::schema connection test'], } } elsif $ensure == absent { if $operate_with_roles { $delete_script = "DROP ROLE ${user_name}" } else { $delete_script = "DROP USER ${user_name}" } - $delete_command = "${::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 user (${user_name})": command => $delete_command, onlyif => $read_command, require => Exec['::cassandra::schema connection test'], } } else { fail("Unknown action (${ensure}) for ensure attribute.") } } diff --git a/spec/classes/schema_spec.rb b/spec/classes/schema_spec.rb index d468623..727a48f 100644 --- a/spec/classes/schema_spec.rb +++ b/spec/classes/schema_spec.rb @@ -1,131 +1,172 @@ 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) + 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' + 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' + 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 diff --git a/spec/defines/schema/cql_type_spec.rb b/spec/defines/schema/cql_type_spec.rb index 9e9b4ee..54ec3eb 100644 --- a/spec/defines/schema/cql_type_spec.rb +++ b/spec/defines/schema/cql_type_spec.rb @@ -1,73 +1,151 @@ require 'spec_helper' describe 'cassandra::schema::cql_type' do context 'CQL TYPE (fullname)' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'fullname' } let(:params) do { 'keyspace' => 'Excelsior', fields: { 'firstname' => 'text', 'lastname' => 'text' - } + }, + 'use_scl' => false, + 'scl_name' => 'nodefault' } end it do is_expected.to compile is_expected.to contain_class('cassandra::schema') is_expected.to contain_cassandra__schema__cql_type('fullname') - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE TYPE IF NOT EXISTS Excelsior.fullname (firstname text, lastname text)" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC TYPE Excelsior.fullname" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE TYPE IF NOT EXISTS Excelsior.fullname ' + exec_command += '(firstname text, lastname text)" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'CQL TYPE (fullname) with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'fullname' } + + let(:params) do + { + 'keyspace' => 'Excelsior', + fields: + { + 'firstname' => 'text', + 'lastname' => 'text' + }, + 'use_scl' => true, + 'scl_name' => 'testscl' + } + end + + it do + is_expected.to compile + is_expected.to contain_class('cassandra::schema') + is_expected.to contain_cassandra__schema__cql_type('fullname') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC TYPE Excelsior.fullname\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE TYPE IF NOT EXISTS Excelsior.fullname ' + exec_command += '(firstname text, lastname text)\" 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) { 'address' } let(:params) do { 'ensure' => 'absent', - 'keyspace' => 'Excalibur' + 'keyspace' => 'Excalibur', + 'use_scl' => false, + 'scl_name' => 'nodefault' + } + end + + it do + is_expected.to compile + is_expected.to contain_cassandra__schema__cql_type('address') + read_command = '/usr/bin/cqlsh -e "DESC TYPE Excalibur.address" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "DROP type Excalibur.address" 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) { 'address' } + let(:params) do + { + 'ensure' => 'absent', + 'keyspace' => 'Excalibur', + 'use_scl' => true, + 'scl_name' => 'testscl' } end it do is_expected.to compile is_expected.to contain_cassandra__schema__cql_type('address') - is_expected.to contain_exec('/usr/bin/cqlsh -e "DROP type Excalibur.address" localhost 9042') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC TYPE Excalibur.address\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP type Excalibur.address\" 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 diff --git a/spec/defines/schema/index_spec.rb b/spec/defines/schema/index_spec.rb index f45d716..930e580 100644 --- a/spec/defines/schema/index_spec.rb +++ b/spec/defines/schema/index_spec.rb @@ -1,121 +1,275 @@ require 'spec_helper' describe 'cassandra::schema::index' do context 'Create a basic index' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'user_index' } let(:params) do { keys: 'lname', keyspace: 'mykeyspace', - table: 'users' + table: 'users', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to compile is_expected.to contain_cassandra__schema__index('user_index') - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE INDEX IF NOT EXISTS user_index ON mykeyspace.users (lname)" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC INDEX mykeyspace.user_index" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE INDEX IF NOT EXISTS user_index ON mykeyspace.users (lname)" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a basic index with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'user_index' } + + let(:params) do + { + keys: 'lname', + keyspace: 'mykeyspace', + table: 'users', + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to compile + is_expected.to contain_cassandra__schema__index('user_index') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC INDEX mykeyspace.user_index\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE INDEX IF NOT EXISTS user_index ON mykeyspace.users (lname)\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Create a custom index.' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'user_index' } let(:params) do { class_name: 'path.to.the.IndexClass', keys: 'email', keyspace: 'Excelsior', - table: 'users' + table: 'users', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to compile - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE CUSTOM INDEX IF NOT EXISTS user_index ON Excelsior.users (email) USING \'path.to.the.IndexClass\'" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC INDEX Excelsior.user_index" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE CUSTOM INDEX IF NOT EXISTS user_index ON Excelsior.users (email) USING \'path.to.the.IndexClass\'" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end + + context 'Create a custom index with SCL.' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'user_index' } + + let(:params) do + { + class_name: 'path.to.the.IndexClass', + keys: 'email', + keyspace: 'Excelsior', + table: 'users', + 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 INDEX Excelsior.user_index\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE CUSTOM INDEX IF NOT EXISTS user_index ON Excelsior.users (email) USING \'path.to.the.IndexClass\'\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + context 'Create a custom index with options.' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'user_index' } let(:params) do { class_name: 'path.to.the.IndexClass', keys: 'email', keyspace: 'Excelsior', options: "{'storage': '/mnt/ssd/indexes/'}", - table: 'users' + table: 'users', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to compile - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE CUSTOM INDEX IF NOT EXISTS user_index ON Excelsior.users (email) USING \'path.to.the.IndexClass\' WITH OPTIONS = {\'storage\': \'/mnt/ssd/indexes/\'}" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC INDEX Excelsior.user_index" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE CUSTOM INDEX IF NOT EXISTS user_index ON ' + exec_command += 'Excelsior.users (email) USING \'path.to.the.IndexClass\' WITH OPTIONS = {' + exec_command += '\'storage\': \'/mnt/ssd/indexes/\'}" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a custom index with options with SCL.' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'user_index' } + + let(:params) do + { + class_name: 'path.to.the.IndexClass', + keys: 'email', + keyspace: 'Excelsior', + options: "{'storage': '/mnt/ssd/indexes/'}", + table: 'users', + 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 INDEX Excelsior.user_index\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE CUSTOM INDEX IF NOT EXISTS user_index ON ' + exec_command += 'Excelsior.users (email) USING \'path.to.the.IndexClass\' WITH OPTIONS = {' + exec_command += '\'storage\': \'/mnt/ssd/indexes/\'}\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Drop Index' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'user_index' } let(:params) do { ensure: 'absent', keys: 'lname', keyspace: 'Excelsior', - table: 'users' + table: 'users', + use_scl: false, + scl_name: 'nodefault' + } + end + + it do + is_expected.to compile + read_command = '/usr/bin/cqlsh -e "DESC INDEX Excelsior.user_index" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "DROP INDEX Excelsior.user_index" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Drop Index with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'user_index' } + + let(:params) do + { + ensure: 'absent', + keys: 'lname', + keyspace: 'Excelsior', + table: 'users', + use_scl: true, + scl_name: 'testscl' } end it do is_expected.to compile - is_expected.to contain_exec('/usr/bin/cqlsh -e "DROP INDEX Excelsior.user_index" localhost 9042') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC INDEX Excelsior.user_index\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP INDEX Excelsior.user_index\" 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 diff --git a/spec/defines/schema/keyspace_spec.rb b/spec/defines/schema/keyspace_spec.rb index 25b9213..616f8c2 100644 --- a/spec/defines/schema/keyspace_spec.rb +++ b/spec/defines/schema/keyspace_spec.rb @@ -1,99 +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' + ensure: 'absent', + use_scl: false, + scl_name: 'nodefault' + } + end + + it do + is_expected.to compile + 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 - is_expected.to contain_exec('/usr/bin/cqlsh -e "DROP KEYSPACE foobar" localhost 9042') + 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 diff --git a/spec/defines/schema/permission_spec.rb b/spec/defines/schema/permission_spec.rb index 7bd53c8..44cf719 100644 --- a/spec/defines/schema/permission_spec.rb +++ b/spec/defines/schema/permission_spec.rb @@ -1,174 +1,399 @@ require 'spec_helper' describe 'cassandra::schema::permission' do 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 { is_expected.to 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 { is_expected.to 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' + permission_name: 'SELECT', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to have_resource_count(9) is_expected.to contain_cassandra__schema__permission('spillman:SELECT:ALL') - is_expected.to contain_exec('GRANT SELECT ON ALL KEYSPACES TO spillman') + read_script = '/usr/bin/cqlsh -e "LIST ALL PERMISSIONS ON ALL KEYSPACES" ' + read_script += 'localhost 9042 | grep \' spillman | *spillman | .* SELECT$\'' + script_command = 'GRANT SELECT ON ALL KEYSPACES TO spillman' + exec_command = "/usr/bin/cqlsh -e \"#{script_command}\" localhost 9042" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'spillman:SELECT:ALL with SCL' do + let(:title) { 'spillman:SELECT:ALL' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { + user_name: 'spillman', + permission_name: 'SELECT', + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to have_resource_count(9) + is_expected.to contain_cassandra__schema__permission('spillman:SELECT:ALL') + read_script = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ALL PERMISSIONS ON ALL KEYSPACES\" ' + read_script += 'localhost 9042 | grep \' spillman | *spillman | .* SELECT$\'"' + script_command = 'GRANT SELECT ON ALL KEYSPACES TO spillman' + exec_command = "/usr/bin/scl enable testscl \"/usr/bin/cqlsh -e \\\"#{script_command}\\\" localhost 9042\"" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') 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' + permission_name: 'MODIFY', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to have_resource_count(9) is_expected.to contain_cassandra__schema__permission('akers:modify:field') - is_expected.to contain_exec('GRANT MODIFY ON KEYSPACE field TO akers') + read_script = '/usr/bin/cqlsh -e "LIST ALL PERMISSIONS ON KEYSPACE field" ' + read_script += 'localhost 9042 | grep \' akers | *akers | .* MODIFY$\'' + script_command = 'GRANT MODIFY ON KEYSPACE field TO akers' + exec_command = "/usr/bin/cqlsh -e \"#{script_command}\" localhost 9042" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'akers:modify:field with SCL' 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', + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to have_resource_count(9) + is_expected.to contain_cassandra__schema__permission('akers:modify:field') + read_script = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ALL PERMISSIONS ON KEYSPACE field\" ' + read_script += 'localhost 9042 | grep \' akers | *akers | .* MODIFY$\'"' + script_command = 'GRANT MODIFY ON KEYSPACE field TO akers' + exec_command = "/usr/bin/scl enable testscl \"/usr/bin/cqlsh -e \\\"#{script_command}\\\" localhost 9042\"" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') 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' + permission_name: 'ALTER', + use_scl: false, + scl_name: 'nodefault' + } + end + + it do + is_expected.to have_resource_count(9) + is_expected.to contain_cassandra__schema__permission('boone:alter:forty9ers') + read_script = '/usr/bin/cqlsh -e "LIST ALL PERMISSIONS ON KEYSPACE forty9ers" ' + read_script += 'localhost 9042 | grep \' boone | *boone | .* ALTER$\'' + script_command = 'GRANT ALTER ON KEYSPACE forty9ers TO boone' + exec_command = "/usr/bin/cqlsh -e \"#{script_command}\" localhost 9042" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'boone:alter:forty9ers with SCL' 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', + use_scl: true, + scl_name: 'testscl' } end it do is_expected.to have_resource_count(9) is_expected.to contain_cassandra__schema__permission('boone:alter:forty9ers') - is_expected.to contain_exec('GRANT ALTER ON KEYSPACE forty9ers TO boone') + read_script = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ALL PERMISSIONS ON KEYSPACE forty9ers\" ' + read_script += 'localhost 9042 | grep \' boone | *boone | .* ALTER$\'"' + script_command = 'GRANT ALTER ON KEYSPACE forty9ers TO boone' + exec_command = "/usr/bin/scl enable testscl \"/usr/bin/cqlsh -e \\\"#{script_command}\\\" localhost 9042\"" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') 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' + table_name: 'plays', + use_scl: false, + scl_name: 'nodefault' } end it do is_expected.to have_resource_count(18) is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays') - is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays - ALTER').with( - ensure: 'present', + end + + expected_values = %w[ALTER AUTHORIZE DROP MODIFY SELECT] + expected_values.each do |val| + it do + is_expected.to contain_cassandra__schema__permission("boone:ALL:ravens.plays - #{val}").with( + ensure: 'present', + user_name: 'boone', + keyspace_name: 'ravens', + permission_name: val, + table_name: 'plays' + ) + end + read_script = '/usr/bin/cqlsh -e "LIST ALL PERMISSIONS ON TABLE ravens.plays" ' + read_script += "localhost 9042 | grep ' boone | *boone | .* #{val}$'" + script_command = "GRANT #{val} ON TABLE ravens.plays TO boone" + exec_command = "/usr/bin/cqlsh -e \"#{script_command}\" localhost 9042" + it do + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') + end + end + end + + context 'boone:ALL:ravens.plays with SCL' do + let(:title) { 'boone:ALL:ravens.plays' } + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:params) do + { user_name: 'boone', keyspace_name: 'ravens', - permission_name: 'ALTER', - table_name: 'plays' - ) - is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays - AUTHORIZE') - is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays - DROP') - is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays - MODIFY') - is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays - SELECT') - is_expected.to contain_exec('GRANT ALTER ON TABLE ravens.plays TO boone') - is_expected.to contain_exec('GRANT AUTHORIZE ON TABLE ravens.plays TO boone') - is_expected.to contain_exec('GRANT DROP ON TABLE ravens.plays TO boone') - is_expected.to contain_exec('GRANT MODIFY ON TABLE ravens.plays TO boone') - is_expected.to contain_exec('GRANT SELECT ON TABLE ravens.plays TO boone') + table_name: 'plays', + use_scl: true, + scl_name: 'testscl' + } + end + + it do + is_expected.to have_resource_count(18) + is_expected.to contain_cassandra__schema__permission('boone:ALL:ravens.plays') + end + + expected_values = %w[ALTER AUTHORIZE DROP MODIFY SELECT] + expected_values.each do |val| + it do + is_expected.to contain_cassandra__schema__permission("boone:ALL:ravens.plays - #{val}").with( + ensure: 'present', + user_name: 'boone', + keyspace_name: 'ravens', + permission_name: val, + table_name: 'plays' + ) + end + read_script = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ALL PERMISSIONS ON TABLE ravens.plays\" ' + read_script += "localhost 9042 | grep ' boone | *boone | .* #{val}$'\"" + script_command = "GRANT #{val} ON TABLE ravens.plays TO boone" + exec_command = "/usr/bin/scl enable testscl \"/usr/bin/cqlsh -e \\\"#{script_command}\\\" localhost 9042\"" + it do + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + unless: read_script, + require: 'Exec[::cassandra::schema connection test]') + end 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' + permission_name: 'SELECT', + use_scl: false, + scl_name: 'nodefault' + } + end + + it do + is_expected.to have_resource_count(9) + is_expected.to contain_cassandra__schema__permission('REVOKE boone:SELECT:ravens.plays') + read_script = '/usr/bin/cqlsh -e "LIST ALL PERMISSIONS ON KEYSPACE forty9ers" ' + read_script += "localhost 9042 | grep ' boone | *boone | .* SELECT$'" + script_command = 'REVOKE SELECT ON KEYSPACE forty9ers FROM boone' + exec_command = "/usr/bin/cqlsh -e \"#{script_command}\" localhost 9042" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + onlyif: read_script, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'REVOKE boone:SELECT:ravens.plays with SCL' 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', + use_scl: true, + scl_name: 'testscl' } end it do is_expected.to have_resource_count(9) is_expected.to contain_cassandra__schema__permission('REVOKE boone:SELECT:ravens.plays') - is_expected.to contain_exec('REVOKE SELECT ON KEYSPACE forty9ers FROM boone') + read_script = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ALL PERMISSIONS ON KEYSPACE forty9ers\" ' + read_script += "localhost 9042 | grep ' boone | *boone | .* SELECT$'\"" + script_command = 'REVOKE SELECT ON KEYSPACE forty9ers FROM boone' + exec_command = "/usr/bin/scl enable testscl \"/usr/bin/cqlsh -e \\\"#{script_command}\\\" localhost 9042\"" + is_expected.to contain_exec(script_command). + only_with(command: exec_command, + onlyif: read_script, + require: 'Exec[::cassandra::schema connection test]') end end end diff --git a/spec/defines/schema/table_spec.rb b/spec/defines/schema/table_spec.rb index 73d15da..a84e914 100644 --- a/spec/defines/schema/table_spec.rb +++ b/spec/defines/schema/table_spec.rb @@ -1,82 +1,173 @@ require 'spec_helper' describe 'cassandra::schema::table' do context 'Create Table' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'users' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', keyspace: 'Excelsior', columns: { 'userid' => 'text', 'username' => 'FROZEN', 'emails' => 'set', 'top_scores' => 'list', 'todo' => 'map', 'COLLECTION-TYPE' => 'tuple', 'PRIMARY KEY' => '(userid)' }, options: [ 'COMPACT STORAGE', 'ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'' ] } end it do is_expected.to compile is_expected.to contain_cassandra__schema__table('users') - is_expected.to contain_exec('/usr/bin/cqlsh -e "CREATE TABLE IF NOT EXISTS Excelsior.users (userid text, username FROZEN, emails set, top_scores list, todo map, tuple, PRIMARY KEY (userid)) WITH COMPACT STORAGE AND ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'" localhost 9042') + read_command = '/usr/bin/cqlsh -e "DESC TABLE Excelsior.users" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "CREATE TABLE IF NOT EXISTS Excelsior.users ' + exec_command += '(userid text, username FROZEN, emails set, top_scores list, ' + exec_command += 'todo map, tuple, PRIMARY KEY (userid)) ' + exec_command += 'WITH COMPACT STORAGE AND ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create Table with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'users' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', + keyspace: 'Excelsior', + columns: + { + 'userid' => 'text', + 'username' => 'FROZEN', + 'emails' => 'set', + 'top_scores' => 'list', + 'todo' => 'map', + 'COLLECTION-TYPE' => 'tuple', + 'PRIMARY KEY' => '(userid)' + }, + options: + [ + 'COMPACT STORAGE', + 'ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'' + ] + } + end + + it do + is_expected.to compile + is_expected.to contain_cassandra__schema__table('users') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC TABLE Excelsior.users\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE TABLE IF NOT EXISTS Excelsior.users ' + exec_command += '(userid text, username FROZEN, emails set, top_scores list, ' + exec_command += 'todo map, tuple, PRIMARY KEY (userid)) ' + exec_command += 'WITH COMPACT STORAGE AND ID=\'5a1c395e-b41f-11e5-9f22-ba0be0483c18\'\" localhost 9042"' + is_expected.to contain_exec(exec_command). + only_with(unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Drop Table' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat' } end let(:title) { 'users' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', + keyspace: 'Excelsior', + ensure: 'absent' + } + end + + it do + is_expected.to compile + read_command = '/usr/bin/cqlsh -e "DESC TABLE Excelsior.users" localhost 9042' + exec_command = '/usr/bin/cqlsh -e "DROP TABLE IF EXISTS Excelsior.users" localhost 9042' + is_expected.to contain_exec(exec_command). + only_with(onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Drop Table with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat' + } + end + + let(:title) { 'users' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', keyspace: 'Excelsior', ensure: 'absent' } end it do is_expected.to compile - is_expected.to contain_exec('/usr/bin/cqlsh -e "DROP TABLE IF EXISTS Excelsior.users" localhost 9042') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DESC TABLE Excelsior.users\" localhost 9042"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP TABLE IF EXISTS Excelsior.users\" 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 diff --git a/spec/defines/schema/user_spec.rb b/spec/defines/schema/user_spec.rb index 9c7af1b..d0abf60 100644 --- a/spec/defines/schema/user_spec.rb +++ b/spec/defines/schema/user_spec.rb @@ -1,200 +1,459 @@ require 'spec_helper' describe 'cassandra::schema::user' do context 'Create a supper user on cassandrarelease undef' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: nil } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', password: 'Niner2', superuser: true } end it do is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') - is_expected.to contain_exec('Create user (akers)').with( - command: '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers WITH PASSWORD \'Niner2\' SUPERUSER" localhost 9042' - ) + read_command = '/usr/bin/cqlsh -e "LIST USERS" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' SUPERUSER" localhost 9042' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a supper user on cassandrarelease undef with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: nil + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', + password: 'Niner2', + superuser: true + } + end + + it do + is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST USERS\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' SUPERUSER\" localhost 9042"' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Create a supper user in cassandrarelease < 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '2.0.1' } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', + password: 'Niner2', + superuser: true + } + end + + it do + is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') + read_command = '/usr/bin/cqlsh -e "LIST USERS" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' SUPERUSER" localhost 9042' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a supper user in cassandrarelease < 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '2.0.1' + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', password: 'Niner2', superuser: true } end it do is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') - is_expected.to contain_exec('Create user (akers)').with( - command: '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers WITH PASSWORD \'Niner2\' SUPERUSER" localhost 9042' - ) + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST USERS\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' SUPERUSER\" localhost 9042"' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Create a user in cassandrarelease < 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '2.0.1' } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', + password: 'Niner2' + } + end + + it do + is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') + read_command = '/usr/bin/cqlsh -e "LIST USERS" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' NOSUPERUSER" localhost 9042' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a user in cassandrarelease < 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '2.0.1' + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', password: 'Niner2' } end it do is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') - is_expected.to contain_exec('Create user (akers)').with( - command: '/usr/bin/cqlsh -e "CREATE USER IF NOT EXISTS akers WITH PASSWORD \'Niner2\' NOSUPERUSER" localhost 9042' - ) + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST USERS\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE USER IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD \'Niner2\' NOSUPERUSER\" localhost 9042"' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Create a supper user with login in cassandrarelease > 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '3.0.9' } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', password: 'Niner2', superuser: true } end it do is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') - is_expected.to contain_exec('Create user (akers)').with( - command: '/usr/bin/cqlsh -e "CREATE ROLE IF NOT EXISTS akers WITH PASSWORD = \'Niner2\' AND SUPERUSER = true AND LOGIN = true" localhost 9042' - ) + read_command = '/usr/bin/cqlsh -e "LIST ROLES" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "CREATE ROLE IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD = \'Niner2\' AND SUPERUSER = true AND LOGIN = true" localhost 9042' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a supper user with login in cassandrarelease > 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '3.0.9' + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', + password: 'Niner2', + superuser: true + } + end + + it do + is_expected.to contain_cassandra__schema__user('akers').with_ensure('present') + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ROLES\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE ROLE IF NOT EXISTS akers' + exec_command += ' WITH PASSWORD = \'Niner2\' AND SUPERUSER = true AND LOGIN = true\" localhost 9042"' + is_expected.to contain_exec('Create user (akers)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Create a user without login in cassandrarelease > 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '3.0.9' } end let(:title) { 'bob' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', + password: 'kaZe89a', + login: false + } + end + + it do + is_expected.to contain_cassandra__schema__user('bob').with_ensure('present') + read_command = '/usr/bin/cqlsh -e "LIST ROLES" localhost 9042 | grep \'\s*bob |\'' + exec_command = '/usr/bin/cqlsh -e "CREATE ROLE IF NOT EXISTS bob' + exec_command += ' WITH PASSWORD = \'kaZe89a\'" localhost 9042' + is_expected.to contain_exec('Create user (bob)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Create a user without login in cassandrarelease > 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '3.0.9' + } + end + + let(:title) { 'bob' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', password: 'kaZe89a', login: false } end it do is_expected.to contain_cassandra__schema__user('bob').with_ensure('present') - is_expected.to contain_exec('Create user (bob)').with( - command: '/usr/bin/cqlsh -e "CREATE ROLE IF NOT EXISTS bob WITH PASSWORD = \'kaZe89a\'" localhost 9042' - ) + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ROLES\" localhost 9042 | grep \'\s*bob |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"CREATE ROLE IF NOT EXISTS bob' + exec_command += ' WITH PASSWORD = \'kaZe89a\'\" localhost 9042"' + is_expected.to contain_exec('Create user (bob)'). + only_with(command: exec_command, + unless: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Drop a user in cassandrarelease > 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '3.0.9' } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', password: 'Niner2', ensure: 'absent' } end it do - is_expected.to contain_exec('Delete user (akers)').with( - command: '/usr/bin/cqlsh -e "DROP ROLE akers" localhost 9042' - ) + read_command = '/usr/bin/cqlsh -e "LIST ROLES" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "DROP ROLE akers" localhost 9042' + is_expected.to contain_exec('Delete user (akers)'). + only_with(command: exec_command, + onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Drop a user in cassandrarelease > 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '3.0.9' + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', + password: 'Niner2', + ensure: 'absent' + } + end + + it do + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST ROLES\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP ROLE akers\" localhost 9042"' + is_expected.to contain_exec('Delete user (akers)'). + only_with(command: exec_command, + onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') end end context 'Drop a user in cassandrarelease < 2.2' do let :facts do { operatingsystemmajrelease: 7, osfamily: 'RedHat', cassandrarelease: '2.0.2' } end let(:title) { 'akers' } let(:params) do { + use_scl: false, + scl_name: 'nodefault', + password: 'Niner2', + ensure: 'absent' + } + end + + it do + read_command = '/usr/bin/cqlsh -e "LIST USERS" localhost 9042 | grep \'\s*akers |\'' + exec_command = '/usr/bin/cqlsh -e "DROP USER akers" localhost 9042' + is_expected.to contain_exec('Delete user (akers)'). + only_with(command: exec_command, + onlyif: read_command, + require: 'Exec[::cassandra::schema connection test]') + end + end + + context 'Drop a user in cassandrarelease < 2.2 with SCL' do + let :facts do + { + operatingsystemmajrelease: 7, + osfamily: 'RedHat', + cassandrarelease: '2.0.2' + } + end + + let(:title) { 'akers' } + + let(:params) do + { + use_scl: true, + scl_name: 'testscl', password: 'Niner2', ensure: 'absent' } end it do - is_expected.to contain_exec('Delete user (akers)').with( - command: '/usr/bin/cqlsh -e "DROP USER akers" localhost 9042' - ) + read_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"LIST USERS\" localhost 9042 | grep \'\s*akers |\'"' + exec_command = '/usr/bin/scl enable testscl "/usr/bin/cqlsh -e \"DROP USER akers\" localhost 9042"' + is_expected.to contain_exec('Delete user (akers)'). + only_with(command: exec_command, + 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