Skip to content

Commit

Permalink
FM_6450 adds the execute SQL task
Browse files Browse the repository at this point in the history
  • Loading branch information
tphoney committed Oct 10, 2017
1 parent 0765497 commit 426bbc6
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,13 @@
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org).

## Supported Release [5.1.0]
### Summary
This release adds Tasks to the Mysql module.

#### Added
- Adds the execute sql task.

## Supported Release [5.0.0]
### Summary
This is a major release that adds support for string translation. Currently the only supported language besides
Expand Down
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -1282,6 +1282,10 @@ Determines the MySQL version by parsing the output from `mysql --version`

Generates a unique id, based on the node's MAC address, which can be used as `server_id`. This fact will *always* return `0` on nodes that have only loopback interfaces. Because those nodes aren't connected to the outside world, this shouldn't cause any conflicts.

### Tasks

The MySQL module has an example task that allows a user to execute arbitary SQL against a database. Please refer to to the [PE documentation](https://puppet.com/docs/pe/2017.3/orchestrator/running_tasks.html) or [Bolt documentation](https://puppet.com/docs/bolt/latest/bolt.html) on how to execute a task.

## Limitations

This module has been tested on:
Expand Down
2 changes: 1 addition & 1 deletion metadata.json
@@ -1,6 +1,6 @@
{
"name": "puppetlabs-mysql",
"version": "5.0.0",
"version": "5.1.0",
"author": "Puppet Labs",
"summary": "Installs, configures, and manages the MySQL service.",
"license": "Apache-2.0",
Expand Down
23 changes: 23 additions & 0 deletions spec/acceptance/sql_task_spec.rb
@@ -0,0 +1,23 @@
# run a test task
require 'spec_helper_acceptance'

describe 'mysql tasks' do
describe 'execute some sql', if: pe_install? && puppet_version =~ %r{(5\.\d\.\d)} do
pp = <<-EOS
class { 'mysql::server': root_password => 'password' }
mysql::db { 'spec1':
user => 'root1',
password => 'password',
}
EOS

it "sets up a mysql instance" do
apply_manifest(pp, catch_failures: true)
end

it 'execute arbitary sql' do
result = run_task(task_name: 'mysql::sql', params: 'sql="show databases;" password=password')
expect_multiple_regexes(result: result, regexes: [%r{information_schema}, %r{performance_schema}, %r{Job completed. 1/1 nodes succeeded}])
end
end
end
42 changes: 42 additions & 0 deletions spec/spec_helper_acceptance.rb
Expand Up @@ -4,8 +4,17 @@
require 'beaker/module_install_helper'
require 'beaker/i18n_helper'

def install_bolt_on(hosts)
on(hosts, "/opt/puppetlabs/puppet/bin/gem install --source http://rubygems.delivery.puppetlabs.net bolt -v '> 0.0.1'", acceptable_exit_codes: [0, 1]).stdout
end

def pe_install?
ENV['PUPPET_INSTALL_TYPE'] =~ %r{pe}i
end

run_puppet_install_helper
install_ca_certs unless ENV['PUPPET_INSTALL_TYPE'] =~ %r{pe}i
install_bolt_on(hosts) unless pe_install?
install_module_on(hosts)
install_module_dependencies_on(hosts)

Expand All @@ -15,6 +24,38 @@ def puppet_version
(on default, puppet('--version')).output.chomp
end

DEFAULT_PASSWORD = if default[:hypervisor] == 'vagrant'
'vagrant'
elsif default[:hypervisor] == 'vcloud'
'Qu@lity!'
end

def run_puppet_access_login(user:, password: '~!@#$%^*-/ aZ', lifetime: '5y')
on(master, puppet('access', 'login', '--username', user, '--lifetime', lifetime), stdin: password)
end

def run_task(task_name:, params: nil, password: DEFAULT_PASSWORD)
if pe_install?
run_puppet_task(task_name: task_name, params: params)
else
run_bolt_task(task_name: task_name, params: params, password: password)
end
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/service --nodes localhost --password #{password} #{params}", acceptable_exit_codes: [0, 1]).stdout # rubocop:disable Metrics/LineLength
end

def run_puppet_task(task_name:, params: nil)
on(master, puppet('task', 'run', task_name, '--nodes', fact_on(master, 'fqdn'), params.to_s), acceptable_exit_codes: [0, 1]).stdout
end

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

RSpec.configure do |c|
# Readable test descriptions
c.formatter = :documentation
Expand All @@ -27,6 +68,7 @@ def puppet_version

# Configure all nodes in nodeset
c.before :suite do
run_puppet_access_login(user: 'admin') if pe_install?
hosts.each do |host|
# This will be removed, this is temporary to test localisation.
if (fact('osfamily') == 'Debian' || fact('osfamily') == 'RedHat') && (puppet_version >= '4.10.5' && puppet_version < '5.2.0')
Expand Down
22 changes: 22 additions & 0 deletions tasks/sql.json
@@ -0,0 +1,22 @@
{
"description": "Allows you to execute arbitary SQL",
"input_method": "stdin",
"parameters": {
"database": {
"description": "Database to connect to",
"type": "Optional[String[1]]"
},
"user": {
"description": "The user",
"type": "Optional[String[1]]"
},
"password": {
"description": "The password",
"type": "Optional[String[1]]"
},
"sql": {
"description": "The SQL you want to execute",
"type": "String[1]"
}
}
}
29 changes: 29 additions & 0 deletions tasks/sql.rb
@@ -0,0 +1,29 @@
#!/opt/puppetlabs/puppet/bin/ruby
require 'json'
require 'open3'
require 'puppet'

def get(sql, database, user, password)
cmd_string = "mysql -e \"#{sql}\""
cmd_string << " --database=#{database}" unless database.nil?
cmd_string << " --user=#{user}" unless user.nil?
cmd_string << " --password=#{password}" unless password.nil?
stdout, stderr, status = Open3.capture3(cmd_string)
raise Puppet::Error, _("stderr: '#{stderr}'") if status != 0
{ status: stdout.strip }
end

params = JSON.parse(STDIN.read)
database = params['database']
user = params['user']
password = params['password']
sql = params['sql']

begin
result = get(sql, database, user, password)
puts result.to_json
exit 0
rescue Puppet::Error => e
puts({ status: 'failure', error: e.message }.to_json)
exit 1
end

0 comments on commit 426bbc6

Please sign in to comment.