Skip to content

Commit

Permalink
Convert redisget to redis::get API v4 function
Browse files Browse the repository at this point in the history
Since we'll be dropping puppet 3 support in the next release, we should
move away from using legacy functions that suffer from environment
isolation issues.

See https://puppet.com/docs/puppet/4.10/functions_legacy.html

The newer function API also has built in support for validating function
arguments, declaring some parameters as optional etc.  This allows us to
remove a lot of our own code that was performing this validation before.

Fixes voxpupuli#291
  • Loading branch information
alexjfisher committed Mar 11, 2019
1 parent eaab8ab commit 8b7104e
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 82 deletions.
23 changes: 4 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,13 @@ class { '::redis::sentinel':
}
```

## `redisget()` function

`redisget()` takes two or three arguments that are strings. The first is the key
to be looked up, the second is the URL to the Redis service and the
optional third argument is a default value to use if the key is not
found or connection to the Redis service cannot be made.

Example of basic usage.

```puppet
$version = redisget('version.myapp', 'redis://redis.example.com:6379')
```

Example with default value specified. This is useful to allow for cached
data in case Redis is not available.

```puppet
$version = redisget('version.myapp', 'redis://redis.example.com:6379', $::myapp_version)
```
## `redis::get()` function

This function is used to get data from redis.
You must have the 'redis' gem installed on your puppet master.

Functions are documented in [REFERENCE.md](REFERENCE.md)

## Unit testing

Plain RSpec:
Expand Down
61 changes: 61 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Reference
<!-- DO NOT EDIT: This document was generated by Puppet Strings -->

## Table of Contents

**Functions**

* [`redis::get`](#redisget): Returns the value of the key being looked up or `undef` if the key does not exist. Takes two arguments with an optional third. The first bein

## Functions

### redis::get

Type: Ruby 4.x API

Returns the value of the key being looked up or `undef` if the key does not
exist. Takes two arguments with an optional third. The first being a string
value of the key to be looked up, the second is the URL to the Redis service
and the third optional argument is a default value to be used if the lookup
fails.

example usage
```
$version = redis::get('version.myapp', 'redis://redis.example.com:6379')
$version_with_default = redis::get('version.myapp', 'redis://redis.example.com:6379', $::myapp_version)
```

#### `redis::get(String[1] $key, Redis::RedisUrl $url, Optional[String] $default)`

Returns the value of the key being looked up or `undef` if the key does not
exist. Takes two arguments with an optional third. The first being a string
value of the key to be looked up, the second is the URL to the Redis service
and the third optional argument is a default value to be used if the lookup
fails.

example usage
```
$version = redis::get('version.myapp', 'redis://redis.example.com:6379')
$version_with_default = redis::get('version.myapp', 'redis://redis.example.com:6379', $::myapp_version)
```

Returns: `Optional[String]` Returns the value of the key from Redis

##### `key`

Data type: `String[1]`

The key to look up in redis

##### `url`

Data type: `Redis::RedisUrl`

The endpoint of the Redis instance

##### `default`

Data type: `Optional[String]`

The value to return if the key is not found or the connection to Redis fails

32 changes: 32 additions & 0 deletions lib/puppet/functions/redis/get.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'redis'
# Returns the value of the key being looked up or `undef` if the key does not
# exist. Takes two arguments with an optional third. The first being a string
# value of the key to be looked up, the second is the URL to the Redis service
# and the third optional argument is a default value to be used if the lookup
# fails.
#
# example usage
# ```
# $version = redis::get('version.myapp', 'redis://redis.example.com:6379')
# $version_with_default = redis::get('version.myapp', 'redis://redis.example.com:6379', $::myapp_version)
# ```
Puppet::Functions.create_function(:'redis::get') do
# @param key The key to look up in redis
# @param url The endpoint of the Redis instance
# @param default The value to return if the key is not found or the connection to Redis fails
# @return Returns the value of the key from Redis
dispatch :get do
param 'String[1]', :key
param 'Redis::RedisUrl', :url
optional_param 'String', :default
return_type 'Optional[String]'
end

def get(key, url, default = nil)
Redis.new(url: url).get(key) || default
rescue Redis::CannotConnectError, SocketError => e
raise Puppet::Error, "connection to redis server failed - #{e}" unless default
Puppet.debug "Connection to redis failed with #{e} - Returning default value of #{default}"
default
end
end
44 changes: 0 additions & 44 deletions lib/puppet/parser/functions/redisget.rb

This file was deleted.

24 changes: 12 additions & 12 deletions spec/acceptance/suites/default/redisget_spec.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# rubocop:disable RSpec/MultipleExpectations
require 'spec_helper_acceptance'

describe 'redisget() function' do
describe 'redis::get() function' do
it 'runs successfully' do
pp = <<-EOS
Exec {
path => [ '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', ]
}
class { '::redis':
class { 'redis':
manage_repo => true,
}
Expand All @@ -33,9 +33,9 @@ class { '::redis':
end
end

it 'returns a value from MyKey with the redisget() function' do
it 'returns a value from MyKey with the redis::get() function' do
pp = <<-EOS
$mykey = redisget('mykey', 'redis://127.0.0.1:6379')
$mykey = redis::get('mykey', 'redis://127.0.0.1:6379')
notify{"mykey value: ${mykey}":}
EOS
Expand All @@ -46,9 +46,9 @@ class { '::redis':
end
end

it 'returns a value from valid MyKey with the redisget() function while specifying a default' do
it 'returns a value from valid MyKey with the redis::get() function while specifying a default' do
pp = <<-EOS
$mykey = redisget('mykey', 'redis://127.0.0.1:6379', 'default_value')
$mykey = redis::get('mykey', 'redis://127.0.0.1:6379', 'default_value')
notify{"mykey value: ${mykey}":}
EOS
Expand All @@ -59,9 +59,9 @@ class { '::redis':
end
end

it 'returns an empty string when value not present with redisget() function' do
it 'returns an empty string when value not present with redis::get() function' do
pp = <<-EOS
$foo_key = redisget('foo', 'redis://127.0.0.1:6379')
$foo_key = redis::get('foo', 'redis://127.0.0.1:6379')
if empty($foo_key){
notify{"foo_key value was empty string":}
Expand All @@ -74,9 +74,9 @@ class { '::redis':
end
end

it 'returns the specified default value when key not present with redisget() function' do
it 'returns the specified default value when key not present with redis::get() function' do
pp = <<-EOS
$foo_key = redisget('foo', 'redis://127.0.0.1:6379', 'default_value')
$foo_key = redis::get('foo', 'redis://127.0.0.1:6379', 'default_value')
notify { $foo_key: }
EOS
Expand All @@ -90,7 +90,7 @@ class { '::redis':
it 'returns the specified default value when connection to redis server fails' do
pp = <<-EOS
# Bogus port for redis server
$foo_key = redisget('foo', 'redis://127.0.0.1:12345', 'default_value')
$foo_key = redis::get('foo', 'redis://127.0.0.1:12345', 'default_value')
notify { $foo_key: }
EOS
Expand All @@ -104,7 +104,7 @@ class { '::redis':
it 'returns an error when specifying a non connectable redis server' do
pp = <<-EOS
# Bogus port for redis server
$foo_key = redisget('foo', 'redis://127.0.0.1:12345')
$foo_key = redis::get('foo', 'redis://127.0.0.1:12345')
notify { $foo_key: }
EOS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
LOCAL_BROKEN_URL = 'redis://localhost:1234'.freeze
REMOTE_BROKEN_URL = 'redis://redis.example.com:1234'.freeze

describe 'redisget' do
describe 'redis::get' do
context 'should error if connection to remote redis server cannot be made and no default is specified' do
it { is_expected.to run.with_params('nonexistent_key', REMOTE_BROKEN_URL).and_raise_error(Puppet::Error, %r{connection to redis server failed - Error connecting to Redis on redis.example.com:1234 \(SocketError\)}) }
end
Expand Down Expand Up @@ -59,15 +59,15 @@

describe 'with incorrect arguments' do
context 'with no argument specified' do
it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
it { is_expected.to run.with_params.and_raise_error(ArgumentError) }
end

context 'with only one argument specified' do
it { is_expected.to run.with_params('some_key').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
it { is_expected.to run.with_params('some_key').and_raise_error(ArgumentError) }
end

context 'with more than three arguments specified' do
it { is_expected.to run.with_params('way', 'too', 'many', 'args').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
it { is_expected.to run.with_params('way', 'too', 'many', 'args').and_raise_error(ArgumentError) }
end
end

Expand All @@ -78,15 +78,15 @@
end
[{ 'ha' => 'sh' }, true, 1, %w[an array]].each do |p|
context "specifing first parameter as <#{p}>" do
it { is_expected.to run.with_params(p, REDIS_URL).and_raise_error(Puppet::ParseError, %r{wrong argument type}i) }
it { is_expected.to run.with_params(p, REDIS_URL).and_raise_error(ArgumentError) }
end

context "specifing second parameter as <#{p}>" do
it { is_expected.to run.with_params('valid', p).and_raise_error(Puppet::ParseError, %r{wrong argument type}i) }
it { is_expected.to run.with_params('valid', p).and_raise_error(ArgumentError) }
end

context "specifing third parameter as <#{p}>" do
it { is_expected.to run.with_params('valid', p).and_raise_error(Puppet::ParseError, %r{wrong argument type}i) }
it { is_expected.to run.with_params('valid', p).and_raise_error(ArgumentError) }
end
end
end
Expand Down
1 change: 1 addition & 0 deletions types/redisurl.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type Redis::RedisUrl = Pattern[/(^redis:\/\/)/]

0 comments on commit 8b7104e

Please sign in to comment.