Class: Inspec::Resources::SybaseSession

Inherits:
Object
  • Object
show all
Defined in:
lib/inspec/resources/sybase_session.rb

Overview

STABILITY: Experimental This resource needs further testing and refinement

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ SybaseSession

Returns a new instance of SybaseSession.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/inspec/resources/sybase_session.rb', line 27

def initialize(opts = {})
  @username = opts[:username]
  @password = opts[:password]
  @database = opts[:database]
  @server = opts[:server]
  @sybase_home = opts[:sybase_home] || "/opt/sap"
  @bin = opts[:bin] || "isql"
  @col_sep = "|"

  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?
end

Instance Attribute Details

#binObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def bin
  @bin
end

#col_sepObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def col_sep
  @col_sep
end

#databaseObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def database
  @database
end

#passwordObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def password
  @password
end

#serverObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def server
  @server
end

#sybase_homeObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def sybase_home
  @sybase_home
end

#usernameObject (readonly)

TODO: allow to set -I interfaces file TODO: allow to customize -s column separator



25
26
27
# File 'lib/inspec/resources/sybase_session.rb', line 25

def username
  @username
end

Instance Method Details

#query(sql) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/inspec/resources/sybase_session.rb', line 42

def query(sql)
  # We must write the SQl to a temp file on the remote target
  # try to get a temp path
  sql_file_path = upload_sql_file(sql)

  # TODO: Find if there is better way to get the current shell
  current_shell = inspec.command("echo $SHELL")

  res = current_shell.exit_status

  # isql reuires that we have a matching locale set, but does not support C.UTF-8. en_US.UTF-8 is the least evil.
  if res == 0 && ( current_shell.stdout&.include?("/csh") || current_shell.stdout&.include?("/tcsh") )
    command = "source #{sybase_home}/SYBASE.csh; setenv LANG en_US.UTF-8; #{bin} -s\"#{col_sep}\" -w80000 -S #{server} -U #{username} -D #{database} -P \"#{password}\" < #{sql_file_path}"
  else
    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}"
  end

  isql_cmd = inspec.command(command)
  # 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

#resource_idObject



76
77
78
# File 'lib/inspec/resources/sybase_session.rb', line 76

def resource_id
  @database || "Sybase Session"
end

#to_sObject



80
81
82
# File 'lib/inspec/resources/sybase_session.rb', line 80

def to_s
  "Sybase Session"
end