inspec-core 4.37.17 → 4.38.3
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.rb +2 -0
- data/lib/inspec/resources/mongodb.rb +65 -0
- data/lib/inspec/resources/mongodb_conf.rb +39 -0
- data/lib/inspec/resources/mysql_session.rb +12 -2
- data/lib/inspec/resources/postgres_session.rb +10 -1
- 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 +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da7b208efcb020501f9a283e5e512d3862cd4c3e7c19f2012e143af2721fd893
|
4
|
+
data.tar.gz: f534843ff5445086f3d40802fff3fe19c8ed787660dde2ce17816e8dc1225cac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efd72de313d408802e8484dba99e6291bcd1a571fe028642736fccfcb3d02b78bb700d88a0441d6b2525285891707a738b8315c8dc315edc50e288eb000940e3
|
7
|
+
data.tar.gz: 12d51bdaea741376370ea5e64abf645d9734a2edf4328118b8931c11d6032446830f0f7f495eed987e7fcc27518472e21f523d93bd1c1578468b97d9028d11c3
|
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)
|
data/lib/inspec/resources.rb
CHANGED
@@ -71,6 +71,8 @@ require "inspec/resources/key_rsa"
|
|
71
71
|
require "inspec/resources/ksh"
|
72
72
|
require "inspec/resources/limits_conf"
|
73
73
|
require "inspec/resources/login_defs"
|
74
|
+
require "inspec/resources/mongodb"
|
75
|
+
require "inspec/resources/mongodb_conf"
|
74
76
|
require "inspec/resources/mount"
|
75
77
|
require "inspec/resources/mssql_session"
|
76
78
|
require "inspec/resources/mysql"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Inspec::Resources
|
2
|
+
class Mongodb < Inspec.resource(1)
|
3
|
+
name "mongodb"
|
4
|
+
supports platform: "unix"
|
5
|
+
supports platform: "windows"
|
6
|
+
|
7
|
+
desc "The 'mongodb' resource is a helper for the 'mongodb_conf' & 'mongodb_session' resources. Please use those instead."
|
8
|
+
|
9
|
+
attr_reader :conf_path
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
case inspec.os[:family]
|
13
|
+
when "debian", "fedora", "redhat", "linux", "suse"
|
14
|
+
init_linux
|
15
|
+
when "darwin"
|
16
|
+
init_macos
|
17
|
+
when "windows"
|
18
|
+
init_windows
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"MongoDB"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def init_linux
|
29
|
+
@conf_path = "/etc/mongod.conf"
|
30
|
+
end
|
31
|
+
|
32
|
+
def init_macos
|
33
|
+
@conf_path = "/usr/local/etc/mongod.conf"
|
34
|
+
end
|
35
|
+
|
36
|
+
def init_windows
|
37
|
+
dir = "C:\\Program Files\\MongoDB\\Server"
|
38
|
+
@version = version_from_dir(dir)
|
39
|
+
unless @version.to_s.empty?
|
40
|
+
@conf_path = "#{dir}\\#{@version}\\bin\\mongod.cfg"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def version_from_dir(dir)
|
45
|
+
dirs = inspec.command("Get-ChildItem -Path \"#{dir}\" -Name").stdout
|
46
|
+
entries = dirs.lines.count
|
47
|
+
case entries
|
48
|
+
when 0
|
49
|
+
warn "Could not determine version of installed MongoDB by inspecting #{dir}"
|
50
|
+
nil
|
51
|
+
when 1
|
52
|
+
dir_to_version(dirs)
|
53
|
+
else
|
54
|
+
warn "Multiple versions of MongoDB installed or incorrect base dir #{dir}"
|
55
|
+
first = dir_to_version(dirs.lines.first)
|
56
|
+
warn "Using the first version found: #{first}"
|
57
|
+
first
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def dir_to_version(dir)
|
62
|
+
dir.chomp.split("/").last
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "inspec/resources/json"
|
2
|
+
require "inspec/resources/mongodb"
|
3
|
+
|
4
|
+
module Inspec::Resources
|
5
|
+
class MongodbConf < JsonConfig
|
6
|
+
name "mongodb_conf"
|
7
|
+
supports platform: "unix"
|
8
|
+
supports platform: "windows"
|
9
|
+
desc "Use the mongodb_conf InSpec audit resource to test the contents of the configuration file for MongoDB, typically located at `/etc/mongod.conf` or `C:\\Program Files\\MongoDB\\Server\\<version>\\bin\\mongod.cfg`, depending on the platform."
|
10
|
+
example <<~EXAMPLE
|
11
|
+
describe mongodb_conf do
|
12
|
+
its(["storage", "dbPath"]) { should eq "/var/lib/mongodb" }
|
13
|
+
its(["net", "port"]) { should eq 27017 }
|
14
|
+
end
|
15
|
+
EXAMPLE
|
16
|
+
|
17
|
+
def initialize(conf_path = nil)
|
18
|
+
@conf_path = conf_path || inspec.mongodb.conf_path
|
19
|
+
|
20
|
+
if @conf_path.nil?
|
21
|
+
return skip_resource "MongoDB conf path is not set."
|
22
|
+
end
|
23
|
+
|
24
|
+
super(@conf_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse(content)
|
30
|
+
YAML.load(content)
|
31
|
+
rescue => e
|
32
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to parse `mongod.conf` or `mongod.cfg` file: #{e.message}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def resource_base_name
|
36
|
+
"MongoDB Configuration"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -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
|
@@ -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
|
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
|
@@ -11,20 +11,10 @@ module InspecPlugins
|
|
11
11
|
def login(options)
|
12
12
|
raise ArgumentError, "Please specify a server using `#{EXEC_NAME} automate login https://SERVER` or `#{EXEC_NAME} compliance login https://SERVER`" unless options["server"]
|
13
13
|
|
14
|
+
options["server_type"] = "automate2"
|
14
15
|
options["server"] = URI("https://#{options["server"]}").to_s if URI(options["server"]).scheme.nil?
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
case options["server_type"]
|
19
|
-
when :automate2
|
20
|
-
Login::Automate2Server.login(options)
|
21
|
-
when :automate
|
22
|
-
Login::AutomateServer.login(options)
|
23
|
-
when :compliance
|
24
|
-
Login::ComplianceServer.login(options)
|
25
|
-
else
|
26
|
-
raise CannotDetermineServerType, "Unable to determine if #{options["server"]} is a #{AUTOMATE_PRODUCT_NAME} or #{COMPLIANCE_PRODUCT_NAME} server"
|
27
|
-
end
|
17
|
+
Login::Automate2Server.login(options)
|
28
18
|
end
|
29
19
|
|
30
20
|
module Automate2Server
|
@@ -48,7 +38,7 @@ module InspecPlugins
|
|
48
38
|
config["user"] = options["user"]
|
49
39
|
config["owner"] = options["user"]
|
50
40
|
config["insecure"] = options["insecure"] || false
|
51
|
-
config["server_type"] = options["server_type"]
|
41
|
+
config["server_type"] = options["server_type"]
|
52
42
|
config["token"] = token
|
53
43
|
config["version"] = "0"
|
54
44
|
|
@@ -69,133 +59,6 @@ module InspecPlugins
|
|
69
59
|
end
|
70
60
|
end
|
71
61
|
|
72
|
-
module AutomateServer
|
73
|
-
def self.login(options)
|
74
|
-
verify_thor_options(options)
|
75
|
-
|
76
|
-
options["url"] = options["server"] + "/compliance"
|
77
|
-
token = options["dctoken"] || options["token"]
|
78
|
-
success, msg = API::Login.authenticate_login(options)
|
79
|
-
success ? store_access_token(options, token) : msg
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.store_access_token(options, token)
|
83
|
-
token_type = if options["token"]
|
84
|
-
"usertoken"
|
85
|
-
else
|
86
|
-
"dctoken"
|
87
|
-
end
|
88
|
-
|
89
|
-
config = InspecPlugins::Compliance::Configuration.new
|
90
|
-
|
91
|
-
config.clean
|
92
|
-
|
93
|
-
config["automate"] = {}
|
94
|
-
config["automate"]["ent"] = options["ent"]
|
95
|
-
config["automate"]["token_type"] = token_type
|
96
|
-
config["server"] = options["url"]
|
97
|
-
config["user"] = options["user"]
|
98
|
-
config["insecure"] = options["insecure"] || false
|
99
|
-
config["server_type"] = options["server_type"].to_s
|
100
|
-
config["token"] = token
|
101
|
-
config["version"] = InspecPlugins::Compliance::API.version(config)
|
102
|
-
|
103
|
-
config.store
|
104
|
-
API::Login.configuration_stored_message(config)
|
105
|
-
end
|
106
|
-
|
107
|
-
# Automate login requires `--ent`, `--user`, and either `--token` or `--dctoken`
|
108
|
-
def self.verify_thor_options(o)
|
109
|
-
error_msg = []
|
110
|
-
|
111
|
-
error_msg.push("Please specify a user using `--user='USER'`") if o["user"].nil?
|
112
|
-
error_msg.push("Please specify an enterprise using `--ent='automate'`") if o["ent"].nil?
|
113
|
-
|
114
|
-
if o["token"].nil? && o["dctoken"].nil?
|
115
|
-
error_msg.push("Please specify a token using `--token='AUTOMATE_TOKEN'` or `--dctoken='DATA_COLLECTOR_TOKEN'`")
|
116
|
-
end
|
117
|
-
|
118
|
-
raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
module ComplianceServer
|
123
|
-
include Inspec::Dist
|
124
|
-
|
125
|
-
def self.login(options)
|
126
|
-
compliance_verify_thor_options(options)
|
127
|
-
|
128
|
-
options["url"] = options["server"] + "/api"
|
129
|
-
|
130
|
-
if options["user"] && options["token"]
|
131
|
-
success, msg = API::Login.authenticate_login(options)
|
132
|
-
success ? compliance_store_access_token(options, options["token"]) : msg
|
133
|
-
elsif options["user"] && options["password"]
|
134
|
-
compliance_login_user_pass(options)
|
135
|
-
elsif options["refresh_token"]
|
136
|
-
compliance_login_refresh_token(options)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def self.compliance_login_user_pass(options)
|
141
|
-
success, msg, token = InspecPlugins::Compliance::API.get_token_via_password(
|
142
|
-
options["url"],
|
143
|
-
options["user"],
|
144
|
-
options["password"],
|
145
|
-
options["insecure"]
|
146
|
-
)
|
147
|
-
|
148
|
-
raise msg unless success
|
149
|
-
|
150
|
-
compliance_store_access_token(options, token)
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.compliance_login_refresh_token(options)
|
154
|
-
success, msg, token = InspecPlugins::Compliance::API.get_token_via_refresh_token(
|
155
|
-
options["url"],
|
156
|
-
options["refresh_token"],
|
157
|
-
options["insecure"]
|
158
|
-
)
|
159
|
-
|
160
|
-
raise msg unless success
|
161
|
-
|
162
|
-
compliance_store_access_token(options, token)
|
163
|
-
end
|
164
|
-
|
165
|
-
def self.compliance_store_access_token(options, token)
|
166
|
-
config = InspecPlugins::Compliance::Configuration.new
|
167
|
-
config.clean
|
168
|
-
|
169
|
-
config["user"] = options["user"] if options["user"]
|
170
|
-
config["server"] = options["url"]
|
171
|
-
config["insecure"] = options["insecure"] || false
|
172
|
-
config["server_type"] = options["server_type"].to_s
|
173
|
-
config["token"] = token
|
174
|
-
config["version"] = InspecPlugins::Compliance::API.version(config)
|
175
|
-
|
176
|
-
config.store
|
177
|
-
API::Login.configuration_stored_message(config)
|
178
|
-
end
|
179
|
-
|
180
|
-
# Compliance login requires `--user` or `--refresh_token`
|
181
|
-
# If `--user` then either `--password`, `--token`, or `--refresh-token`, is required
|
182
|
-
def self.compliance_verify_thor_options(o)
|
183
|
-
error_msg = []
|
184
|
-
|
185
|
-
error_msg.push("Please specify a server using `#{EXEC_NAME} automate login https://SERVER` or `#{EXEC_NAME} compliance login https://SERVER`") if o["server"].nil?
|
186
|
-
|
187
|
-
if o["user"].nil? && o["refresh_token"].nil?
|
188
|
-
error_msg.push("Please specify a `--user='USER'` or a `--refresh-token='TOKEN'`")
|
189
|
-
end
|
190
|
-
|
191
|
-
if o["user"] && o["password"].nil? && o["token"].nil? && o["refresh_token"].nil?
|
192
|
-
error_msg.push("Please specify either a `--password`, `--token`, or `--refresh-token`")
|
193
|
-
end
|
194
|
-
|
195
|
-
raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
62
|
def self.authenticate_login(options)
|
200
63
|
InspecPlugins::Compliance::API.authenticate_login_using_version_api(
|
201
64
|
options["url"],
|
@@ -13,10 +13,9 @@ module InspecPlugins
|
|
13
13
|
long_desc <<-LONGDESC
|
14
14
|
`login` allows you to use InSpec with #{AUTOMATE_PRODUCT_NAME} Server
|
15
15
|
|
16
|
-
You need to a token for communication. More information about token retrieval
|
16
|
+
You need to have a token for communication. More information about token retrieval
|
17
17
|
is available at:
|
18
|
-
https://docs.chef.io/
|
19
|
-
https://docs.chef.io/api_compliance.html#obtaining-an-api-token
|
18
|
+
https://docs.chef.io/automate/api_tokens
|
20
19
|
LONGDESC
|
21
20
|
option :insecure, aliases: :k, type: :boolean,
|
22
21
|
desc: 'Explicitly allows InSpec to perform "insecure" SSL connections and transfers'
|
@@ -32,16 +32,8 @@ module InspecPlugins
|
|
32
32
|
|
33
33
|
def self.check_compliance_token(uri, config)
|
34
34
|
if config["token"].nil? && config["refresh_token"].nil?
|
35
|
-
|
36
|
-
|
37
|
-
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate_server --user USER --ent ENT --dctoken DCTOKEN or --token USERTOKEN"
|
38
|
-
elsif config["server_type"] == "automate2"
|
39
|
-
server = "automate2"
|
40
|
-
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate2_server --user USER --token APITOKEN"
|
41
|
-
else
|
42
|
-
server = "compliance"
|
43
|
-
msg = "#{EXEC_NAME} [automate|compliance] login https://your_compliance_server --user admin --insecure --token 'PASTE TOKEN HERE' "
|
44
|
-
end
|
35
|
+
server = "automate2"
|
36
|
+
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate2_server --user USER --token APITOKEN"
|
45
37
|
raise Inspec::FetcherFailure, <<~EOF
|
46
38
|
|
47
39
|
Cannot fetch #{uri} because your #{server} token has not been
|
@@ -119,19 +111,9 @@ module InspecPlugins
|
|
119
111
|
|
120
112
|
# determine the owner_id and the profile name from the url
|
121
113
|
def compliance_profile_name
|
122
|
-
m =
|
123
|
-
|
124
|
-
|
125
|
-
%r{^#{@config['server']}/profiles/(?<owner>[^/]+)/(?<id>[^/]+)/tar$}
|
126
|
-
else
|
127
|
-
%r{^#{@config['server']}/owners/(?<owner>[^/]+)/compliance/(?<id>[^/]+)/tar$}
|
128
|
-
end.match(@target)
|
129
|
-
|
130
|
-
if InspecPlugins::Compliance::API.is_automate2_server?(@config)
|
131
|
-
m = {}
|
132
|
-
m[:owner] = @config["profile"][0]
|
133
|
-
m[:id] = @config["profile"][1]
|
134
|
-
end
|
114
|
+
m = {}
|
115
|
+
m[:owner] = @config["profile"][0]
|
116
|
+
m[:id] = @config["profile"][1]
|
135
117
|
|
136
118
|
if m.nil?
|
137
119
|
raise "Unable to determine compliance profile name. This can be caused by " \
|
@@ -17,7 +17,8 @@ module InspecPlugins
|
|
17
17
|
option :description, type: :string, default: "", desc: "Multi-line description of the plugin"
|
18
18
|
option :summary, type: :string, default: "A plugin with a default summary", desc: "One-line summary of your plugin"
|
19
19
|
option :license_name, type: :string, default: "Apache-2.0", desc: "The name of a license"
|
20
|
-
option :
|
20
|
+
option :activator, type: :array, default: ["cli_command:my_command"], desc: "A list of plugin activators, in the form type1:name1, type2:name2, etc"
|
21
|
+
option :hook, type: :array, desc: "Legacy name for --activator - Deprecated."
|
21
22
|
# These vars have calculated defaults
|
22
23
|
option :homepage, type: :string, default: nil, desc: "A URL for your project, often a GitHub link"
|
23
24
|
option :module_name, type: :string, default: nil, desc: "Module Name for your plugin package. Will change plugin name to CamelCase by default."
|
@@ -29,6 +30,12 @@ module InspecPlugins
|
|
29
30
|
plugin_type = determine_plugin_type(plugin_name)
|
30
31
|
snake_case = plugin_name.tr("-", "_")
|
31
32
|
|
33
|
+
# Handle deprecation of option --hook
|
34
|
+
unless options[:hook].nil?
|
35
|
+
Inspec.deprecate "cli_option_hook"
|
36
|
+
options[:activator] = options.delete(:hook)
|
37
|
+
end
|
38
|
+
|
32
39
|
template_vars = {
|
33
40
|
name: plugin_name,
|
34
41
|
plugin_name: plugin_name,
|
@@ -41,7 +48,7 @@ module InspecPlugins
|
|
41
48
|
templates_path: TEMPLATES_PATH,
|
42
49
|
overwrite: options[:overwrite],
|
43
50
|
file_rename_map: make_rename_map(plugin_type, plugin_name, snake_case),
|
44
|
-
skip_files: make_skip_list(template_vars["
|
51
|
+
skip_files: make_skip_list(template_vars["activators"].keys),
|
45
52
|
}
|
46
53
|
|
47
54
|
renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
|
@@ -71,12 +78,15 @@ module InspecPlugins
|
|
71
78
|
{
|
72
79
|
"inspec-plugin-template.gemspec" => plugin_name + ".gemspec",
|
73
80
|
File.join("lib", "inspec-plugin-template") => File.join("lib", plugin_name),
|
74
|
-
File.join("lib", "inspec-plugin-template.
|
75
|
-
File.join("lib", "inspec-plugin-template", "cli_command.
|
76
|
-
File.join("lib", "inspec-plugin-template", "reporter.
|
77
|
-
File.join("lib", "inspec-plugin-template", "plugin.
|
78
|
-
File.join("lib", "inspec-plugin-template", "version.
|
79
|
-
File.join("test", "functional", "inspec_plugin_template_test.
|
81
|
+
File.join("lib", "inspec-plugin-template.erb") => File.join("lib", plugin_name + ".rb"),
|
82
|
+
File.join("lib", "inspec-plugin-template", "cli_command.erb") => File.join("lib", plugin_name, "cli_command.rb"),
|
83
|
+
File.join("lib", "inspec-plugin-template", "reporter.erb") => File.join("lib", plugin_name, "reporter.rb"),
|
84
|
+
File.join("lib", "inspec-plugin-template", "plugin.erb") => File.join("lib", plugin_name, "plugin.rb"),
|
85
|
+
File.join("lib", "inspec-plugin-template", "version.erb") => File.join("lib", plugin_name, "version.rb"),
|
86
|
+
File.join("test", "functional", "inspec_plugin_template_test.erb") => File.join("test", "functional", snake_case + "_test.rb"),
|
87
|
+
File.join("test", "unit", "cli_args_test.erb") => File.join("test", "unit", "cli_args_test.rb"),
|
88
|
+
File.join("test", "unit", "plugin_def_test.erb") => File.join("test", "unit", "plugin_def_test.rb"),
|
89
|
+
File.join("test", "helper.erb") => File.join("test", "helper.rb"),
|
80
90
|
}
|
81
91
|
end
|
82
92
|
|
@@ -93,7 +103,7 @@ module InspecPlugins
|
|
93
103
|
ui.error("You requested interactive prompting for the template variables, but this does not seem to be an interactive terminal.")
|
94
104
|
ui.exit(:usage_error)
|
95
105
|
end
|
96
|
-
vars.merge(
|
106
|
+
vars.merge(parse_activator_option(options[:activator]))
|
97
107
|
end
|
98
108
|
|
99
109
|
def vars_from_defaults
|
@@ -121,7 +131,7 @@ module InspecPlugins
|
|
121
131
|
],
|
122
132
|
},
|
123
133
|
homepage: { default_setter: proc { options[:homepage] ||= "https://github.com/" + options[:author_email].split("@").first + "/" + options[:plugin_name] } },
|
124
|
-
# TODO: Handle
|
134
|
+
# TODO: Handle activators, when we ever have more than one type of plugin
|
125
135
|
}
|
126
136
|
|
127
137
|
prompt_for_options(order)
|
@@ -153,26 +163,26 @@ module InspecPlugins
|
|
153
163
|
end
|
154
164
|
end
|
155
165
|
|
156
|
-
def
|
157
|
-
|
166
|
+
def parse_activator_option(raw_option)
|
167
|
+
activators_by_type = {}
|
158
168
|
raw_option.each do |entry|
|
159
169
|
parts = entry.split(":")
|
160
170
|
type = parts.first.to_sym
|
161
171
|
name = parts.last
|
162
|
-
if
|
163
|
-
ui.error "The InSpec plugin generator can currently only generate one
|
172
|
+
if activators_by_type.key?(type)
|
173
|
+
ui.error "The InSpec plugin generator can currently only generate one activator of each type"
|
164
174
|
ui.exit(:usage_error)
|
165
175
|
end
|
166
|
-
|
176
|
+
activators_by_type[type] = name
|
167
177
|
end
|
168
178
|
|
169
|
-
vars = {
|
170
|
-
if
|
171
|
-
vars[:command_name_dashes] =
|
172
|
-
vars[:command_name_snake] =
|
173
|
-
elsif
|
174
|
-
vars[:reporter_name_dashes] =
|
175
|
-
vars[:reporter_name_snake] =
|
179
|
+
vars = { activators: activators_by_type }
|
180
|
+
if activators_by_type.key?(:cli_command)
|
181
|
+
vars[:command_name_dashes] = activators_by_type[:cli_command].tr("_", "-")
|
182
|
+
vars[:command_name_snake] = activators_by_type[:cli_command].tr("-", "_")
|
183
|
+
elsif activators_by_type.key?(:reporter)
|
184
|
+
vars[:reporter_name_dashes] = activators_by_type[:reporter].tr("_", "-")
|
185
|
+
vars[:reporter_name_snake] = activators_by_type[:reporter].tr("-", "_")
|
176
186
|
end
|
177
187
|
vars
|
178
188
|
end
|
@@ -210,7 +220,7 @@ module InspecPlugins
|
|
210
220
|
end
|
211
221
|
end
|
212
222
|
|
213
|
-
def make_skip_list(
|
223
|
+
def make_skip_list(requested_activators)
|
214
224
|
skips = []
|
215
225
|
case options[:detail]
|
216
226
|
when "full" # rubocop: disable Lint/EmptyWhen
|
@@ -230,13 +240,13 @@ module InspecPlugins
|
|
230
240
|
"Rakefile",
|
231
241
|
File.join("test", "fixtures", "README.md"),
|
232
242
|
File.join("test", "fixtures"),
|
233
|
-
File.join("test", "functional", "inspec_plugin_template_test.
|
243
|
+
File.join("test", "functional", "inspec_plugin_template_test.erb"),
|
234
244
|
File.join("test", "functional", "README.md"),
|
235
|
-
File.join("test", "unit", "cli_args_test.
|
236
|
-
File.join("test", "unit", "plugin_def_test.
|
245
|
+
File.join("test", "unit", "cli_args_test.erb"),
|
246
|
+
File.join("test", "unit", "plugin_def_test.erb"),
|
237
247
|
File.join("test", "unit", "README.md"),
|
238
248
|
File.join("test", "unit"),
|
239
|
-
File.join("test", "helper.
|
249
|
+
File.join("test", "helper.erb"),
|
240
250
|
File.join("test"),
|
241
251
|
]
|
242
252
|
else
|
@@ -244,17 +254,17 @@ module InspecPlugins
|
|
244
254
|
ui.exit(:usage_error)
|
245
255
|
end
|
246
256
|
|
247
|
-
# Remove
|
248
|
-
unless
|
257
|
+
# Remove activator-specific files
|
258
|
+
unless requested_activators.include?(:cli_command)
|
249
259
|
skips += [
|
250
|
-
File.join("lib", "inspec-plugin-template", "cli_command.
|
251
|
-
File.join("test", "unit", "cli_args_test.
|
252
|
-
File.join("test", "functional", "inspec_plugin_template_test.
|
260
|
+
File.join("lib", "inspec-plugin-template", "cli_command.erb"),
|
261
|
+
File.join("test", "unit", "cli_args_test.erb"),
|
262
|
+
File.join("test", "functional", "inspec_plugin_template_test.erb"),
|
253
263
|
]
|
254
264
|
end
|
255
|
-
unless
|
265
|
+
unless requested_activators.include?(:reporter)
|
256
266
|
skips += [
|
257
|
-
File.join("lib", "inspec-plugin-template", "reporter.
|
267
|
+
File.join("lib", "inspec-plugin-template", "reporter.erb"),
|
258
268
|
]
|
259
269
|
end
|
260
270
|
|
@@ -65,6 +65,7 @@ module InspecPlugins
|
|
65
65
|
# read & render content
|
66
66
|
content = render(File.read(source_file), template_values)
|
67
67
|
# write file content
|
68
|
+
|
68
69
|
File.write(full_destination_item_path, content)
|
69
70
|
else
|
70
71
|
ui.warning "Ignoring #{ui.emphasis(source_file)}, because its not an file or directoy"
|
@@ -1,11 +1,11 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :development do
|
6
|
-
gem
|
7
|
-
gem
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
6
|
+
gem "bundler"
|
7
|
+
gem "byebug"
|
8
|
+
gem "minitest"
|
9
|
+
gem "rake"
|
10
|
+
gem "rubocop", "= 0.49.1" # Need to keep in sync with main InSpec project, so config files will work
|
11
11
|
end
|
@@ -7,13 +7,13 @@
|
|
7
7
|
|
8
8
|
# This task template will make a task named 'test', and run
|
9
9
|
# the tests that it finds.
|
10
|
-
require
|
10
|
+
require "rake/testtask"
|
11
11
|
|
12
12
|
Rake::TestTask.new do |t|
|
13
|
-
t.libs.push
|
13
|
+
t.libs.push "lib"
|
14
14
|
t.test_files = FileList[
|
15
|
-
|
16
|
-
|
15
|
+
"test/unit/*_test.rb",
|
16
|
+
"test/functional/*_test.rb",
|
17
17
|
]
|
18
18
|
t.verbose = true
|
19
19
|
# Ideally, we'd run tests with warnings enabled,
|
@@ -26,15 +26,15 @@ end
|
|
26
26
|
#------------------------------------------------------------------#
|
27
27
|
# Code Style Tasks
|
28
28
|
#------------------------------------------------------------------#
|
29
|
-
require
|
29
|
+
require "rubocop/rake_task"
|
30
30
|
|
31
31
|
RuboCop::RakeTask.new(:lint) do |t|
|
32
32
|
# Choices of RuboCop rules to enforce are deeply personal.
|
33
33
|
# Here, we set things up so that your plugin will use the Bundler-installed
|
34
34
|
# inspec gem's copy of the InSpec project's rubocop.yml file (which
|
35
35
|
# is indeed packaged with the inspec gem).
|
36
|
-
require
|
37
|
-
inspec_rubocop_yml = File.join(Inspec.src_root,
|
36
|
+
require "inspec/globals"
|
37
|
+
inspec_rubocop_yml = File.join(Inspec.src_root, ".rubocop.yml")
|
38
38
|
|
39
|
-
t.options = [
|
39
|
+
t.options = ["--display-cop-names", "--config", inspec_rubocop_yml]
|
40
40
|
end
|
data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec
CHANGED
@@ -4,23 +4,23 @@
|
|
4
4
|
|
5
5
|
# It is traditional in a gemspec to dynamically load the current version
|
6
6
|
# from a file in the source tree. The next three lines make that happen.
|
7
|
-
lib = File.expand_path(
|
7
|
+
lib = File.expand_path("../lib", __FILE__)
|
8
8
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
9
|
-
require
|
9
|
+
require "<%= plugin_name %>/version"
|
10
10
|
|
11
11
|
Gem::Specification.new do |spec|
|
12
12
|
# Importantly, all InSpec plugins must be prefixed with `inspec-` (most
|
13
13
|
# plugins) or `train-` (plugins which add new connectivity features).
|
14
|
-
spec.name =
|
14
|
+
spec.name = "<%= plugin_name %>"
|
15
15
|
|
16
16
|
# It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
|
17
17
|
spec.version = InspecPlugins::<%= module_name %>::VERSION
|
18
|
-
spec.authors = [
|
19
|
-
spec.email = [
|
20
|
-
spec.summary =
|
21
|
-
spec.description =
|
22
|
-
spec.homepage =
|
23
|
-
spec.license =
|
18
|
+
spec.authors = ["<%= author_name %>"]
|
19
|
+
spec.email = ["<%= author_email %>"]
|
20
|
+
spec.summary = "<%= summary %>"
|
21
|
+
spec.description = "<%= description.is_a?(Array) ? description.join(" "): description %>"
|
22
|
+
spec.homepage = "<%= homepage %>"
|
23
|
+
spec.license = "<%= license_name %>"
|
24
24
|
|
25
25
|
# Though complicated-looking, this is pretty standard for a gemspec.
|
26
26
|
# It just filters what will actually be packaged in the gem (leaving
|
@@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.files = %w{
|
29
29
|
README.md <%= snake_case %>.gemspec Gemfile
|
30
30
|
} + Dir.glob(
|
31
|
-
|
31
|
+
"lib/**/*", File::FNM_DOTMATCH
|
32
32
|
).reject { |f| File.directory?(f) }
|
33
|
-
spec.require_paths = [
|
33
|
+
spec.require_paths = ["lib"]
|
34
34
|
|
35
35
|
# If you rely on any other gems, list them here with any constraints.
|
36
36
|
# This is how `inspec plugin install` is able to manage your dependencies.
|
@@ -39,5 +39,5 @@ Gem::Specification.new do |spec|
|
|
39
39
|
|
40
40
|
# All plugins should mention inspec, > 2.2.78
|
41
41
|
# 2.2.78 included the v2 Plugin API
|
42
|
-
spec.add_dependency
|
42
|
+
spec.add_dependency "inspec", ">= 2.2.78", "< 4.0.0"
|
43
43
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "inspec/resource"
|
2
2
|
|
3
3
|
module InspecPlugins::<%= module_name %>
|
4
4
|
# This class will provide the actual CLI implementation.
|
@@ -21,31 +21,31 @@ module InspecPlugins::<%= module_name %>
|
|
21
21
|
# Note: if you want your command (or subcommand) to have dashes in it,
|
22
22
|
# use underscores where you want a dash, and Thor will convert them.
|
23
23
|
# Thor will fail to find a command that is directly named with dashes.
|
24
|
-
subcommand_desc
|
24
|
+
subcommand_desc "<%= command_name_snake %> [COMMAND]", "Your Usage Message Here"
|
25
25
|
|
26
26
|
# The usual rhythm for a Thor CLI file is description, options, command method.
|
27
27
|
# Thor just has you call DSL methods in sequence prior to each command.
|
28
28
|
|
29
29
|
# Let's make a command, 'do_something'. This will then be available
|
30
|
-
# as `inspec <%= command_name_dashes %> do-something
|
30
|
+
# as `inspec <%= command_name_dashes %> do-something`
|
31
31
|
# (Change this method name to be something sensible for your plugin.)
|
32
32
|
|
33
33
|
# First, provide a usage / description. This will appear
|
34
34
|
# in `inspec help <%= command_name_dashes %>`.
|
35
35
|
# As this is a usage message, you should write the command as it should appear
|
36
36
|
# to the user (if you want it to have dashes, use dashes)
|
37
|
-
desc
|
37
|
+
desc "do-something WHAT [OPTIONS]", "Does something"
|
38
38
|
|
39
39
|
# Let's include an option, -s, to summarize
|
40
40
|
# Refer to the Thors docs; there is a lot you can do here.
|
41
|
-
option :summary, desc:
|
41
|
+
option :summary, desc: "Include a total at the bottom", \
|
42
42
|
type: :boolean, default: true, aliases: [:s]
|
43
43
|
|
44
|
-
# OK, now the actual method itself.
|
44
|
+
# OK, now the actual method itself. If you provide params, you're telling Thor that
|
45
45
|
# you accept CLI arguments after all options have been consumed.
|
46
46
|
# Note again that the method name has an underscore, but when invoked
|
47
47
|
# on the CLI, use a dash.
|
48
|
-
def do_something(what =
|
48
|
+
def do_something(what = "nothing")
|
49
49
|
# The code here will *only* be executed if someone actually
|
50
50
|
# runs `inspec <%= command_name_dashes %> do-something`.
|
51
51
|
|
@@ -55,7 +55,7 @@ module InspecPlugins::<%= module_name %>
|
|
55
55
|
# Talk to the user using the `ui` object (see Inspec::UI)
|
56
56
|
# ui.error('Whoops!')
|
57
57
|
|
58
|
-
ui.warning(
|
58
|
+
ui.warning("This is a generated plugin with a default implementation. Edit lib/<%= plugin_name %>/cli_command.rb to make it do what you want.")
|
59
59
|
ui.exit(:success) # or :usage_error
|
60
60
|
end
|
61
61
|
end
|
@@ -1,49 +1,49 @@
|
|
1
1
|
# Plugin Definition file
|
2
2
|
# The purpose of this file is to declare to InSpec what plugin_types (capabilities)
|
3
|
-
# are included in this plugin, and provide
|
3
|
+
# are included in this plugin, and provide activator that will load them as needed.
|
4
4
|
|
5
5
|
# It is important that this file load successfully and *quickly*.
|
6
6
|
# Your plugin's functionality may never be used on this InSpec run; so we keep things
|
7
7
|
# fast and light by only loading heavy things when they are needed.
|
8
8
|
|
9
9
|
# Presumably this is light
|
10
|
-
require
|
10
|
+
require "<%= plugin_name %>/version"
|
11
11
|
|
12
12
|
# The InspecPlugins namespace is where all plugins should declare themselves.
|
13
|
-
# The
|
13
|
+
# The "Inspec" capitalization is used throughout the InSpec source code; yes, it's
|
14
14
|
# strange.
|
15
15
|
module InspecPlugins
|
16
|
-
# Pick a reasonable namespace here for your plugin.
|
16
|
+
# Pick a reasonable namespace here for your plugin. A reasonable choice
|
17
17
|
# would be the CamelCase version of your plugin gem name.
|
18
18
|
# <%= plugin_name %> => <%= module_name %>
|
19
19
|
module <%= module_name %>
|
20
20
|
# This simple class handles the plugin definition, so calling it simply Plugin is OK.
|
21
21
|
# Inspec.plugin returns various Classes, intended to be superclasses for various
|
22
22
|
# plugin components. Here, the one-arg form gives you the Plugin Definition superclass,
|
23
|
-
# which mainly gives you access to the
|
23
|
+
# which mainly gives you access to the activator / plugin_type DSL.
|
24
24
|
# The number '2' says you are asking for version 2 of the plugin API. If there are
|
25
25
|
# future versions, InSpec promises plugin API v2 will work for at least two more InSpec
|
26
26
|
# major versions.
|
27
27
|
class Plugin < ::Inspec.plugin(2)
|
28
28
|
# Internal machine name of the plugin. InSpec will use this in errors, etc.
|
29
|
-
plugin_name :
|
29
|
+
plugin_name :"<%= plugin_name %>"
|
30
30
|
|
31
|
-
<% if
|
31
|
+
<% if activators[:cli_command] %>
|
32
32
|
# Define a new CLI subcommand.
|
33
33
|
# The argument here will be used to match against the command line args,
|
34
|
-
# and if the user said `inspec list-resources`, this
|
35
|
-
# Notice that you can define multiple
|
34
|
+
# and if the user said `inspec list-resources`, this activator will get called.
|
35
|
+
# Notice that you can define multiple activators with different names, and they
|
36
36
|
# don't have to match the plugin name.
|
37
37
|
|
38
38
|
# We'd like this to be list-resources, but Thor does not support hyphens
|
39
39
|
# see https://github.com/erikhuda/thor/pull/613
|
40
40
|
cli_command :<%= command_name_snake %> do
|
41
|
-
# Calling this
|
41
|
+
# Calling this activator doesn't mean the subcommand is being executed - just
|
42
42
|
# that we should be ready to do so. So, load the file that defines the
|
43
43
|
# functionality.
|
44
|
-
# For example, InSpec will activate this
|
44
|
+
# For example, InSpec will activate this activator when `inspec help` is
|
45
45
|
# executed, so that this plugin's usage message will be included in the help.
|
46
|
-
require
|
46
|
+
require "<%= plugin_name %>/cli_command"
|
47
47
|
|
48
48
|
# Having loaded our functionality, return a class that will let the
|
49
49
|
# CLI engine tap into it.
|
@@ -51,15 +51,15 @@ module InspecPlugins
|
|
51
51
|
end
|
52
52
|
<% end %>
|
53
53
|
|
54
|
-
<% if
|
54
|
+
<% if activators[:reporter] %>
|
55
55
|
# Define a new Reporter.
|
56
56
|
# The argument here will be used to match against the CLI --reporter option.
|
57
57
|
# `--reporter <%= reporter_name_snake %>` will load your reporter and call its renderer.
|
58
58
|
reporter :<%= reporter_name_snake %> do
|
59
|
-
# Calling this
|
59
|
+
# Calling this activator doesn't mean the reporter is being executed - just
|
60
60
|
# that we should be ready to do so. So, load the file that defines the
|
61
61
|
# functionality.
|
62
|
-
require
|
62
|
+
require "<%= plugin_name %>/reporter"
|
63
63
|
|
64
64
|
# Having loaded our functionality, return a class that will let the
|
65
65
|
# reporting engine tap into it.
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.38.3
|
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: 2021-
|
11
|
+
date: 2021-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-telemetry
|
@@ -554,6 +554,8 @@ files:
|
|
554
554
|
- lib/inspec/resources/limits_conf.rb
|
555
555
|
- lib/inspec/resources/linux_kernel_parameter.rb
|
556
556
|
- lib/inspec/resources/login_defs.rb
|
557
|
+
- lib/inspec/resources/mongodb.rb
|
558
|
+
- lib/inspec/resources/mongodb_conf.rb
|
557
559
|
- lib/inspec/resources/mount.rb
|
558
560
|
- lib/inspec/resources/mssql_session.rb
|
559
561
|
- lib/inspec/resources/mysql.rb
|
@@ -712,11 +714,11 @@ files:
|
|
712
714
|
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/README.md
|
713
715
|
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Rakefile
|
714
716
|
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec
|
715
|
-
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.
|
716
|
-
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/cli_command.
|
717
|
-
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.
|
718
|
-
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/reporter.
|
719
|
-
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.
|
717
|
+
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.erb
|
718
|
+
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/cli_command.erb
|
719
|
+
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb
|
720
|
+
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/reporter.erb
|
721
|
+
- lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.erb
|
720
722
|
- lib/plugins/inspec-init/templates/profiles/aws/README.md
|
721
723
|
- lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb
|
722
724
|
- lib/plugins/inspec-init/templates/profiles/aws/inputs.yml
|