inspec-core 4.20.10 → 4.21.1

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: ef611d3b2bb1d1c8ddca64adb1ed3eab50fcbec55a45cb49334ed2084c45e7da
4
- data.tar.gz: 96664cb6183b137db4f84cd26aed2b19496475045bbb458ea9d9004e92aad3f7
3
+ metadata.gz: f7be94754504cd2aeda9badd0701a9ac28691e0c62f76741db0c3b1b75988b2b
4
+ data.tar.gz: 314ce4bedf429cb87185f4903bcb5e47c93587fc1c125f9dcff112574f5dde72
5
5
  SHA512:
6
- metadata.gz: f1d44fc61e4663862a0628a0fcc4c4e3538bdb35d50cee94f1130c47fed5a982297da9c559128b0dddc2a7375658252924959020f24f518202b25939357340de
7
- data.tar.gz: e33e28b5863ce15a54c8f2f76dd3a458762c24fb7d365ba145ae06b6b0be14134b90da5f2610d834ae71a170e5f6b180c78a8ac8763f484b3bbcfa808eec8565
6
+ metadata.gz: fa7f2ac74a61e23f82236d175b5adcc4236eb6b48316d7eaca9cfa85fe9f3917a22eb87fc56723ff56635348897e21f635816071fcf1c13a2f808df212388693
7
+ data.tar.gz: 17245f5ba3ca9aad13bba4870e52bf48c2e2cf2219b03ee569d0a1aa2e699bd2b6de447d30a2d23c44e01c72ded87c9dab596e564eb9206f7826ae72f6b4d366
data/Gemfile CHANGED
@@ -31,6 +31,7 @@ group :test do
31
31
  gem "m"
32
32
  gem "pry", "~> 0.10"
33
33
  gem "pry-byebug"
34
+ gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
34
35
  end
35
36
 
36
37
  group :integration do
@@ -47,10 +47,18 @@ module Inspec::Resources
47
47
  ipv6_addresses && !ipv6_addresses.empty?
48
48
  end
49
49
 
50
+ def ipv4_address
51
+ ipv4_addresses.first
52
+ end
53
+
50
54
  def ipv4_addresses
51
55
  ipv4_cidrs.map { |i| i.split("/")[0] }
52
56
  end
53
57
 
58
+ def ipv6_address
59
+ ipv6_addresses.first
60
+ end
61
+
54
62
  def ipv6_addresses
55
63
  ipv6_cidrs.map { |i| i.split("/")[0] }
56
64
  end
@@ -85,6 +93,7 @@ module Inspec::Resources
85
93
  @cache ||= begin
86
94
  provider = LinuxInterface.new(inspec) if inspec.os.linux?
87
95
  provider = WindowsInterface.new(inspec) if inspec.os.windows?
96
+ provider = BsdInterface.new(inspec) if inspec.os.bsd? # includes macOS
88
97
  Hash(provider && provider.interface_info(@iface))
89
98
  end
90
99
  end
@@ -98,6 +107,52 @@ module Inspec::Resources
98
107
  end
99
108
  end
100
109
 
110
+ class BsdInterface < InterfaceInfo
111
+ def interface_info(iface)
112
+ cmd = inspec.command("ifconfig #{iface}")
113
+ return nil if cmd.exit_status.to_i != 0
114
+
115
+ lines = cmd.stdout.split("\n")
116
+ iface_info = {
117
+ name: iface,
118
+ ipv4_addresses: [], # Actually CIDRs
119
+ ipv6_addresses: [], # are expected to go here
120
+ }
121
+
122
+ iface_info[:up] = lines[0].include?("UP")
123
+ lines.each do |line|
124
+ # IPv4 case
125
+ m = line.match(/^\s+inet\s+((?:\d{1,3}\.){3}\d{1,3})\s+netmask\s+(0x[a-f0-9]{8})/)
126
+ if m
127
+ ip = m[1]
128
+ hex_mask = m[2]
129
+ cidr = hex_mask.to_i(16).to_s(2).count("1")
130
+ iface_info[:ipv4_addresses] << "#{ip}/#{cidr}"
131
+ next
132
+ end
133
+
134
+ # IPv6 case
135
+ m = line.match(/^\s+inet6\s+([a-f0-9:]+)%#{iface}\s+prefixlen\s+(\d+)/)
136
+ if m
137
+ ip = m[1]
138
+ cidr = m[2]
139
+ iface_info[:ipv6_addresses] << "#{ip}/#{cidr}"
140
+ next
141
+ end
142
+
143
+ # Speed detect, crummy - can't detect wifi, finds any number in the string
144
+ # Ethernet autoselect (1000baseT <full-duplex>)
145
+ m = line.match(/^\s+media:\D+(\d+)/)
146
+ if m
147
+ iface_info[:speed] = m[1].to_i
148
+ next
149
+ end
150
+ end
151
+
152
+ iface_info
153
+ end
154
+ end
155
+
101
156
  class LinuxInterface < InterfaceInfo
102
157
  def interface_info(iface)
103
158
  # will return "[mtu]\n1500\n[type]\n1"
@@ -0,0 +1,119 @@
1
+ require "inspec/utils/filter"
2
+ require "inspec/resources/command"
3
+
4
+ module Inspec::Resources
5
+ class Interfaces < Inspec.resource(1)
6
+ name "interfaces"
7
+ supports platform: "unix"
8
+ supports platform: "windows"
9
+ desc "Use the interfaces InSpec audit resource to test properties for multiple network interfaces installed on the system"
10
+ example <<~EXAMPLE
11
+ describe interfaces do
12
+ its('names') { should include 'eth0' }
13
+ end
14
+ EXAMPLE
15
+
16
+ attr_reader :iface_data
17
+
18
+ def to_s
19
+ "Interfaces"
20
+ end
21
+
22
+ filter = FilterTable.create
23
+ filter.register_column(:names, field: "name")
24
+ .install_filter_methods_on_resource(self, :scan_interfaces)
25
+
26
+ def ipv4_address
27
+ require "ipaddr"
28
+
29
+ # Loop over interface names
30
+ # Select those that are up and have an ipv4 address
31
+ interfaces = names.map { |n| inspec.interface(n) }.select do |i|
32
+ i.ipv4_address? && i.up?
33
+ end
34
+
35
+ addrs = interfaces.map(&:ipv4_addresses).flatten.map { |a| IPAddr.new(a) }
36
+
37
+ # Look for progressively "better" IP addresses
38
+ [
39
+ # Loopback and private IP ranges
40
+ IPAddr.new("127.0.0.0/8"),
41
+ IPAddr.new("192.168.0.0/16"),
42
+ IPAddr.new("172.16.0.0/12"),
43
+ IPAddr.new("10.0.0.0/8"),
44
+ ].each do |private_range|
45
+ filtered_addrs = addrs.reject { |a| private_range.include?(a) }
46
+ if filtered_addrs.empty?
47
+ # Everything we had was a private or loopback IP. Return the "best" thing we were left with.
48
+ return addrs.first.to_s
49
+ end
50
+
51
+ addrs = filtered_addrs
52
+ end
53
+ addrs.first.to_s
54
+ end
55
+
56
+ private
57
+
58
+ def scan_interfaces
59
+ @iface_data ||= begin
60
+ provider = LinuxInterfaceLister.new(inspec) if inspec.os.linux?
61
+ provider = WindowsInterfaceLister.new(inspec) if inspec.os.windows?
62
+ provider = BsdInterfaceLister.new(inspec) if inspec.os.bsd? # includes macOS
63
+ Array(provider && provider.scan_interfaces)
64
+ end
65
+ end
66
+
67
+ class InterfaceLister
68
+ attr_reader :inspec
69
+ def initialize(inspec)
70
+ @inspec = inspec
71
+ end
72
+ end
73
+
74
+ class BsdInterfaceLister < InterfaceLister
75
+ def scan_interfaces
76
+ iface_data = []
77
+ cmd = inspec.command("ifconfig -a")
78
+ cmd.stdout.split("\n").each do |line|
79
+ # lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
80
+ m = line.match(/^(\S+):/)
81
+ if m
82
+ iface_data << { "name" => m[1] }
83
+ end
84
+ end
85
+ iface_data
86
+ end
87
+ end
88
+
89
+ class LinuxInterfaceLister < InterfaceLister
90
+ def scan_interfaces
91
+ iface_data = []
92
+ cmd = inspec.command("ls /sys/class/net")
93
+ cmd.stdout.split("\n").each do |iface|
94
+ iface_data << { "name" => iface }
95
+ end
96
+ iface_data
97
+ end
98
+ end
99
+
100
+ class WindowsInterfaceLister < InterfaceLister
101
+ def scan_interfaces
102
+ iface_data = []
103
+ cmd = inspec.command("Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json")
104
+ begin
105
+ adapter_info = JSON.parse(cmd.stdout)
106
+ # May be a Hash if only one, or Array if multiple - normalize to Array
107
+ adapter_info = [ adapter_info ] if adapter_info.is_a? Hash
108
+ rescue JSON::ParserError => _e
109
+ return nil
110
+ end
111
+ adapter_info.each do |info|
112
+ iface_data << { "name" => info["Name"] }
113
+ end
114
+ iface_data
115
+ end
116
+ end
117
+
118
+ end
119
+ end
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.20.10".freeze
2
+ VERSION = "4.21.1".freeze
3
3
  end
@@ -0,0 +1,53 @@
1
+ # inspec-reporter-html2 Plugin
2
+
3
+ An "improved" HTML output reporter specifically for Chef InSpec. Unlike the default `html` reporter, which is RSpec-based, this reporter knows about Chef InSpec structures like Controls and Profiles, and includes full metadata such as control tags, etc.
4
+
5
+ ## To Install This Plugin
6
+
7
+ This plugin ships with Chef InSpec and requires no installation.
8
+
9
+ It should appear when you run:
10
+
11
+ ```
12
+ you@machine $ inspec plugin list
13
+ ```
14
+
15
+ ## How to use this plugin
16
+
17
+ To generate an HTML report using this plugin and save the output to a file named `report.html`, run:
18
+
19
+ ```
20
+ you@machine $ inspec exec some_profile --reporter html2:report.html
21
+ ```
22
+
23
+ Note the `2` in the reporter name. If you omit it and run `--reporter html` instead, you will run the legacy RSpec HTML reporter.
24
+
25
+ ## Configuring the Plugin
26
+
27
+ The `html2` reporter requires no configuration to function. However, two options--`alternate_css_file` and `alternate_js_file`--are available for customization. The options are set in the JSON-formatted configuration file that Chef InSpec consumes. For details, see [our configuration file documentation](https://www.inspec.io/docs/reference/config/).
28
+
29
+ For example:
30
+
31
+ ```json
32
+ {
33
+ "version": "1.2",
34
+ "plugins": {
35
+ "inspec-reporter-html2": {
36
+ "alternate_js_file":"/var/www/js/my-javascript.js",
37
+ "alternate_css_file":"/var/www/css/my-style.css"
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### alternate\_css\_file
44
+
45
+ Specifies the full path to the location of a CSS file that will be read and inlined into the HTML report. The default CSS will not be included.
46
+
47
+ ### alternate\_js\_file
48
+
49
+ Specifies the full path to the location of a JavaScript file that will be read and inlined into the HTML report. The default JavaScript will not be included. The JavaScript file should implement at least a `pageLoaded()` function, which will be called by the `onload` event of the HTML `body` element.
50
+
51
+ ## Developing This Plugin
52
+
53
+ This plugin is part of the Chef InSpec source code. While it has its own tests, the general contribution policy is dictated by the Chef InSpec project at https://github.com/inspec/inspec/blob/master/CONTRIBUTING.md
@@ -0,0 +1,18 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ require "inspec-reporter-html2/version"
5
+ module InspecPlugins
6
+ module Html2Reporter
7
+ class Plugin < ::Inspec.plugin(2)
8
+ # Internal machine name of the plugin. InSpec will use this in errors, etc.
9
+ plugin_name :'inspec-reporter-html2'
10
+
11
+ # Define a new Reporter.
12
+ reporter :html2 do
13
+ require "inspec-reporter-html2/reporter"
14
+ InspecPlugins::Html2Reporter::Reporter
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ require "erb"
2
+ require "inspec/config"
3
+
4
+ module InspecPlugins::Html2Reporter
5
+ class Reporter < Inspec.plugin(2, :reporter)
6
+ def render
7
+ template_path = File.expand_path(__FILE__ + "../../../../templates")
8
+
9
+ # Read config data from the user's config file. Supports two settings, both of which are absolute filesystem paths:
10
+ # alternate_css_file - contents will be used instead of default CSS
11
+ # alternate_js_file - contents will be used instead of default JavaScript
12
+ cfg = Inspec::Config.cached.fetch_plugin_config("inspec-reporter-html2")
13
+ js_path = cfg[:alternate_js_file] || (template_path + "/default.js")
14
+ css_path = cfg[:alternate_css_file] || (template_path + "/default.css")
15
+
16
+ template = ERB.new(File.read(template_path + "/body.html.erb"))
17
+ output(template.result(binding))
18
+ end
19
+
20
+ def self.run_data_schema_constraints
21
+ "~> 0.0"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # This file simply makes it easier for CI engines to update
2
+ # the version stamp, and provide a clean way for the gemspec
3
+ # to learn the current version.
4
+ module InspecPlugins
5
+ module Html2Reporter
6
+ VERSION = "0.1.0".freeze
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <!-- saved from url=(0014)about:internet -->
3
+ <!-- prior comment allows JS to execute on IE when saved as a local file, "MOTW" -->
4
+ <html lang="en">
5
+ <head>
6
+ <title><%= Inspec::Dist::PRODUCT_NAME %> Results</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <style type="text/css">
9
+ /* Must inline all CSS files, this is a single-file output that may be airgapped */
10
+ <%= ERB.new(File.read(css_path), nil, nil, "_css").result(binding) %>
11
+ </style>
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+ /* Must inline all JavaScript files, this is a single-file output that may be airgapped */
15
+ <%= ERB.new(File.read(js_path), nil, nil, "_js").result(binding) %>
16
+ // ]]>
17
+ </script>
18
+ </head>
19
+ <body onload="pageLoaded()">
20
+ <%= ERB.new(File.read(template_path + "/selector.html.erb"), nil, nil, "_select").result(binding) %>
21
+ <div class="inspec-report">
22
+ <h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
23
+ <% run_data.profiles.each do |profile| %>
24
+ <%= ERB.new(File.read(template_path + "/profile.html.erb"), nil, nil, "_prof").result(binding) %>
25
+ <% end %>
26
+
27
+ <div class="inspec-summary">
28
+ <table id="platform" class="info">
29
+ <tr><th colspan=2><h4 id="platform-label">Platform Information</h4></th></tr>
30
+ <tr class= "name"><th>Name:</th><td><%= run_data.platform.name %></td></tr>
31
+ <tr class= "release"><th>Release:</th><td><%= run_data.platform.release %></td></tr>
32
+ <tr class= "target"><th>Target:</th><td><%= run_data.platform.target %></td></tr>
33
+ </table>
34
+ <table id="statistics" class="info">
35
+ <tr><th colspan="2"><h4 id="statistics-label">Control Statistics</h4></th></tr>
36
+ <tr class= "passed"><th>Passed:</th><td><%= run_data.statistics.controls.passed.total %></td></tr>
37
+ <tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
38
+ <tr class= "failed"><th>Failed:</th><td><%= run_data.statistics.controls.failed.total %></td></tr>
39
+ <tr class= "duration"><th>Duration:</th><td><%= run_data.statistics.duration %> seconds</td></tr>
40
+ <tr class= "date"><th>Time Finished:</th><td><%= Time.now %></td></tr>
41
+ </table>
42
+ <span id="inspec-version"><%= Inspec::Dist::PRODUCT_NAME %> version <%= run_data.version %></span>
43
+ </div>
44
+ </div>
45
+ </body>
46
+ </html>
@@ -0,0 +1,77 @@
1
+ <% slugged_id = control.id.tr(" ", "_") %>
2
+ <%
3
+ # Determine status of control
4
+ status = "passed"
5
+ if control.results.any? { |r| r.status == "failed" }
6
+ status = "failed"
7
+ elsif control.results.any? { |r| r.status == "skipped" }
8
+ status = "skipped"
9
+ end
10
+ %>
11
+
12
+ <div class="control control-status-<%= status %>" id="control-<%= slugged_id %>">
13
+
14
+ <%
15
+ # Determine range of impact
16
+ i = control.impact || 0.0
17
+ impact_level = "none"
18
+ if i < 0.3
19
+ impact_level = "low"
20
+ elsif i < 0.7
21
+ impact_level = "medium"
22
+ else
23
+ impact_level = "high"
24
+ end
25
+ %>
26
+
27
+ <h3 class="control-title">Control <code><%= control.id %></code></h3>
28
+ <table class="control-metadata info" id="control-metadata-<%= slugged_id %>">
29
+ <tr class="status status-<%= status %>"><th>Status:</th><td><div><%= status.capitalize %></div></td></tr>
30
+ <% if control.title %><tr class="title"><th>Title:</th><td><%= control.title %></td></tr> <% end %>
31
+ <% if control.desc %><tr class="desc"><th>Description:</th><td><%= control.desc %></td></tr> <% end %>
32
+ <% if control.impact %><tr class="impact impact-<%= impact_level %>"><th>Impact:</th><td><%= control.impact %></td></tr> <% end %>
33
+ <% unless control.tags.empty? %>
34
+ <tr class="tags">
35
+ <th>Tags:</th>
36
+ <td>
37
+ <table class="tags">
38
+ <% control.tags.each do |tag_name, tag_text| %>
39
+ <tr><td><%= tag_name %></td><td><%= tag_text %></td></tr>
40
+ <% end %>
41
+ </table>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ <% unless control.refs.empty? %>
46
+ <tr class="refs">
47
+ <th>References:</th>
48
+ <td>
49
+ <ul>
50
+ <% control.refs.each do |r| %>
51
+ <li><a href="<%= r.url %>"><%= r.ref %></a></li>
52
+ <% end %>
53
+ </ul>
54
+ </td>
55
+ </tr>
56
+ <% end %>
57
+ <tr class="code">
58
+ <th>Source Code:</th>
59
+ <td>
60
+ <input type="button" class="show-source-code" id="show-code-<%= slugged_id %>" value="Show Source"/>
61
+ <input type="button" class="hide-source-code hidden" id="hide-code-<%= slugged_id %>" value="Hide Source"/>
62
+ <pre class="source-code hidden" id="source-code-<%= slugged_id %>">
63
+ <code>
64
+ <%= control.code %>
65
+ </code>
66
+ </pre>
67
+ </td>
68
+ </tr>
69
+ <!-- TODO waiver data -->
70
+
71
+ </table>
72
+
73
+ <% control.results.each do |result| %>
74
+ <%= ERB.new(File.read(template_path + "/result.html.erb"), nil, nil, "_rslt").result(binding) %>
75
+ <% end %>
76
+
77
+ </div>
@@ -0,0 +1,107 @@
1
+ body {
2
+ margin: 20px 10% 20px 10%;
3
+ padding: 0;
4
+ background: #fff;
5
+ }
6
+ h1, h2, h3, h4, h5 {
7
+ font-family: "Lucida Grande", Helvetica, sans-serif;
8
+ }
9
+ h1, h2 {
10
+ padding: 10px;
11
+ text-align: center
12
+ }
13
+ table.info th, table.info th {
14
+ padding: 2px;
15
+ }
16
+ table.info th {
17
+ text-align: right;
18
+ }
19
+ .hidden {
20
+ display: none;
21
+ }
22
+ pre code {
23
+ background-color: #eee;
24
+ border: 1px solid #999;
25
+ display: block;
26
+ padding: 20px;
27
+ }
28
+
29
+ .profile, .control, .profile-metadata {
30
+ border: 1px solid #ccc;
31
+ padding: 10px;
32
+ margin: 5px auto;
33
+ }
34
+
35
+ .resource-title {
36
+ margin-left: 2.5%;
37
+ }
38
+
39
+ .control-title code,
40
+ .resource-title code {
41
+ font-size: larger;
42
+ }
43
+ .control-metadata .status div,
44
+ .result-metadata .status div {
45
+ color: white;
46
+ font-weight: bold;
47
+ width: fit-content;
48
+ padding: 0px 2px;
49
+ }
50
+
51
+ .control-metadata .status-passed div,
52
+ .result-metadata .status-passed div {
53
+ background-color: darkgreen;
54
+ }
55
+ .control-metadata .status-failed div,
56
+ .result-metadata .status-failed div {
57
+ background-color: red;
58
+ }
59
+ .control-metadata .status-skipped div,
60
+ .result-metadata .status-skipped div {
61
+ background-color: grey;
62
+ }
63
+ .result-metadata,
64
+ .control-metadata {
65
+ margin: 0 0 0 5%;
66
+ }
67
+
68
+ .selector-panel {
69
+ position: fixed;
70
+ z-index: 100;
71
+ background-color: #ccc;
72
+ padding: 10px;
73
+ top: 0;
74
+ margin-left: -10%;
75
+ border-bottom-right-radius: 10px;
76
+ }
77
+
78
+ @media print {
79
+ .selector-panel {
80
+ visibility: hidden;
81
+ }
82
+ }
83
+
84
+ .inspec-summary {
85
+ border: 1px solid #ccc;
86
+ padding: 10px;
87
+ margin: 5px auto;
88
+ width: fit-content
89
+ }
90
+
91
+ .inspec-summary h4 {
92
+ margin-bottom: 0px;
93
+ }
94
+
95
+ .inspec-summary #platform, .inspec-summary #statistics {
96
+ display: inline;
97
+ }
98
+
99
+ #statistics .date td {
100
+ width: 100px
101
+ }
102
+
103
+ #inspec-version {
104
+ display: block;
105
+ text-align: center;
106
+ font-style: italic;
107
+ }
@@ -0,0 +1,79 @@
1
+
2
+ /* CSS primitives */
3
+ function addCssClass(id, cls) {
4
+ document.getElementById(id).className += (" " + cls);
5
+ }
6
+
7
+ function removeCssClass(id, cls) {
8
+ var el = document.getElementById(id);
9
+ var classes = el.className.replace(cls,'');
10
+ el.className = classes;
11
+ }
12
+
13
+ function handleShowSource(evt) {
14
+ var control_id = evt.srcElement.id.replace("show-code-", "")
15
+ addCssClass(evt.srcElement.id, "hidden")
16
+ removeCssClass("hide-code-" + control_id, "hidden")
17
+ removeCssClass("source-code-" + control_id, "hidden")
18
+ }
19
+
20
+ function handleHideSource(evt) {
21
+ var control_id = evt.srcElement.id.replace("hide-code-", "")
22
+ addCssClass(evt.srcElement.id, "hidden")
23
+ addCssClass("source-code-" + control_id, "hidden")
24
+ removeCssClass("show-code-" + control_id, "hidden")
25
+ }
26
+
27
+ function handleSelectorChange(evt) {
28
+ var should_show = evt.srcElement.checked
29
+ var which_group = evt.srcElement.id.replace("-checkbox","")
30
+ var controls = document.getElementsByClassName("control-status-" + which_group)
31
+ var i;
32
+ if (should_show) {
33
+ for (i = 0; i < controls.length; i++) {
34
+ removeCssClass(controls[i].id, "hidden")
35
+ }
36
+ } else {
37
+ for (i = 0; i < controls.length; i++) {
38
+ addCssClass(controls[i].id, "hidden")
39
+ }
40
+ }
41
+ }
42
+
43
+ function handleChildProfileChange(evt) {
44
+ var should_show = evt.srcElement.checked
45
+ var child_profiles = document.getElementsByClassName("child-profile")
46
+ var i;
47
+ if (should_show) {
48
+ for (i = 0; i < child_profiles.length; i++) {
49
+ removeCssClass(child_profiles[i].id, "hidden")
50
+ }
51
+ } else {
52
+ for (i = 0; i < child_profiles.length; i++) {
53
+ addCssClass(child_profiles[i].id, "hidden")
54
+ }
55
+ }
56
+ }
57
+
58
+ /* Main entry point */
59
+ function pageLoaded() {
60
+ var i;
61
+
62
+ // wire up show source links
63
+ var show_links = document.getElementsByClassName("show-source-code");
64
+ for (i = 0; i < show_links.length; i++) {
65
+ show_links[i].onclick = handleShowSource;
66
+ }
67
+ // wire up hide source links
68
+ var hide_links = document.getElementsByClassName("hide-source-code");
69
+ for (i = 0; i < hide_links.length; i++) {
70
+ hide_links[i].onclick = handleHideSource;
71
+ }
72
+ // wire up selector checkboxes
73
+ var selectors = document.getElementsByClassName("selector-checkbox");
74
+ for (i = 0; i < selectors.length; i++) {
75
+ selectors[i].onchange = handleSelectorChange;
76
+ }
77
+ // wire up child profile checkbox
78
+ document.getElementById("child-profile-checkbox").onchange = handleChildProfileChange;
79
+ }
@@ -0,0 +1,20 @@
1
+ <div class="profile <%= profile.parent_profile ? "child-profile hidden" : "" %>" id="profile-<%= profile.name %>">
2
+ <% display_name = profile.title || profile.name %>
3
+ <h2 class="profile_title">Profile <%= display_name %> (<%= profile.name %>)</h2>
4
+
5
+ <table class="profile-metadata info" id="profile-metadata-<%= profile.name %>">
6
+ <tr class="profile-version"><th>Version:</th><td><%= profile.version %></td></tr>
7
+ <% if profile.summary %>
8
+ <tr class="profile-summary"><th>Summary:</th><td><%= profile.summary %></td></tr>
9
+ <% end %>
10
+ <% if profile.skip_message %>
11
+ <tr class="profile-skip-message"><th>Skip Message:</th><td><%= profile.skip_message %></td></tr>
12
+ <% end %>
13
+ </table>
14
+
15
+ <% if profile.status == "loaded" %>
16
+ <% profile.controls.each do |control| %>
17
+ <%= ERB.new(File.read(template_path + "/control.html.erb"), nil, nil, "_ctl").result(binding) %>
18
+ <% end %>
19
+ <% end %>
20
+ </div>
@@ -0,0 +1,15 @@
1
+ <% slugged_id = result.resource_title.to_s.gsub(/\W/, "_") %>
2
+ <div class="result" id="result-<%= slugged_id %>">
3
+ <h4 class="resource-title">Resource <code><%= result.resource_title.to_s %></code></h4>
4
+ <table class="result-metadata info">
5
+ <tr class="expectation_message"><th>Test:</th><td><code><%= result.expectation_message %></code></td></tr>
6
+ <tr class="status status-<%= result.status %>"><th>Status:</th><td><div><%= result.status.capitalize %></div></td></tr>
7
+ <% if result.status == "failed" %>
8
+ <tr class="fail_message"><th>Failure Message:</th><td><code><%= result.message %></code></td></tr>
9
+ <% end %>
10
+ <% if result.status == "skipped" %>
11
+ <tr class="skip_message"><th>Skip Message:</th><td><%= result.skip_message %></td></tr>
12
+ <% end %>
13
+ <tr class="duration"><th>Duration:</th><td><%= result.run_time %> seconds</td></tr>
14
+ </table>
15
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="selector-panel">
2
+ <p id="selector-instructions">Display controls that are:</p>
3
+ <input class="selector-checkbox" id="passed-checkbox" type="checkbox" checked="checked"/><label for="passed-checkbox">Passed</label>
4
+ <input class="selector-checkbox" id="skipped-checkbox" type="checkbox" checked="checked"/><label for="skipped-checkbox">Skipped</label>
5
+ <input class="selector-checkbox" id="failed-checkbox" type="checkbox" checked="checked"/><label for="failed-checkbox">Failed</label>
6
+ <p id="selector-instructions">Display profiles that are:</p>
7
+ <input class="profile-selector-checkbox" id="child-profile-checkbox" type="checkbox" /><label for="child-profile-checkbox">Dependent Profiles</label>
8
+ </div>
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: 4.20.10
4
+ version: 4.21.1
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: 2020-06-18 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -536,6 +536,7 @@ files:
536
536
  - lib/inspec/resources/inetd_conf.rb
537
537
  - lib/inspec/resources/ini.rb
538
538
  - lib/inspec/resources/interface.rb
539
+ - lib/inspec/resources/interfaces.rb
539
540
  - lib/inspec/resources/ip6tables.rb
540
541
  - lib/inspec/resources/iptables.rb
541
542
  - lib/inspec/resources/json.rb
@@ -724,6 +725,17 @@ files:
724
725
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb
725
726
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb
726
727
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb
728
+ - lib/plugins/inspec-reporter-html2/README.md
729
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2.rb
730
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/reporter.rb
731
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/version.rb
732
+ - lib/plugins/inspec-reporter-html2/templates/body.html.erb
733
+ - lib/plugins/inspec-reporter-html2/templates/control.html.erb
734
+ - lib/plugins/inspec-reporter-html2/templates/default.css
735
+ - lib/plugins/inspec-reporter-html2/templates/default.js
736
+ - lib/plugins/inspec-reporter-html2/templates/profile.html.erb
737
+ - lib/plugins/inspec-reporter-html2/templates/result.html.erb
738
+ - lib/plugins/inspec-reporter-html2/templates/selector.html.erb
727
739
  - lib/plugins/inspec-reporter-json-min/README.md
728
740
  - lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min.rb
729
741
  - lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min/reporter.rb