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
@@ -6,6 +6,7 @@ import boto3
6
6
  import botocore
7
7
  import neo4j
8
8
 
9
+ from cartography.client.core.tx import run_write_query
9
10
  from cartography.util import aws_handle_regions
10
11
  from cartography.util import run_cleanup_job
11
12
  from cartography.util import timeit
@@ -104,7 +105,8 @@ def load_load_balancer_v2s(
104
105
  logger.warning("Skipping load balancer entry with missing DNSName: %r", lb)
105
106
  continue
106
107
 
107
- neo4j_session.run(
108
+ run_write_query(
109
+ neo4j_session,
108
110
  ingest_load_balancer_v2,
109
111
  ID=load_balancer_id,
110
112
  CREATED_TIME=str(lb["CreatedTime"]),
@@ -138,7 +140,8 @@ def load_load_balancer_v2s(
138
140
  SET r.lastupdated = $update_tag
139
141
  """
140
142
  for group in lb["SecurityGroups"]:
141
- neo4j_session.run(
143
+ run_write_query(
144
+ neo4j_session,
142
145
  ingest_load_balancer_v2_security_group,
143
146
  ID=load_balancer_id,
144
147
  GROUP_ID=str(group),
@@ -182,7 +185,8 @@ def load_load_balancer_v2_subnets(
182
185
  SET r.lastupdated = $update_tag
183
186
  """
184
187
  for az in az_data:
185
- neo4j_session.run(
188
+ run_write_query(
189
+ neo4j_session,
186
190
  ingest_load_balancer_subnet,
187
191
  ID=load_balancer_id,
188
192
  SubnetId=az["SubnetId"],
@@ -219,7 +223,8 @@ def load_load_balancer_v2_target_groups(
219
223
  continue
220
224
 
221
225
  for instance in target_group["Targets"]:
222
- neo4j_session.run(
226
+ run_write_query(
227
+ neo4j_session,
223
228
  ingest_instances,
224
229
  ID=load_balancer_id,
225
230
  INSTANCE_ID=instance,
@@ -253,7 +258,8 @@ def load_load_balancer_v2_listeners(
253
258
  ON CREATE SET r.firstseen = timestamp()
254
259
  SET r.lastupdated = $update_tag
255
260
  """
256
- neo4j_session.run(
261
+ run_write_query(
262
+ neo4j_session,
257
263
  ingest_listener,
258
264
  LoadBalancerId=load_balancer_id,
259
265
  Listeners=listener_data,
@@ -91,13 +91,17 @@ def transform_network_interface_data(
91
91
  "InterfaceType": network_interface["InterfaceType"],
92
92
  "MacAddress": network_interface["MacAddress"],
93
93
  "PrivateDnsName": network_interface.get("PrivateDnsName"),
94
- "PrivateIpAddress": network_interface["PrivateIpAddress"],
94
+ "PrivateIpAddress": network_interface.get("PrivateIpAddress"),
95
95
  "PublicIp": network_interface.get("Association", {}).get("PublicIp"),
96
96
  "RequesterId": network_interface.get("RequesterId"),
97
97
  "RequesterManaged": network_interface["RequesterManaged"],
98
98
  "SourceDestCheck": network_interface["SourceDestCheck"],
99
99
  "Status": network_interface["Status"],
100
100
  "SubnetId": network_interface["SubnetId"],
101
+ "AttachTime": network_interface.get("Attachment", {}).get("AttachTime"),
102
+ "DeviceIndex": network_interface.get("Attachment", {}).get(
103
+ "DeviceIndex"
104
+ ),
101
105
  "ElbV1Id": elb_v1_id,
102
106
  "ElbV2Id": elb_v2_id,
103
107
  },
@@ -6,6 +6,7 @@ import boto3
6
6
  import neo4j
7
7
  from botocore.exceptions import ClientError
8
8
 
9
+ from cartography.client.core.tx import run_write_query
9
10
  from cartography.util import aws_handle_regions
10
11
  from cartography.util import run_cleanup_job
11
12
  from cartography.util import timeit
@@ -64,7 +65,8 @@ def load_reserved_instances(
64
65
  r_instance["Start"] = str(r_instance["Start"])
65
66
  r_instance["End"] = str(r_instance["End"])
66
67
 
67
- neo4j_session.run(
68
+ run_write_query(
69
+ neo4j_session,
68
70
  ingest_reserved_instances,
69
71
  reserved_instances_list=data,
70
72
  AWS_ACCOUNT_ID=current_aws_account_id,
@@ -1,17 +1,22 @@
1
1
  import logging
2
- from string import Template
2
+ from collections import namedtuple
3
+ from typing import Any
3
4
  from typing import Dict
4
5
  from typing import List
5
6
 
6
7
  import boto3
7
8
  import neo4j
8
9
 
10
+ from cartography.client.core.tx import load
9
11
  from cartography.graph.job import GraphJob
12
+ from cartography.models.aws.ec2.security_group_rules import IpPermissionInboundSchema
13
+ from cartography.models.aws.ec2.security_group_rules import IpRangeSchema
14
+ from cartography.models.aws.ec2.security_group_rules import IpRuleSchema
15
+ from cartography.models.aws.ec2.security_groups import EC2SecurityGroupSchema
10
16
  from cartography.models.aws.ec2.securitygroup_instance import (
11
17
  EC2SecurityGroupInstanceSchema,
12
18
  )
13
19
  from cartography.util import aws_handle_regions
14
- from cartography.util import run_cleanup_job
15
20
  from cartography.util import timeit
16
21
 
17
22
  from .util import get_botocore_config
@@ -37,138 +42,146 @@ def get_ec2_security_group_data(
37
42
  return security_groups
38
43
 
39
44
 
45
+ Ec2SecurityGroupData = namedtuple(
46
+ "Ec2SecurityGroupData",
47
+ ["groups", "inbound_rules", "egress_rules", "ranges"],
48
+ )
49
+
50
+
51
+ def transform_ec2_security_group_data(
52
+ data: List[Dict[str, Any]],
53
+ ) -> Ec2SecurityGroupData:
54
+ groups: List[Dict[str, Any]] = []
55
+ inbound_rules: List[Dict[str, Any]] = []
56
+ egress_rules: List[Dict[str, Any]] = []
57
+ ranges: List[Dict[str, Any]] = []
58
+
59
+ for group in data:
60
+ group_record = {
61
+ "GroupId": group["GroupId"],
62
+ "GroupName": group.get("GroupName"),
63
+ "Description": group.get("Description"),
64
+ "VpcId": group.get("VpcId"),
65
+ }
66
+ # Collect referenced security groups for relationship loading
67
+ source_group_ids: set[str] = set()
68
+
69
+ for rule_type, target in (
70
+ ("IpPermissions", inbound_rules),
71
+ ("IpPermissionsEgress", egress_rules),
72
+ ):
73
+ for rule in group.get(rule_type, []):
74
+ protocol = rule.get("IpProtocol", "all")
75
+ from_port = rule.get("FromPort")
76
+ to_port = rule.get("ToPort")
77
+ rule_id = (
78
+ f"{group['GroupId']}/{rule_type}/{from_port}{to_port}{protocol}"
79
+ )
80
+ target.append(
81
+ {
82
+ "RuleId": rule_id,
83
+ "GroupId": group["GroupId"],
84
+ "Protocol": protocol,
85
+ "FromPort": from_port,
86
+ "ToPort": to_port,
87
+ },
88
+ )
89
+ for ip_range in rule.get("IpRanges", []):
90
+ ranges.append({"RangeId": ip_range["CidrIp"], "RuleId": rule_id})
91
+ for pair in rule.get("UserIdGroupPairs", []):
92
+ sg_id = pair.get("GroupId")
93
+ if sg_id:
94
+ source_group_ids.add(sg_id)
95
+
96
+ group_record["SOURCE_GROUP_IDS"] = list(source_group_ids)
97
+ groups.append(group_record)
98
+
99
+ return Ec2SecurityGroupData(
100
+ groups=groups,
101
+ inbound_rules=inbound_rules,
102
+ egress_rules=egress_rules,
103
+ ranges=ranges,
104
+ )
105
+
106
+
40
107
  @timeit
41
- def load_ec2_security_group_rule(
108
+ def load_ip_rules(
42
109
  neo4j_session: neo4j.Session,
43
- group: Dict,
44
- rule_type: str,
110
+ data: List[Dict[str, Any]],
111
+ inbound: bool,
112
+ region: str,
113
+ aws_account_id: str,
45
114
  update_tag: int,
46
115
  ) -> None:
47
- INGEST_RULE_TEMPLATE = Template(
48
- """
49
- MERGE (rule:$rule_label{ruleid: $RuleId})
50
- ON CREATE SET rule :IpRule, rule.firstseen = timestamp(), rule.fromport = $FromPort, rule.toport = $ToPort,
51
- rule.protocol = $Protocol
52
- SET rule.lastupdated = $update_tag
53
- WITH rule
54
- MATCH (group:EC2SecurityGroup{groupid: $GroupId})
55
- MERGE (group)<-[r:MEMBER_OF_EC2_SECURITY_GROUP]-(rule)
56
- ON CREATE SET r.firstseen = timestamp()
57
- SET r.lastupdated = $update_tag;
58
- """,
116
+ schema = IpPermissionInboundSchema() if inbound else IpRuleSchema()
117
+ load(
118
+ neo4j_session,
119
+ schema,
120
+ data,
121
+ Region=region,
122
+ AWS_ID=aws_account_id,
123
+ lastupdated=update_tag,
59
124
  )
60
125
 
61
- ingest_rule_group_pair = """
62
- MERGE (group:EC2SecurityGroup{id: $GroupId})
63
- ON CREATE SET group.firstseen = timestamp(), group.groupid = $GroupId
64
- SET group.lastupdated = $update_tag
65
- WITH group
66
- MATCH (inbound:IpRule{ruleid: $RuleId})
67
- MERGE (inbound)-[r:MEMBER_OF_EC2_SECURITY_GROUP]->(group)
68
- ON CREATE SET r.firstseen = timestamp()
69
- SET r.lastupdated = $update_tag
70
- """
71
-
72
- ingest_range = """
73
- MERGE (range:IpRange{id: $RangeId})
74
- ON CREATE SET range.firstseen = timestamp(), range.range = $RangeId
75
- SET range.lastupdated = $update_tag
76
- WITH range
77
- MATCH (rule:IpRule{ruleid: $RuleId})
78
- MERGE (rule)<-[r:MEMBER_OF_IP_RULE]-(range)
79
- ON CREATE SET r.firstseen = timestamp()
80
- SET r.lastupdated = $update_tag
81
- """
82
-
83
- group_id = group["GroupId"]
84
- rule_type_map = {
85
- "IpPermissions": "IpPermissionInbound",
86
- "IpPermissionsEgress": "IpPermissionEgress",
87
- }
88
-
89
- if group.get(rule_type):
90
- for rule in group[rule_type]:
91
- protocol = rule.get("IpProtocol", "all")
92
- from_port = rule.get("FromPort")
93
- to_port = rule.get("ToPort")
94
-
95
- ruleid = f"{group_id}/{rule_type}/{from_port}{to_port}{protocol}"
96
- # NOTE Cypher query syntax is incompatible with Python string formatting, so we have to do this awkward
97
- # NOTE manual formatting instead.
98
- neo4j_session.run(
99
- INGEST_RULE_TEMPLATE.safe_substitute(
100
- rule_label=rule_type_map[rule_type],
101
- ),
102
- RuleId=ruleid,
103
- FromPort=from_port,
104
- ToPort=to_port,
105
- Protocol=protocol,
106
- GroupId=group_id,
107
- update_tag=update_tag,
108
- )
109
-
110
- neo4j_session.run(
111
- ingest_rule_group_pair,
112
- GroupId=group_id,
113
- RuleId=ruleid,
114
- update_tag=update_tag,
115
- )
116
-
117
- for ip_range in rule["IpRanges"]:
118
- range_id = ip_range["CidrIp"]
119
- neo4j_session.run(
120
- ingest_range,
121
- RangeId=range_id,
122
- RuleId=ruleid,
123
- update_tag=update_tag,
124
- )
126
+
127
+ @timeit
128
+ def load_ip_ranges(
129
+ neo4j_session: neo4j.Session,
130
+ data: List[Dict[str, Any]],
131
+ region: str,
132
+ aws_account_id: str,
133
+ update_tag: int,
134
+ ) -> None:
135
+ load(
136
+ neo4j_session,
137
+ IpRangeSchema(),
138
+ data,
139
+ Region=region,
140
+ AWS_ID=aws_account_id,
141
+ lastupdated=update_tag,
142
+ )
125
143
 
126
144
 
127
145
  @timeit
128
146
  def load_ec2_security_groupinfo(
129
147
  neo4j_session: neo4j.Session,
130
- data: List[Dict],
148
+ data: Ec2SecurityGroupData,
131
149
  region: str,
132
150
  current_aws_account_id: str,
133
151
  update_tag: int,
134
152
  ) -> None:
135
- ingest_security_group = """
136
- MERGE (group:EC2SecurityGroup{id: $GroupId})
137
- ON CREATE SET group.firstseen = timestamp(), group.groupid = $GroupId
138
- SET group.name = $GroupName, group.description = $Description, group.region = $Region,
139
- group.lastupdated = $update_tag
140
- WITH group
141
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
142
- MERGE (aa)-[r:RESOURCE]->(group)
143
- ON CREATE SET r.firstseen = timestamp()
144
- SET r.lastupdated = $update_tag
145
- WITH group
146
- MATCH (vpc:AWSVpc{id: $VpcId})
147
- MERGE (vpc)-[rg:MEMBER_OF_EC2_SECURITY_GROUP]->(group)
148
- ON CREATE SET rg.firstseen = timestamp()
149
- """
150
-
151
- for group in data:
152
- group_id = group["GroupId"]
153
-
154
- neo4j_session.run(
155
- ingest_security_group,
156
- GroupId=group_id,
157
- GroupName=group.get("GroupName"),
158
- Description=group.get("Description"),
159
- VpcId=group.get("VpcId", None),
160
- Region=region,
161
- AWS_ACCOUNT_ID=current_aws_account_id,
162
- update_tag=update_tag,
163
- )
153
+ load(
154
+ neo4j_session,
155
+ EC2SecurityGroupSchema(),
156
+ data.groups,
157
+ Region=region,
158
+ AWS_ID=current_aws_account_id,
159
+ lastupdated=update_tag,
160
+ )
164
161
 
165
- load_ec2_security_group_rule(neo4j_session, group, "IpPermissions", update_tag)
166
- load_ec2_security_group_rule(
167
- neo4j_session,
168
- group,
169
- "IpPermissionsEgress",
170
- update_tag,
171
- )
162
+ load_ip_rules(
163
+ neo4j_session,
164
+ data.inbound_rules,
165
+ inbound=True,
166
+ region=region,
167
+ aws_account_id=current_aws_account_id,
168
+ update_tag=update_tag,
169
+ )
170
+ load_ip_rules(
171
+ neo4j_session,
172
+ data.egress_rules,
173
+ inbound=False,
174
+ region=region,
175
+ aws_account_id=current_aws_account_id,
176
+ update_tag=update_tag,
177
+ )
178
+ load_ip_ranges(
179
+ neo4j_session,
180
+ data.ranges,
181
+ region,
182
+ current_aws_account_id,
183
+ update_tag,
184
+ )
172
185
 
173
186
 
174
187
  @timeit
@@ -176,11 +189,15 @@ def cleanup_ec2_security_groupinfo(
176
189
  neo4j_session: neo4j.Session,
177
190
  common_job_parameters: Dict,
178
191
  ) -> None:
179
- run_cleanup_job(
180
- "aws_import_ec2_security_groupinfo_cleanup.json",
181
- neo4j_session,
192
+ GraphJob.from_node_schema(
193
+ EC2SecurityGroupSchema(),
182
194
  common_job_parameters,
195
+ ).run(neo4j_session)
196
+ GraphJob.from_node_schema(IpPermissionInboundSchema(), common_job_parameters).run(
197
+ neo4j_session,
183
198
  )
199
+ GraphJob.from_node_schema(IpRuleSchema(), common_job_parameters).run(neo4j_session)
200
+ GraphJob.from_node_schema(IpRangeSchema(), common_job_parameters).run(neo4j_session)
184
201
  GraphJob.from_node_schema(
185
202
  EC2SecurityGroupInstanceSchema(),
186
203
  common_job_parameters,
@@ -203,9 +220,10 @@ def sync_ec2_security_groupinfo(
203
220
  current_aws_account_id,
204
221
  )
205
222
  data = get_ec2_security_group_data(boto3_session, region)
223
+ transformed = transform_ec2_security_group_data(data)
206
224
  load_ec2_security_groupinfo(
207
225
  neo4j_session,
208
- data,
226
+ transformed,
209
227
  region,
210
228
  current_aws_account_id,
211
229
  update_tag,
@@ -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
 
@@ -6,8 +7,11 @@ import boto3
6
7
  import neo4j
7
8
  from botocore.exceptions import ClientError
8
9
 
10
+ from cartography.client.core.tx import load
11
+ from cartography.client.core.tx import read_list_of_values_tx
12
+ from cartography.graph.job import GraphJob
13
+ from cartography.models.aws.ec2.snapshots import EBSSnapshotSchema
9
14
  from cartography.util import aws_handle_regions
10
- from cartography.util import run_cleanup_job
11
15
  from cartography.util import timeit
12
16
 
13
17
  logger = logging.getLogger(__name__)
@@ -24,12 +28,13 @@ def get_snapshots_in_use(
24
28
  WHERE v.region = $Region
25
29
  RETURN v.snapshotid as snapshot
26
30
  """
27
- results = neo4j_session.run(
31
+ results = read_list_of_values_tx(
32
+ neo4j_session,
28
33
  query,
29
34
  AWS_ACCOUNT_ID=current_aws_account_id,
30
35
  Region=region,
31
36
  )
32
- return [r["snapshot"] for r in results if r["snapshot"]]
37
+ return [str(snapshot) for snapshot in results if snapshot]
33
38
 
34
39
 
35
40
  @timeit
@@ -45,7 +50,6 @@ def get_snapshots(
45
50
  for page in paginator.paginate(OwnerIds=["self"]):
46
51
  snapshots.extend(page["Snapshots"])
47
52
 
48
- # fetch in-use snapshots not in self_owned snapshots
49
53
  self_owned_snapshot_ids = {s["SnapshotId"] for s in snapshots}
50
54
  other_snapshot_ids = set(in_use_snapshot_ids) - self_owned_snapshot_ids
51
55
  if other_snapshot_ids:
@@ -55,8 +59,7 @@ def get_snapshots(
55
59
  except ClientError as e:
56
60
  if e.response["Error"]["Code"] == "InvalidSnapshot.NotFound":
57
61
  logger.warning(
58
- f"Failed to retrieve page of in-use, \
59
- not owned snapshots. Continuing anyway. Error - {e}",
62
+ f"Failed to retrieve page of in-use, not owned snapshots. Continuing anyway. Error - {e}"
60
63
  )
61
64
  else:
62
65
  raise
@@ -64,93 +67,53 @@ def get_snapshots(
64
67
  return snapshots
65
68
 
66
69
 
70
+ def transform_snapshots(snapshots: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
71
+ transformed: List[Dict[str, Any]] = []
72
+ for snap in snapshots:
73
+ transformed.append(
74
+ {
75
+ "SnapshotId": snap["SnapshotId"],
76
+ "Description": snap.get("Description"),
77
+ "Encrypted": snap.get("Encrypted"),
78
+ "Progress": snap.get("Progress"),
79
+ "StartTime": snap.get("StartTime"),
80
+ "State": snap.get("State"),
81
+ "StateMessage": snap.get("StateMessage"),
82
+ "VolumeId": snap.get("VolumeId"),
83
+ "VolumeSize": snap.get("VolumeSize"),
84
+ "OutpostArn": snap.get("OutpostArn"),
85
+ "DataEncryptionKeyId": snap.get("DataEncryptionKeyId"),
86
+ "KmsKeyId": snap.get("KmsKeyId"),
87
+ }
88
+ )
89
+ return transformed
90
+
91
+
67
92
  @timeit
68
93
  def load_snapshots(
69
94
  neo4j_session: neo4j.Session,
70
- data: List[Dict],
95
+ data: List[Dict[str, Any]],
71
96
  region: str,
72
97
  current_aws_account_id: str,
73
98
  update_tag: int,
74
99
  ) -> None:
75
- ingest_snapshots = """
76
- UNWIND $snapshots_list as snapshot
77
- MERGE (s:EBSSnapshot{id: snapshot.SnapshotId})
78
- ON CREATE SET s.firstseen = timestamp()
79
- SET s.lastupdated = $update_tag, s.description = snapshot.Description, s.encrypted = snapshot.Encrypted,
80
- s.progress = snapshot.Progress, s.starttime = snapshot.StartTime, s.state = snapshot.State,
81
- s.statemessage = snapshot.StateMessage, s.volumeid = snapshot.VolumeId, s.volumesize = snapshot.VolumeSize,
82
- s.outpostarn = snapshot.OutpostArn, s.dataencryptionkeyid = snapshot.DataEncryptionKeyId,
83
- s.kmskeyid = snapshot.KmsKeyId, s.region=$Region
84
- WITH s
85
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
86
- MERGE (aa)-[r:RESOURCE]->(s)
87
- ON CREATE SET r.firstseen = timestamp()
88
- SET r.lastupdated = $update_tag
89
- """
90
-
91
- for snapshot in data:
92
- snapshot["StartTime"] = str(snapshot["StartTime"])
93
-
94
- neo4j_session.run(
95
- ingest_snapshots,
96
- snapshots_list=data,
97
- AWS_ACCOUNT_ID=current_aws_account_id,
100
+ load(
101
+ neo4j_session,
102
+ EBSSnapshotSchema(),
103
+ data,
104
+ lastupdated=update_tag,
98
105
  Region=region,
99
- update_tag=update_tag,
100
- )
101
-
102
-
103
- @timeit
104
- def get_snapshot_volumes(snapshots: List[Dict]) -> List[Dict]:
105
- snapshot_volumes: List[Dict] = []
106
- for snapshot in snapshots:
107
- if snapshot.get("VolumeId"):
108
- snapshot_volumes.append(snapshot)
109
-
110
- return snapshot_volumes
111
-
112
-
113
- @timeit
114
- def load_snapshot_volume_relations(
115
- neo4j_session: neo4j.Session,
116
- data: List[Dict],
117
- current_aws_account_id: str,
118
- update_tag: int,
119
- ) -> None:
120
- ingest_volumes = """
121
- UNWIND $snapshot_volumes_list as volume
122
- MERGE (v:EBSVolume{id: volume.VolumeId})
123
- ON CREATE SET v.firstseen = timestamp()
124
- SET v.lastupdated = $update_tag, v.snapshotid = volume.SnapshotId
125
- WITH v, volume
126
- MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
127
- MERGE (aa)-[r:RESOURCE]->(v)
128
- ON CREATE SET r.firstseen = timestamp()
129
- SET r.lastupdated = $update_tag
130
- WITH v, volume
131
- MATCH (s:EBSSnapshot{id: volume.SnapshotId})
132
- MERGE (s)-[r:CREATED_FROM]->(v)
133
- ON CREATE SET r.firstseen = timestamp()
134
- SET r.lastupdated = $update_tag
135
- """
136
-
137
- neo4j_session.run(
138
- ingest_volumes,
139
- snapshot_volumes_list=data,
140
- AWS_ACCOUNT_ID=current_aws_account_id,
141
- update_tag=update_tag,
106
+ AWS_ID=current_aws_account_id,
142
107
  )
143
108
 
144
109
 
145
110
  @timeit
146
111
  def cleanup_snapshots(
147
112
  neo4j_session: neo4j.Session,
148
- common_job_parameters: Dict,
113
+ common_job_parameters: Dict[str, Any],
149
114
  ) -> None:
150
- run_cleanup_job(
151
- "aws_import_snapshots_cleanup.json",
152
- neo4j_session,
153
- common_job_parameters,
115
+ GraphJob.from_node_schema(EBSSnapshotSchema(), common_job_parameters).run(
116
+ neo4j_session
154
117
  )
155
118
 
156
119
 
@@ -161,7 +124,7 @@ def sync_ebs_snapshots(
161
124
  regions: List[str],
162
125
  current_aws_account_id: str,
163
126
  update_tag: int,
164
- common_job_parameters: Dict,
127
+ common_job_parameters: Dict[str, Any],
165
128
  ) -> None:
166
129
  for region in regions:
167
130
  logger.debug(
@@ -174,12 +137,12 @@ def sync_ebs_snapshots(
174
137
  region,
175
138
  current_aws_account_id,
176
139
  )
177
- data = get_snapshots(boto3_session, region, snapshots_in_use)
178
- load_snapshots(neo4j_session, data, region, current_aws_account_id, update_tag)
179
- snapshot_volumes = get_snapshot_volumes(data)
180
- load_snapshot_volume_relations(
140
+ raw_data = get_snapshots(boto3_session, region, snapshots_in_use)
141
+ transformed_data = transform_snapshots(raw_data)
142
+ load_snapshots(
181
143
  neo4j_session,
182
- snapshot_volumes,
144
+ transformed_data,
145
+ region,
183
146
  current_aws_account_id,
184
147
  update_tag,
185
148
  )