-
Notifications
You must be signed in to change notification settings - Fork 614
(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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
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| | ||
if value | ||
value =~ /[0-9]+/ | ||
end | ||
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 | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
module Puppet | ||
module Util | ||
class PostgresqlValidator | ||
attr_reader :resource | ||
|
||
def initialize(resource) | ||
@resource = resource | ||
end | ||
|
||
def build_psql_cmd | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Postgres has the |
||
final_cmd = [] | ||
|
||
cmd_init = "#{@resource[:psql_path]} --tuples-only --quiet " | ||
|
||
final_cmd.push cmd_init | ||
|
||
cmd_parts = { | ||
:host => "-h #{@resource[:host]}", | ||
:port => "-p #{@resource[:port]}", | ||
:db_username => "-U #{@resource[:db_username]}", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some short and some long arguments don't please my eyes. I prefer |
||
:db_name => "--dbname #{@resource[:db_name]}" | ||
} | ||
|
||
cmd_parts[:db_password] = "-w " 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 | ||
"/bin/echo 'SELECT 1' | #{parse_connect_settings.join(' ')} #{build_psql_cmd} " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't spawn another process but use |
||
end | ||
end | ||
end | ||
end |
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.
Maybe it is better to check this as an integer.