inspec-core 5.10.5 → 5.12.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d96c590b3ff91ce5db5eaf8ee6ef68721fd17d103f250c8c3106941784f8f336
4
- data.tar.gz: 50b56c3506f186b51fcf07df23a59050461132e0c03245bed088961ef0e854fb
3
+ metadata.gz: b7242aa89bb64084dbeb75587b128af25c4967be0bc06ec8e9d8f386e821d36a
4
+ data.tar.gz: 876166ebb7e7ae59bb39fe1b9fd4523f45cdb6c22702f08e0074dad4662bf5bf
5
5
  SHA512:
6
- metadata.gz: 0eeb703b52391323d79b9ff99ce9bdc4b4aac5903fd6e10087b7ae92372b733b7a5779672fb67a3dc7aa6cfb2e3c859ca35ab81a6e49c0331ae623487e6ea241
7
- data.tar.gz: 7f076f8c2bef5080a73b6fb8886657137a558bf9c624dd11906c91ef9f555e8c6713af8f62282f9a2fa20e650624fbcd3172fe0e9557f59dd8eb539684192ff1
6
+ metadata.gz: 155d7f957519b8358c1e8d92373f50b8839cb7f31ca3f32af953a556a2753f768b69b9a78dc7fa2b228ed30e2a26a5b33a393dbe472c501fcc1bda0b54a353f8
7
+ data.tar.gz: af8ec2a17788ba7add5c58c07c0e842b31e8a7a92f6afd38ca0e794c2d297dde6464e8dd9cf8d8a07374042a2437ec41685226be098004a4396160432d68a14f
@@ -43,6 +43,19 @@ module Inspec::Resources
43
43
  status.downcase.start_with?("up") if object_info.entries.length == 1
44
44
  end
45
45
 
46
+ # has_volume? matcher checks if the volume specified in source path of host is mounted in destination path of docker
47
+ def has_volume?(destination, source)
48
+ # volume_info is the hash which contains the low-level information about the container
49
+ # if Mounts key is not present or is nil; raise exception
50
+ raise Inspec::Exceptions::ResourceFailed, "Could not find any mounted volumes for your container" unless volume_info.Mounts[0]
51
+
52
+ # Iterate through the list of mounted volumes and check if it matches with the given destination and source
53
+ # is_mounted flag is used to handle to return explict boolean values of true or false
54
+ is_mounted = false
55
+ volume_info.Mounts.detect { |mount| is_mounted = mount.Destination == destination && mount.Source == source }
56
+ is_mounted
57
+ end
58
+
46
59
  def status
47
60
  object_info.status[0] if object_info.entries.length == 1
48
61
  end
@@ -87,5 +100,13 @@ module Inspec::Resources
87
100
  opts = @opts
88
101
  @info = inspec.docker.containers.where { names == opts[:name] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id]))) }
89
102
  end
103
+
104
+ # volume_info returns the low-level information obtained on docker inspect [container_name/id]
105
+ def volume_info
106
+ return @mount_info if defined?(@mount_info)
107
+
108
+ # Check for either docker inspect [container_name] or docker inspect [container_id]
109
+ @mount_info = inspec.docker.object(@opts[:name] || @opts[:id])
110
+ end
90
111
  end
91
112
  end
@@ -48,6 +48,25 @@ module Inspec::Resources
48
48
  object_info.tags[0] if object_info.entries.size == 1
49
49
  end
50
50
 
51
+ # method_missing handles when hash_keys are invoked to check information obtained on docker inspect [image_name]
52
+ def method_missing(*hash_keys)
53
+ # User can test the low-level inspect information in three ways:
54
+ # Way 1: Serverspec style: its(['Config.Cmd']) { should include some_value }
55
+ # here, the value for hash_keys recieved is [:[], "Config.Cmd"]
56
+ # Way 2: InSpec style: its(['Config','Cmd']) { should include some_value }
57
+ # here, the value for hash_keys recieved is [:[], "Config", "Cmd"]
58
+ # Way 3: Mix of both: its(['GraphDriver.Data','MergedDir']) { should include some_value }
59
+ # here, the value for hash_keys recieved is [:[], "GraphDriver.Data", "MergedDir"]
60
+
61
+ # hash_keys are passed to this method to evaluate the value
62
+ image_hash_inspection(hash_keys)
63
+ end
64
+
65
+ # inspection property allows to test any of the hash key-value pairs as part of the image_inspect_info
66
+ def inspection
67
+ image_inspect_info
68
+ end
69
+
51
70
  def to_s
52
71
  img = @opts[:image] || @opts[:id]
53
72
  "Docker Image #{img}"
@@ -80,5 +99,39 @@ module Inspec::Resources
80
99
  (repository == opts[:repo] && tag == opts[:tag]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
81
100
  end
82
101
  end
102
+
103
+ # image_inspect_info returns the complete inspect hash_values of the image
104
+ def image_inspect_info
105
+ return @inspect_info if defined?(@inspect_info)
106
+
107
+ @inspect_info = inspec.docker.object(@opts[:image] || (!@opts[:id].nil? && @opts[:id]))
108
+ end
109
+
110
+ # image_hash_inspection formats the input hash_keys and checks if any value exists for such keys in @inspect_info(image_inspect_info)
111
+ def image_hash_inspection(hash_keys)
112
+ # The hash_keys recieved are in three formats as mentioned in method_missing
113
+ # The hash_keys recieved must be in array format [] and the zeroth index must be :[]
114
+ # Check for the conditions and remove the zeroth element from the hash_keys
115
+
116
+ hash_keys.shift if hash_keys.is_a?(Array) && hash_keys[0] == :[]
117
+
118
+ # When received hash_keys in Serverspec style or mix of both
119
+ # The hash_keys are to be splitted at '.' (dot) and flatten it so that it doesn't become array of arrays
120
+ # After splitting and flattening is done, hash_keys is now an array with individual keys
121
+ hash_keys = hash_keys.map { |key| key.split(".") }.flatten
122
+
123
+ # image_inspect_info returns the complete inspect hash_values of the image
124
+ # dig() finds the nested value specified by the sequence of the key object by calling dig at each step.
125
+ # hash_keys is the key object. If one of the key is bad, value will be nil.
126
+ hash_value = image_inspect_info.dig(*hash_keys)
127
+
128
+ # If one of the key is bad, hash_value will be nil, so raise exception which throws it in rescue block
129
+ # else return hash_value
130
+ raise Inspec::Exceptions::ResourceFailed if hash_value.nil?
131
+
132
+ hash_value
133
+ rescue
134
+ raise Inspec::Exceptions::ResourceFailed, "#{hash_keys.join(".")} is not a valid key for your image or has nil value."
135
+ end
83
136
  end
84
137
  end
@@ -0,0 +1,46 @@
1
+ require "inspec/resources/command"
2
+ module Inspec::Resources
3
+ class Mailalias < Inspec.resource(1)
4
+ # resource internal name.
5
+ name "mail_alias"
6
+
7
+ # Restrict to only run on the below platforms (if none were given,
8
+ # all OS's and cloud API's supported)
9
+ supports platform: "unix"
10
+
11
+ desc "Use the mail_alias InSpec audit resource to test mail alias present in the aliases file"
12
+
13
+ example <<~EXAMPLE
14
+ describe mail_alias("toor") do
15
+ it { should be_aliased_to "root" }
16
+ end
17
+ EXAMPLE
18
+
19
+ def initialize(alias_key)
20
+ skip_resource "The `mail_alias` resource is not yet available on your OS." unless inspec.os.unix?
21
+ @alias_key = alias_key
22
+ end
23
+
24
+ # resource_id is used in reporting engines to uniquely identify the individual resource.
25
+ def resource_id
26
+ "#{@alias_key}"
27
+ end
28
+
29
+ # resource appearance in test reports.
30
+ def to_s
31
+ "mail_alias #{resource_id}"
32
+ end
33
+
34
+ # aliased_to matcher checks if the given alias_value is set to the initialized alias_key
35
+ def aliased_to?(alias_value)
36
+ # /etc/aliases if the file where the alias and its value(s) are stored
37
+ cmd = inspec.command("cat /etc/aliases | grep '^#{@alias_key}:'")
38
+ raise Inspec::Exceptions::ResourceFailed, "#{@alias_key} is not a valid key in the aliases" if cmd.exit_status.to_i != 0
39
+
40
+ # in general aliases file contains : separated values like alias_key : alias_value1, alias_value2
41
+ alias_values_combined = cmd.stdout.split(":").map(&:strip)[1]
42
+ alias_values_splitted = alias_values_combined.split(",").map(&:strip)
43
+ alias_values_splitted.include?(alias_value)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,137 @@
1
+ require "inspec/resources/command"
2
+
3
+ module Inspec::Resources
4
+ class Routingtable < Inspec.resource(1)
5
+ # resource internal name.
6
+ name "routing_table"
7
+
8
+ # Restrict to only run on the below platforms (if none were given,
9
+ # all OS's and cloud API's supported)
10
+ supports platform: "unix"
11
+ supports platform: "windows"
12
+
13
+ desc "Use the `routing_table` Chef InSpec audit resource to test the routing information parameters(destination, gateway and interface) present in the routing table."
14
+
15
+ example <<~EXAMPLE
16
+ describe routing_table do
17
+ it do
18
+ should have_entry(
19
+ :destination => '192.168.43.1/32',
20
+ :interface => 'lxdbr0',
21
+ :gateway => '172.31.80.1',
22
+ )
23
+ end
24
+ end
25
+
26
+ describe routing_table do
27
+ it { should have_entry(destination: '0.0.0.0', interface: 'eth0', gateway: '172.31.80.1') }
28
+ end
29
+ EXAMPLE
30
+
31
+ def initialize
32
+ skip_resource "The `routing_table` resource is not yet available on your OS." unless inspec.os.unix? || inspec.os.windows?
33
+ # fetch the routing information and store it in @routing_info (could be hash, tbd)
34
+ @routing_info = {}
35
+ fetch_routing_information
36
+ end
37
+
38
+ # resource appearance in test reports.
39
+ def to_s
40
+ "routing_table"
41
+ end
42
+
43
+ def has_entry?(input_route)
44
+ # check if the destination, gateway, interface exists as part of the routing_info
45
+ if input_route.key?(:destination) && input_route.key?(:gateway) && input_route.key?(:interface)
46
+ # check if there is key with destination's value in hash;
47
+ # if yes, check if destination and gateway is present else return false
48
+ @routing_info.key?(input_route[:destination]) ? @routing_info[input_route[:destination]].include?([input_route[:gateway], input_route[:interface]]) : false
49
+ else
50
+ raise Inspec::Exceptions::ResourceSkipped, "One or more missing key, have_entry? matcher expects a hash with 3 keys: destination, gateway and interface"
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ # fetches the routing information for the system
57
+ def fetch_routing_information
58
+ # check if netstat is available on the system
59
+ utility = find_netstat_or_error
60
+
61
+ # the command to fetch the routing information
62
+ fetch_route_cmd = "#{utility} -rn"
63
+
64
+ # execute the above netstat command
65
+ cmd = inspec.command(fetch_route_cmd)
66
+
67
+ # raise error if the exit status is not zero;
68
+ raise Inspec::Exceptions::ResourceFailed, "Executing netstat failed: #{cmd.stderr}" if cmd.exit_status.to_i != 0
69
+
70
+ # Todo:
71
+ # Improve logic to fetch destination, gateway & interface efficiently.
72
+ # The below logic assumes the following:
73
+ # 1. destination, gateway & interface header is present as Destination, Gateway & (Iface or Netif or Interface) respectively.
74
+ # (Netif on BSD, Darwin,Iface on linux & Interface on Windows)
75
+ # 2. there is no blank data for any columns or the blank data are present after the interface column.
76
+
77
+ # cmd.stdout is the standard out of netstat -rn; split on new line to get the rows
78
+ raw_route_info = cmd.stdout.split("\n")
79
+
80
+ # since raw_route_info contains some row before the header (i.e. Destination Gateway ...); remove those rows
81
+ raw_route_info.shift until raw_route_info[0] =~ /Destination/i
82
+
83
+ # split each rows based on space to get the individual columns
84
+ # raw_route_info is now array of arrays with the routing information
85
+ raw_route_info.map! { |info| info.strip.split }
86
+
87
+ # these variables will store the indices where destination, gateway and interface are present
88
+ destination_index, gateway_index, interface_index = -1, -1, -1
89
+
90
+ # The headers in windows are as:
91
+ # Network Destination Netmask Gateway Interface Metric
92
+ # Splitting on space makes "Network Destination" to be two separate values as "Network" & "Destination"
93
+ # Remove "Network" value to apply the logic of finding index
94
+ raw_route_info[0].shift if inspec.os.windows?
95
+
96
+ # find the indices of destination, gateway and interface;
97
+ # because the position of gateway & interface varies with operating system
98
+ raw_route_info[0].each_with_index do |header, index|
99
+ if header =~ /Destination/i
100
+ destination_index = index
101
+ elsif header =~ /Gateway/i
102
+ gateway_index = index
103
+ elsif header =~ /Iface|Netif|Interface/i
104
+ interface_index = index
105
+ end
106
+ end
107
+
108
+ # remove the initial header consisting of Destination, Gateway, Mask, ... since this is of no use
109
+ raw_route_info.shift
110
+
111
+ # check the indices are assigned with some index and not -1
112
+ if destination_index != -1 && gateway_index != -1 && interface_index != -1
113
+ # iterate through the route_info; and find destination, gateway and interface from each row
114
+ raw_route_info.each do |info|
115
+ # if value exists at the destination_index, gateway_index, and interface_index; store the value in @routing_info
116
+ if !info[destination_index].nil? && !info[gateway_index].nil? && !info[interface_index].nil?
117
+ # if the destination_key is already present, append the gateway & interface; else create new array and add them
118
+ if @routing_info.key?(info[destination_index])
119
+ @routing_info[info[destination_index]] << [info[gateway_index], info[interface_index]]
120
+ else
121
+ @routing_info[info[destination_index]] = [[info[gateway_index], info[interface_index]]]
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ # check if netstat is available on the system
129
+ def find_netstat_or_error
130
+ %w{/usr/sbin/netstat /sbin/netstat /usr/bin/netstat /bin/netstat netstat}.each do |cmd|
131
+ return cmd if inspec.command(cmd).exist?
132
+ end
133
+
134
+ raise Inspec::Exceptions::ResourceFailed, "Could not find `netstat` utility to view routing table information"
135
+ end
136
+ end
137
+ end
@@ -537,9 +537,22 @@ module Inspec::Resources
537
537
  end
538
538
 
539
539
  def info(service_name)
540
+ # `service -l` lists all files in /etc/rc.d and the local startup directories
541
+ # % service -l
542
+ # accounting
543
+ # addswap
544
+ # adjkerntz
545
+ # apm
546
+ # archdep
547
+ cmd = inspec.command("#{service_ctl} -l")
548
+ return nil if cmd.exit_status != 0
549
+
550
+ # search for the service
551
+ srv = /^#{service_name}$/.match(cmd.stdout)
552
+ return nil if srv.nil? || srv[0].nil?
553
+
540
554
  # check if service is enabled
541
555
  cmd = inspec.command("#{service_ctl} #{service_name} enabled")
542
-
543
556
  enabled = cmd.exit_status == 0
544
557
 
545
558
  # check if the service is running
@@ -1 +1,13 @@
1
1
  require "inspec/resources/users"
2
+ # user resource belong_to matcher for serverspec compatibility
3
+ RSpec::Matchers.define :belong_to_primary_group do |group|
4
+ match do |user|
5
+ user.belongs_to_primary_group?(group)
6
+ end
7
+ end
8
+
9
+ RSpec::Matchers.define :belong_to_group do |group|
10
+ match do |user|
11
+ user.belongs_to_group?(group)
12
+ end
13
+ end
@@ -137,20 +137,17 @@ module Inspec::Resources
137
137
  # its('badpasswordattempts') { should eq 0 }
138
138
  # end
139
139
  #
140
- # The following Serverspec matchers are deprecated in favor for direct value access
140
+ # The following Serverspec matchers were deprecated in favor for direct value access
141
+ # but are made available as part of Serverspec compatibility in March, 2022.
141
142
  #
142
143
  # describe user('root') do
143
144
  # it { should belong_to_group 'root' }
145
+ # it { should belong_to_primary_group 'root' }
144
146
  # it { should have_uid 0 }
145
147
  # it { should have_home_directory '/root' }
146
148
  # it { should have_login_shell '/bin/bash' }
147
149
  # its('minimum_days_between_password_change') { should eq 0 }
148
150
  # its('maximum_days_between_password_change') { should eq 99 }
149
- # end
150
- #
151
- # ServerSpec tests that are not supported:
152
- #
153
- # describe user('root') do
154
151
  # it { should have_authorized_key 'ssh-rsa ADg54...3434 user@example.local' }
155
152
  # its(:encrypted_password) { should eq 1234 }
156
153
  # end
@@ -258,36 +255,56 @@ module Inspec::Resources
258
255
 
259
256
  # implement 'mindays' method to be compatible with serverspec
260
257
  def minimum_days_between_password_change
261
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `minimum_days_between_password_change` property is deprecated. Please use `mindays`.")
262
258
  mindays
263
259
  end
264
260
 
265
261
  # implement 'maxdays' method to be compatible with serverspec
266
262
  def maximum_days_between_password_change
267
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `maximum_days_between_password_change` property is deprecated. Please use `maxdays`.")
268
263
  maxdays
269
264
  end
270
265
 
271
266
  # implements rspec has matcher, to be compatible with serverspec
272
267
  # @see: https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/built_in/has.rb
268
+ # has_uid matcher: compatibility with serverspec
273
269
  def has_uid?(compare_uid)
274
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `has_uid?` matcher is deprecated.")
275
270
  uid == compare_uid
276
271
  end
277
272
 
273
+ # has_home_directory matcher: compatibility with serverspec
278
274
  def has_home_directory?(compare_home)
279
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `has_home_directory?` matcher is deprecated. Please use `its('home')`.")
280
275
  home == compare_home
281
276
  end
282
277
 
278
+ # has_login_shell matcher: compatibility with serverspec
283
279
  def has_login_shell?(compare_shell)
284
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `has_login_shell?` matcher is deprecated. Please use `its('shell')`.")
285
280
  shell == compare_shell
286
281
  end
287
282
 
288
- def has_authorized_key?(_compare_key)
289
- Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `has_authorized_key?` matcher is deprecated. There is no currently implemented alternative")
290
- raise NotImplementedError
283
+ # has_authorized_key matcher: compatibility with serverspec
284
+ def has_authorized_key?(compare_key)
285
+ # get_authorized_keys returns the list of key, check if given key is included.
286
+ get_authorized_keys.include?(compare_key)
287
+ end
288
+
289
+ # belongs_to_primary_group matcher: compatibility with serverspec
290
+ def belongs_to_primary_group?(group_name)
291
+ groupname == group_name
292
+ end
293
+
294
+ # belongs_to_group matcher: compatibility with serverspec
295
+ def belongs_to_group?(group_name)
296
+ groups.include?(group_name)
297
+ end
298
+
299
+ # encrypted_password property: compatibility with serverspec
300
+ # it allows to run test against the hashed passwords of the given user
301
+ # applicable for unix/linux systems with getent utility.
302
+ def encrypted_password
303
+ raise Inspec::Exceptions::ResourceSkipped, "encrypted_password property is not applicable for your system" if inspec.os.windows? || inspec.os.darwin?
304
+
305
+ # shadow_information returns array of the information from the shadow file
306
+ # the value at 1st index is the encrypted_password information
307
+ shadow_information[1]
291
308
  end
292
309
 
293
310
  def to_s
@@ -314,6 +331,54 @@ module Inspec::Resources
314
331
 
315
332
  @cred_cache = @user_provider.credentials(@username) unless @user_provider.nil?
316
333
  end
334
+
335
+ # helper method for has_authorized_key matcher
336
+ # get_authorized_keys return the key/keys stored in the authorized_keys path
337
+ def get_authorized_keys
338
+ # cat is used in unix system to display content of file; similarly type is used for windows
339
+ bin = inspec.os.windows? ? "type" : "cat"
340
+
341
+ # auth_path gets assigned with the valid path for authorized_keys
342
+ auth_path = ""
343
+
344
+ # possible paths where authorized_keys are stored
345
+ # inspec.command is used over inspec.file because inspec.file requires absolute path
346
+ %w{~/.ssh/authorized_keys ~/.ssh/authorized_keys2}.each do |path|
347
+ if inspec.command("#{bin} #{path}").exit_status == 0
348
+ auth_path = path
349
+ break
350
+ end
351
+ end
352
+
353
+ # if auth_path is empty, no valid path was found, hence raise exception
354
+ raise Inspec::Exceptions::ResourceSkipped, "Can't find any valid path for authorized_keys" if auth_path.empty?
355
+
356
+ # authorized_keys are obtained in the standard output;
357
+ # split keys on newline if more than one keys are part of authorized_keys
358
+ inspec.command("#{bin} #{auth_path}").stdout.split("\n").map(&:strip)
359
+ end
360
+
361
+ # Helper method for encrypted_password property
362
+ def shadow_information
363
+ # check if getent is available on the system
364
+ bin = find_getent_utility
365
+
366
+ # fetch details of the passwd file for the current user using getent
367
+ cmd = inspec.command("#{bin} shadow #{@username}")
368
+ raise Inspec::Exceptions::ResourceFailed, "Executing #{bin} shadow #{@username} failed: #{cmd.stderr}" if cmd.exit_status.to_i != 0
369
+
370
+ # shadow information are : separated values, split and return
371
+ cmd.stdout.split(":").map(&:strip)
372
+ end
373
+
374
+ # check if getent exist in the system
375
+ def find_getent_utility
376
+ %w{/usr/bin/getent /bin/getent getent}.each do |cmd|
377
+ return cmd if inspec.command(cmd).exist?
378
+ end
379
+
380
+ raise Inspec::Exceptions::ResourceFailed, "Could not find `getent` on your system."
381
+ end
317
382
  end
318
383
 
319
384
  # Class defined to compare for groups without case-sensitivity
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "5.10.5".freeze
2
+ VERSION = "5.12.2".freeze
3
3
  end
@@ -41,9 +41,9 @@ module InspecPlugins::StreamingReporterProgressBar
41
41
  # Groovy UTF-8 characters for everyone else...
42
42
  # ...even though they probably only work on Mac
43
43
  INDICATORS = {
44
- "failed" => "×",
45
- "skipped" => "↺",
46
- "passed" => "✔",
44
+ "failed" => "× [FAILED] ",
45
+ "skipped" => "↺ [SKIPPED]",
46
+ "passed" => "✔ [PASSED] ",
47
47
  }.freeze
48
48
  end
49
49
 
@@ -54,58 +54,69 @@ module InspecPlugins::StreamingReporterProgressBar
54
54
  end
55
55
 
56
56
  def example_passed(notification)
57
- control_id = notification.example.metadata[:id]
58
- set_status_mapping(control_id, "passed")
59
- show_progress(control_id) if control_ended?(control_id)
57
+ set_example(notification, "passed")
60
58
  end
61
59
 
62
60
  def example_failed(notification)
63
- control_id = notification.example.metadata[:id]
64
- set_status_mapping(control_id, "failed")
65
- show_progress(control_id) if control_ended?(control_id)
61
+ set_example(notification, "failed")
66
62
  end
67
63
 
68
64
  def example_pending(notification)
69
- control_id = notification.example.metadata[:id]
70
- set_status_mapping(control_id, "skipped")
71
- show_progress(control_id) if control_ended?(control_id)
65
+ set_example(notification, "skipped")
72
66
  end
73
67
 
74
68
  private
75
69
 
76
- def show_progress(control_id)
70
+ def set_example(notification, status)
71
+ control_id = notification.example.metadata[:id]
72
+ title = notification.example.metadata[:title]
73
+ full_description = notification.example.metadata[:full_description]
74
+ control_impact = notification.example.metadata[:impact]
75
+ set_status_mapping(control_id, status)
76
+ show_progress(control_id, title, full_description, control_impact) if control_ended?(control_id)
77
+ end
78
+
79
+ def show_progress(control_id, title, full_description, control_impact)
77
80
  @bar ||= ProgressBar.new(controls_count, :bar, :counter, :percentage)
78
81
  sleep 0.1
79
82
  @bar.increment!
80
- @bar.puts format_it(control_id)
81
- rescue Exception => ex
82
- raise "Exception in Progress Bar streaming reporter: #{ex}"
83
+ @bar.puts format_it(control_id, title, full_description, control_impact)
84
+ rescue StandardError => e
85
+ raise "Exception in Progress Bar streaming reporter: #{e}"
83
86
  end
84
87
 
85
- def format_it(control_id)
88
+ def format_it(control_id, title, full_description, control_impact)
86
89
  control_status = if @status_mapping[control_id].include? "failed"
87
90
  "failed"
88
- elsif @status_mapping[control_id].include? "skipped"
89
- "skipped"
90
91
  elsif @status_mapping[control_id].include? "passed"
91
92
  "passed"
93
+ else
94
+ @status_mapping[control_id].include? "skipped"
95
+ "skipped"
92
96
  end
93
-
94
97
  indicator = INDICATORS[control_status]
95
98
  message_to_format = ""
96
99
  message_to_format += "#{indicator} "
97
- message_to_format += control_id.to_s.lstrip.force_encoding(Encoding::UTF_8)
100
+ message_to_format += "#{control_id.to_s.strip.dup.force_encoding(Encoding::UTF_8)} "
101
+ message_to_format += "#{title.gsub(/\n*\s+/, " ").to_s.force_encoding(Encoding::UTF_8)} " if title
102
+ message_to_format += "#{full_description.gsub(/\n*\s+/, " ").to_s.force_encoding(Encoding::UTF_8)} " unless title
98
103
  format_with_color(control_status, message_to_format)
104
+ rescue Exception => e
105
+ raise "Exception in show_progress: #{e}"
99
106
  end
100
107
 
101
108
  def format_with_color(color_name, text)
102
109
  "#{COLORS[color_name]}#{text}#{COLORS["reset"]}"
110
+ rescue StandardError => e
111
+ raise "Exception in format_with_color: #{e}"
103
112
  end
104
113
 
105
114
  # status mapping with control id to decide the final state of the control
106
115
  def set_status_mapping(control_id, status)
107
116
  @status_mapping[control_id] = [] if @status_mapping[control_id].nil?
108
117
  @status_mapping[control_id].push(status)
118
+ rescue StandardError => e
119
+ raise "Exception in format_with_color: #{e}"
109
120
  end
110
121
 
111
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.10.5
4
+ version: 5.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-23 00:00:00.000000000 Z
11
+ date: 2022-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -569,6 +569,7 @@ files:
569
569
  - lib/inspec/resources/linux_kernel_parameter.rb
570
570
  - lib/inspec/resources/login_defs.rb
571
571
  - lib/inspec/resources/lxc.rb
572
+ - lib/inspec/resources/mail_alias.rb
572
573
  - lib/inspec/resources/mongodb.rb
573
574
  - lib/inspec/resources/mongodb_conf.rb
574
575
  - lib/inspec/resources/mongodb_session.rb
@@ -613,6 +614,7 @@ files:
613
614
  - lib/inspec/resources/rabbitmq_conf.rb
614
615
  - lib/inspec/resources/rabbitmq_config.rb
615
616
  - lib/inspec/resources/registry_key.rb
617
+ - lib/inspec/resources/routing_table.rb
616
618
  - lib/inspec/resources/runit_service.rb
617
619
  - lib/inspec/resources/script.rb
618
620
  - lib/inspec/resources/security_identifier.rb