inspec-core 2.3.5 → 2.3.10
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/CHANGELOG.md +21 -8
- data/lib/bundles/inspec-compliance/api.rb +3 -353
- data/lib/bundles/inspec-compliance/configuration.rb +3 -102
- data/lib/bundles/inspec-compliance/http.rb +3 -115
- data/lib/bundles/inspec-compliance/support.rb +3 -35
- data/lib/bundles/inspec-compliance/target.rb +3 -142
- data/lib/inspec/base_cli.rb +4 -1
- data/lib/inspec/cli.rb +1 -1
- data/lib/inspec/control_eval_context.rb +2 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +3 -3
- data/lib/{bundles → plugins}/inspec-compliance/README.md +0 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +12 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +358 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +192 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +266 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb +103 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb +116 -0
- data/lib/{bundles → plugins/inspec-compliance/lib}/inspec-compliance/images/cc-token.png +0 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb +36 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +143 -0
- data/lib/plugins/inspec-compliance/test/functional/inspec_compliance_test.rb +43 -0
- data/lib/{bundles → plugins}/inspec-compliance/test/integration/default/cli.rb +0 -0
- data/lib/plugins/inspec-compliance/test/unit/api/login_test.rb +190 -0
- data/lib/plugins/inspec-compliance/test/unit/api_test.rb +385 -0
- data/lib/plugins/inspec-compliance/test/unit/target_test.rb +155 -0
- data/lib/resources/processes.rb +19 -3
- metadata +17 -10
- data/lib/bundles/inspec-compliance.rb +0 -16
- data/lib/bundles/inspec-compliance/.kitchen.yml +0 -20
- data/lib/bundles/inspec-compliance/api/login.rb +0 -193
- data/lib/bundles/inspec-compliance/bootstrap.sh +0 -41
- data/lib/bundles/inspec-compliance/cli.rb +0 -276
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c5e7615776b52330a209b35ca344d1bdb85a04f78903152edd67fa94d81700e
|
4
|
+
data.tar.gz: e6042ee4e8ede90034c06762b2dd2ab6135d0eeeef505ffccc138b0df566f5f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22bf4eed15b0f3b8ab6eb0ff13b7901bbe468c956d0a9c7615fcbce1e20e4974b4af823744106ed77db6d6fd40d31ae143a707edb8a94ae1d6aaf40bd1acc707
|
7
|
+
data.tar.gz: 5ff797572d8637e1e1d7a6939e4c95d2b33bdc5e4577f0db0677c85a850d536d7d1677ba28e9112473ebe60ca01f7aa4d0a3d05821a090630667f42b2d687f89
|
data/CHANGELOG.md
CHANGED
@@ -1,20 +1,34 @@
|
|
1
1
|
# Change Log
|
2
2
|
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
|
3
|
-
<!-- latest_release 2.3.
|
4
|
-
## [v2.3.
|
3
|
+
<!-- latest_release 2.3.10 -->
|
4
|
+
## [v2.3.10](https://github.com/inspec/inspec/tree/v2.3.10) (2018-10-04)
|
5
5
|
|
6
|
-
####
|
7
|
-
-
|
6
|
+
#### Enhancements
|
7
|
+
- Move compliance to v2 plugin [#3423](https://github.com/inspec/inspec/pull/3423) ([jquick](https://github.com/jquick))
|
8
8
|
<!-- latest_release -->
|
9
9
|
|
10
|
-
<!-- release_rollup since=2.3.
|
11
|
-
### Changes since 2.3.
|
10
|
+
<!-- release_rollup since=2.3.5 -->
|
11
|
+
### Changes since 2.3.5 release
|
12
12
|
|
13
13
|
#### Bug Fixes
|
14
|
-
-
|
14
|
+
- Fix distinct_exit cli desc to reflect reality [#3463](https://github.com/inspec/inspec/pull/3463) ([teknofire](https://github.com/teknofire)) <!-- 2.3.8 -->
|
15
|
+
|
16
|
+
#### Merged Pull Requests
|
17
|
+
- Fix `attribute` with empty hash regression [#3454](https://github.com/inspec/inspec/pull/3454) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.3.7 -->
|
18
|
+
|
19
|
+
#### Enhancements
|
20
|
+
- Move compliance to v2 plugin [#3423](https://github.com/inspec/inspec/pull/3423) ([jquick](https://github.com/jquick)) <!-- 2.3.10 -->
|
21
|
+
- Support finding larger processes on Busybox [#3446](https://github.com/inspec/inspec/pull/3446) ([RoboticCheese](https://github.com/RoboticCheese)) <!-- 2.3.9 -->
|
22
|
+
- Modify `cmp` matcher output to use `.inspect` [#3450](https://github.com/inspec/inspec/pull/3450) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.3.6 -->
|
15
23
|
<!-- release_rollup -->
|
16
24
|
|
17
25
|
<!-- latest_stable_release -->
|
26
|
+
## [v2.3.5](https://github.com/inspec/inspec/tree/v2.3.5) (2018-10-01)
|
27
|
+
|
28
|
+
#### Bug Fixes
|
29
|
+
- Update plugin gem install code [#3453](https://github.com/inspec/inspec/pull/3453) ([jquick](https://github.com/jquick))
|
30
|
+
<!-- latest_stable_release -->
|
31
|
+
|
18
32
|
## [v2.3.4](https://github.com/inspec/inspec/tree/v2.3.4) (2018-09-28)
|
19
33
|
|
20
34
|
#### New Features
|
@@ -37,7 +51,6 @@
|
|
37
51
|
- RFC inspec style guide [#3356](https://github.com/inspec/inspec/pull/3356) ([arlimus](https://github.com/arlimus))
|
38
52
|
- Pin postgresql to a lower cookbook version [#3449](https://github.com/inspec/inspec/pull/3449) ([jquick](https://github.com/jquick))
|
39
53
|
- Plugins: Example CLI Plugin, a Resource Lister [#3421](https://github.com/inspec/inspec/pull/3421) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
40
|
-
<!-- latest_stable_release -->
|
41
54
|
|
42
55
|
## [v2.2.112](https://github.com/inspec/inspec/tree/v2.2.112) (2018-09-19)
|
43
56
|
|
@@ -1,354 +1,4 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# author: Dominik Richter
|
1
|
+
# This file has been moved to the v2.0 plugins. This redirect allows for legacy use.
|
2
|
+
# TODO: Remove in inspec 4.0
|
4
3
|
|
5
|
-
require '
|
6
|
-
require 'uri'
|
7
|
-
require 'json'
|
8
|
-
|
9
|
-
require_relative 'api/login'
|
10
|
-
|
11
|
-
module Compliance
|
12
|
-
class ServerConfigurationMissing < StandardError; end
|
13
|
-
|
14
|
-
# API Implementation does not hold any state by itself,
|
15
|
-
# everything will be stored in local Configuration store
|
16
|
-
class API
|
17
|
-
extend Compliance::API::Login
|
18
|
-
|
19
|
-
# return all compliance profiles available for the user
|
20
|
-
# the user is either specified in the options hash or by default
|
21
|
-
# the username of the account is used that is logged in
|
22
|
-
def self.profiles(config, profile_filter = nil) # rubocop:disable PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
|
23
|
-
owner = config['owner'] || config['user']
|
24
|
-
|
25
|
-
# Chef Compliance
|
26
|
-
if is_compliance_server?(config)
|
27
|
-
url = "#{config['server']}/user/compliance"
|
28
|
-
# Chef Automate2
|
29
|
-
elsif is_automate2_server?(config)
|
30
|
-
url = "#{config['server']}/compliance/profiles/search"
|
31
|
-
# Chef Automate
|
32
|
-
elsif is_automate_server?(config)
|
33
|
-
url = "#{config['server']}/profiles/#{owner}"
|
34
|
-
else
|
35
|
-
raise ServerConfigurationMissing
|
36
|
-
end
|
37
|
-
|
38
|
-
headers = get_headers(config)
|
39
|
-
if profile_filter
|
40
|
-
_owner, id, ver = profile_split(profile_filter)
|
41
|
-
else
|
42
|
-
id, ver = nil
|
43
|
-
end
|
44
|
-
|
45
|
-
if is_automate2_server?(config)
|
46
|
-
body = { owner: owner, name: id }.to_json
|
47
|
-
response = Compliance::HTTP.post_with_headers(url, headers, body, config['insecure'])
|
48
|
-
else
|
49
|
-
response = Compliance::HTTP.get(url, headers, config['insecure'])
|
50
|
-
end
|
51
|
-
data = response.body
|
52
|
-
response_code = response.code
|
53
|
-
case response_code
|
54
|
-
when '200'
|
55
|
-
msg = 'success'
|
56
|
-
profiles = JSON.parse(data)
|
57
|
-
# iterate over profiles
|
58
|
-
if is_compliance_server?(config)
|
59
|
-
mapped_profiles = []
|
60
|
-
profiles.values.each { |org|
|
61
|
-
mapped_profiles += org.values
|
62
|
-
}
|
63
|
-
# Chef Automate pre 0.8.0
|
64
|
-
elsif is_automate_server_pre_080?(config)
|
65
|
-
mapped_profiles = profiles.values.flatten
|
66
|
-
elsif is_automate2_server?(config)
|
67
|
-
mapped_profiles = []
|
68
|
-
profiles['profiles'].each { |p|
|
69
|
-
mapped_profiles << p
|
70
|
-
}
|
71
|
-
else
|
72
|
-
mapped_profiles = profiles.map { |e|
|
73
|
-
e['owner_id'] = owner
|
74
|
-
e
|
75
|
-
}
|
76
|
-
end
|
77
|
-
# filter by name and version if they were specified in profile_filter
|
78
|
-
mapped_profiles.select! do |p|
|
79
|
-
(!ver || p['version'] == ver) && (!id || p['name'] == id)
|
80
|
-
end
|
81
|
-
return msg, mapped_profiles
|
82
|
-
when '401'
|
83
|
-
msg = '401 Unauthorized. Please check your token.'
|
84
|
-
return msg, []
|
85
|
-
else
|
86
|
-
msg = "An unexpected error occurred (HTTP #{response_code}): #{response.message}"
|
87
|
-
return msg, []
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# return the server api version
|
92
|
-
# NB this method does not use Compliance::Configuration to allow for using
|
93
|
-
# it before we know the version (e.g. oidc or not)
|
94
|
-
def self.version(config)
|
95
|
-
url = config['server']
|
96
|
-
insecure = config['insecure']
|
97
|
-
|
98
|
-
raise ServerConfigurationMissing if url.nil?
|
99
|
-
|
100
|
-
headers = get_headers(config)
|
101
|
-
response = Compliance::HTTP.get(url+'/version', headers, insecure)
|
102
|
-
return {} if response.code == '404'
|
103
|
-
|
104
|
-
data = response.body
|
105
|
-
return {} if data.nil? || data.empty?
|
106
|
-
|
107
|
-
parsed = JSON.parse(data)
|
108
|
-
return {} unless parsed.key?('version') && !parsed['version'].empty?
|
109
|
-
|
110
|
-
parsed
|
111
|
-
end
|
112
|
-
|
113
|
-
# verifies that a profile exists
|
114
|
-
def self.exist?(config, profile)
|
115
|
-
_msg, profiles = Compliance::API.profiles(config, profile)
|
116
|
-
!profiles.empty?
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.upload(config, owner, profile_name, archive_path)
|
120
|
-
# Chef Compliance
|
121
|
-
if is_compliance_server?(config)
|
122
|
-
url = "#{config['server']}/owners/#{owner}/compliance/#{profile_name}/tar"
|
123
|
-
# Chef Automate pre 0.8.0
|
124
|
-
elsif is_automate_server_pre_080?(config)
|
125
|
-
url = "#{config['server']}/#{owner}"
|
126
|
-
elsif is_automate2_server?(config)
|
127
|
-
url = "#{config['server']}/compliance/profiles?owner=#{owner}"
|
128
|
-
# Chef Automate
|
129
|
-
else
|
130
|
-
url = "#{config['server']}/profiles/#{owner}"
|
131
|
-
end
|
132
|
-
|
133
|
-
headers = get_headers(config)
|
134
|
-
if is_automate2_server?(config)
|
135
|
-
res = Compliance::HTTP.post_multipart_file(url, headers, archive_path, config['insecure'])
|
136
|
-
else
|
137
|
-
res = Compliance::HTTP.post_file(url, headers, archive_path, config['insecure'])
|
138
|
-
end
|
139
|
-
|
140
|
-
[res.is_a?(Net::HTTPSuccess), res.body]
|
141
|
-
end
|
142
|
-
|
143
|
-
# Use username and refresh_token to get an API access token
|
144
|
-
def self.get_token_via_refresh_token(url, refresh_token, insecure)
|
145
|
-
uri = URI.parse("#{url}/login")
|
146
|
-
req = Net::HTTP::Post.new(uri.path)
|
147
|
-
req.body = { token: refresh_token }.to_json
|
148
|
-
access_token = nil
|
149
|
-
response = Compliance::HTTP.send_request(uri, req, insecure)
|
150
|
-
data = response.body
|
151
|
-
if response.code == '200'
|
152
|
-
begin
|
153
|
-
tokendata = JSON.parse(data)
|
154
|
-
access_token = tokendata['access_token']
|
155
|
-
msg = 'Successfully fetched API access token'
|
156
|
-
success = true
|
157
|
-
rescue JSON::ParserError => e
|
158
|
-
success = false
|
159
|
-
msg = e.message
|
160
|
-
end
|
161
|
-
else
|
162
|
-
success = false
|
163
|
-
msg = "Failed to authenticate to #{url} \n\
|
164
|
-
Response code: #{response.code}\n Body: #{response.body}"
|
165
|
-
end
|
166
|
-
|
167
|
-
[success, msg, access_token]
|
168
|
-
end
|
169
|
-
|
170
|
-
# Use username and password to get an API access token
|
171
|
-
def self.get_token_via_password(url, username, password, insecure)
|
172
|
-
uri = URI.parse("#{url}/login")
|
173
|
-
req = Net::HTTP::Post.new(uri.path)
|
174
|
-
req.body = { userid: username, password: password }.to_json
|
175
|
-
access_token = nil
|
176
|
-
response = Compliance::HTTP.send_request(uri, req, insecure)
|
177
|
-
data = response.body
|
178
|
-
if response.code == '200'
|
179
|
-
access_token = data
|
180
|
-
msg = 'Successfully fetched an API access token valid for 12 hours'
|
181
|
-
success = true
|
182
|
-
else
|
183
|
-
success = false
|
184
|
-
msg = "Failed to authenticate to #{url} \n\
|
185
|
-
Response code: #{response.code}\n Body: #{response.body}"
|
186
|
-
end
|
187
|
-
|
188
|
-
[success, msg, access_token]
|
189
|
-
end
|
190
|
-
|
191
|
-
def self.get_headers(config)
|
192
|
-
token = get_token(config)
|
193
|
-
if is_automate_server?(config) || is_automate2_server?(config)
|
194
|
-
headers = { 'chef-delivery-enterprise' => config['automate']['ent'] }
|
195
|
-
if config['automate']['token_type'] == 'dctoken'
|
196
|
-
headers['x-data-collector-token'] = token
|
197
|
-
else
|
198
|
-
headers['chef-delivery-user'] = config['user']
|
199
|
-
headers['chef-delivery-token'] = token
|
200
|
-
end
|
201
|
-
else
|
202
|
-
headers = { 'Authorization' => "Bearer #{token}" }
|
203
|
-
end
|
204
|
-
headers
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.get_token(config)
|
208
|
-
return config['token'] unless config['refresh_token']
|
209
|
-
_success, _msg, token = get_token_via_refresh_token(config['server'], config['refresh_token'], config['insecure'])
|
210
|
-
token
|
211
|
-
end
|
212
|
-
|
213
|
-
def self.target_url(config, profile)
|
214
|
-
owner, id, ver = profile_split(profile)
|
215
|
-
|
216
|
-
return "#{config['server']}/compliance/profiles/tar" if is_automate2_server?(config)
|
217
|
-
return "#{config['server']}/owners/#{owner}/compliance/#{id}/tar" unless is_automate_server?(config)
|
218
|
-
|
219
|
-
if ver.nil?
|
220
|
-
"#{config['server']}/profiles/#{owner}/#{id}/tar"
|
221
|
-
else
|
222
|
-
"#{config['server']}/profiles/#{owner}/#{id}/version/#{ver}/tar"
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def self.profile_split(profile)
|
227
|
-
owner, id = profile.split('/')
|
228
|
-
id, version = id.split('#')
|
229
|
-
[owner, id, version]
|
230
|
-
end
|
231
|
-
|
232
|
-
# returns a parsed url for `admin/profile` or `compliance://admin/profile`
|
233
|
-
def self.sanitize_profile_name(profile)
|
234
|
-
if URI(profile).scheme == 'compliance'
|
235
|
-
uri = URI(profile)
|
236
|
-
else
|
237
|
-
uri = URI("compliance://#{profile}")
|
238
|
-
end
|
239
|
-
uri.to_s.sub(%r{^compliance:\/\/}, '')
|
240
|
-
end
|
241
|
-
|
242
|
-
def self.is_compliance_server?(config)
|
243
|
-
config['server_type'] == 'compliance'
|
244
|
-
end
|
245
|
-
|
246
|
-
def self.is_automate_server_pre_080?(config)
|
247
|
-
# Automate versions before 0.8.x do not have a valid version in the config
|
248
|
-
return false unless config['server_type'] == 'automate'
|
249
|
-
server_version_from_config(config).nil?
|
250
|
-
end
|
251
|
-
|
252
|
-
def self.is_automate_server_080_and_later?(config)
|
253
|
-
# Automate versions 0.8.x and later will have a "version" key in the config
|
254
|
-
# that is properly parsed out via server_version_from_config below
|
255
|
-
return false unless config['server_type'] == 'automate'
|
256
|
-
!server_version_from_config(config).nil?
|
257
|
-
end
|
258
|
-
|
259
|
-
def self.is_automate2_server?(config)
|
260
|
-
config['server_type'] == 'automate2'
|
261
|
-
end
|
262
|
-
|
263
|
-
def self.is_automate_server?(config)
|
264
|
-
config['server_type'] == 'automate'
|
265
|
-
end
|
266
|
-
|
267
|
-
def self.server_version_from_config(config)
|
268
|
-
# Automate versions 0.8.x and later will have a "version" key in the config
|
269
|
-
# that looks like: "version":{"api":"compliance","version":"0.8.24"}
|
270
|
-
return nil unless config.key?('version')
|
271
|
-
return nil unless config['version'].is_a?(Hash)
|
272
|
-
config['version']['version']
|
273
|
-
end
|
274
|
-
|
275
|
-
def self.determine_server_type(url, insecure)
|
276
|
-
if target_is_automate2_server?(url, insecure)
|
277
|
-
:automate2
|
278
|
-
elsif target_is_automate_server?(url, insecure)
|
279
|
-
:automate
|
280
|
-
elsif target_is_compliance_server?(url, insecure)
|
281
|
-
:compliance
|
282
|
-
else
|
283
|
-
Inspec::Log.debug('Could not determine server type using known endpoints')
|
284
|
-
nil
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
def self.target_is_automate2_server?(url, insecure)
|
289
|
-
automate_endpoint = '/dex/auth'
|
290
|
-
response = Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
|
291
|
-
if response.code == '400'
|
292
|
-
Inspec::Log.debug(
|
293
|
-
"Received 400 from #{url}#{automate_endpoint} - " \
|
294
|
-
'assuming target is a Chef Automate2 instance',
|
295
|
-
)
|
296
|
-
true
|
297
|
-
else
|
298
|
-
false
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
def self.target_is_automate_server?(url, insecure)
|
303
|
-
automate_endpoint = '/compliance/version'
|
304
|
-
response = Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
|
305
|
-
case response.code
|
306
|
-
when '401'
|
307
|
-
Inspec::Log.debug(
|
308
|
-
"Received 401 from #{url}#{automate_endpoint} - " \
|
309
|
-
'assuming target is a Chef Automate instance',
|
310
|
-
)
|
311
|
-
true
|
312
|
-
when '200'
|
313
|
-
# Chef Automate currently returns 401 for `/compliance/version` but some
|
314
|
-
# versions of OpsWorks Chef Automate return 200 and a Chef Manage page
|
315
|
-
# when unauthenticated requests are received.
|
316
|
-
if response.body.include?('Are You Looking For the Chef Server?')
|
317
|
-
Inspec::Log.debug(
|
318
|
-
"Received 200 from #{url}#{automate_endpoint} - " \
|
319
|
-
'assuming target is an OpsWorks Chef Automate instance',
|
320
|
-
)
|
321
|
-
true
|
322
|
-
else
|
323
|
-
Inspec::Log.debug(
|
324
|
-
"Received 200 from #{url}#{automate_endpoint} " \
|
325
|
-
'but did not receive the Chef Manage page - ' \
|
326
|
-
'assuming target is not a Chef Automate instance',
|
327
|
-
)
|
328
|
-
false
|
329
|
-
end
|
330
|
-
else
|
331
|
-
Inspec::Log.debug(
|
332
|
-
"Received unexpected status code #{response.code} " \
|
333
|
-
"from #{url}#{automate_endpoint} - " \
|
334
|
-
'assuming target is not a Chef Automate instance',
|
335
|
-
)
|
336
|
-
false
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
def self.target_is_compliance_server?(url, insecure)
|
341
|
-
# All versions of Chef Compliance return 200 for `/api/version`
|
342
|
-
compliance_endpoint = '/api/version'
|
343
|
-
|
344
|
-
response = Compliance::HTTP.get(url + compliance_endpoint, nil, insecure)
|
345
|
-
return false unless response.code == '200'
|
346
|
-
|
347
|
-
Inspec::Log.debug(
|
348
|
-
"Received 200 from #{url}#{compliance_endpoint} - " \
|
349
|
-
'assuming target is a Compliance server',
|
350
|
-
)
|
351
|
-
true
|
352
|
-
end
|
353
|
-
end
|
354
|
-
end
|
4
|
+
require 'plugins/inspec-compliance/lib/inspec-compliance/api'
|
@@ -1,103 +1,4 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# author: Dominik Richter
|
1
|
+
# This file has been moved to the v2.0 plugins. This redirect allows for legacy use.
|
2
|
+
# TODO: Remove in inspec 4.0
|
4
3
|
|
5
|
-
|
6
|
-
# stores configuration on local filesystem
|
7
|
-
class Configuration
|
8
|
-
def initialize
|
9
|
-
@config_path = File.join(Dir.home, '.inspec', 'compliance')
|
10
|
-
# ensure the directory is available
|
11
|
-
unless File.directory?(@config_path)
|
12
|
-
FileUtils.mkdir_p(@config_path)
|
13
|
-
end
|
14
|
-
# set config file path
|
15
|
-
@config_file = File.join(@config_path, '/config.json')
|
16
|
-
@config = {}
|
17
|
-
|
18
|
-
# load the data
|
19
|
-
get
|
20
|
-
end
|
21
|
-
|
22
|
-
# direct access to config
|
23
|
-
def [](key)
|
24
|
-
@config[key]
|
25
|
-
end
|
26
|
-
|
27
|
-
def []=(key, value)
|
28
|
-
@config[key] = value
|
29
|
-
end
|
30
|
-
|
31
|
-
def key?(key)
|
32
|
-
@config.key?(key)
|
33
|
-
end
|
34
|
-
|
35
|
-
def clean
|
36
|
-
@config = {}
|
37
|
-
end
|
38
|
-
|
39
|
-
# return the json data
|
40
|
-
def get
|
41
|
-
if File.exist?(@config_file)
|
42
|
-
file = File.read(@config_file)
|
43
|
-
@config = JSON.parse(file)
|
44
|
-
end
|
45
|
-
@config
|
46
|
-
end
|
47
|
-
|
48
|
-
# stores a hash to json
|
49
|
-
def store
|
50
|
-
File.open(@config_file, 'w') do |f|
|
51
|
-
f.chmod(0600)
|
52
|
-
f.write(@config.to_json)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# deletes data
|
57
|
-
def destroy
|
58
|
-
if File.exist?(@config_file)
|
59
|
-
File.delete(@config_file)
|
60
|
-
else
|
61
|
-
true
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# return if the (stored) api version does not support a certain feature
|
66
|
-
def supported?(feature)
|
67
|
-
sup = version_with_support(feature)
|
68
|
-
|
69
|
-
# we do not know the version, therefore we do not know if its possible to use the feature
|
70
|
-
return if self['version'].nil? || self['version']['version'].nil?
|
71
|
-
|
72
|
-
if sup.is_a?(Array)
|
73
|
-
Gem::Version.new(self['version']['version']) >= sup[0] &&
|
74
|
-
Gem::Version.new(self['version']['version']) < sup[1]
|
75
|
-
else
|
76
|
-
Gem::Version.new(self['version']['version']) >= sup
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# exit 1 if the version of compliance that we're working with doesn't support odic
|
81
|
-
def legacy_check!(feature)
|
82
|
-
return if supported?(feature)
|
83
|
-
|
84
|
-
puts "This feature (#{feature}) is not available for legacy installations."
|
85
|
-
puts 'Please upgrade to a recent version of Chef Compliance.'
|
86
|
-
exit 1
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
# for a feature, returns either:
|
92
|
-
# - a version v0: v supports v0 iff v0 <= v
|
93
|
-
# - an array [v0, v1] of two versions: v supports [v0, v1] iff v0 <= v < v1
|
94
|
-
def version_with_support(feature)
|
95
|
-
case feature.to_sym
|
96
|
-
when :oidc
|
97
|
-
Gem::Version.new('0.16.19')
|
98
|
-
else
|
99
|
-
Gem::Version.new('0.0.0')
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
4
|
+
require 'plugins/inspec-compliance/lib/inspec-compliance/configuration'
|