aws_recon 0.2.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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +12 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +1000 -0
  9. data/LICENSE.txt +21 -0
  10. data/Rakefile +10 -0
  11. data/aws_recon.gemspec +36 -0
  12. data/bin/aws_recon +5 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/lib/aws_recon.rb +19 -0
  16. data/lib/aws_recon/aws_recon.rb +115 -0
  17. data/lib/aws_recon/collectors/acm.rb +32 -0
  18. data/lib/aws_recon/collectors/apigateway.rb +50 -0
  19. data/lib/aws_recon/collectors/apigatewayv2.rb +37 -0
  20. data/lib/aws_recon/collectors/athena.rb +28 -0
  21. data/lib/aws_recon/collectors/autoscaling.rb +35 -0
  22. data/lib/aws_recon/collectors/cloudformation.rb +29 -0
  23. data/lib/aws_recon/collectors/cloudfront.rb +28 -0
  24. data/lib/aws_recon/collectors/cloudtrail.rb +33 -0
  25. data/lib/aws_recon/collectors/cloudwatch.rb +33 -0
  26. data/lib/aws_recon/collectors/cloudwatchlogs.rb +36 -0
  27. data/lib/aws_recon/collectors/codebuild.rb +29 -0
  28. data/lib/aws_recon/collectors/codepipeline.rb +27 -0
  29. data/lib/aws_recon/collectors/collectors.rb +2 -0
  30. data/lib/aws_recon/collectors/configservice.rb +80 -0
  31. data/lib/aws_recon/collectors/directconnect.rb +25 -0
  32. data/lib/aws_recon/collectors/directyservice.rb +27 -0
  33. data/lib/aws_recon/collectors/dms.rb +25 -0
  34. data/lib/aws_recon/collectors/dynamodb.rb +26 -0
  35. data/lib/aws_recon/collectors/ec2.rb +257 -0
  36. data/lib/aws_recon/collectors/ecr.rb +39 -0
  37. data/lib/aws_recon/collectors/ecs.rb +40 -0
  38. data/lib/aws_recon/collectors/efs.rb +25 -0
  39. data/lib/aws_recon/collectors/eks.rb +36 -0
  40. data/lib/aws_recon/collectors/elasticloadbalancing.rb +41 -0
  41. data/lib/aws_recon/collectors/elasticloadbalancingv2.rb +63 -0
  42. data/lib/aws_recon/collectors/elasticsearch.rb +27 -0
  43. data/lib/aws_recon/collectors/firehose.rb +29 -0
  44. data/lib/aws_recon/collectors/guardduty.rb +33 -0
  45. data/lib/aws_recon/collectors/iam.rb +136 -0
  46. data/lib/aws_recon/collectors/kafka.rb +27 -0
  47. data/lib/aws_recon/collectors/kinesis.rb +26 -0
  48. data/lib/aws_recon/collectors/kms.rb +71 -0
  49. data/lib/aws_recon/collectors/lambda.rb +42 -0
  50. data/lib/aws_recon/collectors/lightsail.rb +38 -0
  51. data/lib/aws_recon/collectors/organizations.rb +36 -0
  52. data/lib/aws_recon/collectors/rds.rb +81 -0
  53. data/lib/aws_recon/collectors/redshift.rb +40 -0
  54. data/lib/aws_recon/collectors/route53.rb +28 -0
  55. data/lib/aws_recon/collectors/route53domains.rb +25 -0
  56. data/lib/aws_recon/collectors/s3.rb +80 -0
  57. data/lib/aws_recon/collectors/sagemaker.rb +25 -0
  58. data/lib/aws_recon/collectors/servicequotas.rb +44 -0
  59. data/lib/aws_recon/collectors/ses.rb +28 -0
  60. data/lib/aws_recon/collectors/shield.rb +67 -0
  61. data/lib/aws_recon/collectors/sns.rb +38 -0
  62. data/lib/aws_recon/collectors/sqs.rb +28 -0
  63. data/lib/aws_recon/collectors/ssm.rb +41 -0
  64. data/lib/aws_recon/collectors/support.rb +43 -0
  65. data/lib/aws_recon/collectors/transfer.rb +24 -0
  66. data/lib/aws_recon/collectors/wafv2.rb +49 -0
  67. data/lib/aws_recon/collectors/workspaces.rb +24 -0
  68. data/lib/aws_recon/collectors/xray.rb +19 -0
  69. data/lib/aws_recon/lib/formatter.rb +32 -0
  70. data/lib/aws_recon/lib/mapper.rb +69 -0
  71. data/lib/aws_recon/options.rb +141 -0
  72. data/lib/aws_recon/services.yaml +134 -0
  73. data/lib/aws_recon/version.rb +3 -0
  74. data/readme.md +226 -0
  75. data/readme_gem.md +39 -0
  76. metadata +245 -0
@@ -0,0 +1,27 @@
1
+ class Kafka < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ # TODO: test live
6
+ #
7
+ def collect
8
+ resources = []
9
+
10
+ #
11
+ # list_clusters
12
+ #
13
+ @client.list_clusters.each_with_index do |response, page|
14
+ log(response.context.operation_name, page)
15
+
16
+ response.cluster_info_list.each do |cluster|
17
+ struct = OpenStruct.new(cluster.to_h)
18
+ struct.type = 'cluster'
19
+ struct.arn = cluster.cluster_arn
20
+
21
+ resources.push(struct.to_h)
22
+ end
23
+ end
24
+
25
+ resources
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ class Kinesis < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # list_streams
10
+ #
11
+ @client.list_streams.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ # describe_stream
15
+ response.stream_names.each do |stream|
16
+ struct = OpenStruct.new(@client.describe_stream({ stream_name: stream }).stream_description.to_h)
17
+ struct.type = 'stream'
18
+ struct.arn = struct.stream_arn
19
+
20
+ resources.push(struct.to_h)
21
+ end
22
+ end
23
+
24
+ resources
25
+ end
26
+ end
@@ -0,0 +1,71 @@
1
+ class KMS < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # list_keys
10
+ #
11
+ @client.list_keys.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ # describe_key
15
+ response.keys.each do |key|
16
+ log(response.context.operation_name, 'describe_key', page)
17
+ struct = OpenStruct.new(@client
18
+ .describe_key({ key_id: key.key_id })
19
+ .key_metadata.to_h)
20
+ struct.type = 'key'
21
+ struct.grants = []
22
+
23
+ # get_key_rotation_status
24
+ log(response.context.operation_name, 'get_key_rotation_status')
25
+ # The default master key rotation status can't be queried
26
+ begin
27
+ struct.rotation_enabled = @client
28
+ .get_key_rotation_status({ key_id: key.key_id })
29
+ .key_rotation_enabled
30
+ rescue Aws::KMS::Errors::ServiceError => e
31
+ log_error(e.code)
32
+ raise e unless suppressed_errors.include?(e.code)
33
+ end
34
+
35
+ # list_grants
36
+ @client.list_grants({ key_id: key.key_id }).each_with_index do |response, page|
37
+ log(response.context.operation_name, 'list_grants', page)
38
+
39
+ response.grants.each do |grant|
40
+ struct.grants.push(grant.to_h)
41
+ end
42
+ end
43
+
44
+ # get_key_policy - 'default' is the only valid policy
45
+ log(response.context.operation_name, 'get_key_policy')
46
+ struct.policy = @client
47
+ .get_key_policy({ key_id: key.key_id, policy_name: 'default' })
48
+ .policy
49
+
50
+ # list_aliases
51
+ log(response.context.operation_name, 'list_aliases')
52
+ struct.aliases = @client
53
+ .list_aliases({ key_id: key.key_id })
54
+ .aliases.map(&:to_h)
55
+
56
+ resources.push(struct.to_h)
57
+ end
58
+ end
59
+
60
+ resources
61
+ end
62
+
63
+ private
64
+
65
+ # not an error
66
+ def suppressed_errors
67
+ %w[
68
+ AccessDeniedException
69
+ ]
70
+ end
71
+ end
@@ -0,0 +1,42 @@
1
+ class Lambda < Mapper
2
+ def collect
3
+ service = self.class.to_s.downcase
4
+ resources = []
5
+
6
+ #
7
+ # list_functions
8
+ #
9
+ @client.list_functions.each_with_index do |response, page|
10
+ log(response.context.operation_name, page)
11
+
12
+ response.functions.each do |function|
13
+ struct = OpenStruct.new(function)
14
+ struct.type = 'function'
15
+ struct.arn = function.function_arn
16
+
17
+ resources.push(struct.to_h)
18
+ end
19
+ end
20
+
21
+ #
22
+ # list_layers
23
+ #
24
+ @client.list_layers.each_with_index do |response, page|
25
+ log(response.context.operation_name, page)
26
+
27
+ response.layers.each do |layer|
28
+ struct = OpenStruct.new(layer)
29
+ struct.type = 'layer'
30
+ struct.arn = layer.layer_arn
31
+
32
+ # list_layer_versions
33
+ struct.versions = @client.list_layer_versions({ layer_name: layer.layer_name }).layer_versions.map(&:to_h)
34
+ log(response.context.operation_name, 'list_layer_versions')
35
+
36
+ resources.push(struct.to_h)
37
+ end
38
+ end
39
+
40
+ resources
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ class Lightsail < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # get_instances
10
+ #
11
+ @client.get_instances.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ response.instances.each do |instance|
15
+ struct = OpenStruct.new(instance.to_h)
16
+ struct.type = 'instance'
17
+
18
+ resources.push(struct.to_h)
19
+ end
20
+ end
21
+
22
+ #
23
+ # get_load_balancers
24
+ #
25
+ @client.get_load_balancers.each_with_index do |response, page|
26
+ log(response.context.operation_name, page)
27
+
28
+ response.load_balancers.each do |load_balancer|
29
+ struct = OpenStruct.new(load_balancer.to_h)
30
+ struct.type = 'load_balancer'
31
+
32
+ resources.push(struct.to_h)
33
+ end
34
+ end
35
+
36
+ resources
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ class Organizations < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # describe_organization
10
+ #
11
+ @client.describe_organization.each do |response|
12
+ log(response.context.operation_name)
13
+
14
+ struct = OpenStruct.new(response.organization.to_h)
15
+ struct.type = 'organization'
16
+
17
+ resources.push(struct.to_h)
18
+ end
19
+
20
+ #
21
+ # list_handshakes_for_account
22
+ #
23
+ @client.list_handshakes_for_account.each_with_index do |response, page|
24
+ log(response.context.operation_name, page)
25
+
26
+ response.handshakes.each do |handshake|
27
+ struct = OpenStruct.new(handshake.to_h)
28
+ struct.type = 'handshake'
29
+
30
+ resources.push(struct.to_h)
31
+ end
32
+ end
33
+
34
+ resources
35
+ end
36
+ end
@@ -0,0 +1,81 @@
1
+ class RDS < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ # describe_db_engine_versions is skipped with @options.skip_slow
6
+ #
7
+ def collect
8
+ resources = []
9
+
10
+ #
11
+ # describe_db_clusters
12
+ #
13
+ @client.describe_db_clusters.each_with_index do |response, page|
14
+ log(response.context.operation_name, page)
15
+
16
+ response.db_clusters.each do |cluster|
17
+ log(response.context.operation_name, cluster.db_cluster_identifier)
18
+
19
+ struct = OpenStruct.new(cluster.to_h)
20
+ struct.type = 'db_cluster'
21
+ struct.arn = cluster.db_cluster_arn
22
+
23
+ resources.push(struct.to_h)
24
+ end
25
+ end
26
+
27
+ #
28
+ # describe_db_instances
29
+ #
30
+ @client.describe_db_instances.each_with_index do |response, page|
31
+ log(response.context.operation_name, page)
32
+
33
+ response.db_instances.each do |instance|
34
+ log(response.context.operation_name, instance.db_instance_identifier)
35
+
36
+ struct = OpenStruct.new(instance.to_h)
37
+ struct.type = 'db_instance'
38
+ struct.arn = instance.db_instance_arn
39
+ struct.parent_id = instance.db_cluster_identifier
40
+
41
+ resources.push(struct.to_h)
42
+ end
43
+ end
44
+
45
+ #
46
+ # describe_db_snapshots
47
+ #
48
+ @client.describe_db_snapshots.each_with_index do |response, page|
49
+ log(response.context.operation_name, page)
50
+
51
+ response.db_snapshots.each do |snapshot|
52
+ log(response.context.operation_name, snapshot.db_snapshot_identifier)
53
+
54
+ struct = OpenStruct.new(snapshot.to_h)
55
+ struct.type = 'db_snapshot'
56
+ struct.arn = snapshot.db_snapshot_arn
57
+ struct.parent_id = snapshot.db_instance_identifier
58
+
59
+ resources.push(struct.to_h)
60
+ end
61
+ end
62
+
63
+ #
64
+ # describe_db_engine_versions
65
+ #
66
+ unless @options.skip_slow
67
+ @client.describe_db_engine_versions.each_with_index do |response, page|
68
+ log(response.context.operation_name, page)
69
+
70
+ response.db_engine_versions.each do |version|
71
+ struct = OpenStruct.new(version.to_h)
72
+ struct.type = 'db_engine_version'
73
+
74
+ resources.push(struct.to_h)
75
+ end
76
+ end
77
+ end
78
+
79
+ resources
80
+ end
81
+ end
@@ -0,0 +1,40 @@
1
+ class Redshift < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # describe_clusters
10
+ #
11
+ @client.describe_clusters.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ response.clusters.each do |cluster|
15
+ struct = OpenStruct.new(cluster.to_h)
16
+ struct.type = 'cluster'
17
+ struct.arn = cluster.cluster_identifier
18
+
19
+ resources.push(struct.to_h)
20
+ end
21
+ end
22
+
23
+ #
24
+ # describe_cluster_subnet_groups
25
+ #
26
+ @client.describe_cluster_subnet_groups.each_with_index do |response, page|
27
+ log(response.context.operation_name, page)
28
+
29
+ response.cluster_subnet_groups.each do |group|
30
+ struct = OpenStruct.new(group.to_h)
31
+ struct.type = 'subnet_group'
32
+ struct.arn = group.cluster_subnet_group_name
33
+
34
+ resources.push(struct.to_h)
35
+ end
36
+ end
37
+
38
+ resources
39
+ end
40
+ end
@@ -0,0 +1,28 @@
1
+ class Route53 < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # list_hosted_zones
10
+ #
11
+ @client.list_hosted_zones.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ response.hosted_zones.each do |zone|
15
+ struct = OpenStruct.new(zone.to_h)
16
+ struct.type = 'zone'
17
+ struct.arn = zone.id
18
+ struct.logging_config = @client
19
+ .list_query_logging_configs({ hosted_zone_id: zone.id })
20
+ .query_logging_configs.first.to_h
21
+
22
+ resources.push(struct.to_h)
23
+ end
24
+ end
25
+
26
+ resources
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ class Route53Domains < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # list_domains
10
+ #
11
+ @client.list_domains.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ response.domains.each do |domain|
15
+ struct = OpenStruct.new(domain.to_h)
16
+ struct.type = 'domain'
17
+ struct.arn = "arn:aws:#{@service}:#{@region}::domain/#{domain.domain_name}"
18
+
19
+ resources.push(struct.to_h)
20
+ end
21
+ end
22
+
23
+ resources
24
+ end
25
+ end
@@ -0,0 +1,80 @@
1
+ class S3 < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ # Since S3 is a global service, the bucket operation calls
6
+ # can be parallelized.
7
+ #
8
+ def collect
9
+ resources = []
10
+
11
+ #
12
+ # list_buckets
13
+ #
14
+ @client.list_buckets.each_with_index do |response, page|
15
+ log(response.context.operation_name, page)
16
+
17
+ Parallel.map(response.buckets.each, in_threads: @options.threads) do |bucket|
18
+ # use shared client instance
19
+ client = @client
20
+ @thread = Parallel.worker_number
21
+ log(response.context.operation_name, bucket.name)
22
+
23
+ struct = OpenStruct.new(bucket)
24
+ struct.type = 'bucket'
25
+ struct.arn = "arn:aws:s3:::#{bucket.name}"
26
+
27
+ # check bucket region constraint
28
+ location = @client.get_bucket_location({ bucket: bucket.name }).location_constraint
29
+
30
+ # reset client if needed
31
+ unless location.empty?
32
+ client = Aws::S3::Client.new({ region: location })
33
+ end
34
+
35
+ operations = [
36
+ { func: 'get_bucket_acl', key: 'acl', field: nil },
37
+ { func: 'get_bucket_encryption', key: 'encryption', field: 'server_side_encryption_configuration' },
38
+ { func: 'get_bucket_policy', key: 'policy', field: 'policy' },
39
+ { func: 'get_bucket_policy_status', key: 'public', field: 'policy_status' },
40
+ { func: 'get_bucket_tagging', key: 'tagging', field: nil },
41
+ { func: 'get_bucket_logging', key: 'logging', field: 'logging_enabled' },
42
+ { func: 'get_bucket_versioning', key: 'versioning', field: nil },
43
+ { func: 'get_bucket_website', key: 'website', field: nil }
44
+ ]
45
+
46
+ operations.each do |operation|
47
+ op = OpenStruct.new(operation)
48
+
49
+ resp = client.send(op.func, { bucket: bucket.name })
50
+
51
+ struct[op.key] = if op.key == 'policy'
52
+ resp.policy.string
53
+ else
54
+ op.field ? resp.send(op.field).to_h : resp.to_h
55
+ end
56
+
57
+ rescue Aws::S3::Errors::ServiceError => e
58
+ raise e unless suppressed_errors.include?(e.code)
59
+ end
60
+
61
+ resources.push(struct.to_h)
62
+ end
63
+ end
64
+
65
+ resources
66
+ end
67
+
68
+ private
69
+
70
+ # not an error
71
+ def suppressed_errors
72
+ %w[
73
+ AccessDenied
74
+ ServerSideEncryptionConfigurationNotFoundError
75
+ NoSuchBucketPolicy
76
+ NoSuchTagSet
77
+ NoSuchWebsiteConfiguration
78
+ ]
79
+ end
80
+ end