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

Add option in postgres_session resource to establish socket connection #5664

Merged
merged 2 commits into from Sep 28, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions docs-chef-io/content/inspec/resources/postgres_session.md
Expand Up @@ -28,24 +28,27 @@ This resource first became available in v1.0.0 of InSpec.
A `postgres_session` resource block declares the username and password to use for the session, and then the command to be run:

# Create a PostgreSQL session:
sql = postgres_session('username', 'password', 'host', 'port')
sql = postgres_session('username', 'password', 'host', 'port', 'socketpath')

# default values:
# username: 'postgres'
# host: 'localhost'
# port: 5432
# socketpath (optional): nil

# Run an SQL query with an optional database to execute
sql.query('sql_query', ['database_name'])`

A full example is:

sql = postgres_session('username', 'password', 'host', 'port')
sql = postgres_session('username', 'password', 'host', 'port', 'socketpath')
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
its('output') { should eq '' }
end

where `its('output') { should eq '' }` compares the results of the query against the expected result in the test
where
- `its('output') { should eq '' }` compares the results of the query against the expected result in the test
- `socketpath` is an optional parameter. Use `socketpath` to establish a socket connection with Postgres by specifying one of the Postgres Unix domain socket paths. Only supported on Unix-based platforms.

## Examples

Expand Down
19 changes: 15 additions & 4 deletions lib/inspec/resources/postgres_session.rb
Expand Up @@ -40,11 +40,12 @@ class PostgresSession < Inspec.resource(1)
end
EXAMPLE

def initialize(user, pass, host = nil, port = nil)
def initialize(user, pass, host = nil, port = nil, socket_path = nil)
@user = user || "postgres"
@pass = pass
@host = host || "localhost"
@port = port || 5432
@socket_path = socket_path
raise Inspec::Exceptions::ResourceFailed, "Can't run PostgreSQL SQL checks without authentication." if @user.nil? || @pass.nil?
end

Expand All @@ -69,10 +70,20 @@ def escaped_query(query)

def create_psql_cmd(query, db = [])
dbs = db.map { |x| "#{x}" }.join(" ")
if inspec.os.windows?
"psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c \"#{query}\""

if @socket_path && !inspec.os.windows?
# Socket path and empty host in the connection string establishes socket connection
# Socket connection only enabled for non-windows platforms
# Windows does not support unix domain sockets
"psql -d postgresql://#{@user}:#{@pass}@/#{dbs}?host=#{@socket_path} -A -t -w -c #{escaped_query(query)}"
Vasu1105 marked this conversation as resolved.
Show resolved Hide resolved
else
"psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c #{escaped_query(query)}"
# Host in connection string establishes tcp/ip connection
if inspec.os.windows?
warn "Socket based connection not supported in windows, connecting using host" if @socket_path
"psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c \"#{query}\""
else
"psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c #{escaped_query(query)}"
end
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions test/unit/resources/postgres_session_test.rb
Expand Up @@ -37,4 +37,9 @@
resource = load_resource("postgres_session", "postgres", "postgres", "localhost", 5432)
_(proc { resource.send(:query, "Select 5;", ["mydatabase"]) }).must_raise Inspec::Exceptions::ResourceFailed
end

it "verify postgres_session create_psql_cmd in socket connection" do
resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1", 5432, "/var/run/postgresql")
_(resource.send(:create_psql_cmd, "SELECT * FROM STUDENTS;", ["testdb"])).must_equal "psql -d postgresql://myuser:mypass@/testdb?host=/var/run/postgresql -A -t -w -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;"
end
end