Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support redis sentinels and add master property #509

Merged
merged 2 commits into from
Jul 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions lib/puppet/provider/sensu_redis_config/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ def conf
end

def flush
# Clean nil valued properties, esp. sentinel related
# Related to https://github.com/sensu/sensu-puppet/issues/394.
self.class.resource_type.validproperties.each do |prop|
if resource.should(prop).nil?
conf['redis'].delete prop.to_s
end
end

File.open(config_file, 'w') do |f|
f.puts JSON.pretty_generate(conf)
end
Expand All @@ -38,19 +46,27 @@ def exists?
end

def port
conf['redis']['port'].to_s
if conf['redis']['port'] then conf['redis']['port'].to_s else :absent end
end

def port=(value)
conf['redis']['port'] = value.to_i
if value == :absent
conf['redis'].delete 'port'
else
conf['redis']['port'] = value.to_i
end
end

def host
conf['redis']['host']
conf['redis']['host'] || :absent
end

def host=(value)
conf['redis']['host'] = value
if value == :absent
conf['redis'].delete 'host'
else
conf['redis']['host'] = value
end
end

def password
Expand All @@ -77,6 +93,30 @@ def db=(value)
conf['redis']['db'] = value.to_i
end

def sentinels
conf['redis']['sentinels'] || []
end

def sentinels=(value)
if value == []
conf['redis'].delete 'sentinels'
else
conf['redis']['sentinels'] = value
end
end

def master
conf['redis']['master'] || :absent
end

def master=(value)
if value == :absent
conf['redis'].delete 'master'
else
conf['redis']['master'] = value.to_s
end
end

def auto_reconnect
conf['redis']['auto_reconnect']
end
Expand Down
60 changes: 58 additions & 2 deletions lib/puppet/type/sensu_redis_config.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'set'
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..',
'puppet_x', 'sensu', 'boolean_property.rb'))

Expand All @@ -13,6 +14,22 @@ def initialize(*args)
].select { |ref| catalog.resource(ref) }
end

def has_sentinels?
sentinels = self.should(:sentinels)
return sentinels && !sentinels.empty?
end

def pre_run_check
if self.has_sentinels? then
if self.should(:host) && self.should(:host) != :absent then
raise Puppet::Error, "Redis 'host' (#{self.should(:host)}) must not be specified when sentinels are specified"
end
if self.should(:port) && self.should(:port) != :absent then
raise Puppet::Error, "Redis 'port' (#{self.should(:port)}) must not be specified when sentinels are specified"
end
end
end

ensurable do
newvalue(:present) do
provider.create
Expand All @@ -37,13 +54,25 @@ def initialize(*args)
newproperty(:port) do
desc "The port that Redis is listening on"

defaultto '6379'
defaultto {
if [email protected]_sentinels? then '6379' else :absent end
}
def insync?(is)
if should.is_a?(Symbol) then should == is else super(is) end
end
end

newproperty(:host) do
desc "The hostname that Redis is listening on"

defaultto '127.0.0.1'
defaultto {
# Use absent to ensure that config is flushed
# when property gets unset
if [email protected]_sentinels? then '127.0.0.1' else :absent end
}
def insync?(is)
if should.is_a?(Symbol) then should == is else super(is) end
end
end

newproperty(:password) do
Expand All @@ -68,6 +97,33 @@ def initialize(*args)
defaultto :true
end

newproperty(:sentinels, :array_matching => :all) do
desc "Redis Sentinel configuration for HA clustering"
defaultto []

def insync?(is)
# this probably needs more checks, for duplicate values, etc
# but for now it works fine
Set.new(is) == Set.new(should)
end

munge do |value|
Hash[value.map do |k, v|
[k, if k == "port" then v.to_i else v.to_s end]
end]
end
end

newproperty(:master) do
desc "Redis master name in the sentinel configuration"
# Use absent to ensure that config is flushed
# when property gets unset
defaultto :absent
def insync?(is)
if should.is_a?(Symbol) then should == is else super(is) end
end
end

autorequire(:package) do
['sensu']
end
Expand Down
10 changes: 10 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@
# Integer. The Redis instance DB to use/select
# Default: 0
#
# [*redis_sentinels*]
# Array. Redis Sentinel configuration and connection information for one or more Sentinels
# Default: Not configured
#
# [*redis_master*]
# String. Redis master name in the sentinel configuration
# Default: undef. In the end whatever sensu defaults to, which is "mymaster" currently.
#
# [*redis_auto_reconnect*]
# Boolean. Reconnect to Redis in the event of a connection failure
# Default: true
Expand Down Expand Up @@ -354,6 +362,8 @@
$redis_reconnect_on_error = false,
$redis_db = 0,
$redis_auto_reconnect = true,
$redis_sentinels = undef,
$redis_master = undef,
$api_bind = '0.0.0.0',
$api_host = '127.0.0.1',
$api_port = 4567,
Expand Down
12 changes: 10 additions & 2 deletions manifests/redis/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,23 @@
before => Sensu_redis_config[$::fqdn],
}

$has_sentinels = !($sensu::redis_sentinels == undef or $sensu::redis_sentinels == [])
$host = $has_sentinels ? { false => $sensu::redis_host, true => undef, }
$port = $has_sentinels ? { false => $sensu::redis_port, true => undef, }
$sentinels = $has_sentinels ? { true => $sensu::redis_sentinels, false => undef, }
$master = $has_sentinels ? { true => $sensu::redis_master, false => undef, }

sensu_redis_config { $::fqdn:
ensure => $ensure,
base_path => "${sensu::etc_dir}/conf.d",
host => $sensu::redis_host,
port => $sensu::redis_port,
host => $host,
port => $port,
password => $sensu::redis_password,
reconnect_on_error => $sensu::redis_reconnect_on_error,
db => $sensu::redis_db,
auto_reconnect => $sensu::redis_auto_reconnect,
sentinels => $sentinels,
master => $master,
}

}
40 changes: 37 additions & 3 deletions spec/classes/sensu_redis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)}
end # default settings

context 'be configurable' do
context 'be configurable without sentinels' do
let(:params) { {
:redis_host => 'redis.domain.com',
:redis_port => 1234,
Expand All @@ -28,9 +28,43 @@
:port => 1234,
:password => 'password',
:db => 1,
:auto_reconnect => false
:auto_reconnect => false,
:sentinels => nil,
:master => nil
)}
end # be configurable
end # be configurable without sentinels

context 'be configurable with sentinels' do
let(:params) { {
:redis_password => 'password',
:redis_db => 1,
:redis_auto_reconnect => false,
:redis_sentinels => [{
'host' => 'redis1.domain.com',
'port' => 1234
}, {
'host' => 'redis2.domain.com',
'port' => '5678'
}],
:redis_master => 'master-name'
} }

it { should contain_sensu_redis_config('testhost.domain.com').with(
:host => nil,
:port => nil,
:password => 'password',
:db => 1,
:auto_reconnect => false,
:sentinels => [{
'host' => 'redis1.domain.com',
'port' => 1234
}, {
'host' => 'redis2.domain.com',
'port' => 5678
}],
:master => "master-name"
)}
end # be configurable with sentinels

context 'with server' do
let(:params) { { :server => true } }
Expand Down
Loading