inspec 4.56.19 → 5.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/inspec.gemspec +4 -1
  3. data/lib/plugins/inspec-artifact/inspec-artifact.gemspec +9 -0
  4. data/lib/plugins/inspec-compliance/inspec-compliance.gemspec +9 -0
  5. data/lib/plugins/inspec-habitat/inspec-habitat.gemspec +9 -0
  6. data/lib/plugins/inspec-init/inspec-init.gemspec +9 -0
  7. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
  8. data/lib/plugins/inspec-plugin-manager-cli/inspec-plugin-manager-cli.gemspec +10 -0
  9. data/lib/plugins/inspec-reporter-html2/inspec-reporter-html2.gemspec +9 -0
  10. data/lib/plugins/inspec-reporter-json-min/inspec-reporter-json-min.gemspec +9 -0
  11. data/lib/plugins/inspec-reporter-junit/inspec-reporter-junit.gemspec +9 -0
  12. data/lib/plugins/inspec-streaming-reporter-progress-bar/inspec-streaming-reporter-progress-bar.gemspec +9 -0
  13. metadata +28 -62
  14. data/lib/resource_support/aws/aws_backend_base.rb +0 -12
  15. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +0 -12
  16. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +0 -24
  17. data/lib/resource_support/aws/aws_resource_mixin.rb +0 -69
  18. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +0 -27
  19. data/lib/resource_support/aws.rb +0 -76
  20. data/lib/resources/aws/aws_billing_report.rb +0 -105
  21. data/lib/resources/aws/aws_billing_reports.rb +0 -74
  22. data/lib/resources/aws/aws_cloudtrail_trail.rb +0 -97
  23. data/lib/resources/aws/aws_cloudtrail_trails.rb +0 -51
  24. data/lib/resources/aws/aws_cloudwatch_alarm.rb +0 -67
  25. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +0 -105
  26. data/lib/resources/aws/aws_config_delivery_channel.rb +0 -74
  27. data/lib/resources/aws/aws_config_recorder.rb +0 -99
  28. data/lib/resources/aws/aws_ebs_volume.rb +0 -127
  29. data/lib/resources/aws/aws_ebs_volumes.rb +0 -69
  30. data/lib/resources/aws/aws_ec2_instance.rb +0 -162
  31. data/lib/resources/aws/aws_ec2_instances.rb +0 -69
  32. data/lib/resources/aws/aws_ecs_cluster.rb +0 -87
  33. data/lib/resources/aws/aws_eks_cluster.rb +0 -105
  34. data/lib/resources/aws/aws_elb.rb +0 -85
  35. data/lib/resources/aws/aws_elbs.rb +0 -84
  36. data/lib/resources/aws/aws_flow_log.rb +0 -106
  37. data/lib/resources/aws/aws_iam_access_key.rb +0 -112
  38. data/lib/resources/aws/aws_iam_access_keys.rb +0 -153
  39. data/lib/resources/aws/aws_iam_group.rb +0 -62
  40. data/lib/resources/aws/aws_iam_groups.rb +0 -56
  41. data/lib/resources/aws/aws_iam_password_policy.rb +0 -121
  42. data/lib/resources/aws/aws_iam_policies.rb +0 -57
  43. data/lib/resources/aws/aws_iam_policy.rb +0 -311
  44. data/lib/resources/aws/aws_iam_role.rb +0 -60
  45. data/lib/resources/aws/aws_iam_root_user.rb +0 -82
  46. data/lib/resources/aws/aws_iam_user.rb +0 -145
  47. data/lib/resources/aws/aws_iam_users.rb +0 -160
  48. data/lib/resources/aws/aws_kms_key.rb +0 -100
  49. data/lib/resources/aws/aws_kms_keys.rb +0 -58
  50. data/lib/resources/aws/aws_rds_instance.rb +0 -74
  51. data/lib/resources/aws/aws_route_table.rb +0 -67
  52. data/lib/resources/aws/aws_route_tables.rb +0 -64
  53. data/lib/resources/aws/aws_s3_bucket.rb +0 -141
  54. data/lib/resources/aws/aws_s3_bucket_object.rb +0 -87
  55. data/lib/resources/aws/aws_s3_buckets.rb +0 -52
  56. data/lib/resources/aws/aws_security_group.rb +0 -314
  57. data/lib/resources/aws/aws_security_groups.rb +0 -71
  58. data/lib/resources/aws/aws_sns_subscription.rb +0 -82
  59. data/lib/resources/aws/aws_sns_topic.rb +0 -57
  60. data/lib/resources/aws/aws_sns_topics.rb +0 -60
  61. data/lib/resources/aws/aws_sqs_queue.rb +0 -66
  62. data/lib/resources/aws/aws_subnet.rb +0 -92
  63. data/lib/resources/aws/aws_subnets.rb +0 -56
  64. data/lib/resources/aws/aws_vpc.rb +0 -77
  65. data/lib/resources/aws/aws_vpcs.rb +0 -55
  66. data/lib/resources/azure/azure_backend.rb +0 -379
  67. data/lib/resources/azure/azure_generic_resource.rb +0 -55
  68. data/lib/resources/azure/azure_resource_group.rb +0 -151
  69. data/lib/resources/azure/azure_virtual_machine.rb +0 -262
  70. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +0 -131
@@ -1,106 +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 AwsFlowLog < Inspec.resource(1)
6
- name "aws_flow_log"
7
- supports platform: "aws"
8
- desc "This resource is used to test the attributes of a Flow Log."
9
- example <<~EXAMPLE
10
- describe aws_flow_log('fl-9c718cf5') do
11
- it { should exist }
12
- end
13
- EXAMPLE
14
-
15
- include AwsSingularResourceMixin
16
-
17
- def to_s
18
- "AWS Flow Log #{id}"
19
- end
20
-
21
- def resource_type
22
- case @resource_id
23
- when /^eni/
24
- @resource_type = "eni"
25
- when /^subnet/
26
- @resource_type = "subnet"
27
- when /^vpc/
28
- @resource_type = "vpc"
29
- end
30
- end
31
-
32
- def attached_to_eni?
33
- resource_type.eql?("eni") ? true : false
34
- end
35
-
36
- def attached_to_subnet?
37
- resource_type.eql?("subnet") ? true : false
38
- end
39
-
40
- def attached_to_vpc?
41
- resource_type.eql?("vpc") ? true : false
42
- end
43
-
44
- attr_reader :log_group_name, :resource_id, :flow_log_id
45
-
46
- private
47
-
48
- def validate_params(raw_params)
49
- validated_params = check_resource_param_names(
50
- raw_params: raw_params,
51
- allowed_params: %i{flow_log_id subnet_id vpc_id},
52
- allowed_scalar_name: :flow_log_id,
53
- allowed_scalar_type: String
54
- )
55
-
56
- if validated_params.empty?
57
- raise ArgumentError,
58
- "aws_flow_log requires a parameter: flow_log_id, subnet_id, or vpc_id"
59
- end
60
-
61
- validated_params
62
- end
63
-
64
- def fetch_from_api
65
- backend = BackendFactory.create(inspec_runner)
66
-
67
- resp = backend.describe_flow_logs(filter_args)
68
- flow_log = resp.to_h[:flow_logs].first
69
- @exists = !flow_log.nil?
70
- unless flow_log.nil?
71
- @log_group_name = flow_log[:log_group_name]
72
- @resource_id = flow_log[:resource_id]
73
- @flow_log_id = flow_log[:flow_log_id]
74
- end
75
- end
76
-
77
- def filter_args
78
- if @flow_log_id
79
- { filter: [{ name: "flow-log-id", values: [@flow_log_id] }] }
80
- elsif @subnet_id || @vpc_id
81
- filter = @subnet_id || @vpc_id
82
- { filter: [{ name: "resource-id", values: [filter] }] }
83
- end
84
- end
85
-
86
- def id
87
- return @flow_log_id if @flow_log_id
88
- return @subnet_id if @subnet_id
89
- return @vpc_id if @vpc_id
90
- end
91
-
92
- def backend
93
- BackendFactory.create(inspec_runner)
94
- end
95
-
96
- class Backend
97
- class AwsClientApi < AwsBackendBase
98
- AwsFlowLog::BackendFactory.set_default_backend(self)
99
- self.aws_client_class = Aws::EC2::Client
100
-
101
- def describe_flow_logs(query)
102
- aws_service_client.describe_flow_logs(query)
103
- end
104
- end
105
- end
106
- end
@@ -1,112 +0,0 @@
1
- require "resource_support/aws/aws_singular_resource_mixin"
2
- require "resource_support/aws/aws_backend_base"
3
- require "aws-sdk-iam"
4
-
5
- class AwsIamAccessKey < Inspec.resource(1)
6
- name "aws_iam_access_key"
7
- desc "Verifies settings for an individual IAM access key"
8
- example <<~EXAMPLE
9
- describe aws_iam_access_key(username: 'username', id: 'access-key id') do
10
- it { should exist }
11
- it { should_not be_active }
12
- its('create_date') { should be > Time.now - 365 * 86400 }
13
- its('last_used_date') { should be > Time.now - 90 * 86400 }
14
- end
15
- EXAMPLE
16
- supports platform: "aws"
17
-
18
- include AwsSingularResourceMixin
19
- attr_reader :access_key_id, :create_date, :status, :username
20
- alias id access_key_id
21
-
22
- def validate_params(raw_params)
23
- recognized_params = check_resource_param_names(
24
- raw_params: raw_params,
25
- allowed_params: %i{username id access_key_id},
26
- allowed_scalar_name: :access_key_id,
27
- allowed_scalar_type: String
28
- )
29
-
30
- # id and access_key_id are aliases; standardize on access_key_id
31
- recognized_params[:access_key_id] = recognized_params.delete(:id) if recognized_params.key?(:id)
32
-
33
- # Validate format of access_key_id
34
- if recognized_params[:access_key_id] &&
35
- recognized_params[:access_key_id] !~ (/^AKIA[0-9A-Z]{16}$/)
36
- raise ArgumentError, "Incorrect format for Access Key ID - expected AKIA followed " \
37
- "by 16 letters or numbers"
38
- end
39
-
40
- # One of username and access_key_id is required
41
- if recognized_params[:username].nil? && recognized_params[:access_key_id].nil?
42
- raise ArgumentError, "You must provide at lease one of access_key_id or username to aws_iam_access_key"
43
- end
44
-
45
- recognized_params
46
- end
47
-
48
- def active?
49
- return nil unless exists?
50
-
51
- status == "Active"
52
- end
53
-
54
- def to_s
55
- "IAM Access-Key #{access_key_id}"
56
- end
57
-
58
- def last_used_date
59
- return nil unless exists?
60
- return @last_used_date if defined? @last_used_date
61
-
62
- backend = BackendFactory.create(inspec_runner)
63
- catch_aws_errors do
64
- @last_used_date = backend.get_access_key_last_used({ access_key_id: access_key_id }).access_key_last_used.last_used_date
65
- end
66
- end
67
-
68
- def fetch_from_api
69
- backend = BackendFactory.create(inspec_runner)
70
- query = {}
71
- query[:user_name] = username if username
72
-
73
- response = backend.list_access_keys(query)
74
-
75
- access_keys = response.access_key_metadata.select do |key|
76
- if access_key_id
77
- key.access_key_id == access_key_id
78
- else
79
- true
80
- end
81
- end
82
-
83
- if access_keys.empty?
84
- @exists = false
85
- return
86
- end
87
-
88
- if access_keys.count > 1
89
- raise "More than one access key matched for aws_iam_access_key. Use more specific parameters, such as access_key_id."
90
- end
91
-
92
- @exists = true
93
- @access_key_id = access_keys[0].access_key_id
94
- @username = access_keys[0].user_name
95
- @create_date = access_keys[0].create_date
96
- @status = access_keys[0].status
97
- # Last used date is lazily loaded, separate API call
98
- rescue Aws::IAM::Errors::NoSuchEntity
99
- @exists = false
100
- end
101
-
102
- class Backend
103
- class AwsClientApi < AwsBackendBase
104
- BackendFactory.set_default_backend(self)
105
- self.aws_client_class = Aws::IAM::Client
106
-
107
- def list_access_keys(query)
108
- aws_service_client.list_access_keys(query)
109
- end
110
- end
111
- end
112
- end
@@ -1,153 +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 AwsIamAccessKeys < Inspec.resource(1)
6
- name "aws_iam_access_keys"
7
- desc "Verifies settings for AWS IAM Access Keys in bulk"
8
- example <<~EXAMPLE
9
- describe aws_iam_access_keys do
10
- it { should_not exist }
11
- end
12
- EXAMPLE
13
- supports platform: "aws"
14
-
15
- include AwsPluralResourceMixin
16
-
17
- def validate_params(raw_params)
18
- recognized_params = check_resource_param_names(
19
- raw_params: raw_params,
20
- allowed_params: %i{username id access_key_id created_date},
21
- allowed_scalar_name: :access_key_id,
22
- allowed_scalar_type: String
23
- )
24
-
25
- # id and access_key_id are aliases; standardize on access_key_id
26
- recognized_params[:access_key_id] = recognized_params.delete(:id) if recognized_params.key?(:id)
27
- if recognized_params[:access_key_id] &&
28
- recognized_params[:access_key_id] !~ (/^AKIA[0-9A-Z]{16}$/)
29
- raise "Incorrect format for Access Key ID - expected AKIA followed " \
30
- "by 16 letters or numbers"
31
- end
32
-
33
- recognized_params
34
- end
35
-
36
- def fetch_from_api
37
- # TODO: this interface should be normalized to match the AWS API
38
- criteria = {}
39
- criteria[:username] = @username if defined? @username
40
- @table = BackendFactory.create(inspec_runner).fetch(criteria)
41
- end
42
-
43
- # Underlying FilterTable implementation.
44
- filter = FilterTable.create
45
- filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
46
- filter.register_column(:access_key_ids, field: :access_key_id)
47
- .register_column(:created_date, field: :create_date)
48
- .register_column(:created_days_ago, field: :created_days_ago)
49
- .register_column(:created_with_user, field: :created_with_user)
50
- .register_column(:created_hours_ago, field: :created_hours_ago)
51
- .register_column(:usernames, field: :username)
52
- .register_column(:active, field: :active)
53
- .register_column(:inactive, field: :inactive)
54
- .register_column(:last_used_date, field: :last_used_date)
55
- .register_column(:last_used_hours_ago, field: :last_used_hours_ago)
56
- .register_column(:last_used_days_ago, field: :last_used_days_ago)
57
- .register_column(:ever_used, field: :ever_used)
58
- .register_column(:never_used, field: :never_used)
59
- .register_column(:user_created_date, field: :user_created_date)
60
- filter.install_filter_methods_on_resource(self, :table)
61
-
62
- def to_s
63
- "IAM Access Keys"
64
- end
65
-
66
- # Internal support class. This is used to fetch
67
- # the users and access keys. We have an abstract
68
- # class with a concrete AWS implementation provided here;
69
- # a few mock implementations are also provided in the unit tests.
70
- class Backend
71
- # Implementation of AccessKeyProvider which operates by looping over
72
- # all users, then fetching their access keys.
73
- # TODO: An alternate, more scalable implementation could be made
74
- # using the Credential Report.
75
- class AwsUserIterator < AwsBackendBase
76
- BackendFactory.set_default_backend(self)
77
- self.aws_client_class = Aws::IAM::Client
78
-
79
- def fetch(criteria)
80
- iam_client = aws_service_client
81
-
82
- user_details = {}
83
- if criteria.key?(:username)
84
- begin
85
- user_details[criteria[:username]] = iam_client.get_user(user_name: criteria[:username]).user
86
- rescue Aws::IAM::Errors::NoSuchEntity # rubocop:disable Lint/HandleExceptions
87
- # Swallow - a miss on search results should return an empty table
88
- end
89
- else
90
- pagination_opts = {}
91
- loop do
92
- api_result = iam_client.list_users(pagination_opts)
93
- api_result.users.each do |info|
94
- user_details[info.user_name] = info
95
- end
96
- break unless api_result.is_truncated
97
-
98
- pagination_opts[:marker] = api_result.marker
99
- end
100
- end
101
-
102
- access_key_data = []
103
- user_details.each_key do |username|
104
-
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])
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
- end
126
- access_key_data
127
- end
128
-
129
- def add_synthetic_fields(key_info, user_details) # rubocop:disable Metrics/AbcSize
130
- key_info[:id] = key_info[:access_key_id]
131
- key_info[:active] = key_info[:status] == "Active"
132
- key_info[:inactive] = key_info[:status] != "Active"
133
- key_info[:created_hours_ago] = ((Time.now - key_info[:create_date]) / (60 * 60)).to_i
134
- key_info[:created_days_ago] = (key_info[:created_hours_ago] / 24).to_i
135
- key_info[:user_created_date] = user_details[:create_date]
136
- key_info[:created_with_user] = (key_info[:create_date] - key_info[:user_created_date]).abs < 1.0 / 24.0
137
-
138
- # Last used is a separate API call
139
- iam_client = aws_service_client
140
- last_used =
141
- iam_client.get_access_key_last_used(access_key_id: key_info[:access_key_id])
142
- .access_key_last_used.last_used_date
143
- key_info[:ever_used] = !last_used.nil?
144
- key_info[:never_used] = last_used.nil?
145
- key_info[:last_used_time] = last_used
146
- return unless last_used
147
-
148
- key_info[:last_used_hours_ago] = ((Time.now - last_used) / (60 * 60)).to_i
149
- key_info[:last_used_days_ago] = (key_info[:last_used_hours_ago] / 24).to_i
150
- end
151
- end
152
- end
153
- end
@@ -1,62 +0,0 @@
1
- require "resource_support/aws/aws_singular_resource_mixin"
2
- require "resource_support/aws/aws_backend_base"
3
- require "aws-sdk-iam"
4
-
5
- class AwsIamGroup < Inspec.resource(1)
6
- name "aws_iam_group"
7
- desc "Verifies settings for AWS IAM Group"
8
- example <<~EXAMPLE
9
- describe aws_iam_group('mygroup') do
10
- it { should exist }
11
- end
12
- EXAMPLE
13
- supports platform: "aws"
14
-
15
- include AwsSingularResourceMixin
16
- attr_reader :group_name, :users
17
-
18
- def to_s
19
- "IAM Group #{group_name}"
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: [:group_name],
28
- allowed_scalar_name: :group_name,
29
- allowed_scalar_type: String
30
- )
31
-
32
- if validated_params.empty?
33
- raise ArgumentError, "You must provide a group_name to aws_iam_group."
34
- end
35
-
36
- validated_params
37
- end
38
-
39
- def fetch_from_api
40
- backend = AwsIamGroup::BackendFactory.create(inspec_runner)
41
-
42
- begin
43
- resp = backend.get_group(group_name: group_name)
44
- @exists = true
45
- @aws_group_struct = resp[:group]
46
- @users = resp[:users].map(&:user_name)
47
- rescue Aws::IAM::Errors::NoSuchEntity
48
- @exists = false
49
- end
50
- end
51
-
52
- class Backend
53
- class AwsClientApi < AwsBackendBase
54
- BackendFactory.set_default_backend(self)
55
- self.aws_client_class = Aws::IAM::Client
56
-
57
- def get_group(query)
58
- aws_service_client.get_group(query)
59
- end
60
- end
61
- end
62
- end
@@ -1,56 +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 AwsIamGroups < Inspec.resource(1)
6
- name "aws_iam_groups"
7
- desc "Verifies settings for AWS IAM groups in bulk"
8
- example <<~EXAMPLE
9
- describe aws_iam_groups do
10
- it { should exist }
11
- end
12
- EXAMPLE
13
- supports platform: "aws"
14
-
15
- include AwsPluralResourceMixin
16
-
17
- def validate_params(resource_params)
18
- unless resource_params.empty?
19
- raise ArgumentError, "aws_iam_groups does not accept resource parameters."
20
- end
21
-
22
- resource_params
23
- end
24
-
25
- # Underlying FilterTable implementation.
26
- filter = FilterTable.create
27
- filter.register_column(:group_names, field: :group_name)
28
- filter.install_filter_methods_on_resource(self, :table)
29
-
30
- def to_s
31
- "IAM Groups"
32
- end
33
-
34
- def fetch_from_api
35
- backend = BackendFactory.create(inspec_runner)
36
- @table = []
37
- pagination_opts = {}
38
- loop do
39
- api_result = backend.list_groups(pagination_opts)
40
- @table += api_result.groups.map(&:to_h)
41
- pagination_opts = { marker: api_result.marker }
42
- break unless api_result.is_truncated
43
- end
44
- end
45
-
46
- class Backend
47
- class AwsClientApi < AwsBackendBase
48
- BackendFactory.set_default_backend(self)
49
- self.aws_client_class = Aws::IAM::Client
50
-
51
- def list_groups(query = {})
52
- aws_service_client.list_groups(query)
53
- end
54
- end
55
- end
56
- end
@@ -1,121 +0,0 @@
1
- require "resource_support/aws/aws_singular_resource_mixin"
2
- require "resource_support/aws/aws_backend_base"
3
- require "aws-sdk-iam"
4
-
5
- class AwsIamPasswordPolicy < Inspec.resource(1)
6
- name "aws_iam_password_policy"
7
- desc "Verifies iam password policy"
8
-
9
- example <<~EXAMPLE
10
- describe aws_iam_password_policy do
11
- its('requires_lowercase_characters?') { should be true }
12
- end
13
-
14
- describe aws_iam_password_policy do
15
- its('requires_uppercase_characters?') { should be true }
16
- end
17
- EXAMPLE
18
- supports platform: "aws"
19
-
20
- # TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
21
- def initialize(conn = nil)
22
- catch_aws_errors do
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
32
- end
33
- rescue Aws::IAM::Errors::NoSuchEntity
34
- @policy = nil
35
-
36
- end
37
- end
38
-
39
- # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
40
- # Copied from resource_support/aws/aws_resource_mixin.rb
41
- def catch_aws_errors
42
- yield
43
- rescue Aws::Errors::MissingCredentialsError
44
- # The AWS error here is unhelpful:
45
- # "unable to sign request without credentials set"
46
- Inspec::Log.error "It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://docs.chef.io/inspec/platforms/ for details."
47
- fail_resource("No AWS credentials available")
48
- rescue Aws::Errors::ServiceError => e
49
- fail_resource e.message
50
- end
51
-
52
- # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
53
- # Copied from resource_support/aws/aws_singular_resource_mixin.rb
54
- def inspec_runner
55
- # When running under inspec-cli, we have an 'inspec' method that
56
- # returns the runner. When running under unit tests, we don't
57
- # have that, but we still have to call this to pass something
58
- # (nil is OK) to the backend.
59
- # TODO: remove with https://github.com/chef/inspec-aws/issues/216
60
- # TODO: remove after rewrite to include AwsSingularResource
61
- inspec if respond_to?(:inspec)
62
- end
63
-
64
- def to_s
65
- "IAM Password-Policy"
66
- end
67
-
68
- def exists?
69
- !@policy.nil?
70
- end
71
-
72
- #-------------------------- Properties ----------------------------#
73
-
74
- def minimum_password_length
75
- @policy.minimum_password_length
76
- end
77
-
78
- def max_password_age_in_days
79
- raise "this policy does not expire passwords" unless expire_passwords?
80
-
81
- @policy.max_password_age
82
- end
83
-
84
- def number_of_passwords_to_remember
85
- raise "this policy does not prevent password reuse" \
86
- unless prevent_password_reuse?
87
-
88
- @policy.password_reuse_prevention
89
- end
90
-
91
- #-------------------------- Matchers ----------------------------#
92
- %i{
93
- require_lowercase_characters
94
- require_uppercase_characters
95
- require_symbols
96
- require_numbers
97
- expire_passwords
98
- }.each do |matcher_stem|
99
- # Create our predicates (for example, 'require_symbols?')
100
- stem_with_question_mark = (matcher_stem.to_s + "?").to_sym
101
- define_method stem_with_question_mark do
102
- @policy.send(matcher_stem)
103
- end
104
- # RSpec will expose that as (for example) `be_require_symbols`.
105
- # To undo that, we have to make a matcher alias.
106
- stem_with_be = ("be_" + matcher_stem.to_s).to_sym
107
- RSpec::Matchers.alias_matcher matcher_stem, stem_with_be
108
- end
109
-
110
- # This one has an awkward name mapping
111
- def allow_users_to_change_passwords?
112
- @policy.allow_users_to_change_password
113
- end
114
- RSpec::Matchers.alias_matcher :allow_users_to_change_passwords, :be_allow_users_to_change_passwords
115
-
116
- # This one has custom logic and renaming
117
- def prevent_password_reuse?
118
- !@policy.password_reuse_prevention.nil?
119
- end
120
- RSpec::Matchers.alias_matcher :prevent_password_reuse, :be_prevent_password_reuse
121
- end
@@ -1,57 +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 AwsIamPolicies < Inspec.resource(1)
6
- name "aws_iam_policies"
7
- desc "Verifies settings for AWS IAM Policies in bulk"
8
- example <<~EXAMPLE
9
- describe aws_iam_policies 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_iam_policies 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(:policy_names, field: :policy_name)
28
- .register_column(:arns, field: :arn)
29
- filter.install_filter_methods_on_resource(self, :table)
30
-
31
- def to_s
32
- "IAM Policies"
33
- end
34
-
35
- def fetch_from_api
36
- backend = BackendFactory.create(inspec_runner)
37
- @table = []
38
- pagination_opts = {}
39
- loop do
40
- api_result = backend.list_policies(pagination_opts)
41
- @table += api_result.policies.map(&:to_h)
42
- pagination_opts = { marker: api_result.marker }
43
- break unless api_result.is_truncated
44
- end
45
- end
46
-
47
- class Backend
48
- class AwsClientApi < AwsBackendBase
49
- BackendFactory.set_default_backend(self)
50
- self.aws_client_class = Aws::IAM::Client
51
-
52
- def list_policies(query)
53
- aws_service_client.list_policies(query)
54
- end
55
- end
56
- end
57
- end