cartography 0.102.0rc1__py3-none-any.whl → 0.103.0rc1__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 (251) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +2 -2
  3. cartography/cli.py +302 -253
  4. cartography/client/core/tx.py +39 -18
  5. cartography/config.py +4 -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/config.py +56 -20
  23. cartography/intel/aws/dynamodb.py +108 -40
  24. cartography/intel/aws/ec2/__init__.py +2 -2
  25. cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
  26. cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
  27. cartography/intel/aws/ec2/images.py +49 -20
  28. cartography/intel/aws/ec2/instances.py +234 -136
  29. cartography/intel/aws/ec2/internet_gateways.py +40 -11
  30. cartography/intel/aws/ec2/key_pairs.py +44 -20
  31. cartography/intel/aws/ec2/launch_templates.py +101 -59
  32. cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
  33. cartography/intel/aws/ec2/load_balancers.py +82 -42
  34. cartography/intel/aws/ec2/network_acls.py +89 -65
  35. cartography/intel/aws/ec2/network_interfaces.py +146 -87
  36. cartography/intel/aws/ec2/reserved_instances.py +45 -16
  37. cartography/intel/aws/ec2/route_tables.py +327 -0
  38. cartography/intel/aws/ec2/security_groups.py +71 -21
  39. cartography/intel/aws/ec2/snapshots.py +61 -22
  40. cartography/intel/aws/ec2/subnets.py +54 -18
  41. cartography/intel/aws/ec2/tgw.py +100 -34
  42. cartography/intel/aws/ec2/util.py +1 -1
  43. cartography/intel/aws/ec2/volumes.py +69 -41
  44. cartography/intel/aws/ec2/vpc.py +37 -12
  45. cartography/intel/aws/ec2/vpc_peerings.py +83 -24
  46. cartography/intel/aws/ecr.py +88 -32
  47. cartography/intel/aws/ecs.py +83 -47
  48. cartography/intel/aws/eks.py +55 -29
  49. cartography/intel/aws/elasticache.py +42 -18
  50. cartography/intel/aws/elasticsearch.py +57 -20
  51. cartography/intel/aws/emr.py +61 -23
  52. cartography/intel/aws/iam.py +401 -145
  53. cartography/intel/aws/iam_instance_profiles.py +22 -22
  54. cartography/intel/aws/identitycenter.py +71 -37
  55. cartography/intel/aws/inspector.py +159 -89
  56. cartography/intel/aws/kms.py +92 -38
  57. cartography/intel/aws/lambda_function.py +103 -34
  58. cartography/intel/aws/organizations.py +30 -10
  59. cartography/intel/aws/permission_relationships.py +133 -51
  60. cartography/intel/aws/rds.py +249 -85
  61. cartography/intel/aws/redshift.py +107 -46
  62. cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
  63. cartography/intel/aws/resources.py +53 -44
  64. cartography/intel/aws/route53.py +108 -61
  65. cartography/intel/aws/s3.py +168 -83
  66. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  67. cartography/intel/aws/secretsmanager.py +24 -12
  68. cartography/intel/aws/securityhub.py +20 -9
  69. cartography/intel/aws/sns.py +166 -0
  70. cartography/intel/aws/sqs.py +60 -28
  71. cartography/intel/aws/ssm.py +70 -30
  72. cartography/intel/aws/util/arns.py +7 -7
  73. cartography/intel/aws/util/common.py +31 -4
  74. cartography/intel/azure/__init__.py +78 -19
  75. cartography/intel/azure/compute.py +101 -27
  76. cartography/intel/azure/cosmosdb.py +496 -170
  77. cartography/intel/azure/sql.py +296 -105
  78. cartography/intel/azure/storage.py +322 -113
  79. cartography/intel/azure/subscription.py +39 -23
  80. cartography/intel/azure/tenant.py +13 -4
  81. cartography/intel/azure/util/credentials.py +95 -55
  82. cartography/intel/bigfix/__init__.py +2 -2
  83. cartography/intel/bigfix/computers.py +93 -65
  84. cartography/intel/create_indexes.py +3 -2
  85. cartography/intel/crowdstrike/__init__.py +11 -9
  86. cartography/intel/crowdstrike/endpoints.py +5 -1
  87. cartography/intel/crowdstrike/spotlight.py +8 -3
  88. cartography/intel/cve/__init__.py +46 -13
  89. cartography/intel/cve/feed.py +48 -12
  90. cartography/intel/digitalocean/__init__.py +22 -13
  91. cartography/intel/digitalocean/compute.py +75 -108
  92. cartography/intel/digitalocean/management.py +44 -80
  93. cartography/intel/digitalocean/platform.py +48 -43
  94. cartography/intel/dns.py +36 -10
  95. cartography/intel/duo/__init__.py +21 -16
  96. cartography/intel/duo/api_host.py +14 -9
  97. cartography/intel/duo/endpoints.py +50 -45
  98. cartography/intel/duo/groups.py +18 -14
  99. cartography/intel/duo/phones.py +37 -34
  100. cartography/intel/duo/tokens.py +26 -23
  101. cartography/intel/duo/users.py +54 -50
  102. cartography/intel/duo/web_authn_credentials.py +30 -25
  103. cartography/intel/entra/__init__.py +25 -7
  104. cartography/intel/entra/ou.py +112 -0
  105. cartography/intel/entra/users.py +69 -63
  106. cartography/intel/gcp/__init__.py +185 -49
  107. cartography/intel/gcp/compute.py +418 -231
  108. cartography/intel/gcp/crm.py +96 -43
  109. cartography/intel/gcp/dns.py +60 -19
  110. cartography/intel/gcp/gke.py +72 -38
  111. cartography/intel/gcp/iam.py +61 -41
  112. cartography/intel/gcp/storage.py +84 -55
  113. cartography/intel/github/__init__.py +13 -11
  114. cartography/intel/github/repos.py +270 -137
  115. cartography/intel/github/teams.py +170 -88
  116. cartography/intel/github/users.py +70 -39
  117. cartography/intel/github/util.py +36 -34
  118. cartography/intel/gsuite/__init__.py +47 -26
  119. cartography/intel/gsuite/api.py +73 -30
  120. cartography/intel/jamf/__init__.py +19 -1
  121. cartography/intel/jamf/computers.py +30 -7
  122. cartography/intel/jamf/util.py +7 -2
  123. cartography/intel/kandji/__init__.py +6 -3
  124. cartography/intel/kandji/devices.py +14 -8
  125. cartography/intel/kubernetes/namespaces.py +7 -4
  126. cartography/intel/kubernetes/pods.py +7 -4
  127. cartography/intel/kubernetes/services.py +8 -4
  128. cartography/intel/lastpass/__init__.py +2 -2
  129. cartography/intel/lastpass/users.py +23 -12
  130. cartography/intel/oci/__init__.py +44 -11
  131. cartography/intel/oci/iam.py +134 -38
  132. cartography/intel/oci/organizations.py +13 -6
  133. cartography/intel/oci/utils.py +43 -20
  134. cartography/intel/okta/__init__.py +66 -15
  135. cartography/intel/okta/applications.py +42 -20
  136. cartography/intel/okta/awssaml.py +93 -33
  137. cartography/intel/okta/factors.py +16 -4
  138. cartography/intel/okta/groups.py +56 -29
  139. cartography/intel/okta/organization.py +5 -1
  140. cartography/intel/okta/origins.py +6 -2
  141. cartography/intel/okta/roles.py +15 -5
  142. cartography/intel/okta/users.py +20 -8
  143. cartography/intel/okta/utils.py +6 -4
  144. cartography/intel/pagerduty/__init__.py +8 -7
  145. cartography/intel/pagerduty/escalation_policies.py +18 -6
  146. cartography/intel/pagerduty/schedules.py +12 -4
  147. cartography/intel/pagerduty/services.py +11 -4
  148. cartography/intel/pagerduty/teams.py +8 -3
  149. cartography/intel/pagerduty/users.py +3 -1
  150. cartography/intel/pagerduty/vendors.py +3 -1
  151. cartography/intel/semgrep/__init__.py +24 -6
  152. cartography/intel/semgrep/dependencies.py +50 -28
  153. cartography/intel/semgrep/deployment.py +3 -1
  154. cartography/intel/semgrep/findings.py +42 -18
  155. cartography/intel/snipeit/__init__.py +17 -3
  156. cartography/intel/snipeit/asset.py +12 -6
  157. cartography/intel/snipeit/user.py +8 -5
  158. cartography/intel/snipeit/util.py +9 -4
  159. cartography/models/aws/apigateway.py +21 -17
  160. cartography/models/aws/apigatewaycertificate.py +28 -22
  161. cartography/models/aws/apigatewayresource.py +28 -20
  162. cartography/models/aws/apigatewaystage.py +33 -25
  163. cartography/models/aws/cloudtrail/__init__.py +0 -0
  164. cartography/models/aws/cloudtrail/trail.py +61 -0
  165. cartography/models/aws/dynamodb/gsi.py +30 -22
  166. cartography/models/aws/dynamodb/tables.py +25 -17
  167. cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
  168. cartography/models/aws/ec2/images.py +36 -34
  169. cartography/models/aws/ec2/instances.py +51 -45
  170. cartography/models/aws/ec2/keypair.py +21 -16
  171. cartography/models/aws/ec2/keypair_instance.py +28 -21
  172. cartography/models/aws/ec2/launch_configurations.py +30 -26
  173. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  174. cartography/models/aws/ec2/launch_templates.py +21 -17
  175. cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
  176. cartography/models/aws/ec2/load_balancers.py +47 -37
  177. cartography/models/aws/ec2/network_acl_rules.py +38 -30
  178. cartography/models/aws/ec2/network_acls.py +38 -29
  179. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  180. cartography/models/aws/ec2/networkinterfaces.py +53 -37
  181. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  182. cartography/models/aws/ec2/reservations.py +18 -14
  183. cartography/models/aws/ec2/route_table_associations.py +97 -0
  184. cartography/models/aws/ec2/route_tables.py +128 -0
  185. cartography/models/aws/ec2/routes.py +85 -0
  186. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  187. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  188. cartography/models/aws/ec2/subnet_instance.py +24 -19
  189. cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
  190. cartography/models/aws/ec2/volumes.py +47 -40
  191. cartography/models/aws/eks/clusters.py +23 -21
  192. cartography/models/aws/emr.py +32 -30
  193. cartography/models/aws/iam/instanceprofile.py +33 -24
  194. cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
  195. cartography/models/aws/identitycenter/awspermissionset.py +37 -29
  196. cartography/models/aws/identitycenter/awsssouser.py +23 -21
  197. cartography/models/aws/inspector/findings.py +77 -65
  198. cartography/models/aws/inspector/packages.py +35 -29
  199. cartography/models/aws/s3/__init__.py +0 -0
  200. cartography/models/aws/s3/account_public_access_block.py +51 -0
  201. cartography/models/aws/sns/__init__.py +0 -0
  202. cartography/models/aws/sns/topic.py +50 -0
  203. cartography/models/aws/ssm/instance_information.py +51 -39
  204. cartography/models/aws/ssm/instance_patch.py +32 -26
  205. cartography/models/bigfix/bigfix_computer.py +42 -38
  206. cartography/models/bigfix/bigfix_root.py +3 -3
  207. cartography/models/core/common.py +12 -10
  208. cartography/models/core/nodes.py +5 -2
  209. cartography/models/core/relationships.py +14 -6
  210. cartography/models/crowdstrike/hosts.py +37 -35
  211. cartography/models/cve/cve.py +34 -32
  212. cartography/models/cve/cve_feed.py +6 -6
  213. cartography/models/digitalocean/__init__.py +0 -0
  214. cartography/models/digitalocean/account.py +21 -0
  215. cartography/models/digitalocean/droplet.py +56 -0
  216. cartography/models/digitalocean/project.py +48 -0
  217. cartography/models/duo/api_host.py +3 -3
  218. cartography/models/duo/endpoint.py +43 -41
  219. cartography/models/duo/group.py +14 -14
  220. cartography/models/duo/phone.py +27 -27
  221. cartography/models/duo/token.py +16 -16
  222. cartography/models/duo/user.py +46 -44
  223. cartography/models/duo/web_authn_credential.py +27 -19
  224. cartography/models/entra/ou.py +48 -0
  225. cartography/models/entra/tenant.py +24 -18
  226. cartography/models/entra/user.py +64 -48
  227. cartography/models/gcp/iam.py +23 -23
  228. cartography/models/github/orgs.py +5 -4
  229. cartography/models/github/teams.py +37 -31
  230. cartography/models/github/users.py +34 -23
  231. cartography/models/kandji/device.py +22 -16
  232. cartography/models/kandji/tenant.py +6 -4
  233. cartography/models/lastpass/tenant.py +3 -3
  234. cartography/models/lastpass/user.py +32 -28
  235. cartography/models/semgrep/dependencies.py +36 -24
  236. cartography/models/semgrep/deployment.py +5 -5
  237. cartography/models/semgrep/findings.py +58 -42
  238. cartography/models/semgrep/locations.py +27 -21
  239. cartography/models/snipeit/asset.py +30 -21
  240. cartography/models/snipeit/tenant.py +6 -4
  241. cartography/models/snipeit/user.py +19 -12
  242. cartography/stats.py +3 -3
  243. cartography/sync.py +107 -31
  244. cartography/util.py +84 -62
  245. {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/METADATA +3 -14
  246. cartography-0.103.0rc1.dist-info/RECORD +396 -0
  247. {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/WHEEL +1 -1
  248. cartography-0.102.0rc1.dist-info/RECORD +0 -377
  249. {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/entry_points.txt +0 -0
  250. {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/licenses/LICENSE +0 -0
  251. {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/top_level.txt +0 -0
@@ -6,38 +6,47 @@ import boto3
6
6
  import botocore
7
7
  import neo4j
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_load_balancer_v2_listeners(client: botocore.client.BaseClient, load_balancer_arn: str) -> List[Dict]:
20
- paginator = client.get_paginator('describe_listeners')
20
+ def get_load_balancer_v2_listeners(
21
+ client: botocore.client.BaseClient,
22
+ load_balancer_arn: str,
23
+ ) -> List[Dict]:
24
+ paginator = client.get_paginator("describe_listeners")
21
25
  listeners: List[Dict] = []
22
26
  for page in paginator.paginate(LoadBalancerArn=load_balancer_arn):
23
- listeners.extend(page['Listeners'])
27
+ listeners.extend(page["Listeners"])
24
28
 
25
29
  return listeners
26
30
 
27
31
 
28
32
  @timeit
29
- def get_load_balancer_v2_target_groups(client: botocore.client.BaseClient, load_balancer_arn: str) -> List[Dict]:
30
- paginator = client.get_paginator('describe_target_groups')
33
+ def get_load_balancer_v2_target_groups(
34
+ client: botocore.client.BaseClient,
35
+ load_balancer_arn: str,
36
+ ) -> List[Dict]:
37
+ paginator = client.get_paginator("describe_target_groups")
31
38
  target_groups: List[Dict] = []
32
39
  for page in paginator.paginate(LoadBalancerArn=load_balancer_arn):
33
- target_groups.extend(page['TargetGroups'])
40
+ target_groups.extend(page["TargetGroups"])
34
41
 
35
42
  # Add instance data
36
43
  for target_group in target_groups:
37
- target_group['Targets'] = []
38
- target_health = client.describe_target_health(TargetGroupArn=target_group['TargetGroupArn'])
39
- for target_health_description in target_health['TargetHealthDescriptions']:
40
- target_group['Targets'].append(target_health_description['Target']['Id'])
44
+ target_group["Targets"] = []
45
+ target_health = client.describe_target_health(
46
+ TargetGroupArn=target_group["TargetGroupArn"],
47
+ )
48
+ for target_health_description in target_health["TargetHealthDescriptions"]:
49
+ target_group["Targets"].append(target_health_description["Target"]["Id"])
41
50
 
42
51
  return target_groups
43
52
 
@@ -45,22 +54,35 @@ def get_load_balancer_v2_target_groups(client: botocore.client.BaseClient, load_
45
54
  @timeit
46
55
  @aws_handle_regions
47
56
  def get_loadbalancer_v2_data(boto3_session: boto3.Session, region: str) -> List[Dict]:
48
- client = boto3_session.client('elbv2', region_name=region, config=get_botocore_config())
49
- paginator = client.get_paginator('describe_load_balancers')
57
+ client = boto3_session.client(
58
+ "elbv2",
59
+ region_name=region,
60
+ config=get_botocore_config(),
61
+ )
62
+ paginator = client.get_paginator("describe_load_balancers")
50
63
  elbv2s: List[Dict] = []
51
64
  for page in paginator.paginate():
52
- elbv2s.extend(page['LoadBalancers'])
65
+ elbv2s.extend(page["LoadBalancers"])
53
66
 
54
67
  # Make extra calls to get listeners
55
68
  for elbv2 in elbv2s:
56
- elbv2['Listeners'] = get_load_balancer_v2_listeners(client, elbv2['LoadBalancerArn'])
57
- elbv2['TargetGroups'] = get_load_balancer_v2_target_groups(client, elbv2['LoadBalancerArn'])
69
+ elbv2["Listeners"] = get_load_balancer_v2_listeners(
70
+ client,
71
+ elbv2["LoadBalancerArn"],
72
+ )
73
+ elbv2["TargetGroups"] = get_load_balancer_v2_target_groups(
74
+ client,
75
+ elbv2["LoadBalancerArn"],
76
+ )
58
77
  return elbv2s
59
78
 
60
79
 
61
80
  @timeit
62
81
  def load_load_balancer_v2s(
63
- neo4j_session: neo4j.Session, data: List[Dict], region: str, current_aws_account_id: str,
82
+ neo4j_session: neo4j.Session,
83
+ data: List[Dict],
84
+ region: str,
85
+ current_aws_account_id: str,
64
86
  update_tag: int,
65
87
  ) -> None:
66
88
  ingest_load_balancer_v2 = """
@@ -95,10 +117,16 @@ def load_load_balancer_v2s(
95
117
 
96
118
  if lb["AvailabilityZones"]:
97
119
  az = lb["AvailabilityZones"]
98
- load_load_balancer_v2_subnets(neo4j_session, load_balancer_id, az, region, update_tag)
120
+ load_load_balancer_v2_subnets(
121
+ neo4j_session,
122
+ load_balancer_id,
123
+ az,
124
+ region,
125
+ update_tag,
126
+ )
99
127
 
100
128
  # NLB's don't have SecurityGroups, so check for one first.
101
- if 'SecurityGroups' in lb and lb["SecurityGroups"]:
129
+ if "SecurityGroups" in lb and lb["SecurityGroups"]:
102
130
  ingest_load_balancer_v2_security_group = """
103
131
  MATCH (elbv2:LoadBalancerV2{id: $ID}),
104
132
  (group:EC2SecurityGroup{groupid: $GROUP_ID})
@@ -114,20 +142,31 @@ def load_load_balancer_v2s(
114
142
  update_tag=update_tag,
115
143
  )
116
144
 
117
- if lb['Listeners']:
118
- load_load_balancer_v2_listeners(neo4j_session, load_balancer_id, lb['Listeners'], update_tag)
145
+ if lb["Listeners"]:
146
+ load_load_balancer_v2_listeners(
147
+ neo4j_session,
148
+ load_balancer_id,
149
+ lb["Listeners"],
150
+ update_tag,
151
+ )
119
152
 
120
- if lb['TargetGroups']:
153
+ if lb["TargetGroups"]:
121
154
  load_load_balancer_v2_target_groups(
122
- neo4j_session, load_balancer_id, lb['TargetGroups'],
123
- current_aws_account_id, update_tag,
155
+ neo4j_session,
156
+ load_balancer_id,
157
+ lb["TargetGroups"],
158
+ current_aws_account_id,
159
+ update_tag,
124
160
  )
125
161
 
126
162
 
127
163
  @timeit
128
164
  def load_load_balancer_v2_subnets(
129
- neo4j_session: neo4j.Session, load_balancer_id: str, az_data: List[Dict],
130
- region: str, update_tag: int,
165
+ neo4j_session: neo4j.Session,
166
+ load_balancer_id: str,
167
+ az_data: List[Dict],
168
+ region: str,
169
+ update_tag: int,
131
170
  ) -> None:
132
171
  ingest_load_balancer_subnet = """
133
172
  MATCH (elbv2:LoadBalancerV2{id: $ID})
@@ -143,7 +182,7 @@ def load_load_balancer_v2_subnets(
143
182
  neo4j_session.run(
144
183
  ingest_load_balancer_subnet,
145
184
  ID=load_balancer_id,
146
- SubnetId=az['SubnetId'],
185
+ SubnetId=az["SubnetId"],
147
186
  region=region,
148
187
  update_tag=update_tag,
149
188
  )
@@ -151,7 +190,10 @@ def load_load_balancer_v2_subnets(
151
190
 
152
191
  @timeit
153
192
  def load_load_balancer_v2_target_groups(
154
- neo4j_session: neo4j.Session, load_balancer_id: str, target_groups: List[Dict], current_aws_account_id: str,
193
+ neo4j_session: neo4j.Session,
194
+ load_balancer_id: str,
195
+ target_groups: List[Dict],
196
+ current_aws_account_id: str,
155
197
  update_tag: int,
156
198
  ) -> None:
157
199
  ingest_instances = """
@@ -169,7 +211,7 @@ def load_load_balancer_v2_target_groups(
169
211
  """
170
212
  for target_group in target_groups:
171
213
 
172
- if not target_group['TargetType'] == 'instance':
214
+ if not target_group["TargetType"] == "instance":
173
215
  # Only working on EC2 Instances now. TODO: Add IP & Lambda EXPOSE.
174
216
  continue
175
217
 
@@ -179,16 +221,18 @@ def load_load_balancer_v2_target_groups(
179
221
  ID=load_balancer_id,
180
222
  INSTANCE_ID=instance,
181
223
  AWS_ACCOUNT_ID=current_aws_account_id,
182
- TARGET_GROUP_ARN=target_group.get('TargetGroupArn'),
183
- PORT=target_group.get('Port'),
184
- PROTOCOL=target_group.get('Protocol'),
224
+ TARGET_GROUP_ARN=target_group.get("TargetGroupArn"),
225
+ PORT=target_group.get("Port"),
226
+ PROTOCOL=target_group.get("Protocol"),
185
227
  update_tag=update_tag,
186
228
  )
187
229
 
188
230
 
189
231
  @timeit
190
232
  def load_load_balancer_v2_listeners(
191
- neo4j_session: neo4j.Session, load_balancer_id: str, listener_data: List[Dict],
233
+ neo4j_session: neo4j.Session,
234
+ load_balancer_id: str,
235
+ listener_data: List[Dict],
192
236
  update_tag: int,
193
237
  ) -> None:
194
238
  ingest_listener = """
@@ -215,18 +259,39 @@ def load_load_balancer_v2_listeners(
215
259
 
216
260
 
217
261
  @timeit
218
- def cleanup_load_balancer_v2s(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
262
+ def cleanup_load_balancer_v2s(
263
+ neo4j_session: neo4j.Session,
264
+ common_job_parameters: Dict,
265
+ ) -> None:
219
266
  """Delete elbv2's and dependent resources in the DB without the most recent lastupdated tag."""
220
- run_cleanup_job('aws_ingest_load_balancers_v2_cleanup.json', neo4j_session, common_job_parameters)
267
+ run_cleanup_job(
268
+ "aws_ingest_load_balancers_v2_cleanup.json",
269
+ neo4j_session,
270
+ common_job_parameters,
271
+ )
221
272
 
222
273
 
223
274
  @timeit
224
275
  def sync_load_balancer_v2s(
225
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
226
- update_tag: int, common_job_parameters: Dict,
276
+ neo4j_session: neo4j.Session,
277
+ boto3_session: boto3.session.Session,
278
+ regions: List[str],
279
+ current_aws_account_id: str,
280
+ update_tag: int,
281
+ common_job_parameters: Dict,
227
282
  ) -> None:
228
283
  for region in regions:
229
- logger.info("Syncing EC2 load balancers v2 for region '%s' in account '%s'.", region, current_aws_account_id)
284
+ logger.info(
285
+ "Syncing EC2 load balancers v2 for region '%s' in account '%s'.",
286
+ region,
287
+ current_aws_account_id,
288
+ )
230
289
  data = get_loadbalancer_v2_data(boto3_session, region)
231
- load_load_balancer_v2s(neo4j_session, data, region, current_aws_account_id, update_tag)
290
+ load_load_balancer_v2s(
291
+ neo4j_session,
292
+ data,
293
+ region,
294
+ current_aws_account_id,
295
+ update_tag,
296
+ )
232
297
  cleanup_load_balancer_v2s(neo4j_session, common_job_parameters)
@@ -3,7 +3,6 @@ import logging
3
3
  import boto3
4
4
  import neo4j
5
5
 
6
- from .util import get_botocore_config
7
6
  from cartography.client.core.tx import load
8
7
  from cartography.graph.job import GraphJob
9
8
  from cartography.models.aws.ec2.load_balancer_listeners import ELBListenerSchema
@@ -11,6 +10,8 @@ from cartography.models.aws.ec2.load_balancers import LoadBalancerSchema
11
10
  from cartography.util import aws_handle_regions
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
 
@@ -29,7 +30,9 @@ def _get_listener_id(load_balancer_id: str, port: int, protocol: str) -> str:
29
30
  return f"{load_balancer_id}{port}{protocol}"
30
31
 
31
32
 
32
- def transform_load_balancer_listener_data(load_balancer_id: str, listener_data: list[dict]) -> list[dict]:
33
+ def transform_load_balancer_listener_data(
34
+ load_balancer_id: str, listener_data: list[dict]
35
+ ) -> list[dict]:
33
36
  """
34
37
  Transform load balancer listener data into a format suitable for cartography ingestion.
35
38
 
@@ -42,21 +45,27 @@ def transform_load_balancer_listener_data(load_balancer_id: str, listener_data:
42
45
  """
43
46
  transformed = []
44
47
  for listener in listener_data:
45
- listener_info = listener['Listener']
48
+ listener_info = listener["Listener"]
46
49
  transformed_listener = {
47
- 'id': _get_listener_id(load_balancer_id, listener_info['LoadBalancerPort'], listener_info['Protocol']),
48
- 'port': listener_info.get('LoadBalancerPort'),
49
- 'protocol': listener_info.get('Protocol'),
50
- 'instance_port': listener_info.get('InstancePort'),
51
- 'instance_protocol': listener_info.get('InstanceProtocol'),
52
- 'policy_names': listener.get('PolicyNames', []),
53
- 'LoadBalancerId': load_balancer_id,
50
+ "id": _get_listener_id(
51
+ load_balancer_id,
52
+ listener_info["LoadBalancerPort"],
53
+ listener_info["Protocol"],
54
+ ),
55
+ "port": listener_info.get("LoadBalancerPort"),
56
+ "protocol": listener_info.get("Protocol"),
57
+ "instance_port": listener_info.get("InstancePort"),
58
+ "instance_protocol": listener_info.get("InstanceProtocol"),
59
+ "policy_names": listener.get("PolicyNames", []),
60
+ "LoadBalancerId": load_balancer_id,
54
61
  }
55
62
  transformed.append(transformed_listener)
56
63
  return transformed
57
64
 
58
65
 
59
- def transform_load_balancer_data(load_balancers: list[dict]) -> tuple[list[dict], list[dict]]:
66
+ def transform_load_balancer_data(
67
+ load_balancers: list[dict],
68
+ ) -> tuple[list[dict], list[dict]]:
60
69
  """
61
70
  Transform load balancer data into a format suitable for cartography ingestion.
62
71
 
@@ -70,35 +79,38 @@ def transform_load_balancer_data(load_balancers: list[dict]) -> tuple[list[dict]
70
79
  listener_data = []
71
80
 
72
81
  for lb in load_balancers:
73
- load_balancer_id = lb['DNSName']
82
+ load_balancer_id = lb["DNSName"]
74
83
  transformed_lb = {
75
- 'id': load_balancer_id,
76
- 'name': lb['LoadBalancerName'],
77
- 'dnsname': lb['DNSName'],
78
- 'canonicalhostedzonename': lb.get('CanonicalHostedZoneName'),
79
- 'canonicalhostedzonenameid': lb.get('CanonicalHostedZoneNameID'),
80
- 'scheme': lb.get('Scheme'),
81
- 'createdtime': str(lb['CreatedTime']),
82
- 'GROUP_NAME': lb.get('SourceSecurityGroup', {}).get('GroupName'),
83
- 'GROUP_IDS': [str(group) for group in lb.get('SecurityGroups', [])],
84
- 'INSTANCE_IDS': [instance['InstanceId'] for instance in lb.get('Instances', [])],
85
- 'LISTENER_IDS': [
84
+ "id": load_balancer_id,
85
+ "name": lb["LoadBalancerName"],
86
+ "dnsname": lb["DNSName"],
87
+ "canonicalhostedzonename": lb.get("CanonicalHostedZoneName"),
88
+ "canonicalhostedzonenameid": lb.get("CanonicalHostedZoneNameID"),
89
+ "scheme": lb.get("Scheme"),
90
+ "createdtime": str(lb["CreatedTime"]),
91
+ "GROUP_NAME": lb.get("SourceSecurityGroup", {}).get("GroupName"),
92
+ "GROUP_IDS": [str(group) for group in lb.get("SecurityGroups", [])],
93
+ "INSTANCE_IDS": [
94
+ instance["InstanceId"] for instance in lb.get("Instances", [])
95
+ ],
96
+ "LISTENER_IDS": [
86
97
  _get_listener_id(
87
98
  load_balancer_id,
88
- listener['Listener']['LoadBalancerPort'],
89
- listener['Listener']['Protocol'],
90
- ) for listener in lb.get('ListenerDescriptions', [])
99
+ listener["Listener"]["LoadBalancerPort"],
100
+ listener["Listener"]["Protocol"],
101
+ )
102
+ for listener in lb.get("ListenerDescriptions", [])
91
103
  ],
92
104
  }
93
105
  transformed.append(transformed_lb)
94
106
 
95
107
  # Classic ELB listeners are not returned anywhere else in AWS, so we must parse them out
96
108
  # of the describe_load_balancers response.
97
- if lb.get('ListenerDescriptions'):
109
+ if lb.get("ListenerDescriptions"):
98
110
  listener_data.extend(
99
111
  transform_load_balancer_listener_data(
100
112
  load_balancer_id,
101
- lb.get('ListenerDescriptions', []),
113
+ lb.get("ListenerDescriptions", []),
102
114
  ),
103
115
  )
104
116
 
@@ -107,18 +119,25 @@ def transform_load_balancer_data(load_balancers: list[dict]) -> tuple[list[dict]
107
119
 
108
120
  @timeit
109
121
  @aws_handle_regions
110
- def get_loadbalancer_data(boto3_session: boto3.session.Session, region: str) -> list[dict]:
111
- client = boto3_session.client('elb', region_name=region, config=get_botocore_config())
112
- paginator = client.get_paginator('describe_load_balancers')
122
+ def get_loadbalancer_data(
123
+ boto3_session: boto3.session.Session, region: str
124
+ ) -> list[dict]:
125
+ client = boto3_session.client(
126
+ "elb", region_name=region, config=get_botocore_config()
127
+ )
128
+ paginator = client.get_paginator("describe_load_balancers")
113
129
  elbs: list[dict] = []
114
130
  for page in paginator.paginate():
115
- elbs.extend(page['LoadBalancerDescriptions'])
131
+ elbs.extend(page["LoadBalancerDescriptions"])
116
132
  return elbs
117
133
 
118
134
 
119
135
  @timeit
120
136
  def load_load_balancers(
121
- neo4j_session: neo4j.Session, data: list[dict], region: str, current_aws_account_id: str,
137
+ neo4j_session: neo4j.Session,
138
+ data: list[dict],
139
+ region: str,
140
+ current_aws_account_id: str,
122
141
  update_tag: int,
123
142
  ) -> None:
124
143
  load(
@@ -133,7 +152,10 @@ def load_load_balancers(
133
152
 
134
153
  @timeit
135
154
  def load_load_balancer_listeners(
136
- neo4j_session: neo4j.Session, data: list[dict], region: str, current_aws_account_id: str,
155
+ neo4j_session: neo4j.Session,
156
+ data: list[dict],
157
+ region: str,
158
+ current_aws_account_id: str,
137
159
  update_tag: int,
138
160
  ) -> None:
139
161
  load(
@@ -147,22 +169,40 @@ def load_load_balancer_listeners(
147
169
 
148
170
 
149
171
  @timeit
150
- def cleanup_load_balancers(neo4j_session: neo4j.Session, common_job_parameters: dict) -> None:
151
- GraphJob.from_node_schema(ELBListenerSchema(), common_job_parameters).run(neo4j_session)
152
- GraphJob.from_node_schema(LoadBalancerSchema(), common_job_parameters).run(neo4j_session)
172
+ def cleanup_load_balancers(
173
+ neo4j_session: neo4j.Session, common_job_parameters: dict
174
+ ) -> None:
175
+ GraphJob.from_node_schema(ELBListenerSchema(), common_job_parameters).run(
176
+ neo4j_session
177
+ )
178
+ GraphJob.from_node_schema(LoadBalancerSchema(), common_job_parameters).run(
179
+ neo4j_session
180
+ )
153
181
 
154
182
 
155
183
  @timeit
156
184
  def sync_load_balancers(
157
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: list[str], current_aws_account_id: str,
158
- update_tag: int, common_job_parameters: dict,
185
+ neo4j_session: neo4j.Session,
186
+ boto3_session: boto3.session.Session,
187
+ regions: list[str],
188
+ current_aws_account_id: str,
189
+ update_tag: int,
190
+ common_job_parameters: dict,
159
191
  ) -> None:
160
192
  for region in regions:
161
- logger.info("Syncing EC2 load balancers for region '%s' in account '%s'.", region, current_aws_account_id)
193
+ logger.info(
194
+ "Syncing EC2 load balancers for region '%s' in account '%s'.",
195
+ region,
196
+ current_aws_account_id,
197
+ )
162
198
  data = get_loadbalancer_data(boto3_session, region)
163
199
  transformed_data, listener_data = transform_load_balancer_data(data)
164
200
 
165
- load_load_balancers(neo4j_session, transformed_data, region, current_aws_account_id, update_tag)
166
- load_load_balancer_listeners(neo4j_session, listener_data, region, current_aws_account_id, update_tag)
201
+ load_load_balancers(
202
+ neo4j_session, transformed_data, region, current_aws_account_id, update_tag
203
+ )
204
+ load_load_balancer_listeners(
205
+ neo4j_session, listener_data, region, current_aws_account_id, update_tag
206
+ )
167
207
 
168
208
  cleanup_load_balancers(neo4j_session, common_job_parameters)