inspec-core 5.22.3 → 5.22.36
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 +4 -4
- data/Gemfile +6 -19
- data/inspec-core.gemspec +6 -4
- data/lib/inspec/cli.rb +22 -5
- data/lib/inspec/config.rb +32 -10
- data/lib/inspec/fetcher/git.rb +43 -28
- data/lib/inspec/formatters/base.rb +1 -1
- data/lib/inspec/profile.rb +340 -18
- data/lib/inspec/resources/host.rb +4 -16
- data/lib/inspec/resources/security_policy.rb +7 -2
- data/lib/inspec/rule.rb +5 -0
- data/lib/inspec/utils/profile_ast_helpers.rb +372 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +5 -3
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +2 -2
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +7 -6
- data/lib/plugins/inspec-reporter-html2/templates/default.js +6 -6
- metadata +11 -10
@@ -0,0 +1,372 @@
|
|
1
|
+
require "ast"
|
2
|
+
require "rubocop-ast"
|
3
|
+
module Inspec
|
4
|
+
class Profile
|
5
|
+
class AstHelper
|
6
|
+
class CollectorBase
|
7
|
+
include Parser::AST::Processor::Mixin
|
8
|
+
include RuboCop::AST::Traversal
|
9
|
+
|
10
|
+
attr_reader :memo
|
11
|
+
def initialize(memo)
|
12
|
+
@memo = memo
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class InputCollectorBase < CollectorBase
|
17
|
+
VALID_INPUT_OPTIONS = %i{name value type required priority pattern profile sensitive}.freeze
|
18
|
+
|
19
|
+
REQUIRED_VALUES_MAP = {
|
20
|
+
true: true,
|
21
|
+
false: false,
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
def initialize(memo)
|
25
|
+
@memo = memo
|
26
|
+
end
|
27
|
+
|
28
|
+
def collect_input(input_children)
|
29
|
+
input_name = input_children.children[2].value
|
30
|
+
|
31
|
+
# Check if memo[:inputs] already has a value for the input_name, if yes, then skip adding it to the array
|
32
|
+
unless memo[:inputs].any? { |input| input[:name] == input_name }
|
33
|
+
# The value will be updated if available in the input_children
|
34
|
+
opts = {
|
35
|
+
value: "Input '#{input_name}' does not have a value. Skipping test.",
|
36
|
+
}
|
37
|
+
|
38
|
+
if input_children.children[3]&.type == :hash
|
39
|
+
input_children.children[3].children.each do |child_node|
|
40
|
+
if VALID_INPUT_OPTIONS.include?(child_node.key.value)
|
41
|
+
if child_node.value.class == RuboCop::AST::Node && REQUIRED_VALUES_MAP.key?(child_node.value.type)
|
42
|
+
opts.merge!(child_node.key.value => REQUIRED_VALUES_MAP[child_node.value.type])
|
43
|
+
elsif child_node.value.class == RuboCop::AST::HashNode
|
44
|
+
# Here value will be a hash
|
45
|
+
values = {}
|
46
|
+
child_node.value.children.each do |grand_child_node|
|
47
|
+
values.merge!(grand_child_node.key.value => grand_child_node.value.value)
|
48
|
+
end
|
49
|
+
opts.merge!(child_node.key.value => values)
|
50
|
+
else
|
51
|
+
opts.merge!(child_node.key.value => child_node.value.value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# TODO: Add rules for handling the input options or use existing rules if available
|
58
|
+
# 1. Handle pattern matching for the given input value
|
59
|
+
# 2. Handle data-type matching for the given input value
|
60
|
+
# 3. Handle required flag for the given input value
|
61
|
+
# 4. Handle sensitive flag for the given input value
|
62
|
+
memo[:inputs] ||= []
|
63
|
+
input_hash = {
|
64
|
+
name: input_name,
|
65
|
+
options: opts,
|
66
|
+
}
|
67
|
+
memo[:inputs] << input_hash
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def check_and_collect_input(node)
|
72
|
+
if input_pattern_match?(node)
|
73
|
+
collect_input(node)
|
74
|
+
else
|
75
|
+
node.children.each do |child_node|
|
76
|
+
check_and_collect_input(child_node) if input_pattern_match?(child_node)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def input_pattern_match?(node)
|
82
|
+
RuboCop::AST::NodePattern.new("(send nil? :input ...)").match(node)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class ImpactCollector < CollectorBase
|
87
|
+
def on_send(node)
|
88
|
+
if RuboCop::AST::NodePattern.new("(send nil? :impact ...)").match(node)
|
89
|
+
memo[:impact] = node.children[2].value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class DescCollector < CollectorBase
|
95
|
+
def on_send(node)
|
96
|
+
if RuboCop::AST::NodePattern.new("(send nil? :desc ...)").match(node)
|
97
|
+
memo[:descriptions] ||= {}
|
98
|
+
if node.children[2] && node.children[3]
|
99
|
+
# NOTE: This assumes the description is as below
|
100
|
+
# desc 'label', 'An optional description with a label' # Pair a part of the description with a label
|
101
|
+
memo[:descriptions] = memo[:descriptions].merge(node.children[2].value => node.children[3].value)
|
102
|
+
else
|
103
|
+
memo[:desc] = node.children[2].value
|
104
|
+
memo[:descriptions] = memo[:descriptions].merge(default: node.children[2].value)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class TitleCollector < CollectorBase
|
111
|
+
def on_send(node)
|
112
|
+
if RuboCop::AST::NodePattern.new("(send nil? :title ...)").match(node)
|
113
|
+
# TODO - title may not be a simple string
|
114
|
+
memo[:title] = node.children[2].value
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class TagCollector < CollectorBase
|
120
|
+
|
121
|
+
ACCPETABLE_TAG_TYPE_TO_VALUES = {
|
122
|
+
false: false,
|
123
|
+
true: true,
|
124
|
+
nil: nil,
|
125
|
+
}.freeze
|
126
|
+
|
127
|
+
def on_send(node)
|
128
|
+
if RuboCop::AST::NodePattern.new("(send nil? :tag ...)").match(node)
|
129
|
+
memo[:tags] ||= {}
|
130
|
+
|
131
|
+
node.children[2..-1].each do |tag_node|
|
132
|
+
collect_tags(tag_node)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def collect_tags(tag_node)
|
140
|
+
if tag_node.type == :str || tag_node.type == :sym
|
141
|
+
memo[:tags] = memo[:tags].merge(tag_node.value => nil)
|
142
|
+
elsif tag_node.type == :hash
|
143
|
+
tags_coll = {}
|
144
|
+
tag_node.children.each do |child_tag|
|
145
|
+
key = child_tag.key.value
|
146
|
+
if child_tag.value.type == :array
|
147
|
+
value = child_tag.value.children.map { |child_node| child_node.type == :str ? child_node.children.first : nil }
|
148
|
+
elsif ACCPETABLE_TAG_TYPE_TO_VALUES.key?(child_tag.value.type)
|
149
|
+
value = ACCPETABLE_TAG_TYPE_TO_VALUES[child_tag.value.type]
|
150
|
+
else
|
151
|
+
if child_tag.value.children.first.class == RuboCop::AST::SendNode
|
152
|
+
# Cases like this: (where there is no assignment of the value to a variable like gcp_project_id)
|
153
|
+
# tag project: gcp_project_id.to_s
|
154
|
+
#
|
155
|
+
# Lecacy evaluates gcp_project_id.to_s and then passes the value to the tag
|
156
|
+
# We are not evaluating the value here, so we are just passing the value as it is
|
157
|
+
#
|
158
|
+
# TODO: Do we need to evaluate the value here?
|
159
|
+
# (byebug) child_tag.value
|
160
|
+
# s(:send,
|
161
|
+
# s(:send, nil, :gcp_project_id), :to_s)
|
162
|
+
value = child_tag.value.children.first.children[1]
|
163
|
+
elsif child_tag.value.children.first.class == RuboCop::AST::Node
|
164
|
+
# Cases like this:
|
165
|
+
# control_id = '1.1'
|
166
|
+
# tag cis_gcp: control_id.to_s
|
167
|
+
value = child_tag.value.children.first.children[0]
|
168
|
+
else
|
169
|
+
value = child_tag.value.value
|
170
|
+
end
|
171
|
+
end
|
172
|
+
tags_coll.merge!(key => value)
|
173
|
+
end
|
174
|
+
memo[:tags] = memo[:tags].merge(tags_coll)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class RefCollector < CollectorBase
|
180
|
+
def on_send(node)
|
181
|
+
if RuboCop::AST::NodePattern.new("(send nil? :ref ...)").match(node)
|
182
|
+
# Construct the array of refs hash as below
|
183
|
+
|
184
|
+
# "refs": [
|
185
|
+
# {
|
186
|
+
# "url": "http://",
|
187
|
+
# "ref": "Some ref"
|
188
|
+
# },
|
189
|
+
# {
|
190
|
+
# "ref": "https://",
|
191
|
+
# }
|
192
|
+
# ]
|
193
|
+
|
194
|
+
# node.children[1] && node.children[1] == :ref - we don't need this check as the pattern match above will take care of it
|
195
|
+
return unless node.children[2]
|
196
|
+
|
197
|
+
references = {}
|
198
|
+
|
199
|
+
if node.children[2].type == :begin
|
200
|
+
# Case for: ref ({:ref=>"Some ref", :url=>"https://"})
|
201
|
+
# find the hash node
|
202
|
+
iterate_child_and_collect_ref(node.children[2].children, references)
|
203
|
+
elsif node.children[2].type == :str
|
204
|
+
# Case for: ref "ref1", url: "http://",
|
205
|
+
references.merge!(ref: node.children[2].value)
|
206
|
+
iterate_child_and_collect_ref(node.children[3..-1], references)
|
207
|
+
end
|
208
|
+
|
209
|
+
memo[:refs] ||= []
|
210
|
+
memo[:refs] << references
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
def iterate_child_and_collect_ref(child_node, references = {})
|
217
|
+
child_node.each do |ref_node|
|
218
|
+
if ref_node.type == :hash
|
219
|
+
iterate_hash_node(ref_node, references)
|
220
|
+
elsif ref_node.type == :str
|
221
|
+
references.merge!(ref_node.value => nil)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def iterate_hash_node(hash_node, references = {})
|
227
|
+
# hash node like this:
|
228
|
+
# s(:hash,
|
229
|
+
# s(:pair,
|
230
|
+
# s(:sym, :url),
|
231
|
+
# s(:str, "https://")))
|
232
|
+
#
|
233
|
+
# or like this:
|
234
|
+
# (byebug) hash_node
|
235
|
+
# s(:hash,
|
236
|
+
# s(:pair,
|
237
|
+
# s(:sym, :url),
|
238
|
+
# s(:send,
|
239
|
+
# s(:send, nil, :cis_url), :to_s)))
|
240
|
+
hash_node.children.each do |child_node|
|
241
|
+
if child_node.type == :pair
|
242
|
+
if child_node.value.children.first.class == RuboCop::AST::SendNode
|
243
|
+
# Case like this (where there is no assignment of the value to a variable like cis_url)
|
244
|
+
# ref 'CIS Benchmark', url: cis_url.to_s
|
245
|
+
# Lecacy evaluates cis_url.to_s and then passes the value to the ref
|
246
|
+
# We are not evaluating the value here, so we are just passing the value as it is
|
247
|
+
#
|
248
|
+
# TODO: Do we need to evaluate the value here?
|
249
|
+
#
|
250
|
+
# (byebug) child_node.value.children.first
|
251
|
+
# s(:send, nil, :cis_url)
|
252
|
+
value = child_node.value.children.first.children[1]
|
253
|
+
elsif child_node.value.class == RuboCop::AST::SendNode
|
254
|
+
# Cases like this:
|
255
|
+
# cis_url = attribute('cis_url')
|
256
|
+
# ref 'CIS Benchmark', url: cis_url.to_s
|
257
|
+
value = child_node.value.children.first.children[0]
|
258
|
+
else
|
259
|
+
# Cases like this: ref 'CIS Benchmark - 2', url: "https://"
|
260
|
+
# require 'byebug'; byebug
|
261
|
+
value = child_node.value.value
|
262
|
+
end
|
263
|
+
references.merge!(child_node.key.value => value)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class ControlIDCollector < CollectorBase
|
270
|
+
attr_reader :seen_control_ids, :source_location_ref, :include_tests
|
271
|
+
def initialize(memo, source_location_ref, include_tests: false)
|
272
|
+
@memo = memo
|
273
|
+
@seen_control_ids = {}
|
274
|
+
@source_location_ref = source_location_ref
|
275
|
+
@include_tests = include_tests
|
276
|
+
end
|
277
|
+
|
278
|
+
def on_block(block_node)
|
279
|
+
if RuboCop::AST::NodePattern.new("(block (send nil? :control ...) ...)").match(block_node)
|
280
|
+
# NOTE: Assuming begin block is at the index 2
|
281
|
+
begin_block = block_node.children[2]
|
282
|
+
control_node = block_node.children[0]
|
283
|
+
|
284
|
+
# TODO - This assumes the control ID is always a plain string, which we know it is often not!
|
285
|
+
control_id = control_node.children[2].value
|
286
|
+
# TODO - BUG - this keeps seeing the same nodes over and over againa, and so repeating control IDs. We are ignoring duplicate control IDs, which is incorrect.
|
287
|
+
return if seen_control_ids[control_id]
|
288
|
+
|
289
|
+
seen_control_ids[control_id] = true
|
290
|
+
|
291
|
+
control_data = {
|
292
|
+
id: control_id,
|
293
|
+
code: block_node.source,
|
294
|
+
source_location: {
|
295
|
+
line: block_node.first_line,
|
296
|
+
ref: source_location_ref,
|
297
|
+
},
|
298
|
+
title: nil,
|
299
|
+
desc: nil,
|
300
|
+
descriptions: {},
|
301
|
+
impact: 0.5,
|
302
|
+
refs: [],
|
303
|
+
tags: {},
|
304
|
+
}
|
305
|
+
control_data[:checks] = [] if include_tests
|
306
|
+
|
307
|
+
# Scan the code block for per-control metadata
|
308
|
+
collectors = []
|
309
|
+
collectors.push ImpactCollector.new(control_data)
|
310
|
+
collectors.push DescCollector.new(control_data)
|
311
|
+
collectors.push TitleCollector.new(control_data)
|
312
|
+
collectors.push TagCollector.new(control_data)
|
313
|
+
collectors.push RefCollector.new(control_data)
|
314
|
+
collectors.push InputCollectorWithinControlBlock.new(@memo)
|
315
|
+
collectors.push TestsCollector.new(control_data) if include_tests
|
316
|
+
|
317
|
+
begin_block.each_node do |node_within_control|
|
318
|
+
collectors.each { |collector| collector.process(node_within_control) }
|
319
|
+
end
|
320
|
+
|
321
|
+
memo[:controls].push control_data
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
class InputCollectorWithinControlBlock < InputCollectorBase
|
327
|
+
def initialize(memo)
|
328
|
+
@memo = memo
|
329
|
+
end
|
330
|
+
|
331
|
+
def on_send(node)
|
332
|
+
check_and_collect_input(node)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
class InputCollectorOutsideControlBlock < InputCollectorBase
|
337
|
+
def initialize(memo)
|
338
|
+
@memo = memo
|
339
|
+
end
|
340
|
+
|
341
|
+
# TODO: There is scope to refactor InputCollectorOutsideControlBlock and InputCollectorWithinControlBlock
|
342
|
+
# 1. We can have a single class for both the collectors
|
343
|
+
# 2. We can have a on_send and on_lvasgn method in the same class
|
344
|
+
# :lvasgn in ast stands for "local variable assignment"
|
345
|
+
def on_lvasgn(node)
|
346
|
+
# We are looking for the following pattern in the AST
|
347
|
+
# (lvasgn :var_name (send nil? :input ...))
|
348
|
+
# example: a = input('a') or a = input('a', value: 'b')
|
349
|
+
# and not this: a = 1
|
350
|
+
if RuboCop::AST::NodePattern.new("(lvasgn _ (send nil? :input ...))").match(node)
|
351
|
+
input_children = node.children[1]
|
352
|
+
collect_input(input_children)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def on_send(node)
|
357
|
+
check_and_collect_input(node)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
class TestsCollector < CollectorBase
|
362
|
+
|
363
|
+
def on_block(node)
|
364
|
+
if RuboCop::AST::NodePattern.new("(block (send nil? :describe ...) ...)").match(node) ||
|
365
|
+
RuboCop::AST::NodePattern.new("(block (send nil? :expect ...) ...)").match(node)
|
366
|
+
memo[:checks] << node.source
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
data/lib/inspec/version.rb
CHANGED
@@ -19,15 +19,17 @@ module Inspec
|
|
19
19
|
data = nil
|
20
20
|
if [".yaml", ".yml"].include? file_extension
|
21
21
|
data = Secrets::YAML.resolve(file_path)
|
22
|
-
|
23
|
-
|
22
|
+
unless data.nil?
|
23
|
+
data = data.inputs
|
24
|
+
validate_json_yaml(data)
|
25
|
+
end
|
24
26
|
elsif file_extension == ".csv"
|
25
27
|
data = Waivers::CSVFileReader.resolve(file_path)
|
26
28
|
headers = Waivers::CSVFileReader.headers
|
27
29
|
validate_headers(headers)
|
28
30
|
elsif file_extension == ".json"
|
29
31
|
data = Waivers::JSONFileReader.resolve(file_path)
|
30
|
-
validate_json_yaml(data)
|
32
|
+
validate_json_yaml(data) unless data.nil?
|
31
33
|
end
|
32
34
|
output.merge!(data) if !data.nil? && data.is_a?(Hash)
|
33
35
|
|
@@ -168,10 +168,10 @@ module InspecPlugins
|
|
168
168
|
end
|
169
169
|
|
170
170
|
# read profile name from inspec.yml
|
171
|
-
profile_name = profile.
|
171
|
+
profile_name = profile.name
|
172
172
|
|
173
173
|
# read profile version from inspec.yml
|
174
|
-
profile_version = profile.
|
174
|
+
profile_version = profile.version
|
175
175
|
|
176
176
|
# check that the profile is not uploaded already,
|
177
177
|
# confirm upload to the user (overwrite with --force)
|
@@ -1,4 +1,5 @@
|
|
1
|
-
<%
|
1
|
+
<% slugged_control_id = control.id.tr(" ", "_") %>
|
2
|
+
<% slugged_profile_id = profile.name.gsub(/\W/, "_") %>
|
2
3
|
<%
|
3
4
|
if enhanced_outcomes
|
4
5
|
status = control.status
|
@@ -13,7 +14,7 @@
|
|
13
14
|
end
|
14
15
|
%>
|
15
16
|
|
16
|
-
<div class="control control-status-<%= status %>" id="control-<%=
|
17
|
+
<div class="control control-status-<%= status %>" id="profile-<%= slugged_profile_id %>-control-<%= slugged_control_id %>">
|
17
18
|
|
18
19
|
<%
|
19
20
|
# Determine range of impact
|
@@ -29,7 +30,7 @@
|
|
29
30
|
%>
|
30
31
|
|
31
32
|
<h3 class="control-title">Control <code><%= control.id %></code></h3>
|
32
|
-
<table class="control-metadata info" id="control-metadata-<%=
|
33
|
+
<table class="control-metadata info" id="profile-<%= slugged_profile_id %>-control-metadata-<%= slugged_control_id %>">
|
33
34
|
<caption>Control Table</caption>
|
34
35
|
<tr class="status status-<%= status %>"><th>Status:</th><td><div><%= status.capitalize %></div></td></tr>
|
35
36
|
<% if control.title %><tr class="title"><th>Title:</th><td><%= control.title %></td></tr> <% end %>
|
@@ -64,9 +65,9 @@
|
|
64
65
|
<tr class="code">
|
65
66
|
<th>Source Code:</th>
|
66
67
|
<td>
|
67
|
-
<input type="button" class="show-source-code" id="show-code-<%=
|
68
|
-
<input type="button" class="hide-source-code hidden" id="hide-code-<%=
|
69
|
-
<pre class="source-code hidden" id="source-code-<%=
|
68
|
+
<input type="button" class="show-source-code" id="show-code-<%= slugged_profile_id %>-<%= slugged_control_id %>" value="Show Source"/>
|
69
|
+
<input type="button" class="hide-source-code hidden" id="hide-code-<%= slugged_profile_id %>-<%= slugged_control_id %>" value="Hide Source"/>
|
70
|
+
<pre class="source-code hidden" id="source-code-<%= slugged_profile_id %>-<%= slugged_control_id %>">
|
70
71
|
<code>
|
71
72
|
<%= control.code %>
|
72
73
|
</code>
|
@@ -11,17 +11,17 @@ function removeCssClass(id, cls) {
|
|
11
11
|
}
|
12
12
|
|
13
13
|
function handleShowSource(evt) {
|
14
|
-
var
|
14
|
+
var slugged_id = evt.srcElement.id.replace("show-code-", "")
|
15
15
|
addCssClass(evt.srcElement.id, "hidden")
|
16
|
-
removeCssClass("hide-code-" +
|
17
|
-
removeCssClass("source-code-" +
|
16
|
+
removeCssClass("hide-code-" + slugged_id, "hidden")
|
17
|
+
removeCssClass("source-code-" + slugged_id, "hidden")
|
18
18
|
}
|
19
19
|
|
20
20
|
function handleHideSource(evt) {
|
21
|
-
var
|
21
|
+
var slugged_id = evt.srcElement.id.replace("hide-code-", "")
|
22
22
|
addCssClass(evt.srcElement.id, "hidden")
|
23
|
-
addCssClass("source-code-" +
|
24
|
-
removeCssClass("show-code-" +
|
23
|
+
addCssClass("source-code-" + slugged_id, "hidden")
|
24
|
+
removeCssClass("show-code-" + slugged_id, "hidden")
|
25
25
|
}
|
26
26
|
|
27
27
|
function handleSelectorChange(evt) {
|
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.22.
|
4
|
+
version: 5.22.36
|
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: 2023-
|
11
|
+
date: 2023-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-telemetry
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
version: '0.20'
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 1.3.0
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -69,7 +69,7 @@ dependencies:
|
|
69
69
|
version: '0.20'
|
70
70
|
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
72
|
+
version: 1.3.0
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: method_source
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,7 +119,7 @@ dependencies:
|
|
119
119
|
version: '3.9'
|
120
120
|
- - "<="
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: '3.
|
122
|
+
version: '3.12'
|
123
123
|
type: :runtime
|
124
124
|
prerelease: false
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -129,7 +129,7 @@ dependencies:
|
|
129
129
|
version: '3.9'
|
130
130
|
- - "<="
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: '3.
|
132
|
+
version: '3.12'
|
133
133
|
- !ruby/object:Gem::Dependency
|
134
134
|
name: rspec-its
|
135
135
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,7 +167,7 @@ dependencies:
|
|
167
167
|
version: '3.4'
|
168
168
|
- - "<"
|
169
169
|
- !ruby/object:Gem::Version
|
170
|
-
version: '
|
170
|
+
version: '6.0'
|
171
171
|
type: :runtime
|
172
172
|
prerelease: false
|
173
173
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -177,7 +177,7 @@ dependencies:
|
|
177
177
|
version: '3.4'
|
178
178
|
- - "<"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
180
|
+
version: '6.0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: mixlib-log
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -325,7 +325,7 @@ dependencies:
|
|
325
325
|
version: '1.5'
|
326
326
|
- - "<"
|
327
327
|
- !ruby/object:Gem::Version
|
328
|
-
version: '
|
328
|
+
version: '3.0'
|
329
329
|
type: :runtime
|
330
330
|
prerelease: false
|
331
331
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -335,7 +335,7 @@ dependencies:
|
|
335
335
|
version: '1.5'
|
336
336
|
- - "<"
|
337
337
|
- !ruby/object:Gem::Version
|
338
|
-
version: '
|
338
|
+
version: '3.0'
|
339
339
|
- !ruby/object:Gem::Dependency
|
340
340
|
name: semverse
|
341
341
|
requirement: !ruby/object:Gem::Requirement
|
@@ -716,6 +716,7 @@ files:
|
|
716
716
|
- lib/inspec/utils/parser.rb
|
717
717
|
- lib/inspec/utils/pkey_reader.rb
|
718
718
|
- lib/inspec/utils/podman.rb
|
719
|
+
- lib/inspec/utils/profile_ast_helpers.rb
|
719
720
|
- lib/inspec/utils/run_data_filters.rb
|
720
721
|
- lib/inspec/utils/simpleconfig.rb
|
721
722
|
- lib/inspec/utils/spdx.rb
|