inspec 4.36.4 → 4.37.23
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 +14 -1
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +6 -6
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +12 -12
- data/lib/resources/aws/aws_cloudtrail_trail.rb +6 -6
- data/lib/resources/aws/aws_iam_access_keys.rb +19 -19
- data/lib/resources/aws/aws_iam_password_policy.rb +12 -12
- data/lib/resources/aws/aws_kms_key.rb +24 -24
- data/lib/resources/aws/aws_rds_instance.rb +7 -7
- data/lib/resources/aws/aws_s3_bucket.rb +17 -18
- data/lib/resources/aws/aws_s3_bucket_object.rb +10 -10
- data/lib/resources/aws/aws_sns_subscription.rb +13 -13
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c7b7ca05613e276fff9bb13c14a98aa79930cc082426541f33d0505277a7835
|
4
|
+
data.tar.gz: 2bd297d4af75c978c71dfc3a516f2fbb7757dec96323a59f4869ca1c19ada716
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 693f5c2b12410258d36574364c003d320370729218b7083f0be53f9920a4fea80539d36ae5f2c42558cf1f7f48b01fd08b98a563064152e353dae328d75286d8
|
7
|
+
data.tar.gz: 599017125ae5e0e4f90223900de906ac6e82b8b83b08d58d121495dab27ab1d70d55aaea83a40bd362bb7b39af7703d376637ab202ab681603058e7d310d9131
|
data/Gemfile
CHANGED
@@ -28,7 +28,7 @@ group :omnibus do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
group :test do
|
31
|
-
gem "chefstyle", "~>
|
31
|
+
gem "chefstyle", "~> 2.0.3"
|
32
32
|
gem "concurrent-ruby", "~> 1.0"
|
33
33
|
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
|
34
34
|
gem "json_schemer", ">= 0.2.1", "< 0.2.19"
|
@@ -48,3 +48,16 @@ end
|
|
48
48
|
group :deploy do
|
49
49
|
gem "inquirer"
|
50
50
|
end
|
51
|
+
|
52
|
+
# Only include Test Kitchen support if we are on Ruby 2.7 or higher
|
53
|
+
# as chef-zero support requires Ruby 2.6
|
54
|
+
# See https://github.com/inspec/inspec/pull/5341
|
55
|
+
if Gem.ruby_version >= Gem::Version.new("2.7.0")
|
56
|
+
group :kitchen do
|
57
|
+
gem "berkshelf"
|
58
|
+
gem "test-kitchen", ">= 2.8"
|
59
|
+
gem "kitchen-inspec", ">= 2.0"
|
60
|
+
gem "kitchen-dokken", ">= 2.11"
|
61
|
+
gem "git"
|
62
|
+
end
|
63
|
+
end
|
@@ -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
|
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
|
@@ -36,12 +36,12 @@ class AwsCloudTrailTrail < Inspec.resource(1)
|
|
36
36
|
def delivered_logs_days_ago
|
37
37
|
query = { name: @trail_name }
|
38
38
|
catch_aws_errors do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
|
40
|
+
resp = BackendFactory.create(inspec_runner).get_trail_status(query).to_h
|
41
|
+
((Time.now - resp[:latest_cloud_watch_logs_delivery_time]) / (24 * 60 * 60)).to_i unless resp[:latest_cloud_watch_logs_delivery_time].nil?
|
42
|
+
rescue Aws::CloudTrail::Errors::TrailNotFoundException
|
43
|
+
nil
|
44
|
+
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -101,27 +101,27 @@ class AwsIamAccessKeys < Inspec.resource(1)
|
|
101
101
|
|
102
102
|
access_key_data = []
|
103
103
|
user_details.each_key do |username|
|
104
|
-
begin
|
105
|
-
user_keys = iam_client.list_access_keys(user_name: username)
|
106
|
-
.access_key_metadata
|
107
|
-
user_keys = user_keys.map do |metadata|
|
108
|
-
{
|
109
|
-
access_key_id: metadata.access_key_id,
|
110
|
-
username: username,
|
111
|
-
status: metadata.status,
|
112
|
-
create_date: metadata.create_date, # DateTime.parse(metadata.create_date),
|
113
|
-
}
|
114
|
-
end
|
115
104
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
105
|
+
user_keys = iam_client.list_access_keys(user_name: username)
|
106
|
+
.access_key_metadata
|
107
|
+
user_keys = user_keys.map do |metadata|
|
108
|
+
{
|
109
|
+
access_key_id: metadata.access_key_id,
|
110
|
+
username: username,
|
111
|
+
status: metadata.status,
|
112
|
+
create_date: metadata.create_date, # DateTime.parse(metadata.create_date),
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
# Copy in from user data
|
117
|
+
# Synthetics
|
118
|
+
user_keys.each do |key_info|
|
119
|
+
add_synthetic_fields(key_info, user_details[username])
|
124
120
|
end
|
121
|
+
access_key_data.concat(user_keys)
|
122
|
+
rescue Aws::IAM::Errors::NoSuchEntity # rubocop:disable Lint/HandleExceptions
|
123
|
+
# Swallow - a miss on search results should return an empty table
|
124
|
+
|
125
125
|
end
|
126
126
|
access_key_data
|
127
127
|
end
|
@@ -20,19 +20,19 @@ class AwsIamPasswordPolicy < Inspec.resource(1)
|
|
20
20
|
# TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
|
21
21
|
def initialize(conn = nil)
|
22
22
|
catch_aws_errors do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
34
|
-
@policy = nil
|
23
|
+
|
24
|
+
if conn
|
25
|
+
# We're in a mocked unit test.
|
26
|
+
@policy = conn.iam_resource.account_password_policy
|
27
|
+
else
|
28
|
+
# Don't use the resource approach. It's a CRUD operation
|
29
|
+
# - if the policy does not exist, you get back a blank object to populate and save.
|
30
|
+
# Using the Client will throw an exception if no policy exists.
|
31
|
+
@policy = inspec_runner.backend.aws_client(Aws::IAM::Client).get_account_password_policy.password_policy
|
35
32
|
end
|
33
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
34
|
+
@policy = nil
|
35
|
+
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -56,30 +56,30 @@ class AwsKmsKey < Inspec.resource(1)
|
|
56
56
|
|
57
57
|
query = { key_id: @key_id }
|
58
58
|
catch_aws_errors do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
59
|
+
|
60
|
+
resp = backend.describe_key(query)
|
61
|
+
|
62
|
+
@exists = true
|
63
|
+
@key = resp.key_metadata.to_h
|
64
|
+
@key_id = @key[:key_id]
|
65
|
+
@arn = @key[:arn]
|
66
|
+
@creation_date = @key[:creation_date]
|
67
|
+
@enabled = @key[:enabled]
|
68
|
+
@description = @key[:description]
|
69
|
+
@key_usage = @key[:key_usage]
|
70
|
+
@key_state = @key[:key_state]
|
71
|
+
@deletion_date = @key[:deletion_date]
|
72
|
+
@valid_to = @key[:valid_to]
|
73
|
+
@external = @key[:origin] == "EXTERNAL"
|
74
|
+
@has_key_expiration = @key[:expiration_model] == "KEY_MATERIAL_EXPIRES"
|
75
|
+
@managed_by_aws = @key[:key_manager] == "AWS"
|
76
|
+
|
77
|
+
resp = backend.get_key_rotation_status(query)
|
78
|
+
@has_rotation_enabled = resp.key_rotation_enabled unless resp.empty?
|
79
|
+
rescue Aws::KMS::Errors::NotFoundException
|
80
|
+
@exists = false
|
81
|
+
return
|
82
|
+
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -43,13 +43,13 @@ class AwsRdsInstance < Inspec.resource(1)
|
|
43
43
|
backend = BackendFactory.create(inspec_runner)
|
44
44
|
dsg_response = nil
|
45
45
|
catch_aws_errors do
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
|
47
|
+
dsg_response = backend.describe_db_instances(db_instance_identifier: db_instance_identifier)
|
48
|
+
@exists = true
|
49
|
+
rescue Aws::RDS::Errors::DBInstanceNotFound
|
50
|
+
@exists = false
|
51
|
+
return
|
52
|
+
|
53
53
|
end
|
54
54
|
|
55
55
|
if dsg_response.db_instances.empty?
|
@@ -85,30 +85,29 @@ class AwsS3Bucket < Inspec.resource(1)
|
|
85
85
|
def fetch_bucket_policy
|
86
86
|
backend = BackendFactory.create(inspec_runner)
|
87
87
|
catch_aws_errors do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
rescue Aws::S3::Errors::NoSuchBucketPolicy
|
97
|
-
@bucket_policy = []
|
88
|
+
|
89
|
+
# AWS SDK returns a StringIO, we have to read()
|
90
|
+
raw_policy = backend.get_bucket_policy(bucket: bucket_name).policy
|
91
|
+
return JSON.parse(raw_policy.read)["Statement"].map do |statement|
|
92
|
+
lowercase_hash = {}
|
93
|
+
statement.each_key { |k| lowercase_hash[k.downcase] = statement[k] }
|
94
|
+
@bucket_policy = OpenStruct.new(lowercase_hash)
|
98
95
|
end
|
96
|
+
rescue Aws::S3::Errors::NoSuchBucketPolicy
|
97
|
+
@bucket_policy = []
|
98
|
+
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
def fetch_bucket_encryption_configuration
|
103
103
|
@has_default_encryption_enabled ||= catch_aws_errors do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
104
|
+
!BackendFactory.create(inspec_runner)
|
105
|
+
.get_bucket_encryption(bucket: bucket_name)
|
106
|
+
.server_side_encryption_configuration
|
107
|
+
.nil?
|
108
|
+
rescue Aws::S3::Errors::ServerSideEncryptionConfigurationNotFoundError
|
109
|
+
false
|
110
|
+
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
@@ -55,16 +55,16 @@ class AwsS3BucketObject < Inspec.resource(1)
|
|
55
55
|
def fetch_from_api
|
56
56
|
backend = BackendFactory.create(inspec_runner)
|
57
57
|
catch_aws_errors do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
58
|
+
|
59
|
+
# Just use get_object to detect if the bucket exists
|
60
|
+
backend.get_object(bucket: bucket_name, key: key)
|
61
|
+
rescue Aws::S3::Errors::NoSuchBucket
|
62
|
+
@exists = false
|
63
|
+
return
|
64
|
+
rescue Aws::S3::Errors::NoSuchKey
|
65
|
+
@exists = false
|
66
|
+
return
|
67
|
+
|
68
68
|
end
|
69
69
|
@exists = true
|
70
70
|
end
|
@@ -53,19 +53,19 @@ class AwsSnsSubscription < Inspec.resource(1)
|
|
53
53
|
def fetch_from_api
|
54
54
|
backend = BackendFactory.create(inspec_runner)
|
55
55
|
catch_aws_errors do
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
56
|
+
|
57
|
+
aws_response = backend.get_subscription_attributes(subscription_arn: @subscription_arn).attributes
|
58
|
+
@exists = true
|
59
|
+
@owner = aws_response["Owner"]
|
60
|
+
@raw_message_delivery = aws_response["RawMessageDelivery"].eql?("true")
|
61
|
+
@topic_arn = aws_response["TopicArn"]
|
62
|
+
@endpoint = aws_response["Endpoint"]
|
63
|
+
@protocol = aws_response["Protocol"]
|
64
|
+
@confirmation_was_authenticated = aws_response["ConfirmationWasAuthenticated"].eql?("true")
|
65
|
+
rescue Aws::SNS::Errors::NotFound
|
66
|
+
@exists = false
|
67
|
+
return
|
68
|
+
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.37.23
|
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-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inspec-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.
|
19
|
+
version: 4.37.23
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.
|
26
|
+
version: 4.37.23
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: train
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|