inspec 4.22.1

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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +63 -0
  3. data/inspec.gemspec +36 -0
  4. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +11 -0
  5. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +43 -0
  6. data/lib/plugins/inspec-init/templates/profiles/aws/README.md +192 -0
  7. data/lib/plugins/inspec-init/templates/profiles/aws/attributes.yml +2 -0
  8. data/lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb +39 -0
  9. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +22 -0
  10. data/lib/plugins/inspec-init/templates/profiles/azure/README.md +56 -0
  11. data/lib/plugins/inspec-init/templates/profiles/azure/controls/example.rb +14 -0
  12. data/lib/plugins/inspec-init/templates/profiles/azure/inspec.yml +14 -0
  13. data/lib/plugins/inspec-init/templates/profiles/gcp/README.md +66 -0
  14. data/lib/plugins/inspec-init/templates/profiles/gcp/attributes.yml +2 -0
  15. data/lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb +27 -0
  16. data/lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml +19 -0
  17. data/lib/resource_support/aws.rb +76 -0
  18. data/lib/resource_support/aws/aws_backend_base.rb +12 -0
  19. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -0
  20. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +24 -0
  21. data/lib/resource_support/aws/aws_resource_mixin.rb +69 -0
  22. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +27 -0
  23. data/lib/resources/aws/aws_billing_report.rb +107 -0
  24. data/lib/resources/aws/aws_billing_reports.rb +74 -0
  25. data/lib/resources/aws/aws_cloudtrail_trail.rb +97 -0
  26. data/lib/resources/aws/aws_cloudtrail_trails.rb +51 -0
  27. data/lib/resources/aws/aws_cloudwatch_alarm.rb +67 -0
  28. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +105 -0
  29. data/lib/resources/aws/aws_config_delivery_channel.rb +74 -0
  30. data/lib/resources/aws/aws_config_recorder.rb +99 -0
  31. data/lib/resources/aws/aws_ebs_volume.rb +127 -0
  32. data/lib/resources/aws/aws_ebs_volumes.rb +69 -0
  33. data/lib/resources/aws/aws_ec2_instance.rb +162 -0
  34. data/lib/resources/aws/aws_ec2_instances.rb +69 -0
  35. data/lib/resources/aws/aws_ecs_cluster.rb +88 -0
  36. data/lib/resources/aws/aws_eks_cluster.rb +105 -0
  37. data/lib/resources/aws/aws_elb.rb +85 -0
  38. data/lib/resources/aws/aws_elbs.rb +84 -0
  39. data/lib/resources/aws/aws_flow_log.rb +106 -0
  40. data/lib/resources/aws/aws_iam_access_key.rb +112 -0
  41. data/lib/resources/aws/aws_iam_access_keys.rb +153 -0
  42. data/lib/resources/aws/aws_iam_group.rb +62 -0
  43. data/lib/resources/aws/aws_iam_groups.rb +56 -0
  44. data/lib/resources/aws/aws_iam_password_policy.rb +121 -0
  45. data/lib/resources/aws/aws_iam_policies.rb +57 -0
  46. data/lib/resources/aws/aws_iam_policy.rb +311 -0
  47. data/lib/resources/aws/aws_iam_role.rb +60 -0
  48. data/lib/resources/aws/aws_iam_root_user.rb +82 -0
  49. data/lib/resources/aws/aws_iam_user.rb +145 -0
  50. data/lib/resources/aws/aws_iam_users.rb +160 -0
  51. data/lib/resources/aws/aws_kms_key.rb +100 -0
  52. data/lib/resources/aws/aws_kms_keys.rb +58 -0
  53. data/lib/resources/aws/aws_rds_instance.rb +74 -0
  54. data/lib/resources/aws/aws_route_table.rb +67 -0
  55. data/lib/resources/aws/aws_route_tables.rb +64 -0
  56. data/lib/resources/aws/aws_s3_bucket.rb +142 -0
  57. data/lib/resources/aws/aws_s3_bucket_object.rb +87 -0
  58. data/lib/resources/aws/aws_s3_buckets.rb +52 -0
  59. data/lib/resources/aws/aws_security_group.rb +314 -0
  60. data/lib/resources/aws/aws_security_groups.rb +71 -0
  61. data/lib/resources/aws/aws_sns_subscription.rb +82 -0
  62. data/lib/resources/aws/aws_sns_topic.rb +57 -0
  63. data/lib/resources/aws/aws_sns_topics.rb +60 -0
  64. data/lib/resources/aws/aws_sqs_queue.rb +66 -0
  65. data/lib/resources/aws/aws_subnet.rb +92 -0
  66. data/lib/resources/aws/aws_subnets.rb +56 -0
  67. data/lib/resources/aws/aws_vpc.rb +77 -0
  68. data/lib/resources/aws/aws_vpcs.rb +55 -0
  69. data/lib/resources/azure/azure_backend.rb +379 -0
  70. data/lib/resources/azure/azure_generic_resource.rb +55 -0
  71. data/lib/resources/azure/azure_resource_group.rb +151 -0
  72. data/lib/resources/azure/azure_virtual_machine.rb +262 -0
  73. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +131 -0
  74. metadata +202 -0
@@ -0,0 +1,14 @@
1
+ # copyright: 2018, The Authors
2
+
3
+ title "Sample Section"
4
+
5
+ # you add controls here
6
+ control "azure-virtual-machines-exist-check" do # A unique ID for this control.
7
+ impact 1.0 # The criticality, if this control fails.
8
+ title "Check resource groups to see if any VMs exist." # A human-readable title
9
+ azurerm_resource_groups.names.each do |resource_group_name| # Plural resources can be leveraged to loop across many resources
10
+ describe azurerm_virtual_machines(resource_group: resource_group_name) do
11
+ it { should exist } # The test itself.
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ name: <%= name %>
2
+ title: Azure InSpec Profile
3
+ maintainer: The Authors
4
+ copyright: The Authors
5
+ copyright_email: you@example.com
6
+ license: Apache-2.0
7
+ summary: An InSpec Compliance Profile For Azure
8
+ version: 0.1.0
9
+ inspec_version: '>= 2.2.7'
10
+ depends:
11
+ - name: inspec-azure
12
+ url: https://github.com/inspec/inspec-azure/archive/master.tar.gz
13
+ supports:
14
+ - platform: azure
@@ -0,0 +1,66 @@
1
+ # Example InSpec Profile For GCP
2
+
3
+ This example shows the implementation of an InSpec profile for GCP that depends on the [InSpec GCP Resource Pack](https://github.com/inspec/inspec-gcp). See the [README](https://github.com/inspec/inspec-gcp) for instructions on setting up appropriate GCP credentials.
4
+
5
+ ## Create a profile
6
+
7
+ ```
8
+ $ inspec init profile --platform gcp my-profile
9
+ Create new profile at /Users/spaterson/my-profile
10
+ * Create directory libraries
11
+ * Create file README.md
12
+ * Create directory controls
13
+ * Create file controls/example.rb
14
+ * Create file inspec.yml
15
+ * Create file attributes.yml
16
+ * Create file libraries/.gitkeep
17
+
18
+ ```
19
+
20
+ ## Update `attributes.yml` to point to your project
21
+
22
+ ```
23
+ gcp_project_id: 'my-gcp-project'
24
+ ```
25
+
26
+ ## Run the tests
27
+
28
+ ```
29
+ $ cd gcp-profile/
30
+ $ inspec exec . -t gcp:// --attrs attributes.yml
31
+
32
+ Profile: GCP InSpec Profile (my-profile)
33
+ Version: 0.1.0
34
+ Target: gcp://local-service-account@my-gcp-project.iam.gserviceaccount.com
35
+
36
+ ✔ gcp-single-region-1.0: Ensure single region has the correct properties.
37
+ ✔ Region europe-west2 zone_names should include "europe-west2-a"
38
+ ✔ gcp-regions-loop-1.0: Ensure regions have the correct properties in bulk.
39
+ ✔ Region asia-east1 should be up
40
+ ✔ Region asia-northeast1 should be up
41
+ ✔ Region asia-south1 should be up
42
+ ✔ Region asia-southeast1 should be up
43
+ ✔ Region australia-southeast1 should be up
44
+ ✔ Region europe-north1 should be up
45
+ ✔ Region europe-west1 should be up
46
+ ✔ Region europe-west2 should be up
47
+ ✔ Region europe-west3 should be up
48
+ ✔ Region europe-west4 should be up
49
+ ✔ Region northamerica-northeast1 should be up
50
+ ✔ Region southamerica-east1 should be up
51
+ ✔ Region us-central1 should be up
52
+ ✔ Region us-east1 should be up
53
+ ✔ Region us-east4 should be up
54
+ ✔ Region us-west1 should be up
55
+ ✔ Region us-west2 should be up
56
+
57
+
58
+ Profile: Google Cloud Platform Resource Pack (inspec-gcp)
59
+ Version: 0.5.0
60
+ Target: gcp://local-service-account@my-gcp-project.iam.gserviceaccount.com
61
+
62
+ No tests executed.
63
+
64
+ Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped
65
+ Test Summary: 18 successful, 0 failures, 0 skipped
66
+ ```
@@ -0,0 +1,2 @@
1
+ # Below is to be uncommented and set with your GCP project ID:
2
+ # gcp_project_id: 'your-gcp-project'
@@ -0,0 +1,27 @@
1
+ # copyright: 2018, The Authors
2
+
3
+ title "Sample Section"
4
+
5
+ gcp_project_id = attribute("gcp_project_id")
6
+
7
+ # you add controls here
8
+ control "gcp-single-region-1.0" do # A unique ID for this control
9
+ impact 1.0 # The criticality, if this control fails.
10
+ title "Ensure single region has the correct properties." # A human-readable title
11
+ desc "An optional description..."
12
+ describe google_compute_region(project: gcp_project_id, name: "europe-west2") do # The actual test
13
+ its("zone_names") { should include "europe-west2-a" }
14
+ end
15
+ end
16
+
17
+ # plural resources can be leveraged to loop across many resources
18
+ control "gcp-regions-loop-1.0" do # A unique ID for this control
19
+ impact 1.0 # The criticality, if this control fails.
20
+ title "Ensure regions have the correct properties in bulk." # A human-readable title
21
+ desc "An optional description..."
22
+ google_compute_regions(project: gcp_project_id).region_names.each do |region_name| # Loop across all regions by name
23
+ describe google_compute_region(project: gcp_project_id, name: region_name) do # The test for a single region
24
+ it { should be_up }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ name: <%= name %>
2
+ title: GCP InSpec Profile
3
+ maintainer: The Authors
4
+ copyright: The Authors
5
+ copyright_email: you@example.com
6
+ license: Apache-2.0
7
+ summary: An InSpec Compliance Profile For GCP
8
+ version: 0.1.0
9
+ inspec_version: '>= 2.3.5'
10
+ attributes:
11
+ - name: gcp_project_id
12
+ required: true
13
+ description: 'The GCP project identifier.'
14
+ type: string
15
+ depends:
16
+ - name: inspec-gcp
17
+ url: https://github.com/inspec/inspec-gcp/archive/master.tar.gz
18
+ supports:
19
+ - platform: gcp
@@ -0,0 +1,76 @@
1
+ # Main AWS loader file. The intent is for this to be
2
+ # loaded only if AWS resources are needed.
3
+
4
+ require "aws-sdk-core"
5
+
6
+ require "aws-sdk-cloudtrail"
7
+ require "aws-sdk-cloudwatch"
8
+ require "aws-sdk-cloudwatchlogs"
9
+ require "aws-sdk-costandusagereportservice"
10
+ require "aws-sdk-configservice"
11
+ require "aws-sdk-ec2"
12
+ require "aws-sdk-ecs"
13
+ require "aws-sdk-eks"
14
+ require "aws-sdk-elasticloadbalancing"
15
+ require "aws-sdk-iam"
16
+ require "aws-sdk-kms"
17
+ require "aws-sdk-rds"
18
+ require "aws-sdk-s3"
19
+ require "aws-sdk-sqs"
20
+ require "aws-sdk-sns"
21
+
22
+ require "resource_support/aws/aws_backend_factory_mixin"
23
+ require "resource_support/aws/aws_resource_mixin"
24
+ require "resource_support/aws/aws_singular_resource_mixin"
25
+ require "resource_support/aws/aws_plural_resource_mixin"
26
+ require "resource_support/aws/aws_backend_base"
27
+
28
+ # Load all AWS resources
29
+ # TODO: loop over and load entire directory
30
+ # for f in ls lib/resources/aws/*; do t=$(echo $f | cut -c 5- | cut -f1 -d. ); echo "require '${t}'"; done
31
+ require "resources/aws/aws_billing_report"
32
+ require "resources/aws/aws_billing_reports"
33
+ require "resources/aws/aws_cloudtrail_trail"
34
+ require "resources/aws/aws_cloudtrail_trails"
35
+ require "resources/aws/aws_cloudwatch_alarm"
36
+ require "resources/aws/aws_cloudwatch_log_metric_filter"
37
+ require "resources/aws/aws_config_delivery_channel"
38
+ require "resources/aws/aws_config_recorder"
39
+ require "resources/aws/aws_ec2_instance"
40
+ require "resources/aws/aws_ebs_volume"
41
+ require "resources/aws/aws_ebs_volumes"
42
+ require "resources/aws/aws_flow_log"
43
+ require "resources/aws/aws_ec2_instances"
44
+ require "resources/aws/aws_ecs_cluster"
45
+ require "resources/aws/aws_eks_cluster"
46
+ require "resources/aws/aws_elb"
47
+ require "resources/aws/aws_elbs"
48
+ require "resources/aws/aws_iam_access_key"
49
+ require "resources/aws/aws_iam_access_keys"
50
+ require "resources/aws/aws_iam_group"
51
+ require "resources/aws/aws_iam_groups"
52
+ require "resources/aws/aws_iam_password_policy"
53
+ require "resources/aws/aws_iam_policies"
54
+ require "resources/aws/aws_iam_policy"
55
+ require "resources/aws/aws_iam_role"
56
+ require "resources/aws/aws_iam_root_user"
57
+ require "resources/aws/aws_iam_user"
58
+ require "resources/aws/aws_iam_users"
59
+ require "resources/aws/aws_kms_key"
60
+ require "resources/aws/aws_kms_keys"
61
+ require "resources/aws/aws_rds_instance"
62
+ require "resources/aws/aws_route_table"
63
+ require "resources/aws/aws_route_tables"
64
+ require "resources/aws/aws_s3_bucket"
65
+ require "resources/aws/aws_s3_bucket_object"
66
+ require "resources/aws/aws_s3_buckets"
67
+ require "resources/aws/aws_security_group"
68
+ require "resources/aws/aws_security_groups"
69
+ require "resources/aws/aws_sns_subscription"
70
+ require "resources/aws/aws_sns_topic"
71
+ require "resources/aws/aws_sns_topics"
72
+ require "resources/aws/aws_sqs_queue"
73
+ require "resources/aws/aws_subnet"
74
+ require "resources/aws/aws_subnets"
75
+ require "resources/aws/aws_vpc"
76
+ require "resources/aws/aws_vpcs"
@@ -0,0 +1,12 @@
1
+ class AwsBackendBase
2
+ attr_reader :aws_transport
3
+ class << self; attr_accessor :aws_client_class end
4
+
5
+ def initialize(inspec = nil)
6
+ @aws_transport = inspec ? inspec.backend : nil
7
+ end
8
+
9
+ def aws_service_client
10
+ aws_transport.aws_client(self.class.aws_client_class)
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # Intended to be pulled in via extend, not include
2
+ module AwsBackendFactoryMixin
3
+ def create(inspec)
4
+ @selected_backend.new(inspec)
5
+ end
6
+
7
+ def select(klass)
8
+ @selected_backend = klass
9
+ end
10
+
11
+ alias set_default_backend select
12
+ end
@@ -0,0 +1,24 @@
1
+ require "resource_support/aws/aws_resource_mixin"
2
+ require "resource_support/aws/aws_backend_factory_mixin"
3
+
4
+ module AwsPluralResourceMixin
5
+ include AwsResourceMixin
6
+ attr_reader :table
7
+
8
+ # This sets up a class, AwsSomeResource::BackendFactory, that
9
+ # provides a mechanism to create and use backends without
10
+ # having to know which is selected. This is mainly used for
11
+ # unit testing.
12
+ # TODO: DRY up. This code exists in both the Singular and Plural mixins.
13
+ # We'd like to put it in AwsResourceMixin, but included only sees the
14
+ # directly-including class - we can't see second-order includers.
15
+ def self.included(base)
16
+ # Create a new class, whose body is simply to extend the
17
+ # backend factory mixin
18
+ resource_backend_factory_class = Class.new(Object) do
19
+ extend AwsBackendFactoryMixin
20
+ end
21
+ # Name that class
22
+ base.const_set("BackendFactory", resource_backend_factory_class)
23
+ end
24
+ end
@@ -0,0 +1,69 @@
1
+ module AwsResourceMixin
2
+ def initialize(resource_params = {})
3
+ Inspec.deprecate(:aws_resources_in_resource_pack,
4
+ "Resource '#{@__resource_name__ ||= self.class.to_s}'")
5
+ validate_params(resource_params).each do |param, value|
6
+ instance_variable_set(:"@#{param}", value)
7
+ end
8
+ catch_aws_errors do
9
+ fetch_from_api
10
+ end
11
+ rescue ArgumentError => e
12
+ # continue with ArgumentError if testing
13
+ raise unless respond_to?(:inspec) && inspec
14
+
15
+ raise Inspec::Exceptions::ResourceFailed, e.message
16
+ end
17
+
18
+ # Default implementation of validate params accepts everything.
19
+ def validate_params(resource_params)
20
+ resource_params
21
+ end
22
+
23
+ def check_resource_param_names(raw_params: {}, allowed_params: [], allowed_scalar_name: nil, allowed_scalar_type: nil)
24
+ # Some resources allow passing in a single ID value. Check and convert to hash if so.
25
+ if allowed_scalar_name && !raw_params.is_a?(Hash)
26
+ value_seen = raw_params
27
+ if value_seen.is_a?(allowed_scalar_type)
28
+ raw_params = { allowed_scalar_name => value_seen }
29
+ else
30
+ raise ArgumentError, "If you pass a single value to the resource, it must " \
31
+ "be a #{allowed_scalar_type}, not an #{value_seen.class}."
32
+ end
33
+ end
34
+
35
+ # Remove all expected params from the raw param hash
36
+ recognized_params = {}
37
+ allowed_params.each do |expected_param|
38
+ recognized_params[expected_param] = raw_params.delete(expected_param) if raw_params.key?(expected_param)
39
+ end
40
+
41
+ # Any leftovers are unwelcome
42
+ unless raw_params.empty?
43
+ raise ArgumentError, "Unrecognized resource param '#{raw_params.keys.first}'. Expected parameters: #{allowed_params.join(", ")}"
44
+ end
45
+
46
+ recognized_params
47
+ end
48
+
49
+ def inspec_runner
50
+ # When running under inspec-cli, we have an 'inspec' method that
51
+ # returns the runner. When running under unit tests, we don't
52
+ # have that, but we still have to call this to pass something
53
+ # (nil is OK) to the backend.
54
+ # TODO: remove with https://github.com/chef/inspec-aws/issues/216
55
+ inspec if respond_to?(:inspec)
56
+ end
57
+
58
+ # Intercept AWS exceptions
59
+ def catch_aws_errors
60
+ yield
61
+ rescue Aws::Errors::MissingCredentialsError
62
+ # The AWS error here is unhelpful:
63
+ # "unable to sign request without credentials set"
64
+ 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://www.inspec.io/docs/reference/platforms for details."
65
+ fail_resource("No AWS credentials available")
66
+ rescue Aws::Errors::ServiceError => e
67
+ fail_resource e.message
68
+ end
69
+ end
@@ -0,0 +1,27 @@
1
+ require "resource_support/aws/aws_resource_mixin"
2
+ require "resource_support/aws/aws_backend_factory_mixin"
3
+
4
+ module AwsSingularResourceMixin
5
+ include AwsResourceMixin
6
+
7
+ def exists?
8
+ @exists
9
+ end
10
+
11
+ # This sets up a class, AwsSomeResource::BackendFactory, that
12
+ # provides a mechanism to create and use backends without
13
+ # having to know which is selected. This is mainly used for
14
+ # unit testing.
15
+ # TODO: DRY up. This code exists in both the Singular and Plural mixins.
16
+ # We'd like to put it in AwsResourceMixin, but included only sees the
17
+ # directly-including class - we can't see second-order includers.
18
+ def self.included(base)
19
+ # Create a new class, whose body is simply to extend the
20
+ # backend factory mixin
21
+ resource_backend_factory_class = Class.new(Object) do
22
+ extend AwsBackendFactoryMixin
23
+ end
24
+ # Name that class
25
+ base.const_set("BackendFactory", resource_backend_factory_class)
26
+ end
27
+ end
@@ -0,0 +1,107 @@
1
+ require "resource_support/aws/aws_singular_resource_mixin"
2
+ require "resource_support/aws/aws_backend_base"
3
+
4
+ require "resource_support/aws/aws_singular_resource_mixin"
5
+ require "resource_support/aws/aws_backend_base"
6
+ require "aws-sdk-costandusagereportservice.rb"
7
+
8
+ class AwsBillingReport < Inspec.resource(1)
9
+ name "aws_billing_report"
10
+ supports platform: "aws"
11
+ desc "Verifies settings for AWS Cost and Billing Reports."
12
+ example <<~EXAMPLE
13
+ describe aws_billing_report('inspec1') do
14
+ its('report_name') { should cmp 'inspec1' }
15
+ its('time_unit') { should cmp 'hourly' }
16
+ end
17
+
18
+ describe aws_billing_report(report: 'inspec1') do
19
+ it { should exist }
20
+ end
21
+ EXAMPLE
22
+
23
+ include AwsSingularResourceMixin
24
+
25
+ attr_reader :report_name, :time_unit, :format, :compression, :s3_bucket,
26
+ :s3_prefix, :s3_region
27
+
28
+ def to_s
29
+ "AWS Billing Report #{report_name}"
30
+ end
31
+
32
+ def hourly?
33
+ exists? ? time_unit.eql?("hourly") : nil
34
+ end
35
+
36
+ def daily?
37
+ exists? ? time_unit.eql?("daily") : nil
38
+ end
39
+
40
+ def zip?
41
+ exists? ? compression.eql?("zip") : nil
42
+ end
43
+
44
+ def gzip?
45
+ exists? ? compression.eql?("gzip") : nil
46
+ end
47
+
48
+ private
49
+
50
+ def validate_params(raw_params)
51
+ validated_params = check_resource_param_names(
52
+ raw_params: raw_params,
53
+ allowed_params: [:report_name],
54
+ allowed_scalar_name: :report_name,
55
+ allowed_scalar_type: String
56
+ )
57
+
58
+ if validated_params.empty?
59
+ raise ArgumentError, "You must provide the parameter 'report_name' to aws_billing_report."
60
+ end
61
+
62
+ validated_params
63
+ end
64
+
65
+ def fetch_from_api
66
+ report = find_report(report_name)
67
+ @exists = !report.nil?
68
+ if exists?
69
+ @time_unit = report.time_unit.downcase
70
+ @format = report.format.downcase
71
+ @compression = report.compression.downcase
72
+ @s3_bucket = report.s3_bucket
73
+ @s3_prefix = report.s3_prefix
74
+ @s3_region = report.s3_region
75
+ end
76
+ end
77
+
78
+ def find_report(report_name)
79
+ pagination_opts = {}
80
+ found_report_def = nil
81
+ while found_report_def.nil?
82
+ api_result = backend.describe_report_definitions(pagination_opts)
83
+ next_token = api_result.next_token
84
+ found_report_def = api_result.report_definitions.find { |report_def| report_def.report_name == report_name }
85
+ pagination_opts = { next_token: next_token }
86
+
87
+ next if found_report_def.nil? && next_token # Loop again: didn't find it, but there are more results
88
+ break if found_report_def.nil? && next_token.nil? # Give up: didn't find it, no more results
89
+ end
90
+ found_report_def
91
+ end
92
+
93
+ def backend
94
+ @backend ||= BackendFactory.create(inspec_runner)
95
+ end
96
+
97
+ class Backend
98
+ class AwsClientApi < AwsBackendBase
99
+ AwsBillingReport::BackendFactory.set_default_backend(self)
100
+ self.aws_client_class = Aws::CostandUsageReportService::Client
101
+
102
+ def describe_report_definitions(query = {})
103
+ aws_service_client.describe_report_definitions(query)
104
+ end
105
+ end
106
+ end
107
+ end