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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +12 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +1000 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +10 -0
- data/aws_recon.gemspec +36 -0
- data/bin/aws_recon +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/aws_recon.rb +19 -0
- data/lib/aws_recon/aws_recon.rb +115 -0
- data/lib/aws_recon/collectors/acm.rb +32 -0
- data/lib/aws_recon/collectors/apigateway.rb +50 -0
- data/lib/aws_recon/collectors/apigatewayv2.rb +37 -0
- data/lib/aws_recon/collectors/athena.rb +28 -0
- data/lib/aws_recon/collectors/autoscaling.rb +35 -0
- data/lib/aws_recon/collectors/cloudformation.rb +29 -0
- data/lib/aws_recon/collectors/cloudfront.rb +28 -0
- data/lib/aws_recon/collectors/cloudtrail.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatch.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatchlogs.rb +36 -0
- data/lib/aws_recon/collectors/codebuild.rb +29 -0
- data/lib/aws_recon/collectors/codepipeline.rb +27 -0
- data/lib/aws_recon/collectors/collectors.rb +2 -0
- data/lib/aws_recon/collectors/configservice.rb +80 -0
- data/lib/aws_recon/collectors/directconnect.rb +25 -0
- data/lib/aws_recon/collectors/directyservice.rb +27 -0
- data/lib/aws_recon/collectors/dms.rb +25 -0
- data/lib/aws_recon/collectors/dynamodb.rb +26 -0
- data/lib/aws_recon/collectors/ec2.rb +257 -0
- data/lib/aws_recon/collectors/ecr.rb +39 -0
- data/lib/aws_recon/collectors/ecs.rb +40 -0
- data/lib/aws_recon/collectors/efs.rb +25 -0
- data/lib/aws_recon/collectors/eks.rb +36 -0
- data/lib/aws_recon/collectors/elasticloadbalancing.rb +41 -0
- data/lib/aws_recon/collectors/elasticloadbalancingv2.rb +63 -0
- data/lib/aws_recon/collectors/elasticsearch.rb +27 -0
- data/lib/aws_recon/collectors/firehose.rb +29 -0
- data/lib/aws_recon/collectors/guardduty.rb +33 -0
- data/lib/aws_recon/collectors/iam.rb +136 -0
- data/lib/aws_recon/collectors/kafka.rb +27 -0
- data/lib/aws_recon/collectors/kinesis.rb +26 -0
- data/lib/aws_recon/collectors/kms.rb +71 -0
- data/lib/aws_recon/collectors/lambda.rb +42 -0
- data/lib/aws_recon/collectors/lightsail.rb +38 -0
- data/lib/aws_recon/collectors/organizations.rb +36 -0
- data/lib/aws_recon/collectors/rds.rb +81 -0
- data/lib/aws_recon/collectors/redshift.rb +40 -0
- data/lib/aws_recon/collectors/route53.rb +28 -0
- data/lib/aws_recon/collectors/route53domains.rb +25 -0
- data/lib/aws_recon/collectors/s3.rb +80 -0
- data/lib/aws_recon/collectors/sagemaker.rb +25 -0
- data/lib/aws_recon/collectors/servicequotas.rb +44 -0
- data/lib/aws_recon/collectors/ses.rb +28 -0
- data/lib/aws_recon/collectors/shield.rb +67 -0
- data/lib/aws_recon/collectors/sns.rb +38 -0
- data/lib/aws_recon/collectors/sqs.rb +28 -0
- data/lib/aws_recon/collectors/ssm.rb +41 -0
- data/lib/aws_recon/collectors/support.rb +43 -0
- data/lib/aws_recon/collectors/transfer.rb +24 -0
- data/lib/aws_recon/collectors/wafv2.rb +49 -0
- data/lib/aws_recon/collectors/workspaces.rb +24 -0
- data/lib/aws_recon/collectors/xray.rb +19 -0
- data/lib/aws_recon/lib/formatter.rb +32 -0
- data/lib/aws_recon/lib/mapper.rb +69 -0
- data/lib/aws_recon/options.rb +141 -0
- data/lib/aws_recon/services.yaml +134 -0
- data/lib/aws_recon/version.rb +3 -0
- data/readme.md +226 -0
- data/readme_gem.md +39 -0
- metadata +245 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
class SageMaker < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_notebook_instances
|
10
|
+
#
|
11
|
+
@client.list_notebook_instances.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.notebook_instances.each do |instance|
|
15
|
+
struct = OpenStruct.new(instance.to_h)
|
16
|
+
struct.type = 'notebook_instance'
|
17
|
+
struct.arn = instance.notebook_instance_arn
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
resources
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class ServiceQuotas < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_service_quotas
|
10
|
+
#
|
11
|
+
# TODO: expand to more services as needed
|
12
|
+
#
|
13
|
+
# service_codes = %w[autoscaling ec2 ecr eks elasticloadbalancing fargate iam vpc]
|
14
|
+
service_codes = %w[ec2 eks iam]
|
15
|
+
|
16
|
+
service_codes.each do |service|
|
17
|
+
@client.list_service_quotas({ service_code: service }).each_with_index do |response, page|
|
18
|
+
log(response.context.operation_name, service, page)
|
19
|
+
|
20
|
+
response.quotas.each do |quota|
|
21
|
+
struct = OpenStruct.new(quota.to_h)
|
22
|
+
struct.type = 'quota'
|
23
|
+
struct.arn = quota.quota_arn
|
24
|
+
|
25
|
+
resources.push(struct.to_h)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue Aws::ServiceQuotas::Errors::ServiceError => e
|
29
|
+
log_error(e.code, service)
|
30
|
+
raise e unless suppressed_errors.include?(e.code)
|
31
|
+
end
|
32
|
+
|
33
|
+
resources
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# not an error
|
39
|
+
def suppressed_errors
|
40
|
+
%w[
|
41
|
+
NoSuchResourceException
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SES < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_identities
|
10
|
+
#
|
11
|
+
@client.list_identities.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.identities.each do |identity|
|
15
|
+
struct = OpenStruct.new
|
16
|
+
struct.type = 'identity'
|
17
|
+
struct.arn = "aws:ses:#{@region}::identity/#{identity}"
|
18
|
+
|
19
|
+
# get_identity_dkim_attributes
|
20
|
+
struct.dkim_attributes = @client.get_identity_dkim_attributes({ identities: [identity] }).dkim_attributes[identity].to_h
|
21
|
+
|
22
|
+
resources.push(struct.to_h)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
resources
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Shield < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_subscription
|
10
|
+
#
|
11
|
+
@client.describe_subscription.each do |response|
|
12
|
+
log(response.context.operation_name)
|
13
|
+
|
14
|
+
struct = OpenStruct.new(response.subscription.to_h)
|
15
|
+
struct.type = 'subscription'
|
16
|
+
struct.arn = "arn:aws:shield:#{@region}:#{account}:subscription"
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# describe_emergency_contact_settings
|
23
|
+
#
|
24
|
+
@client.describe_emergency_contact_settings.each do |response|
|
25
|
+
log(response.context.operation_name)
|
26
|
+
|
27
|
+
struct = OpenStruct.new
|
28
|
+
struct.type = 'contact_list'
|
29
|
+
struct.arn = "arn:aws:shield:#{@region}:#{account}:contact_list"
|
30
|
+
struct.contacts = response.emergency_contact_list.map(&:to_h)
|
31
|
+
|
32
|
+
resources.push(struct.to_h)
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# list_protections
|
37
|
+
#
|
38
|
+
@client.list_protections.each_with_index do |response, page|
|
39
|
+
log(response.context.operation_name, page)
|
40
|
+
|
41
|
+
# describe_protection
|
42
|
+
response.protections.each do |protection|
|
43
|
+
struct = OpenStruct.new(@client.describe_protection({ protection_id: protection.id }).protection.to_h)
|
44
|
+
struct.type = 'protection'
|
45
|
+
struct.arn = protection.resource_arn
|
46
|
+
|
47
|
+
resources.push(struct.to_h)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
resources
|
52
|
+
rescue Aws::Shield::Errors::ServiceError => e
|
53
|
+
log_error(e.code)
|
54
|
+
raise e unless suppressed_errors.include?(e.code)
|
55
|
+
|
56
|
+
[] # no access or service isn't enabled
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# not an error
|
62
|
+
def suppressed_errors
|
63
|
+
%w[
|
64
|
+
ResourceNotFoundException
|
65
|
+
]
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class SNS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_topics
|
10
|
+
#
|
11
|
+
@client.list_topics.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.topics.each do |topic|
|
15
|
+
log(response.context.operation_name, topic.topic_arn, page)
|
16
|
+
|
17
|
+
# get_topic_attributes
|
18
|
+
struct = OpenStruct.new(@client.get_topic_attributes({ topic_arn: topic.topic_arn }).attributes.to_h)
|
19
|
+
struct.type = 'topic'
|
20
|
+
struct.arn = topic.topic_arn
|
21
|
+
struct.subscriptions = []
|
22
|
+
|
23
|
+
# list_subscriptions_by_topic
|
24
|
+
@client.list_subscriptions_by_topic({ topic_arn: topic.topic_arn }).each_with_index do |response, page|
|
25
|
+
log(response.context.operation_name, topic.topic_arn, page)
|
26
|
+
|
27
|
+
response.subscriptions.each do |sub|
|
28
|
+
struct.subscriptions.push(sub.to_h)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
resources.push(struct.to_h)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
resources
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SQS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_queues
|
10
|
+
#
|
11
|
+
@client.list_queues.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.queue_urls.each do |queue|
|
15
|
+
log(response.context.operation_name, queue.downcase.split('/').last, page)
|
16
|
+
|
17
|
+
# get_queue_attributes
|
18
|
+
struct = OpenStruct.new(@client.get_queue_attributes({ queue_url: queue, attribute_names: ['All'] }).attributes.to_h)
|
19
|
+
struct.type = 'queue'
|
20
|
+
struct.arn = struct.QueueArn
|
21
|
+
|
22
|
+
resources.push(struct.to_h)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
resources
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class SSM < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_instance_information
|
10
|
+
#
|
11
|
+
@client.describe_instance_information.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.instance_information_list.each do |instance|
|
15
|
+
struct = OpenStruct.new(instance.to_h)
|
16
|
+
struct.type = 'instance'
|
17
|
+
struct.arn = instance.instance_id
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# describe_parameters
|
25
|
+
#
|
26
|
+
@client.describe_parameters.each_with_index do |response, page|
|
27
|
+
log(response.context.operation_name, page)
|
28
|
+
|
29
|
+
response.parameters.each do |parameter|
|
30
|
+
struct = OpenStruct.new(parameter.to_h)
|
31
|
+
struct.string_type = parameter.type
|
32
|
+
struct.type = 'parameter'
|
33
|
+
struct.arn = "arn:aws:#{@service}:#{@region}::parameter/#{parameter.name}"
|
34
|
+
|
35
|
+
resources.push(struct.to_h)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
resources
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Support < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_trusted_advisor_checks
|
10
|
+
#
|
11
|
+
@client.describe_trusted_advisor_checks({ language: 'en' }).each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.checks.each do |check|
|
15
|
+
struct = OpenStruct.new(check.to_h)
|
16
|
+
struct.type = 'trusted_advisor_check'
|
17
|
+
struct.arn = "arn:aws:support::trusted_advisor_check/#{check.id}"
|
18
|
+
|
19
|
+
# describe_trusted_advisor_check_result
|
20
|
+
struct.result = @client.describe_trusted_advisor_check_result({ check_id: check.id }).result.to_h
|
21
|
+
log(response.context.operation_name, 'describe_trusted_advisor_check_result', check.id)
|
22
|
+
|
23
|
+
resources.push(struct.to_h)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
resources
|
28
|
+
rescue Aws::Support::Errors::ServiceError => e
|
29
|
+
log_error(e.code)
|
30
|
+
raise e unless suppressed_errors.include?(e.code)
|
31
|
+
|
32
|
+
[] # no Support subscription
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# not an error
|
38
|
+
def suppressed_errors
|
39
|
+
%w[
|
40
|
+
SubscriptionRequiredException
|
41
|
+
]
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Transfer < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_servers
|
10
|
+
#
|
11
|
+
@client.list_servers.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.servers.each do |server|
|
15
|
+
struct = OpenStruct.new(server.to_h)
|
16
|
+
struct.type = 'server'
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class WAFV2 < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
# TODO: test live
|
6
|
+
# TODO: resolve scope (e.g. CLOUDFRONT supported?)
|
7
|
+
# TODO: confirm paging behavior
|
8
|
+
#
|
9
|
+
def collect
|
10
|
+
resources = []
|
11
|
+
|
12
|
+
#
|
13
|
+
# list_web_acls
|
14
|
+
#
|
15
|
+
# %w[CLOUDFRONT REGIONAL].each do |scope|
|
16
|
+
%w[REGIONAL].each do |scope|
|
17
|
+
@client.list_web_acls({ scope: scope }).each_with_index do |response, page|
|
18
|
+
log(response.context.operation_name, page)
|
19
|
+
|
20
|
+
response.web_acls.each do |acl|
|
21
|
+
struct = OpenStruct.new(acl.to_h)
|
22
|
+
struct.type = 'web_acl'
|
23
|
+
# struct.arn = "arn:aws:#{@service}:#{@region}::web_acl/#{acl.id}"
|
24
|
+
|
25
|
+
params = {
|
26
|
+
name: acl.name,
|
27
|
+
scope: scope,
|
28
|
+
id: acl.id
|
29
|
+
}
|
30
|
+
|
31
|
+
# get_web_acl
|
32
|
+
@client.get_web_acl(params).each do |response|
|
33
|
+
struct.arn = response.web_acl.arn
|
34
|
+
struct.details = response.web_acl
|
35
|
+
end
|
36
|
+
|
37
|
+
# list_resources_for_web_acl
|
38
|
+
@client.list_resources_for_web_acl({ web_acl_arn: 'ResourceArn' }).each do |response|
|
39
|
+
struct.resources = response.resource_arns.map(&:to_h)
|
40
|
+
end
|
41
|
+
|
42
|
+
resources.push(struct.to_h)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
resources
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class WorkSpaces < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
#
|
8
|
+
# describe_workspaces
|
9
|
+
#
|
10
|
+
@client.describe_workspaces.each_with_index do |response, page|
|
11
|
+
log(response.context.operation_name, page)
|
12
|
+
|
13
|
+
response.workspaces.each do |workspace|
|
14
|
+
struct = OpenStruct.new(workspace.to_h)
|
15
|
+
struct.type = 'workspace'
|
16
|
+
struct.arn = "arn:aws:workspaces:#{@region}::workspace/#{workspace.workspace_id}"
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class XRay < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# get_encryption_config
|
10
|
+
#
|
11
|
+
struct = OpenStruct.new
|
12
|
+
struct.config = @client.get_encryption_config.encryption_config.to_h
|
13
|
+
struct.type = 'config'
|
14
|
+
|
15
|
+
resources.push(struct.to_h)
|
16
|
+
|
17
|
+
resources
|
18
|
+
end
|
19
|
+
end
|