Merge pull request #5567 from inspec/nm/oracle-session-exception

Oracle Session Exception Handling
This commit is contained in:
Clinton Wolfe 2021-06-29 00:47:23 -04:00 committed by GitHub
commit 61c83d28b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 11 deletions

View file

@ -38,11 +38,12 @@ module Inspec::Resources
@sqlcl_bin = opts[:sqlcl_bin] || nil
@sqlplus_bin = opts[:sqlplus_bin] || "sqlplus"
skip_resource "Option 'as_os_user' not available in Windows" if inspec.os.windows? && su_user
fail_resource "Can't run Oracle checks without authentication" unless su_user && (user || password)
fail_resource "You must provide a service name for the session" unless service
fail_resource "Can't run Oracle checks without authentication" unless su_user || (user || password)
end
def query(sql)
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
if @sqlcl_bin && inspec.command(@sqlcl_bin).exist?
@bin = @sqlcl_bin
format_options = "set sqlformat csv\nSET FEEDBACK OFF"
@ -53,8 +54,17 @@ module Inspec::Resources
command = command_builder(format_options, sql)
inspec_cmd = inspec.command(command)
out = inspec_cmd.stdout + "\n" + inspec_cmd.stderr
DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout))
if inspec_cmd.exit_status != 0 || !inspec_cmd.stderr.empty? || out.downcase =~ /^error.*/
raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}"
else
begin
DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout))
rescue
raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}"
end
end
end
def to_s
@ -77,11 +87,11 @@ module Inspec::Resources
end
if @db_role.nil?
%{#{sql_prefix}#{bin} "#{user}"/"#{password}"@#{host}:#{port}/#{@service}#{sql_postfix}}
"#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}"
elsif @su_user.nil?
%{#{sql_prefix}#{bin} "#{user}"/"#{password}"@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
"#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}"
else
%{su - #{@su_user} -c "env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
"su - #{@su_user} -c env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"
end
end

1
test/fixtures/cmd/oracle-error vendored Normal file
View file

@ -0,0 +1 @@
error: sqlplus: command not found

View file

@ -7,7 +7,7 @@ describe "Inspec::Resources::OracledbSession" do
resource = quick_resource(:oracledb_session, :linux, user: "USER", password: "password", host: "localhost", service: "ORCL", port: 1527, sqlplus_bin: "/bin/sqlplus") do |cmd|
cmd.strip!
case cmd
when "/bin/sqlplus -S \"USER\"/\"password\"@localhost:1527/ORCL <<'EOC'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\nEOC" then
when "/bin/sqlplus -S USER/password@localhost:1527/ORCL <<'EOC'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\nEOC" then
stdout_file "test/fixtures/cmd/oracle-result"
else
raise cmd.inspect
@ -24,7 +24,7 @@ describe "Inspec::Resources::OracledbSession" do
resource = quick_resource(:oracledb_session, :windows, user: "USER", password: "password", host: "localhost", service: "ORCL", port: 1527, sqlplus_bin: "C:/sqlplus.exe") do |cmd|
cmd.strip!
case cmd
when "@'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\n'@ | C:/sqlplus.exe -S \"USER\"/\"password\"@localhost:1527/ORCL" then
when "@'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\n'@ | C:/sqlplus.exe -S USER/password@localhost:1527/ORCL" then
stdout_file "test/fixtures/cmd/oracle-result"
else
raise cmd.inspect
@ -51,11 +51,10 @@ describe "Inspec::Resources::OracledbSession" do
_(resource.resource_exception_message).must_equal "Can't run Oracle checks without authentication"
end
it "fails when no service name is provided" do
it "does not fails when no service name is provided" do
resource = quick_resource(:oracledb_session, :windows, user: "USER", password: "password", host: "localhost", port: 1527, sqlplus_bin: "C:/sqlplus.exe")
_(resource.resource_failed?).must_equal true
_(resource.resource_exception_message).must_equal "You must provide a service name for the session"
_(resource.resource_failed?).must_equal false
end
it "verify oracledb_session configuration" do
@ -69,4 +68,32 @@ describe "Inspec::Resources::OracledbSession" do
_(resource.su_user).must_equal "osuser"
_(resource.bin).must_equal "sqlplus"
end
it "fails when no connection established in linux" do
resource = quick_resource(:oracledb_session, :linux, user: "USER", password: "wrongpassword", host: "localhost", service: "ORCL", port: 1527, sqlplus_bin: "/bin/sqlplus") do |cmd|
cmd.strip!
case cmd
when "/bin/sqlplus -S USER/wrongpassword@localhost:1527/ORCL <<'EOC'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\nEOC" then
stdout_file "test/fixtures/cmd/oracle-error"
else
raise cmd.inspect
end
end
ex = assert_raises(Inspec::Exceptions::ResourceFailed) { resource.query("SELECT NAME AS VALUE FROM v$database") }
_(ex.message).must_include("Oracle query with errors")
end
it "fails when no connection established in windows" do
resource = quick_resource(:oracledb_session, :windows, user: "USER", password: "wrongpassword", host: "localhost", service: "ORCL", port: 1527, sqlplus_bin: "C:/sqlplus.exe") do |cmd|
cmd.strip!
case cmd
when "@'\nSET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF\nSELECT NAME AS VALUE FROM v$database;\nEXIT\n'@ | C:/sqlplus.exe -S USER/wrongpassword@localhost:1527/ORCL" then
stdout_file "test/fixtures/cmd/oracle-error"
else
raise cmd.inspect
end
ex = assert_raises(Inspec::Exceptions::ResourceFailed) { resource.query("SELECT NAME AS VALUE FROM v$database") }
_(ex.message).must_include("Oracle query with errors")
end
end
end