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

Adds redis_cli task #245

Merged
merged 1 commit into from
Nov 27, 2017
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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ group :system_tests do
gem "beaker", '2.41.0', :require => false
gem "beaker-rspec", '5.6.0', :require => false
gem 'beaker-puppet_install_helper', :require => false
gem 'beaker-module_install_helper'
gem 'vagrant-wrapper'
end

ENV['PUPPET_GEM_VERSION'].nil? ? puppetversion = '~> 4.0' : puppetversion = ENV['PUPPET_GEM_VERSION'].to_s
Expand Down
2 changes: 2 additions & 0 deletions spec/acceptance/nodesets/centos-6-docker.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
HOSTS:
centos-6-x64:
roles:
- master
platform: el-6-x86_64
hypervisor : docker
image: petems/docker-centos-6-ssh-locale:centos-6
Expand Down
2 changes: 2 additions & 0 deletions spec/acceptance/nodesets/centos-7-docker.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
HOSTS:
centos-7-x64:
roles:
- master
platform: el-7-x86_64
hypervisor : docker
image: petems/docker-centos-7-ssh-locale:centos-7
Expand Down
2 changes: 2 additions & 0 deletions spec/acceptance/nodesets/ubuntu-1604-docker.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
HOSTS:
ubuntu-16-04:
roles:
- master
platform: ubuntu-16.04-amd64
image: ubuntu:16.04
hypervisor: docker
Expand Down
37 changes: 37 additions & 0 deletions spec/acceptance/redis_cli_task_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# run a test task
require 'spec_helper_acceptance'

describe 'redis-cli task' do

it 'install redis-cli with the class' do
pp = <<-EOS
Exec {
path => [ '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', ]
}

class { '::redis':
manage_repo => true,
}
EOS

# Apply twice to ensure no errors the second time.
apply_manifest(pp, :catch_failures => true)
end

describe 'ping' do
it 'execute ping' do
result = run_task(task_name: 'redis::redis_cli', params: 'command="ping"')
expect_multiple_regexes(result: result, regexes: [%r{{"status":"PONG"}}, %r{Ran on 1 node in .+ seconds}])
end
end

describe 'security' do
it 'stops script injections and escapes' do
result = run_task(task_name: 'redis::redis_cli', params: 'command="ping; cat /etc/passwd"')
expect_multiple_regexes(result: result, regexes: [%r{{"status":"ERR unknown command 'ping; cat /etc/passwd'"}}, %r{Ran on 1 node in .+ seconds}])

result = run_task(task_name: 'redis::redis_cli', params: 'command="ping && cat /etc/passwd"')
expect_multiple_regexes(result: result, regexes: [%r{{"status":"ERR unknown command 'ping && cat /etc/passwd'"}}, %r{Ran on 1 node in .+ seconds}])
end
end
end
73 changes: 65 additions & 8 deletions spec/spec_helper_acceptance.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,67 @@
require 'beaker-rspec'
require 'beaker/puppet_install_helper'
require 'beaker/module_install_helper'

def change_root_password
on(hosts, 'echo "root:root" | chpasswd')
end

def install_bolt_on(hosts)
on(hosts, "/opt/puppetlabs/puppet/bin/gem install bolt -v '0.5.1' --no-ri --no-rdoc", acceptable_exit_codes: [0]).stdout
end

run_puppet_install_helper unless ENV['BEAKER_provision'] == 'no'
change_root_password
install_module_on(hosts)
install_module_dependencies_on(hosts)

UNSUPPORTED_PLATFORMS = %w[windows AIX Solaris].freeze

DEFAULT_PASSWORD = if default[:hypervisor] == 'vagrant'
'root'
elsif default[:hypervisor] == 'docker'
'root'
end

def run_task(task_name:, params: nil, password: DEFAULT_PASSWORD)
run_bolt_task(task_name: task_name, params: params, password: password)
end

def run_bolt_task(task_name:, params: nil, password: DEFAULT_PASSWORD)
on(master, "/opt/puppetlabs/puppet/bin/bolt task run #{task_name} --modules /etc/puppetlabs/code/modules/ --nodes localhost --user root --password #{password} #{params}", acceptable_exit_codes: [0, 1]).stdout # rubocop:disable Metrics/LineLength
end

def expect_multiple_regexes(result:, regexes:)
regexes.each do |regex|
expect(result).to match(regex)
end
end

# This method allows a block to be passed in and if an exception is raised
# that matches the 'error_matcher' matcher, the block will wait a set number
# of seconds before retrying.
# Params:
# - max_retry_count - Max number of retries
# - retry_wait_interval_secs - Number of seconds to wait before retry
# - error_matcher - Matcher which the exception raised must match to allow retry
# Example Usage:
# retry_on_error_matching(3, 5, /OpenGPG Error/) do
# apply_manifest(pp, :catch_failures => true)
# end
def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, error_matcher = nil)
try = 0
begin
try += 1
yield
rescue Exception => e
if try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher)
sleep retry_wait_interval_secs
retry
else
raise
end
end
end

RSpec.configure do |c|
# Project root
Expand All @@ -11,20 +71,17 @@
c.formatter = :documentation

c.before :suite do
# Install module and dependencies
puppet_module_install(:source => proj_root, :module_name => 'redis')

hosts.each do |host|
if fact('osfamily') == 'Debian'
# These should be on all Deb-flavor machines by default...
# But Docker is often more slimline
shell('apt-get install apt-transport-https software-properties-common -y', { :acceptable_exit_codes => [0] })
shell('apt-get install apt-transport-https software-properties-common -y', acceptable_exit_codes: [0])
end
on host, puppet('module', 'install', 'puppetlabs-stdlib -v 4.11.0'), { :acceptable_exit_codes => [0] }
on host, puppet('module', 'install', 'puppetlabs-apt -v 2.3.0'), { :acceptable_exit_codes => [0] }
on host, puppet('module', 'install', 'stahnma-epel -v 1.2.2'), { :acceptable_exit_codes => [0] }
on host, puppet('module', 'install', 'herculesteam/augeasproviders_core -v 2.1.0'), { :acceptable_exit_codes => [0] }
on host, puppet('module', 'install', 'herculesteam/augeasproviders_sysctl -v 2.1.0'), { :acceptable_exit_codes => [0] }
# Bolt requires gcc and make
install_package(host, 'gcc')
install_package(host, 'make')
install_bolt_on(host)
end
end
end
10 changes: 10 additions & 0 deletions tasks/redis_cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"description": "Executes a redis-cli command on the target system",
"input_method": "stdin",
"parameters": {
"command": {
"description": "The command to run, including all arguments",
"type": "String[1]"
}
}
}
22 changes: 22 additions & 0 deletions tasks/redis_cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/opt/puppetlabs/puppet/bin/ruby
require 'json'
require 'open3'
require 'puppet'

def redis_cli(command)
stdout, stderr, status = Open3.capture3("redis-cli", command)
raise Puppet::Error, stderr if status != 0
{ status: stdout.strip }
end

params = JSON.parse(STDIN.read)
command = params['command']

begin
result = redis_cli(command)
puts result.to_json
exit 0
rescue Puppet::Error => e
puts({ status: 'failure', error: e.message }.to_json)
exit 1
end