-
Notifications
You must be signed in to change notification settings - Fork 612
(MODULES-1394) replace validate_db_connection type with custom type #879
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
Merged
HelenCampbell
merged 3 commits into
puppetlabs:master
from
eputnam:validate_db_connection
Jun 12, 2017
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),"..","..","..")) | ||
require 'puppet/util/postgresql_validator' | ||
|
||
# This file contains a provider for the resource type `postgresql_conn_validator`, | ||
# which validates the puppetdb connection by attempting an https connection. | ||
|
||
Puppet::Type.type(:postgresql_conn_validator).provide(:ruby) do | ||
desc "A provider for the resource type `postgresql_conn_validator`, | ||
which validates the PostgreSQL connection by attempting a query | ||
to the target PostgreSQL server." | ||
|
||
# Test to see if the resource exists, returns true if it does, false if it | ||
# does not. | ||
# | ||
# Here we simply monopolize the resource API, to execute a test to see if the | ||
# database is connectable. When we return a state of `false` it triggers the | ||
# create method where we can return an error message. | ||
# | ||
# @return [bool] did the test succeed? | ||
def exists? | ||
validator.attempt_connection(resource[:sleep], resource[:tries]) | ||
end | ||
|
||
# This method is called when the exists? method returns false. | ||
# | ||
# @return [void] | ||
def create | ||
# If `#create` is called, that means that `#exists?` returned false, which | ||
# means that the connection could not be established... so we need to | ||
# cause a failure here. | ||
raise Puppet::Error, "Unable to connect to PostgreSQL server! (#{resource[:host]}:#{resource[:port]})" | ||
end | ||
|
||
# Returns the existing validator, if one exists otherwise creates a new object | ||
# from the class. | ||
# | ||
# @api private | ||
def validator | ||
@validator ||= Puppet::Util::PostgresqlValidator.new(resource) | ||
end | ||
|
||
end | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
Puppet::Type.newtype(:postgresql_conn_validator) do | ||
|
||
@doc = "Verify that a connection can be successfully established between a node | ||
and the PostgreSQL server. Its primary use is as a precondition to | ||
prevent configuration changes from being applied if the PostgreSQL | ||
server cannot be reached, but it could potentially be used for other | ||
purposes such as monitoring." | ||
|
||
ensurable do | ||
defaultvalues | ||
defaultto :present | ||
end | ||
|
||
newparam(:name, :namevar => true) do | ||
desc 'An arbitrary name used as the identity of the resource.' | ||
end | ||
|
||
newparam(:db_name) do | ||
desc "The name of the database you are trying to validate a connection with." | ||
end | ||
|
||
newparam(:db_username) do | ||
desc "A user that has access to the target PostgreSQL database." | ||
end | ||
|
||
newparam(:db_password) do | ||
desc "The password required to access the target PostgreSQL database." | ||
end | ||
|
||
newparam(:host) do | ||
desc 'The DNS name or IP address of the server where PostgreSQL should be running.' | ||
end | ||
|
||
newparam(:port) do | ||
desc 'The port that the PostgreSQL server should be listening on.' | ||
|
||
validate do |value| | ||
Integer(value) | ||
end | ||
munge do |value| | ||
Integer(value) | ||
end | ||
end | ||
|
||
newparam(:connect_settings) do | ||
desc 'Hash of environment variables for connection to a db.' | ||
end | ||
|
||
newparam(:sleep) do | ||
desc "The length of sleep time between connection tries." | ||
|
||
validate do |value| | ||
Integer(value) | ||
end | ||
munge do |value| | ||
Integer(value) | ||
end | ||
|
||
defaultto 2 | ||
end | ||
|
||
newparam(:tries) do | ||
desc "The number of tries to validate the connection to the target PostgreSQL database." | ||
|
||
validate do |value| | ||
Integer(value) | ||
end | ||
munge do |value| | ||
Integer(value) | ||
end | ||
|
||
defaultto 10 | ||
end | ||
|
||
newparam(:psql_path) do | ||
desc "Path to the psql command." | ||
end | ||
|
||
newparam(:run_as) do | ||
desc "System user that will run the psql command." | ||
end | ||
|
||
newparam(:command) do | ||
desc "Command to run against target database." | ||
|
||
defaultto "SELECT 1" | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
module Puppet | ||
module Util | ||
class PostgresqlValidator | ||
attr_reader :resource | ||
|
||
def initialize(resource) | ||
@resource = resource | ||
end | ||
|
||
def build_psql_cmd | ||
final_cmd = [] | ||
|
||
cmd_init = "#{@resource[:psql_path]} --tuples-only --quiet --no-psqlrc" | ||
|
||
final_cmd.push cmd_init | ||
|
||
cmd_parts = { | ||
:host => "--host=#{@resource[:host]}", | ||
:port => "--port=#{@resource[:port]}", | ||
:db_username => "--username=#{@resource[:db_username]}", | ||
:db_name => "--dbname=#{@resource[:db_name]}", | ||
:command => "--command='#{@resource[:command]}'" | ||
} | ||
|
||
cmd_parts[:db_password] = "--no-password " if @resource[:db_password] | ||
|
||
cmd_parts.each do |k,v| | ||
final_cmd.push v if @resource[k] | ||
end | ||
|
||
final_cmd.join ' ' | ||
end | ||
|
||
def parse_connect_settings | ||
c_settings = @resource[:connect_settings] || {} | ||
c_settings.merge! ({ 'PGPASSWORD' => @resource[:db_password] }) if @resource[:db_password] | ||
return c_settings.map { |k,v| "#{k}=#{v}" } | ||
end | ||
|
||
def attempt_connection(sleep_length, tries) | ||
(0..tries-1).each do |try| | ||
Puppet.debug "PostgresqlValidator.attempt_connection: Attempting connection to #{@resource[:db_name]}" | ||
if execute_command =~ /1/ | ||
Puppet.debug "PostgresqlValidator.attempt_connection: Connection to #{@resource[:db_name]} successful!" | ||
return true | ||
else | ||
Puppet.warning "PostgresqlValidator.attempt_connection: Sleeping for #{sleep_length} seconds" | ||
sleep sleep_length | ||
end | ||
end | ||
false | ||
end | ||
|
||
private | ||
|
||
def execute_command | ||
Execution.execute(build_validate_cmd, :uid => @resource[:run_as]) | ||
end | ||
|
||
def build_validate_cmd | ||
"#{parse_connect_settings.join(' ')} #{build_psql_cmd} " | ||
end | ||
end | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Postgres has the
PQping()
command on its binary protocol to issue a connection check. It can be used withpg_isready
binary. I think it would make a good default provider. It would be more efficient and easier to use, because you don't need to pass authentication. It also supports a custom timeout.