inspec-core 4.21.1 → 4.22.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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