Skip to content

Commit e3d4296

Browse files
Merge pull request #22 from leandrodamascena/developer
Developer to master
2 parents a0e21c6 + 40fd81b commit e3d4296

13 files changed

+858
-616
lines changed

README.md

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,32 @@ AWS Network Discovery helps you analyze what's resources are using a custom VPC.
88

99
Following services are integrated
1010

11-
- EC2
12-
- IAM POLICY
13-
- Lambda
14-
- RDS
15-
- EFS
16-
- ELASTICACHE
17-
- S3 POLICY
18-
- ELASTICSEARCH
19-
- DOCUMENTDB
20-
- SQS QUEUE POLICY
21-
- MSK
22-
- NAT GATEWAY
23-
- INTERNET GATEWAY (IGW)
24-
- CLASSIC/NETWORK/APPLICATION LOAD BALANCING
25-
- ROUTE TABLE
26-
- SUBNET
27-
- NACL
28-
- SECURITY GROUP
29-
- VPC PEERING
30-
- VPC ENDPOINT
31-
- EKS
11+
- EC2
12+
- IAM POLICY
13+
- Lambda
14+
- RDS
15+
- EFS
16+
- ELASTICACHE
17+
- S3 POLICY
18+
- ELASTICSEARCH
19+
- DOCUMENTDB
20+
- SQS QUEUE POLICY
21+
- MSK
22+
- NAT GATEWAY
23+
- INTERNET GATEWAY (IGW)
24+
- CLASSIC/NETWORK/APPLICATION LOAD BALANCING
25+
- ROUTE TABLE
26+
- SUBNET
27+
- NACL
28+
- SECURITY GROUP
29+
- VPC PEERING
30+
- VPC ENDPOINT
31+
- EKS
32+
- CLOUDFORMATION
33+
- SYNTHETIC CANARIES
34+
- EMR
35+
- ECS
36+
- AUTOSCALING
3237

3338
### News
3439

aws-network-discovery.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
from commands.vpc import Vpc
3838

39-
__version__ = "0.6.0"
39+
__version__ = "0.7.0"
4040

4141
AVAILABLE_LANGUAGES = ['en_US','pt_BR']
4242

@@ -97,4 +97,8 @@ def main():
9797

9898

9999
if __name__ == "__main__":
100-
main()
100+
try:
101+
main()
102+
except KeyboardInterrupt:
103+
print('Finishing script...')
104+
sys.exit(0)

shared/awscommands.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from shared.internal.security import IAM, IAMPOLICY
33
from shared.internal.network import VPC, IGW, NATGATEWAY, ELB, ELBV2, ROUTETABLE, SUBNET, NACL, SG, VPCPEERING
44
from shared.internal.network import VPCENDPOINT
5-
from shared.internal.compute import LAMBDA, EC2, EKS
5+
from shared.internal.compute import LAMBDA, EC2, EKS, EMR, ASG
66
from shared.internal.database import RDS, ELASTICACHE, DOCUMENTDB
77
from shared.internal.storage import EFS, S3POLICY
88
from shared.internal.analytics import ELASTICSEARCH, MSK
99
from shared.internal.application import SQSPOLICY
10+
from shared.internal.management import CLOUDFORMATION, CANARIES
11+
from shared.internal.containers import ECS
1012

1113

1214
class AwsCommands(object):
@@ -24,6 +26,8 @@ def run(self):
2426
EC2(self.vpc_options).run()
2527
LAMBDA(self.vpc_options).run()
2628
EKS(self.vpc_options).run()
29+
EMR(self.vpc_options).run()
30+
ASG(self.vpc_options).run()
2731

2832
""" Database resources """
2933
RDS(self.vpc_options).run()
@@ -55,4 +59,11 @@ def run(self):
5559
SG(self.vpc_options).run()
5660
VPCPEERING(self.vpc_options).run()
5761
VPCENDPOINT(self.vpc_options).run()
62+
63+
""" Management resources """
64+
CLOUDFORMATION(self.vpc_options).run()
65+
CANARIES(self.vpc_options).run()
66+
67+
""" Containers """
68+
ECS(self.vpc_options).run()
5869

shared/error_handler.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import functools
2+
from shared.common import *
3+
4+
def exception(func):
5+
"""
6+
Decorator to catch exceptions and avoid stop script
7+
"""
8+
@functools.wraps(func)
9+
def wrapper(*args, **kwargs):
10+
try:
11+
return func(*args, **kwargs)
12+
except Exception as e:
13+
message = "\nError running check {}. Error message {}".format(func.__qualname__, str(e))
14+
log_critical(message)
15+
pass
16+
return wrapper

shared/internal/analytics.py

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,94 @@
11
from shared.common import *
22
import json
3+
from shared.error_handler import exception
34

45
class ELASTICSEARCH(object):
56

67
def __init__(self, vpc_options: VpcOptions):
78
self.vpc_options = vpc_options
89

10+
@exception
911
def run(self):
10-
try:
11-
client = self.vpc_options.client('es')
12-
13-
response = client.list_domain_names()
14-
15-
message_handler("\nChecking ELASTICSEARCH DOMAINS...", "HEADER")
1612

17-
if len(response["DomainNames"]) == 0:
18-
message_handler("Found 0 Elastic Search Domains in region {0}".format(self.vpc_options.region_name), "OKBLUE")
19-
else:
20-
found = 0
21-
message = ""
22-
for data in response["DomainNames"]:
13+
client = self.vpc_options.client('es')
14+
15+
response = client.list_domain_names()
16+
17+
message_handler("\nChecking ELASTICSEARCH DOMAINS...", "HEADER")
2318

24-
elasticsearch_domain = client.describe_elasticsearch_domain(DomainName=data['DomainName'])
19+
if len(response["DomainNames"]) == 0:
20+
message_handler("Found 0 Elastic Search Domains in region {0}".format(self.vpc_options.region_name), "OKBLUE")
21+
else:
22+
found = 0
23+
message = ""
24+
for data in response["DomainNames"]:
2525

26-
documentpolicy = elasticsearch_domain['DomainStatus']['AccessPolicies']
26+
elasticsearch_domain = client.describe_elasticsearch_domain(DomainName=data['DomainName'])
2727

28-
document = json.dumps(documentpolicy, default=datetime_to_string)
28+
documentpolicy = elasticsearch_domain['DomainStatus']['AccessPolicies']
2929

30-
""" check either vpc_id or potencial subnet ip are found """
31-
ipvpc_found = check_ipvpc_inpolicy(document=document, vpc_options=self.vpc_options)
30+
document = json.dumps(documentpolicy, default=datetime_to_string)
3231

33-
""" elasticsearch uses accesspolicies too, so check both situation """
34-
if elasticsearch_domain['DomainStatus']['VPCOptions']['VPCId'] == self.vpc_options.vpc_id \
35-
or ipvpc_found is True:
36-
found += 1
37-
message = message + "\nDomainId: {0} - DomainName: {1} - VpcId {2}".format(
38-
elasticsearch_domain['DomainStatus']['DomainId'],
39-
elasticsearch_domain['DomainStatus']['DomainName'],
40-
self.vpc_options.vpc_id
41-
)
42-
message_handler("Found {0} ElasticSearch Domains using VPC {1} {2}".format(str(found), self.vpc_options.vpc_id, message),'OKBLUE')
43-
44-
except Exception as e:
45-
message = "Can't list ElasticSearch Domains\nError {0}".format(str(e))
46-
exit_critical(message)
32+
""" check either vpc_id or potencial subnet ip are found """
33+
ipvpc_found = check_ipvpc_inpolicy(document=document, vpc_options=self.vpc_options)
34+
35+
""" elasticsearch uses accesspolicies too, so check both situation """
36+
if elasticsearch_domain['DomainStatus']['VPCOptions']['VPCId'] == self.vpc_options.vpc_id \
37+
or ipvpc_found is True:
38+
found += 1
39+
message = message + "\nDomainId: {0} - DomainName: {1} - VpcId {2}".format(
40+
elasticsearch_domain['DomainStatus']['DomainId'],
41+
elasticsearch_domain['DomainStatus']['DomainName'],
42+
self.vpc_options.vpc_id
43+
)
44+
message_handler("Found {0} ElasticSearch Domains using VPC {1} {2}".format(str(found), self.vpc_options.vpc_id, message),'OKBLUE')
45+
46+
return True
4747

4848
class MSK(object):
4949

5050
def __init__(self, vpc_options: VpcOptions):
5151
self.vpc_options = vpc_options
5252

53+
@exception
5354
def run(self):
54-
try:
55-
client = self.vpc_options.client('kafka')
5655

57-
""" get all cache clusters """
58-
response = client.list_clusters()
56+
client = self.vpc_options.client('kafka')
57+
58+
""" get all cache clusters """
59+
response = client.list_clusters()
5960

60-
message_handler("\nChecking MSK CLUSTERS...", "HEADER")
61+
message_handler("\nChecking MSK CLUSTERS...", "HEADER")
6162

62-
if len(response['ClusterInfoList']) == 0:
63-
message_handler("Found 0 MSK Clusters in region {0}".format(self.vpc_options.region_name), "OKBLUE")
64-
else:
65-
found = 0
66-
message = ""
63+
if len(response['ClusterInfoList']) == 0:
64+
message_handler("Found 0 MSK Clusters in region {0}".format(self.vpc_options.region_name), "OKBLUE")
65+
else:
66+
found = 0
67+
message = ""
6768

68-
""" iterate cache clusters to get subnet groups """
69-
for data in response['ClusterInfoList']:
69+
""" iterate cache clusters to get subnet groups """
70+
for data in response['ClusterInfoList']:
7071

71-
msk_subnets = ", ".join(data['BrokerNodeGroupInfo']['ClientSubnets'])
72+
msk_subnets = ", ".join(data['BrokerNodeGroupInfo']['ClientSubnets'])
7273

73-
ec2 = self.vpc_options.session.resource('ec2', region_name=self.vpc_options.region_name)
74+
ec2 = self.vpc_options.session.resource('ec2', region_name=self.vpc_options.region_name)
7475

75-
filters = [{'Name':'vpc-id',
76-
'Values':[self.vpc_options.vpc_id]}]
76+
filters = [{'Name':'vpc-id',
77+
'Values':[self.vpc_options.vpc_id]}]
7778

78-
subnets = ec2.subnets.filter(Filters=filters)
79+
subnets = ec2.subnets.filter(Filters=filters)
7980

80-
for subnet in list(subnets):
81+
for subnet in list(subnets):
8182

82-
if subnet.id in msk_subnets:
83+
if subnet.id in msk_subnets:
8384

84-
found += 1
85-
message = message + "\nClusterName: {0} - VpcId: {1}".format(
86-
data['ClusterName'],
87-
self.vpc_options.vpc_id
88-
)
89-
break
85+
found += 1
86+
message = message + "\nClusterName: {0} - VpcId: {1}".format(
87+
data['ClusterName'],
88+
self.vpc_options.vpc_id
89+
)
90+
break
9091

91-
message_handler("Found {0} MSK Clusters using VPC {1} {2}".format(str(found), self.vpc_options.vpc_id, message),'OKBLUE')
92+
message_handler("Found {0} MSK Clusters using VPC {1} {2}".format(str(found), self.vpc_options.vpc_id, message),'OKBLUE')
9293

93-
except Exception as e:
94-
message = "Can't list MSK Clusters\nError {0}".format(str(e))
95-
exit_critical(message)
94+
return True

shared/internal/application.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from concurrent.futures.thread import ThreadPoolExecutor
2-
2+
from shared.error_handler import exception
33
from shared.common import *
44
import json
55

@@ -9,14 +9,13 @@ class SQSPOLICY(object):
99
def __init__(self, vpc_options: VpcOptions):
1010
self.vpc_options = vpc_options
1111

12+
@exception
1213
def run(self):
13-
try:
14-
client = self.vpc_options.client('sqs')
15-
response = client.list_queues()
16-
except Exception as e:
17-
message = "Can't list SQS Queue Policy\nError {0}".format(str(e))
18-
log_critical(message)
19-
return
14+
15+
client = self.vpc_options.client('sqs')
16+
17+
response = client.list_queues()
18+
2019
message_handler("\nChecking SQS QUEUE POLICY...", "HEADER")
2120

2221
if "QueueUrls" not in response:
@@ -34,25 +33,27 @@ def run(self):
3433
message += result[1]
3534
message_handler("Found {0} SQS Queue Policy using VPC {1} {2}".format(str(found), self.vpc_options.vpc_id, message),'OKBLUE')
3635

36+
return True
37+
38+
@exception
3739
def analyze_queues(self, client, queue):
38-
try:
39-
sqs_queue_policy = client.get_queue_attributes(QueueUrl=queue, AttributeNames=['Policy'])
40-
if "Attributes" in sqs_queue_policy:
41-
42-
""" Not sure about boto3 return """
43-
44-
documentpolicy = sqs_queue_policy['Attributes']['Policy']
45-
document = json.dumps(documentpolicy, default=datetime_to_string)
46-
47-
""" check either vpc_id or potencial subnet ip are found """
48-
ipvpc_found = check_ipvpc_inpolicy(document=document, vpc_options=self.vpc_options)
49-
50-
if ipvpc_found is not False:
51-
return True, "\nQueueUrl: {0} -> {1} -> VPC {2}".format(
52-
queue,
53-
ipvpc_found,
54-
self.vpc_options.vpc_id
55-
)
56-
except Exception as e:
57-
log_critical(str(e))
40+
41+
sqs_queue_policy = client.get_queue_attributes(QueueUrl=queue, AttributeNames=['Policy'])
42+
if "Attributes" in sqs_queue_policy:
43+
44+
""" Not sure about boto3 return """
45+
46+
documentpolicy = sqs_queue_policy['Attributes']['Policy']
47+
document = json.dumps(documentpolicy, default=datetime_to_string)
48+
49+
""" check either vpc_id or potencial subnet ip are found """
50+
ipvpc_found = check_ipvpc_inpolicy(document=document, vpc_options=self.vpc_options)
51+
52+
if ipvpc_found is not False:
53+
return True, "\nQueueUrl: {0} -> {1} -> VPC {2}".format(
54+
queue,
55+
ipvpc_found,
56+
self.vpc_options.vpc_id
57+
)
58+
5859
return False, None

0 commit comments

Comments
 (0)