299 lines
9.0 KiB
Ruby
299 lines
9.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
provides :redisio_sentinel_instance
|
|
unified_mode true
|
|
|
|
use '_partial/_base'
|
|
|
|
property :instance_name, String, name_property: true
|
|
property :name_override, String
|
|
property :sentinel_bind, [String, Array, nil], default: nil
|
|
property :sentinel_port, [String, Integer], default: 26_379
|
|
property :masters, Array, default: []
|
|
property :master_name, String
|
|
property :master_ip, String
|
|
property :master_port, [String, Integer, nil], default: nil
|
|
property :quorum_count, [String, Integer], default: 2
|
|
property :auth_pass, String
|
|
property :down_after_milliseconds, [String, Integer], default: 30_000
|
|
property :parallel_syncs, [String, Integer], default: 1
|
|
property :failover_timeout, [String, Integer], default: 900_000
|
|
property :announce_ip, String
|
|
property :announce_port, [String, Integer, nil], default: nil
|
|
property :notification_script, String
|
|
property :client_reconfig_script, String
|
|
|
|
action_class do
|
|
include RedisioCookbook::Helpers
|
|
|
|
def resolved_instance_name
|
|
(new_resource.name_override || new_resource.instance_name).to_s
|
|
end
|
|
|
|
def resolved_group
|
|
new_resource.group || platform_default_group
|
|
end
|
|
|
|
def resolved_homedir
|
|
new_resource.homedir || platform_default_home
|
|
end
|
|
|
|
def resolved_shell
|
|
new_resource.shell || platform_default_shell
|
|
end
|
|
|
|
def resolved_configdir
|
|
new_resource.configdir || platform_default_config_dir
|
|
end
|
|
|
|
def resolved_bin_path
|
|
new_resource.bin_path || platform_default_bin_path(package_install: new_resource.package_install, install_dir: new_resource.install_dir)
|
|
end
|
|
|
|
def resolved_package_name
|
|
new_resource.package_name || platform_package_name
|
|
end
|
|
|
|
def resolved_version_hash
|
|
version = if new_resource.version
|
|
new_resource.version
|
|
elsif new_resource.package_install
|
|
'7.0.0'
|
|
else
|
|
installed_redis_version(resolved_bin_path, package_install: new_resource.package_install, package_name: resolved_package_name)
|
|
end
|
|
|
|
redis_version_to_hash(version || '0.0.0')
|
|
end
|
|
|
|
def resolved_config_name
|
|
sentinel_config_name(resolved_instance_name)
|
|
end
|
|
|
|
def resolved_piddir
|
|
::File.join(new_resource.base_piddir, resolved_config_name)
|
|
end
|
|
|
|
def resolved_log_directory
|
|
return if new_resource.logfile.nil?
|
|
return if new_resource.logfile.empty? || new_resource.logfile == 'stdout'
|
|
|
|
::File.dirname(new_resource.logfile)
|
|
end
|
|
|
|
def resolved_log_file
|
|
return if new_resource.logfile.nil?
|
|
return if new_resource.logfile.empty? || new_resource.logfile == 'stdout'
|
|
|
|
new_resource.logfile
|
|
end
|
|
|
|
def base_master
|
|
{
|
|
'master_name' => new_resource.master_name,
|
|
'master_ip' => new_resource.master_ip,
|
|
'master_port' => new_resource.master_port,
|
|
'quorum_count' => new_resource.quorum_count,
|
|
'auth_pass' => new_resource.auth_pass,
|
|
'down_after_milliseconds' => new_resource.down_after_milliseconds,
|
|
'parallel_syncs' => new_resource.parallel_syncs,
|
|
'failover_timeout' => new_resource.failover_timeout,
|
|
}
|
|
end
|
|
|
|
def resolved_masters
|
|
masters = normalize_array(new_resource.masters).map { |master| deep_stringify_keys(normalize_hash(master)) }
|
|
masters = [base_master] if masters.empty? && new_resource.master_ip
|
|
raise 'At least one sentinel master must be defined' if masters.empty?
|
|
|
|
bag_secret = if new_resource.data_bag_name && new_resource.data_bag_item && new_resource.data_bag_key
|
|
data_bag_item(new_resource.data_bag_name, new_resource.data_bag_item)[new_resource.data_bag_key]
|
|
end
|
|
|
|
masters.map do |master|
|
|
{
|
|
'master_name' => master['master_name'] || master['name'],
|
|
'master_ip' => master['master_ip'],
|
|
'master_port' => master['master_port'],
|
|
'quorum_count' => master['quorum_count'].nil? ? new_resource.quorum_count : master['quorum_count'],
|
|
'auth_pass' => bag_secret || master['auth_pass'],
|
|
'down_after_milliseconds' => master['down_after_milliseconds'].nil? ? new_resource.down_after_milliseconds : master['down_after_milliseconds'],
|
|
'parallel_syncs' => master['parallel_syncs'].nil? ? new_resource.parallel_syncs : master['parallel_syncs'],
|
|
'failover_timeout' => master['failover_timeout'].nil? ? new_resource.failover_timeout : master['failover_timeout'],
|
|
}.tap do |resolved|
|
|
%w(master_name master_ip master_port quorum_count).each do |key|
|
|
raise "Missing required sentinel parameter #{key}" if resolved[key].nil?
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def config_path
|
|
::File.join(resolved_configdir, "#{resolved_config_name}.conf")
|
|
end
|
|
|
|
def breadcrumb_path
|
|
"#{config_path}.breadcrumb"
|
|
end
|
|
|
|
def service_name
|
|
sentinel_service_name(resolved_instance_name)
|
|
end
|
|
end
|
|
|
|
action :create do
|
|
user new_resource.user do
|
|
comment 'Redis service account'
|
|
manage_home true
|
|
home resolved_homedir
|
|
shell resolved_shell
|
|
system new_resource.systemuser
|
|
uid new_resource.uid unless new_resource.uid.nil?
|
|
end
|
|
|
|
directory resolved_configdir do
|
|
owner 'root'
|
|
group resolved_group
|
|
mode '0775'
|
|
recursive true
|
|
end
|
|
|
|
directory resolved_piddir do
|
|
owner new_resource.user
|
|
group resolved_group
|
|
mode '0755'
|
|
recursive true
|
|
end
|
|
|
|
unless resolved_log_directory.nil?
|
|
directory resolved_log_directory do
|
|
owner new_resource.user
|
|
group resolved_group
|
|
mode '0755'
|
|
recursive true
|
|
end
|
|
end
|
|
|
|
unless resolved_log_file.nil?
|
|
file resolved_log_file do
|
|
owner new_resource.user
|
|
group resolved_group
|
|
mode '0644'
|
|
backup false
|
|
action :create
|
|
end
|
|
end
|
|
|
|
template config_path do
|
|
source 'sentinel.conf.erb'
|
|
cookbook 'redisio'
|
|
owner new_resource.user
|
|
group resolved_group
|
|
mode '0644'
|
|
variables(
|
|
name: resolved_instance_name,
|
|
piddir: resolved_piddir,
|
|
version: resolved_version_hash,
|
|
job_control: 'systemd',
|
|
sentinel_bind: new_resource.sentinel_bind,
|
|
sentinel_port: new_resource.sentinel_port,
|
|
loglevel: new_resource.loglevel,
|
|
logfile: new_resource.logfile,
|
|
syslogenabled: new_resource.syslogenabled,
|
|
syslogfacility: new_resource.syslogfacility,
|
|
masters: resolved_masters,
|
|
announce_ip: new_resource.announce_ip,
|
|
announce_port: new_resource.announce_port,
|
|
notification_script: new_resource.notification_script,
|
|
client_reconfig_script: new_resource.client_reconfig_script,
|
|
protected_mode: new_resource.protected_mode,
|
|
maxclients: new_resource.maxclients,
|
|
aclfile: new_resource.aclfile,
|
|
includes: new_resource.includes,
|
|
tlsport: new_resource.tlsport,
|
|
tlscertfile: new_resource.tlscertfile,
|
|
tlskeyfile: new_resource.tlskeyfile,
|
|
tlskeyfilepass: new_resource.tlskeyfilepass,
|
|
tlsclientcertfile: new_resource.tlsclientcertfile,
|
|
tlsclientkeyfile: new_resource.tlsclientkeyfile,
|
|
tlsclientkeyfilepass: new_resource.tlsclientkeyfilepass,
|
|
tlsdhparamsfile: new_resource.tlsdhparamsfile,
|
|
tlscacertfile: new_resource.tlscacertfile,
|
|
tlscacertdir: new_resource.tlscacertdir,
|
|
tlsauthclients: new_resource.tlsauthclients,
|
|
tlsreplication: new_resource.tlsreplication,
|
|
tlscluster: new_resource.tlscluster,
|
|
tlsprotocols: new_resource.tlsprotocols,
|
|
tlsciphers: new_resource.tlsciphers,
|
|
tlsciphersuites: new_resource.tlsciphersuites,
|
|
tlspreferserverciphers: new_resource.tlspreferserverciphers,
|
|
tlssessioncaching: new_resource.tlssessioncaching,
|
|
tlssessioncachesize: new_resource.tlssessioncachesize,
|
|
tlssessioncachetimeout: new_resource.tlssessioncachetimeout
|
|
)
|
|
not_if { ::File.exist?(breadcrumb_path) }
|
|
notifies :restart, "service[#{service_name}]", :delayed
|
|
end
|
|
|
|
file breadcrumb_path do
|
|
content 'This file prevents the Chef cookbook from overwriting the sentinel config more than once'
|
|
action :create_if_missing
|
|
end
|
|
|
|
systemd_unit "#{service_name}.service" do
|
|
content(
|
|
Unit: {
|
|
Description: "Redis Sentinel (#{resolved_instance_name})",
|
|
After: 'network.target',
|
|
},
|
|
Service: {
|
|
Type: 'notify',
|
|
ExecStart: "#{redis_server_binary(resolved_bin_path, package_install: new_resource.package_install, package_name: resolved_package_name)} #{config_path} --sentinel --daemonize no",
|
|
User: new_resource.user,
|
|
Group: resolved_group,
|
|
LimitNOFILE: new_resource.maxclients + 32,
|
|
},
|
|
Install: {
|
|
WantedBy: 'multi-user.target',
|
|
}
|
|
)
|
|
action %i(create enable)
|
|
end
|
|
|
|
service service_name do
|
|
action %i(enable start)
|
|
supports status: true, restart: true
|
|
end
|
|
end
|
|
|
|
action :delete do
|
|
service service_name do
|
|
action %i(stop disable)
|
|
supports status: true, restart: true
|
|
ignore_failure true
|
|
end
|
|
|
|
systemd_unit "#{service_name}.service" do
|
|
action %i(disable delete)
|
|
end
|
|
|
|
file breadcrumb_path do
|
|
action :delete
|
|
end
|
|
|
|
file config_path do
|
|
action :delete
|
|
end
|
|
|
|
unless resolved_log_file.nil?
|
|
file resolved_log_file do
|
|
action :delete
|
|
end
|
|
end
|
|
|
|
directory resolved_piddir do
|
|
recursive true
|
|
action :delete
|
|
end
|
|
end
|