inspec-core 4.21.1 → 4.22.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/inspec-core.gemspec +2 -4
  4. data/lib/bundles/inspec-supermarket/cli.rb +1 -1
  5. data/lib/inspec/base_cli.rb +2 -2
  6. data/lib/inspec/config.rb +0 -1
  7. data/lib/inspec/exceptions.rb +1 -0
  8. data/lib/inspec/input_registry.rb +2 -1
  9. data/lib/inspec/metadata.rb +6 -1
  10. data/lib/inspec/plugin/v2/plugin_types/reporter.rb +11 -5
  11. data/lib/inspec/profile.rb +30 -9
  12. data/lib/inspec/reporters.rb +0 -3
  13. data/lib/inspec/reporters/automate.rb +3 -3
  14. data/lib/inspec/reporters/base.rb +11 -5
  15. data/lib/inspec/reporters/cli.rb +1 -0
  16. data/lib/inspec/reporters/json.rb +9 -4
  17. data/lib/inspec/resources/apt.rb +2 -0
  18. data/lib/inspec/resources/bridge.rb +1 -1
  19. data/lib/inspec/resources/host.rb +1 -1
  20. data/lib/inspec/resources/mount.rb +1 -1
  21. data/lib/inspec/resources/mysql_session.rb +31 -8
  22. data/lib/inspec/resources/postgres.rb +1 -1
  23. data/lib/inspec/resources/postgres_session.rb +1 -1
  24. data/lib/inspec/resources/service.rb +2 -2
  25. data/lib/inspec/resources/users.rb +1 -1
  26. data/lib/inspec/resources/windows_firewall.rb +110 -0
  27. data/lib/inspec/resources/windows_firewall_rule.rb +137 -0
  28. data/lib/inspec/run_data.rb +1 -1
  29. data/lib/inspec/run_data/profile.rb +4 -4
  30. data/lib/inspec/runner.rb +8 -2
  31. data/lib/inspec/runner_rspec.rb +4 -1
  32. data/lib/inspec/schema.rb +2 -0
  33. data/lib/inspec/schema/exec_json.rb +4 -3
  34. data/lib/inspec/schema/primitives.rb +1 -1
  35. data/lib/inspec/utils/parser.rb +1 -1
  36. data/lib/inspec/version.rb +1 -1
  37. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +4 -4
  38. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +1 -1
  39. data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +5 -2
  40. data/lib/plugins/inspec-reporter-junit/README.md +15 -0
  41. data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb +12 -0
  42. data/lib/{inspec/reporters/junit.rb → plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb} +22 -26
  43. data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb +5 -0
  44. metadata +16 -34
  45. data/README.md +0 -474
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7be94754504cd2aeda9badd0701a9ac28691e0c62f76741db0c3b1b75988b2b
4
- data.tar.gz: 314ce4bedf429cb87185f4903bcb5e47c93587fc1c125f9dcff112574f5dde72
3
+ metadata.gz: feb9a92b579da111caf36845c7ba22e6d0831233d59c5f6f5de0212aa8ef529c
4
+ data.tar.gz: 945341a0aa073b969ce15e35d058246af5584d3ddfb94a5b7ffbd86cb8162254
5
5
  SHA512:
6
- metadata.gz: fa7f2ac74a61e23f82236d175b5adcc4236eb6b48316d7eaca9cfa85fe9f3917a22eb87fc56723ff56635348897e21f635816071fcf1c13a2f808df212388693
7
- data.tar.gz: 17245f5ba3ca9aad13bba4870e52bf48c2e2cf2219b03ee569d0a1aa2e699bd2b6de447d30a2d23c44e01c72ded87c9dab596e564eb9206f7826ae72f6b4d366
6
+ metadata.gz: 148281428e3b5d2855a2c89eccb3a29e4b159933b025049d9852eab4336b9ffb0f267bb48701b208c06fc71ce2c173fe175466622b3ec535ddb4a2692d3d927f
7
+ data.tar.gz: ac2e46f5dc21b7359b76df729d6b47c0f51f1f8bd272872121477204f3422d49028982a39a01df60a4ae796f03ccb41f6a448a994e22e2feb7e4d946b574cc27
data/Gemfile CHANGED
@@ -19,7 +19,7 @@ group :omnibus do
19
19
  end
20
20
 
21
21
  group :test do
22
- gem "chefstyle", "~> 0.13.0"
22
+ gem "chefstyle", "~> 1.2.1"
23
23
  gem "minitest", "~> 5.5"
24
24
  gem "minitest-sprint", "~> 1.0"
25
25
  gem "rake", ">= 10"
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  # the gemfile and gemspec are necessary for appbundler so don't remove it
19
19
  spec.files =
20
- Dir.glob("{{lib,etc}/**/*,README.md,LICENSE,Gemfile,inspec-core.gemspec}")
20
+ Dir.glob("{{lib,etc}/**/*,LICENSE,Gemfile,inspec-core.gemspec}")
21
21
  .grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp)})
22
22
  .grep_v(%r{lib/plugins/.*/test/})
23
23
  .reject { |f| File.directory?(f) }
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "chef-telemetry", "~> 1.0"
27
27
  spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
28
28
  spec.add_dependency "thor", ">= 0.20", "< 2.0"
29
- spec.add_dependency "json_schemer", "~> 0.2.1"
29
+ spec.add_dependency "json_schemer", ">= 0.2.1", "< 0.2.12"
30
30
  spec.add_dependency "method_source", ">= 0.8", "< 2.0"
31
31
  spec.add_dependency "rubyzip", "~> 1.2", ">= 1.2.2"
32
32
  spec.add_dependency "rspec", "~> 3.9"
@@ -43,9 +43,7 @@ Gem::Specification.new do |spec|
43
43
  spec.add_dependency "addressable", "~> 2.4"
44
44
  spec.add_dependency "parslet", "~> 1.5"
45
45
  spec.add_dependency "semverse", "~> 3.0"
46
- spec.add_dependency "htmlentities", "~> 4.3" # TODO: remove when #4853 fixed
47
46
  spec.add_dependency "multipart-post", "~> 2.0"
48
- spec.add_dependency "term-ansicolor", "~> 1.7"
49
47
 
50
48
  spec.add_dependency "train-core", "~> 3.0"
51
49
  end
@@ -5,7 +5,7 @@ module Supermarket
5
5
  class SupermarketCLI < Inspec::BaseCLI
6
6
  namespace "supermarket"
7
7
 
8
- # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
8
+ # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed.
9
9
  def self.banner(command, _namespace = nil, _subcommand = false)
10
10
  "#{basename} #{subcommand_prefix} #{command.usage}"
11
11
  end
@@ -60,7 +60,7 @@ module Inspec
60
60
  true
61
61
  end
62
62
 
63
- def self.target_options # rubocop:disable MethodLength
63
+ def self.target_options # rubocop:disable Metrics/MethodLength
64
64
  option :target, aliases: :t, type: :string,
65
65
  desc: "Simple targeting option using URIs, e.g. ssh://user:pass@host:port"
66
66
  option :backend, aliases: :b, type: :string,
@@ -231,7 +231,7 @@ module Inspec
231
231
 
232
232
  private
233
233
 
234
- ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html yaml documentation progress}.freeze # BUT WHY?!?!
234
+ ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html html2 yaml documentation progress}.freeze # BUT WHY?!?!
235
235
 
236
236
  def suppress_log_output?(opts)
237
237
  return false if opts["reporter"].nil?
@@ -344,7 +344,6 @@ module Inspec
344
344
  cli
345
345
  json
346
346
  json-automate
347
- junit
348
347
  yaml
349
348
  }
350
349
 
@@ -4,6 +4,7 @@ module Inspec
4
4
  module Exceptions
5
5
  class InputsFileDoesNotExist < ArgumentError; end
6
6
  class InputsFileNotReadable < ArgumentError; end
7
+ class ProfileLoadFailed < StandardError; end
7
8
  class ResourceFailed < StandardError; end
8
9
  class ResourceSkipped < StandardError; end
9
10
  class SecretsBackendNotFound < ArgumentError; end
@@ -165,7 +165,8 @@ module Inspec
165
165
  raise ArgumentError, "ERROR: An '=' is required when using --input. Usage: --input input_name1=input_value1 input2=value2"
166
166
  end
167
167
  end
168
- input_name, input_value = pair.split("=")
168
+ pair = pair.match(/(.*?)=(.*)/)
169
+ input_name, input_value = pair[1], pair[2]
169
170
  input_value = parse_cli_input_value(input_name, input_value)
170
171
  evt = Inspec::Input::Event.new(
171
172
  value: input_value,
@@ -9,7 +9,12 @@ require "inspec/version"
9
9
  require "inspec/utils/spdx"
10
10
 
11
11
  module Inspec
12
- # Extract metadata.rb information
12
+ # The Metadata class represents a profile's metadata.
13
+ # This includes the metadata stored in the profile's metadata.rb file, as well as inferred
14
+ # metadata like if this profile supports the current runtime and the intended target.
15
+ # This class does NOT represent the runtime state of a profile during execution.
16
+ # See lib/inspec/profile.rb for the runtime representation of a profile.
17
+ #
13
18
  # A Metadata object may be created and finalized with invalid data.
14
19
  # This allows the check CLI command to analyse the issues.
15
20
  # Use valid? to determine if the metadata is coherent.
@@ -31,17 +31,14 @@ module Inspec::Plugin::V2::PluginType
31
31
  runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
32
32
 
33
33
  message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
34
- trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
34
+ @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
35
35
  include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
36
36
 
37
37
  @run_data[:profiles]&.each do |p|
38
38
  p[:controls].each do |c|
39
39
  c[:results]&.map! do |r|
40
40
  r.delete(:backtrace) unless include_backtrace
41
- if r.key?(:message) && r[:message] != "" && trunc > -1
42
- r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
43
- end
44
- r
41
+ process_message_truncation(r)
45
42
  end
46
43
  end
47
44
  end
@@ -64,5 +61,14 @@ module Inspec::Plugin::V2::PluginType
64
61
  def self.run_data_schema_constraints
65
62
  raise NotImplementedError, "#{self.class} must implement a `run_data_schema_constraints` class method to declare its compatibiltity with the RunData API."
66
63
  end
64
+
65
+ private
66
+
67
+ def process_message_truncation(result)
68
+ if result.key?(:message) && result[:message] != "" && @trunc > -1 && result[:message].length > @trunc
69
+ result[:message] = result[:message][0...@trunc] + "[Truncated to #{@trunc} characters]"
70
+ end
71
+ result
72
+ end
67
73
  end
68
74
  end
@@ -94,6 +94,7 @@ module Inspec
94
94
  @input_values = options[:inputs]
95
95
  @tests_collected = false
96
96
  @libraries_loaded = false
97
+ @state = :loaded
97
98
  @check_mode = options[:check_mode] || false
98
99
  @parent_profile = options[:parent_profile]
99
100
  @legacy_profile_path = options[:profiles_path] || false
@@ -146,7 +147,12 @@ module Inspec
146
147
  options[:profile_context] ||
147
148
  Inspec::ProfileContext.for_profile(self, @backend)
148
149
 
149
- @supports_platform = metadata.supports_platform?(@backend)
150
+ if metadata.supports_platform?(@backend)
151
+ @supports_platform = true
152
+ else
153
+ @supports_platform = false
154
+ @state = :skipped
155
+ end
150
156
  @supports_runtime = metadata.supports_runtime?
151
157
  end
152
158
 
@@ -162,6 +168,10 @@ module Inspec
162
168
  @writable
163
169
  end
164
170
 
171
+ def failed?
172
+ @state == :failed
173
+ end
174
+
165
175
  #
166
176
  # Is this profile is supported on the current platform of the
167
177
  # backend machine and the current inspec version.
@@ -197,7 +207,7 @@ module Inspec
197
207
  end
198
208
 
199
209
  def collect_tests(include_list = @controls)
200
- unless @tests_collected
210
+ unless @tests_collected || failed?
201
211
  return unless supports_platform?
202
212
 
203
213
  locked_dependencies.each(&:collect_tests)
@@ -206,7 +216,12 @@ module Inspec
206
216
  next if content.nil? || content.empty?
207
217
 
208
218
  abs_path = source_reader.target.abs_path(path)
209
- @runner_context.load_control_file(content, abs_path, nil)
219
+ begin
220
+ @runner_context.load_control_file(content, abs_path, nil)
221
+ rescue => e
222
+ @state = :failed
223
+ raise Inspec::Exceptions::ProfileLoadFailed, "Failed to load source for #{path}: #{e}"
224
+ end
210
225
  end
211
226
  @tests_collected = true
212
227
  end
@@ -249,12 +264,13 @@ module Inspec
249
264
  d = dep.profile
250
265
  # this will force a dependent profile load so we are only going to add
251
266
  # this metadata if the parent profile is supported.
252
- if supports_platform? && !d.supports_platform?
267
+ if @supports_platform && !d.supports_platform?
253
268
  # since ruby 1.9 hashes are ordered so we can just use index values here
254
269
  # TODO: NO! this is a violation of encapsulation to an extreme
255
270
  metadata.dependencies[i][:status] = "skipped"
256
271
  msg = "Skipping profile: '#{d.name}' on unsupported platform: '#{d.backend.platform.name}/#{d.backend.platform.release}'."
257
- metadata.dependencies[i][:skip_message] = msg
272
+ metadata.dependencies[i][:status_message] = msg
273
+ metadata.dependencies[i][:skip_message] = msg # Repeat as skip_message for backward compatibility
258
274
  next
259
275
  elsif metadata.dependencies[i]
260
276
  # Currently wrapper profiles will load all dependencies, and then we
@@ -324,12 +340,13 @@ module Inspec
324
340
  res[:sha256] = sha256
325
341
  res[:parent_profile] = parent_profile unless parent_profile.nil?
326
342
 
327
- if !supports_platform?
343
+ if @supports_platform
344
+ res[:status_message] = @status_message || ""
345
+ res[:status] = failed? ? "failed" : "loaded"
346
+ else
328
347
  res[:status] = "skipped"
329
348
  msg = "Skipping profile: '#{name}' on unsupported platform: '#{backend.platform.name}/#{backend.platform.release}'."
330
- res[:skip_message] = msg
331
- else
332
- res[:status] = "loaded"
349
+ res[:status_message] = msg
333
350
  end
334
351
 
335
352
  # convert legacy os-* supports to their platform counterpart
@@ -455,6 +472,10 @@ module Inspec
455
472
  params[:controls].values.length
456
473
  end
457
474
 
475
+ def set_status_message(msg)
476
+ @status_message = msg.to_s
477
+ end
478
+
458
479
  # generates a archive of a folder profile
459
480
  # assumes that the profile was checked before
460
481
  def archive(opts)
@@ -2,7 +2,6 @@ require "inspec/reporters/base"
2
2
  require "inspec/reporters/cli"
3
3
  require "inspec/reporters/json"
4
4
  require "inspec/reporters/json_automate"
5
- require "inspec/reporters/junit"
6
5
  require "inspec/reporters/automate"
7
6
  require "inspec/reporters/yaml"
8
7
 
@@ -20,8 +19,6 @@ module Inspec::Reporters
20
19
  # right to introduce breaking changes to this reporter at any time.
21
20
  when "json-automate"
22
21
  reporter = Inspec::Reporters::JsonAutomate.new(config)
23
- when "junit"
24
- reporter = Inspec::Reporters::Junit.new(config)
25
22
  when "automate"
26
23
  reporter = Inspec::Reporters::Automate.new(config)
27
24
  when "yaml"
@@ -49,14 +49,14 @@ module Inspec::Reporters
49
49
 
50
50
  res = http.request(req)
51
51
  if res.is_a?(Net::HTTPSuccess)
52
- return true
52
+ true
53
53
  else
54
54
  Inspec::Log.error "send_report: POST to #{uri.path} returned: #{res.body}"
55
- return false
55
+ false
56
56
  end
57
57
  rescue => e
58
58
  Inspec::Log.error "send_report: POST to #{uri.path} returned: #{e.message}"
59
- return false
59
+ false
60
60
  end
61
61
  end
62
62
 
@@ -14,17 +14,14 @@ module Inspec::Reporters
14
14
  runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
15
15
 
16
16
  message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
17
- trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
17
+ @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
18
18
  include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
19
19
 
20
20
  @run_data[:profiles]&.each do |p|
21
21
  p[:controls].each do |c|
22
22
  c[:results]&.map! do |r|
23
23
  r.delete(:backtrace) unless include_backtrace
24
- if r.key?(:message) && r[:message] != "" && trunc > -1
25
- r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
26
- end
27
- r
24
+ process_message_truncation(r)
28
25
  end
29
26
  end
30
27
  end
@@ -43,5 +40,14 @@ module Inspec::Reporters
43
40
  def render
44
41
  raise NotImplementedError, "#{self.class} must implement a `#render` method to format its output."
45
42
  end
43
+
44
+ private
45
+
46
+ def process_message_truncation(result)
47
+ if result.key?(:message) && result[:message] != "" && @trunc > -1 && result[:message].length > @trunc
48
+ result[:message] = result[:message][0...@trunc] + "[Truncated to #{@trunc} characters]"
49
+ end
50
+ result
51
+ end
46
52
  end
47
53
  end
@@ -72,6 +72,7 @@ module Inspec::Reporters
72
72
  "Profile" => format_profile_name(profile),
73
73
  "Version" => profile[:version] || "(not specified)",
74
74
  }
75
+ header["Failure Message"] = profile[:status_message] if profile[:status] == "failed"
75
76
  header["Target"] = run_data[:platform][:target] unless run_data[:platform][:target].nil?
76
77
  header["Target ID"] = @config["target_id"] unless @config["target_id"].nil?
77
78
 
@@ -45,8 +45,8 @@ module Inspec::Reporters
45
45
  end
46
46
 
47
47
  def profiles
48
- run_data[:profiles].map { |p|
49
- {
48
+ run_data[:profiles].map do |p|
49
+ res = {
50
50
  name: p[:name],
51
51
  version: p[:version],
52
52
  sha256: p[:sha256],
@@ -64,10 +64,15 @@ module Inspec::Reporters
64
64
  groups: profile_groups(p),
65
65
  controls: profile_controls(p),
66
66
  status: p[:status],
67
- skip_message: p[:skip_message],
67
+ status_message: p[:status_message],
68
68
  waiver_data: p[:waiver_data],
69
69
  }.reject { |_k, v| v.nil? }
70
- }
70
+
71
+ # For backwards compatibility
72
+ res[:skip_message] = res[:status_message] if res[:status] == "skipped"
73
+
74
+ res
75
+ end
71
76
  end
72
77
 
73
78
  def profile_groups(profile)
@@ -90,12 +90,14 @@ module Inspec::Resources
90
90
  # deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
91
91
  # deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
92
92
  # deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
93
+ # deb cdrom:[Ubuntu 15.10 _Wily Werewolf_ - Release amd64 (20151021)]/ wily main restricted ...
93
94
 
94
95
  words = line.split
95
96
  words.delete_at 1 if words[1] && words[1].start_with?("[")
96
97
  type, url, distro, *components = words
97
98
  url = url.delete('"') if url
98
99
 
100
+ next if words[1] && words[1].start_with?("cdrom:") # skip unsupported apt-cdrom repos
99
101
  next if components.empty?
100
102
  next unless URI::HTTP === URI.parse(url)
101
103
  next unless %w{deb deb-src}.include? type
@@ -27,7 +27,7 @@ module Inspec::Resources
27
27
  elsif inspec.os.windows?
28
28
  @bridge_provider = WindowsBridge.new(inspec)
29
29
  else
30
- return skip_resource "The `bridge` resource is not supported on your OS yet."
30
+ skip_resource "The `bridge` resource is not supported on your OS yet."
31
31
  end
32
32
  end
33
33
 
@@ -71,7 +71,7 @@ module Inspec::Resources
71
71
 
72
72
  missing_requirements = @host_provider.missing_requirements(protocol)
73
73
  unless missing_requirements.empty?
74
- return skip_resource "The following requirements are not met for this resource: " \
74
+ skip_resource "The following requirements are not met for this resource: " \
75
75
  "#{missing_requirements.join(", ")}"
76
76
  end
77
77
  end
@@ -61,7 +61,7 @@ module Inspec::Resources
61
61
  os = inspec.os
62
62
  if os.linux?
63
63
  LinuxMounts.new(inspec)
64
- elsif ["freebsd"].include?(os[:family])
64
+ elsif os.bsd?
65
65
  BsdMounts.new(inspec)
66
66
  end
67
67
  end
@@ -4,6 +4,27 @@ require "inspec/resources/command"
4
4
  require "shellwords"
5
5
 
6
6
  module Inspec::Resources
7
+ class Lines
8
+ attr_reader :output, :stdout, :stderr, :exit_status
9
+
10
+ def initialize(raw, desc, exit_status)
11
+ @output = raw
12
+ @desc = desc
13
+ @exit_status = exit_status
14
+ # backwards compatibility
15
+ @stdout = raw
16
+ @stderr = raw
17
+ end
18
+
19
+ def lines
20
+ output.split("\n")
21
+ end
22
+
23
+ def to_s
24
+ @desc
25
+ end
26
+ end
27
+
7
28
  class MysqlSession < Inspec.resource(1)
8
29
  name "mysql_session"
9
30
  supports platform: "unix"
@@ -12,7 +33,7 @@ module Inspec::Resources
12
33
  example <<~EXAMPLE
13
34
  sql = mysql_session('my_user','password','host')
14
35
  describe sql.query('show databases like \'test\';') do
15
- its('stdout') { should_not match(/test/) }
36
+ its('output') { should_not match(/test/) }
16
37
  end
17
38
  EXAMPLE
18
39
 
@@ -28,15 +49,17 @@ module Inspec::Resources
28
49
 
29
50
  def query(q, db = "")
30
51
  mysql_cmd = create_mysql_cmd(q, db)
31
- cmd = inspec.command(mysql_cmd)
52
+ cmd = if !@pass.nil?
53
+ inspec.command(mysql_cmd, redact_regex: /(mysql -u\w+ -p).+(\s-(h|S).*)/)
54
+ else
55
+ inspec.command(mysql_cmd)
56
+ end
32
57
  out = cmd.stdout + "\n" + cmd.stderr
33
- if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error /
34
- # skip this test if the server can't run the query
35
- warn("Can't connect to MySQL instance for SQL checks.")
58
+ if cmd.exit_status != 0 || out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error:.*/
59
+ Lines.new(out, "MySQL query with errors: #{q}", cmd.exit_status)
60
+ else
61
+ Lines.new(cmd.stdout.strip, "MySQL query: #{q}", cmd.exit_status)
36
62
  end
37
-
38
- # return the raw command output
39
- cmd
40
63
  end
41
64
 
42
65
  def to_s