cartography 0.102.0rc1__py3-none-any.whl → 0.103.0__py3-none-any.whl

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.

Potentially problematic release.


This version of cartography might be problematic. Click here for more details.

Files changed (297) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +2 -2
  3. cartography/cli.py +376 -249
  4. cartography/client/core/tx.py +39 -18
  5. cartography/config.py +28 -0
  6. cartography/driftdetect/__main__.py +1 -2
  7. cartography/driftdetect/add_shortcut.py +10 -2
  8. cartography/driftdetect/cli.py +71 -75
  9. cartography/driftdetect/detect_deviations.py +7 -3
  10. cartography/driftdetect/get_states.py +20 -8
  11. cartography/driftdetect/model.py +5 -5
  12. cartography/driftdetect/serializers.py +8 -6
  13. cartography/driftdetect/storage.py +2 -2
  14. cartography/graph/cleanupbuilder.py +35 -15
  15. cartography/graph/job.py +46 -17
  16. cartography/graph/querybuilder.py +165 -80
  17. cartography/graph/statement.py +35 -26
  18. cartography/intel/analysis.py +4 -1
  19. cartography/intel/aws/__init__.py +114 -55
  20. cartography/intel/aws/apigateway.py +134 -63
  21. cartography/intel/aws/cloudtrail.py +127 -0
  22. cartography/intel/aws/cloudwatch.py +93 -0
  23. cartography/intel/aws/config.py +56 -20
  24. cartography/intel/aws/dynamodb.py +108 -40
  25. cartography/intel/aws/ec2/__init__.py +2 -2
  26. cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
  27. cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
  28. cartography/intel/aws/ec2/images.py +49 -20
  29. cartography/intel/aws/ec2/instances.py +234 -136
  30. cartography/intel/aws/ec2/internet_gateways.py +40 -11
  31. cartography/intel/aws/ec2/key_pairs.py +44 -20
  32. cartography/intel/aws/ec2/launch_templates.py +101 -59
  33. cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
  34. cartography/intel/aws/ec2/load_balancers.py +82 -42
  35. cartography/intel/aws/ec2/network_acls.py +89 -65
  36. cartography/intel/aws/ec2/network_interfaces.py +146 -87
  37. cartography/intel/aws/ec2/reserved_instances.py +45 -16
  38. cartography/intel/aws/ec2/route_tables.py +327 -0
  39. cartography/intel/aws/ec2/security_groups.py +71 -21
  40. cartography/intel/aws/ec2/snapshots.py +61 -22
  41. cartography/intel/aws/ec2/subnets.py +54 -18
  42. cartography/intel/aws/ec2/tgw.py +100 -34
  43. cartography/intel/aws/ec2/util.py +1 -1
  44. cartography/intel/aws/ec2/volumes.py +69 -41
  45. cartography/intel/aws/ec2/vpc.py +37 -12
  46. cartography/intel/aws/ec2/vpc_peerings.py +83 -24
  47. cartography/intel/aws/ecr.py +88 -32
  48. cartography/intel/aws/ecs.py +83 -47
  49. cartography/intel/aws/efs.py +93 -0
  50. cartography/intel/aws/eks.py +55 -29
  51. cartography/intel/aws/elasticache.py +42 -18
  52. cartography/intel/aws/elasticsearch.py +57 -20
  53. cartography/intel/aws/emr.py +61 -23
  54. cartography/intel/aws/iam.py +401 -145
  55. cartography/intel/aws/iam_instance_profiles.py +22 -22
  56. cartography/intel/aws/identitycenter.py +71 -37
  57. cartography/intel/aws/inspector.py +159 -89
  58. cartography/intel/aws/kms.py +92 -38
  59. cartography/intel/aws/lambda_function.py +103 -34
  60. cartography/intel/aws/organizations.py +30 -10
  61. cartography/intel/aws/permission_relationships.py +133 -51
  62. cartography/intel/aws/rds.py +249 -85
  63. cartography/intel/aws/redshift.py +107 -46
  64. cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
  65. cartography/intel/aws/resources.py +57 -44
  66. cartography/intel/aws/route53.py +108 -61
  67. cartography/intel/aws/s3.py +168 -83
  68. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  69. cartography/intel/aws/secretsmanager.py +24 -12
  70. cartography/intel/aws/securityhub.py +20 -9
  71. cartography/intel/aws/sns.py +166 -0
  72. cartography/intel/aws/sqs.py +60 -28
  73. cartography/intel/aws/ssm.py +70 -30
  74. cartography/intel/aws/util/arns.py +7 -7
  75. cartography/intel/aws/util/common.py +31 -4
  76. cartography/intel/azure/__init__.py +78 -19
  77. cartography/intel/azure/compute.py +101 -27
  78. cartography/intel/azure/cosmosdb.py +496 -170
  79. cartography/intel/azure/sql.py +296 -105
  80. cartography/intel/azure/storage.py +322 -113
  81. cartography/intel/azure/subscription.py +39 -23
  82. cartography/intel/azure/tenant.py +13 -4
  83. cartography/intel/azure/util/credentials.py +95 -55
  84. cartography/intel/bigfix/__init__.py +2 -2
  85. cartography/intel/bigfix/computers.py +93 -65
  86. cartography/intel/cloudflare/__init__.py +74 -0
  87. cartography/intel/cloudflare/accounts.py +57 -0
  88. cartography/intel/cloudflare/dnsrecords.py +64 -0
  89. cartography/intel/cloudflare/members.py +75 -0
  90. cartography/intel/cloudflare/roles.py +65 -0
  91. cartography/intel/cloudflare/zones.py +64 -0
  92. cartography/intel/create_indexes.py +3 -2
  93. cartography/intel/crowdstrike/__init__.py +11 -9
  94. cartography/intel/crowdstrike/endpoints.py +5 -1
  95. cartography/intel/crowdstrike/spotlight.py +8 -3
  96. cartography/intel/cve/__init__.py +46 -13
  97. cartography/intel/cve/feed.py +48 -12
  98. cartography/intel/digitalocean/__init__.py +22 -13
  99. cartography/intel/digitalocean/compute.py +75 -108
  100. cartography/intel/digitalocean/management.py +44 -80
  101. cartography/intel/digitalocean/platform.py +48 -43
  102. cartography/intel/dns.py +36 -10
  103. cartography/intel/duo/__init__.py +21 -16
  104. cartography/intel/duo/api_host.py +14 -9
  105. cartography/intel/duo/endpoints.py +50 -45
  106. cartography/intel/duo/groups.py +18 -14
  107. cartography/intel/duo/phones.py +37 -34
  108. cartography/intel/duo/tokens.py +26 -23
  109. cartography/intel/duo/users.py +54 -50
  110. cartography/intel/duo/web_authn_credentials.py +30 -25
  111. cartography/intel/entra/__init__.py +25 -7
  112. cartography/intel/entra/ou.py +112 -0
  113. cartography/intel/entra/users.py +69 -63
  114. cartography/intel/gcp/__init__.py +185 -49
  115. cartography/intel/gcp/compute.py +418 -231
  116. cartography/intel/gcp/crm.py +96 -43
  117. cartography/intel/gcp/dns.py +60 -19
  118. cartography/intel/gcp/gke.py +72 -38
  119. cartography/intel/gcp/iam.py +61 -41
  120. cartography/intel/gcp/storage.py +84 -55
  121. cartography/intel/github/__init__.py +13 -11
  122. cartography/intel/github/repos.py +270 -137
  123. cartography/intel/github/teams.py +170 -88
  124. cartography/intel/github/users.py +70 -39
  125. cartography/intel/github/util.py +36 -34
  126. cartography/intel/gsuite/__init__.py +47 -26
  127. cartography/intel/gsuite/api.py +73 -30
  128. cartography/intel/jamf/__init__.py +19 -1
  129. cartography/intel/jamf/computers.py +30 -7
  130. cartography/intel/jamf/util.py +7 -2
  131. cartography/intel/kandji/__init__.py +6 -3
  132. cartography/intel/kandji/devices.py +14 -8
  133. cartography/intel/kubernetes/namespaces.py +7 -4
  134. cartography/intel/kubernetes/pods.py +7 -4
  135. cartography/intel/kubernetes/services.py +8 -4
  136. cartography/intel/lastpass/__init__.py +2 -2
  137. cartography/intel/lastpass/users.py +23 -12
  138. cartography/intel/oci/__init__.py +44 -11
  139. cartography/intel/oci/iam.py +134 -38
  140. cartography/intel/oci/organizations.py +13 -6
  141. cartography/intel/oci/utils.py +43 -20
  142. cartography/intel/okta/__init__.py +66 -15
  143. cartography/intel/okta/applications.py +42 -20
  144. cartography/intel/okta/awssaml.py +93 -33
  145. cartography/intel/okta/factors.py +16 -4
  146. cartography/intel/okta/groups.py +56 -29
  147. cartography/intel/okta/organization.py +5 -1
  148. cartography/intel/okta/origins.py +6 -2
  149. cartography/intel/okta/roles.py +15 -5
  150. cartography/intel/okta/users.py +20 -8
  151. cartography/intel/okta/utils.py +6 -4
  152. cartography/intel/openai/__init__.py +86 -0
  153. cartography/intel/openai/adminapikeys.py +90 -0
  154. cartography/intel/openai/apikeys.py +96 -0
  155. cartography/intel/openai/projects.py +94 -0
  156. cartography/intel/openai/serviceaccounts.py +82 -0
  157. cartography/intel/openai/users.py +78 -0
  158. cartography/intel/openai/util.py +29 -0
  159. cartography/intel/pagerduty/__init__.py +8 -7
  160. cartography/intel/pagerduty/escalation_policies.py +18 -6
  161. cartography/intel/pagerduty/schedules.py +12 -4
  162. cartography/intel/pagerduty/services.py +11 -4
  163. cartography/intel/pagerduty/teams.py +8 -3
  164. cartography/intel/pagerduty/users.py +3 -1
  165. cartography/intel/pagerduty/vendors.py +3 -1
  166. cartography/intel/semgrep/__init__.py +24 -6
  167. cartography/intel/semgrep/dependencies.py +50 -28
  168. cartography/intel/semgrep/deployment.py +3 -1
  169. cartography/intel/semgrep/findings.py +42 -18
  170. cartography/intel/snipeit/__init__.py +17 -3
  171. cartography/intel/snipeit/asset.py +12 -6
  172. cartography/intel/snipeit/user.py +8 -5
  173. cartography/intel/snipeit/util.py +9 -4
  174. cartography/intel/tailscale/__init__.py +77 -0
  175. cartography/intel/tailscale/acls.py +146 -0
  176. cartography/intel/tailscale/devices.py +127 -0
  177. cartography/intel/tailscale/postureintegrations.py +81 -0
  178. cartography/intel/tailscale/tailnets.py +76 -0
  179. cartography/intel/tailscale/users.py +80 -0
  180. cartography/intel/tailscale/utils.py +132 -0
  181. cartography/models/aws/apigateway.py +21 -17
  182. cartography/models/aws/apigatewaycertificate.py +28 -22
  183. cartography/models/aws/apigatewayresource.py +28 -20
  184. cartography/models/aws/apigatewaystage.py +33 -25
  185. cartography/models/aws/cloudtrail/__init__.py +0 -0
  186. cartography/models/aws/cloudtrail/trail.py +61 -0
  187. cartography/models/aws/cloudwatch/__init__.py +0 -0
  188. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  189. cartography/models/aws/dynamodb/gsi.py +30 -22
  190. cartography/models/aws/dynamodb/tables.py +25 -17
  191. cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
  192. cartography/models/aws/ec2/images.py +36 -34
  193. cartography/models/aws/ec2/instances.py +51 -45
  194. cartography/models/aws/ec2/keypair.py +21 -16
  195. cartography/models/aws/ec2/keypair_instance.py +28 -21
  196. cartography/models/aws/ec2/launch_configurations.py +30 -26
  197. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  198. cartography/models/aws/ec2/launch_templates.py +21 -17
  199. cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
  200. cartography/models/aws/ec2/load_balancers.py +47 -37
  201. cartography/models/aws/ec2/network_acl_rules.py +38 -30
  202. cartography/models/aws/ec2/network_acls.py +38 -29
  203. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  204. cartography/models/aws/ec2/networkinterfaces.py +53 -37
  205. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  206. cartography/models/aws/ec2/reservations.py +18 -14
  207. cartography/models/aws/ec2/route_table_associations.py +97 -0
  208. cartography/models/aws/ec2/route_tables.py +128 -0
  209. cartography/models/aws/ec2/routes.py +85 -0
  210. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  211. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  212. cartography/models/aws/ec2/subnet_instance.py +24 -19
  213. cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
  214. cartography/models/aws/ec2/volumes.py +47 -40
  215. cartography/models/aws/efs/__init__.py +0 -0
  216. cartography/models/aws/efs/mount_target.py +52 -0
  217. cartography/models/aws/eks/clusters.py +23 -21
  218. cartography/models/aws/emr.py +32 -30
  219. cartography/models/aws/iam/instanceprofile.py +33 -24
  220. cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
  221. cartography/models/aws/identitycenter/awspermissionset.py +37 -29
  222. cartography/models/aws/identitycenter/awsssouser.py +23 -21
  223. cartography/models/aws/inspector/findings.py +77 -65
  224. cartography/models/aws/inspector/packages.py +35 -29
  225. cartography/models/aws/s3/__init__.py +0 -0
  226. cartography/models/aws/s3/account_public_access_block.py +51 -0
  227. cartography/models/aws/sns/__init__.py +0 -0
  228. cartography/models/aws/sns/topic.py +50 -0
  229. cartography/models/aws/ssm/instance_information.py +51 -39
  230. cartography/models/aws/ssm/instance_patch.py +32 -26
  231. cartography/models/bigfix/bigfix_computer.py +42 -38
  232. cartography/models/bigfix/bigfix_root.py +3 -3
  233. cartography/models/cloudflare/__init__.py +0 -0
  234. cartography/models/cloudflare/account.py +25 -0
  235. cartography/models/cloudflare/dnsrecord.py +55 -0
  236. cartography/models/cloudflare/member.py +82 -0
  237. cartography/models/cloudflare/role.py +44 -0
  238. cartography/models/cloudflare/zone.py +59 -0
  239. cartography/models/core/common.py +12 -10
  240. cartography/models/core/nodes.py +5 -2
  241. cartography/models/core/relationships.py +14 -6
  242. cartography/models/crowdstrike/hosts.py +37 -35
  243. cartography/models/cve/cve.py +34 -32
  244. cartography/models/cve/cve_feed.py +6 -6
  245. cartography/models/digitalocean/__init__.py +0 -0
  246. cartography/models/digitalocean/account.py +21 -0
  247. cartography/models/digitalocean/droplet.py +56 -0
  248. cartography/models/digitalocean/project.py +48 -0
  249. cartography/models/duo/api_host.py +3 -3
  250. cartography/models/duo/endpoint.py +43 -41
  251. cartography/models/duo/group.py +14 -14
  252. cartography/models/duo/phone.py +27 -27
  253. cartography/models/duo/token.py +16 -16
  254. cartography/models/duo/user.py +46 -44
  255. cartography/models/duo/web_authn_credential.py +27 -19
  256. cartography/models/entra/ou.py +48 -0
  257. cartography/models/entra/tenant.py +24 -18
  258. cartography/models/entra/user.py +64 -48
  259. cartography/models/gcp/iam.py +23 -23
  260. cartography/models/github/orgs.py +5 -4
  261. cartography/models/github/teams.py +37 -31
  262. cartography/models/github/users.py +34 -23
  263. cartography/models/kandji/device.py +22 -16
  264. cartography/models/kandji/tenant.py +6 -4
  265. cartography/models/lastpass/tenant.py +3 -3
  266. cartography/models/lastpass/user.py +32 -28
  267. cartography/models/openai/__init__.py +0 -0
  268. cartography/models/openai/adminapikey.py +90 -0
  269. cartography/models/openai/apikey.py +84 -0
  270. cartography/models/openai/organization.py +17 -0
  271. cartography/models/openai/project.py +70 -0
  272. cartography/models/openai/serviceaccount.py +50 -0
  273. cartography/models/openai/user.py +49 -0
  274. cartography/models/semgrep/dependencies.py +36 -24
  275. cartography/models/semgrep/deployment.py +5 -5
  276. cartography/models/semgrep/findings.py +58 -42
  277. cartography/models/semgrep/locations.py +27 -21
  278. cartography/models/snipeit/asset.py +30 -21
  279. cartography/models/snipeit/tenant.py +6 -4
  280. cartography/models/snipeit/user.py +19 -12
  281. cartography/models/tailscale/__init__.py +0 -0
  282. cartography/models/tailscale/device.py +95 -0
  283. cartography/models/tailscale/group.py +86 -0
  284. cartography/models/tailscale/postureintegration.py +58 -0
  285. cartography/models/tailscale/tag.py +102 -0
  286. cartography/models/tailscale/tailnet.py +29 -0
  287. cartography/models/tailscale/user.py +52 -0
  288. cartography/stats.py +3 -3
  289. cartography/sync.py +113 -31
  290. cartography/util.py +84 -62
  291. {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/METADATA +8 -15
  292. cartography-0.103.0.dist-info/RECORD +442 -0
  293. {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/WHEEL +1 -1
  294. cartography-0.102.0rc1.dist-info/RECORD +0 -377
  295. {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/entry_points.txt +0 -0
  296. {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/licenses/LICENSE +0 -0
  297. {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/top_level.txt +0 -0
@@ -11,12 +11,18 @@ import neo4j
11
11
  from cartography.client.core.tx import load
12
12
  from cartography.graph.job import GraphJob
13
13
  from cartography.intel.aws.ec2.util import get_botocore_config
14
- from cartography.models.aws.ec2.auto_scaling_groups import EC2InstanceAutoScalingGroupSchema
14
+ from cartography.models.aws.ec2.auto_scaling_groups import (
15
+ EC2InstanceAutoScalingGroupSchema,
16
+ )
15
17
  from cartography.models.aws.ec2.instances import EC2InstanceSchema
16
18
  from cartography.models.aws.ec2.keypair_instance import EC2KeyPairInstanceSchema
17
- from cartography.models.aws.ec2.networkinterface_instance import EC2NetworkInterfaceInstanceSchema
19
+ from cartography.models.aws.ec2.networkinterface_instance import (
20
+ EC2NetworkInterfaceInstanceSchema,
21
+ )
18
22
  from cartography.models.aws.ec2.reservations import EC2ReservationSchema
19
- from cartography.models.aws.ec2.securitygroup_instance import EC2SecurityGroupInstanceSchema
23
+ from cartography.models.aws.ec2.securitygroup_instance import (
24
+ EC2SecurityGroupInstanceSchema,
25
+ )
20
26
  from cartography.models.aws.ec2.subnet_instance import EC2SubnetInstanceSchema
21
27
  from cartography.models.aws.ec2.volumes import EBSVolumeInstanceSchema
22
28
  from cartography.util import aws_handle_regions
@@ -25,7 +31,8 @@ from cartography.util import timeit
25
31
  logger = logging.getLogger(__name__)
26
32
 
27
33
  Ec2Data = namedtuple(
28
- 'Ec2Data', [
34
+ "Ec2Data",
35
+ [
29
36
  "reservation_list",
30
37
  "instance_list",
31
38
  "subnet_list",
@@ -40,15 +47,23 @@ Ec2Data = namedtuple(
40
47
  @timeit
41
48
  @aws_handle_regions
42
49
  def get_ec2_instances(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
43
- client = boto3_session.client('ec2', region_name=region, config=get_botocore_config())
44
- paginator = client.get_paginator('describe_instances')
50
+ client = boto3_session.client(
51
+ "ec2",
52
+ region_name=region,
53
+ config=get_botocore_config(),
54
+ )
55
+ paginator = client.get_paginator("describe_instances")
45
56
  reservations: List[Dict[str, Any]] = []
46
57
  for page in paginator.paginate():
47
- reservations.extend(page['Reservations'])
58
+ reservations.extend(page["Reservations"])
48
59
  return reservations
49
60
 
50
61
 
51
- def transform_ec2_instances(reservations: List[Dict[str, Any]], region: str, current_aws_account_id: str) -> Ec2Data:
62
+ def transform_ec2_instances(
63
+ reservations: List[Dict[str, Any]],
64
+ region: str,
65
+ current_aws_account_id: str,
66
+ ) -> Ec2Data:
52
67
  reservation_list = []
53
68
  instance_list = []
54
69
  subnet_list = []
@@ -58,92 +73,119 @@ def transform_ec2_instances(reservations: List[Dict[str, Any]], region: str, cur
58
73
  instance_ebs_volumes_list = []
59
74
 
60
75
  for reservation in reservations:
61
- reservation_id = reservation['ReservationId']
62
- reservation_list.append({
63
- 'RequesterId': reservation.get('RequesterId'),
64
- 'ReservationId': reservation['ReservationId'],
65
- 'OwnerId': reservation['OwnerId'],
66
- })
67
- for instance in reservation['Instances']:
68
- instance_id = instance['InstanceId']
76
+ reservation_id = reservation["ReservationId"]
77
+ reservation_list.append(
78
+ {
79
+ "RequesterId": reservation.get("RequesterId"),
80
+ "ReservationId": reservation["ReservationId"],
81
+ "OwnerId": reservation["OwnerId"],
82
+ },
83
+ )
84
+ for instance in reservation["Instances"]:
85
+ instance_id = instance["InstanceId"]
69
86
  launch_time = instance.get("LaunchTime")
70
- launch_time_unix = str(time.mktime(launch_time.timetuple())) if launch_time else None
87
+ launch_time_unix = (
88
+ str(time.mktime(launch_time.timetuple())) if launch_time else None
89
+ )
71
90
  instance_list.append(
72
91
  {
73
- 'InstanceId': instance_id,
74
- 'ReservationId': reservation_id,
75
- 'PublicDnsName': instance.get("PublicDnsName"),
76
- 'PublicIpAddress': instance.get("PublicIpAddress"),
77
- 'PrivateIpAddress': instance.get("PrivateIpAddress"),
78
- 'ImageId': instance.get("ImageId"),
79
- 'InstanceType': instance.get("InstanceType"),
80
- 'IamInstanceProfile': instance.get("IamInstanceProfile", {}).get("Arn"),
81
- 'MonitoringState': instance.get("Monitoring", {}).get("State"),
82
- 'LaunchTime': instance.get("LaunchTime"),
83
- 'LaunchTimeUnix': launch_time_unix,
84
- 'State': instance.get("State", {}).get("Name"),
85
- 'AvailabilityZone': instance.get("Placement", {}).get("AvailabilityZone"),
86
- 'Tenancy': instance.get("Placement", {}).get("Tenancy"),
87
- 'HostResourceGroupArn': instance.get("Placement", {}).get("HostResourceGroupArn"),
88
- 'Platform': instance.get("Platform"),
89
- 'Architecture': instance.get("Architecture"),
90
- 'EbsOptimized': instance.get("EbsOptimized"),
91
- 'BootMode': instance.get("BootMode"),
92
- 'InstanceLifecycle': instance.get("InstanceLifecycle"),
93
- 'HibernationOptions': instance.get("HibernationOptions", {}).get("Configured"),
92
+ "InstanceId": instance_id,
93
+ "ReservationId": reservation_id,
94
+ "PublicDnsName": instance.get("PublicDnsName"),
95
+ "PublicIpAddress": instance.get("PublicIpAddress"),
96
+ "PrivateIpAddress": instance.get("PrivateIpAddress"),
97
+ "ImageId": instance.get("ImageId"),
98
+ "InstanceType": instance.get("InstanceType"),
99
+ "IamInstanceProfile": instance.get("IamInstanceProfile", {}).get(
100
+ "Arn",
101
+ ),
102
+ "MonitoringState": instance.get("Monitoring", {}).get("State"),
103
+ "LaunchTime": instance.get("LaunchTime"),
104
+ "LaunchTimeUnix": launch_time_unix,
105
+ "State": instance.get("State", {}).get("Name"),
106
+ "AvailabilityZone": instance.get("Placement", {}).get(
107
+ "AvailabilityZone",
108
+ ),
109
+ "Tenancy": instance.get("Placement", {}).get("Tenancy"),
110
+ "HostResourceGroupArn": instance.get("Placement", {}).get(
111
+ "HostResourceGroupArn",
112
+ ),
113
+ "Platform": instance.get("Platform"),
114
+ "Architecture": instance.get("Architecture"),
115
+ "EbsOptimized": instance.get("EbsOptimized"),
116
+ "BootMode": instance.get("BootMode"),
117
+ "InstanceLifecycle": instance.get("InstanceLifecycle"),
118
+ "HibernationOptions": instance.get("HibernationOptions", {}).get(
119
+ "Configured",
120
+ ),
94
121
  },
95
122
  )
96
123
 
97
- subnet_id = instance.get('SubnetId')
124
+ subnet_id = instance.get("SubnetId")
98
125
  if subnet_id:
99
126
  subnet_list.append(
100
127
  {
101
- 'SubnetId': subnet_id,
102
- 'InstanceId': instance_id,
128
+ "SubnetId": subnet_id,
129
+ "InstanceId": instance_id,
103
130
  },
104
131
  )
105
132
 
106
133
  if instance.get("KeyName"):
107
134
  key_name = instance["KeyName"]
108
- key_pair_arn = f'arn:aws:ec2:{region}:{current_aws_account_id}:key-pair/{key_name}'
109
- keypair_list.append({
110
- 'KeyPairArn': key_pair_arn,
111
- 'KeyName': key_name,
112
- 'InstanceId': instance_id,
113
- })
135
+ key_pair_arn = (
136
+ f"arn:aws:ec2:{region}:{current_aws_account_id}:key-pair/{key_name}"
137
+ )
138
+ keypair_list.append(
139
+ {
140
+ "KeyPairArn": key_pair_arn,
141
+ "KeyName": key_name,
142
+ "InstanceId": instance_id,
143
+ },
144
+ )
114
145
 
115
146
  if instance.get("SecurityGroups"):
116
147
  for group in instance["SecurityGroups"]:
117
148
  sg_list.append(
118
149
  {
119
- 'GroupId': group['GroupId'],
120
- 'InstanceId': instance_id,
150
+ "GroupId": group["GroupId"],
151
+ "InstanceId": instance_id,
121
152
  },
122
153
  )
123
154
 
124
- for network_interface in instance['NetworkInterfaces']:
125
- for security_group in network_interface.get('Groups', []):
126
- network_interface_list.append({
127
- 'NetworkInterfaceId': network_interface['NetworkInterfaceId'],
128
- 'Status': network_interface['Status'],
129
- 'MacAddress': network_interface['MacAddress'],
130
- 'Description': network_interface['Description'],
131
- 'PrivateDnsName': network_interface.get('PrivateDnsName'),
132
- 'PrivateIpAddress': network_interface['PrivateIpAddress'],
133
- 'InstanceId': instance_id,
134
- 'SubnetId': subnet_id,
135
- 'GroupId': security_group['GroupId'],
136
- })
137
-
138
- if 'BlockDeviceMappings' in instance and len(instance['BlockDeviceMappings']) > 0:
139
- for mapping in instance['BlockDeviceMappings']:
140
- if 'VolumeId' in mapping['Ebs']:
141
- instance_ebs_volumes_list.append({
142
- 'InstanceId': instance_id,
143
- 'VolumeId': mapping['Ebs']['VolumeId'],
144
- 'DeleteOnTermination': mapping['Ebs']['DeleteOnTermination'],
145
- # 'SnapshotId': mapping['Ebs']['SnapshotId'], # TODO check on this
146
- })
155
+ for network_interface in instance["NetworkInterfaces"]:
156
+ for security_group in network_interface.get("Groups", []):
157
+ network_interface_list.append(
158
+ {
159
+ "NetworkInterfaceId": network_interface[
160
+ "NetworkInterfaceId"
161
+ ],
162
+ "Status": network_interface["Status"],
163
+ "MacAddress": network_interface["MacAddress"],
164
+ "Description": network_interface["Description"],
165
+ "PrivateDnsName": network_interface.get("PrivateDnsName"),
166
+ "PrivateIpAddress": network_interface["PrivateIpAddress"],
167
+ "InstanceId": instance_id,
168
+ "SubnetId": subnet_id,
169
+ "GroupId": security_group["GroupId"],
170
+ },
171
+ )
172
+
173
+ if (
174
+ "BlockDeviceMappings" in instance
175
+ and len(instance["BlockDeviceMappings"]) > 0
176
+ ):
177
+ for mapping in instance["BlockDeviceMappings"]:
178
+ if "VolumeId" in mapping["Ebs"]:
179
+ instance_ebs_volumes_list.append(
180
+ {
181
+ "InstanceId": instance_id,
182
+ "VolumeId": mapping["Ebs"]["VolumeId"],
183
+ "DeleteOnTermination": mapping["Ebs"][
184
+ "DeleteOnTermination"
185
+ ],
186
+ # 'SnapshotId': mapping['Ebs']['SnapshotId'], # TODO check on this
187
+ },
188
+ )
147
189
 
148
190
  return Ec2Data(
149
191
  reservation_list=reservation_list,
@@ -158,11 +200,11 @@ def transform_ec2_instances(reservations: List[Dict[str, Any]], region: str, cur
158
200
 
159
201
  @timeit
160
202
  def load_ec2_reservations(
161
- neo4j_session: neo4j.Session,
162
- reservation_list: List[Dict[str, Any]],
163
- region: str,
164
- current_aws_account_id: str,
165
- update_tag: int,
203
+ neo4j_session: neo4j.Session,
204
+ reservation_list: List[Dict[str, Any]],
205
+ region: str,
206
+ current_aws_account_id: str,
207
+ update_tag: int,
166
208
  ) -> None:
167
209
  load(
168
210
  neo4j_session,
@@ -176,11 +218,11 @@ def load_ec2_reservations(
176
218
 
177
219
  @timeit
178
220
  def load_ec2_subnets(
179
- neo4j_session: neo4j.Session,
180
- subnet_list: List[Dict[str, Any]],
181
- region: str,
182
- current_aws_account_id: str,
183
- update_tag: int,
221
+ neo4j_session: neo4j.Session,
222
+ subnet_list: List[Dict[str, Any]],
223
+ region: str,
224
+ current_aws_account_id: str,
225
+ update_tag: int,
184
226
  ) -> None:
185
227
  load(
186
228
  neo4j_session,
@@ -194,11 +236,11 @@ def load_ec2_subnets(
194
236
 
195
237
  @timeit
196
238
  def load_ec2_keypair_instances(
197
- neo4j_session: neo4j.Session,
198
- key_pair_list: List[Dict[str, Any]],
199
- region: str,
200
- current_aws_account_id: str,
201
- update_tag: int,
239
+ neo4j_session: neo4j.Session,
240
+ key_pair_list: List[Dict[str, Any]],
241
+ region: str,
242
+ current_aws_account_id: str,
243
+ update_tag: int,
202
244
  ) -> None:
203
245
  # Load EC2 keypairs as known by describe-instances.
204
246
  load(
@@ -213,11 +255,11 @@ def load_ec2_keypair_instances(
213
255
 
214
256
  @timeit
215
257
  def load_ec2_security_groups(
216
- neo4j_session: neo4j.Session,
217
- sg_list: List[Dict[str, Any]],
218
- region: str,
219
- current_aws_account_id: str,
220
- update_tag: int,
258
+ neo4j_session: neo4j.Session,
259
+ sg_list: List[Dict[str, Any]],
260
+ region: str,
261
+ current_aws_account_id: str,
262
+ update_tag: int,
221
263
  ) -> None:
222
264
  load(
223
265
  neo4j_session,
@@ -231,11 +273,11 @@ def load_ec2_security_groups(
231
273
 
232
274
  @timeit
233
275
  def load_ec2_network_interfaces(
234
- neo4j_session: neo4j.Session,
235
- network_interface_list: List[Dict[str, Any]],
236
- region: str,
237
- current_aws_account_id: str,
238
- update_tag: int,
276
+ neo4j_session: neo4j.Session,
277
+ network_interface_list: List[Dict[str, Any]],
278
+ region: str,
279
+ current_aws_account_id: str,
280
+ update_tag: int,
239
281
  ) -> None:
240
282
  load(
241
283
  neo4j_session,
@@ -249,11 +291,11 @@ def load_ec2_network_interfaces(
249
291
 
250
292
  @timeit
251
293
  def load_ec2_instance_nodes(
252
- neo4j_session: neo4j.Session,
253
- data: List[Dict],
254
- region: str,
255
- current_aws_account_id: str,
256
- update_tag: int,
294
+ neo4j_session: neo4j.Session,
295
+ data: List[Dict],
296
+ region: str,
297
+ current_aws_account_id: str,
298
+ update_tag: int,
257
299
  ) -> None:
258
300
  load(
259
301
  neo4j_session,
@@ -267,11 +309,11 @@ def load_ec2_instance_nodes(
267
309
 
268
310
  @timeit
269
311
  def load_ec2_instance_ebs_volumes(
270
- neo4j_session: neo4j.Session,
271
- ebs_data: List[Dict[str, Any]],
272
- region: str,
273
- current_aws_account_id: str,
274
- update_tag: int,
312
+ neo4j_session: neo4j.Session,
313
+ ebs_data: List[Dict[str, Any]],
314
+ region: str,
315
+ current_aws_account_id: str,
316
+ update_tag: int,
275
317
  ) -> None:
276
318
  load(
277
319
  neo4j_session,
@@ -284,46 +326,102 @@ def load_ec2_instance_ebs_volumes(
284
326
 
285
327
 
286
328
  def load_ec2_instance_data(
287
- neo4j_session: neo4j.Session,
288
- region: str,
289
- current_aws_account_id: str,
290
- update_tag: int,
291
- reservation_list: List[Dict[str, Any]],
292
- instance_list: List[Dict[str, Any]],
293
- subnet_list: List[Dict[str, Any]],
294
- sg_list: List[Dict[str, Any]],
295
- key_pair_list: List[Dict[str, Any]],
296
- nic_list: List[Dict[str, Any]],
297
- ebs_volumes_list: List[Dict[str, Any]],
329
+ neo4j_session: neo4j.Session,
330
+ region: str,
331
+ current_aws_account_id: str,
332
+ update_tag: int,
333
+ reservation_list: List[Dict[str, Any]],
334
+ instance_list: List[Dict[str, Any]],
335
+ subnet_list: List[Dict[str, Any]],
336
+ sg_list: List[Dict[str, Any]],
337
+ key_pair_list: List[Dict[str, Any]],
338
+ nic_list: List[Dict[str, Any]],
339
+ ebs_volumes_list: List[Dict[str, Any]],
298
340
  ) -> None:
299
- load_ec2_reservations(neo4j_session, reservation_list, region, current_aws_account_id, update_tag)
300
- load_ec2_instance_nodes(neo4j_session, instance_list, region, current_aws_account_id, update_tag)
301
- load_ec2_subnets(neo4j_session, subnet_list, region, current_aws_account_id, update_tag)
302
- load_ec2_security_groups(neo4j_session, sg_list, region, current_aws_account_id, update_tag)
303
- load_ec2_keypair_instances(neo4j_session, key_pair_list, region, current_aws_account_id, update_tag)
304
- load_ec2_network_interfaces(neo4j_session, nic_list, region, current_aws_account_id, update_tag)
305
- load_ec2_instance_ebs_volumes(neo4j_session, ebs_volumes_list, region, current_aws_account_id, update_tag)
341
+ load_ec2_reservations(
342
+ neo4j_session,
343
+ reservation_list,
344
+ region,
345
+ current_aws_account_id,
346
+ update_tag,
347
+ )
348
+ load_ec2_instance_nodes(
349
+ neo4j_session,
350
+ instance_list,
351
+ region,
352
+ current_aws_account_id,
353
+ update_tag,
354
+ )
355
+ load_ec2_subnets(
356
+ neo4j_session,
357
+ subnet_list,
358
+ region,
359
+ current_aws_account_id,
360
+ update_tag,
361
+ )
362
+ load_ec2_security_groups(
363
+ neo4j_session,
364
+ sg_list,
365
+ region,
366
+ current_aws_account_id,
367
+ update_tag,
368
+ )
369
+ load_ec2_keypair_instances(
370
+ neo4j_session,
371
+ key_pair_list,
372
+ region,
373
+ current_aws_account_id,
374
+ update_tag,
375
+ )
376
+ load_ec2_network_interfaces(
377
+ neo4j_session,
378
+ nic_list,
379
+ region,
380
+ current_aws_account_id,
381
+ update_tag,
382
+ )
383
+ load_ec2_instance_ebs_volumes(
384
+ neo4j_session,
385
+ ebs_volumes_list,
386
+ region,
387
+ current_aws_account_id,
388
+ update_tag,
389
+ )
306
390
 
307
391
 
308
392
  @timeit
309
- def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
393
+ def cleanup(
394
+ neo4j_session: neo4j.Session,
395
+ common_job_parameters: Dict[str, Any],
396
+ ) -> None:
310
397
  logger.debug("Running EC2 instance cleanup")
311
- GraphJob.from_node_schema(EC2ReservationSchema(), common_job_parameters).run(neo4j_session)
312
- GraphJob.from_node_schema(EC2InstanceSchema(), common_job_parameters).run(neo4j_session)
313
- GraphJob.from_node_schema(EC2InstanceAutoScalingGroupSchema(), common_job_parameters).run(neo4j_session)
398
+ GraphJob.from_node_schema(EC2ReservationSchema(), common_job_parameters).run(
399
+ neo4j_session,
400
+ )
401
+ GraphJob.from_node_schema(EC2InstanceSchema(), common_job_parameters).run(
402
+ neo4j_session,
403
+ )
404
+ GraphJob.from_node_schema(
405
+ EC2InstanceAutoScalingGroupSchema(),
406
+ common_job_parameters,
407
+ ).run(neo4j_session)
314
408
 
315
409
 
316
410
  @timeit
317
411
  def sync_ec2_instances(
318
- neo4j_session: neo4j.Session,
319
- boto3_session: boto3.session.Session,
320
- regions: List[str],
321
- current_aws_account_id: str,
322
- update_tag: int,
323
- common_job_parameters: Dict[str, Any],
412
+ neo4j_session: neo4j.Session,
413
+ boto3_session: boto3.session.Session,
414
+ regions: List[str],
415
+ current_aws_account_id: str,
416
+ update_tag: int,
417
+ common_job_parameters: Dict[str, Any],
324
418
  ) -> None:
325
419
  for region in regions:
326
- logger.info("Syncing EC2 instances for region '%s' in account '%s'.", region, current_aws_account_id)
420
+ logger.info(
421
+ "Syncing EC2 instances for region '%s' in account '%s'.",
422
+ region,
423
+ current_aws_account_id,
424
+ )
327
425
  reservations = get_ec2_instances(boto3_session, region)
328
426
  ec2_data = transform_ec2_instances(reservations, region, current_aws_account_id)
329
427
  load_ec2_instance_data(
@@ -5,25 +5,36 @@ from typing import List
5
5
  import boto3
6
6
  import neo4j
7
7
 
8
- from .util import get_botocore_config
9
8
  from cartography.util import aws_handle_regions
10
9
  from cartography.util import run_cleanup_job
11
10
  from cartography.util import timeit
12
11
 
12
+ from .util import get_botocore_config
13
+
13
14
  logger = logging.getLogger(__name__)
14
15
 
15
16
 
16
17
  @timeit
17
18
  @aws_handle_regions
18
- def get_internet_gateways(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
19
- client = boto3_session.client('ec2', region_name=region, config=get_botocore_config())
20
- return client.describe_internet_gateways()['InternetGateways']
19
+ def get_internet_gateways(
20
+ boto3_session: boto3.session.Session,
21
+ region: str,
22
+ ) -> List[Dict]:
23
+ client = boto3_session.client(
24
+ "ec2",
25
+ region_name=region,
26
+ config=get_botocore_config(),
27
+ )
28
+ return client.describe_internet_gateways()["InternetGateways"]
21
29
 
22
30
 
23
31
  @timeit
24
32
  def load_internet_gateways(
25
- neo4j_session: neo4j.Session, internet_gateways: List[Dict], region: str,
26
- current_aws_account_id: str, update_tag: int,
33
+ neo4j_session: neo4j.Session,
34
+ internet_gateways: List[Dict],
35
+ region: str,
36
+ current_aws_account_id: str,
37
+ update_tag: int,
27
38
  ) -> None:
28
39
  logger.info("Loading %d Internet Gateways in %s.", len(internet_gateways), region)
29
40
  # TODO: Right now this won't work in non-AWS commercial (GovCloud, China) as partition is hardcoded
@@ -64,17 +75,35 @@ def load_internet_gateways(
64
75
  @timeit
65
76
  def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
66
77
  logger.debug("Running Internet Gateway cleanup job.")
67
- run_cleanup_job('aws_import_internet_gateways_cleanup.json', neo4j_session, common_job_parameters)
78
+ run_cleanup_job(
79
+ "aws_import_internet_gateways_cleanup.json",
80
+ neo4j_session,
81
+ common_job_parameters,
82
+ )
68
83
 
69
84
 
70
85
  @timeit
71
86
  def sync_internet_gateways(
72
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
73
- update_tag: int, common_job_parameters: Dict,
87
+ neo4j_session: neo4j.Session,
88
+ boto3_session: boto3.session.Session,
89
+ regions: List[str],
90
+ current_aws_account_id: str,
91
+ update_tag: int,
92
+ common_job_parameters: Dict,
74
93
  ) -> None:
75
94
  for region in regions:
76
- logger.info("Syncing Internet Gateways for region '%s' in account '%s'.", region, current_aws_account_id)
95
+ logger.info(
96
+ "Syncing Internet Gateways for region '%s' in account '%s'.",
97
+ region,
98
+ current_aws_account_id,
99
+ )
77
100
  internet_gateways = get_internet_gateways(boto3_session, region)
78
- load_internet_gateways(neo4j_session, internet_gateways, region, current_aws_account_id, update_tag)
101
+ load_internet_gateways(
102
+ neo4j_session,
103
+ internet_gateways,
104
+ region,
105
+ current_aws_account_id,
106
+ update_tag,
107
+ )
79
108
 
80
109
  cleanup(neo4j_session, common_job_parameters)