inspec 4.56.58 → 5.7.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +24 -9
- data/inspec.gemspec +5 -2
- data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
- metadata +21 -64
- data/lib/resource_support/aws/aws_backend_base.rb +0 -12
- data/lib/resource_support/aws/aws_backend_factory_mixin.rb +0 -12
- data/lib/resource_support/aws/aws_plural_resource_mixin.rb +0 -24
- data/lib/resource_support/aws/aws_resource_mixin.rb +0 -69
- data/lib/resource_support/aws/aws_singular_resource_mixin.rb +0 -27
- data/lib/resource_support/aws.rb +0 -76
- data/lib/resources/aws/aws_billing_report.rb +0 -105
- data/lib/resources/aws/aws_billing_reports.rb +0 -74
- data/lib/resources/aws/aws_cloudtrail_trail.rb +0 -97
- data/lib/resources/aws/aws_cloudtrail_trails.rb +0 -51
- data/lib/resources/aws/aws_cloudwatch_alarm.rb +0 -67
- data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +0 -105
- data/lib/resources/aws/aws_config_delivery_channel.rb +0 -74
- data/lib/resources/aws/aws_config_recorder.rb +0 -99
- data/lib/resources/aws/aws_ebs_volume.rb +0 -127
- data/lib/resources/aws/aws_ebs_volumes.rb +0 -69
- data/lib/resources/aws/aws_ec2_instance.rb +0 -162
- data/lib/resources/aws/aws_ec2_instances.rb +0 -69
- data/lib/resources/aws/aws_ecs_cluster.rb +0 -87
- data/lib/resources/aws/aws_eks_cluster.rb +0 -105
- data/lib/resources/aws/aws_elb.rb +0 -85
- data/lib/resources/aws/aws_elbs.rb +0 -84
- data/lib/resources/aws/aws_flow_log.rb +0 -106
- data/lib/resources/aws/aws_iam_access_key.rb +0 -112
- data/lib/resources/aws/aws_iam_access_keys.rb +0 -153
- data/lib/resources/aws/aws_iam_group.rb +0 -62
- data/lib/resources/aws/aws_iam_groups.rb +0 -56
- data/lib/resources/aws/aws_iam_password_policy.rb +0 -121
- data/lib/resources/aws/aws_iam_policies.rb +0 -57
- data/lib/resources/aws/aws_iam_policy.rb +0 -311
- data/lib/resources/aws/aws_iam_role.rb +0 -60
- data/lib/resources/aws/aws_iam_root_user.rb +0 -82
- data/lib/resources/aws/aws_iam_user.rb +0 -145
- data/lib/resources/aws/aws_iam_users.rb +0 -160
- data/lib/resources/aws/aws_kms_key.rb +0 -100
- data/lib/resources/aws/aws_kms_keys.rb +0 -58
- data/lib/resources/aws/aws_rds_instance.rb +0 -74
- data/lib/resources/aws/aws_route_table.rb +0 -67
- data/lib/resources/aws/aws_route_tables.rb +0 -64
- data/lib/resources/aws/aws_s3_bucket.rb +0 -141
- data/lib/resources/aws/aws_s3_bucket_object.rb +0 -87
- data/lib/resources/aws/aws_s3_buckets.rb +0 -52
- data/lib/resources/aws/aws_security_group.rb +0 -314
- data/lib/resources/aws/aws_security_groups.rb +0 -71
- data/lib/resources/aws/aws_sns_subscription.rb +0 -82
- data/lib/resources/aws/aws_sns_topic.rb +0 -57
- data/lib/resources/aws/aws_sns_topics.rb +0 -60
- data/lib/resources/aws/aws_sqs_queue.rb +0 -66
- data/lib/resources/aws/aws_subnet.rb +0 -92
- data/lib/resources/aws/aws_subnets.rb +0 -56
- data/lib/resources/aws/aws_vpc.rb +0 -77
- data/lib/resources/aws/aws_vpcs.rb +0 -55
- data/lib/resources/azure/azure_backend.rb +0 -379
- data/lib/resources/azure/azure_generic_resource.rb +0 -55
- data/lib/resources/azure/azure_resource_group.rb +0 -151
- data/lib/resources/azure/azure_virtual_machine.rb +0 -262
- data/lib/resources/azure/azure_virtual_machine_data_disk.rb +0 -131
@@ -1,160 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_plural_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-iam"
|
4
|
-
|
5
|
-
class AwsIamUsers < Inspec.resource(1)
|
6
|
-
name "aws_iam_users"
|
7
|
-
desc "Verifies settings for AWS IAM users"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_iam_users.where(has_mfa_enabled?: false) do
|
10
|
-
it { should_not exist }
|
11
|
-
end
|
12
|
-
describe aws_iam_users.where(has_console_password?: true) do
|
13
|
-
it { should exist }
|
14
|
-
end
|
15
|
-
describe aws_iam_users.where(has_inline_policies?: true) do
|
16
|
-
it { should_not exist }
|
17
|
-
end
|
18
|
-
describe aws_iam_users.where(has_attached_policies?: true) do
|
19
|
-
it { should_not exist }
|
20
|
-
end
|
21
|
-
EXAMPLE
|
22
|
-
supports platform: "aws"
|
23
|
-
|
24
|
-
include AwsPluralResourceMixin
|
25
|
-
|
26
|
-
def self.lazy_get_login_profile(row, _criterion, table)
|
27
|
-
backend = BackendFactory.create(table.resource.inspec_runner)
|
28
|
-
begin
|
29
|
-
_login_profile = backend.get_login_profile(user_name: row[:user_name])
|
30
|
-
row[:has_console_password] = true
|
31
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
32
|
-
row[:has_console_password] = false
|
33
|
-
end
|
34
|
-
row[:has_console_password?] = row[:has_console_password]
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.lazy_list_mfa_devices(row, _criterion, table)
|
38
|
-
backend = BackendFactory.create(table.resource.inspec_runner)
|
39
|
-
begin
|
40
|
-
aws_mfa_devices = backend.list_mfa_devices(user_name: row[:user_name])
|
41
|
-
row[:has_mfa_enabled] = !aws_mfa_devices.mfa_devices.empty?
|
42
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
43
|
-
row[:has_mfa_enabled] = false
|
44
|
-
end
|
45
|
-
row[:has_mfa_enabled?] = row[:has_mfa_enabled]
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.lazy_list_user_policies(row, _criterion, table)
|
49
|
-
backend = BackendFactory.create(table.resource.inspec_runner)
|
50
|
-
row[:inline_policy_names] = backend.list_user_policies(user_name: row[:user_name]).policy_names
|
51
|
-
row[:has_inline_policies] = !row[:inline_policy_names].empty?
|
52
|
-
row[:has_inline_policies?] = row[:has_inline_policies]
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.lazy_list_attached_policies(row, _criterion, table)
|
56
|
-
backend = BackendFactory.create(table.resource.inspec_runner)
|
57
|
-
attached_policies = backend.list_attached_user_policies(user_name: row[:user_name]).attached_policies
|
58
|
-
row[:has_attached_policies] = !attached_policies.empty?
|
59
|
-
row[:has_attached_policies?] = row[:has_attached_policies]
|
60
|
-
row[:attached_policy_names] = attached_policies.map { |p| p[:policy_name] }
|
61
|
-
row[:attached_policy_arns] = attached_policies.map { |p| p[:policy_arn] }
|
62
|
-
end
|
63
|
-
|
64
|
-
filter = FilterTable.create
|
65
|
-
|
66
|
-
# These are included on the initial fetch
|
67
|
-
filter.register_column(:usernames, field: :user_name)
|
68
|
-
.register_column(:username) { |res| res.entries.map { |row| row[:user_name] } } # We should deprecate this; plural resources get plural properties
|
69
|
-
.register_column(:password_ever_used?, field: :password_ever_used?)
|
70
|
-
.register_column(:password_never_used?, field: :password_never_used?)
|
71
|
-
.register_column(:password_last_used_days_ago, field: :password_last_used_days_ago)
|
72
|
-
|
73
|
-
# Remaining properties / criteria are handled lazily, grouped by fetcher
|
74
|
-
filter.register_column(:has_console_password?, field: :has_console_password?, lazy: method(:lazy_get_login_profile))
|
75
|
-
.register_column(:has_console_password, field: :has_console_password, lazy: method(:lazy_get_login_profile))
|
76
|
-
|
77
|
-
filter.register_column(:has_mfa_enabled?, field: :has_mfa_enabled?, lazy: method(:lazy_list_mfa_devices))
|
78
|
-
.register_column(:has_mfa_enabled, field: :has_mfa_enabled, lazy: method(:lazy_list_mfa_devices))
|
79
|
-
|
80
|
-
filter.register_column(:has_inline_policies?, field: :has_inline_policies?, lazy: method(:lazy_list_user_policies))
|
81
|
-
.register_column(:has_inline_policies, field: :has_inline_policies, lazy: method(:lazy_list_user_policies))
|
82
|
-
.register_column(:inline_policy_names, field: :inline_policy_names, style: :simple, lazy: method(:lazy_list_user_policies))
|
83
|
-
|
84
|
-
filter.register_column(:has_attached_policies?, field: :has_attached_policies?, lazy: method(:lazy_list_attached_policies))
|
85
|
-
.register_column(:has_attached_policies, field: :has_attached_policies, lazy: method(:lazy_list_attached_policies))
|
86
|
-
.register_column(:attached_policy_names, field: :attached_policy_names, style: :simple, lazy: method(:lazy_list_attached_policies))
|
87
|
-
.register_column(:attached_policy_arns, field: :attached_policy_arns, style: :simple, lazy: method(:lazy_list_attached_policies))
|
88
|
-
filter.install_filter_methods_on_resource(self, :table)
|
89
|
-
|
90
|
-
def validate_params(raw_params)
|
91
|
-
# No params yet
|
92
|
-
unless raw_params.empty?
|
93
|
-
raise ArgumentError, "aws_iam_users does not accept resource parameters"
|
94
|
-
end
|
95
|
-
|
96
|
-
raw_params
|
97
|
-
end
|
98
|
-
|
99
|
-
def fetch_from_api_paginated(backend)
|
100
|
-
table = []
|
101
|
-
page_marker = nil
|
102
|
-
loop do
|
103
|
-
api_result = backend.list_users(marker: page_marker)
|
104
|
-
table += api_result.users.map(&:to_h)
|
105
|
-
page_marker = api_result.marker
|
106
|
-
break unless api_result.is_truncated
|
107
|
-
end
|
108
|
-
table
|
109
|
-
end
|
110
|
-
|
111
|
-
def fetch_from_api
|
112
|
-
backend = BackendFactory.create(inspec_runner)
|
113
|
-
@table = fetch_from_api_paginated(backend)
|
114
|
-
|
115
|
-
@table.each do |user|
|
116
|
-
password_last_used = user[:password_last_used]
|
117
|
-
user[:password_ever_used?] = !password_last_used.nil?
|
118
|
-
user[:password_never_used?] = password_last_used.nil?
|
119
|
-
if user[:password_ever_used?]
|
120
|
-
user[:password_last_used_days_ago] = ((Time.now - password_last_used) / (24 * 60 * 60)).to_i
|
121
|
-
end
|
122
|
-
end
|
123
|
-
@table
|
124
|
-
end
|
125
|
-
|
126
|
-
def to_s
|
127
|
-
"IAM Users"
|
128
|
-
end
|
129
|
-
|
130
|
-
#===========================================================================#
|
131
|
-
# Backend Implementation
|
132
|
-
#===========================================================================#
|
133
|
-
class Backend
|
134
|
-
class AwsClientApi < AwsBackendBase
|
135
|
-
BackendFactory.set_default_backend(self)
|
136
|
-
self.aws_client_class = Aws::IAM::Client
|
137
|
-
|
138
|
-
# TODO: delegate this out
|
139
|
-
def list_users(query = {})
|
140
|
-
aws_service_client.list_users(query)
|
141
|
-
end
|
142
|
-
|
143
|
-
def get_login_profile(query)
|
144
|
-
aws_service_client.get_login_profile(query)
|
145
|
-
end
|
146
|
-
|
147
|
-
def list_mfa_devices(query)
|
148
|
-
aws_service_client.list_mfa_devices(query)
|
149
|
-
end
|
150
|
-
|
151
|
-
def list_user_policies(query)
|
152
|
-
aws_service_client.list_user_policies(query)
|
153
|
-
end
|
154
|
-
|
155
|
-
def list_attached_user_policies(query)
|
156
|
-
aws_service_client.list_attached_user_policies(query)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_singular_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-kms"
|
4
|
-
|
5
|
-
class AwsKmsKey < Inspec.resource(1)
|
6
|
-
name "aws_kms_key"
|
7
|
-
desc "Verifies settings for an individual AWS KMS Key"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_kms_key('arn:aws:kms:us-east-1::key/4321dcba-21io-23de-85he-ab0987654321') do
|
10
|
-
it { should exist }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
|
14
|
-
supports platform: "aws"
|
15
|
-
|
16
|
-
include AwsSingularResourceMixin
|
17
|
-
attr_reader :key_id, :arn, :creation_date, :key_usage, :key_state, :description,
|
18
|
-
:deletion_date, :valid_to, :external, :has_key_expiration, :managed_by_aws,
|
19
|
-
:has_rotation_enabled, :enabled
|
20
|
-
# Use aliases for matchers
|
21
|
-
alias deletion_time deletion_date
|
22
|
-
alias invalidation_time valid_to
|
23
|
-
alias external? external
|
24
|
-
alias enabled? enabled
|
25
|
-
alias managed_by_aws? managed_by_aws
|
26
|
-
alias has_key_expiration? has_key_expiration
|
27
|
-
alias has_rotation_enabled? has_rotation_enabled
|
28
|
-
|
29
|
-
def to_s
|
30
|
-
"KMS Key #{@key_id}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def created_days_ago
|
34
|
-
((Time.now - creation_date) / (24 * 60 * 60)).to_i unless creation_date.nil?
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def validate_params(raw_params)
|
40
|
-
validated_params = check_resource_param_names(
|
41
|
-
raw_params: raw_params,
|
42
|
-
allowed_params: [:key_id],
|
43
|
-
allowed_scalar_name: :key_id,
|
44
|
-
allowed_scalar_type: String
|
45
|
-
)
|
46
|
-
|
47
|
-
if validated_params.empty?
|
48
|
-
raise ArgumentError, "You must provide the parameter 'key_id' to aws_kms_key."
|
49
|
-
end
|
50
|
-
|
51
|
-
validated_params
|
52
|
-
end
|
53
|
-
|
54
|
-
def fetch_from_api
|
55
|
-
backend = BackendFactory.create(inspec_runner)
|
56
|
-
|
57
|
-
query = { key_id: @key_id }
|
58
|
-
catch_aws_errors do
|
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
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class Backend
|
87
|
-
class AwsClientApi < AwsBackendBase
|
88
|
-
BackendFactory.set_default_backend(self)
|
89
|
-
self.aws_client_class = Aws::KMS::Client
|
90
|
-
|
91
|
-
def describe_key(query)
|
92
|
-
aws_service_client.describe_key(query)
|
93
|
-
end
|
94
|
-
|
95
|
-
def get_key_rotation_status(query)
|
96
|
-
aws_service_client.get_key_rotation_status(query)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_plural_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-kms"
|
4
|
-
|
5
|
-
class AwsKmsKeys < Inspec.resource(1)
|
6
|
-
name "aws_kms_keys"
|
7
|
-
desc "Verifies settings for AWS KMS Keys in bulk"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_kms_keys do
|
10
|
-
it { should exist }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
supports platform: "aws"
|
14
|
-
|
15
|
-
include AwsPluralResourceMixin
|
16
|
-
def validate_params(resource_params)
|
17
|
-
unless resource_params.empty?
|
18
|
-
raise ArgumentError, "aws_kms_keys does not accept resource parameters."
|
19
|
-
end
|
20
|
-
|
21
|
-
resource_params
|
22
|
-
end
|
23
|
-
|
24
|
-
# Underlying FilterTable implementation.
|
25
|
-
filter = FilterTable.create
|
26
|
-
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
|
27
|
-
filter.register_column(:key_arns, field: :key_arn)
|
28
|
-
.register_column(:key_ids, field: :key_id)
|
29
|
-
filter.install_filter_methods_on_resource(self, :table)
|
30
|
-
|
31
|
-
def to_s
|
32
|
-
"KMS Keys"
|
33
|
-
end
|
34
|
-
|
35
|
-
def fetch_from_api
|
36
|
-
backend = BackendFactory.create(inspec_runner)
|
37
|
-
@table = []
|
38
|
-
pagination_opts = { limit: 1000 }
|
39
|
-
loop do
|
40
|
-
api_result = backend.list_keys(pagination_opts)
|
41
|
-
@table += api_result.keys.map(&:to_h)
|
42
|
-
break unless api_result.truncated
|
43
|
-
|
44
|
-
pagination_opts = { marker: api_result.next_marker }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class Backend
|
49
|
-
class AwsClientApi < AwsBackendBase
|
50
|
-
BackendFactory.set_default_backend(self)
|
51
|
-
self.aws_client_class = Aws::KMS::Client
|
52
|
-
|
53
|
-
def list_keys(query = {})
|
54
|
-
aws_service_client.list_keys(query)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_singular_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-rds"
|
4
|
-
|
5
|
-
class AwsRdsInstance < Inspec.resource(1)
|
6
|
-
name "aws_rds_instance"
|
7
|
-
desc "Verifies settings for an rds instance"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_rds_instance(db_instance_identifier: 'test-instance-id') do
|
10
|
-
it { should exist }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
supports platform: "aws"
|
14
|
-
|
15
|
-
include AwsSingularResourceMixin
|
16
|
-
attr_reader :db_instance_identifier
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
"RDS Instance #{@db_instance_identifier}"
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def validate_params(raw_params)
|
25
|
-
validated_params = check_resource_param_names(
|
26
|
-
raw_params: raw_params,
|
27
|
-
allowed_params: [:db_instance_identifier],
|
28
|
-
allowed_scalar_name: :db_instance_identifier,
|
29
|
-
allowed_scalar_type: String
|
30
|
-
)
|
31
|
-
if validated_params.empty? || !validated_params.key?(:db_instance_identifier)
|
32
|
-
raise ArgumentError, "You must provide an id for the aws_rds_instance."
|
33
|
-
end
|
34
|
-
|
35
|
-
if validated_params.key?(:db_instance_identifier) && validated_params[:db_instance_identifier] !~ /^[a-z]{1}[0-9a-z\-]{0,62}$/
|
36
|
-
raise ArgumentError, "aws_rds_instance Database Instance ID must be in the format: start with a letter followed by up to 62 letters/numbers/hyphens."
|
37
|
-
end
|
38
|
-
|
39
|
-
validated_params
|
40
|
-
end
|
41
|
-
|
42
|
-
def fetch_from_api
|
43
|
-
backend = BackendFactory.create(inspec_runner)
|
44
|
-
dsg_response = nil
|
45
|
-
catch_aws_errors do
|
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
|
-
end
|
54
|
-
|
55
|
-
if dsg_response.db_instances.empty?
|
56
|
-
@exists = false
|
57
|
-
return
|
58
|
-
end
|
59
|
-
|
60
|
-
@db_instance_identifier = dsg_response.db_instances[0].db_instance_identifier
|
61
|
-
end
|
62
|
-
|
63
|
-
# Uses the SDK API to really talk to AWS
|
64
|
-
class Backend
|
65
|
-
class AwsClientApi < AwsBackendBase
|
66
|
-
BackendFactory.set_default_backend(self)
|
67
|
-
self.aws_client_class = Aws::RDS::Client
|
68
|
-
|
69
|
-
def describe_db_instances(query)
|
70
|
-
aws_service_client.describe_db_instances(query)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_singular_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-ec2"
|
4
|
-
|
5
|
-
class AwsRouteTable < Inspec.resource(1)
|
6
|
-
name "aws_route_table"
|
7
|
-
desc "Verifies settings for an AWS Route Table"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_route_table do
|
10
|
-
its('route_table_id') { should cmp 'rtb-05462d2278326a79c' }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
supports platform: "aws"
|
14
|
-
|
15
|
-
include AwsSingularResourceMixin
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
"Route Table #{@route_table_id}"
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_reader :route_table_id, :vpc_id
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def validate_params(raw_params)
|
26
|
-
validated_params = check_resource_param_names(
|
27
|
-
raw_params: raw_params,
|
28
|
-
allowed_params: [:route_table_id],
|
29
|
-
allowed_scalar_name: :route_table_id,
|
30
|
-
allowed_scalar_type: String
|
31
|
-
)
|
32
|
-
|
33
|
-
if validated_params.key?(:route_table_id) &&
|
34
|
-
validated_params[:route_table_id] !~ /^rtb\-([0-9a-f]{17})|(^rtb\-[0-9a-f]{8})$/
|
35
|
-
raise ArgumentError,
|
36
|
-
"aws_route_table Route Table ID must be in the" \
|
37
|
-
' format "rtb-" followed by 8 or 17 hexadecimal characters.'
|
38
|
-
end
|
39
|
-
|
40
|
-
validated_params
|
41
|
-
end
|
42
|
-
|
43
|
-
def fetch_from_api
|
44
|
-
backend = BackendFactory.create(inspec_runner)
|
45
|
-
|
46
|
-
if @route_table_id.nil?
|
47
|
-
args = nil
|
48
|
-
else
|
49
|
-
args = { filters: [{ name: "route-table-id", values: [@route_table_id] }] }
|
50
|
-
end
|
51
|
-
|
52
|
-
resp = backend.describe_route_tables(args)
|
53
|
-
routetable = resp.to_h[:route_tables]
|
54
|
-
@exists = !routetable.empty?
|
55
|
-
end
|
56
|
-
|
57
|
-
class Backend
|
58
|
-
class AwsClientApi < AwsBackendBase
|
59
|
-
BackendFactory.set_default_backend(self)
|
60
|
-
self.aws_client_class = Aws::EC2::Client
|
61
|
-
|
62
|
-
def describe_route_tables(query)
|
63
|
-
aws_service_client.describe_route_tables(query)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_plural_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-ec2"
|
4
|
-
|
5
|
-
class AwsRouteTables < Inspec.resource(1)
|
6
|
-
name "aws_route_tables"
|
7
|
-
desc "Verifies settings for AWS Route Tables in bulk"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_route_tables do
|
10
|
-
it { should exist }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
supports platform: "aws"
|
14
|
-
|
15
|
-
include AwsPluralResourceMixin
|
16
|
-
# Underlying FilterTable implementation.
|
17
|
-
filter = FilterTable.create
|
18
|
-
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
|
19
|
-
filter.register_column(:vpc_ids, field: :vpc_id)
|
20
|
-
.register_column(:route_table_ids, field: :route_table_id)
|
21
|
-
filter.install_filter_methods_on_resource(self, :routes_data)
|
22
|
-
|
23
|
-
def routes_data
|
24
|
-
@table
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_s
|
28
|
-
"Route Tables"
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def validate_params(raw_criteria)
|
34
|
-
unless raw_criteria.is_a? Hash
|
35
|
-
raise "Unrecognized criteria for fetching Route Tables. " \
|
36
|
-
"Use 'criteria: value' format."
|
37
|
-
end
|
38
|
-
|
39
|
-
# No criteria yet
|
40
|
-
unless raw_criteria.empty?
|
41
|
-
raise ArgumentError, "aws_route_tables does not currently accept resource parameters."
|
42
|
-
end
|
43
|
-
|
44
|
-
raw_criteria
|
45
|
-
end
|
46
|
-
|
47
|
-
def fetch_from_api
|
48
|
-
backend = BackendFactory.create(inspec_runner)
|
49
|
-
catch_aws_errors do
|
50
|
-
@table = backend.describe_route_tables({}).to_h[:route_tables]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class Backend
|
55
|
-
class AwsClientApi < AwsBackendBase
|
56
|
-
BackendFactory.set_default_backend self
|
57
|
-
self.aws_client_class = Aws::EC2::Client
|
58
|
-
|
59
|
-
def describe_route_tables(query = {})
|
60
|
-
aws_service_client.describe_route_tables(query)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require "resource_support/aws/aws_singular_resource_mixin"
|
2
|
-
require "resource_support/aws/aws_backend_base"
|
3
|
-
require "aws-sdk-s3"
|
4
|
-
|
5
|
-
class AwsS3Bucket < Inspec.resource(1)
|
6
|
-
name "aws_s3_bucket"
|
7
|
-
desc "Verifies settings for a s3 bucket"
|
8
|
-
example <<~EXAMPLE
|
9
|
-
describe aws_s3_bucket(bucket_name: 'test_bucket') do
|
10
|
-
it { should exist }
|
11
|
-
end
|
12
|
-
EXAMPLE
|
13
|
-
supports platform: "aws"
|
14
|
-
|
15
|
-
include AwsSingularResourceMixin
|
16
|
-
attr_reader :bucket_name, :has_default_encryption_enabled, :has_access_logging_enabled, :region
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
"S3 Bucket #{@bucket_name}"
|
20
|
-
end
|
21
|
-
|
22
|
-
def bucket_acl
|
23
|
-
catch_aws_errors do
|
24
|
-
@bucket_acl ||= BackendFactory.create(inspec_runner).get_bucket_acl(bucket: bucket_name).grants
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def bucket_policy
|
29
|
-
@bucket_policy ||= fetch_bucket_policy
|
30
|
-
end
|
31
|
-
|
32
|
-
# RSpec will alias this to be_public
|
33
|
-
def public?
|
34
|
-
# first line just for formatting
|
35
|
-
false || \
|
36
|
-
bucket_acl.any? { |g| g.grantee.type == "Group" && g.grantee.uri =~ /AllUsers/ } || \
|
37
|
-
bucket_acl.any? { |g| g.grantee.type == "Group" && g.grantee.uri =~ /AuthenticatedUsers/ } || \
|
38
|
-
bucket_policy.any? { |s| s.effect == "Allow" && s.principal == "*" }
|
39
|
-
end
|
40
|
-
|
41
|
-
def has_default_encryption_enabled?
|
42
|
-
return false unless @exists
|
43
|
-
|
44
|
-
@has_default_encryption_enabled ||= fetch_bucket_encryption_configuration
|
45
|
-
end
|
46
|
-
|
47
|
-
def has_access_logging_enabled?
|
48
|
-
return false unless @exists
|
49
|
-
|
50
|
-
catch_aws_errors do
|
51
|
-
@has_access_logging_enabled ||= !BackendFactory.create(inspec_runner).get_bucket_logging(bucket: bucket_name).logging_enabled.nil?
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def validate_params(raw_params)
|
58
|
-
validated_params = check_resource_param_names(
|
59
|
-
raw_params: raw_params,
|
60
|
-
allowed_params: [:bucket_name],
|
61
|
-
allowed_scalar_name: :bucket_name,
|
62
|
-
allowed_scalar_type: String
|
63
|
-
)
|
64
|
-
if validated_params.empty? || !validated_params.key?(:bucket_name)
|
65
|
-
raise ArgumentError, "You must provide a bucket_name to aws_s3_bucket."
|
66
|
-
end
|
67
|
-
|
68
|
-
validated_params
|
69
|
-
end
|
70
|
-
|
71
|
-
def fetch_from_api
|
72
|
-
backend = BackendFactory.create(inspec_runner)
|
73
|
-
|
74
|
-
# Since there is no basic "get_bucket" API call, use the
|
75
|
-
# region fetch as the existence check.
|
76
|
-
begin
|
77
|
-
@region = backend.get_bucket_location(bucket: bucket_name).location_constraint
|
78
|
-
rescue Aws::S3::Errors::NoSuchBucket
|
79
|
-
@exists = false
|
80
|
-
return
|
81
|
-
end
|
82
|
-
@exists = true
|
83
|
-
end
|
84
|
-
|
85
|
-
def fetch_bucket_policy
|
86
|
-
backend = BackendFactory.create(inspec_runner)
|
87
|
-
catch_aws_errors do
|
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)
|
95
|
-
end
|
96
|
-
rescue Aws::S3::Errors::NoSuchBucketPolicy
|
97
|
-
@bucket_policy = []
|
98
|
-
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def fetch_bucket_encryption_configuration
|
103
|
-
@has_default_encryption_enabled ||= catch_aws_errors do
|
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
|
-
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Uses the SDK API to really talk to AWS
|
115
|
-
class Backend
|
116
|
-
class AwsClientApi < AwsBackendBase
|
117
|
-
BackendFactory.set_default_backend(self)
|
118
|
-
self.aws_client_class = Aws::S3::Client
|
119
|
-
|
120
|
-
def get_bucket_acl(query)
|
121
|
-
aws_service_client.get_bucket_acl(query)
|
122
|
-
end
|
123
|
-
|
124
|
-
def get_bucket_location(query)
|
125
|
-
aws_service_client.get_bucket_location(query)
|
126
|
-
end
|
127
|
-
|
128
|
-
def get_bucket_policy(query)
|
129
|
-
aws_service_client.get_bucket_policy(query)
|
130
|
-
end
|
131
|
-
|
132
|
-
def get_bucket_logging(query)
|
133
|
-
aws_service_client.get_bucket_logging(query)
|
134
|
-
end
|
135
|
-
|
136
|
-
def get_bucket_encryption(query)
|
137
|
-
aws_service_client.get_bucket_encryption(query)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|