inspec-core 2.2.78 → 2.2.101

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd2c06a328a1d1852683797eaafa3b7391e39b82a22b8bb830bb965fabb6b1ab
4
- data.tar.gz: bc65f001fafc0b7b7fefe90309388cea38ad6968e081dc4a136f4cc1bb6ee531
3
+ metadata.gz: bad3e7476f7a3931284706247846b67ecabfb59be55430187e86dc6635436a4f
4
+ data.tar.gz: ec9f1586d0bde6037aa60a25ee9d758feb21e9715a45019baaa7189b9de599df
5
5
  SHA512:
6
- metadata.gz: '0822f141bda2c4640c154f61f3b819f05c154a213aaef9fca6e24b011d10c8344f85637bb356c4ec1ae6772db1fb27c88637beb0051607a0b71d1afb07977e00'
7
- data.tar.gz: aa6727726d7418819f3c905c058a49911fbb272bc0a7627307112015eb0fa455a5fbdd6592ebf6cbfe6a7d7416bd091b9a51139a8f5d8eb80ec72cedd307f3a6
6
+ metadata.gz: ca03041c8f5168ac760996394b57649208debb42e761dcca2fda628adc9850d72c4c962ceb34df836313169d1137a9217dc69b6f3fa3fa64c64f70298b514a18
7
+ data.tar.gz: 6a6aeb327d3664bb505b35d80a68d157eef7427f2bfe43062c2559ca6dc320bc4350be61fe85b26768a9d8348923099b726880609628162ee3478b6956146485
@@ -1,31 +1,62 @@
1
1
  # Change Log
2
2
  <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
3
- <!-- latest_release 2.2.78 -->
4
- ## [v2.2.78](https://github.com/inspec/inspec/tree/v2.2.78) (2018-08-30)
3
+ <!-- latest_release 2.2.101 -->
4
+ ## [v2.2.101](https://github.com/inspec/inspec/tree/v2.2.101) (2018-09-14)
5
5
 
6
6
  #### Merged Pull Requests
7
- - Update demo site nom packages [#3343](https://github.com/inspec/inspec/pull/3343) ([miah](https://github.com/miah))
7
+ - Fix profile vendoring on Windows [#3378](https://github.com/inspec/inspec/pull/3378) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
8
8
  <!-- latest_release -->
9
9
 
10
- <!-- release_rollup since=2.2.70 -->
11
- ### Changes since 2.2.70 release
10
+ <!-- release_rollup since=2.2.78 -->
11
+ ### Changes since 2.2.78 release
12
12
 
13
13
  #### New Features
14
- - Add HTTP basic auth for URL based inspec deps [#3341](https://github.com/inspec/inspec/pull/3341) ([frezbo](https://github.com/frezbo)) <!-- 2.2.77 -->
15
- - Support erb rendering [#3338](https://github.com/inspec/inspec/pull/3338) ([frezbo](https://github.com/frezbo)) <!-- 2.2.76 -->
14
+ - Add string impact options for controls [#3359](https://github.com/inspec/inspec/pull/3359) ([jquick](https://github.com/jquick)) <!-- 2.2.96 -->
16
15
 
17
16
  #### Bug Fixes
18
- - fix skip message not being passed for merge [#3329](https://github.com/inspec/inspec/pull/3329) ([frezbo](https://github.com/frezbo)) <!-- 2.2.73 -->
17
+ - Fix the compliance target error checks [#3392](https://github.com/inspec/inspec/pull/3392) ([jquick](https://github.com/jquick)) <!-- 2.2.94 -->
18
+ - Prevent logs from showing up when running inspec json [#3391](https://github.com/inspec/inspec/pull/3391) ([jquick](https://github.com/jquick)) <!-- 2.2.93 -->
19
+ - Fixing AWS integration tests. [#3374](https://github.com/inspec/inspec/pull/3374) ([MartinLogan](https://github.com/MartinLogan)) <!-- 2.2.87 -->
20
+ - enforce utf encoding for cli output [#3376](https://github.com/inspec/inspec/pull/3376) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.86 -->
21
+ - Fix vendoring functional test cleanup [#3377](https://github.com/inspec/inspec/pull/3377) ([jquick](https://github.com/jquick)) <!-- 2.2.85 -->
22
+ - use multipart gem for upload to support upload on windows [#3369](https://github.com/inspec/inspec/pull/3369) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.84 -->
23
+ - ensure we use the mock backend when we upload profiles [#3370](https://github.com/inspec/inspec/pull/3370) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.83 -->
24
+
25
+ #### Enhancements
26
+ - do not show success message since its confusing [#3366](https://github.com/inspec/inspec/pull/3366) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.82 -->
27
+ - Harmonize vendoring (ensure archives are extracted and local paths do not vendor on exec) [#3286](https://github.com/inspec/inspec/pull/3286) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.2.81 -->
28
+ - handle errors from automate report and display them to the user [#3360](https://github.com/inspec/inspec/pull/3360) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.80 -->
19
29
 
20
30
  #### Merged Pull Requests
21
- - Update demo site nom packages [#3343](https://github.com/inspec/inspec/pull/3343) ([miah](https://github.com/miah)) <!-- 2.2.78 -->
22
- - Fix the brew command to install inspec [#3335](https://github.com/inspec/inspec/pull/3335) ([tas50](https://github.com/tas50)) <!-- 2.2.75 -->
23
- - Convert legacy supports to their platform counterparts [#3333](https://github.com/inspec/inspec/pull/3333) ([jquick](https://github.com/jquick)) <!-- 2.2.74 -->
24
- - bump inspec/train version [#3331](https://github.com/inspec/inspec/pull/3331) ([tomqwu](https://github.com/tomqwu)) <!-- 2.2.72 -->
25
- - Cached profiles with Compliance Fetcher [#3221](https://github.com/inspec/inspec/pull/3221) ([itmustbejj](https://github.com/itmustbejj)) <!-- 2.2.71 -->
31
+ - Fix profile vendoring on Windows [#3378](https://github.com/inspec/inspec/pull/3378) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.2.101 -->
32
+ - Add platforms schema command [#3346](https://github.com/inspec/inspec/pull/3346) ([jquick](https://github.com/jquick)) <!-- 2.2.97 -->
33
+ - Bump omnibus ruby to 2.5.1 [#3390](https://github.com/inspec/inspec/pull/3390) ([jquick](https://github.com/jquick)) <!-- 2.2.95 -->
34
+ - Add windows functional tests [#3385](https://github.com/inspec/inspec/pull/3385) ([jquick](https://github.com/jquick)) <!-- 2.2.92 -->
35
+ - Populate code for inspec json inheritance [#3386](https://github.com/inspec/inspec/pull/3386) ([jquick](https://github.com/jquick)) <!-- 2.2.91 -->
36
+ - Revert uuid change from A2 report [#3387](https://github.com/inspec/inspec/pull/3387) ([jquick](https://github.com/jquick)) <!-- 2.2.90 -->
37
+ - Implement InSpec global attributes [#3318](https://github.com/inspec/inspec/pull/3318) ([jquick](https://github.com/jquick)) <!-- 2.2.89 -->
38
+ - Update rubyzip to resolve a directory traversal security vulnerability. [#3388](https://github.com/inspec/inspec/pull/3388) ([miah](https://github.com/miah)) <!-- 2.2.88 -->
39
+ - Allow target-id passthrough [#3320](https://github.com/inspec/inspec/pull/3320) ([jquick](https://github.com/jquick)) <!-- 2.2.79 -->
26
40
  <!-- release_rollup -->
27
41
 
28
42
  <!-- latest_stable_release -->
43
+ ## [v2.2.78](https://github.com/inspec/inspec/tree/v2.2.78) (2018-08-30)
44
+
45
+ #### New Features
46
+ - Support erb rendering [#3338](https://github.com/inspec/inspec/pull/3338) ([frezbo](https://github.com/frezbo))
47
+ - Add HTTP basic auth for URL based inspec deps [#3341](https://github.com/inspec/inspec/pull/3341) ([frezbo](https://github.com/frezbo))
48
+
49
+ #### Bug Fixes
50
+ - fix skip message not being passed for merge [#3329](https://github.com/inspec/inspec/pull/3329) ([frezbo](https://github.com/frezbo))
51
+
52
+ #### Merged Pull Requests
53
+ - Cached profiles with Compliance Fetcher [#3221](https://github.com/inspec/inspec/pull/3221) ([itmustbejj](https://github.com/itmustbejj))
54
+ - bump inspec/train version [#3331](https://github.com/inspec/inspec/pull/3331) ([tomqwu](https://github.com/tomqwu))
55
+ - Convert legacy supports to their platform counterparts [#3333](https://github.com/inspec/inspec/pull/3333) ([jquick](https://github.com/jquick))
56
+ - Fix the brew command to install inspec [#3335](https://github.com/inspec/inspec/pull/3335) ([tas50](https://github.com/tas50))
57
+ - Update demo site nom packages [#3343](https://github.com/inspec/inspec/pull/3343) ([miah](https://github.com/miah))
58
+ <!-- latest_stable_release -->
59
+
29
60
  ## [v2.2.70](https://github.com/inspec/inspec/tree/v2.2.70) (2018-08-24)
30
61
 
31
62
  #### Enhancements
@@ -38,7 +69,6 @@
38
69
  - Add cloudlinux under redhat family [#2935](https://github.com/inspec/inspec/pull/2935) ([tarcinil](https://github.com/tarcinil))
39
70
  - Suppress logs for json-automate reporter [#3324](https://github.com/inspec/inspec/pull/3324) ([jquick](https://github.com/jquick))
40
71
  - Rebuild InSpec omni bundles [#3327](https://github.com/inspec/inspec/pull/3327) ([jquick](https://github.com/jquick))
41
- <!-- latest_stable_release -->
42
72
 
43
73
  ## [v2.2.64](https://github.com/inspec/inspec/tree/v2.2.64) (2018-08-17)
44
74
 
@@ -51,6 +51,7 @@ Each profile must have an `inspec.yml` file that defines the following informati
51
51
  * Use `inspec_version` to place SemVer constraints on the version of InSpec that the profile can run under.
52
52
  * Use `supports` to specify a list of supported platform targets.
53
53
  * Use `depends` to define a list of profiles on which this profile depends.
54
+ * Use `attributes` to define a list of attributes you can use in your controls.
54
55
 
55
56
  `name` is required; all other profile settings are optional. For example:
56
57
 
@@ -336,15 +337,68 @@ profile `my_dep` using the name `my_res2`.
336
337
 
337
338
  # Profile Attributes
338
339
 
339
- Attributes may be used in profiles to define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. First specify a variable in the control for each secret, then add the secret to a YAML file located on the local machine, and then run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
340
+ Attributes are frequently used to parameterize a profile for use in different environments or targets. It can also be used define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. Attributes may be set for the whole profile in the `inspec.yml`.
340
341
 
341
- For example, a control:
342
+ Attributes may contain the following options:
342
343
 
344
+ * Use `default` to set a default value for the attribute.
345
+ * Use `type` to restrict an attribute to a specific type (any, string, numeric, array, hash, boolean, regex).
346
+ * Use `required` to mandate the attribute has a default value or a value from a attribute YAML file.
347
+ * Use `description` to set a brief description for the attribute.
348
+
349
+
350
+ You can specify attributes in your `inspec.yml` using the `attributes` setting. For example, to add a `user` attribute for your profile:
351
+ ```YAML
352
+ attributes:
353
+ - name: user
354
+ type: string
355
+ default: bob
356
+ ```
357
+
358
+ Example of adding a array object of servers:
359
+ ```YAML
360
+ attributes:
361
+ - name: servers
362
+ type: array
363
+ default:
364
+ - server1
365
+ - server2
366
+ - server3
367
+ ```
368
+
369
+ To access an attribute you will use the `attribute` keyword. You can use this anywhere in your control code.
370
+
371
+ For example:
343
372
  ```Ruby
344
- # define these attributes on the top-level of your file and re-use them across all tests!
345
- val_user = attribute('user', default: 'alice', description: 'An identification for the user')
346
- val_password = attribute('password', description: 'A value for the password')
373
+ current_user = attribute('user')
374
+
375
+ control 'system-users' do
376
+ describe attribute('user') do
377
+ it { should eq 'bob' }
378
+ end
379
+
380
+ describe current_user do
381
+ it { should eq attribute('user') }
382
+ end
383
+ end
384
+ ```
385
+
386
+ For sensitive data it is recomended to use a secrets YAML file located on the local machine to populate the values of attributes. A secrets file will always overwrite a attributes default value. To use the secrets file run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
387
+
388
+ For example, a inspec.yml:
389
+ ```YAML
390
+ attributes:
391
+ - name: username
392
+ type: string
393
+ required: true
394
+ - name: password
395
+ type: string
396
+ required: true
397
+ ```
347
398
 
399
+ The control:
400
+
401
+ ```Ruby
348
402
  control 'system-users' do
349
403
  impact 0.8
350
404
  desc '
@@ -352,11 +406,11 @@ control 'system-users' do
352
406
  specified password.
353
407
  '
354
408
 
355
- val_user do
409
+ describe attribute('username') do
356
410
  it { should eq 'bob' }
357
411
  end
358
412
 
359
- describe val_password do
413
+ describe attribute('password') do
360
414
  it { should eq 'secret' }
361
415
  end
362
416
  end
@@ -365,7 +419,7 @@ end
365
419
  And a YAML file named `profile-attribute.yml`:
366
420
 
367
421
  ```YAML
368
- user: bob
422
+ username: bob
369
423
  password: secret
370
424
  ```
371
425
 
@@ -375,6 +429,50 @@ The following command runs the tests and applies the secrets specified in `profi
375
429
  $ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
376
430
  ```
377
431
 
432
+ To change your attributes for platform specific cases you can setup multiple `--attrs` files.
433
+
434
+ For example, a inspec.yml:
435
+ ```YAML
436
+ attributes:
437
+ - name: users
438
+ type: array
439
+ required: true
440
+ ```
441
+
442
+ A YAML file named `windows.yml`
443
+ ```YAML
444
+ users:
445
+ - Administrator
446
+ - Guest
447
+ - Randy
448
+ ```
449
+
450
+ A YAML file named `linux.yml`
451
+ ```YAML
452
+ users:
453
+ - root
454
+ - shadow
455
+ - rmadison
456
+ ```
457
+
458
+ The control file:
459
+ ```RUBY
460
+ control 'system-users' do
461
+ impact 0.8
462
+ desc 'Confirm the proper users are created on the system'
463
+
464
+ describe users do
465
+ its('usernames') { should eq attribute('users') }
466
+ end
467
+ end
468
+ ```
469
+
470
+ The following command runs the tests and applies the attributes specified:
471
+ ```bash
472
+ $ inspec exec examples/profile-attribute --attrs examples/windows.yml
473
+ $ inspec exec examples/profile-attribute --attrs examples/linux.yml
474
+ ```
475
+
378
476
  See the full example in the InSpec open source repository: [Example InSpec Profile with Attributes](https://github.com/chef/inspec/tree/master/examples/profile-attribute)
379
477
 
380
478
  # Profile files
@@ -7,7 +7,8 @@ license: Apache-2.0
7
7
  summary: Demonstrates the use of InSpec profile inheritance
8
8
  version: 1.0.0
9
9
  supports:
10
- - os-family: unix
10
+ - platform-family: unix
11
+ - platform-family: windows
11
12
  depends:
12
13
  - name: profile
13
14
  path: ../profile
@@ -11,7 +11,7 @@ title 'Gordon Config Checks'
11
11
  # EOF
12
12
  # ```
13
13
  control 'gordon-1.0' do
14
- impact 0.7
14
+ impact 'critical'
15
15
  title 'Verify the version number of Gordon'
16
16
  desc 'An optional description...'
17
17
  tag 'gordon'
@@ -28,6 +28,8 @@ control 'ssh-1' do
28
28
  ref 'DISA-RHEL6-SG - Section 9.2.1', url: 'http://iasecontent.disa.mil/stigs/zip/Jan2016/U_RedHat_6_V1R10_STIG.zip'
29
29
  ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
30
30
 
31
+ only_if { platform.in_family?('unix') }
32
+
31
33
  describe file('/bin/sh') do
32
34
  it { should be_owned_by 'root' }
33
35
  end
@@ -7,4 +7,5 @@ license: Apache-2.0
7
7
  summary: Demonstrates the use of InSpec Compliance Profile
8
8
  version: 1.0.0
9
9
  supports:
10
- - os-family: unix
10
+ - platform-family: unix
11
+ - platform-family: windows
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.required_ruby_version = '>= 2.3'
24
24
 
25
- spec.add_dependency 'train-core', '~> 1.4', '>= 1.4.35'
25
+ spec.add_dependency 'train-core', '~> 1.4', '>= 1.4.37'
26
26
  spec.add_dependency 'thor', '~> 0.20'
27
27
  spec.add_dependency 'json', '>= 1.8', '< 3.0'
28
28
  spec.add_dependency 'method_source', '~> 0.8'
@@ -40,4 +40,5 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency 'parslet', '~> 1.5'
41
41
  spec.add_dependency 'semverse'
42
42
  spec.add_dependency 'htmlentities'
43
+ spec.add_dependency 'multipart-post'
43
44
  end
@@ -69,7 +69,8 @@ module Compliance
69
69
  li("#{profile['title']} v#{profile['version']} (#{mark_text(owner + '/' + profile['name'])})")
70
70
  }
71
71
  else
72
- puts msg, 'Could not find any profiles'
72
+ puts msg if msg != 'success'
73
+ puts 'Could not find any profiles'
73
74
  exit 1
74
75
  end
75
76
  rescue Compliance::ServerConfigurationMissing
@@ -149,6 +150,12 @@ module Compliance
149
150
 
150
151
  o = options.dup
151
152
  configure_logger(o)
153
+
154
+ # only run against the mock backend, otherwise we run against the local system
155
+ o[:backend] = Inspec::Backend.create(target: 'mock://')
156
+ o[:check_mode] = true
157
+ o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
158
+
152
159
  # check the profile, we only allow to upload valid profiles
153
160
  profile = Inspec::Profile.for_target(path, o)
154
161
 
@@ -190,7 +197,9 @@ module Compliance
190
197
  end
191
198
 
192
199
  # if it is a directory, tar it to tmp directory
200
+ generated = false
193
201
  if File.directory?(path)
202
+ generated = true
194
203
  archive_path = Dir::Tmpname.create([profile_name, '.tar.gz']) {}
195
204
  puts "Generate temporary profile archive at #{archive_path}"
196
205
  profile.archive({ output: archive_path, ignore_errors: false, overwrite: true })
@@ -208,6 +217,9 @@ module Compliance
208
217
  end
209
218
  success, msg = Compliance::API.upload(config, config['owner'], pname, archive_path)
210
219
 
220
+ # delete temp file if it was temporary generated
221
+ File.delete(archive_path) if generated && File.exist?(archive_path)
222
+
211
223
  if success
212
224
  puts 'Successfully uploaded profile'
213
225
  else
@@ -3,6 +3,7 @@
3
3
  # author: Dominik Richter
4
4
 
5
5
  require 'net/http'
6
+ require 'net/http/post/multipart'
6
7
  require 'uri'
7
8
 
8
9
  module Compliance
@@ -60,7 +61,7 @@ module Compliance
60
61
 
61
62
  req.body_stream=File.open(file_path, 'rb')
62
63
  req.add_field('Content-Length', File.size(file_path))
63
- req.add_field('Content-Type', 'application/x-gtar')
64
+ req.add_field('Content-Type', 'application/x-gzip')
64
65
 
65
66
  boundary = 'INSPEC-PROFILE-UPLOAD'
66
67
  req.add_field('session', boundary)
@@ -77,24 +78,14 @@ module Compliance
77
78
  http.use_ssl = (uri.scheme == 'https')
78
79
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE if insecure
79
80
 
80
- req = Net::HTTP::Post.new(uri)
81
- headers.each do |key, value|
82
- req.add_field(key, value)
81
+ File.open(file_path) do |tar|
82
+ req = Net::HTTP::Post::Multipart.new(uri, 'file' => UploadIO.new(tar, 'application/x-gzip', File.basename(file_path)))
83
+ headers.each do |key, value|
84
+ req.add_field(key, value)
85
+ end
86
+ res = http.request(req)
87
+ return res
83
88
  end
84
-
85
- boundry = 'AaB03x'
86
- req.add_field('Content-Type', "multipart/form-data; boundary=#{boundry}")
87
-
88
- post_body = []
89
- post_body << "--#{boundry}\r\n"
90
- post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{File.basename(file_path)}\"\r\n"
91
- post_body << "Content-Type: application/x-gtar\r\n\r\n"
92
- post_body << File.read(file_path)
93
- post_body << "\r\n\r\n--#{boundry}--\r\n"
94
- req.body = post_body.join
95
-
96
- res=http.request(req)
97
- res
98
89
  end
99
90
 
100
91
  # sends a http requests
@@ -17,12 +17,12 @@ module Compliance
17
17
 
18
18
  def initialize(target, opts)
19
19
  super(target, opts)
20
+ @upstream_sha256 = ''
20
21
  if target.is_a?(Hash) && target.key?(:url)
21
22
  @target = target[:url]
22
23
  @upstream_sha256 = target[:sha256]
23
24
  elsif target.is_a?(String)
24
25
  @target = target
25
- @upstream_sha256 = ''
26
26
  end
27
27
  end
28
28
 
@@ -30,7 +30,7 @@ module Compliance
30
30
  upstream_sha256.empty? ? super : upstream_sha256
31
31
  end
32
32
 
33
- def self.check_compliance_token(config)
33
+ def self.check_compliance_token(uri, config)
34
34
  if config['token'].nil? && config['refresh_token'].nil?
35
35
  if config['server_type'] == 'automate'
36
36
  server = 'automate'
@@ -73,7 +73,7 @@ module Compliance
73
73
  if target.respond_to?(:key?) && target.key?(:sha256)
74
74
  profile_checksum = target[:sha256]
75
75
  else
76
- check_compliance_token(config)
76
+ check_compliance_token(uri, config)
77
77
  # verifies that the target e.g base/ssh exists
78
78
  # Call profiles directly instead of exist? to capture the results
79
79
  # so we can access the upstream sha256 from the results.
@@ -10,21 +10,23 @@ module Fetchers
10
10
  priority 0
11
11
 
12
12
  def self.resolve(target)
13
- local_path = if target.is_a?(String)
14
- resolve_from_string(target)
15
- elsif target.is_a?(Hash)
16
- resolve_from_hash(target)
17
- end
18
-
19
- new(local_path) if local_path
13
+ if target.is_a?(String)
14
+ local_path = resolve_from_string(target)
15
+ new(local_path) if local_path
16
+ elsif target.is_a?(Hash)
17
+ local_path = resolve_from_hash(target)
18
+ new(local_path, target) if local_path
19
+ end
20
20
  end
21
21
 
22
22
  def self.resolve_from_hash(target)
23
23
  return unless target.key?(:path)
24
24
 
25
- local_path = target[:path]
26
- local_path = File.expand_path(local_path, target[:cwd]) if target.key?(:cwd)
27
- local_path
25
+ if target.key?(:cwd)
26
+ File.expand_path(target[:path], target[:cwd])
27
+ else
28
+ target[:path]
29
+ end
28
30
  end
29
31
 
30
32
  def self.resolve_from_string(target)
@@ -36,15 +38,48 @@ module Fetchers
36
38
  target = target.tr('\\', '/')
37
39
  end
38
40
 
39
- target if File.exist?(target)
41
+ target if File.exist?(File.expand_path(target))
40
42
  end
41
43
 
42
- def initialize(target)
44
+ def initialize(target, opts = {})
43
45
  @target = target
46
+ @backend = opts[:backend]
47
+ @archive_shasum = nil
44
48
  end
45
49
 
46
- def fetch(_path)
47
- archive_path
50
+ def fetch(path)
51
+ # If `inspec exec` is used then we should not vendor/fetch. This makes
52
+ # local development easier and more predictable.
53
+ return @target if Inspec::BaseCLI.inspec_cli_command == :exec
54
+
55
+ # Skip vendoring if @backend is not set (example: ad hoc runners)
56
+ return @target unless @backend
57
+
58
+ if File.directory?(@target)
59
+ # Create an archive, checksum, and move to the vendor directory
60
+ Dir.mktmpdir do |tmpdir|
61
+ temp_archive = File.join(tmpdir, "#{File.basename(@target)}.tar.gz")
62
+ opts = {
63
+ backend: @backend,
64
+ output: temp_archive,
65
+ }
66
+
67
+ # Create a temporary archive at `opts[:output]`
68
+ Inspec::Profile.for_target(@target, opts).archive(opts)
69
+
70
+ checksum = perform_shasum(temp_archive)
71
+ final_path = File.join(path, checksum)
72
+ FileUtils.mkdir_p(final_path)
73
+ Inspec::FileProvider.for_path(temp_archive).extract(final_path)
74
+ end
75
+ else
76
+ # Verify profile (archive) is valid and extract to vendor directory
77
+ opts = { backend: @backend }
78
+ Inspec::Profile.for_target(@target, opts).check
79
+ Inspec::FileProvider.for_path(@target).extract(path)
80
+ end
81
+
82
+ @target
48
83
  end
49
84
 
50
85
  def archive_path
@@ -60,9 +95,17 @@ module Fetchers
60
95
  end
61
96
 
62
97
  def sha256
63
- return nil if File.directory?(@target)
64
- @archive_shasum ||=
65
- OpenSSL::Digest::SHA256.digest(File.read(@target)).unpack('H*')[0]
98
+ if !@archive_shasum.nil?
99
+ @archive_shasum
100
+ elsif File.directory?(@target)
101
+ nil
102
+ else
103
+ perform_shasum(@target)
104
+ end
105
+ end
106
+
107
+ def perform_shasum(target)
108
+ @archive_shasum ||= OpenSSL::Digest::SHA256.digest(File.read(target)).unpack('H*')[0]
66
109
  end
67
110
 
68
111
  def resolved_source