Skip to content

Commit 1e678f2

Browse files
author
Parag Sathaye
committed
Created new models for AWS resources
- created methods to populate the models from AWS - created models to store various AWS resources
1 parent 9f453c0 commit 1e678f2

File tree

4 files changed

+527
-0
lines changed

4 files changed

+527
-0
lines changed

apps/aws/admin.py

+21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
from django.contrib import admin
2+
from apps.aws.aws_models import (
3+
EC2Instance,
4+
S3Bucket,
5+
IAMRole,
6+
IAMPolicy,
7+
IAMInlinePolicy,
8+
LambdaFunction,
9+
SQSQueue,
10+
)
211
from .models import Resource, Application, Permission, ApplicationPermission
312

413

@@ -37,3 +46,15 @@ class ApplicationPermissionAdmin(admin.ModelAdmin):
3746
)
3847
list_filter = ("application", "resource", "permission")
3948
ordering = ("application", "resource", "permission")
49+
50+
51+
# AWS models from aws_models.py
52+
53+
# Register your models here
54+
admin.site.register(EC2Instance)
55+
admin.site.register(S3Bucket)
56+
admin.site.register(IAMRole)
57+
admin.site.register(IAMPolicy)
58+
admin.site.register(IAMInlinePolicy)
59+
admin.site.register(LambdaFunction)
60+
admin.site.register(SQSQueue)

apps/aws/aws_models.py

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
from django.db import models
2+
import boto3
3+
4+
5+
class EC2Instance(models.Model):
6+
instance_id = models.CharField(max_length=20, unique=True)
7+
name = models.CharField(max_length=255, blank=True, null=True)
8+
instance_type = models.CharField(max_length=20)
9+
region = models.CharField(max_length=20)
10+
availability_zone = models.CharField(max_length=20)
11+
public_ip = models.GenericIPAddressField(blank=True, null=True)
12+
private_ip = models.GenericIPAddressField(blank=True, null=True)
13+
state = models.CharField(max_length=20)
14+
launch_time = models.DateTimeField()
15+
iam_role = models.CharField(max_length=255, blank=True, null=True)
16+
17+
def __str__(self):
18+
return f"{self.name}" or f"{self.instance_id}"
19+
20+
21+
class S3Bucket(models.Model):
22+
name = models.CharField(max_length=255, unique=True)
23+
region = models.CharField(max_length=20)
24+
creation_date = models.DateTimeField()
25+
26+
def __str__(self):
27+
return f"{self.name}"
28+
29+
30+
class IAMPolicy(models.Model):
31+
policy_name = models.CharField(max_length=255, unique=True)
32+
policy_id = models.CharField(max_length=128, unique=True)
33+
arn = models.CharField(max_length=255)
34+
create_date = models.DateTimeField()
35+
policy_document = models.JSONField()
36+
37+
def __str__(self):
38+
return f"{self.policy_name}"
39+
40+
41+
class IAMInlinePolicy(models.Model):
42+
role = models.ForeignKey(
43+
"IAMRole", related_name="inline_policies", on_delete=models.CASCADE
44+
)
45+
policy_name = models.CharField(max_length=255)
46+
policy_document = models.JSONField()
47+
48+
def __str__(self):
49+
return f"{self.role.role_name} - {self.policy_name}"
50+
51+
52+
class IAMRole(models.Model):
53+
role_name = models.CharField(max_length=255, unique=True)
54+
role_id = models.CharField(max_length=128, unique=True)
55+
arn = models.CharField(max_length=255)
56+
create_date = models.DateTimeField()
57+
policies = models.ManyToManyField("IAMPolicy", related_name="roles")
58+
# Inline policies are linked through a ForeignKey in IAMInlinePolicy
59+
60+
def __str__(self):
61+
return f"{self.role_name}"
62+
63+
def sync_inline_policies(self, region):
64+
client = boto3.client("iam", region_name=region)
65+
policies = client.list_role_policies(RoleName=self.role_name)
66+
for policy_name in policies["PolicyNames"]:
67+
policy = client.get_role_policy(
68+
RoleName=self.role_name, PolicyName=policy_name
69+
)
70+
IAMInlinePolicy.objects.update_or_create(
71+
role=self,
72+
policy_name=policy_name,
73+
defaults={"policy_document": policy["PolicyDocument"]},
74+
)
75+
76+
def attach_inline_policy(self, policy_name, policy_document, region):
77+
client = boto3.client("iam", region_name=region)
78+
client.put_role_policy(
79+
RoleName=self.role_name,
80+
PolicyName=policy_name,
81+
PolicyDocument=policy_document,
82+
)
83+
IAMInlinePolicy.objects.create(
84+
role=self, policy_name=policy_name, policy_document=policy_document
85+
)
86+
87+
def delete_inline_policy(self, policy_name, region):
88+
client = boto3.client("iam", region_name=region)
89+
client.delete_role_policy(RoleName=self.role_name, PolicyName=policy_name)
90+
IAMInlinePolicy.objects.filter(role=self, policy_name=policy_name).delete()
91+
92+
93+
class IAMPermission(models.Model):
94+
action = models.CharField(max_length=255)
95+
resource = models.CharField(max_length=255)
96+
97+
def __str__(self):
98+
return f"Action: {self.action}, Resource: {self.resource}"
99+
100+
101+
class LambdaFunction(models.Model):
102+
function_name = models.CharField(max_length=255, unique=True)
103+
function_arn = models.CharField(max_length=255, unique=True)
104+
runtime = models.CharField(max_length=64)
105+
handler = models.CharField(max_length=255)
106+
role = models.CharField(max_length=255)
107+
code_size = models.BigIntegerField()
108+
description = models.TextField(blank=True, null=True)
109+
timeout = models.IntegerField()
110+
memory_size = models.IntegerField()
111+
last_modified = models.DateTimeField()
112+
region = models.CharField(max_length=64)
113+
114+
def __str__(self):
115+
return f"{self.function_name}"
116+
117+
118+
class SQSQueue(models.Model):
119+
queue_name = models.CharField(max_length=255, unique=True)
120+
queue_url = models.URLField(max_length=1024, unique=True)
121+
region = models.CharField(max_length=64)
122+
arn = models.CharField(max_length=255, unique=True)
123+
created_timestamp = models.DateTimeField()
124+
visibility_timeout = models.IntegerField()
125+
maximum_message_size = models.IntegerField()
126+
message_retention_period = models.IntegerField()
127+
128+
def __str__(self):
129+
return f"{self.queue_name}"

apps/aws/aws_shared.py

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
from datetime import datetime
2+
import boto3
3+
from apps.aws.aws_models import (
4+
IAMRole,
5+
IAMPolicy,
6+
IAMInlinePolicy,
7+
EC2Instance,
8+
S3Bucket,
9+
LambdaFunction,
10+
SQSQueue,
11+
)
12+
13+
14+
def populate_iam_roles_and_policies(region_name):
15+
# Initialize boto3 IAM client
16+
client = boto3.client("iam", region_name=region_name)
17+
18+
# Get list of all IAM roles
19+
roles = client.list_roles()
20+
21+
for role_data in roles["Roles"]:
22+
role, _ = IAMRole.objects.update_or_create(
23+
role_name=role_data["RoleName"],
24+
defaults={
25+
"role_id": role_data["RoleId"],
26+
"arn": role_data["Arn"],
27+
"create_date": role_data["CreateDate"],
28+
},
29+
)
30+
31+
# Fetch and attach managed policies to the role
32+
attached_policies = client.list_attached_role_policies(RoleName=role.role_name)
33+
for policy in attached_policies["AttachedPolicies"]:
34+
policy_details = client.get_policy(PolicyArn=policy["PolicyArn"])
35+
policy_version = client.get_policy_version(
36+
PolicyArn=policy["PolicyArn"],
37+
VersionId=policy_details["Policy"]["DefaultVersionId"],
38+
)
39+
iam_policy, _ = IAMPolicy.objects.update_or_create(
40+
policy_name=policy["PolicyName"],
41+
defaults={
42+
"policy_id": policy_details["Policy"]["PolicyId"],
43+
"arn": policy_details["Policy"]["Arn"],
44+
"create_date": policy_details["Policy"]["CreateDate"],
45+
"policy_document": policy_version["PolicyVersion"]["Document"],
46+
},
47+
)
48+
# Only add the policy if it's attached to the current role
49+
role.policies.add(iam_policy)
50+
print(
51+
f"Attached policy: {iam_policy.policy_name} to role: {role.role_name}"
52+
)
53+
54+
print(f"Populated IAM roles and policies for region: {region_name}")
55+
56+
57+
def populate_iam_inline_policies(region_name):
58+
client = boto3.client("iam", region_name=region_name)
59+
60+
# Iterate over all roles in the database
61+
for role in IAMRole.objects.all():
62+
inline_policies = client.list_role_policies(RoleName=role.role_name)
63+
64+
for policy_name in inline_policies["PolicyNames"]:
65+
policy = client.get_role_policy(
66+
RoleName=role.role_name, PolicyName=policy_name
67+
)
68+
IAMInlinePolicy.objects.update_or_create(
69+
role=role,
70+
policy_name=policy_name,
71+
defaults={"policy_document": policy["PolicyDocument"]},
72+
)
73+
74+
print(f"Populated IAM inline policies for region: {region_name}")
75+
76+
77+
def populate_ec2_instances(region_name):
78+
client = boto3.client("ec2", region_name=region_name)
79+
80+
instances = client.describe_instances()
81+
82+
for reservation in instances["Reservations"]:
83+
for instance_data in reservation["Instances"]:
84+
EC2Instance.objects.update_or_create(
85+
instance_id=instance_data["InstanceId"],
86+
defaults={
87+
"name": next(
88+
(
89+
tag["Value"]
90+
for tag in instance_data.get("Tags", [])
91+
if tag["Key"] == "Name"
92+
),
93+
None,
94+
),
95+
"instance_type": instance_data["InstanceType"],
96+
"region": region_name,
97+
"availability_zone": instance_data["Placement"]["AvailabilityZone"],
98+
"public_ip": instance_data.get("PublicIpAddress"),
99+
"private_ip": instance_data.get("PrivateIpAddress"),
100+
"state": instance_data["State"]["Name"],
101+
"launch_time": instance_data["LaunchTime"],
102+
"iam_role": instance_data.get("IamInstanceProfile", {}).get("Arn"),
103+
},
104+
)
105+
106+
print(f"Populated EC2 instances for region: {region_name}")
107+
108+
109+
def populate_s3_buckets(region_name):
110+
client = boto3.client("s3", region_name=region_name)
111+
112+
buckets = client.list_buckets()
113+
114+
for bucket_data in buckets["Buckets"]:
115+
bucket_location = client.get_bucket_location(Bucket=bucket_data["Name"])
116+
bucket_region = bucket_location["LocationConstraint"] or "us-east-1"
117+
if bucket_region == region_name:
118+
S3Bucket.objects.update_or_create(
119+
name=bucket_data["Name"],
120+
defaults={
121+
"region": bucket_region,
122+
"creation_date": bucket_data["CreationDate"],
123+
},
124+
)
125+
126+
print(f"Populated S3 buckets for region: {region_name}")
127+
128+
129+
def populate_lambda_functions(region_name):
130+
client = boto3.client("lambda", region_name=region_name)
131+
132+
functions = client.list_functions()
133+
134+
for function_data in functions["Functions"]:
135+
LambdaFunction.objects.update_or_create(
136+
function_name=function_data["FunctionName"],
137+
defaults={
138+
"function_arn": function_data["FunctionArn"],
139+
"runtime": function_data["Runtime"],
140+
"handler": function_data["Handler"],
141+
"role": function_data["Role"],
142+
"code_size": function_data["CodeSize"],
143+
"description": function_data.get("Description", ""),
144+
"timeout": function_data["Timeout"],
145+
"memory_size": function_data["MemorySize"],
146+
"last_modified": function_data["LastModified"],
147+
"region": region_name,
148+
},
149+
)
150+
151+
print(f"Populated Lambda functions for region: {region_name}")
152+
153+
154+
def populate_sqs_queues(region_name):
155+
client = boto3.client("sqs", region_name=region_name)
156+
157+
queues = client.list_queues()
158+
159+
if "QueueUrls" in queues:
160+
for queue_url in queues["QueueUrls"]:
161+
queue_attributes = client.get_queue_attributes(
162+
QueueUrl=queue_url, AttributeNames=["All"]
163+
)["Attributes"]
164+
165+
# Convert Unix timestamp to datetime object
166+
created_timestamp = datetime.utcfromtimestamp(
167+
float(queue_attributes["CreatedTimestamp"])
168+
)
169+
170+
SQSQueue.objects.update_or_create(
171+
queue_name=queue_attributes["QueueArn"].split(":")[-1],
172+
defaults={
173+
"queue_url": queue_url,
174+
"region": region_name,
175+
"arn": queue_attributes["QueueArn"],
176+
"created_timestamp": created_timestamp,
177+
"visibility_timeout": queue_attributes["VisibilityTimeout"],
178+
"maximum_message_size": queue_attributes["MaximumMessageSize"],
179+
"message_retention_period": queue_attributes[
180+
"MessageRetentionPeriod"
181+
],
182+
},
183+
)
184+
185+
print(f"Populated SQS queues for region: {region_name}")
186+
187+
188+
def populate_aws_resources(region_name):
189+
populate_iam_roles_and_policies(region_name)
190+
populate_iam_inline_policies(region_name)
191+
populate_ec2_instances(region_name)
192+
populate_s3_buckets(region_name)
193+
populate_lambda_functions(region_name)
194+
populate_sqs_queues(region_name)

0 commit comments

Comments
 (0)