From 0e2d97e570a08576fde3f279053c38d1858f92b4 Mon Sep 17 00:00:00 2001 From: Steve Traylen Date: Tue, 16 Apr 2024 16:28:27 +0200 Subject: [PATCH] Support rich datatypes and deferred password values Process the configuration file `redis.conf` template twice if some of the templates values are deferred. Currently with deferred values the resulting deferred template cannot be processed since it contains complex datatypes from stdlib in particular. This is a redis specific solution that may arrive genraly one day in https://github.com/puppetlabs/puppetlabs-stdlib/pull/1425 --- manifests/instance.pp | 235 ++++++++++-------- .../suites/default/redis_deferred_spec.rb | 27 ++ 2 files changed, 155 insertions(+), 107 deletions(-) create mode 100644 spec/acceptance/suites/default/redis_deferred_spec.rb diff --git a/manifests/instance.pp b/manifests/instance.pp index 7eb5fdd0..3b18cfca 100644 --- a/manifests/instance.pp +++ b/manifests/instance.pp @@ -501,118 +501,139 @@ $bind_arr = [$bind].flatten + $_template_params = { + daemonize => $daemonize, + pid_file => $pid_file, + protected_mode => $protected_mode, + port => $port, + tcp_backlog => $tcp_backlog, + bind_arr => $bind_arr, + unixsocket => $unixsocket, + unixsocketperm => $unixsocketperm, + timeout => $timeout, + tcp_keepalive => $tcp_keepalive, + log_level => $log_level, + log_file => $_real_log_file, + syslog_enabled => $syslog_enabled, + syslog_facility => $syslog_facility, + databases => $databases, + save_db_to_disk => $save_db_to_disk, + save_db_to_disk_interval => $save_db_to_disk_interval, + stop_writes_on_bgsave_error => $stop_writes_on_bgsave_error, + rdbcompression => $rdbcompression, + dbfilename => $dbfilename, + workdir => $workdir, + slaveof => $slaveof, + replicaof => $replicaof, + masterauth => $masterauth, + slave_serve_stale_data => $slave_serve_stale_data, + slave_read_only => $slave_read_only, + repl_announce_ip => $repl_announce_ip, + repl_announce_port => $repl_announce_port, + repl_ping_slave_period => $repl_ping_slave_period, + repl_timeout => $repl_timeout, + repl_disable_tcp_nodelay => $repl_disable_tcp_nodelay, + repl_backlog_size => $repl_backlog_size, + repl_backlog_ttl => $repl_backlog_ttl, + slave_priority => $slave_priority, + min_slaves_to_write => $min_slaves_to_write, + min_slaves_max_lag => $min_slaves_max_lag, + requirepass => $requirepass, + rename_commands => $rename_commands, + maxclients => $maxclients, + maxmemory => $maxmemory, + maxmemory_policy => $maxmemory_policy, + maxmemory_samples => $maxmemory_samples, + appendonly => $appendonly, + appendfilename => $appendfilename, + appendfsync => $appendfsync, + no_appendfsync_on_rewrite => $no_appendfsync_on_rewrite, + auto_aof_rewrite_percentage => $auto_aof_rewrite_percentage, + auto_aof_rewrite_min_size => $auto_aof_rewrite_min_size, + aof_load_truncated => $aof_load_truncated, + slowlog_log_slower_than => $slowlog_log_slower_than, + slowlog_max_len => $slowlog_max_len, + latency_monitor_threshold => $latency_monitor_threshold, + notify_keyspace_events => $notify_keyspace_events, + hash_max_ziplist_entries => $hash_max_ziplist_entries, + hash_max_ziplist_value => $hash_max_ziplist_value, + list_max_ziplist_entries => $list_max_ziplist_entries, + list_max_ziplist_value => $list_max_ziplist_value, + set_max_intset_entries => $set_max_intset_entries, + zset_max_ziplist_entries => $zset_max_ziplist_entries, + zset_max_ziplist_value => $zset_max_ziplist_value, + hll_sparse_max_bytes => $hll_sparse_max_bytes, + activerehashing => $activerehashing, + output_buffer_limit_slave => $output_buffer_limit_slave, + output_buffer_limit_pubsub => $output_buffer_limit_pubsub, + hz => $hz, + aof_rewrite_incremental_fsync => $aof_rewrite_incremental_fsync, + cluster_enabled => $cluster_enabled, + cluster_config_file => $cluster_config_file, + cluster_node_timeout => $cluster_node_timeout, + cluster_slave_validity_factor => $cluster_slave_validity_factor, + cluster_require_full_coverage => $cluster_require_full_coverage, + cluster_migration_barrier => $cluster_migration_barrier, + extra_config_file => $extra_config_file, + tls_port => $tls_port, + tls_cert_file => $tls_cert_file, + tls_key_file => $tls_key_file, + tls_ca_cert_file => $tls_ca_cert_file, + tls_ca_cert_dir => $tls_ca_cert_dir, + tls_ciphers => $tls_ciphers, + tls_ciphersuites => $tls_ciphersuites, + tls_protocols => $tls_protocols, + tls_auth_clients => $tls_auth_clients, + tls_replication => $tls_replication, + tls_cluster => $tls_cluster, + tls_prefer_server_ciphers => $tls_prefer_server_ciphers, + modules => $modules, + io_threads => $io_threads, + io_threads_do_reads => $io_threads_do_reads, + cluster_allow_reads_when_down => $cluster_allow_reads_when_down, + cluster_replica_no_failover => $cluster_replica_no_failover, + dynamic_hz => $dynamic_hz, + activedefrag => $activedefrag, + active_defrag_ignore_bytes => $active_defrag_ignore_bytes, + active_defrag_threshold_lower => $active_defrag_threshold_lower, + active_defrag_threshold_upper => $active_defrag_threshold_upper, + active_defrag_cycle_min => $active_defrag_cycle_min, + active_defrag_cycle_max => $active_defrag_cycle_max, + active_defrag_max_scan_fields => $active_defrag_max_scan_fields, + jemalloc_bg_thread => $jemalloc_bg_thread, + rdb_save_incremental_fsync => $rdb_save_incremental_fsync, + acls => $acls, + custom_options => $custom_options, + } + + # TODO: Rely on https://github.com/puppetlabs/puppetlabs-stdlib/pull/1425 + # once available. + if $_template_params.any |$_key, $_value| { $_value.is_a(Deferred) } { + $_template_params_escaped = $_template_params.map | $_var , $_value | { + if $_value.is_a(Deferred) { + { $_var => "<%= \$${_var} %>" } + } else { + { $_var => $_value } + } + }.reduce | $_memo, $_kv | { $_memo + $_kv } + + $_content = Deferred( + 'inline_epp', + [ + epp($conf_template,$_template_params_escaped), + $_template_params, + ] + ) + } else { + $_content = epp($conf_template, $_template_params) + } + file { $redis_file_name_orig: ensure => file, owner => $config_owner, group => $config_group, mode => $config_file_mode, - content => stdlib::deferrable_epp( - $conf_template, - { - daemonize => $daemonize, - pid_file => $pid_file, - protected_mode => $protected_mode, - port => $port, - tcp_backlog => $tcp_backlog, - bind_arr => $bind_arr, - unixsocket => $unixsocket, - unixsocketperm => $unixsocketperm, - timeout => $timeout, - tcp_keepalive => $tcp_keepalive, - log_level => $log_level, - log_file => $_real_log_file, - syslog_enabled => $syslog_enabled, - syslog_facility => $syslog_facility, - databases => $databases, - save_db_to_disk => $save_db_to_disk, - save_db_to_disk_interval => $save_db_to_disk_interval, - stop_writes_on_bgsave_error => $stop_writes_on_bgsave_error, - rdbcompression => $rdbcompression, - dbfilename => $dbfilename, - workdir => $workdir, - slaveof => $slaveof, - replicaof => $replicaof, - masterauth => $masterauth, - slave_serve_stale_data => $slave_serve_stale_data, - slave_read_only => $slave_read_only, - repl_announce_ip => $repl_announce_ip, - repl_announce_port => $repl_announce_port, - repl_ping_slave_period => $repl_ping_slave_period, - repl_timeout => $repl_timeout, - repl_disable_tcp_nodelay => $repl_disable_tcp_nodelay, - repl_backlog_size => $repl_backlog_size, - repl_backlog_ttl => $repl_backlog_ttl, - slave_priority => $slave_priority, - min_slaves_to_write => $min_slaves_to_write, - min_slaves_max_lag => $min_slaves_max_lag, - requirepass => $requirepass, - rename_commands => $rename_commands, - maxclients => $maxclients, - maxmemory => $maxmemory, - maxmemory_policy => $maxmemory_policy, - maxmemory_samples => $maxmemory_samples, - appendonly => $appendonly, - appendfilename => $appendfilename, - appendfsync => $appendfsync, - no_appendfsync_on_rewrite => $no_appendfsync_on_rewrite, - auto_aof_rewrite_percentage => $auto_aof_rewrite_percentage, - auto_aof_rewrite_min_size => $auto_aof_rewrite_min_size, - aof_load_truncated => $aof_load_truncated, - slowlog_log_slower_than => $slowlog_log_slower_than, - slowlog_max_len => $slowlog_max_len, - latency_monitor_threshold => $latency_monitor_threshold, - notify_keyspace_events => $notify_keyspace_events, - hash_max_ziplist_entries => $hash_max_ziplist_entries, - hash_max_ziplist_value => $hash_max_ziplist_value, - list_max_ziplist_entries => $list_max_ziplist_entries, - list_max_ziplist_value => $list_max_ziplist_value, - set_max_intset_entries => $set_max_intset_entries, - zset_max_ziplist_entries => $zset_max_ziplist_entries, - zset_max_ziplist_value => $zset_max_ziplist_value, - hll_sparse_max_bytes => $hll_sparse_max_bytes, - activerehashing => $activerehashing, - output_buffer_limit_slave => $output_buffer_limit_slave, - output_buffer_limit_pubsub => $output_buffer_limit_pubsub, - hz => $hz, - aof_rewrite_incremental_fsync => $aof_rewrite_incremental_fsync, - cluster_enabled => $cluster_enabled, - cluster_config_file => $cluster_config_file, - cluster_node_timeout => $cluster_node_timeout, - cluster_slave_validity_factor => $cluster_slave_validity_factor, - cluster_require_full_coverage => $cluster_require_full_coverage, - cluster_migration_barrier => $cluster_migration_barrier, - extra_config_file => $extra_config_file, - tls_port => $tls_port, - tls_cert_file => $tls_cert_file, - tls_key_file => $tls_key_file, - tls_ca_cert_file => $tls_ca_cert_file, - tls_ca_cert_dir => $tls_ca_cert_dir, - tls_ciphers => $tls_ciphers, - tls_ciphersuites => $tls_ciphersuites, - tls_protocols => $tls_protocols, - tls_auth_clients => $tls_auth_clients, - tls_replication => $tls_replication, - tls_cluster => $tls_cluster, - tls_prefer_server_ciphers => $tls_prefer_server_ciphers, - modules => $modules, - io_threads => $io_threads, - io_threads_do_reads => $io_threads_do_reads, - cluster_allow_reads_when_down => $cluster_allow_reads_when_down, - cluster_replica_no_failover => $cluster_replica_no_failover, - dynamic_hz => $dynamic_hz, - activedefrag => $activedefrag, - active_defrag_ignore_bytes => $active_defrag_ignore_bytes, - active_defrag_threshold_lower => $active_defrag_threshold_lower, - active_defrag_threshold_upper => $active_defrag_threshold_upper, - active_defrag_cycle_min => $active_defrag_cycle_min, - active_defrag_cycle_max => $active_defrag_cycle_max, - active_defrag_max_scan_fields => $active_defrag_max_scan_fields, - jemalloc_bg_thread => $jemalloc_bg_thread, - rdb_save_incremental_fsync => $rdb_save_incremental_fsync, - acls => $acls, - custom_options => $custom_options, - } - ), + content => $_content, } exec { "copy ${redis_file_name_orig} to ${redis_file_name}": diff --git a/spec/acceptance/suites/default/redis_deferred_spec.rb b/spec/acceptance/suites/default/redis_deferred_spec.rb new file mode 100644 index 00000000..3797732b --- /dev/null +++ b/spec/acceptance/suites/default/redis_deferred_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper_acceptance' + +describe 'redis with deferred password' do + include_examples 'an idempotent resource' do + let(:manifest) do + <<-PUPPET + class { 'redis': + manage_repo => true, + redis_apt_repo => true, + port => 10001, + requirepass => Deferred('inline_epp',['<%= $pass %>',{'pass' => 'topsecret'}]), + } + PUPPET + end + end + + describe command('redis-cli -p 10001 -a topsecret ping') do + its(:exit_status) { is_expected.to eq 0 } + its(:stdout) { is_expected.to match %r{PONG} } + end + + describe command('redis-cli -p 10001 -a nonsense ping') do + its(:stdout) { is_expected.not_to match %r{PONG} } + end +end