cartography 0.102.0rc2__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 +138 -98
  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 -46
  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 +44 -34
  208. cartography/models/aws/ec2/route_tables.py +50 -43
  209. cartography/models/aws/ec2/routes.py +45 -37
  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.0rc2.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.0rc2.dist-info → cartography-0.103.0.dist-info}/WHEEL +1 -1
  294. cartography-0.102.0rc2.dist-info/RECORD +0 -381
  295. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/entry_points.txt +0 -0
  296. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/licenses/LICENSE +0 -0
  297. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/top_level.txt +0 -0
@@ -14,22 +14,28 @@ logger = logging.getLogger(__name__)
14
14
 
15
15
  @timeit
16
16
  @aws_handle_regions
17
- def get_configuration_recorders(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
18
- client = boto3_session.client('config', region_name=region)
17
+ def get_configuration_recorders(
18
+ boto3_session: boto3.session.Session,
19
+ region: str,
20
+ ) -> List[Dict]:
21
+ client = boto3_session.client("config", region_name=region)
19
22
  recorders: List[Dict] = []
20
23
  response = client.describe_configuration_recorders()
21
- for recorder in response.get('ConfigurationRecorders'):
24
+ for recorder in response.get("ConfigurationRecorders"):
22
25
  recorders.append(recorder)
23
26
  return recorders
24
27
 
25
28
 
26
29
  @timeit
27
30
  @aws_handle_regions
28
- def get_delivery_channels(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
29
- client = boto3_session.client('config', region_name=region)
31
+ def get_delivery_channels(
32
+ boto3_session: boto3.session.Session,
33
+ region: str,
34
+ ) -> List[Dict]:
35
+ client = boto3_session.client("config", region_name=region)
30
36
  channels: List[Dict] = []
31
37
  response = client.describe_delivery_channels()
32
- for channel in response.get('DeliveryChannels'):
38
+ for channel in response.get("DeliveryChannels"):
33
39
  channels.append(channel)
34
40
  return channels
35
41
 
@@ -37,11 +43,11 @@ def get_delivery_channels(boto3_session: boto3.session.Session, region: str) ->
37
43
  @timeit
38
44
  @aws_handle_regions
39
45
  def get_config_rules(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
40
- client = boto3_session.client('config', region_name=region)
41
- paginator = client.get_paginator('describe_config_rules')
46
+ client = boto3_session.client("config", region_name=region)
47
+ paginator = client.get_paginator("describe_config_rules")
42
48
  rules: List[Dict] = []
43
49
  for page in paginator.paginate():
44
- rules.extend(page['ConfigRules'])
50
+ rules.extend(page["ConfigRules"])
45
51
  return rules
46
52
 
47
53
 
@@ -72,7 +78,7 @@ def load_configuration_recorders(
72
78
  # generate a unique id using a combo of the name, account id and region, since the name
73
79
  # itself is unique per region.
74
80
  for recorder in data:
75
- recorder['_id'] = f'{recorder["name"]}:{current_aws_account_id}:{region}'
81
+ recorder["_id"] = f'{recorder["name"]}:{current_aws_account_id}:{region}'
76
82
 
77
83
  neo4j_session.run(
78
84
  ingest_configuration_recorders,
@@ -112,7 +118,7 @@ def load_delivery_channels(
112
118
  # generate a unique id using a combo of the name, account id and region, since the name
113
119
  # itself is unique per region.
114
120
  for channel in data:
115
- channel['_id'] = f'{channel["name"]}:{current_aws_account_id}:{region}'
121
+ channel["_id"] = f'{channel["name"]}:{current_aws_account_id}:{region}'
116
122
 
117
123
  neo4j_session.run(
118
124
  ingest_delivery_channels,
@@ -157,9 +163,9 @@ def load_config_rules(
157
163
  """
158
164
  for rule in data:
159
165
  details = []
160
- if rule.get('Source', {}).get('SourceDetails'):
166
+ if rule.get("Source", {}).get("SourceDetails"):
161
167
  for detail in rule["Source"]["SourceDetails"]:
162
- details.append(f'{detail}')
168
+ details.append(f"{detail}")
163
169
  rule["_source_details"] = details
164
170
  neo4j_session.run(
165
171
  ingest_config_rules,
@@ -172,20 +178,50 @@ def load_config_rules(
172
178
 
173
179
  @timeit
174
180
  def cleanup_config(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
175
- run_cleanup_job('aws_import_config_cleanup.json', neo4j_session, common_job_parameters)
181
+ run_cleanup_job(
182
+ "aws_import_config_cleanup.json",
183
+ neo4j_session,
184
+ common_job_parameters,
185
+ )
176
186
 
177
187
 
178
188
  @timeit
179
189
  def sync(
180
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
181
- update_tag: int, common_job_parameters: Dict,
190
+ neo4j_session: neo4j.Session,
191
+ boto3_session: boto3.session.Session,
192
+ regions: List[str],
193
+ current_aws_account_id: str,
194
+ update_tag: int,
195
+ common_job_parameters: Dict,
182
196
  ) -> None:
183
197
  for region in regions:
184
- logger.info("Syncing AWS Config for region '%s' in account '%s'.", region, current_aws_account_id)
198
+ logger.info(
199
+ "Syncing AWS Config for region '%s' in account '%s'.",
200
+ region,
201
+ current_aws_account_id,
202
+ )
185
203
  recorders = get_configuration_recorders(boto3_session, region)
186
- load_configuration_recorders(neo4j_session, recorders, region, current_aws_account_id, update_tag)
204
+ load_configuration_recorders(
205
+ neo4j_session,
206
+ recorders,
207
+ region,
208
+ current_aws_account_id,
209
+ update_tag,
210
+ )
187
211
  channels = get_delivery_channels(boto3_session, region)
188
- load_delivery_channels(neo4j_session, channels, region, current_aws_account_id, update_tag)
212
+ load_delivery_channels(
213
+ neo4j_session,
214
+ channels,
215
+ region,
216
+ current_aws_account_id,
217
+ update_tag,
218
+ )
189
219
  rules = get_config_rules(boto3_session, region)
190
- load_config_rules(neo4j_session, rules, region, current_aws_account_id, update_tag)
220
+ load_config_rules(
221
+ neo4j_session,
222
+ rules,
223
+ region,
224
+ current_aws_account_id,
225
+ update_tag,
226
+ )
191
227
  cleanup_config(neo4j_session, common_job_parameters)
@@ -22,12 +22,19 @@ stat_handler = get_stats_client(__name__)
22
22
 
23
23
  @timeit
24
24
  @aws_handle_regions
25
- def get_dynamodb_tables(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
26
- client = boto3_session.client('dynamodb', region_name=region, config=get_botocore_config())
27
- paginator = client.get_paginator('list_tables')
25
+ def get_dynamodb_tables(
26
+ boto3_session: boto3.session.Session,
27
+ region: str,
28
+ ) -> List[Dict]:
29
+ client = boto3_session.client(
30
+ "dynamodb",
31
+ region_name=region,
32
+ config=get_botocore_config(),
33
+ )
34
+ paginator = client.get_paginator("list_tables")
28
35
  dynamodb_tables = []
29
36
  for page in paginator.paginate():
30
- for table_name in page['TableNames']:
37
+ for table_name in page["TableNames"]:
31
38
  dynamodb_tables.append(client.describe_table(TableName=table_name))
32
39
  return dynamodb_tables
33
40
 
@@ -38,33 +45,50 @@ def transform_dynamodb_tables(dynamodb_tables: List, region: str) -> Any:
38
45
  ddb_gsi_data: List[Dict[str, Any]] = []
39
46
 
40
47
  for table in dynamodb_tables:
41
- ddb_table_data.append({
42
- 'Arn': table['Table']['TableArn'],
43
- 'TableName': table['Table']['TableName'],
44
- 'Region': region,
45
- 'Rows': table['Table']['ItemCount'],
46
- 'Size': table['Table']['TableSizeBytes'],
47
- 'ProvisionedThroughputReadCapacityUnits': table['Table']['ProvisionedThroughput']['ReadCapacityUnits'],
48
- 'ProvisionedThroughputWriteCapacityUnits': table['Table']['ProvisionedThroughput']['WriteCapacityUnits'],
49
- })
50
- for gsi in table['Table'].get('GlobalSecondaryIndexes', []):
51
- ddb_gsi_data.append({
52
- 'Arn': gsi['IndexArn'],
53
- 'TableArn': table['Table']['TableArn'],
54
- 'Region': region,
55
- 'ProvisionedThroughputReadCapacityUnits': gsi['ProvisionedThroughput']['ReadCapacityUnits'],
56
- 'ProvisionedThroughputWriteCapacityUnits': gsi['ProvisionedThroughput']['WriteCapacityUnits'],
57
- 'GSIName': gsi['IndexName'],
58
- })
48
+ ddb_table_data.append(
49
+ {
50
+ "Arn": table["Table"]["TableArn"],
51
+ "TableName": table["Table"]["TableName"],
52
+ "Region": region,
53
+ "Rows": table["Table"]["ItemCount"],
54
+ "Size": table["Table"]["TableSizeBytes"],
55
+ "ProvisionedThroughputReadCapacityUnits": table["Table"][
56
+ "ProvisionedThroughput"
57
+ ]["ReadCapacityUnits"],
58
+ "ProvisionedThroughputWriteCapacityUnits": table["Table"][
59
+ "ProvisionedThroughput"
60
+ ]["WriteCapacityUnits"],
61
+ },
62
+ )
63
+ for gsi in table["Table"].get("GlobalSecondaryIndexes", []):
64
+ ddb_gsi_data.append(
65
+ {
66
+ "Arn": gsi["IndexArn"],
67
+ "TableArn": table["Table"]["TableArn"],
68
+ "Region": region,
69
+ "ProvisionedThroughputReadCapacityUnits": gsi[
70
+ "ProvisionedThroughput"
71
+ ]["ReadCapacityUnits"],
72
+ "ProvisionedThroughputWriteCapacityUnits": gsi[
73
+ "ProvisionedThroughput"
74
+ ]["WriteCapacityUnits"],
75
+ "GSIName": gsi["IndexName"],
76
+ },
77
+ )
59
78
  return ddb_table_data, ddb_gsi_data
60
79
 
61
80
 
62
81
  @timeit
63
82
  def load_dynamodb_tables(
64
- neo4j_session: neo4j.Session, tables_data: List[Dict[str, Any]], region: str, current_aws_account_id: str,
83
+ neo4j_session: neo4j.Session,
84
+ tables_data: List[Dict[str, Any]],
85
+ region: str,
86
+ current_aws_account_id: str,
65
87
  aws_update_tag: int,
66
88
  ) -> None:
67
- logger.info(f"Loading Dynamo DB tables {len(tables_data)} for region '{region}' into graph.")
89
+ logger.info(
90
+ f"Loading Dynamo DB tables {len(tables_data)} for region '{region}' into graph.",
91
+ )
68
92
  load(
69
93
  neo4j_session,
70
94
  DynamoDBTableSchema(),
@@ -77,10 +101,15 @@ def load_dynamodb_tables(
77
101
 
78
102
  @timeit
79
103
  def load_dynamodb_gsi(
80
- neo4j_session: neo4j.Session, gsi_data: List[Dict[str, Any]], region: str, current_aws_account_id: str,
104
+ neo4j_session: neo4j.Session,
105
+ gsi_data: List[Dict[str, Any]],
106
+ region: str,
107
+ current_aws_account_id: str,
81
108
  aws_update_tag: int,
82
109
  ) -> None:
83
- logger.info(f"Loading Dynamo DB GSI {len(gsi_data)} for region '{region}' into graph.")
110
+ logger.info(
111
+ f"Loading Dynamo DB GSI {len(gsi_data)} for region '{region}' into graph.",
112
+ )
84
113
  load(
85
114
  neo4j_session,
86
115
  DynamoDBGSISchema(),
@@ -92,38 +121,77 @@ def load_dynamodb_gsi(
92
121
 
93
122
 
94
123
  @timeit
95
- def cleanup_dynamodb_tables(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
96
- GraphJob.from_node_schema(DynamoDBTableSchema(), common_job_parameters).run(neo4j_session)
97
- GraphJob.from_node_schema(DynamoDBGSISchema(), common_job_parameters).run(neo4j_session)
124
+ def cleanup_dynamodb_tables(
125
+ neo4j_session: neo4j.Session,
126
+ common_job_parameters: Dict,
127
+ ) -> None:
128
+ GraphJob.from_node_schema(DynamoDBTableSchema(), common_job_parameters).run(
129
+ neo4j_session,
130
+ )
131
+ GraphJob.from_node_schema(DynamoDBGSISchema(), common_job_parameters).run(
132
+ neo4j_session,
133
+ )
98
134
 
99
135
 
100
136
  @timeit
101
137
  def sync_dynamodb_tables(
102
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
103
- aws_update_tag: int, common_job_parameters: Dict,
138
+ neo4j_session: neo4j.Session,
139
+ boto3_session: boto3.session.Session,
140
+ regions: List[str],
141
+ current_aws_account_id: str,
142
+ aws_update_tag: int,
143
+ common_job_parameters: Dict,
104
144
  ) -> None:
105
145
  for region in regions:
106
- logger.info("Syncing DynamoDB for region in '%s' in account '%s'.", region, current_aws_account_id)
146
+ logger.info(
147
+ "Syncing DynamoDB for region in '%s' in account '%s'.",
148
+ region,
149
+ current_aws_account_id,
150
+ )
107
151
  dynamodb_tables = get_dynamodb_tables(boto3_session, region)
108
- ddb_table_data, ddb_gsi_data = transform_dynamodb_tables(dynamodb_tables, region)
109
- load_dynamodb_tables(neo4j_session, ddb_table_data, region, current_aws_account_id, aws_update_tag)
110
- load_dynamodb_gsi(neo4j_session, ddb_gsi_data, region, current_aws_account_id, aws_update_tag)
152
+ ddb_table_data, ddb_gsi_data = transform_dynamodb_tables(
153
+ dynamodb_tables,
154
+ region,
155
+ )
156
+ load_dynamodb_tables(
157
+ neo4j_session,
158
+ ddb_table_data,
159
+ region,
160
+ current_aws_account_id,
161
+ aws_update_tag,
162
+ )
163
+ load_dynamodb_gsi(
164
+ neo4j_session,
165
+ ddb_gsi_data,
166
+ region,
167
+ current_aws_account_id,
168
+ aws_update_tag,
169
+ )
111
170
  cleanup_dynamodb_tables(neo4j_session, common_job_parameters)
112
171
 
113
172
 
114
173
  @timeit
115
174
  def sync(
116
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
117
- update_tag: int, common_job_parameters: Dict,
175
+ neo4j_session: neo4j.Session,
176
+ boto3_session: boto3.session.Session,
177
+ regions: List[str],
178
+ current_aws_account_id: str,
179
+ update_tag: int,
180
+ common_job_parameters: Dict,
118
181
  ) -> None:
119
182
  sync_dynamodb_tables(
120
- neo4j_session, boto3_session, regions, current_aws_account_id, update_tag, common_job_parameters,
183
+ neo4j_session,
184
+ boto3_session,
185
+ regions,
186
+ current_aws_account_id,
187
+ update_tag,
188
+ common_job_parameters,
121
189
  )
122
190
  merge_module_sync_metadata(
123
191
  neo4j_session,
124
- group_type='AWSAccount',
192
+ group_type="AWSAccount",
125
193
  group_id=current_aws_account_id,
126
- synced_type='DynamoDBTable',
194
+ synced_type="DynamoDBTable",
127
195
  update_tag=update_tag,
128
196
  stat_handler=stat_handler,
129
197
  )
@@ -10,6 +10,6 @@ logger = logging.getLogger(__name__)
10
10
 
11
11
  @timeit
12
12
  def get_ec2_regions(boto3_session: boto3.session.Session) -> List[str]:
13
- client = boto3_session.client('ec2')
13
+ client = boto3_session.client("ec2")
14
14
  result = client.describe_regions()
15
- return [r['RegionName'] for r in result['Regions']]
15
+ return [r["RegionName"] for r in result["Regions"]]