mirror of
https://github.com/inspec/inspec
synced 2024-11-27 07:00:39 +00:00
Add error handling and output handling to sybase_session
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
parent
99ae095c66
commit
7da5c4aec3
1 changed files with 22 additions and 13 deletions
|
@ -32,7 +32,7 @@ module Inspec::Resources
|
|||
@bin = opts[:bin] || "isql"
|
||||
@col_sep = "|"
|
||||
|
||||
fail_resource "Can't run Sybase checks without authentication" unless (username && password)
|
||||
fail_resource "Can't run Sybase checks without authentication" unless username && password
|
||||
fail_resource "You must provide a server name for the session" unless server
|
||||
fail_resource "You must provide a database name for the session" unless database
|
||||
fail_resource "Cannot find #{bin} CLI tool" unless inspec.command(bin).exist?
|
||||
|
@ -45,19 +45,27 @@ module Inspec::Resources
|
|||
|
||||
# TODO: replace echos with a a train upload command if possible.
|
||||
# echos are senstive to shell interpolation, such as the asterisk in SELECT *
|
||||
res = inspec.command("echo #{sql} > #{sql_file_path}").exit_status # TODO: handle
|
||||
res = inspec.command("echo go >> #{sql_file_path}").exit_status # TODO: handle
|
||||
inspec.command("echo #{sql} > #{sql_file_path}").exit_status # TODO: handle
|
||||
inspec.command("echo go >> #{sql_file_path}").exit_status # TODO: handle
|
||||
|
||||
# isql reuires that we have a matching locale set, but does not support C.UTF-8. en_US.UTF-8 is the least evil.
|
||||
command = "LANG=en_US.UTF-8 SYBASE=#{sybase_home} #{bin} -s\"#{col_sep}\" -w80000 -S #{server} -U #{username} -D #{database} -P \"#{password}\" < #{sql_file_path}"
|
||||
inspec_cmd = inspec.command(command)
|
||||
isql_cmd = inspec.command(command)
|
||||
|
||||
# TODO: isql is ill-behaved, and returns 0 on error
|
||||
# TODO: check sdterr for errors on 0 return
|
||||
# TODO: check stdout for error messages when stderr is empty "Msg 102, Level 15, State 181:\nServer 'SYBASE', Line 1:\nIncorrect syntax near '.'.\n"
|
||||
res = inspec_cmd.exit_status # TODO: handle
|
||||
res = inspec.command("rm #{sql_file_path}").exit_status # TODO: handle
|
||||
DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout))
|
||||
# Check for isql errors
|
||||
res = isql_cmd.exit_status
|
||||
raise Inspec::Exceptions::ResourceFailed.new("isql exited with code #{res} and stderr '#{isql_cmd.stderr}', stdout '#{isql_cmd.stdout}'") unless res == 0
|
||||
# isql is ill-behaved, and returns 0 on error
|
||||
raise Inspec::Exceptions::ResourceFailed.new("isql exited with error '#{isql_cmd.stderr}', stdout '#{isql_cmd.stdout}'") unless isql_cmd.stderr == ""
|
||||
# check stdout for error messages when stderr is empty "Msg 102, Level 15, State 181:\nServer 'SYBASE', Line 1:\nIncorrect syntax near '.'.\n"
|
||||
raise Inspec::Exceptions::ResourceFailed.new("isql exited with error #{isql_cmd.stdout}") if isql_cmd.stdout.match?(/Msg\s\d+,\sLevel\s\d+,\sState\s\d+/)
|
||||
|
||||
# Clean up temporary file
|
||||
rm_cmd = inspec.command("rm #{sql_file_path}")
|
||||
res = rm_cmd.exit_status # TODO: handle
|
||||
raise Inspec::Exceptions::ResourceFailed.new("Unable to delete temproary SQL input file at #{sql_file_path}: #{rm_cmd.stderr}") unless res == 0
|
||||
|
||||
DatabaseHelper::SQLQueryResult.new(isql_cmd, parse_csv_result(isql_cmd.stdout))
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -68,11 +76,12 @@ module Inspec::Resources
|
|||
|
||||
def parse_csv_result(stdout)
|
||||
output = stdout.sub(/\r/, "").strip
|
||||
# TODO: remove second header row
|
||||
# TODO: remove trailing blank line and summary line (23 rows affected)
|
||||
lines = output.lines
|
||||
# Remove second row (all dashes) and last two rows (blank and summary line)
|
||||
trimmed_output = ([lines[0]] << lines.slice(2..-3)).join("\n")
|
||||
header_converter = ->(header) { header.downcase.strip }
|
||||
field_converter = ->(field) { field&.strip }
|
||||
CSV.parse(output, headers: true, header_converters: header_converter, converters: field_converter, col_sep: col_sep).map { |row| Hashie::Mash.new(row.to_h) }
|
||||
CSV.parse(trimmed_output, headers: true, header_converters: header_converter, converters: field_converter, col_sep: col_sep).map { |row| Hashie::Mash.new(row.to_h) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue