From c28bacdab7e80105d41c5f16f18617b249c6cac8 Mon Sep 17 00:00:00 2001 From: Nikita Mathur Date: Wed, 16 Jun 2021 19:37:56 +0530 Subject: [PATCH 1/4] Oracle session exception handling Signed-off-by: Nikita Mathur --- lib/inspec/resources/oracledb_session.rb | 12 +++++-- test/unit/resources/oracledb_session_test.rb | 33 ++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/lib/inspec/resources/oracledb_session.rb b/lib/inspec/resources/oracledb_session.rb index 19be00943..cf2da5c75 100644 --- a/lib/inspec/resources/oracledb_session.rb +++ b/lib/inspec/resources/oracledb_session.rb @@ -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,13 @@ 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 || out.downcase =~ /^error.*/ + raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}" + else + DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout)) + end end def to_s diff --git a/test/unit/resources/oracledb_session_test.rb b/test/unit/resources/oracledb_session_test.rb index be7f7fc70..f46ab9fdb 100644 --- a/test/unit/resources/oracledb_session_test.rb +++ b/test/unit/resources/oracledb_session_test.rb @@ -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 From d08b8bb8f3ed20c3e5ea2803805cfa7b6b92d49f Mon Sep 17 00:00:00 2001 From: Nikita Mathur Date: Fri, 18 Jun 2021 14:14:25 +0530 Subject: [PATCH 2/4] exception handling when exception in case of no error Signed-off-by: Nikita Mathur --- lib/inspec/resources/oracledb_session.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/inspec/resources/oracledb_session.rb b/lib/inspec/resources/oracledb_session.rb index cf2da5c75..0eeb06990 100644 --- a/lib/inspec/resources/oracledb_session.rb +++ b/lib/inspec/resources/oracledb_session.rb @@ -56,10 +56,14 @@ module Inspec::Resources inspec_cmd = inspec.command(command) out = inspec_cmd.stdout + "\n" + inspec_cmd.stderr - if inspec_cmd.exit_status != 0 || out.downcase =~ /^error.*/ + if inspec_cmd.exit_status != 0 || !inspec_cmd.stderr.empty? || out.downcase =~ /^error.*/ raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}" else - DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout)) + 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 From 88641c3fac0f0862a65c11d5eb3339799b8824af Mon Sep 17 00:00:00 2001 From: Nikita Mathur Date: Mon, 21 Jun 2021 12:09:53 +0530 Subject: [PATCH 3/4] Fix in oracle command which weren't working in windows powershell Signed-off-by: Nikita Mathur --- lib/inspec/resources/oracledb_session.rb | 6 +++--- test/unit/resources/oracledb_session_test.rb | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/inspec/resources/oracledb_session.rb b/lib/inspec/resources/oracledb_session.rb index 0eeb06990..4da2de5e4 100644 --- a/lib/inspec/resources/oracledb_session.rb +++ b/lib/inspec/resources/oracledb_session.rb @@ -87,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 diff --git a/test/unit/resources/oracledb_session_test.rb b/test/unit/resources/oracledb_session_test.rb index f46ab9fdb..eeca847ec 100644 --- a/test/unit/resources/oracledb_session_test.rb +++ b/test/unit/resources/oracledb_session_test.rb @@ -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 @@ -73,7 +73,7 @@ describe "Inspec::Resources::OracledbSession" 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 + 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 @@ -87,7 +87,7 @@ describe "Inspec::Resources::OracledbSession" 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 + 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 From 7ec66a0ca95204d31295ae01e48f09a63bd080ed Mon Sep 17 00:00:00 2001 From: Nikita Mathur Date: Thu, 24 Jun 2021 00:13:03 +0530 Subject: [PATCH 4/4] Missing oracle-error file added for testing Signed-off-by: Nikita Mathur --- test/fixtures/cmd/oracle-error | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/fixtures/cmd/oracle-error diff --git a/test/fixtures/cmd/oracle-error b/test/fixtures/cmd/oracle-error new file mode 100644 index 000000000..299937c0f --- /dev/null +++ b/test/fixtures/cmd/oracle-error @@ -0,0 +1 @@ +error: sqlplus: command not found \ No newline at end of file