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
@@ -8,20 +8,28 @@ from typing import List
8
8
  import boto3
9
9
  import neo4j
10
10
 
11
- from .util import get_botocore_config
12
11
  from cartography.client.core.tx import load
13
12
  from cartography.graph.job import GraphJob
14
13
  from cartography.models.aws.ec2.networkinterfaces import EC2NetworkInterfaceSchema
15
- from cartography.models.aws.ec2.privateip_networkinterface import EC2PrivateIpNetworkInterfaceSchema
16
- from cartography.models.aws.ec2.securitygroup_networkinterface import EC2SecurityGroupNetworkInterfaceSchema
17
- from cartography.models.aws.ec2.subnet_networkinterface import EC2SubnetNetworkInterfaceSchema
14
+ from cartography.models.aws.ec2.privateip_networkinterface import (
15
+ EC2PrivateIpNetworkInterfaceSchema,
16
+ )
17
+ from cartography.models.aws.ec2.securitygroup_networkinterface import (
18
+ EC2SecurityGroupNetworkInterfaceSchema,
19
+ )
20
+ from cartography.models.aws.ec2.subnet_networkinterface import (
21
+ EC2SubnetNetworkInterfaceSchema,
22
+ )
18
23
  from cartography.util import aws_handle_regions
19
24
  from cartography.util import timeit
20
25
 
26
+ from .util import get_botocore_config
27
+
21
28
  logger = logging.getLogger(__name__)
22
29
 
23
30
  Ec2NetworkData = namedtuple(
24
- "Ec2NetworkData", [
31
+ "Ec2NetworkData",
32
+ [
25
33
  "network_interface_list",
26
34
  "private_ip_list",
27
35
  "sg_list",
@@ -32,16 +40,26 @@ Ec2NetworkData = namedtuple(
32
40
 
33
41
  @timeit
34
42
  @aws_handle_regions
35
- def get_network_interface_data(boto3_session: boto3.session.Session, region: str) -> List[Dict[str, Any]]:
36
- client = boto3_session.client('ec2', region_name=region, config=get_botocore_config())
37
- paginator = client.get_paginator('describe_network_interfaces')
43
+ def get_network_interface_data(
44
+ boto3_session: boto3.session.Session,
45
+ region: str,
46
+ ) -> List[Dict[str, Any]]:
47
+ client = boto3_session.client(
48
+ "ec2",
49
+ region_name=region,
50
+ config=get_botocore_config(),
51
+ )
52
+ paginator = client.get_paginator("describe_network_interfaces")
38
53
  subnets: List[Dict] = []
39
54
  for page in paginator.paginate():
40
- subnets.extend(page['NetworkInterfaces'])
55
+ subnets.extend(page["NetworkInterfaces"])
41
56
  return subnets
42
57
 
43
58
 
44
- def transform_network_interface_data(data_list: List[Dict[str, Any]], region: str) -> Ec2NetworkData:
59
+ def transform_network_interface_data(
60
+ data_list: List[Dict[str, Any]],
61
+ region: str,
62
+ ) -> Ec2NetworkData:
45
63
  network_interface_list = []
46
64
  private_ip_list = []
47
65
  sg_list = []
@@ -52,45 +70,52 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
52
70
  # https://aws.amazon.com/premiumsupport/knowledge-center/elb-find-load-balancer-IP/
53
71
  elb_v1_id = None
54
72
  elb_v2_id = None
55
- elb_match = re.match(r'^ELB (?:net|app)/([^\/]+)\/(.*)', network_interface.get('Description', ''))
73
+ elb_match = re.match(
74
+ r"^ELB (?:net|app)/([^\/]+)\/(.*)",
75
+ network_interface.get("Description", ""),
76
+ )
56
77
  if elb_match:
57
- elb_v1_id = f'{elb_match[1]}-{elb_match[2]}.elb.{region}.amazonaws.com'
78
+ elb_v1_id = f"{elb_match[1]}-{elb_match[2]}.elb.{region}.amazonaws.com"
58
79
  else:
59
- elb_match = re.match(r'^ELB (.*)', network_interface.get('Description', ''))
80
+ elb_match = re.match(r"^ELB (.*)", network_interface.get("Description", ""))
60
81
  if elb_match:
61
82
  elb_v2_id = elb_match[1]
62
83
  # TODO issue #1024 change this to arn when ready
63
- network_interface_id = network_interface['NetworkInterfaceId']
84
+ network_interface_id = network_interface["NetworkInterfaceId"]
64
85
  network_interface_list.append(
65
86
  {
66
- 'Id': network_interface_id,
67
- 'NetworkInterfaceId': network_interface['NetworkInterfaceId'],
68
- 'Description': network_interface['Description'],
69
- 'InstanceId': network_interface.get('Attachment', {}).get('InstanceId'),
70
- 'InterfaceType': network_interface['InterfaceType'],
71
- 'MacAddress': network_interface['MacAddress'],
72
- 'PrivateDnsName': network_interface.get('PrivateDnsName'),
73
- 'PrivateIpAddress': network_interface['PrivateIpAddress'],
74
- 'PublicIp': network_interface.get('Association', {}).get('PublicIp'),
75
- 'RequesterId': network_interface.get('RequesterId'),
76
- 'RequesterManaged': network_interface['RequesterManaged'],
77
- 'SourceDestCheck': network_interface['SourceDestCheck'],
78
- 'Status': network_interface['Status'],
79
- 'SubnetId': network_interface['SubnetId'],
80
- 'ElbV1Id': elb_v1_id,
81
- 'ElbV2Id': elb_v2_id,
87
+ "Id": network_interface_id,
88
+ "NetworkInterfaceId": network_interface["NetworkInterfaceId"],
89
+ "Description": network_interface["Description"],
90
+ "InstanceId": network_interface.get("Attachment", {}).get("InstanceId"),
91
+ "InterfaceType": network_interface["InterfaceType"],
92
+ "MacAddress": network_interface["MacAddress"],
93
+ "PrivateDnsName": network_interface.get("PrivateDnsName"),
94
+ "PrivateIpAddress": network_interface["PrivateIpAddress"],
95
+ "PublicIp": network_interface.get("Association", {}).get("PublicIp"),
96
+ "RequesterId": network_interface.get("RequesterId"),
97
+ "RequesterManaged": network_interface["RequesterManaged"],
98
+ "SourceDestCheck": network_interface["SourceDestCheck"],
99
+ "Status": network_interface["Status"],
100
+ "SubnetId": network_interface["SubnetId"],
101
+ "ElbV1Id": elb_v1_id,
102
+ "ElbV2Id": elb_v2_id,
82
103
  },
83
104
  )
84
- if network_interface.get('PrivateIpAddresses'):
85
- for private_ip_address in network_interface['PrivateIpAddresses']:
105
+ if network_interface.get("PrivateIpAddresses"):
106
+ for private_ip_address in network_interface["PrivateIpAddresses"]:
86
107
  private_ip_list.append(
87
108
  {
88
- 'Id': f"{network_interface['NetworkInterfaceId']}:{private_ip_address['PrivateIpAddress']}",
89
- 'NetworkInterfaceId': network_interface['NetworkInterfaceId'],
90
- 'IpOwnerId': private_ip_address.get('Association', {}).get('IpOwnerId'),
91
- 'Primary': private_ip_address['Primary'],
92
- 'PrivateIpAddress': private_ip_address['PrivateIpAddress'],
93
- 'PublicIp': private_ip_address.get('Association', {}).get('PublicIp'),
109
+ "Id": f"{network_interface['NetworkInterfaceId']}:{private_ip_address['PrivateIpAddress']}",
110
+ "NetworkInterfaceId": network_interface["NetworkInterfaceId"],
111
+ "IpOwnerId": private_ip_address.get("Association", {}).get(
112
+ "IpOwnerId",
113
+ ),
114
+ "Primary": private_ip_address["Primary"],
115
+ "PrivateIpAddress": private_ip_address["PrivateIpAddress"],
116
+ "PublicIp": private_ip_address.get("Association", {}).get(
117
+ "PublicIp",
118
+ ),
94
119
  },
95
120
  )
96
121
 
@@ -98,19 +123,19 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
98
123
  for group in network_interface["Groups"]:
99
124
  sg_list.append(
100
125
  {
101
- 'GroupId': group['GroupId'],
102
- 'NetworkInterfaceId': network_interface_id,
126
+ "GroupId": group["GroupId"],
127
+ "NetworkInterfaceId": network_interface_id,
103
128
  },
104
129
  )
105
130
 
106
- subnet_id = network_interface.get('SubnetId')
131
+ subnet_id = network_interface.get("SubnetId")
107
132
  if subnet_id:
108
133
  subnet_list.append(
109
134
  {
110
- 'NetworkInterfaceId': network_interface_id,
111
- 'SubnetId': subnet_id,
112
- 'ElbV1Id': elb_v1_id,
113
- 'ElbV2Id': elb_v2_id,
135
+ "NetworkInterfaceId": network_interface_id,
136
+ "SubnetId": subnet_id,
137
+ "ElbV1Id": elb_v1_id,
138
+ "ElbV2Id": elb_v2_id,
114
139
  },
115
140
  )
116
141
 
@@ -124,11 +149,11 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
124
149
 
125
150
  @timeit
126
151
  def load_network_interfaces(
127
- neo4j_session: neo4j.Session,
128
- data: List[Dict[str, Any]],
129
- region: str,
130
- aws_account_id: str,
131
- update_tag: int,
152
+ neo4j_session: neo4j.Session,
153
+ data: List[Dict[str, Any]],
154
+ region: str,
155
+ aws_account_id: str,
156
+ update_tag: int,
132
157
  ) -> None:
133
158
  logger.info(f"Loading {len(data)} network interfaces in {region}.")
134
159
  load(
@@ -143,11 +168,11 @@ def load_network_interfaces(
143
168
 
144
169
  @timeit
145
170
  def load_private_ip_network_interface(
146
- neo4j_session: neo4j.Session,
147
- data: List[Dict[str, Any]],
148
- region: str,
149
- aws_account_id: str,
150
- update_tag: int,
171
+ neo4j_session: neo4j.Session,
172
+ data: List[Dict[str, Any]],
173
+ region: str,
174
+ aws_account_id: str,
175
+ update_tag: int,
151
176
  ) -> None:
152
177
  """
153
178
  Private IPs as known by describe-network-interfaces.
@@ -165,11 +190,11 @@ def load_private_ip_network_interface(
165
190
 
166
191
  @timeit
167
192
  def load_security_group_network_interface(
168
- neo4j_session: neo4j.Session,
169
- data: List[Dict[str, Any]],
170
- region: str,
171
- aws_account_id: str,
172
- update_tag: int,
193
+ neo4j_session: neo4j.Session,
194
+ data: List[Dict[str, Any]],
195
+ region: str,
196
+ aws_account_id: str,
197
+ update_tag: int,
173
198
  ) -> None:
174
199
  """
175
200
  Security groups as known by describe-network-interfaces.
@@ -187,11 +212,11 @@ def load_security_group_network_interface(
187
212
 
188
213
  @timeit
189
214
  def load_subnet_network_interface(
190
- neo4j_session: neo4j.Session,
191
- data: List[Dict[str, Any]],
192
- region: str,
193
- aws_account_id: str,
194
- update_tag: int,
215
+ neo4j_session: neo4j.Session,
216
+ data: List[Dict[str, Any]],
217
+ region: str,
218
+ aws_account_id: str,
219
+ update_tag: int,
195
220
  ) -> None:
196
221
  """
197
222
  Subnets as known by describe-network-interfaces.
@@ -208,38 +233,72 @@ def load_subnet_network_interface(
208
233
 
209
234
 
210
235
  def load_network_data(
211
- neo4j_session: neo4j.Session,
212
- region: str,
213
- current_aws_account_id: str,
214
- update_tag: int,
215
- network_interface_list: List[Dict[str, Any]],
216
- private_ip_list: List[Dict[str, Any]],
217
- subnet_list: List[Dict[str, Any]],
218
- sg_list: List[Dict[str, Any]],
236
+ neo4j_session: neo4j.Session,
237
+ region: str,
238
+ current_aws_account_id: str,
239
+ update_tag: int,
240
+ network_interface_list: List[Dict[str, Any]],
241
+ private_ip_list: List[Dict[str, Any]],
242
+ subnet_list: List[Dict[str, Any]],
243
+ sg_list: List[Dict[str, Any]],
219
244
  ) -> None:
220
- load_network_interfaces(neo4j_session, network_interface_list, region, current_aws_account_id, update_tag)
221
- load_private_ip_network_interface(neo4j_session, private_ip_list, region, current_aws_account_id, update_tag)
222
- load_subnet_network_interface(neo4j_session, subnet_list, region, current_aws_account_id, update_tag)
223
- load_security_group_network_interface(neo4j_session, sg_list, region, current_aws_account_id, update_tag)
245
+ load_network_interfaces(
246
+ neo4j_session,
247
+ network_interface_list,
248
+ region,
249
+ current_aws_account_id,
250
+ update_tag,
251
+ )
252
+ load_private_ip_network_interface(
253
+ neo4j_session,
254
+ private_ip_list,
255
+ region,
256
+ current_aws_account_id,
257
+ update_tag,
258
+ )
259
+ load_subnet_network_interface(
260
+ neo4j_session,
261
+ subnet_list,
262
+ region,
263
+ current_aws_account_id,
264
+ update_tag,
265
+ )
266
+ load_security_group_network_interface(
267
+ neo4j_session,
268
+ sg_list,
269
+ region,
270
+ current_aws_account_id,
271
+ update_tag,
272
+ )
224
273
 
225
274
 
226
275
  @timeit
227
- def cleanup_network_interfaces(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
228
- GraphJob.from_node_schema(EC2NetworkInterfaceSchema(), common_job_parameters).run(neo4j_session)
229
- GraphJob.from_node_schema(EC2PrivateIpNetworkInterfaceSchema(), common_job_parameters).run(neo4j_session)
276
+ def cleanup_network_interfaces(
277
+ neo4j_session: neo4j.Session,
278
+ common_job_parameters: Dict,
279
+ ) -> None:
280
+ GraphJob.from_node_schema(EC2NetworkInterfaceSchema(), common_job_parameters).run(
281
+ neo4j_session,
282
+ )
283
+ GraphJob.from_node_schema(
284
+ EC2PrivateIpNetworkInterfaceSchema(),
285
+ common_job_parameters,
286
+ ).run(neo4j_session)
230
287
 
231
288
 
232
289
  @timeit
233
290
  def sync_network_interfaces(
234
- neo4j_session: neo4j.Session,
235
- boto3_session: boto3.session.Session,
236
- regions: List[str],
237
- current_aws_account_id: str,
238
- update_tag: int,
239
- common_job_parameters: Dict,
291
+ neo4j_session: neo4j.Session,
292
+ boto3_session: boto3.session.Session,
293
+ regions: List[str],
294
+ current_aws_account_id: str,
295
+ update_tag: int,
296
+ common_job_parameters: Dict,
240
297
  ) -> None:
241
298
  for region in regions:
242
- logger.info(f"Syncing EC2 network interfaces for region '{region}' in account '{current_aws_account_id}'.")
299
+ logger.info(
300
+ f"Syncing EC2 network interfaces for region '{region}' in account '{current_aws_account_id}'.",
301
+ )
243
302
  data = get_network_interface_data(boto3_session, region)
244
303
  ec2_network_data = transform_network_interface_data(data, region)
245
304
  load_network_data(
@@ -6,30 +6,43 @@ import boto3
6
6
  import neo4j
7
7
  from botocore.exceptions import ClientError
8
8
 
9
- from .util import get_botocore_config
10
9
  from cartography.util import aws_handle_regions
11
10
  from cartography.util import run_cleanup_job
12
11
  from cartography.util import timeit
13
12
 
13
+ from .util import get_botocore_config
14
+
14
15
  logger = logging.getLogger(__name__)
15
16
 
16
17
 
17
18
  @timeit
18
19
  @aws_handle_regions
19
- def get_reserved_instances(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
20
- client = boto3_session.client('ec2', region_name=region, config=get_botocore_config())
20
+ def get_reserved_instances(
21
+ boto3_session: boto3.session.Session,
22
+ region: str,
23
+ ) -> List[Dict]:
24
+ client = boto3_session.client(
25
+ "ec2",
26
+ region_name=region,
27
+ config=get_botocore_config(),
28
+ )
21
29
  try:
22
- reserved_instances = client.describe_reserved_instances()['ReservedInstances']
30
+ reserved_instances = client.describe_reserved_instances()["ReservedInstances"]
23
31
  except ClientError as e:
24
- logger.warning(f"Failed retrieve reserved instances for region - {region}. Error - {e}")
32
+ logger.warning(
33
+ f"Failed retrieve reserved instances for region - {region}. Error - {e}",
34
+ )
25
35
  raise
26
36
  return reserved_instances
27
37
 
28
38
 
29
39
  @timeit
30
40
  def load_reserved_instances(
31
- neo4j_session: neo4j.Session, data: List[Dict], region: str,
32
- current_aws_account_id: str, update_tag: int,
41
+ neo4j_session: neo4j.Session,
42
+ data: List[Dict],
43
+ region: str,
44
+ current_aws_account_id: str,
45
+ update_tag: int,
33
46
  ) -> None:
34
47
  ingest_reserved_instances = """
35
48
  UNWIND $reserved_instances_list as res
@@ -48,8 +61,8 @@ def load_reserved_instances(
48
61
  """
49
62
 
50
63
  for r_instance in data:
51
- r_instance['Start'] = str(r_instance['Start'])
52
- r_instance['End'] = str(r_instance['End'])
64
+ r_instance["Start"] = str(r_instance["Start"])
65
+ r_instance["End"] = str(r_instance["End"])
53
66
 
54
67
  neo4j_session.run(
55
68
  ingest_reserved_instances,
@@ -61,9 +74,12 @@ def load_reserved_instances(
61
74
 
62
75
 
63
76
  @timeit
64
- def cleanup_reserved_instances(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
77
+ def cleanup_reserved_instances(
78
+ neo4j_session: neo4j.Session,
79
+ common_job_parameters: Dict,
80
+ ) -> None:
65
81
  run_cleanup_job(
66
- 'aws_import_reserved_instances_cleanup.json',
82
+ "aws_import_reserved_instances_cleanup.json",
67
83
  neo4j_session,
68
84
  common_job_parameters,
69
85
  )
@@ -71,12 +87,25 @@ def cleanup_reserved_instances(neo4j_session: neo4j.Session, common_job_paramete
71
87
 
72
88
  @timeit
73
89
  def sync_ec2_reserved_instances(
74
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str],
75
- current_aws_account_id: str,
76
- update_tag: int, common_job_parameters: Dict,
90
+ neo4j_session: neo4j.Session,
91
+ boto3_session: boto3.session.Session,
92
+ regions: List[str],
93
+ current_aws_account_id: str,
94
+ update_tag: int,
95
+ common_job_parameters: Dict,
77
96
  ) -> None:
78
97
  for region in regions:
79
- logger.debug("Syncing reserved instances for region '%s' in account '%s'.", region, current_aws_account_id)
98
+ logger.debug(
99
+ "Syncing reserved instances for region '%s' in account '%s'.",
100
+ region,
101
+ current_aws_account_id,
102
+ )
80
103
  data = get_reserved_instances(boto3_session, region)
81
- load_reserved_instances(neo4j_session, data, region, current_aws_account_id, update_tag)
104
+ load_reserved_instances(
105
+ neo4j_session,
106
+ data,
107
+ region,
108
+ current_aws_account_id,
109
+ update_tag,
110
+ )
82
111
  cleanup_reserved_instances(neo4j_session, common_job_parameters)