inspec-core 4.37.8 → 4.37.30
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 +12 -0
- data/etc/deprecations.json +5 -0
- data/lib/inspec/base_cli.rb +2 -2
- data/lib/inspec/cli.rb +1 -1
- data/lib/inspec/fetcher/local.rb +2 -1
- data/lib/inspec/fetcher/mock.rb +5 -3
- data/lib/inspec/resources/file.rb +4 -5
- data/lib/inspec/resources/mysql_session.rb +12 -2
- data/lib/inspec/resources/port.rb +9 -3
- data/lib/inspec/resources/postgres_session.rb +10 -1
- data/lib/inspec/resources/windows_feature.rb +1 -1
- data/lib/inspec/resources/zfs_dataset.rb +7 -3
- data/lib/inspec/resources/zfs_pool.rb +7 -3
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +19 -179
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +3 -140
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +2 -3
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +5 -23
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +44 -34
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +1 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +6 -6
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Rakefile +8 -8
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +12 -12
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/{inspec-plugin-template.rb → inspec-plugin-template.erb} +1 -1
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/{cli_command.rb → cli_command.erb} +8 -8
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/{plugin.rb → plugin.erb} +15 -15
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/{reporter.rb → reporter.erb} +0 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/{version.rb → version.erb} +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c945fbd0ce14959ea0286c4bfc5928d547bd7c48dd80828a955585493383476
|
|
4
|
+
data.tar.gz: c9f3f58a8b68ec6039ef432421150690870ffce295691ad2e9f1b72e31b4802b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b75d54fae752d292467fe333a8081c739ae24c2570256b26a6c104893e29a234182018e00d555a31e02cd19f189c7561489b1c2c13b03c4eacca04562b3a3343
|
|
7
|
+
data.tar.gz: bc67f78180eb7516f28dfae3fc0bcf8a0bb523b05ff3e5aa32df156279797d9d6f3801c00ff347159fc7cdf399d1c6a00cd29a4a506611c53c044eaac5a938dc
|
data/Gemfile
CHANGED
|
@@ -20,11 +20,22 @@ end
|
|
|
20
20
|
# but our runtime dep is still 3.9+
|
|
21
21
|
gem "rspec", ">= 3.10"
|
|
22
22
|
|
|
23
|
+
def probably_x86?
|
|
24
|
+
# We don't currently build on ARM windows, so assume x86 there
|
|
25
|
+
return true if RUBY_PLATFORM =~ /windows|mswin|msys|mingw|cygwin/
|
|
26
|
+
|
|
27
|
+
# Otherwise rely on uname -m
|
|
28
|
+
`uname -m`.match?(/^(x86_64|i\d86)/)
|
|
29
|
+
end
|
|
30
|
+
|
|
23
31
|
group :omnibus do
|
|
24
32
|
gem "rb-readline"
|
|
25
33
|
gem "appbundler"
|
|
26
34
|
gem "ed25519" # ed25519 ssh key support done here as its a native gem we can't put in the gemspec
|
|
27
35
|
gem "bcrypt_pbkdf" # ed25519 ssh key support done here as its a native gem we can't put in the gemspec
|
|
36
|
+
if probably_x86?
|
|
37
|
+
gem "x25519" # ed25519 KEX module, not supported on ARM
|
|
38
|
+
end
|
|
28
39
|
end
|
|
29
40
|
|
|
30
41
|
group :test do
|
|
@@ -55,6 +66,7 @@ end
|
|
|
55
66
|
if Gem.ruby_version >= Gem::Version.new("2.7.0")
|
|
56
67
|
group :kitchen do
|
|
57
68
|
gem "berkshelf"
|
|
69
|
+
gem "chef", ">= 16.0" # Required to allow net-ssh > 6
|
|
58
70
|
gem "test-kitchen", ">= 2.8"
|
|
59
71
|
gem "kitchen-inspec", ">= 2.0"
|
|
60
72
|
gem "kitchen-dokken", ">= 2.11"
|
data/etc/deprecations.json
CHANGED
|
@@ -120,6 +120,11 @@
|
|
|
120
120
|
"object_classes": {
|
|
121
121
|
"action": "warn",
|
|
122
122
|
"suffix": "These classes will be removed in InSpec 5.0."
|
|
123
|
+
},
|
|
124
|
+
"cli_option_hook":{
|
|
125
|
+
"action": "warn",
|
|
126
|
+
"prefix": "The --hook option is being replaced by the --activator option.",
|
|
127
|
+
"suffix": "This options will be removed in InSpec 4.0."
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
130
|
}
|
data/lib/inspec/base_cli.rb
CHANGED
|
@@ -181,7 +181,7 @@ module Inspec
|
|
|
181
181
|
puts " Patents: chef.io/patents\n\n"
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
def self.format_platform_info(params: {}, indent: 0, color: 39)
|
|
184
|
+
def self.format_platform_info(params: {}, indent: 0, color: 39, enable_color: true)
|
|
185
185
|
str = ""
|
|
186
186
|
params.each do |item, info|
|
|
187
187
|
data = info
|
|
@@ -192,7 +192,7 @@ module Inspec
|
|
|
192
192
|
# Do not output fields of data is missing ('unknown' is fine)
|
|
193
193
|
next if data.nil?
|
|
194
194
|
|
|
195
|
-
data = "\e[1m\e[#{color}m#{data}\e[0m"
|
|
195
|
+
data = "\e[1m\e[#{color}m#{data}\e[0m" if enable_color
|
|
196
196
|
str << format("#{" " * indent}%-10s %s\n", item.to_s.capitalize + ":", data)
|
|
197
197
|
end
|
|
198
198
|
str
|
data/lib/inspec/cli.rb
CHANGED
|
@@ -305,7 +305,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
|
305
305
|
puts res.to_json
|
|
306
306
|
else
|
|
307
307
|
ui.headline("Platform Details")
|
|
308
|
-
ui.plain Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36)
|
|
308
|
+
ui.plain Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36, enable_color: ui.color?)
|
|
309
309
|
end
|
|
310
310
|
rescue ArgumentError, RuntimeError, Train::UserError => e
|
|
311
311
|
$stderr.puts e.message
|
data/lib/inspec/fetcher/local.rb
CHANGED
|
@@ -3,7 +3,8 @@ require "openssl" unless defined?(OpenSSL)
|
|
|
3
3
|
module Inspec::Fetcher
|
|
4
4
|
class Local < Inspec.fetcher(1)
|
|
5
5
|
name "local"
|
|
6
|
-
priority
|
|
6
|
+
priority 1
|
|
7
|
+
# Priority is used for setting precedence of fetchers. And registry plugin(v1) decides which fetcher to use for loading profiles by using this priority
|
|
7
8
|
|
|
8
9
|
def self.resolve(target)
|
|
9
10
|
if target.is_a?(String)
|
data/lib/inspec/fetcher/mock.rb
CHANGED
|
@@ -6,9 +6,11 @@ module Inspec::Fetcher
|
|
|
6
6
|
priority 0
|
|
7
7
|
|
|
8
8
|
def self.resolve(target)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if (target.is_a? Hash) && ((target.keys & %i{cwd path backend}).empty?)
|
|
10
|
+
new(target)
|
|
11
|
+
else
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def initialize(data)
|
|
@@ -136,10 +136,10 @@ module Inspec::Resources
|
|
|
136
136
|
alias sticky? sticky
|
|
137
137
|
|
|
138
138
|
def more_permissive_than?(max_mode = nil)
|
|
139
|
-
|
|
140
|
-
raise ArgumentError, "You must
|
|
141
|
-
raise ArgumentError, "You must
|
|
142
|
-
raise ArgumentError, "The value of the `maximum permission target` should be a valid file mode in 4-
|
|
139
|
+
return nil unless exist?
|
|
140
|
+
raise ArgumentError, "You must provide a value for the `maximum allowable permission` for the file." if max_mode.nil?
|
|
141
|
+
raise ArgumentError, "You must provide the `maximum permission target` as a `String`, you provided: " + max_mode.class.to_s unless max_mode.is_a?(String)
|
|
142
|
+
raise ArgumentError, "The value of the `maximum permission target` should be a valid file mode in 4-digit octal format: for example, `0644` or `0777`" unless /(0)?([0-7])([0-7])([0-7])/.match?(max_mode)
|
|
143
143
|
|
|
144
144
|
# Using the files mode and a few bit-wise calculations we can ensure a
|
|
145
145
|
# file is no more permisive than desired.
|
|
@@ -160,7 +160,6 @@ module Inspec::Resources
|
|
|
160
160
|
|
|
161
161
|
max_mode = max_mode.to_i(8)
|
|
162
162
|
inv_mode = 0777 ^ max_mode
|
|
163
|
-
|
|
164
163
|
inv_mode & file.mode != 0
|
|
165
164
|
end
|
|
166
165
|
|
|
@@ -44,10 +44,14 @@ module Inspec::Resources
|
|
|
44
44
|
@port = port
|
|
45
45
|
@socket = socket
|
|
46
46
|
init_fallback if user.nil? || pass.nil?
|
|
47
|
-
|
|
47
|
+
raise Inspec::Exceptions::ResourceFailed, "Can't run MySQL SQL checks without authentication." if @user.nil? || @pass.nil?
|
|
48
|
+
|
|
49
|
+
test_connection
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
def query(q, db = "")
|
|
53
|
+
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
|
|
54
|
+
|
|
51
55
|
mysql_cmd = create_mysql_cmd(q, db)
|
|
52
56
|
cmd = if !@pass.nil?
|
|
53
57
|
inspec.command(mysql_cmd, redact_regex: /(mysql -u\w+ -p).+(\s-(h|S).*)/)
|
|
@@ -56,7 +60,7 @@ module Inspec::Resources
|
|
|
56
60
|
end
|
|
57
61
|
out = cmd.stdout + "\n" + cmd.stderr
|
|
58
62
|
if cmd.exit_status != 0 || out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error:.*/
|
|
59
|
-
|
|
63
|
+
raise Inspec::Exceptions::ResourceFailed, "MySQL query with errors: #{out}"
|
|
60
64
|
else
|
|
61
65
|
Lines.new(cmd.stdout.strip, "MySQL query: #{q}", cmd.exit_status)
|
|
62
66
|
end
|
|
@@ -68,6 +72,12 @@ module Inspec::Resources
|
|
|
68
72
|
|
|
69
73
|
private
|
|
70
74
|
|
|
75
|
+
# Querying on the database to make sure conneciton can be established. If not this will set the resource exception
|
|
76
|
+
# message which we raise before querying on the database using mysql_session object.
|
|
77
|
+
def test_connection
|
|
78
|
+
query("select now()")
|
|
79
|
+
end
|
|
80
|
+
|
|
71
81
|
def escape_string(query)
|
|
72
82
|
Shellwords.escape(query)
|
|
73
83
|
end
|
|
@@ -54,7 +54,7 @@ module Inspec::Resources
|
|
|
54
54
|
def port_manager_for_os
|
|
55
55
|
os = inspec.os
|
|
56
56
|
if os.linux?
|
|
57
|
-
LinuxPorts.new(inspec)
|
|
57
|
+
LinuxPorts.new(inspec, @port)
|
|
58
58
|
elsif os.aix?
|
|
59
59
|
# AIX: see http://www.ibm.com/developerworks/aix/library/au-lsof.html#resources
|
|
60
60
|
# and https://www-01.ibm.com/marketing/iwm/iwm/web/reg/pick.do?source=aixbp
|
|
@@ -102,8 +102,9 @@ module Inspec::Resources
|
|
|
102
102
|
# }]
|
|
103
103
|
class PortsInfo
|
|
104
104
|
attr_reader :inspec
|
|
105
|
-
def initialize(inspec)
|
|
105
|
+
def initialize(inspec, port = nil)
|
|
106
106
|
@inspec = inspec
|
|
107
|
+
@port = port
|
|
107
108
|
end
|
|
108
109
|
end
|
|
109
110
|
|
|
@@ -394,7 +395,12 @@ module Inspec::Resources
|
|
|
394
395
|
def ports_via_ss
|
|
395
396
|
return nil unless inspec.command("ss").exist?
|
|
396
397
|
|
|
397
|
-
|
|
398
|
+
if @port.nil?
|
|
399
|
+
cmd = inspec.command("ss -tulpen")
|
|
400
|
+
else
|
|
401
|
+
cmd = inspec.command("ss -tulpen '( dport = #{@port} or sport = #{@port} )'")
|
|
402
|
+
end
|
|
403
|
+
|
|
398
404
|
return nil unless cmd.exit_status.to_i == 0
|
|
399
405
|
|
|
400
406
|
ports = []
|
|
@@ -45,14 +45,19 @@ module Inspec::Resources
|
|
|
45
45
|
@pass = pass
|
|
46
46
|
@host = host || "localhost"
|
|
47
47
|
@port = port || 5432
|
|
48
|
+
raise Inspec::Exceptions::ResourceFailed, "Can't run PostgreSQL SQL checks without authentication." if @user.nil? || @pass.nil?
|
|
49
|
+
|
|
50
|
+
test_connection
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def query(query, db = [])
|
|
54
|
+
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
|
|
55
|
+
|
|
51
56
|
psql_cmd = create_psql_cmd(query, db)
|
|
52
57
|
cmd = inspec.command(psql_cmd, redact_regex: /(PGPASSWORD=').+(' psql .*)/)
|
|
53
58
|
out = cmd.stdout + "\n" + cmd.stderr
|
|
54
59
|
if cmd.exit_status != 0 || out =~ /could not connect to .*/ || out.downcase =~ /^error:.*/
|
|
55
|
-
|
|
60
|
+
raise Inspec::Exceptions::ResourceFailed, "PostgreSQL query with errors: #{out}"
|
|
56
61
|
else
|
|
57
62
|
Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}")
|
|
58
63
|
end
|
|
@@ -60,6 +65,10 @@ module Inspec::Resources
|
|
|
60
65
|
|
|
61
66
|
private
|
|
62
67
|
|
|
68
|
+
def test_connection
|
|
69
|
+
query("select now()")
|
|
70
|
+
end
|
|
71
|
+
|
|
63
72
|
def escaped_query(query)
|
|
64
73
|
Shellwords.escape(query)
|
|
65
74
|
end
|
|
@@ -83,7 +83,7 @@ module Inspec::Resources
|
|
|
83
83
|
feature_info = {
|
|
84
84
|
name: result.match(feature_name_regex).captures[0].chomp,
|
|
85
85
|
description: result.match(description_regex).captures[0].chomp,
|
|
86
|
-
installed: result.match(state_regex).captures[0].chomp ==
|
|
86
|
+
installed: result.match(state_regex).captures[0].chomp == "Enabled",
|
|
87
87
|
}
|
|
88
88
|
end
|
|
89
89
|
|
|
@@ -16,16 +16,20 @@ module Inspec::Resources
|
|
|
16
16
|
EXAMPLE
|
|
17
17
|
|
|
18
18
|
def initialize(zfs_dataset)
|
|
19
|
-
return skip_resource "The `zfs_dataset` resource is not supported on your OS yet." unless inspec.os.bsd?
|
|
19
|
+
return skip_resource "The `zfs_dataset` resource is not supported on your OS yet." unless inspec.os.bsd? || inspec.os.linux?
|
|
20
20
|
|
|
21
21
|
@zfs_dataset = zfs_dataset
|
|
22
|
+
find_zfs = inspec.command("which zfs")
|
|
23
|
+
@zfs_cmd = find_zfs.stdout.strip
|
|
24
|
+
|
|
25
|
+
return skip_resource "zfs is not installed" if find_zfs.exit_status != 0
|
|
22
26
|
|
|
23
27
|
@params = gather
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
# method called by 'it { should exist }'
|
|
27
31
|
def exists?
|
|
28
|
-
inspec.command("
|
|
32
|
+
inspec.command("#{@zfs_cmd} get -Hp all #{@zfs_dataset}").exit_status == 0
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def mounted?
|
|
@@ -39,7 +43,7 @@ module Inspec::Resources
|
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
def gather
|
|
42
|
-
cmd = inspec.command("
|
|
46
|
+
cmd = inspec.command("#{@zfs_cmd} get -Hp all #{@zfs_dataset}")
|
|
43
47
|
return nil if cmd.exit_status.to_i != 0
|
|
44
48
|
|
|
45
49
|
# parse data
|
|
@@ -15,16 +15,20 @@ module Inspec::Resources
|
|
|
15
15
|
EXAMPLE
|
|
16
16
|
|
|
17
17
|
def initialize(zfs_pool)
|
|
18
|
-
return skip_resource "The `zfs_pool` resource is not supported on your OS yet." unless inspec.os.bsd?
|
|
18
|
+
return skip_resource "The `zfs_pool` resource is not supported on your OS yet." unless inspec.os.bsd? || inspec.os.linux?
|
|
19
19
|
|
|
20
20
|
@zfs_pool = zfs_pool
|
|
21
|
+
find_zpool = inspec.command("which zpool")
|
|
22
|
+
@zpool_cmd = find_zpool.stdout.strip
|
|
23
|
+
|
|
24
|
+
return skip_resource "zfs is not installed" if find_zpool.exit_status != 0
|
|
21
25
|
|
|
22
26
|
@params = gather
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
# method called by 'it { should exist }'
|
|
26
30
|
def exists?
|
|
27
|
-
inspec.command("
|
|
31
|
+
inspec.command("#{@zpool_cmd} get -Hp all #{@zfs_pool}").exit_status == 0
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def to_s
|
|
@@ -32,7 +36,7 @@ module Inspec::Resources
|
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def gather
|
|
35
|
-
cmd = inspec.command("
|
|
39
|
+
cmd = inspec.command("#{@zpool_cmd} get -Hp all #{@zfs_pool}")
|
|
36
40
|
return nil if cmd.exit_status.to_i != 0
|
|
37
41
|
|
|
38
42
|
# parse data
|
data/lib/inspec/version.rb
CHANGED
|
@@ -24,16 +24,8 @@ module InspecPlugins
|
|
|
24
24
|
# the username of the account is used that is logged in
|
|
25
25
|
def self.profiles(config, profile_filter = nil) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
|
|
26
26
|
owner = config["owner"] || config["user"]
|
|
27
|
-
|
|
28
|
-
# Chef Compliance
|
|
29
|
-
if is_compliance_server?(config)
|
|
30
|
-
url = "#{config["server"]}/user/compliance"
|
|
31
|
-
# Chef Automate2
|
|
32
|
-
elsif is_automate2_server?(config)
|
|
27
|
+
if is_automate2_server?(config)
|
|
33
28
|
url = "#{config["server"]}/compliance/profiles/search"
|
|
34
|
-
# Chef Automate
|
|
35
|
-
elsif is_automate_server?(config)
|
|
36
|
-
url = "#{config["server"]}/profiles/#{owner}"
|
|
37
29
|
else
|
|
38
30
|
raise ServerConfigurationMissing
|
|
39
31
|
end
|
|
@@ -45,12 +37,9 @@ module InspecPlugins
|
|
|
45
37
|
id, ver = nil
|
|
46
38
|
end
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
else
|
|
52
|
-
response = InspecPlugins::Compliance::HTTP.get(url, headers, config["insecure"])
|
|
53
|
-
end
|
|
40
|
+
body = { owner: owner, name: id }.to_json
|
|
41
|
+
response = InspecPlugins::Compliance::HTTP.post_with_headers(url, headers, body, config["insecure"])
|
|
42
|
+
|
|
54
43
|
data = response.body
|
|
55
44
|
response_code = response.code
|
|
56
45
|
case response_code
|
|
@@ -58,25 +47,12 @@ module InspecPlugins
|
|
|
58
47
|
msg = "success"
|
|
59
48
|
profiles = JSON.parse(data)
|
|
60
49
|
# iterate over profiles
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
# Chef Automate pre 0.8.0
|
|
67
|
-
elsif is_automate_server_pre_080?(config)
|
|
68
|
-
mapped_profiles = profiles.values.flatten
|
|
69
|
-
elsif is_automate2_server?(config)
|
|
70
|
-
mapped_profiles = []
|
|
71
|
-
profiles["profiles"].each do |p|
|
|
72
|
-
mapped_profiles << p
|
|
73
|
-
end
|
|
74
|
-
else
|
|
75
|
-
mapped_profiles = profiles.map do |e|
|
|
76
|
-
e["owner_id"] = owner
|
|
77
|
-
e
|
|
78
|
-
end
|
|
50
|
+
|
|
51
|
+
mapped_profiles = []
|
|
52
|
+
profiles["profiles"].each do |p|
|
|
53
|
+
mapped_profiles << p
|
|
79
54
|
end
|
|
55
|
+
|
|
80
56
|
# filter by name and version if they were specified in profile_filter
|
|
81
57
|
mapped_profiles.select! do |p|
|
|
82
58
|
(!ver || p["version"] == ver) && (!id || p["name"] == id)
|
|
@@ -120,26 +96,9 @@ module InspecPlugins
|
|
|
120
96
|
end
|
|
121
97
|
|
|
122
98
|
def self.upload(config, owner, profile_name, archive_path)
|
|
123
|
-
|
|
124
|
-
if is_compliance_server?(config)
|
|
125
|
-
url = "#{config["server"]}/owners/#{owner}/compliance/#{profile_name}/tar"
|
|
126
|
-
# Chef Automate pre 0.8.0
|
|
127
|
-
elsif is_automate_server_pre_080?(config)
|
|
128
|
-
url = "#{config["server"]}/#{owner}"
|
|
129
|
-
elsif is_automate2_server?(config)
|
|
130
|
-
url = "#{config["server"]}/compliance/profiles?owner=#{owner}"
|
|
131
|
-
# Chef Automate
|
|
132
|
-
else
|
|
133
|
-
url = "#{config["server"]}/profiles/#{owner}"
|
|
134
|
-
end
|
|
135
|
-
|
|
99
|
+
url = "#{config["server"]}/compliance/profiles?owner=#{owner}"
|
|
136
100
|
headers = get_headers(config)
|
|
137
|
-
|
|
138
|
-
res = InspecPlugins::Compliance::HTTP.post_multipart_file(url, headers, archive_path, config["insecure"])
|
|
139
|
-
else
|
|
140
|
-
res = InspecPlugins::Compliance::HTTP.post_file(url, headers, archive_path, config["insecure"])
|
|
141
|
-
end
|
|
142
|
-
|
|
101
|
+
res = InspecPlugins::Compliance::HTTP.post_multipart_file(url, headers, archive_path, config["insecure"])
|
|
143
102
|
[res.is_a?(Net::HTTPSuccess), res.body]
|
|
144
103
|
end
|
|
145
104
|
|
|
@@ -210,16 +169,12 @@ module InspecPlugins
|
|
|
210
169
|
|
|
211
170
|
def self.get_headers(config)
|
|
212
171
|
token = get_token(config)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
headers["x-data-collector-token"] = token
|
|
217
|
-
else
|
|
218
|
-
headers["chef-delivery-user"] = config["user"]
|
|
219
|
-
headers["chef-delivery-token"] = token
|
|
220
|
-
end
|
|
172
|
+
headers = { "chef-delivery-enterprise" => config["automate"]["ent"] }
|
|
173
|
+
if config["automate"]["token_type"] == "dctoken"
|
|
174
|
+
headers["x-data-collector-token"] = token
|
|
221
175
|
else
|
|
222
|
-
headers
|
|
176
|
+
headers["chef-delivery-user"] = config["user"]
|
|
177
|
+
headers["chef-delivery-token"] = token
|
|
223
178
|
end
|
|
224
179
|
headers
|
|
225
180
|
end
|
|
@@ -232,16 +187,7 @@ module InspecPlugins
|
|
|
232
187
|
end
|
|
233
188
|
|
|
234
189
|
def self.target_url(config, profile)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return "#{config["server"]}/compliance/profiles/tar" if is_automate2_server?(config)
|
|
238
|
-
return "#{config["server"]}/owners/#{owner}/compliance/#{id}/tar" unless is_automate_server?(config)
|
|
239
|
-
|
|
240
|
-
if ver.nil?
|
|
241
|
-
"#{config["server"]}/profiles/#{owner}/#{id}/tar"
|
|
242
|
-
else
|
|
243
|
-
"#{config["server"]}/profiles/#{owner}/#{id}/version/#{ver}/tar"
|
|
244
|
-
end
|
|
190
|
+
"#{config["server"]}/compliance/profiles/tar"
|
|
245
191
|
end
|
|
246
192
|
|
|
247
193
|
def self.profile_split(profile)
|
|
@@ -260,33 +206,6 @@ module InspecPlugins
|
|
|
260
206
|
uri.to_s.sub(%r{^compliance:\/\/}, "")
|
|
261
207
|
end
|
|
262
208
|
|
|
263
|
-
def self.is_compliance_server?(config)
|
|
264
|
-
config["server_type"] == "compliance"
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def self.is_automate_server_pre_080?(config)
|
|
268
|
-
# Automate versions before 0.8.x do not have a valid version in the config
|
|
269
|
-
return false unless config["server_type"] == "automate"
|
|
270
|
-
|
|
271
|
-
server_version_from_config(config).nil?
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def self.is_automate_server_080_and_later?(config)
|
|
275
|
-
# Automate versions 0.8.x and later will have a "version" key in the config
|
|
276
|
-
# that is properly parsed out via server_version_from_config below
|
|
277
|
-
return false unless config["server_type"] == "automate"
|
|
278
|
-
|
|
279
|
-
!server_version_from_config(config).nil?
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
def self.is_automate2_server?(config)
|
|
283
|
-
config["server_type"] == "automate2"
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
def self.is_automate_server?(config)
|
|
287
|
-
config["server_type"] == "automate"
|
|
288
|
-
end
|
|
289
|
-
|
|
290
209
|
def self.server_version_from_config(config)
|
|
291
210
|
# Automate versions 0.8.x and later will have a "version" key in the config
|
|
292
211
|
# that looks like: "version":{"api":"compliance","version":"0.8.24"}
|
|
@@ -296,87 +215,8 @@ module InspecPlugins
|
|
|
296
215
|
config["version"]["version"]
|
|
297
216
|
end
|
|
298
217
|
|
|
299
|
-
def self.
|
|
300
|
-
|
|
301
|
-
:automate2
|
|
302
|
-
elsif target_is_automate_server?(url, insecure)
|
|
303
|
-
:automate
|
|
304
|
-
elsif target_is_compliance_server?(url, insecure)
|
|
305
|
-
:compliance
|
|
306
|
-
else
|
|
307
|
-
Inspec::Log.debug("Could not determine server type using known endpoints")
|
|
308
|
-
nil
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def self.target_is_automate2_server?(url, insecure)
|
|
313
|
-
automate_endpoint = "/dex/auth"
|
|
314
|
-
response = InspecPlugins::Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
|
|
315
|
-
if response.code == "400"
|
|
316
|
-
Inspec::Log.debug(
|
|
317
|
-
"Received 400 from #{url}#{automate_endpoint} - " \
|
|
318
|
-
"assuming target is a #{AUTOMATE_PRODUCT_NAME}2 instance"
|
|
319
|
-
)
|
|
320
|
-
true
|
|
321
|
-
else
|
|
322
|
-
Inspec::Log.debug(
|
|
323
|
-
"Received #{response.code} from #{url}#{automate_endpoint} - " \
|
|
324
|
-
"assuming target is not an #{AUTOMATE_PRODUCT_NAME}2 instance"
|
|
325
|
-
)
|
|
326
|
-
false
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def self.target_is_automate_server?(url, insecure)
|
|
331
|
-
automate_endpoint = "/compliance/version"
|
|
332
|
-
response = InspecPlugins::Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
|
|
333
|
-
case response.code
|
|
334
|
-
when "401"
|
|
335
|
-
Inspec::Log.debug(
|
|
336
|
-
"Received 401 from #{url}#{automate_endpoint} - " \
|
|
337
|
-
"assuming target is a #{AUTOMATE_PRODUCT_NAME} instance"
|
|
338
|
-
)
|
|
339
|
-
true
|
|
340
|
-
when "200"
|
|
341
|
-
# Chef Automate currently returns 401 for `/compliance/version` but some
|
|
342
|
-
# versions of OpsWorks Chef Automate return 200 and a Chef Manage page
|
|
343
|
-
# when unauthenticated requests are received.
|
|
344
|
-
if response.body.include?("Are You Looking For the #{SERVER_PRODUCT_NAME}?")
|
|
345
|
-
Inspec::Log.debug(
|
|
346
|
-
"Received 200 from #{url}#{automate_endpoint} - " \
|
|
347
|
-
"assuming target is an #{AUTOMATE_PRODUCT_NAME} instance"
|
|
348
|
-
)
|
|
349
|
-
true
|
|
350
|
-
else
|
|
351
|
-
Inspec::Log.debug(
|
|
352
|
-
"Received 200 from #{url}#{automate_endpoint} " \
|
|
353
|
-
"but did not receive the Chef Manage page - " \
|
|
354
|
-
"assuming target is not a #{AUTOMATE_PRODUCT_NAME} instance"
|
|
355
|
-
)
|
|
356
|
-
false
|
|
357
|
-
end
|
|
358
|
-
else
|
|
359
|
-
Inspec::Log.debug(
|
|
360
|
-
"Received unexpected status code #{response.code} " \
|
|
361
|
-
"from #{url}#{automate_endpoint} - " \
|
|
362
|
-
"assuming target is not a #{AUTOMATE_PRODUCT_NAME} instance"
|
|
363
|
-
)
|
|
364
|
-
false
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
def self.target_is_compliance_server?(url, insecure)
|
|
369
|
-
# All versions of Chef Compliance return 200 for `/api/version`
|
|
370
|
-
compliance_endpoint = "/api/version"
|
|
371
|
-
|
|
372
|
-
response = InspecPlugins::Compliance::HTTP.get(url + compliance_endpoint, nil, insecure)
|
|
373
|
-
return false unless response.code == "200"
|
|
374
|
-
|
|
375
|
-
Inspec::Log.debug(
|
|
376
|
-
"Received 200 from #{url}#{compliance_endpoint} - " \
|
|
377
|
-
"assuming target is a #{AUTOMATE_PRODUCT_NAME} server"
|
|
378
|
-
)
|
|
379
|
-
true
|
|
218
|
+
def self.is_automate2_server?(config)
|
|
219
|
+
config["server_type"] == "automate2"
|
|
380
220
|
end
|
|
381
221
|
end
|
|
382
222
|
end
|