cartography 0.104.0rc2__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 (642) hide show
  1. cartography/_version.py +16 -3
  2. cartography/cli.py +466 -5
  3. cartography/client/aws/__init__.py +19 -0
  4. cartography/client/aws/ecr.py +51 -0
  5. cartography/client/core/tx.py +357 -8
  6. cartography/config.py +153 -0
  7. cartography/data/azure_permission_relationships.yaml +20 -0
  8. cartography/data/gcp_permission_relationships.yaml +21 -0
  9. cartography/data/indexes.cypher +0 -186
  10. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  11. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  12. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  13. cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
  14. cartography/driftdetect/cli.py +3 -2
  15. cartography/graph/cleanupbuilder.py +198 -41
  16. cartography/graph/job.py +54 -6
  17. cartography/graph/querybuilder.py +528 -27
  18. cartography/graph/statement.py +5 -1
  19. cartography/intel/airbyte/__init__.py +105 -0
  20. cartography/intel/airbyte/connections.py +120 -0
  21. cartography/intel/airbyte/destinations.py +81 -0
  22. cartography/intel/airbyte/organizations.py +59 -0
  23. cartography/intel/airbyte/sources.py +78 -0
  24. cartography/intel/airbyte/tags.py +64 -0
  25. cartography/intel/airbyte/users.py +106 -0
  26. cartography/intel/airbyte/util.py +122 -0
  27. cartography/intel/airbyte/workspaces.py +63 -0
  28. cartography/intel/aws/__init__.py +24 -9
  29. cartography/intel/aws/acm.py +124 -0
  30. cartography/intel/aws/apigateway.py +253 -22
  31. cartography/intel/aws/apigatewayv2.py +116 -0
  32. cartography/intel/aws/cloudtrail.py +17 -39
  33. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  34. cartography/intel/aws/cloudwatch.py +150 -4
  35. cartography/intel/aws/codebuild.py +132 -0
  36. cartography/intel/aws/cognito.py +201 -0
  37. cartography/intel/aws/config.py +7 -3
  38. cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
  39. cartography/intel/aws/ec2/instances.py +25 -1
  40. cartography/intel/aws/ec2/internet_gateways.py +4 -2
  41. cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
  42. cartography/intel/aws/ec2/network_interfaces.py +5 -1
  43. cartography/intel/aws/ec2/reserved_instances.py +3 -1
  44. cartography/intel/aws/ec2/security_groups.py +140 -122
  45. cartography/intel/aws/ec2/snapshots.py +47 -84
  46. cartography/intel/aws/ec2/subnets.py +37 -63
  47. cartography/intel/aws/ec2/tgw.py +11 -5
  48. cartography/intel/aws/ec2/volumes.py +1 -1
  49. cartography/intel/aws/ec2/vpc.py +140 -124
  50. cartography/intel/aws/ec2/vpc_peerings.py +262 -125
  51. cartography/intel/aws/ecr.py +269 -98
  52. cartography/intel/aws/ecr_image_layers.py +923 -0
  53. cartography/intel/aws/ecs.py +251 -380
  54. cartography/intel/aws/efs.py +179 -11
  55. cartography/intel/aws/elasticache.py +102 -79
  56. cartography/intel/aws/elasticsearch.py +13 -4
  57. cartography/intel/aws/eventbridge.py +164 -0
  58. cartography/intel/aws/glue.py +181 -0
  59. cartography/intel/aws/guardduty.py +443 -0
  60. cartography/intel/aws/iam.py +750 -493
  61. cartography/intel/aws/identitycenter.py +605 -83
  62. cartography/intel/aws/inspector.py +221 -105
  63. cartography/intel/aws/kms.py +173 -201
  64. cartography/intel/aws/lambda_function.py +272 -189
  65. cartography/intel/aws/organizations.py +10 -9
  66. cartography/intel/aws/permission_relationships.py +10 -20
  67. cartography/intel/aws/rds.py +337 -446
  68. cartography/intel/aws/redshift.py +9 -4
  69. cartography/intel/aws/resourcegroupstaggingapi.py +78 -19
  70. cartography/intel/aws/resources.py +18 -0
  71. cartography/intel/aws/route53.py +386 -332
  72. cartography/intel/aws/s3.py +322 -14
  73. cartography/intel/aws/secretsmanager.py +81 -49
  74. cartography/intel/aws/securityhub.py +3 -1
  75. cartography/intel/aws/sns.py +62 -2
  76. cartography/intel/aws/sqs.py +36 -90
  77. cartography/intel/aws/ssm.py +3 -5
  78. cartography/intel/azure/__init__.py +202 -48
  79. cartography/intel/azure/aks.py +175 -0
  80. cartography/intel/azure/app_service.py +105 -0
  81. cartography/intel/azure/compute.py +59 -112
  82. cartography/intel/azure/container_instances.py +95 -0
  83. cartography/intel/azure/cosmosdb.py +222 -361
  84. cartography/intel/azure/data_factory.py +85 -0
  85. cartography/intel/azure/data_factory_dataset.py +128 -0
  86. cartography/intel/azure/data_factory_linked_service.py +119 -0
  87. cartography/intel/azure/data_factory_pipeline.py +142 -0
  88. cartography/intel/azure/data_lake.py +124 -0
  89. cartography/intel/azure/event_grid.py +94 -0
  90. cartography/intel/azure/functions.py +124 -0
  91. cartography/intel/azure/load_balancers.py +263 -0
  92. cartography/intel/azure/logic_apps.py +101 -0
  93. cartography/intel/azure/monitor.py +105 -0
  94. cartography/intel/azure/network.py +467 -0
  95. cartography/intel/azure/permission_relationships.py +466 -0
  96. cartography/intel/azure/rbac.py +309 -0
  97. cartography/intel/azure/resource_groups.py +82 -0
  98. cartography/intel/azure/security_center.py +106 -0
  99. cartography/intel/azure/sql.py +145 -292
  100. cartography/intel/azure/storage.py +185 -262
  101. cartography/intel/azure/subscription.py +21 -43
  102. cartography/intel/azure/tenant.py +39 -30
  103. cartography/intel/azure/util/common.py +13 -0
  104. cartography/intel/azure/util/credentials.py +49 -174
  105. cartography/intel/azure/util/tag.py +41 -0
  106. cartography/intel/create_indexes.py +2 -1
  107. cartography/intel/crowdstrike/spotlight.py +5 -2
  108. cartography/intel/dns.py +5 -2
  109. cartography/intel/entra/__init__.py +100 -1
  110. cartography/intel/entra/app_role_assignments.py +284 -0
  111. cartography/intel/entra/applications.py +182 -0
  112. cartography/intel/entra/federation/__init__.py +0 -0
  113. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  114. cartography/intel/entra/groups.py +198 -0
  115. cartography/intel/entra/ou.py +48 -24
  116. cartography/intel/entra/service_principals.py +217 -0
  117. cartography/intel/entra/users.py +105 -57
  118. cartography/intel/gcp/__init__.py +334 -396
  119. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  120. cartography/intel/gcp/bigtable_backup.py +91 -0
  121. cartography/intel/gcp/bigtable_cluster.py +93 -0
  122. cartography/intel/gcp/bigtable_instance.py +86 -0
  123. cartography/intel/gcp/bigtable_table.py +87 -0
  124. cartography/intel/gcp/cai.py +292 -0
  125. cartography/intel/gcp/clients.py +112 -0
  126. cartography/intel/gcp/compute.py +128 -119
  127. cartography/intel/gcp/crm/__init__.py +0 -0
  128. cartography/intel/gcp/crm/folders.py +114 -0
  129. cartography/intel/gcp/crm/orgs.py +70 -0
  130. cartography/intel/gcp/crm/projects.py +120 -0
  131. cartography/intel/gcp/dns.py +83 -169
  132. cartography/intel/gcp/gke.py +72 -113
  133. cartography/intel/gcp/iam.py +111 -91
  134. cartography/intel/gcp/permission_relationships.py +394 -0
  135. cartography/intel/gcp/policy_bindings.py +225 -0
  136. cartography/intel/gcp/storage.py +75 -159
  137. cartography/intel/github/__init__.py +62 -25
  138. cartography/intel/github/commits.py +423 -0
  139. cartography/intel/github/repos.py +463 -85
  140. cartography/intel/github/teams.py +3 -3
  141. cartography/intel/github/users.py +5 -0
  142. cartography/intel/github/util.py +12 -0
  143. cartography/intel/googleworkspace/__init__.py +193 -0
  144. cartography/intel/googleworkspace/devices.py +254 -0
  145. cartography/intel/googleworkspace/groups.py +568 -0
  146. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  147. cartography/intel/googleworkspace/tenant.py +85 -0
  148. cartography/intel/googleworkspace/users.py +138 -0
  149. cartography/intel/gsuite/__init__.py +17 -9
  150. cartography/intel/gsuite/groups.py +291 -0
  151. cartography/intel/gsuite/users.py +142 -0
  152. cartography/intel/jamf/computers.py +7 -1
  153. cartography/intel/keycloak/__init__.py +153 -0
  154. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  155. cartography/intel/keycloak/authenticationflows.py +77 -0
  156. cartography/intel/keycloak/clients.py +187 -0
  157. cartography/intel/keycloak/groups.py +126 -0
  158. cartography/intel/keycloak/identityproviders.py +94 -0
  159. cartography/intel/keycloak/organizations.py +163 -0
  160. cartography/intel/keycloak/realms.py +61 -0
  161. cartography/intel/keycloak/roles.py +202 -0
  162. cartography/intel/keycloak/scopes.py +73 -0
  163. cartography/intel/keycloak/users.py +70 -0
  164. cartography/intel/keycloak/util.py +47 -0
  165. cartography/intel/kubernetes/__init__.py +60 -14
  166. cartography/intel/kubernetes/clusters.py +86 -0
  167. cartography/intel/kubernetes/eks.py +402 -0
  168. cartography/intel/kubernetes/namespaces.py +59 -57
  169. cartography/intel/kubernetes/pods.py +168 -75
  170. cartography/intel/kubernetes/rbac.py +597 -0
  171. cartography/intel/kubernetes/secrets.py +95 -45
  172. cartography/intel/kubernetes/services.py +131 -67
  173. cartography/intel/kubernetes/util.py +142 -14
  174. cartography/intel/oci/iam.py +23 -9
  175. cartography/intel/oci/organizations.py +3 -1
  176. cartography/intel/oci/utils.py +28 -5
  177. cartography/intel/okta/applications.py +15 -5
  178. cartography/intel/okta/awssaml.py +14 -10
  179. cartography/intel/okta/factors.py +3 -1
  180. cartography/intel/okta/groups.py +5 -2
  181. cartography/intel/okta/organization.py +3 -1
  182. cartography/intel/okta/origins.py +3 -1
  183. cartography/intel/okta/roles.py +5 -2
  184. cartography/intel/okta/users.py +10 -2
  185. cartography/intel/ontology/__init__.py +44 -0
  186. cartography/intel/ontology/devices.py +54 -0
  187. cartography/intel/ontology/users.py +54 -0
  188. cartography/intel/ontology/utils.py +176 -0
  189. cartography/intel/pagerduty/escalation_policies.py +13 -6
  190. cartography/intel/pagerduty/schedules.py +9 -4
  191. cartography/intel/pagerduty/services.py +7 -3
  192. cartography/intel/pagerduty/teams.py +5 -2
  193. cartography/intel/pagerduty/users.py +3 -1
  194. cartography/intel/pagerduty/vendors.py +3 -1
  195. cartography/intel/scaleway/__init__.py +127 -0
  196. cartography/intel/scaleway/iam/__init__.py +0 -0
  197. cartography/intel/scaleway/iam/apikeys.py +71 -0
  198. cartography/intel/scaleway/iam/applications.py +71 -0
  199. cartography/intel/scaleway/iam/groups.py +71 -0
  200. cartography/intel/scaleway/iam/users.py +71 -0
  201. cartography/intel/scaleway/instances/__init__.py +0 -0
  202. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  203. cartography/intel/scaleway/instances/instances.py +92 -0
  204. cartography/intel/scaleway/projects.py +79 -0
  205. cartography/intel/scaleway/storage/__init__.py +0 -0
  206. cartography/intel/scaleway/storage/snapshots.py +86 -0
  207. cartography/intel/scaleway/storage/volumes.py +84 -0
  208. cartography/intel/scaleway/utils.py +37 -0
  209. cartography/intel/sentinelone/__init__.py +75 -0
  210. cartography/intel/sentinelone/account.py +140 -0
  211. cartography/intel/sentinelone/agent.py +139 -0
  212. cartography/intel/sentinelone/api.py +124 -0
  213. cartography/intel/sentinelone/application.py +248 -0
  214. cartography/intel/sentinelone/cve.py +119 -0
  215. cartography/intel/sentinelone/utils.py +28 -0
  216. cartography/intel/slack/__init__.py +78 -0
  217. cartography/intel/slack/channels.py +80 -0
  218. cartography/intel/slack/groups.py +90 -0
  219. cartography/intel/slack/teams.py +65 -0
  220. cartography/intel/slack/users.py +57 -0
  221. cartography/intel/slack/utils.py +29 -0
  222. cartography/intel/spacelift/__init__.py +161 -0
  223. cartography/intel/spacelift/account.py +73 -0
  224. cartography/intel/spacelift/ec2_ownership.py +280 -0
  225. cartography/intel/spacelift/runs.py +463 -0
  226. cartography/intel/spacelift/spaces.py +112 -0
  227. cartography/intel/spacelift/stacks.py +119 -0
  228. cartography/intel/spacelift/util.py +122 -0
  229. cartography/intel/spacelift/workerpools.py +131 -0
  230. cartography/intel/spacelift/workers.py +128 -0
  231. cartography/intel/trivy/__init__.py +272 -0
  232. cartography/intel/trivy/scanner.py +386 -0
  233. cartography/models/airbyte/__init__.py +0 -0
  234. cartography/models/airbyte/connection.py +138 -0
  235. cartography/models/airbyte/destination.py +75 -0
  236. cartography/models/airbyte/organization.py +19 -0
  237. cartography/models/airbyte/source.py +75 -0
  238. cartography/models/airbyte/stream.py +74 -0
  239. cartography/models/airbyte/tag.py +69 -0
  240. cartography/models/airbyte/user.py +115 -0
  241. cartography/models/airbyte/workspace.py +46 -0
  242. cartography/models/anthropic/apikey.py +4 -0
  243. cartography/models/anthropic/user.py +4 -0
  244. cartography/models/aws/acm/__init__.py +0 -0
  245. cartography/models/aws/acm/certificate.py +75 -0
  246. cartography/models/aws/apigateway/__init__.py +0 -0
  247. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  248. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  249. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  250. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  251. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  252. cartography/models/aws/cloudtrail/management_events.py +153 -0
  253. cartography/models/aws/cloudtrail/trail.py +45 -0
  254. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  255. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  256. cartography/models/aws/codebuild/__init__.py +0 -0
  257. cartography/models/aws/codebuild/project.py +49 -0
  258. cartography/models/aws/cognito/__init__.py +0 -0
  259. cartography/models/aws/cognito/identity_pool.py +70 -0
  260. cartography/models/aws/cognito/user_pool.py +47 -0
  261. cartography/models/aws/dynamodb/tables.py +2 -0
  262. cartography/models/aws/ec2/instances.py +25 -1
  263. cartography/models/aws/ec2/networkinterfaces.py +4 -0
  264. cartography/models/aws/ec2/security_group_rules.py +109 -0
  265. cartography/models/aws/ec2/security_groups.py +90 -0
  266. cartography/models/aws/ec2/snapshots.py +58 -0
  267. cartography/models/aws/ec2/subnet_instance.py +2 -0
  268. cartography/models/aws/ec2/subnet_networkinterface.py +2 -0
  269. cartography/models/aws/ec2/subnets.py +65 -0
  270. cartography/models/aws/ec2/volumes.py +20 -0
  271. cartography/models/aws/ec2/vpc.py +46 -0
  272. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  273. cartography/models/aws/ec2/vpc_peering.py +157 -0
  274. cartography/models/aws/ecr/__init__.py +0 -0
  275. cartography/models/aws/ecr/image.py +146 -0
  276. cartography/models/aws/ecr/image_layer.py +107 -0
  277. cartography/models/aws/ecr/repository.py +72 -0
  278. cartography/models/aws/ecr/repository_image.py +95 -0
  279. cartography/models/aws/ecs/__init__.py +0 -0
  280. cartography/models/aws/ecs/clusters.py +64 -0
  281. cartography/models/aws/ecs/container_definitions.py +93 -0
  282. cartography/models/aws/ecs/container_instances.py +84 -0
  283. cartography/models/aws/ecs/containers.py +101 -0
  284. cartography/models/aws/ecs/services.py +134 -0
  285. cartography/models/aws/ecs/task_definitions.py +135 -0
  286. cartography/models/aws/ecs/tasks.py +134 -0
  287. cartography/models/aws/efs/access_point.py +77 -0
  288. cartography/models/aws/efs/file_system.py +60 -0
  289. cartography/models/aws/efs/mount_target.py +29 -2
  290. cartography/models/aws/elasticache/__init__.py +0 -0
  291. cartography/models/aws/elasticache/cluster.py +65 -0
  292. cartography/models/aws/elasticache/topic.py +67 -0
  293. cartography/models/aws/eventbridge/__init__.py +0 -0
  294. cartography/models/aws/eventbridge/rule.py +77 -0
  295. cartography/models/aws/eventbridge/target.py +71 -0
  296. cartography/models/aws/glue/__init__.py +0 -0
  297. cartography/models/aws/glue/connection.py +51 -0
  298. cartography/models/aws/glue/job.py +69 -0
  299. cartography/models/aws/guardduty/__init__.py +1 -0
  300. cartography/models/aws/guardduty/detectors.py +50 -0
  301. cartography/models/aws/guardduty/findings.py +121 -0
  302. cartography/models/aws/iam/access_key.py +103 -0
  303. cartography/models/aws/iam/account_role.py +24 -0
  304. cartography/models/aws/iam/federated_principal.py +60 -0
  305. cartography/models/aws/iam/group.py +60 -0
  306. cartography/models/aws/iam/group_membership.py +27 -0
  307. cartography/models/aws/iam/inline_policy.py +78 -0
  308. cartography/models/aws/iam/managed_policy.py +51 -0
  309. cartography/models/aws/iam/policy_statement.py +57 -0
  310. cartography/models/aws/iam/role.py +83 -0
  311. cartography/models/aws/iam/root_principal.py +52 -0
  312. cartography/models/aws/iam/service_principal.py +30 -0
  313. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  314. cartography/models/aws/iam/user.py +59 -0
  315. cartography/models/aws/identitycenter/awsidentitycenter.py +1 -0
  316. cartography/models/aws/identitycenter/awspermissionset.py +70 -0
  317. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  318. cartography/models/aws/identitycenter/awsssouser.py +49 -9
  319. cartography/models/aws/inspector/findings.py +37 -0
  320. cartography/models/aws/inspector/packages.py +1 -31
  321. cartography/models/aws/kms/__init__.py +0 -0
  322. cartography/models/aws/kms/aliases.py +86 -0
  323. cartography/models/aws/kms/grants.py +65 -0
  324. cartography/models/aws/kms/keys.py +88 -0
  325. cartography/models/aws/lambda_function/__init__.py +0 -0
  326. cartography/models/aws/lambda_function/alias.py +74 -0
  327. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  328. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  329. cartography/models/aws/lambda_function/layer.py +72 -0
  330. cartography/models/aws/rds/__init__.py +0 -0
  331. cartography/models/aws/rds/cluster.py +91 -0
  332. cartography/models/aws/rds/event_subscription.py +146 -0
  333. cartography/models/aws/rds/instance.py +156 -0
  334. cartography/models/aws/rds/snapshot.py +108 -0
  335. cartography/models/aws/rds/subnet_group.py +101 -0
  336. cartography/models/aws/route53/__init__.py +0 -0
  337. cartography/models/aws/route53/dnsrecord.py +235 -0
  338. cartography/models/aws/route53/nameserver.py +63 -0
  339. cartography/models/aws/route53/subzone.py +40 -0
  340. cartography/models/aws/route53/zone.py +47 -0
  341. cartography/models/aws/s3/notification.py +24 -0
  342. cartography/models/aws/secretsmanager/secret.py +106 -0
  343. cartography/models/aws/secretsmanager/secret_version.py +0 -2
  344. cartography/models/aws/sns/topic_subscription.py +74 -0
  345. cartography/models/aws/sqs/__init__.py +0 -0
  346. cartography/models/aws/sqs/queue.py +89 -0
  347. cartography/models/azure/__init__.py +0 -0
  348. cartography/models/azure/aks_cluster.py +54 -0
  349. cartography/models/azure/aks_nodepool.py +54 -0
  350. cartography/models/azure/app_service.py +59 -0
  351. cartography/models/azure/container_instance.py +57 -0
  352. cartography/models/azure/cosmosdb/__init__.py +0 -0
  353. cartography/models/azure/cosmosdb/account.py +77 -0
  354. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  355. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  356. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  357. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  358. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  359. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  360. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  361. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  362. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  363. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  364. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  365. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  366. cartography/models/azure/data_factory/__init__.py +0 -0
  367. cartography/models/azure/data_factory/data_factory.py +51 -0
  368. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  369. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  370. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  371. cartography/models/azure/data_lake_filesystem.py +51 -0
  372. cartography/models/azure/event_grid_topic.py +57 -0
  373. cartography/models/azure/function_app.py +59 -0
  374. cartography/models/azure/load_balancer/__init__.py +0 -0
  375. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  376. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  377. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  378. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  379. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  380. cartography/models/azure/logic_apps.py +56 -0
  381. cartography/models/azure/monitor.py +54 -0
  382. cartography/models/azure/network_interface.py +112 -0
  383. cartography/models/azure/network_security_group.py +50 -0
  384. cartography/models/azure/permission_relationships.py +60 -0
  385. cartography/models/azure/principal.py +41 -0
  386. cartography/models/azure/public_ip_address.py +50 -0
  387. cartography/models/azure/rbac.py +268 -0
  388. cartography/models/azure/resource_groups.py +52 -0
  389. cartography/models/azure/security_center.py +50 -0
  390. cartography/models/azure/sql/__init__.py +0 -0
  391. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  392. cartography/models/azure/sql/elasticpool.py +77 -0
  393. cartography/models/azure/sql/failovergroup.py +73 -0
  394. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  395. cartography/models/azure/sql/replicationlink.py +81 -0
  396. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  397. cartography/models/azure/sql/restorepoint.py +74 -0
  398. cartography/models/azure/sql/serveradadministrator.py +74 -0
  399. cartography/models/azure/sql/serverdnsalias.py +71 -0
  400. cartography/models/azure/sql/sqldatabase.py +85 -0
  401. cartography/models/azure/sql/sqlserver.py +50 -0
  402. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  403. cartography/models/azure/storage/__init__.py +0 -0
  404. cartography/models/azure/storage/account.py +59 -0
  405. cartography/models/azure/storage/blobcontainer.py +85 -0
  406. cartography/models/azure/storage/blobservice.py +71 -0
  407. cartography/models/azure/storage/fileservice.py +71 -0
  408. cartography/models/azure/storage/fileshare.py +82 -0
  409. cartography/models/azure/storage/queue.py +71 -0
  410. cartography/models/azure/storage/queueservice.py +73 -0
  411. cartography/models/azure/storage/table.py +72 -0
  412. cartography/models/azure/storage/tableservice.py +73 -0
  413. cartography/models/azure/subnet.py +101 -0
  414. cartography/models/azure/subscription.py +47 -0
  415. cartography/models/azure/tags/__init__.py +0 -0
  416. cartography/models/azure/tags/storage_tag.py +40 -0
  417. cartography/models/azure/tags/tag.py +37 -0
  418. cartography/models/azure/tenant.py +17 -0
  419. cartography/models/azure/virtual_network.py +49 -0
  420. cartography/models/azure/vm/__init__.py +0 -0
  421. cartography/models/azure/vm/datadisk.py +80 -0
  422. cartography/models/azure/vm/disk.py +55 -0
  423. cartography/models/azure/vm/snapshot.py +56 -0
  424. cartography/models/azure/vm/virtualmachine.py +59 -0
  425. cartography/models/bigfix/bigfix_computer.py +1 -1
  426. cartography/models/cloudflare/member.py +4 -0
  427. cartography/models/core/common.py +1 -0
  428. cartography/models/core/nodes.py +15 -2
  429. cartography/models/core/relationships.py +44 -0
  430. cartography/models/crowdstrike/hosts.py +1 -1
  431. cartography/models/digitalocean/droplet.py +2 -0
  432. cartography/models/duo/endpoint.py +1 -1
  433. cartography/models/duo/phone.py +2 -2
  434. cartography/models/duo/user.py +4 -0
  435. cartography/models/entra/app_role_assignment.py +115 -0
  436. cartography/models/entra/application.py +49 -0
  437. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  438. cartography/models/entra/group.py +117 -0
  439. cartography/models/entra/service_principal.py +104 -0
  440. cartography/models/entra/user.py +42 -51
  441. cartography/models/gcp/__init__.py +0 -0
  442. cartography/models/gcp/bigtable/__init__.py +0 -0
  443. cartography/models/gcp/bigtable/app_profile.py +94 -0
  444. cartography/models/gcp/bigtable/backup.py +91 -0
  445. cartography/models/gcp/bigtable/cluster.py +73 -0
  446. cartography/models/gcp/bigtable/instance.py +52 -0
  447. cartography/models/gcp/bigtable/table.py +69 -0
  448. cartography/models/gcp/compute/__init__.py +0 -0
  449. cartography/models/gcp/compute/subnet.py +74 -0
  450. cartography/models/gcp/compute/vpc.py +50 -0
  451. cartography/models/gcp/crm/__init__.py +0 -0
  452. cartography/models/gcp/crm/folders.py +98 -0
  453. cartography/models/gcp/crm/organizations.py +21 -0
  454. cartography/models/gcp/crm/projects.py +100 -0
  455. cartography/models/gcp/dns.py +109 -0
  456. cartography/models/gcp/gke.py +69 -0
  457. cartography/models/gcp/iam.py +3 -0
  458. cartography/models/gcp/permission_relationships.py +61 -0
  459. cartography/models/gcp/policy_bindings.py +93 -0
  460. cartography/models/gcp/storage/__init__.py +0 -0
  461. cartography/models/gcp/storage/bucket.py +119 -0
  462. cartography/models/github/commits.py +63 -0
  463. cartography/models/github/dependencies.py +73 -0
  464. cartography/models/github/manifests.py +49 -0
  465. cartography/models/github/users.py +10 -0
  466. cartography/models/googleworkspace/__init__.py +0 -0
  467. cartography/models/googleworkspace/device.py +132 -0
  468. cartography/models/googleworkspace/group.py +382 -0
  469. cartography/models/googleworkspace/oauth_app.py +124 -0
  470. cartography/models/googleworkspace/tenant.py +30 -0
  471. cartography/models/googleworkspace/user.py +113 -0
  472. cartography/models/gsuite/__init__.py +0 -0
  473. cartography/models/gsuite/group.py +218 -0
  474. cartography/models/gsuite/tenant.py +29 -0
  475. cartography/models/gsuite/user.py +107 -0
  476. cartography/models/kandji/device.py +1 -2
  477. cartography/models/keycloak/__init__.py +0 -0
  478. cartography/models/keycloak/authenticationexecution.py +160 -0
  479. cartography/models/keycloak/authenticationflow.py +54 -0
  480. cartography/models/keycloak/client.py +179 -0
  481. cartography/models/keycloak/group.py +101 -0
  482. cartography/models/keycloak/identityprovider.py +89 -0
  483. cartography/models/keycloak/organization.py +116 -0
  484. cartography/models/keycloak/organizationdomain.py +73 -0
  485. cartography/models/keycloak/realm.py +173 -0
  486. cartography/models/keycloak/role.py +126 -0
  487. cartography/models/keycloak/scope.py +73 -0
  488. cartography/models/keycloak/user.py +55 -0
  489. cartography/models/kubernetes/__init__.py +0 -0
  490. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  491. cartography/models/kubernetes/clusterroles.py +52 -0
  492. cartography/models/kubernetes/clusters.py +26 -0
  493. cartography/models/kubernetes/containers.py +133 -0
  494. cartography/models/kubernetes/groups.py +107 -0
  495. cartography/models/kubernetes/namespaces.py +51 -0
  496. cartography/models/kubernetes/oidc.py +51 -0
  497. cartography/models/kubernetes/pods.py +80 -0
  498. cartography/models/kubernetes/rolebindings.py +159 -0
  499. cartography/models/kubernetes/roles.py +76 -0
  500. cartography/models/kubernetes/secrets.py +79 -0
  501. cartography/models/kubernetes/serviceaccounts.py +77 -0
  502. cartography/models/kubernetes/services.py +108 -0
  503. cartography/models/kubernetes/users.py +105 -0
  504. cartography/models/lastpass/user.py +4 -0
  505. cartography/models/ontology/__init__.py +0 -0
  506. cartography/models/ontology/device.py +137 -0
  507. cartography/models/ontology/mapping/__init__.py +76 -0
  508. cartography/models/ontology/mapping/data/__init__.py +0 -0
  509. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  510. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  511. cartography/models/ontology/mapping/data/containers.py +88 -0
  512. cartography/models/ontology/mapping/data/databases.py +182 -0
  513. cartography/models/ontology/mapping/data/devices.py +194 -0
  514. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  515. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  516. cartography/models/ontology/mapping/data/users.py +63 -0
  517. cartography/models/ontology/mapping/specs.py +85 -0
  518. cartography/models/ontology/user.py +51 -0
  519. cartography/models/openai/adminapikey.py +4 -0
  520. cartography/models/openai/apikey.py +4 -0
  521. cartography/models/openai/user.py +4 -0
  522. cartography/models/scaleway/__init__.py +0 -0
  523. cartography/models/scaleway/iam/__init__.py +0 -0
  524. cartography/models/scaleway/iam/apikey.py +100 -0
  525. cartography/models/scaleway/iam/application.py +52 -0
  526. cartography/models/scaleway/iam/group.py +95 -0
  527. cartography/models/scaleway/iam/user.py +64 -0
  528. cartography/models/scaleway/instance/__init__.py +0 -0
  529. cartography/models/scaleway/instance/flexibleip.py +52 -0
  530. cartography/models/scaleway/instance/instance.py +120 -0
  531. cartography/models/scaleway/organization.py +19 -0
  532. cartography/models/scaleway/project.py +48 -0
  533. cartography/models/scaleway/storage/__init__.py +0 -0
  534. cartography/models/scaleway/storage/snapshot.py +78 -0
  535. cartography/models/scaleway/storage/volume.py +51 -0
  536. cartography/models/sentinelone/__init__.py +1 -0
  537. cartography/models/sentinelone/account.py +40 -0
  538. cartography/models/sentinelone/agent.py +50 -0
  539. cartography/models/sentinelone/application.py +44 -0
  540. cartography/models/sentinelone/application_version.py +96 -0
  541. cartography/models/sentinelone/cve.py +73 -0
  542. cartography/models/slack/__init__.py +0 -0
  543. cartography/models/slack/channels.py +92 -0
  544. cartography/models/slack/group.py +129 -0
  545. cartography/models/slack/team.py +22 -0
  546. cartography/models/slack/user.py +62 -0
  547. cartography/models/snipeit/asset.py +2 -0
  548. cartography/models/snipeit/user.py +4 -0
  549. cartography/models/spacelift/__init__.py +0 -0
  550. cartography/models/spacelift/cloudtrailevent.py +120 -0
  551. cartography/models/spacelift/run.py +162 -0
  552. cartography/models/spacelift/space.py +131 -0
  553. cartography/models/spacelift/spaceliftaccount.py +31 -0
  554. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  555. cartography/models/spacelift/stack.py +96 -0
  556. cartography/models/spacelift/user.py +63 -0
  557. cartography/models/spacelift/worker.py +97 -0
  558. cartography/models/spacelift/workerpool.py +90 -0
  559. cartography/models/tailscale/device.py +2 -1
  560. cartography/models/tailscale/user.py +6 -1
  561. cartography/models/trivy/__init__.py +0 -0
  562. cartography/models/trivy/findings.py +66 -0
  563. cartography/models/trivy/fix.py +66 -0
  564. cartography/models/trivy/package.py +71 -0
  565. cartography/rules/README.md +1 -0
  566. cartography/rules/__init__.py +0 -0
  567. cartography/rules/cli.py +261 -0
  568. cartography/rules/data/__init__.py +0 -0
  569. cartography/rules/data/rules/__init__.py +46 -0
  570. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  571. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  572. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  573. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  574. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  575. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  576. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  577. cartography/rules/data/rules/mfa_missing.py +46 -0
  578. cartography/rules/data/rules/object_storage_public.py +100 -0
  579. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  580. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  581. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  582. cartography/rules/formatters.py +108 -0
  583. cartography/rules/runners.py +216 -0
  584. cartography/rules/spec/__init__.py +0 -0
  585. cartography/rules/spec/model.py +267 -0
  586. cartography/rules/spec/result.py +38 -0
  587. cartography/sync.py +25 -5
  588. cartography/util.py +101 -31
  589. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/METADATA +61 -22
  590. cartography-0.123.0.dist-info/RECORD +856 -0
  591. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  592. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  593. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  594. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  595. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  596. cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
  597. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  598. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  599. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  600. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  601. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  602. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  603. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  604. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  605. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  606. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  607. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  608. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  609. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  610. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  611. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  612. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  613. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  614. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  615. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  616. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  617. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  618. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  619. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  620. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  621. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  622. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  623. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  624. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  625. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  626. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  627. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  628. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  629. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  630. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  631. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  632. cartography/intel/gcp/crm.py +0 -355
  633. cartography/intel/gsuite/api.py +0 -342
  634. cartography-0.104.0rc2.dist-info/RECORD +0 -455
  635. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  636. /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
  637. /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
  638. /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
  639. /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
  640. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/WHEEL +0 -0
  641. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/licenses/LICENSE +0 -0
  642. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ import neo4j
7
7
 
8
8
  from cartography.client.core.tx import load
9
9
  from cartography.graph.job import GraphJob
10
+ from cartography.models.aws.secretsmanager.secret import SecretsManagerSecretSchema
10
11
  from cartography.models.aws.secretsmanager.secret_version import (
11
12
  SecretsManagerSecretVersionSchema,
12
13
  )
@@ -14,7 +15,6 @@ from cartography.stats import get_stats_client
14
15
  from cartography.util import aws_handle_regions
15
16
  from cartography.util import dict_date_to_epoch
16
17
  from cartography.util import merge_module_sync_metadata
17
- from cartography.util import run_cleanup_job
18
18
  from cartography.util import timeit
19
19
 
20
20
  logger = logging.getLogger(__name__)
@@ -32,6 +32,37 @@ def get_secret_list(boto3_session: boto3.session.Session, region: str) -> List[D
32
32
  return secrets
33
33
 
34
34
 
35
+ def transform_secrets(
36
+ secrets: List[Dict],
37
+ ) -> List[Dict]:
38
+ """
39
+ Transform AWS Secrets Manager Secrets to match the data model.
40
+ """
41
+ transformed_data = []
42
+ for secret in secrets:
43
+ # Start with a copy of the original secret data
44
+ transformed = dict(secret)
45
+
46
+ # Convert date fields to epoch timestamps
47
+ transformed["CreatedDate"] = dict_date_to_epoch(secret, "CreatedDate")
48
+ transformed["LastRotatedDate"] = dict_date_to_epoch(secret, "LastRotatedDate")
49
+ transformed["LastChangedDate"] = dict_date_to_epoch(secret, "LastChangedDate")
50
+ transformed["LastAccessedDate"] = dict_date_to_epoch(secret, "LastAccessedDate")
51
+ transformed["DeletedDate"] = dict_date_to_epoch(secret, "DeletedDate")
52
+
53
+ # Flatten nested RotationRules.AutomaticallyAfterDays property
54
+ if "RotationRules" in secret and secret["RotationRules"]:
55
+ rotation_rules = secret["RotationRules"]
56
+ if "AutomaticallyAfterDays" in rotation_rules:
57
+ transformed["RotationRulesAutomaticallyAfterDays"] = rotation_rules[
58
+ "AutomaticallyAfterDays"
59
+ ]
60
+
61
+ transformed_data.append(transformed)
62
+
63
+ return transformed_data
64
+
65
+
35
66
  @timeit
36
67
  def load_secrets(
37
68
  neo4j_session: neo4j.Session,
@@ -40,48 +71,33 @@ def load_secrets(
40
71
  current_aws_account_id: str,
41
72
  aws_update_tag: int,
42
73
  ) -> None:
43
- ingest_secrets = """
44
- UNWIND $Secrets as secret
45
- MERGE (s:SecretsManagerSecret{id: secret.ARN})
46
- ON CREATE SET s.firstseen = timestamp()
47
- SET s.name = secret.Name, s.arn = secret.ARN, s.description = secret.Description,
48
- s.kms_key_id = secret.KmsKeyId, s.rotation_enabled = secret.RotationEnabled,
49
- s.rotation_lambda_arn = secret.RotationLambdaARN,
50
- s.rotation_rules_automatically_after_days = secret.RotationRules.AutomaticallyAfterDays,
51
- s.last_rotated_date = secret.LastRotatedDate, s.last_changed_date = secret.LastChangedDate,
52
- s.last_accessed_date = secret.LastAccessedDate, s.deleted_date = secret.DeletedDate,
53
- s.owning_service = secret.OwningService, s.created_date = secret.CreatedDate,
54
- s.primary_region = secret.PrimaryRegion, s.region = $Region,
55
- s.lastupdated = $aws_update_tag
56
- WITH s
57
- MATCH (owner:AWSAccount{id: $AWS_ACCOUNT_ID})
58
- MERGE (owner)-[r:RESOURCE]->(s)
59
- ON CREATE SET r.firstseen = timestamp()
60
- SET r.lastupdated = $aws_update_tag
61
- """
62
- for secret in data:
63
- secret["LastRotatedDate"] = dict_date_to_epoch(secret, "LastRotatedDate")
64
- secret["LastChangedDate"] = dict_date_to_epoch(secret, "LastChangedDate")
65
- secret["LastAccessedDate"] = dict_date_to_epoch(secret, "LastAccessedDate")
66
- secret["DeletedDate"] = dict_date_to_epoch(secret, "DeletedDate")
67
- secret["CreatedDate"] = dict_date_to_epoch(secret, "CreatedDate")
68
-
69
- neo4j_session.run(
70
- ingest_secrets,
71
- Secrets=data,
74
+ """
75
+ Load transformed secrets into Neo4j using the data model.
76
+ Expects data to already be transformed by transform_secrets().
77
+ """
78
+ logger.info(f"Loading {len(data)} Secrets for region {region} into graph.")
79
+
80
+ # Load using the schema-based approach
81
+ load(
82
+ neo4j_session,
83
+ SecretsManagerSecretSchema(),
84
+ data,
85
+ lastupdated=aws_update_tag,
72
86
  Region=region,
73
- AWS_ACCOUNT_ID=current_aws_account_id,
74
- aws_update_tag=aws_update_tag,
87
+ AWS_ID=current_aws_account_id,
75
88
  )
76
89
 
77
90
 
78
91
  @timeit
79
92
  def cleanup_secrets(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
80
- run_cleanup_job(
81
- "aws_import_secrets_cleanup.json",
82
- neo4j_session,
83
- common_job_parameters,
93
+ """
94
+ Run Secrets cleanup job using the data model.
95
+ """
96
+ logger.debug("Running Secrets cleanup job.")
97
+ cleanup_job = GraphJob.from_node_schema(
98
+ SecretsManagerSecretSchema(), common_job_parameters
84
99
  )
100
+ cleanup_job.run(neo4j_session)
85
101
 
86
102
 
87
103
  @timeit
@@ -91,24 +107,36 @@ def get_secret_versions(
91
107
  ) -> List[Dict]:
92
108
  """
93
109
  Get all versions of a secret from AWS Secrets Manager.
110
+
111
+ Note: list_secret_version_ids is not paginatable through boto3's paginator,
112
+ so we implement manual pagination.
94
113
  """
95
114
  client = boto3_session.client("secretsmanager", region_name=region)
96
- paginator = client.get_paginator("list_secret_version_ids")
115
+ next_token = None
97
116
  versions = []
98
117
 
99
- for page in paginator.paginate(SecretId=secret_arn, IncludeDeprecated=True):
100
- for version in page["Versions"]:
118
+ while True:
119
+ params = {"SecretId": secret_arn, "IncludeDeprecated": True}
120
+ if next_token:
121
+ params["NextToken"] = next_token
122
+
123
+ response = client.list_secret_version_ids(**params)
124
+
125
+ for version in response.get("Versions", []):
101
126
  version["SecretId"] = secret_arn
102
127
  version["ARN"] = f"{secret_arn}:version:{version['VersionId']}"
103
- versions.extend(page["Versions"])
128
+
129
+ versions.extend(response.get("Versions", []))
130
+
131
+ next_token = response.get("NextToken")
132
+ if not next_token:
133
+ break
104
134
 
105
135
  return versions
106
136
 
107
137
 
108
138
  def transform_secret_versions(
109
139
  versions: List[Dict],
110
- region: str,
111
- aws_account_id: str,
112
140
  ) -> List[Dict]:
113
141
  """
114
142
  Transform AWS Secrets Manager Secret Versions to match the data model.
@@ -119,7 +147,7 @@ def transform_secret_versions(
119
147
  "ARN": version["ARN"],
120
148
  "SecretId": version["SecretId"],
121
149
  "VersionId": version["VersionId"],
122
- "VersionStages": version["VersionStages"],
150
+ "VersionStages": version.get("VersionStages"),
123
151
  "CreatedDate": dict_date_to_epoch(version, "CreatedDate"),
124
152
  }
125
153
 
@@ -189,7 +217,15 @@ def sync(
189
217
  )
190
218
  secrets = get_secret_list(boto3_session, region)
191
219
 
192
- load_secrets(neo4j_session, secrets, region, current_aws_account_id, update_tag)
220
+ transformed_secrets = transform_secrets(secrets)
221
+
222
+ load_secrets(
223
+ neo4j_session,
224
+ transformed_secrets,
225
+ region,
226
+ current_aws_account_id,
227
+ update_tag,
228
+ )
193
229
 
194
230
  all_versions = []
195
231
  for secret in secrets:
@@ -202,11 +238,7 @@ def sync(
202
238
  )
203
239
  all_versions.extend(versions)
204
240
 
205
- transformed_data = transform_secret_versions(
206
- all_versions,
207
- region,
208
- current_aws_account_id,
209
- )
241
+ transformed_data = transform_secret_versions(all_versions)
210
242
 
211
243
  load_secret_versions(
212
244
  neo4j_session,
@@ -6,6 +6,7 @@ import boto3
6
6
  import neo4j
7
7
  from dateutil import parser
8
8
 
9
+ from cartography.client.core.tx import run_write_query
9
10
  from cartography.util import run_cleanup_job
10
11
  from cartography.util import timeit
11
12
 
@@ -50,7 +51,8 @@ def load_hub(
50
51
  ON CREATE SET r.firstseen = timestamp()
51
52
  SET r.lastupdated = $aws_update_tag
52
53
  """
53
- neo4j_session.run(
54
+ run_write_query(
55
+ neo4j_session,
54
56
  ingest_hub,
55
57
  Hub=data,
56
58
  AWS_ACCOUNT_ID=current_aws_account_id,
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ from typing import Any
2
3
  from typing import Dict
3
4
  from typing import List
4
5
  from typing import Optional
@@ -9,6 +10,7 @@ import neo4j
9
10
  from cartography.client.core.tx import load
10
11
  from cartography.graph.job import GraphJob
11
12
  from cartography.models.aws.sns.topic import SNSTopicSchema
13
+ from cartography.models.aws.sns.topic_subscription import SNSTopicSubscriptionSchema
12
14
  from cartography.stats import get_stats_client
13
15
  from cartography.util import aws_handle_regions
14
16
  from cartography.util import merge_module_sync_metadata
@@ -108,6 +110,48 @@ def load_sns_topics(
108
110
  )
109
111
 
110
112
 
113
+ @timeit
114
+ @aws_handle_regions
115
+ def get_subscriptions(
116
+ boto3_session: boto3.session.Session, region: str
117
+ ) -> List[Dict[str, Any]]:
118
+ """
119
+ Get all SNS Topics Subscriptions for a region.
120
+ """
121
+ client = boto3_session.client("sns", region_name=region)
122
+ paginator = client.get_paginator("list_subscriptions")
123
+ subscriptions = []
124
+ for page in paginator.paginate():
125
+ subscriptions.extend(page.get("Subscriptions", []))
126
+
127
+ return subscriptions
128
+
129
+
130
+ @timeit
131
+ def load_sns_topic_subscription(
132
+ neo4j_session: neo4j.Session,
133
+ data: List[Dict[str, Any]],
134
+ region: str,
135
+ aws_account_id: str,
136
+ update_tag: int,
137
+ ) -> None:
138
+ """
139
+ Load SNS Topic Subscription information into the graph
140
+ """
141
+ logger.info(
142
+ f"Loading {len(data)} SNS topic subscription for region {region} into graph."
143
+ )
144
+
145
+ load(
146
+ neo4j_session,
147
+ SNSTopicSubscriptionSchema(),
148
+ data,
149
+ lastupdated=update_tag,
150
+ Region=region,
151
+ AWS_ID=aws_account_id,
152
+ )
153
+
154
+
111
155
  @timeit
112
156
  def cleanup_sns(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
113
157
  """
@@ -117,6 +161,11 @@ def cleanup_sns(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> No
117
161
  cleanup_job = GraphJob.from_node_schema(SNSTopicSchema(), common_job_parameters)
118
162
  cleanup_job.run(neo4j_session)
119
163
 
164
+ cleanup_job = GraphJob.from_node_schema(
165
+ SNSTopicSubscriptionSchema(), common_job_parameters
166
+ )
167
+ cleanup_job.run(neo4j_session)
168
+
120
169
 
121
170
  @timeit
122
171
  def sync(
@@ -128,7 +177,7 @@ def sync(
128
177
  common_job_parameters: Dict,
129
178
  ) -> None:
130
179
  """
131
- Sync SNS Topics for all regions
180
+ Sync SNS Topics and Subscriptions for all regions
132
181
  """
133
182
  for region in regions:
134
183
  logger.info(
@@ -153,9 +202,20 @@ def sync(
153
202
  update_tag,
154
203
  )
155
204
 
205
+ # Get and load subscriptions
206
+ subscriptions = get_subscriptions(boto3_session, region)
207
+
208
+ load_sns_topic_subscription(
209
+ neo4j_session,
210
+ subscriptions,
211
+ region,
212
+ current_aws_account_id,
213
+ update_tag,
214
+ )
215
+
216
+ # Cleanup and metadata update (outside region loop)
156
217
  cleanup_sns(neo4j_session, common_job_parameters)
157
218
 
158
- # Record that we've synced this module
159
219
  merge_module_sync_metadata(
160
220
  neo4j_session,
161
221
  group_type="AWSAccount",
@@ -9,8 +9,10 @@ import boto3
9
9
  import neo4j
10
10
  from botocore.exceptions import ClientError
11
11
 
12
+ from cartography.client.core.tx import load
13
+ from cartography.graph.job import GraphJob
14
+ from cartography.models.aws.sqs.queue import SQSQueueSchema
12
15
  from cartography.util import aws_handle_regions
13
- from cartography.util import run_cleanup_job
14
16
  from cartography.util import timeit
15
17
 
16
18
  logger = logging.getLogger(__name__)
@@ -33,9 +35,7 @@ def get_sqs_queue_attributes(
33
35
  boto3_session: boto3.session.Session,
34
36
  queue_urls: List[str],
35
37
  ) -> List[Tuple[str, Any]]:
36
- """
37
- Iterates over all SQS queues. Returns a dict with url as key, and attributes as value.
38
- """
38
+ """Iterates over all SQS queues and returns a list of (url, attributes)."""
39
39
  client = boto3_session.client("sqs")
40
40
 
41
41
  queue_attributes = []
@@ -58,108 +58,53 @@ def get_sqs_queue_attributes(
58
58
  return queue_attributes
59
59
 
60
60
 
61
- @timeit
62
- def load_sqs_queues(
63
- neo4j_session: neo4j.Session,
64
- data: List[Tuple[str, Any]],
65
- region: str,
66
- current_aws_account_id: str,
67
- aws_update_tag: int,
68
- ) -> None:
69
- ingest_queues = """
70
- UNWIND $Queues as sqs_queue
71
- MERGE (queue:SQSQueue{id: sqs_queue.QueueArn})
72
- ON CREATE SET queue.firstseen = timestamp(), queue.url = sqs_queue.url
73
- SET queue.name = sqs_queue.name, queue.region = $Region, queue.arn = sqs_queue.QueueArn,
74
- queue.created_timestamp = sqs_queue.CreatedTimestamp, queue.delay_seconds = sqs_queue.DelaySeconds,
75
- queue.last_modified_timestamp = sqs_queue.LastModifiedTimestamp,
76
- queue.maximum_message_size = sqs_queue.MaximumMessageSize,
77
- queue.message_retention_period = sqs_queue.MessageRetentionPeriod,
78
- queue.policy = sqs_queue.Policy, queue.arn = sqs_queue.QueueArn,
79
- queue.receive_message_wait_time_seconds = sqs_queue.ReceiveMessageWaitTimeSeconds,
80
- queue.redrive_policy_dead_letter_target_arn = sqs_queue.RedrivePolicy.deadLetterTargetArn,
81
- queue.redrive_policy_max_receive_count = sqs_queue.RedrivePolicy.maxReceiveCount,
82
- queue.visibility_timeout = sqs_queue.VisibilityTimeout,
83
- queue.kms_master_key_id = sqs_queue.KmsMasterKeyId,
84
- queue.kms_data_key_reuse_period_seconds = sqs_queue.KmsDataKeyReusePeriodSeconds,
85
- queue.fifo_queue = sqs_queue.FifoQueue,
86
- queue.content_based_deduplication = sqs_queue.ContentBasedDeduplication,
87
- queue.deduplication_scope = sqs_queue.DeduplicationScope,
88
- queue.fifo_throughput_limit = sqs_queue.FifoThroughputLimit,
89
- queue.lastupdated = $aws_update_tag
90
- WITH queue
91
- MATCH (owner:AWSAccount{id: $AWS_ACCOUNT_ID})
92
- MERGE (owner)-[r:RESOURCE]->(queue)
93
- ON CREATE SET r.firstseen = timestamp()
94
- SET r.lastupdated = $aws_update_tag
95
- """
96
- dead_letter_queues: List[Dict] = []
97
- queues: List[Dict] = []
98
- for url, queue in data:
61
+ def transform_sqs_queues(data: List[Tuple[str, Any]]) -> List[Dict[str, Any]]:
62
+ transformed: List[Dict[str, Any]] = []
63
+ for url, attrs in data:
64
+ queue = dict(attrs)
99
65
  queue["url"] = url
100
- queue["name"] = queue["QueueArn"].split(":")[-1]
101
- queue["CreatedTimestamp"] = int(queue["CreatedTimestamp"])
102
- queue["LastModifiedTimestamp"] = int(queue["LastModifiedTimestamp"])
103
- redrive_policy = queue.get("RedrivePolicy")
66
+ queue["name"] = attrs["QueueArn"].split(":")[-1]
67
+ queue["CreatedTimestamp"] = int(attrs.get("CreatedTimestamp", 0))
68
+ queue["LastModifiedTimestamp"] = int(attrs.get("LastModifiedTimestamp", 0))
69
+ redrive_policy = attrs.get("RedrivePolicy")
104
70
  if redrive_policy:
105
71
  try:
106
72
  rp = json.loads(redrive_policy)
107
73
  except TypeError:
108
74
  rp = {}
109
- queue["RedrivePolicy"] = rp
110
- dead_letter_arn = rp.get("deadLetterTargetArn")
111
- if dead_letter_arn:
112
- dead_letter_queues.append(
113
- {
114
- "arn": queue["QueueArn"],
115
- "dead_letter_arn": dead_letter_arn,
116
- },
117
- )
118
- queues.append(queue)
119
-
120
- neo4j_session.run(
121
- ingest_queues,
122
- Queues=queues,
123
- Region=region,
124
- AWS_ACCOUNT_ID=current_aws_account_id,
125
- aws_update_tag=aws_update_tag,
126
- )
127
-
128
- _attach_dead_letter_queues(neo4j_session, dead_letter_queues, aws_update_tag)
75
+ queue["redrive_policy_dead_letter_target_arn"] = rp.get(
76
+ "deadLetterTargetArn"
77
+ )
78
+ queue["redrive_policy_max_receive_count"] = rp.get("maxReceiveCount")
79
+ transformed.append(queue)
80
+ return transformed
129
81
 
130
82
 
131
83
  @timeit
132
- def _attach_dead_letter_queues(
84
+ def load_sqs_queues(
133
85
  neo4j_session: neo4j.Session,
134
- data: List[Dict[str, str]],
86
+ data: List[Dict[str, Any]],
87
+ region: str,
88
+ current_aws_account_id: str,
135
89
  aws_update_tag: int,
136
90
  ) -> None:
137
- """
138
- Attach deadletter queues to their queues.
139
- """
140
- attach_deadletter_to_queue = """
141
- UNWIND $Relations as relation
142
- MATCH (queue:SQSQueue{id: relation.arn}), (deadletter:SQSQueue{id: relation.dead_letter_arn})
143
- MERGE (queue)-[r:HAS_DEADLETTER_QUEUE]->(deadletter)
144
- ON CREATE SET r.firstseen = timestamp()
145
- SET r.lastupdated = $aws_update_tag
146
- """
147
- neo4j_session.run(
148
- attach_deadletter_to_queue,
149
- Relations=data,
150
- aws_update_tag=aws_update_tag,
91
+ load(
92
+ neo4j_session,
93
+ SQSQueueSchema(),
94
+ data,
95
+ lastupdated=aws_update_tag,
96
+ Region=region,
97
+ AWS_ID=current_aws_account_id,
151
98
  )
152
99
 
153
100
 
154
101
  @timeit
155
102
  def cleanup_sqs_queues(
156
103
  neo4j_session: neo4j.Session,
157
- common_job_parameters: Dict,
104
+ common_job_parameters: Dict[str, Any],
158
105
  ) -> None:
159
- run_cleanup_job(
160
- "aws_import_sqs_queues_cleanup.json",
161
- neo4j_session,
162
- common_job_parameters,
106
+ GraphJob.from_node_schema(SQSQueueSchema(), common_job_parameters).run(
107
+ neo4j_session
163
108
  )
164
109
 
165
110
 
@@ -170,7 +115,7 @@ def sync(
170
115
  regions: List[str],
171
116
  current_aws_account_id: str,
172
117
  update_tag: int,
173
- common_job_parameters: Dict,
118
+ common_job_parameters: Dict[str, Any],
174
119
  ) -> None:
175
120
  for region in regions:
176
121
  logger.info(
@@ -179,12 +124,13 @@ def sync(
179
124
  current_aws_account_id,
180
125
  )
181
126
  queue_urls = get_sqs_queue_list(boto3_session, region)
182
- if len(queue_urls) == 0:
127
+ if not queue_urls:
183
128
  continue
184
129
  queue_attributes = get_sqs_queue_attributes(boto3_session, queue_urls)
130
+ transformed = transform_sqs_queues(queue_attributes)
185
131
  load_sqs_queues(
186
132
  neo4j_session,
187
- queue_attributes,
133
+ transformed,
188
134
  region,
189
135
  current_aws_account_id,
190
136
  update_tag,
@@ -9,6 +9,7 @@ import boto3
9
9
  import neo4j
10
10
 
11
11
  from cartography.client.core.tx import load
12
+ from cartography.client.core.tx import read_list_of_values_tx
12
13
  from cartography.graph.job import GraphJob
13
14
  from cartography.models.aws.ssm.instance_information import SSMInstanceInformationSchema
14
15
  from cartography.models.aws.ssm.instance_patch import SSMInstancePatchSchema
@@ -31,15 +32,12 @@ def get_instance_ids(
31
32
  WHERE i.region = $Region
32
33
  RETURN i.id
33
34
  """
34
- results = neo4j_session.run(
35
+ return neo4j_session.execute_read(
36
+ read_list_of_values_tx,
35
37
  get_instances_query,
36
38
  AWS_ACCOUNT_ID=current_aws_account_id,
37
39
  Region=region,
38
40
  )
39
- instance_ids = []
40
- for r in results:
41
- instance_ids.append(r["i.id"])
42
- return instance_ids
43
41
 
44
42
 
45
43
  @timeit