cartography 0.93.0rc1__py3-none-any.whl → 0.123.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.
Files changed (822) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +34 -0
  3. cartography/cli.py +903 -225
  4. cartography/client/aws/__init__.py +19 -0
  5. cartography/client/aws/ecr.py +51 -0
  6. cartography/client/core/tx.py +400 -27
  7. cartography/config.py +215 -10
  8. cartography/data/azure_permission_relationships.yaml +20 -0
  9. cartography/data/gcp_permission_relationships.yaml +21 -0
  10. cartography/data/indexes.cypher +1 -200
  11. cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
  12. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  13. cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
  14. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  15. cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
  16. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  17. cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
  18. cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
  19. cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
  20. cartography/driftdetect/__main__.py +1 -2
  21. cartography/driftdetect/add_shortcut.py +10 -2
  22. cartography/driftdetect/cli.py +72 -75
  23. cartography/driftdetect/detect_deviations.py +7 -3
  24. cartography/driftdetect/get_states.py +20 -8
  25. cartography/driftdetect/model.py +5 -5
  26. cartography/driftdetect/serializers.py +8 -6
  27. cartography/driftdetect/storage.py +2 -2
  28. cartography/graph/cleanupbuilder.py +255 -35
  29. cartography/graph/job.py +104 -20
  30. cartography/graph/querybuilder.py +689 -91
  31. cartography/graph/statement.py +49 -36
  32. cartography/intel/airbyte/__init__.py +105 -0
  33. cartography/intel/airbyte/connections.py +120 -0
  34. cartography/intel/airbyte/destinations.py +81 -0
  35. cartography/intel/airbyte/organizations.py +59 -0
  36. cartography/intel/airbyte/sources.py +78 -0
  37. cartography/intel/airbyte/tags.py +64 -0
  38. cartography/intel/airbyte/users.py +106 -0
  39. cartography/intel/airbyte/util.py +122 -0
  40. cartography/intel/airbyte/workspaces.py +63 -0
  41. cartography/intel/analysis.py +4 -1
  42. cartography/intel/anthropic/__init__.py +62 -0
  43. cartography/intel/anthropic/apikeys.py +72 -0
  44. cartography/intel/anthropic/users.py +75 -0
  45. cartography/intel/anthropic/util.py +51 -0
  46. cartography/intel/anthropic/workspaces.py +95 -0
  47. cartography/intel/aws/__init__.py +137 -59
  48. cartography/intel/aws/acm.py +124 -0
  49. cartography/intel/aws/apigateway.py +482 -217
  50. cartography/intel/aws/apigatewayv2.py +116 -0
  51. cartography/intel/aws/cloudtrail.py +105 -0
  52. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  53. cartography/intel/aws/cloudwatch.py +239 -0
  54. cartography/intel/aws/codebuild.py +132 -0
  55. cartography/intel/aws/cognito.py +201 -0
  56. cartography/intel/aws/config.py +63 -23
  57. cartography/intel/aws/dynamodb.py +108 -40
  58. cartography/intel/aws/ec2/__init__.py +2 -2
  59. cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
  60. cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
  61. cartography/intel/aws/ec2/images.py +74 -39
  62. cartography/intel/aws/ec2/instances.py +262 -137
  63. cartography/intel/aws/ec2/internet_gateways.py +44 -13
  64. cartography/intel/aws/ec2/key_pairs.py +72 -39
  65. cartography/intel/aws/ec2/launch_templates.py +143 -66
  66. cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
  67. cartography/intel/aws/ec2/load_balancers.py +165 -147
  68. cartography/intel/aws/ec2/network_acls.py +233 -0
  69. cartography/intel/aws/ec2/network_interfaces.py +150 -87
  70. cartography/intel/aws/ec2/reserved_instances.py +48 -17
  71. cartography/intel/aws/ec2/route_tables.py +327 -0
  72. cartography/intel/aws/ec2/security_groups.py +189 -121
  73. cartography/intel/aws/ec2/snapshots.py +93 -91
  74. cartography/intel/aws/ec2/subnets.py +70 -58
  75. cartography/intel/aws/ec2/tgw.py +111 -39
  76. cartography/intel/aws/ec2/util.py +1 -1
  77. cartography/intel/aws/ec2/volumes.py +69 -41
  78. cartography/intel/aws/ec2/vpc.py +157 -116
  79. cartography/intel/aws/ec2/vpc_peerings.py +317 -121
  80. cartography/intel/aws/ecr.py +336 -93
  81. cartography/intel/aws/ecr_image_layers.py +923 -0
  82. cartography/intel/aws/ecs.py +310 -403
  83. cartography/intel/aws/efs.py +261 -0
  84. cartography/intel/aws/eks.py +55 -29
  85. cartography/intel/aws/elasticache.py +130 -83
  86. cartography/intel/aws/elasticsearch.py +70 -24
  87. cartography/intel/aws/emr.py +61 -23
  88. cartography/intel/aws/eventbridge.py +164 -0
  89. cartography/intel/aws/glue.py +181 -0
  90. cartography/intel/aws/guardduty.py +443 -0
  91. cartography/intel/aws/iam.py +978 -464
  92. cartography/intel/aws/iam_instance_profiles.py +73 -0
  93. cartography/intel/aws/identitycenter.py +847 -0
  94. cartography/intel/aws/inspector.py +330 -133
  95. cartography/intel/aws/kms.py +235 -209
  96. cartography/intel/aws/lambda_function.py +328 -176
  97. cartography/intel/aws/organizations.py +40 -19
  98. cartography/intel/aws/permission_relationships.py +144 -68
  99. cartography/intel/aws/rds.py +467 -412
  100. cartography/intel/aws/redshift.py +116 -50
  101. cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
  102. cartography/intel/aws/resources.py +80 -42
  103. cartography/intel/aws/route53.py +419 -318
  104. cartography/intel/aws/s3.py +489 -96
  105. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  106. cartography/intel/aws/secretsmanager.py +217 -40
  107. cartography/intel/aws/securityhub.py +23 -10
  108. cartography/intel/aws/sns.py +226 -0
  109. cartography/intel/aws/sqs.py +74 -96
  110. cartography/intel/aws/ssm.py +142 -33
  111. cartography/intel/aws/util/arns.py +7 -7
  112. cartography/intel/aws/util/common.py +31 -4
  113. cartography/intel/azure/__init__.py +259 -46
  114. cartography/intel/azure/aks.py +175 -0
  115. cartography/intel/azure/app_service.py +105 -0
  116. cartography/intel/azure/compute.py +141 -120
  117. cartography/intel/azure/container_instances.py +95 -0
  118. cartography/intel/azure/cosmosdb.py +706 -519
  119. cartography/intel/azure/data_factory.py +85 -0
  120. cartography/intel/azure/data_factory_dataset.py +128 -0
  121. cartography/intel/azure/data_factory_linked_service.py +119 -0
  122. cartography/intel/azure/data_factory_pipeline.py +142 -0
  123. cartography/intel/azure/data_lake.py +124 -0
  124. cartography/intel/azure/event_grid.py +94 -0
  125. cartography/intel/azure/functions.py +124 -0
  126. cartography/intel/azure/load_balancers.py +263 -0
  127. cartography/intel/azure/logic_apps.py +101 -0
  128. cartography/intel/azure/monitor.py +105 -0
  129. cartography/intel/azure/network.py +467 -0
  130. cartography/intel/azure/permission_relationships.py +466 -0
  131. cartography/intel/azure/rbac.py +309 -0
  132. cartography/intel/azure/resource_groups.py +82 -0
  133. cartography/intel/azure/security_center.py +106 -0
  134. cartography/intel/azure/sql.py +436 -392
  135. cartography/intel/azure/storage.py +467 -335
  136. cartography/intel/azure/subscription.py +49 -55
  137. cartography/intel/azure/tenant.py +46 -28
  138. cartography/intel/azure/util/common.py +13 -0
  139. cartography/intel/azure/util/credentials.py +58 -143
  140. cartography/intel/azure/util/tag.py +41 -0
  141. cartography/intel/bigfix/__init__.py +2 -2
  142. cartography/intel/bigfix/computers.py +93 -65
  143. cartography/intel/cloudflare/__init__.py +74 -0
  144. cartography/intel/cloudflare/accounts.py +57 -0
  145. cartography/intel/cloudflare/dnsrecords.py +64 -0
  146. cartography/intel/cloudflare/members.py +75 -0
  147. cartography/intel/cloudflare/roles.py +65 -0
  148. cartography/intel/cloudflare/zones.py +64 -0
  149. cartography/intel/create_indexes.py +5 -3
  150. cartography/intel/crowdstrike/__init__.py +26 -12
  151. cartography/intel/crowdstrike/endpoints.py +17 -45
  152. cartography/intel/crowdstrike/spotlight.py +13 -5
  153. cartography/intel/cve/__init__.py +91 -26
  154. cartography/intel/cve/feed.py +77 -56
  155. cartography/intel/digitalocean/__init__.py +22 -13
  156. cartography/intel/digitalocean/compute.py +75 -108
  157. cartography/intel/digitalocean/management.py +44 -80
  158. cartography/intel/digitalocean/platform.py +48 -43
  159. cartography/intel/dns.py +41 -12
  160. cartography/intel/duo/__init__.py +21 -16
  161. cartography/intel/duo/api_host.py +14 -9
  162. cartography/intel/duo/endpoints.py +50 -45
  163. cartography/intel/duo/groups.py +18 -14
  164. cartography/intel/duo/phones.py +37 -34
  165. cartography/intel/duo/tokens.py +26 -23
  166. cartography/intel/duo/users.py +54 -50
  167. cartography/intel/duo/web_authn_credentials.py +30 -25
  168. cartography/intel/entra/__init__.py +160 -0
  169. cartography/intel/entra/app_role_assignments.py +284 -0
  170. cartography/intel/entra/applications.py +182 -0
  171. cartography/intel/entra/federation/__init__.py +0 -0
  172. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  173. cartography/intel/entra/groups.py +198 -0
  174. cartography/intel/entra/ou.py +136 -0
  175. cartography/intel/entra/service_principals.py +217 -0
  176. cartography/intel/entra/users.py +259 -0
  177. cartography/intel/gcp/__init__.py +381 -175
  178. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  179. cartography/intel/gcp/bigtable_backup.py +91 -0
  180. cartography/intel/gcp/bigtable_cluster.py +93 -0
  181. cartography/intel/gcp/bigtable_instance.py +86 -0
  182. cartography/intel/gcp/bigtable_table.py +87 -0
  183. cartography/intel/gcp/cai.py +292 -0
  184. cartography/intel/gcp/clients.py +112 -0
  185. cartography/intel/gcp/compute.py +521 -325
  186. cartography/intel/gcp/crm/__init__.py +0 -0
  187. cartography/intel/gcp/crm/folders.py +114 -0
  188. cartography/intel/gcp/crm/orgs.py +70 -0
  189. cartography/intel/gcp/crm/projects.py +120 -0
  190. cartography/intel/gcp/dns.py +134 -179
  191. cartography/intel/gcp/gke.py +100 -107
  192. cartography/intel/gcp/iam.py +262 -0
  193. cartography/intel/gcp/permission_relationships.py +394 -0
  194. cartography/intel/gcp/policy_bindings.py +225 -0
  195. cartography/intel/gcp/storage.py +103 -158
  196. cartography/intel/github/__init__.py +66 -27
  197. cartography/intel/github/commits.py +423 -0
  198. cartography/intel/github/repos.py +871 -160
  199. cartography/intel/github/teams.py +386 -53
  200. cartography/intel/github/users.py +214 -49
  201. cartography/intel/github/util.py +50 -35
  202. cartography/intel/googleworkspace/__init__.py +193 -0
  203. cartography/intel/googleworkspace/devices.py +254 -0
  204. cartography/intel/googleworkspace/groups.py +568 -0
  205. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  206. cartography/intel/googleworkspace/tenant.py +85 -0
  207. cartography/intel/googleworkspace/users.py +138 -0
  208. cartography/intel/gsuite/__init__.py +101 -42
  209. cartography/intel/gsuite/groups.py +291 -0
  210. cartography/intel/gsuite/users.py +142 -0
  211. cartography/intel/jamf/__init__.py +19 -1
  212. cartography/intel/jamf/computers.py +37 -8
  213. cartography/intel/jamf/util.py +7 -2
  214. cartography/intel/kandji/__init__.py +6 -3
  215. cartography/intel/kandji/devices.py +40 -10
  216. cartography/intel/keycloak/__init__.py +153 -0
  217. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  218. cartography/intel/keycloak/authenticationflows.py +77 -0
  219. cartography/intel/keycloak/clients.py +187 -0
  220. cartography/intel/keycloak/groups.py +126 -0
  221. cartography/intel/keycloak/identityproviders.py +94 -0
  222. cartography/intel/keycloak/organizations.py +163 -0
  223. cartography/intel/keycloak/realms.py +61 -0
  224. cartography/intel/keycloak/roles.py +202 -0
  225. cartography/intel/keycloak/scopes.py +73 -0
  226. cartography/intel/keycloak/users.py +70 -0
  227. cartography/intel/keycloak/util.py +47 -0
  228. cartography/intel/kubernetes/__init__.py +60 -14
  229. cartography/intel/kubernetes/clusters.py +86 -0
  230. cartography/intel/kubernetes/eks.py +402 -0
  231. cartography/intel/kubernetes/namespaces.py +60 -55
  232. cartography/intel/kubernetes/pods.py +171 -75
  233. cartography/intel/kubernetes/rbac.py +597 -0
  234. cartography/intel/kubernetes/secrets.py +95 -45
  235. cartography/intel/kubernetes/services.py +131 -63
  236. cartography/intel/kubernetes/util.py +142 -14
  237. cartography/intel/lastpass/__init__.py +2 -2
  238. cartography/intel/lastpass/users.py +23 -12
  239. cartography/intel/oci/__init__.py +44 -11
  240. cartography/intel/oci/iam.py +157 -47
  241. cartography/intel/oci/organizations.py +16 -7
  242. cartography/intel/oci/utils.py +71 -25
  243. cartography/intel/okta/__init__.py +66 -15
  244. cartography/intel/okta/applications.py +57 -25
  245. cartography/intel/okta/awssaml.py +105 -41
  246. cartography/intel/okta/factors.py +19 -5
  247. cartography/intel/okta/groups.py +61 -31
  248. cartography/intel/okta/organization.py +8 -2
  249. cartography/intel/okta/origins.py +9 -3
  250. cartography/intel/okta/roles.py +20 -7
  251. cartography/intel/okta/users.py +31 -10
  252. cartography/intel/okta/utils.py +6 -4
  253. cartography/intel/ontology/__init__.py +44 -0
  254. cartography/intel/ontology/devices.py +54 -0
  255. cartography/intel/ontology/users.py +54 -0
  256. cartography/intel/ontology/utils.py +176 -0
  257. cartography/intel/openai/__init__.py +86 -0
  258. cartography/intel/openai/adminapikeys.py +89 -0
  259. cartography/intel/openai/apikeys.py +96 -0
  260. cartography/intel/openai/projects.py +97 -0
  261. cartography/intel/openai/serviceaccounts.py +82 -0
  262. cartography/intel/openai/users.py +75 -0
  263. cartography/intel/openai/util.py +45 -0
  264. cartography/intel/pagerduty/__init__.py +8 -7
  265. cartography/intel/pagerduty/escalation_policies.py +31 -12
  266. cartography/intel/pagerduty/schedules.py +21 -8
  267. cartography/intel/pagerduty/services.py +18 -7
  268. cartography/intel/pagerduty/teams.py +13 -5
  269. cartography/intel/pagerduty/users.py +6 -2
  270. cartography/intel/pagerduty/vendors.py +6 -2
  271. cartography/intel/scaleway/__init__.py +127 -0
  272. cartography/intel/scaleway/iam/__init__.py +0 -0
  273. cartography/intel/scaleway/iam/apikeys.py +71 -0
  274. cartography/intel/scaleway/iam/applications.py +71 -0
  275. cartography/intel/scaleway/iam/groups.py +71 -0
  276. cartography/intel/scaleway/iam/users.py +71 -0
  277. cartography/intel/scaleway/instances/__init__.py +0 -0
  278. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  279. cartography/intel/scaleway/instances/instances.py +92 -0
  280. cartography/intel/scaleway/projects.py +79 -0
  281. cartography/intel/scaleway/storage/__init__.py +0 -0
  282. cartography/intel/scaleway/storage/snapshots.py +86 -0
  283. cartography/intel/scaleway/storage/volumes.py +84 -0
  284. cartography/intel/scaleway/utils.py +37 -0
  285. cartography/intel/semgrep/__init__.py +30 -5
  286. cartography/intel/semgrep/dependencies.py +255 -0
  287. cartography/intel/semgrep/deployment.py +69 -0
  288. cartography/intel/semgrep/findings.py +157 -117
  289. cartography/intel/sentinelone/__init__.py +75 -0
  290. cartography/intel/sentinelone/account.py +140 -0
  291. cartography/intel/sentinelone/agent.py +139 -0
  292. cartography/intel/sentinelone/api.py +124 -0
  293. cartography/intel/sentinelone/application.py +248 -0
  294. cartography/intel/sentinelone/cve.py +119 -0
  295. cartography/intel/sentinelone/utils.py +28 -0
  296. cartography/intel/slack/__init__.py +78 -0
  297. cartography/intel/slack/channels.py +80 -0
  298. cartography/intel/slack/groups.py +90 -0
  299. cartography/intel/slack/teams.py +65 -0
  300. cartography/intel/slack/users.py +57 -0
  301. cartography/intel/slack/utils.py +29 -0
  302. cartography/intel/snipeit/__init__.py +44 -0
  303. cartography/intel/snipeit/asset.py +80 -0
  304. cartography/intel/snipeit/user.py +78 -0
  305. cartography/intel/snipeit/util.py +40 -0
  306. cartography/intel/spacelift/__init__.py +161 -0
  307. cartography/intel/spacelift/account.py +73 -0
  308. cartography/intel/spacelift/ec2_ownership.py +280 -0
  309. cartography/intel/spacelift/runs.py +463 -0
  310. cartography/intel/spacelift/spaces.py +112 -0
  311. cartography/intel/spacelift/stacks.py +119 -0
  312. cartography/intel/spacelift/util.py +122 -0
  313. cartography/intel/spacelift/workerpools.py +131 -0
  314. cartography/intel/spacelift/workers.py +128 -0
  315. cartography/intel/tailscale/__init__.py +77 -0
  316. cartography/intel/tailscale/acls.py +146 -0
  317. cartography/intel/tailscale/devices.py +127 -0
  318. cartography/intel/tailscale/postureintegrations.py +81 -0
  319. cartography/intel/tailscale/tailnets.py +76 -0
  320. cartography/intel/tailscale/users.py +80 -0
  321. cartography/intel/tailscale/utils.py +132 -0
  322. cartography/intel/trivy/__init__.py +272 -0
  323. cartography/intel/trivy/scanner.py +386 -0
  324. cartography/models/airbyte/__init__.py +0 -0
  325. cartography/models/airbyte/connection.py +138 -0
  326. cartography/models/airbyte/destination.py +75 -0
  327. cartography/models/airbyte/organization.py +19 -0
  328. cartography/models/airbyte/source.py +75 -0
  329. cartography/models/airbyte/stream.py +74 -0
  330. cartography/models/airbyte/tag.py +69 -0
  331. cartography/models/airbyte/user.py +115 -0
  332. cartography/models/airbyte/workspace.py +46 -0
  333. cartography/models/anthropic/__init__.py +0 -0
  334. cartography/models/anthropic/apikey.py +94 -0
  335. cartography/models/anthropic/organization.py +19 -0
  336. cartography/models/anthropic/user.py +52 -0
  337. cartography/models/anthropic/workspace.py +90 -0
  338. cartography/models/aws/acm/__init__.py +0 -0
  339. cartography/models/aws/acm/certificate.py +75 -0
  340. cartography/models/aws/apigateway/__init__.py +0 -0
  341. cartography/models/aws/apigateway/apigateway.py +51 -0
  342. cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
  343. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  344. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  345. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  346. cartography/models/aws/apigateway/apigatewayresource.py +70 -0
  347. cartography/models/aws/apigateway/apigatewaystage.py +75 -0
  348. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  349. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  350. cartography/models/aws/cloudtrail/__init__.py +0 -0
  351. cartography/models/aws/cloudtrail/management_events.py +153 -0
  352. cartography/models/aws/cloudtrail/trail.py +106 -0
  353. cartography/models/aws/cloudwatch/__init__.py +0 -0
  354. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  355. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  356. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  357. cartography/models/aws/codebuild/__init__.py +0 -0
  358. cartography/models/aws/codebuild/project.py +49 -0
  359. cartography/models/aws/cognito/__init__.py +0 -0
  360. cartography/models/aws/cognito/identity_pool.py +70 -0
  361. cartography/models/aws/cognito/user_pool.py +47 -0
  362. cartography/models/aws/dynamodb/gsi.py +30 -22
  363. cartography/models/aws/dynamodb/tables.py +27 -17
  364. cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
  365. cartography/models/aws/ec2/images.py +36 -34
  366. cartography/models/aws/ec2/instances.py +85 -38
  367. cartography/models/aws/ec2/keypair.py +59 -0
  368. cartography/models/aws/ec2/keypair_instance.py +76 -0
  369. cartography/models/aws/ec2/launch_configurations.py +59 -0
  370. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  371. cartography/models/aws/ec2/launch_templates.py +21 -17
  372. cartography/models/aws/ec2/load_balancer_listeners.py +72 -0
  373. cartography/models/aws/ec2/load_balancers.py +112 -0
  374. cartography/models/aws/ec2/network_acl_rules.py +106 -0
  375. cartography/models/aws/ec2/network_acls.py +95 -0
  376. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  377. cartography/models/aws/ec2/networkinterfaces.py +57 -37
  378. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  379. cartography/models/aws/ec2/reservations.py +18 -14
  380. cartography/models/aws/ec2/route_table_associations.py +97 -0
  381. cartography/models/aws/ec2/route_tables.py +128 -0
  382. cartography/models/aws/ec2/routes.py +85 -0
  383. cartography/models/aws/ec2/security_group_rules.py +109 -0
  384. cartography/models/aws/ec2/security_groups.py +90 -0
  385. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  386. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  387. cartography/models/aws/ec2/snapshots.py +58 -0
  388. cartography/models/aws/ec2/subnet_instance.py +26 -19
  389. cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
  390. cartography/models/aws/ec2/subnets.py +65 -0
  391. cartography/models/aws/ec2/volumes.py +67 -40
  392. cartography/models/aws/ec2/vpc.py +46 -0
  393. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  394. cartography/models/aws/ec2/vpc_peering.py +157 -0
  395. cartography/models/aws/ecr/__init__.py +0 -0
  396. cartography/models/aws/ecr/image.py +146 -0
  397. cartography/models/aws/ecr/image_layer.py +107 -0
  398. cartography/models/aws/ecr/repository.py +72 -0
  399. cartography/models/aws/ecr/repository_image.py +95 -0
  400. cartography/models/aws/ecs/__init__.py +0 -0
  401. cartography/models/aws/ecs/clusters.py +64 -0
  402. cartography/models/aws/ecs/container_definitions.py +93 -0
  403. cartography/models/aws/ecs/container_instances.py +84 -0
  404. cartography/models/aws/ecs/containers.py +101 -0
  405. cartography/models/aws/ecs/services.py +134 -0
  406. cartography/models/aws/ecs/task_definitions.py +135 -0
  407. cartography/models/aws/ecs/tasks.py +134 -0
  408. cartography/models/aws/efs/__init__.py +0 -0
  409. cartography/models/aws/efs/access_point.py +77 -0
  410. cartography/models/aws/efs/file_system.py +60 -0
  411. cartography/models/aws/efs/mount_target.py +79 -0
  412. cartography/models/aws/eks/clusters.py +23 -21
  413. cartography/models/aws/elasticache/__init__.py +0 -0
  414. cartography/models/aws/elasticache/cluster.py +65 -0
  415. cartography/models/aws/elasticache/topic.py +67 -0
  416. cartography/models/aws/emr.py +32 -30
  417. cartography/models/aws/eventbridge/__init__.py +0 -0
  418. cartography/models/aws/eventbridge/rule.py +77 -0
  419. cartography/models/aws/eventbridge/target.py +71 -0
  420. cartography/models/aws/glue/__init__.py +0 -0
  421. cartography/models/aws/glue/connection.py +51 -0
  422. cartography/models/aws/glue/job.py +69 -0
  423. cartography/models/aws/guardduty/__init__.py +1 -0
  424. cartography/models/aws/guardduty/detectors.py +50 -0
  425. cartography/models/aws/guardduty/findings.py +121 -0
  426. cartography/models/aws/iam/__init__.py +0 -0
  427. cartography/models/aws/iam/access_key.py +103 -0
  428. cartography/models/aws/iam/account_role.py +24 -0
  429. cartography/models/aws/iam/federated_principal.py +60 -0
  430. cartography/models/aws/iam/group.py +60 -0
  431. cartography/models/aws/iam/group_membership.py +27 -0
  432. cartography/models/aws/iam/inline_policy.py +78 -0
  433. cartography/models/aws/iam/instanceprofile.py +76 -0
  434. cartography/models/aws/iam/managed_policy.py +51 -0
  435. cartography/models/aws/iam/policy_statement.py +57 -0
  436. cartography/models/aws/iam/role.py +83 -0
  437. cartography/models/aws/iam/root_principal.py +52 -0
  438. cartography/models/aws/iam/service_principal.py +30 -0
  439. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  440. cartography/models/aws/iam/user.py +59 -0
  441. cartography/models/aws/identitycenter/__init__.py +0 -0
  442. cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
  443. cartography/models/aws/identitycenter/awspermissionset.py +162 -0
  444. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  445. cartography/models/aws/identitycenter/awsssouser.py +110 -0
  446. cartography/models/aws/inspector/findings.py +124 -58
  447. cartography/models/aws/inspector/packages.py +18 -42
  448. cartography/models/aws/kms/__init__.py +0 -0
  449. cartography/models/aws/kms/aliases.py +86 -0
  450. cartography/models/aws/kms/grants.py +65 -0
  451. cartography/models/aws/kms/keys.py +88 -0
  452. cartography/models/aws/lambda_function/__init__.py +0 -0
  453. cartography/models/aws/lambda_function/alias.py +74 -0
  454. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  455. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  456. cartography/models/aws/lambda_function/layer.py +72 -0
  457. cartography/models/aws/rds/__init__.py +0 -0
  458. cartography/models/aws/rds/cluster.py +91 -0
  459. cartography/models/aws/rds/event_subscription.py +146 -0
  460. cartography/models/aws/rds/instance.py +156 -0
  461. cartography/models/aws/rds/snapshot.py +108 -0
  462. cartography/models/aws/rds/subnet_group.py +101 -0
  463. cartography/models/aws/route53/__init__.py +0 -0
  464. cartography/models/aws/route53/dnsrecord.py +235 -0
  465. cartography/models/aws/route53/nameserver.py +63 -0
  466. cartography/models/aws/route53/subzone.py +40 -0
  467. cartography/models/aws/route53/zone.py +47 -0
  468. cartography/models/aws/s3/__init__.py +0 -0
  469. cartography/models/aws/s3/account_public_access_block.py +51 -0
  470. cartography/models/aws/s3/notification.py +24 -0
  471. cartography/models/aws/secretsmanager/__init__.py +0 -0
  472. cartography/models/aws/secretsmanager/secret.py +106 -0
  473. cartography/models/aws/secretsmanager/secret_version.py +114 -0
  474. cartography/models/aws/sns/__init__.py +0 -0
  475. cartography/models/aws/sns/topic.py +50 -0
  476. cartography/models/aws/sns/topic_subscription.py +74 -0
  477. cartography/models/aws/sqs/__init__.py +0 -0
  478. cartography/models/aws/sqs/queue.py +89 -0
  479. cartography/models/aws/ssm/instance_information.py +51 -39
  480. cartography/models/aws/ssm/instance_patch.py +32 -26
  481. cartography/models/aws/ssm/parameters.py +84 -0
  482. cartography/models/azure/__init__.py +0 -0
  483. cartography/models/azure/aks_cluster.py +54 -0
  484. cartography/models/azure/aks_nodepool.py +54 -0
  485. cartography/models/azure/app_service.py +59 -0
  486. cartography/models/azure/container_instance.py +57 -0
  487. cartography/models/azure/cosmosdb/__init__.py +0 -0
  488. cartography/models/azure/cosmosdb/account.py +77 -0
  489. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  490. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  491. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  492. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  493. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  494. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  495. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  496. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  497. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  498. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  499. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  500. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  501. cartography/models/azure/data_factory/__init__.py +0 -0
  502. cartography/models/azure/data_factory/data_factory.py +51 -0
  503. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  504. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  505. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  506. cartography/models/azure/data_lake_filesystem.py +51 -0
  507. cartography/models/azure/event_grid_topic.py +57 -0
  508. cartography/models/azure/function_app.py +59 -0
  509. cartography/models/azure/load_balancer/__init__.py +0 -0
  510. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  511. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  512. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  513. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  514. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  515. cartography/models/azure/logic_apps.py +56 -0
  516. cartography/models/azure/monitor.py +54 -0
  517. cartography/models/azure/network_interface.py +112 -0
  518. cartography/models/azure/network_security_group.py +50 -0
  519. cartography/models/azure/permission_relationships.py +60 -0
  520. cartography/models/azure/principal.py +41 -0
  521. cartography/models/azure/public_ip_address.py +50 -0
  522. cartography/models/azure/rbac.py +268 -0
  523. cartography/models/azure/resource_groups.py +52 -0
  524. cartography/models/azure/security_center.py +50 -0
  525. cartography/models/azure/sql/__init__.py +0 -0
  526. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  527. cartography/models/azure/sql/elasticpool.py +77 -0
  528. cartography/models/azure/sql/failovergroup.py +73 -0
  529. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  530. cartography/models/azure/sql/replicationlink.py +81 -0
  531. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  532. cartography/models/azure/sql/restorepoint.py +74 -0
  533. cartography/models/azure/sql/serveradadministrator.py +74 -0
  534. cartography/models/azure/sql/serverdnsalias.py +71 -0
  535. cartography/models/azure/sql/sqldatabase.py +85 -0
  536. cartography/models/azure/sql/sqlserver.py +50 -0
  537. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  538. cartography/models/azure/storage/__init__.py +0 -0
  539. cartography/models/azure/storage/account.py +59 -0
  540. cartography/models/azure/storage/blobcontainer.py +85 -0
  541. cartography/models/azure/storage/blobservice.py +71 -0
  542. cartography/models/azure/storage/fileservice.py +71 -0
  543. cartography/models/azure/storage/fileshare.py +82 -0
  544. cartography/models/azure/storage/queue.py +71 -0
  545. cartography/models/azure/storage/queueservice.py +73 -0
  546. cartography/models/azure/storage/table.py +72 -0
  547. cartography/models/azure/storage/tableservice.py +73 -0
  548. cartography/models/azure/subnet.py +101 -0
  549. cartography/models/azure/subscription.py +47 -0
  550. cartography/models/azure/tags/__init__.py +0 -0
  551. cartography/models/azure/tags/storage_tag.py +40 -0
  552. cartography/models/azure/tags/tag.py +37 -0
  553. cartography/models/azure/tenant.py +17 -0
  554. cartography/models/azure/virtual_network.py +49 -0
  555. cartography/models/azure/vm/__init__.py +0 -0
  556. cartography/models/azure/vm/datadisk.py +80 -0
  557. cartography/models/azure/vm/disk.py +55 -0
  558. cartography/models/azure/vm/snapshot.py +56 -0
  559. cartography/models/azure/vm/virtualmachine.py +59 -0
  560. cartography/models/bigfix/bigfix_computer.py +42 -38
  561. cartography/models/bigfix/bigfix_root.py +3 -3
  562. cartography/models/cloudflare/__init__.py +0 -0
  563. cartography/models/cloudflare/account.py +25 -0
  564. cartography/models/cloudflare/dnsrecord.py +55 -0
  565. cartography/models/cloudflare/member.py +86 -0
  566. cartography/models/cloudflare/role.py +44 -0
  567. cartography/models/cloudflare/zone.py +59 -0
  568. cartography/models/core/common.py +53 -2
  569. cartography/models/core/nodes.py +20 -4
  570. cartography/models/core/relationships.py +58 -6
  571. cartography/models/crowdstrike/__init__.py +0 -0
  572. cartography/models/crowdstrike/hosts.py +51 -0
  573. cartography/models/cve/cve.py +34 -32
  574. cartography/models/cve/cve_feed.py +6 -6
  575. cartography/models/digitalocean/__init__.py +0 -0
  576. cartography/models/digitalocean/account.py +21 -0
  577. cartography/models/digitalocean/droplet.py +58 -0
  578. cartography/models/digitalocean/project.py +48 -0
  579. cartography/models/duo/api_host.py +3 -3
  580. cartography/models/duo/endpoint.py +43 -41
  581. cartography/models/duo/group.py +14 -14
  582. cartography/models/duo/phone.py +27 -27
  583. cartography/models/duo/token.py +16 -16
  584. cartography/models/duo/user.py +50 -44
  585. cartography/models/duo/web_authn_credential.py +27 -19
  586. cartography/models/entra/__init__.py +0 -0
  587. cartography/models/entra/app_role_assignment.py +115 -0
  588. cartography/models/entra/application.py +49 -0
  589. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  590. cartography/models/entra/group.py +117 -0
  591. cartography/models/entra/ou.py +48 -0
  592. cartography/models/entra/service_principal.py +104 -0
  593. cartography/models/entra/tenant.py +39 -0
  594. cartography/models/entra/user.py +90 -0
  595. cartography/models/gcp/__init__.py +0 -0
  596. cartography/models/gcp/bigtable/__init__.py +0 -0
  597. cartography/models/gcp/bigtable/app_profile.py +94 -0
  598. cartography/models/gcp/bigtable/backup.py +91 -0
  599. cartography/models/gcp/bigtable/cluster.py +73 -0
  600. cartography/models/gcp/bigtable/instance.py +52 -0
  601. cartography/models/gcp/bigtable/table.py +69 -0
  602. cartography/models/gcp/compute/__init__.py +0 -0
  603. cartography/models/gcp/compute/subnet.py +74 -0
  604. cartography/models/gcp/compute/vpc.py +50 -0
  605. cartography/models/gcp/crm/__init__.py +0 -0
  606. cartography/models/gcp/crm/folders.py +98 -0
  607. cartography/models/gcp/crm/organizations.py +21 -0
  608. cartography/models/gcp/crm/projects.py +100 -0
  609. cartography/models/gcp/dns.py +109 -0
  610. cartography/models/gcp/gke.py +69 -0
  611. cartography/models/gcp/iam.py +73 -0
  612. cartography/models/gcp/permission_relationships.py +61 -0
  613. cartography/models/gcp/policy_bindings.py +93 -0
  614. cartography/models/gcp/storage/__init__.py +0 -0
  615. cartography/models/gcp/storage/bucket.py +119 -0
  616. cartography/models/github/commits.py +63 -0
  617. cartography/models/github/dependencies.py +73 -0
  618. cartography/models/github/manifests.py +49 -0
  619. cartography/models/github/orgs.py +27 -0
  620. cartography/models/github/teams.py +74 -22
  621. cartography/models/github/users.py +149 -0
  622. cartography/models/googleworkspace/__init__.py +0 -0
  623. cartography/models/googleworkspace/device.py +132 -0
  624. cartography/models/googleworkspace/group.py +382 -0
  625. cartography/models/googleworkspace/oauth_app.py +124 -0
  626. cartography/models/googleworkspace/tenant.py +30 -0
  627. cartography/models/googleworkspace/user.py +113 -0
  628. cartography/models/gsuite/__init__.py +0 -0
  629. cartography/models/gsuite/group.py +218 -0
  630. cartography/models/gsuite/tenant.py +29 -0
  631. cartography/models/gsuite/user.py +107 -0
  632. cartography/models/kandji/device.py +22 -17
  633. cartography/models/kandji/tenant.py +6 -4
  634. cartography/models/keycloak/__init__.py +0 -0
  635. cartography/models/keycloak/authenticationexecution.py +160 -0
  636. cartography/models/keycloak/authenticationflow.py +54 -0
  637. cartography/models/keycloak/client.py +179 -0
  638. cartography/models/keycloak/group.py +101 -0
  639. cartography/models/keycloak/identityprovider.py +89 -0
  640. cartography/models/keycloak/organization.py +116 -0
  641. cartography/models/keycloak/organizationdomain.py +73 -0
  642. cartography/models/keycloak/realm.py +173 -0
  643. cartography/models/keycloak/role.py +126 -0
  644. cartography/models/keycloak/scope.py +73 -0
  645. cartography/models/keycloak/user.py +55 -0
  646. cartography/models/kubernetes/__init__.py +0 -0
  647. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  648. cartography/models/kubernetes/clusterroles.py +52 -0
  649. cartography/models/kubernetes/clusters.py +26 -0
  650. cartography/models/kubernetes/containers.py +133 -0
  651. cartography/models/kubernetes/groups.py +107 -0
  652. cartography/models/kubernetes/namespaces.py +51 -0
  653. cartography/models/kubernetes/oidc.py +51 -0
  654. cartography/models/kubernetes/pods.py +80 -0
  655. cartography/models/kubernetes/rolebindings.py +159 -0
  656. cartography/models/kubernetes/roles.py +76 -0
  657. cartography/models/kubernetes/secrets.py +79 -0
  658. cartography/models/kubernetes/serviceaccounts.py +77 -0
  659. cartography/models/kubernetes/services.py +108 -0
  660. cartography/models/kubernetes/users.py +105 -0
  661. cartography/models/lastpass/tenant.py +3 -3
  662. cartography/models/lastpass/user.py +36 -28
  663. cartography/models/ontology/__init__.py +0 -0
  664. cartography/models/ontology/device.py +137 -0
  665. cartography/models/ontology/mapping/__init__.py +76 -0
  666. cartography/models/ontology/mapping/data/__init__.py +0 -0
  667. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  668. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  669. cartography/models/ontology/mapping/data/containers.py +88 -0
  670. cartography/models/ontology/mapping/data/databases.py +182 -0
  671. cartography/models/ontology/mapping/data/devices.py +194 -0
  672. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  673. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  674. cartography/models/ontology/mapping/data/users.py +63 -0
  675. cartography/models/ontology/mapping/specs.py +85 -0
  676. cartography/models/ontology/user.py +51 -0
  677. cartography/models/openai/__init__.py +0 -0
  678. cartography/models/openai/adminapikey.py +94 -0
  679. cartography/models/openai/apikey.py +88 -0
  680. cartography/models/openai/organization.py +17 -0
  681. cartography/models/openai/project.py +89 -0
  682. cartography/models/openai/serviceaccount.py +50 -0
  683. cartography/models/openai/user.py +53 -0
  684. cartography/models/scaleway/__init__.py +0 -0
  685. cartography/models/scaleway/iam/__init__.py +0 -0
  686. cartography/models/scaleway/iam/apikey.py +100 -0
  687. cartography/models/scaleway/iam/application.py +52 -0
  688. cartography/models/scaleway/iam/group.py +95 -0
  689. cartography/models/scaleway/iam/user.py +64 -0
  690. cartography/models/scaleway/instance/__init__.py +0 -0
  691. cartography/models/scaleway/instance/flexibleip.py +52 -0
  692. cartography/models/scaleway/instance/instance.py +120 -0
  693. cartography/models/scaleway/organization.py +19 -0
  694. cartography/models/scaleway/project.py +48 -0
  695. cartography/models/scaleway/storage/__init__.py +0 -0
  696. cartography/models/scaleway/storage/snapshot.py +78 -0
  697. cartography/models/scaleway/storage/volume.py +51 -0
  698. cartography/models/semgrep/dependencies.py +102 -0
  699. cartography/models/semgrep/deployment.py +5 -5
  700. cartography/models/semgrep/findings.py +58 -40
  701. cartography/models/semgrep/locations.py +27 -21
  702. cartography/models/sentinelone/__init__.py +1 -0
  703. cartography/models/sentinelone/account.py +40 -0
  704. cartography/models/sentinelone/agent.py +50 -0
  705. cartography/models/sentinelone/application.py +44 -0
  706. cartography/models/sentinelone/application_version.py +96 -0
  707. cartography/models/sentinelone/cve.py +73 -0
  708. cartography/models/slack/__init__.py +0 -0
  709. cartography/models/slack/channels.py +92 -0
  710. cartography/models/slack/group.py +129 -0
  711. cartography/models/slack/team.py +22 -0
  712. cartography/models/slack/user.py +62 -0
  713. cartography/models/snipeit/__init__.py +0 -0
  714. cartography/models/snipeit/asset.py +92 -0
  715. cartography/models/snipeit/tenant.py +19 -0
  716. cartography/models/snipeit/user.py +60 -0
  717. cartography/models/spacelift/__init__.py +0 -0
  718. cartography/models/spacelift/cloudtrailevent.py +120 -0
  719. cartography/models/spacelift/run.py +162 -0
  720. cartography/models/spacelift/space.py +131 -0
  721. cartography/models/spacelift/spaceliftaccount.py +31 -0
  722. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  723. cartography/models/spacelift/stack.py +96 -0
  724. cartography/models/spacelift/user.py +63 -0
  725. cartography/models/spacelift/worker.py +97 -0
  726. cartography/models/spacelift/workerpool.py +90 -0
  727. cartography/models/tailscale/__init__.py +0 -0
  728. cartography/models/tailscale/device.py +96 -0
  729. cartography/models/tailscale/group.py +86 -0
  730. cartography/models/tailscale/postureintegration.py +58 -0
  731. cartography/models/tailscale/tag.py +102 -0
  732. cartography/models/tailscale/tailnet.py +29 -0
  733. cartography/models/tailscale/user.py +57 -0
  734. cartography/models/trivy/__init__.py +0 -0
  735. cartography/models/trivy/findings.py +66 -0
  736. cartography/models/trivy/fix.py +66 -0
  737. cartography/models/trivy/package.py +71 -0
  738. cartography/rules/README.md +1 -0
  739. cartography/rules/__init__.py +0 -0
  740. cartography/rules/cli.py +261 -0
  741. cartography/rules/data/__init__.py +0 -0
  742. cartography/rules/data/rules/__init__.py +46 -0
  743. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  744. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  745. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  746. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  747. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  748. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  749. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  750. cartography/rules/data/rules/mfa_missing.py +46 -0
  751. cartography/rules/data/rules/object_storage_public.py +100 -0
  752. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  753. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  754. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  755. cartography/rules/formatters.py +108 -0
  756. cartography/rules/runners.py +216 -0
  757. cartography/rules/spec/__init__.py +0 -0
  758. cartography/rules/spec/model.py +267 -0
  759. cartography/rules/spec/result.py +38 -0
  760. cartography/stats.py +4 -4
  761. cartography/sync.py +137 -31
  762. cartography/util.py +187 -77
  763. cartography-0.123.0.dist-info/METADATA +230 -0
  764. cartography-0.123.0.dist-info/RECORD +856 -0
  765. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
  766. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  767. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
  768. cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
  769. cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
  770. cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
  771. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  772. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  773. cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
  774. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  775. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  776. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  777. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  778. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  779. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  780. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  781. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  782. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  783. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  784. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  785. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  786. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  787. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  788. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  789. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  790. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  791. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  792. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  793. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  794. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  795. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  796. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  797. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  798. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  799. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  800. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  801. cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
  802. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  803. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  804. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  805. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  806. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  807. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  808. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  809. cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
  810. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  811. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  812. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  813. cartography/intel/crxcavator/__init__.py +0 -44
  814. cartography/intel/crxcavator/crxcavator.py +0 -329
  815. cartography/intel/gcp/crm.py +0 -302
  816. cartography/intel/gsuite/api.py +0 -284
  817. cartography/models/aws/ec2/keypairs.py +0 -64
  818. cartography-0.93.0rc1.dist-info/METADATA +0 -55
  819. cartography-0.93.0rc1.dist-info/NOTICE +0 -4
  820. cartography-0.93.0rc1.dist-info/RECORD +0 -341
  821. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  822. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -6,12 +6,18 @@ from typing import List
6
6
  import boto3
7
7
  import neo4j
8
8
 
9
+ from cartography.client.core.tx import load
10
+ from cartography.graph.job import GraphJob
11
+ from cartography.models.aws.rds.cluster import RDSClusterSchema
12
+ from cartography.models.aws.rds.event_subscription import RDSEventSubscriptionSchema
13
+ from cartography.models.aws.rds.instance import RDSInstanceSchema
14
+ from cartography.models.aws.rds.snapshot import RDSSnapshotSchema
15
+ from cartography.models.aws.rds.subnet_group import DBSubnetGroupSchema
9
16
  from cartography.stats import get_stats_client
10
17
  from cartography.util import aws_handle_regions
11
18
  from cartography.util import aws_paginate
12
19
  from cartography.util import dict_value_to_str
13
20
  from cartography.util import merge_module_sync_metadata
14
- from cartography.util import run_cleanup_job
15
21
  from cartography.util import timeit
16
22
 
17
23
  logger = logging.getLogger(__name__)
@@ -20,441 +26,146 @@ stat_handler = get_stats_client(__name__)
20
26
 
21
27
  @timeit
22
28
  @aws_handle_regions
23
- def get_rds_cluster_data(boto3_session: boto3.session.Session, region: str) -> List[Any]:
29
+ def get_rds_cluster_data(
30
+ boto3_session: boto3.session.Session,
31
+ region: str,
32
+ ) -> List[Any]:
24
33
  """
25
34
  Create an RDS boto3 client and grab all the DBClusters.
26
35
  """
27
- client = boto3_session.client('rds', region_name=region)
28
- paginator = client.get_paginator('describe_db_clusters')
36
+ client = boto3_session.client("rds", region_name=region)
37
+ paginator = client.get_paginator("describe_db_clusters")
29
38
  instances: List[Any] = []
30
39
  for page in paginator.paginate():
31
- instances.extend(page['DBClusters'])
40
+ instances.extend(page["DBClusters"])
32
41
 
33
42
  return instances
34
43
 
35
44
 
36
45
  @timeit
37
46
  def load_rds_clusters(
38
- neo4j_session: neo4j.Session, data: Dict, region: str, current_aws_account_id: str,
47
+ neo4j_session: neo4j.Session,
48
+ data: List[Dict],
49
+ region: str,
50
+ current_aws_account_id: str,
39
51
  aws_update_tag: int,
40
52
  ) -> None:
41
53
  """
42
54
  Ingest the RDS clusters to neo4j and link them to necessary nodes.
43
55
  """
44
- ingest_rds_cluster = """
45
- UNWIND $Clusters as rds_cluster
46
- MERGE (cluster:RDSCluster{id: rds_cluster.DBClusterArn})
47
- ON CREATE SET cluster.firstseen = timestamp(),
48
- cluster.arn = rds_cluster.DBClusterArn
49
- SET cluster.allocated_storage = rds_cluster.AllocatedStorage,
50
- cluster.availability_zones = rds_cluster.AvailabilityZones,
51
- cluster.backup_retention_period = rds_cluster.BackupRetentionPeriod,
52
- cluster.character_set_name = rds_cluster.CharacterSetName,
53
- cluster.database_name = rds_cluster.DatabaseName,
54
- cluster.db_cluster_identifier = rds_cluster.DBClusterIdentifier,
55
- cluster.db_parameter_group = rds_cluster.DBClusterParameterGroup,
56
- cluster.status = rds_cluster.Status,
57
- cluster.earliest_restorable_time = rds_cluster.EarliestRestorableTime,
58
- cluster.endpoint = rds_cluster.Endpoint,
59
- cluster.reader_endpoint = rds_cluster.ReaderEndpoint,
60
- cluster.multi_az = rds_cluster.MultiAZ,
61
- cluster.engine = rds_cluster.Engine,
62
- cluster.engine_version = rds_cluster.EngineVersion,
63
- cluster.latest_restorable_time = rds_cluster.LatestRestorableTime,
64
- cluster.port = rds_cluster.Port,
65
- cluster.master_username = rds_cluster.MasterUsername,
66
- cluster.preferred_backup_window = rds_cluster.PreferredBackupWindow,
67
- cluster.preferred_maintenance_window = rds_cluster.PreferredMaintenanceWindow,
68
- cluster.hosted_zone_id = rds_cluster.HostedZoneId,
69
- cluster.storage_encrypted = rds_cluster.StorageEncrypted,
70
- cluster.kms_key_id = rds_cluster.KmsKeyId,
71
- cluster.db_cluster_resource_id = rds_cluster.DbClusterResourceId,
72
- cluster.clone_group_id = rds_cluster.CloneGroupId,
73
- cluster.cluster_create_time = rds_cluster.ClusterCreateTime,
74
- cluster.earliest_backtrack_time = rds_cluster.EarliestBacktrackTime,
75
- cluster.backtrack_window = rds_cluster.BacktrackWindow,
76
- cluster.backtrack_consumed_change_records = rds_cluster.BacktrackConsumedChangeRecords,
77
- cluster.capacity = rds_cluster.Capacity,
78
- cluster.engine_mode = rds_cluster.EngineMode,
79
- cluster.scaling_configuration_info_min_capacity = rds_cluster.ScalingConfigurationInfoMinCapacity,
80
- cluster.scaling_configuration_info_max_capacity = rds_cluster.ScalingConfigurationInfoMaxCapacity,
81
- cluster.scaling_configuration_info_auto_pause = rds_cluster.ScalingConfigurationInfoAutoPause,
82
- cluster.deletion_protection = rds_cluster.DeletionProtection,
83
- cluster.region = $Region,
84
- cluster.lastupdated = $aws_update_tag
85
- WITH cluster
86
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
87
- MERGE (aa)-[r:RESOURCE]->(cluster)
88
- ON CREATE SET r.firstseen = timestamp()
89
- SET r.lastupdated = $aws_update_tag
90
- """
91
- for cluster in data:
92
- # TODO: track read replicas
93
- # TODO: track associated roles
94
- # TODO: track security groups
95
- # TODO: track subnet groups
96
-
97
- cluster['EarliestRestorableTime'] = dict_value_to_str(cluster, 'EarliestRestorableTime')
98
- cluster['LatestRestorableTime'] = dict_value_to_str(cluster, 'LatestRestorableTime')
99
- cluster['ClusterCreateTime'] = dict_value_to_str(cluster, 'ClusterCreateTime')
100
- cluster['EarliestBacktrackTime'] = dict_value_to_str(cluster, 'EarliestBacktrackTime')
101
- cluster['ScalingConfigurationInfoMinCapacity'] = cluster.get('ScalingConfigurationInfo', {}).get('MinCapacity')
102
- cluster['ScalingConfigurationInfoMaxCapacity'] = cluster.get('ScalingConfigurationInfo', {}).get('MaxCapacity')
103
- cluster['ScalingConfigurationInfoAutoPause'] = cluster.get('ScalingConfigurationInfo', {}).get('AutoPause')
104
-
105
- neo4j_session.run(
106
- ingest_rds_cluster,
107
- Clusters=data,
56
+ load(
57
+ neo4j_session,
58
+ RDSClusterSchema(),
59
+ data,
60
+ lastupdated=aws_update_tag,
108
61
  Region=region,
109
- AWS_ACCOUNT_ID=current_aws_account_id,
110
- aws_update_tag=aws_update_tag,
62
+ AWS_ID=current_aws_account_id,
111
63
  )
112
64
 
113
65
 
114
66
  @timeit
115
67
  @aws_handle_regions
116
- def get_rds_instance_data(boto3_session: boto3.session.Session, region: str) -> List[Any]:
68
+ def get_rds_instance_data(
69
+ boto3_session: boto3.session.Session,
70
+ region: str,
71
+ ) -> List[Any]:
117
72
  """
118
73
  Create an RDS boto3 client and grab all the DBInstances.
119
74
  """
120
- client = boto3_session.client('rds', region_name=region)
121
- paginator = client.get_paginator('describe_db_instances')
75
+ client = boto3_session.client("rds", region_name=region)
76
+ paginator = client.get_paginator("describe_db_instances")
122
77
  instances: List[Any] = []
123
78
  for page in paginator.paginate():
124
- instances.extend(page['DBInstances'])
79
+ instances.extend(page["DBInstances"])
125
80
 
126
81
  return instances
127
82
 
128
83
 
129
84
  @timeit
130
85
  def load_rds_instances(
131
- neo4j_session: neo4j.Session, data: Dict, region: str, current_aws_account_id: str,
86
+ neo4j_session: neo4j.Session,
87
+ data: List[Dict],
88
+ region: str,
89
+ current_aws_account_id: str,
132
90
  aws_update_tag: int,
133
91
  ) -> None:
134
92
  """
135
- Ingest the RDS instances to neo4j and link them to necessary nodes.
136
- """
137
- ingest_rds_instance = """
138
- UNWIND $Instances as rds_instance
139
- MERGE (rds:RDSInstance{id: rds_instance.DBInstanceArn})
140
- ON CREATE SET rds.firstseen = timestamp(),
141
- rds.arn = rds_instance.DBInstanceArn
142
- SET rds.db_instance_identifier = rds_instance.DBInstanceIdentifier,
143
- rds.db_instance_class = rds_instance.DBInstanceClass,
144
- rds.engine = rds_instance.Engine,
145
- rds.master_username = rds_instance.MasterUsername,
146
- rds.db_name = rds_instance.DBName,
147
- rds.instance_create_time = rds_instance.InstanceCreateTime,
148
- rds.availability_zone = rds_instance.AvailabilityZone,
149
- rds.multi_az = rds_instance.MultiAZ,
150
- rds.engine_version = rds_instance.EngineVersion,
151
- rds.publicly_accessible = rds_instance.PubliclyAccessible,
152
- rds.db_cluster_identifier = rds_instance.DBClusterIdentifier,
153
- rds.storage_encrypted = rds_instance.StorageEncrypted,
154
- rds.kms_key_id = rds_instance.KmsKeyId,
155
- rds.dbi_resource_id = rds_instance.DbiResourceId,
156
- rds.ca_certificate_identifier = rds_instance.CACertificateIdentifier,
157
- rds.enhanced_monitoring_resource_arn = rds_instance.EnhancedMonitoringResourceArn,
158
- rds.monitoring_role_arn = rds_instance.MonitoringRoleArn,
159
- rds.performance_insights_enabled = rds_instance.PerformanceInsightsEnabled,
160
- rds.performance_insights_kms_key_id = rds_instance.PerformanceInsightsKMSKeyId,
161
- rds.region = rds_instance.Region,
162
- rds.deletion_protection = rds_instance.DeletionProtection,
163
- rds.preferred_backup_window = rds_instance.PreferredBackupWindow,
164
- rds.latest_restorable_time = rds_instance.LatestRestorableTime,
165
- rds.preferred_maintenance_window = rds_instance.PreferredMaintenanceWindow,
166
- rds.backup_retention_period = rds_instance.BackupRetentionPeriod,
167
- rds.endpoint_address = rds_instance.EndpointAddress,
168
- rds.endpoint_hostedzoneid = rds_instance.EndpointHostedZoneId,
169
- rds.endpoint_port = rds_instance.EndpointPort,
170
- rds.iam_database_authentication_enabled = rds_instance.IAMDatabaseAuthenticationEnabled,
171
- rds.auto_minor_version_upgrade = rds_instance.AutoMinorVersionUpgrade,
172
- rds.lastupdated = $aws_update_tag
173
- WITH rds
174
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
175
- MERGE (aa)-[r:RESOURCE]->(rds)
176
- ON CREATE SET r.firstseen = timestamp()
177
- SET r.lastupdated = $aws_update_tag
178
- """
179
- read_replicas = []
180
- clusters = []
181
- secgroups = []
182
- subnets = []
183
-
184
- for rds in data:
185
- ep = _validate_rds_endpoint(rds)
186
-
187
- # Keep track of instances that are read replicas so we can attach them to their source instances later
188
- if rds.get("ReadReplicaSourceDBInstanceIdentifier"):
189
- read_replicas.append(rds)
190
-
191
- # Keep track of instances that are cluster members so we can attach them to their source clusters later
192
- if rds.get("DBClusterIdentifier"):
193
- clusters.append(rds)
194
-
195
- if rds.get('VpcSecurityGroups'):
196
- secgroups.append(rds)
197
-
198
- if rds.get('DBSubnetGroup'):
199
- subnets.append(rds)
200
-
201
- rds['InstanceCreateTime'] = dict_value_to_str(rds, 'InstanceCreateTime')
202
- rds['LatestRestorableTime'] = dict_value_to_str(rds, 'LatestRestorableTime')
203
- rds['EndpointAddress'] = ep.get('Address')
204
- rds['EndpointHostedZoneId'] = ep.get('HostedZoneId')
205
- rds['EndpointPort'] = ep.get('Port')
206
-
207
- neo4j_session.run(
208
- ingest_rds_instance,
209
- Instances=data,
93
+ Ingest the RDS instances to Neo4j and link them to necessary nodes.
94
+ """
95
+ load(
96
+ neo4j_session,
97
+ RDSInstanceSchema(),
98
+ data,
99
+ lastupdated=aws_update_tag,
210
100
  Region=region,
211
- AWS_ACCOUNT_ID=current_aws_account_id,
212
- aws_update_tag=aws_update_tag,
101
+ AWS_ID=current_aws_account_id,
213
102
  )
214
- _attach_ec2_security_groups(neo4j_session, secgroups, aws_update_tag)
215
- _attach_ec2_subnet_groups(neo4j_session, subnets, region, current_aws_account_id, aws_update_tag)
216
- _attach_read_replicas(neo4j_session, read_replicas, aws_update_tag)
217
- _attach_clusters(neo4j_session, clusters, aws_update_tag)
218
103
 
219
104
 
220
105
  @timeit
221
106
  @aws_handle_regions
222
- def get_rds_snapshot_data(boto3_session: boto3.session.Session, region: str) -> List[Any]:
107
+ def get_rds_snapshot_data(
108
+ boto3_session: boto3.session.Session,
109
+ region: str,
110
+ ) -> List[Any]:
223
111
  """
224
112
  Create an RDS boto3 client and grab all the DBSnapshots.
225
113
  """
226
- client = boto3_session.client('rds', region_name=region)
227
- return aws_paginate(client, 'describe_db_snapshots', 'DBSnapshots')
114
+ client = boto3_session.client("rds", region_name=region)
115
+ snapshots = list(aws_paginate(client, "describe_db_snapshots", "DBSnapshots"))
116
+ return snapshots
228
117
 
229
118
 
230
119
  @timeit
231
120
  def load_rds_snapshots(
232
- neo4j_session: neo4j.Session, data: Dict, region: str, current_aws_account_id: str,
121
+ neo4j_session: neo4j.Session,
122
+ data: List[Dict],
123
+ region: str,
124
+ current_aws_account_id: str,
233
125
  aws_update_tag: int,
234
126
  ) -> None:
235
127
  """
236
128
  Ingest the RDS snapshots to neo4j and link them to necessary nodes.
237
129
  """
238
- ingest_rds_snapshot = """
239
- UNWIND $Snapshots as rds_snapshot
240
- MERGE (snapshot:RDSSnapshot{id: rds_snapshot.DBSnapshotArn})
241
- ON CREATE SET snapshot.firstseen = timestamp(),
242
- snapshot.arn = rds_snapshot.DBSnapshotArn
243
- SET snapshot.db_snapshot_identifier = rds_snapshot.DBSnapshotIdentifier,
244
- snapshot.db_instance_identifier = rds_snapshot.DBInstanceIdentifier,
245
- snapshot.snapshot_create_time = rds_snapshot.SnapshotCreateTime,
246
- snapshot.engine = rds_snapshot.Engine,
247
- snapshot.allocated_storage = rds_snapshot.AllocatedStorage,
248
- snapshot.status = rds_snapshot.Status,
249
- snapshot.port = rds_snapshot.Port,
250
- snapshot.availability_zone = rds_snapshot.AvailabilityZone,
251
- snapshot.vpc_id = rds_snapshot.VpcId,
252
- snapshot.instance_create_time = rds_snapshot.InstanceCreateTime,
253
- snapshot.master_username = rds_snapshot.MasterUsername,
254
- snapshot.engine_version = rds_snapshot.EngineVersion,
255
- snapshot.license_model = rds_snapshot.LicenseModel,
256
- snapshot.snapshot_type = rds_snapshot.SnapshotType,
257
- snapshot.iops = rds_snapshot.Iops,
258
- snapshot.option_group_name = rds_snapshot.OptionGroupName,
259
- snapshot.percent_progress = rds_snapshot.PercentProgress,
260
- snapshot.source_region = rds_snapshot.SourceRegion,
261
- snapshot.source_db_snapshot_identifier = rds_snapshot.SourceDBSnapshotIdentifier,
262
- snapshot.storage_type = rds_snapshot.StorageType,
263
- snapshot.tde_credential_arn = rds_snapshot.TdeCredentialArn,
264
- snapshot.encrypted = rds_snapshot.Encrypted,
265
- snapshot.kms_key_id = rds_snapshot.KmsKeyId,
266
- snapshot.timezone = rds_snapshot.Timezone,
267
- snapshot.iam_database_authentication_enabled = rds_snapshot.IAMDatabaseAuthenticationEnabled,
268
- snapshot.processor_features = rds_snapshot.ProcessorFeatures,
269
- snapshot.dbi_resource_id = rds_snapshot.DbiResourceId,
270
- snapshot.original_snapshot_create_time = rds_snapshot.OriginalSnapshotCreateTime,
271
- snapshot.snapshot_database_time = rds_snapshot.SnapshotDatabaseTime,
272
- snapshot.snapshot_target = rds_snapshot.SnapshotTarget,
273
- snapshot.storage_throughput = rds_snapshot.StorageThroughput,
274
- snapshot.region = $Region,
275
- snapshot.lastupdated = $aws_update_tag
276
- WITH snapshot
277
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
278
- MERGE (aa)-[r:RESOURCE]->(snapshot)
279
- ON CREATE SET r.firstseen = timestamp()
280
- SET r.lastupdated = $aws_update_tag
281
- """
282
-
283
- snapshots = transform_rds_snapshots(data)
284
-
285
- neo4j_session.run(
286
- ingest_rds_snapshot,
287
- Snapshots=snapshots,
130
+ load(
131
+ neo4j_session,
132
+ RDSSnapshotSchema(),
133
+ data,
134
+ lastupdated=aws_update_tag,
288
135
  Region=region,
289
- AWS_ACCOUNT_ID=current_aws_account_id,
290
- aws_update_tag=aws_update_tag,
136
+ AWS_ID=current_aws_account_id,
291
137
  )
292
- _attach_snapshots(neo4j_session, snapshots, aws_update_tag)
293
138
 
294
139
 
295
140
  @timeit
296
- def _attach_snapshots(neo4j_session: neo4j.Session, snapshots: List[Dict], aws_update_tag: int) -> None:
297
- """
298
- Attach snapshots to their source instance
299
- """
300
- attach_member_to_source = """
301
- UNWIND $Snapshots as snapshot
302
- MATCH (rdsInstance:RDSInstance {db_instance_identifier: snapshot.DBInstanceIdentifier}),
303
- (rdsSnapshot:RDSSnapshot {arn: snapshot.DBSnapshotArn})
304
- MERGE (rdsInstance)-[r:IS_SNAPSHOT_SOURCE]->(rdsSnapshot)
305
- ON CREATE SET r.firstseen = timestamp()
306
- SET r.lastupdated = $aws_update_tag
307
- """
308
- neo4j_session.run(
309
- attach_member_to_source,
310
- Snapshots=snapshots,
311
- aws_update_tag=aws_update_tag,
312
- )
141
+ @aws_handle_regions
142
+ def get_rds_event_subscription_data(
143
+ boto3_session: boto3.session.Session,
144
+ region: str,
145
+ ) -> List[Dict[str, Any]]:
146
+ client = boto3_session.client("rds", region_name=region)
147
+ paginator = client.get_paginator("describe_event_subscriptions")
148
+ subscriptions = []
149
+ for page in paginator.paginate():
150
+ subscriptions.extend(page["EventSubscriptionsList"])
151
+ return subscriptions
313
152
 
314
153
 
315
154
  @timeit
316
- def _attach_ec2_subnet_groups(
317
- neo4j_session: neo4j.Session, instances: List[Dict], region: str, current_aws_account_id: str,
155
+ def load_rds_event_subscriptions(
156
+ neo4j_session: neo4j.Session,
157
+ data: List[Dict],
158
+ region: str,
159
+ current_aws_account_id: str,
318
160
  aws_update_tag: int,
319
161
  ) -> None:
320
- """
321
- Attach RDS instances to their EC2 subnet groups
322
- """
323
- attach_rds_to_subnet_group = """
324
- UNWIND $SubnetGroups as rds_sng
325
- MERGE (sng:DBSubnetGroup{id: rds_sng.arn})
326
- ON CREATE SET sng.firstseen = timestamp()
327
- SET sng.name = rds_sng.DBSubnetGroupName,
328
- sng.vpc_id = rds_sng.VpcId,
329
- sng.description = rds_sng.DBSubnetGroupDescription,
330
- sng.status = rds_sng.DBSubnetGroupStatus,
331
- sng.lastupdated = $aws_update_tag
332
- WITH sng, rds_sng.instance_arn AS instance_arn
333
- MATCH(rds:RDSInstance{id: instance_arn})
334
- MERGE(rds)-[r:MEMBER_OF_DB_SUBNET_GROUP]->(sng)
335
- ON CREATE SET r.firstseen = timestamp()
336
- SET r.lastupdated = $aws_update_tag
337
- """
338
- db_sngs = []
339
- for instance in instances:
340
- db_sng = instance['DBSubnetGroup']
341
- db_sng['arn'] = _get_db_subnet_group_arn(region, current_aws_account_id, db_sng['DBSubnetGroupName'])
342
- db_sng['instance_arn'] = instance['DBInstanceArn']
343
- db_sngs.append(db_sng)
344
- neo4j_session.run(
345
- attach_rds_to_subnet_group,
346
- SubnetGroups=db_sngs,
347
- aws_update_tag=aws_update_tag,
348
- )
349
- _attach_ec2_subnets_to_subnetgroup(neo4j_session, db_sngs, region, current_aws_account_id, aws_update_tag)
350
-
351
-
352
- @timeit
353
- def _attach_ec2_subnets_to_subnetgroup(
354
- neo4j_session: neo4j.Session, db_subnet_groups: List[Dict], region: str,
355
- current_aws_account_id: str, aws_update_tag: int,
356
- ) -> None:
357
- """
358
- Attach EC2Subnets to their DB Subnet Group.
359
-
360
- From https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:
361
- `Each DB subnet group should have subnets in at least two Availability Zones in a given region. When creating a DB
362
- instance in a VPC, you must select a DB subnet group. Amazon RDS uses that DB subnet group and your preferred
363
- Availability Zone to select a subnet and an IP address within that subnet to associate with your DB instance.`
364
- """
365
- attach_subnets_to_sng = """
366
- UNWIND $Subnets as rds_sn
367
- MATCH(sng:DBSubnetGroup{id: rds_sn.sng_arn})
368
- MERGE(subnet:EC2Subnet{subnetid: rds_sn.sn_id})
369
- ON CREATE SET subnet.firstseen = timestamp()
370
- MERGE(sng)-[r:RESOURCE]->(subnet)
371
- ON CREATE SET r.firstseen = timestamp()
372
- SET r.lastupdated = $aws_update_tag,
373
- subnet.availability_zone = rds_sn.az,
374
- subnet.lastupdated = $aws_update_tag
375
- """
376
- subnets = []
377
- for subnet_group in db_subnet_groups:
378
- for subnet in subnet_group.get('Subnets', []):
379
- sn_id = subnet.get('SubnetIdentifier')
380
- sng_arn = _get_db_subnet_group_arn(region, current_aws_account_id, subnet_group['DBSubnetGroupName'])
381
- az = subnet.get('SubnetAvailabilityZone', {}).get('Name')
382
- subnets.append({
383
- 'sn_id': sn_id,
384
- 'sng_arn': sng_arn,
385
- 'az': az,
386
- })
387
- neo4j_session.run(
388
- attach_subnets_to_sng,
389
- Subnets=subnets,
390
- aws_update_tag=aws_update_tag,
391
- )
392
-
393
-
394
- @timeit
395
- def _attach_ec2_security_groups(neo4j_session: neo4j.Session, instances: List[Dict], aws_update_tag: int) -> None:
396
- """
397
- Attach an RDS instance to its EC2SecurityGroups
398
- """
399
- attach_rds_to_group = """
400
- UNWIND $Groups as rds_sg
401
- MATCH (rds:RDSInstance{id: rds_sg.arn})
402
- MERGE (sg:EC2SecurityGroup{id: rds_sg.group_id})
403
- MERGE (rds)-[m:MEMBER_OF_EC2_SECURITY_GROUP]->(sg)
404
- ON CREATE SET m.firstseen = timestamp()
405
- SET m.lastupdated = $aws_update_tag
406
- """
407
- groups = []
408
- for instance in instances:
409
- for group in instance['VpcSecurityGroups']:
410
- groups.append({
411
- 'arn': instance['DBInstanceArn'],
412
- 'group_id': group['VpcSecurityGroupId'],
413
- })
414
- neo4j_session.run(
415
- attach_rds_to_group,
416
- Groups=groups,
417
- aws_update_tag=aws_update_tag,
418
- )
419
-
420
-
421
- @timeit
422
- def _attach_read_replicas(neo4j_session: neo4j.Session, read_replicas: List[Dict], aws_update_tag: int) -> None:
423
- """
424
- Attach read replicas to their source instances
425
- """
426
- attach_replica_to_source = """
427
- UNWIND $Replicas as rds_replica
428
- MATCH (replica:RDSInstance{id: rds_replica.DBInstanceArn}),
429
- (source:RDSInstance{db_instance_identifier: rds_replica.ReadReplicaSourceDBInstanceIdentifier})
430
- MERGE (replica)-[r:IS_READ_REPLICA_OF]->(source)
431
- ON CREATE SET r.firstseen = timestamp()
432
- SET r.lastupdated = $aws_update_tag
433
- """
434
- neo4j_session.run(
435
- attach_replica_to_source,
436
- Replicas=read_replicas,
437
- aws_update_tag=aws_update_tag,
438
- )
439
-
440
-
441
- @timeit
442
- def _attach_clusters(neo4j_session: neo4j.Session, cluster_members: List[Dict], aws_update_tag: int) -> None:
443
- """
444
- Attach cluster members to their source clusters
445
- """
446
- attach_member_to_source = """
447
- UNWIND $Members as rds_cluster_member
448
- MATCH (member:RDSInstance{id: rds_cluster_member.DBInstanceArn}),
449
- (source:RDSCluster{db_cluster_identifier: rds_cluster_member.DBClusterIdentifier})
450
- MERGE (member)-[r:IS_CLUSTER_MEMBER_OF]->(source)
451
- ON CREATE SET r.firstseen = timestamp()
452
- SET r.lastupdated = $aws_update_tag
453
- """
454
- neo4j_session.run(
455
- attach_member_to_source,
456
- Members=cluster_members,
457
- aws_update_tag=aws_update_tag,
162
+ load(
163
+ neo4j_session,
164
+ RDSEventSubscriptionSchema(),
165
+ data,
166
+ lastupdated=aws_update_tag,
167
+ Region=region,
168
+ AWS_ID=current_aws_account_id,
458
169
  )
459
170
 
460
171
 
@@ -462,13 +173,20 @@ def _validate_rds_endpoint(rds: Dict) -> Dict:
462
173
  """
463
174
  Get Endpoint from RDS data structure. Log to debug if an Endpoint field does not exist.
464
175
  """
465
- ep = rds.get('Endpoint', {})
176
+ ep = rds.get("Endpoint", {})
466
177
  if not ep:
467
- logger.debug("RDS instance does not have an Endpoint field. Here is the object: %r", rds)
178
+ logger.debug(
179
+ "RDS instance does not have an Endpoint field. Here is the object: %r",
180
+ rds,
181
+ )
468
182
  return ep
469
183
 
470
184
 
471
- def _get_db_subnet_group_arn(region: str, current_aws_account_id: str, db_subnet_group_name: str) -> str:
185
+ def _get_db_subnet_group_arn(
186
+ region: str,
187
+ current_aws_account_id: str,
188
+ db_subnet_group_name: str,
189
+ ) -> str:
472
190
  """
473
191
  Return an ARN for the DB subnet group name by concatenating the account name and region.
474
192
  This is done to avoid another AWS API call since the describe_db_instances boto call does not return the DB subnet
@@ -476,116 +194,453 @@ def _get_db_subnet_group_arn(region: str, current_aws_account_id: str, db_subnet
476
194
  Form is arn:aws:rds:{region}:{account-id}:subgrp:{subnet-group-name}
477
195
  as per https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
478
196
  """
479
- return f"arn:aws:rds:{region}:{current_aws_account_id}:subgrp:{db_subnet_group_name}"
197
+ return (
198
+ f"arn:aws:rds:{region}:{current_aws_account_id}:subgrp:{db_subnet_group_name}"
199
+ )
480
200
 
481
201
 
482
- @timeit
483
- def transform_rds_snapshots(data: Dict) -> List[Dict]:
202
+ def transform_rds_clusters(data: List[Dict]) -> List[Dict]:
203
+ """
204
+ Transform RDS cluster data for Neo4j ingestion
205
+ """
206
+ clusters = []
207
+
208
+ for cluster in data:
209
+ # Copy the cluster data
210
+ transformed_cluster = cluster.copy()
211
+
212
+ # Convert datetime fields
213
+ transformed_cluster["EarliestRestorableTime"] = dict_value_to_str(
214
+ cluster, "EarliestRestorableTime"
215
+ )
216
+ transformed_cluster["LatestRestorableTime"] = dict_value_to_str(
217
+ cluster, "LatestRestorableTime"
218
+ )
219
+ transformed_cluster["ClusterCreateTime"] = dict_value_to_str(
220
+ cluster, "ClusterCreateTime"
221
+ )
222
+ transformed_cluster["EarliestBacktrackTime"] = dict_value_to_str(
223
+ cluster, "EarliestBacktrackTime"
224
+ )
225
+
226
+ # Extract scaling configuration info
227
+ scaling_config = cluster.get("ScalingConfigurationInfo", {})
228
+ transformed_cluster["ScalingConfigurationInfoMinCapacity"] = scaling_config.get(
229
+ "MinCapacity"
230
+ )
231
+ transformed_cluster["ScalingConfigurationInfoMaxCapacity"] = scaling_config.get(
232
+ "MaxCapacity"
233
+ )
234
+ transformed_cluster["ScalingConfigurationInfoAutoPause"] = scaling_config.get(
235
+ "AutoPause"
236
+ )
237
+
238
+ clusters.append(transformed_cluster)
239
+
240
+ return clusters
241
+
242
+
243
+ def transform_rds_snapshots(data: List[Dict]) -> List[Dict]:
484
244
  snapshots = []
485
245
 
486
246
  for snapshot in data:
487
247
  snapshots.append(snapshot)
488
248
 
489
- snapshot['SnapshotCreateTime'] = dict_value_to_str(snapshot, 'EarliestRestorableTime')
490
- snapshot['InstanceCreateTime'] = dict_value_to_str(snapshot, 'InstanceCreateTime')
491
- snapshot['ProcessorFeatures'] = dict_value_to_str(snapshot, 'ProcessorFeatures')
492
- snapshot['OriginalSnapshotCreateTime'] = dict_value_to_str(snapshot, 'OriginalSnapshotCreateTime')
493
- snapshot['SnapshotDatabaseTime'] = dict_value_to_str(snapshot, 'SnapshotDatabaseTime')
249
+ snapshot["SnapshotCreateTime"] = dict_value_to_str(
250
+ snapshot,
251
+ "EarliestRestorableTime",
252
+ )
253
+ snapshot["InstanceCreateTime"] = dict_value_to_str(
254
+ snapshot,
255
+ "InstanceCreateTime",
256
+ )
257
+ snapshot["ProcessorFeatures"] = dict_value_to_str(snapshot, "ProcessorFeatures")
258
+ snapshot["OriginalSnapshotCreateTime"] = dict_value_to_str(
259
+ snapshot,
260
+ "OriginalSnapshotCreateTime",
261
+ )
262
+ snapshot["SnapshotDatabaseTime"] = dict_value_to_str(
263
+ snapshot,
264
+ "SnapshotDatabaseTime",
265
+ )
494
266
 
495
267
  return snapshots
496
268
 
497
269
 
270
+ def transform_rds_instances(
271
+ data: List[Dict], region: str, current_aws_account_id: str
272
+ ) -> List[Dict]:
273
+ """
274
+ Transform RDS instance data for Neo4j ingestion
275
+ """
276
+ instances = []
277
+
278
+ for instance in data:
279
+ # Copy the instance data
280
+ transformed_instance = instance.copy()
281
+
282
+ # Extract security group IDs for the relationship
283
+ security_group_ids = []
284
+ if instance.get("VpcSecurityGroups"):
285
+ for group in instance["VpcSecurityGroups"]:
286
+ security_group_ids.append(group["VpcSecurityGroupId"])
287
+
288
+ transformed_instance["security_group_ids"] = security_group_ids
289
+
290
+ # Handle read replica source identifier for the relationship
291
+ if instance.get("ReadReplicaSourceDBInstanceIdentifier"):
292
+ transformed_instance["read_replica_source_identifier"] = instance[
293
+ "ReadReplicaSourceDBInstanceIdentifier"
294
+ ]
295
+
296
+ # Handle cluster identifier for the relationship
297
+ if instance.get("DBClusterIdentifier"):
298
+ transformed_instance["db_cluster_identifier"] = instance[
299
+ "DBClusterIdentifier"
300
+ ]
301
+
302
+ # Handle subnet group data for the relationship
303
+ if instance.get("DBSubnetGroup"):
304
+ db_subnet_group = instance["DBSubnetGroup"]
305
+ transformed_instance["db_subnet_group_arn"] = _get_db_subnet_group_arn(
306
+ region, current_aws_account_id, db_subnet_group["DBSubnetGroupName"]
307
+ )
308
+
309
+ # Handle endpoint data
310
+ ep = _validate_rds_endpoint(instance)
311
+ transformed_instance["EndpointAddress"] = ep.get("Address")
312
+ transformed_instance["EndpointHostedZoneId"] = ep.get("HostedZoneId")
313
+ transformed_instance["EndpointPort"] = ep.get("Port")
314
+
315
+ # Convert datetime fields
316
+ transformed_instance["InstanceCreateTime"] = dict_value_to_str(
317
+ instance, "InstanceCreateTime"
318
+ )
319
+ transformed_instance["LatestRestorableTime"] = dict_value_to_str(
320
+ instance, "LatestRestorableTime"
321
+ )
322
+
323
+ instances.append(transformed_instance)
324
+
325
+ return instances
326
+
327
+
328
+ def transform_rds_event_subscriptions(data: List[Dict]) -> List[Dict]:
329
+ subscriptions = []
330
+ for subscription in data:
331
+ transformed = {
332
+ "CustSubscriptionId": subscription.get("CustSubscriptionId"),
333
+ "EventSubscriptionArn": subscription.get("EventSubscriptionArn"),
334
+ "CustomerAwsId": subscription.get("CustomerAwsId"),
335
+ "SnsTopicArn": subscription.get("SnsTopicArn"),
336
+ "SourceType": subscription.get("SourceType"),
337
+ "Status": subscription.get("Status"),
338
+ "Enabled": subscription.get("Enabled"),
339
+ "SubscriptionCreationTime": dict_value_to_str(
340
+ subscription, "SubscriptionCreationTime"
341
+ ),
342
+ "event_categories": subscription.get("EventCategoriesList") or None,
343
+ "source_ids": subscription.get("SourceIdsList") or None,
344
+ "lastupdated": None, # This will be set by the loader
345
+ }
346
+ subscriptions.append(transformed)
347
+ return subscriptions
348
+
349
+
350
+ def transform_rds_subnet_groups(
351
+ data: List[Dict], region: str, current_aws_account_id: str
352
+ ) -> List[Dict]:
353
+ """
354
+ Transform RDS subnet group data for Neo4j ingestion
355
+ """
356
+ subnet_groups_dict = {}
357
+
358
+ for instance in data:
359
+ if instance.get("DBSubnetGroup"):
360
+ db_subnet_group = instance["DBSubnetGroup"]
361
+ db_subnet_group_arn = _get_db_subnet_group_arn(
362
+ region, current_aws_account_id, db_subnet_group["DBSubnetGroupName"]
363
+ )
364
+
365
+ # If this subnet group doesn't exist yet, create it
366
+ if db_subnet_group_arn not in subnet_groups_dict:
367
+ subnet_groups_dict[db_subnet_group_arn] = {
368
+ "id": db_subnet_group_arn,
369
+ "name": db_subnet_group["DBSubnetGroupName"],
370
+ "vpc_id": db_subnet_group["VpcId"],
371
+ "description": db_subnet_group["DBSubnetGroupDescription"],
372
+ "status": db_subnet_group["SubnetGroupStatus"],
373
+ "db_instance_identifier": [],
374
+ "subnet_ids": [],
375
+ }
376
+
377
+ # Add this RDS instance to the subnet group's list
378
+ if instance.get("DBInstanceIdentifier"):
379
+ subnet_groups_dict[db_subnet_group_arn][
380
+ "db_instance_identifier"
381
+ ].append(instance["DBInstanceIdentifier"])
382
+
383
+ # Add subnet IDs from the DB subnet group
384
+ for subnet in db_subnet_group.get("Subnets", []):
385
+ subnet_id = subnet.get("SubnetIdentifier")
386
+ if (
387
+ subnet_id
388
+ and subnet_id
389
+ not in subnet_groups_dict[db_subnet_group_arn]["subnet_ids"]
390
+ ):
391
+ subnet_groups_dict[db_subnet_group_arn]["subnet_ids"].append(
392
+ subnet_id
393
+ )
394
+
395
+ return list(subnet_groups_dict.values())
396
+
397
+
498
398
  @timeit
499
- def cleanup_rds_instances_and_db_subnet_groups(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
399
+ def load_rds_subnet_groups(
400
+ neo4j_session: neo4j.Session,
401
+ data: List[Dict],
402
+ region: str,
403
+ current_aws_account_id: str,
404
+ aws_update_tag: int,
405
+ ) -> None:
500
406
  """
501
- Remove RDS graph nodes and DBSubnetGroups that were created from other ingestion runs
407
+ Ingest the RDS subnet groups to Neo4j and link them to necessary nodes.
502
408
  """
503
- run_cleanup_job('aws_import_rds_instances_cleanup.json', neo4j_session, common_job_parameters)
409
+ load(
410
+ neo4j_session,
411
+ DBSubnetGroupSchema(),
412
+ data,
413
+ lastupdated=aws_update_tag,
414
+ Region=region,
415
+ AWS_ID=current_aws_account_id,
416
+ )
504
417
 
505
418
 
506
419
  @timeit
507
- def cleanup_rds_clusters(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
420
+ def cleanup_rds_instances_and_db_subnet_groups(
421
+ neo4j_session: neo4j.Session,
422
+ common_job_parameters: Dict,
423
+ ) -> None:
508
424
  """
509
- Remove RDS cluster graph nodes
425
+ Remove RDS instances and DB subnet groups that weren't updated in this sync run
510
426
  """
511
- run_cleanup_job('aws_import_rds_clusters_cleanup.json', neo4j_session, common_job_parameters)
427
+ logger.debug("Running RDS instances and DB subnet groups cleanup job")
428
+
429
+ # Clean up RDS instances
430
+ GraphJob.from_node_schema(RDSInstanceSchema(), common_job_parameters).run(
431
+ neo4j_session
432
+ )
433
+
434
+ # Clean up DB subnet groups
435
+ GraphJob.from_node_schema(DBSubnetGroupSchema(), common_job_parameters).run(
436
+ neo4j_session
437
+ )
512
438
 
513
439
 
514
440
  @timeit
515
- def cleanup_rds_snapshots(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
441
+ def cleanup_rds_clusters(
442
+ neo4j_session: neo4j.Session,
443
+ common_job_parameters: Dict,
444
+ ) -> None:
516
445
  """
517
- Remove RDS snapshots graph nodes
446
+ Remove RDS clusters that weren't updated in this sync run
518
447
  """
519
- run_cleanup_job('aws_import_rds_snapshots_cleanup.json', neo4j_session, common_job_parameters)
448
+ logger.debug("Running RDS clusters cleanup job")
449
+
450
+ GraphJob.from_node_schema(RDSClusterSchema(), common_job_parameters).run(
451
+ neo4j_session
452
+ )
453
+
454
+
455
+ @timeit
456
+ def cleanup_rds_snapshots(
457
+ neo4j_session: neo4j.Session,
458
+ common_job_parameters: Dict,
459
+ ) -> None:
460
+ """
461
+ Remove RDS snapshots that weren't updated in this sync run
462
+ """
463
+ logger.debug("Running RDS snapshots cleanup job")
464
+
465
+ GraphJob.from_node_schema(RDSSnapshotSchema(), common_job_parameters).run(
466
+ neo4j_session
467
+ )
468
+
469
+
470
+ @timeit
471
+ def cleanup_rds_event_subscriptions(
472
+ neo4j_session: neo4j.Session,
473
+ common_job_parameters: Dict,
474
+ ) -> None:
475
+ """
476
+ Remove RDS event subscriptions that weren't updated in this sync run
477
+ """
478
+ logger.debug("Running RDS event subscriptions cleanup job")
479
+ GraphJob.from_node_schema(RDSEventSubscriptionSchema(), common_job_parameters).run(
480
+ neo4j_session
481
+ )
520
482
 
521
483
 
522
484
  @timeit
523
485
  def sync_rds_clusters(
524
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
525
- update_tag: int, common_job_parameters: Dict,
486
+ neo4j_session: neo4j.Session,
487
+ boto3_session: boto3.session.Session,
488
+ regions: List[str],
489
+ current_aws_account_id: str,
490
+ update_tag: int,
491
+ common_job_parameters: Dict,
526
492
  ) -> None:
527
493
  """
528
- Grab RDS instance data from AWS, ingest to neo4j, and run the cleanup job.
494
+ Grab RDS cluster data from AWS, ingest to neo4j, and run the cleanup job.
529
495
  """
530
496
  for region in regions:
531
- logger.info("Syncing RDS for region '%s' in account '%s'.", region, current_aws_account_id)
497
+ logger.info(
498
+ "Syncing RDS clusters for region '%s' in account '%s'.",
499
+ region,
500
+ current_aws_account_id,
501
+ )
532
502
  data = get_rds_cluster_data(boto3_session, region)
533
- load_rds_clusters(neo4j_session, data, region, current_aws_account_id, update_tag) # type: ignore
503
+ transformed_data = transform_rds_clusters(data)
504
+ load_rds_clusters(
505
+ neo4j_session, transformed_data, region, current_aws_account_id, update_tag
506
+ )
534
507
  cleanup_rds_clusters(neo4j_session, common_job_parameters)
535
508
 
536
509
 
537
510
  @timeit
538
511
  def sync_rds_instances(
539
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
540
- update_tag: int, common_job_parameters: Dict,
512
+ neo4j_session: neo4j.Session,
513
+ boto3_session: boto3.session.Session,
514
+ regions: List[str],
515
+ current_aws_account_id: str,
516
+ update_tag: int,
517
+ common_job_parameters: Dict,
541
518
  ) -> None:
542
519
  """
543
520
  Grab RDS instance data from AWS, ingest to neo4j, and run the cleanup job.
544
521
  """
545
522
  for region in regions:
546
- logger.info("Syncing RDS for region '%s' in account '%s'.", region, current_aws_account_id)
523
+ logger.info(
524
+ "Syncing RDS instances for region '%s' in account '%s'.",
525
+ region,
526
+ current_aws_account_id,
527
+ )
547
528
  data = get_rds_instance_data(boto3_session, region)
548
- load_rds_instances(neo4j_session, data, region, current_aws_account_id, update_tag) # type: ignore
529
+ transformed_data = transform_rds_instances(data, region, current_aws_account_id)
530
+ load_rds_instances(
531
+ neo4j_session, transformed_data, region, current_aws_account_id, update_tag
532
+ )
533
+
534
+ # Load subnet groups from RDS instances
535
+ subnet_group_data = transform_rds_subnet_groups(
536
+ data, region, current_aws_account_id
537
+ )
538
+ load_rds_subnet_groups(
539
+ neo4j_session, subnet_group_data, region, current_aws_account_id, update_tag
540
+ )
549
541
  cleanup_rds_instances_and_db_subnet_groups(neo4j_session, common_job_parameters)
550
542
 
551
543
 
552
544
  @timeit
553
545
  def sync_rds_snapshots(
554
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
555
- update_tag: int, common_job_parameters: Dict,
546
+ neo4j_session: neo4j.Session,
547
+ boto3_session: boto3.session.Session,
548
+ regions: List[str],
549
+ current_aws_account_id: str,
550
+ update_tag: int,
551
+ common_job_parameters: Dict,
556
552
  ) -> None:
557
553
  """
558
554
  Grab RDS snapshot data from AWS, ingest to neo4j, and run the cleanup job.
559
555
  """
560
556
  for region in regions:
561
- logger.info("Syncing RDS for region '%s' in account '%s'.", region, current_aws_account_id)
557
+ logger.info(
558
+ "Syncing RDS snapshots for region '%s' in account '%s'.",
559
+ region,
560
+ current_aws_account_id,
561
+ )
562
562
  data = get_rds_snapshot_data(boto3_session, region)
563
- load_rds_snapshots(neo4j_session, data, region, current_aws_account_id, update_tag) # type: ignore
563
+ transformed_data = transform_rds_snapshots(data)
564
+ load_rds_snapshots(
565
+ neo4j_session, transformed_data, region, current_aws_account_id, update_tag
566
+ )
564
567
  cleanup_rds_snapshots(neo4j_session, common_job_parameters)
565
568
 
566
569
 
570
+ @timeit
571
+ def sync_rds_event_subscriptions(
572
+ neo4j_session: neo4j.Session,
573
+ boto3_session: boto3.session.Session,
574
+ regions: List[str],
575
+ current_aws_account_id: str,
576
+ update_tag: int,
577
+ common_job_parameters: Dict,
578
+ ) -> None:
579
+ """
580
+ Grab RDS event subscription data from AWS, ingest to neo4j, and run the cleanup job.
581
+ """
582
+ for region in regions:
583
+ logger.info(
584
+ "Syncing RDS event subscriptions for region '%s' in account '%s'.",
585
+ region,
586
+ current_aws_account_id,
587
+ )
588
+ data = get_rds_event_subscription_data(boto3_session, region)
589
+ transformed = transform_rds_event_subscriptions(data)
590
+ load_rds_event_subscriptions(
591
+ neo4j_session, transformed, region, current_aws_account_id, update_tag
592
+ )
593
+ cleanup_rds_event_subscriptions(neo4j_session, common_job_parameters)
594
+
595
+
567
596
  @timeit
568
597
  def sync(
569
- neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str], current_aws_account_id: str,
570
- update_tag: int, common_job_parameters: Dict,
598
+ neo4j_session: neo4j.Session,
599
+ boto3_session: boto3.session.Session,
600
+ regions: List[str],
601
+ current_aws_account_id: str,
602
+ update_tag: int,
603
+ common_job_parameters: Dict,
571
604
  ) -> None:
572
605
  sync_rds_clusters(
573
- neo4j_session, boto3_session, regions, current_aws_account_id, update_tag,
606
+ neo4j_session,
607
+ boto3_session,
608
+ regions,
609
+ current_aws_account_id,
610
+ update_tag,
574
611
  common_job_parameters,
575
612
  )
576
613
  sync_rds_instances(
577
- neo4j_session, boto3_session, regions, current_aws_account_id, update_tag,
614
+ neo4j_session,
615
+ boto3_session,
616
+ regions,
617
+ current_aws_account_id,
618
+ update_tag,
578
619
  common_job_parameters,
579
620
  )
580
621
  sync_rds_snapshots(
581
- neo4j_session, boto3_session, regions, current_aws_account_id, update_tag,
622
+ neo4j_session,
623
+ boto3_session,
624
+ regions,
625
+ current_aws_account_id,
626
+ update_tag,
627
+ common_job_parameters,
628
+ )
629
+
630
+ sync_rds_event_subscriptions(
631
+ neo4j_session,
632
+ boto3_session,
633
+ regions,
634
+ current_aws_account_id,
635
+ update_tag,
582
636
  common_job_parameters,
583
637
  )
638
+
584
639
  merge_module_sync_metadata(
585
640
  neo4j_session,
586
- group_type='AWSAccount',
641
+ group_type="AWSAccount",
587
642
  group_id=current_aws_account_id,
588
- synced_type='RDSCluster',
643
+ synced_type="RDSCluster",
589
644
  update_tag=update_tag,
590
645
  stat_handler=stat_handler,
591
646
  )