cartography 0.93.0rc1__py3-none-any.whl → 0.123.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (822) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +34 -0
  3. cartography/cli.py +903 -225
  4. cartography/client/aws/__init__.py +19 -0
  5. cartography/client/aws/ecr.py +51 -0
  6. cartography/client/core/tx.py +400 -27
  7. cartography/config.py +215 -10
  8. cartography/data/azure_permission_relationships.yaml +20 -0
  9. cartography/data/gcp_permission_relationships.yaml +21 -0
  10. cartography/data/indexes.cypher +1 -200
  11. cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
  12. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  13. cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
  14. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  15. cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
  16. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  17. cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
  18. cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
  19. cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
  20. cartography/driftdetect/__main__.py +1 -2
  21. cartography/driftdetect/add_shortcut.py +10 -2
  22. cartography/driftdetect/cli.py +72 -75
  23. cartography/driftdetect/detect_deviations.py +7 -3
  24. cartography/driftdetect/get_states.py +20 -8
  25. cartography/driftdetect/model.py +5 -5
  26. cartography/driftdetect/serializers.py +8 -6
  27. cartography/driftdetect/storage.py +2 -2
  28. cartography/graph/cleanupbuilder.py +255 -35
  29. cartography/graph/job.py +104 -20
  30. cartography/graph/querybuilder.py +689 -91
  31. cartography/graph/statement.py +49 -36
  32. cartography/intel/airbyte/__init__.py +105 -0
  33. cartography/intel/airbyte/connections.py +120 -0
  34. cartography/intel/airbyte/destinations.py +81 -0
  35. cartography/intel/airbyte/organizations.py +59 -0
  36. cartography/intel/airbyte/sources.py +78 -0
  37. cartography/intel/airbyte/tags.py +64 -0
  38. cartography/intel/airbyte/users.py +106 -0
  39. cartography/intel/airbyte/util.py +122 -0
  40. cartography/intel/airbyte/workspaces.py +63 -0
  41. cartography/intel/analysis.py +4 -1
  42. cartography/intel/anthropic/__init__.py +62 -0
  43. cartography/intel/anthropic/apikeys.py +72 -0
  44. cartography/intel/anthropic/users.py +75 -0
  45. cartography/intel/anthropic/util.py +51 -0
  46. cartography/intel/anthropic/workspaces.py +95 -0
  47. cartography/intel/aws/__init__.py +137 -59
  48. cartography/intel/aws/acm.py +124 -0
  49. cartography/intel/aws/apigateway.py +482 -217
  50. cartography/intel/aws/apigatewayv2.py +116 -0
  51. cartography/intel/aws/cloudtrail.py +105 -0
  52. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  53. cartography/intel/aws/cloudwatch.py +239 -0
  54. cartography/intel/aws/codebuild.py +132 -0
  55. cartography/intel/aws/cognito.py +201 -0
  56. cartography/intel/aws/config.py +63 -23
  57. cartography/intel/aws/dynamodb.py +108 -40
  58. cartography/intel/aws/ec2/__init__.py +2 -2
  59. cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
  60. cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
  61. cartography/intel/aws/ec2/images.py +74 -39
  62. cartography/intel/aws/ec2/instances.py +262 -137
  63. cartography/intel/aws/ec2/internet_gateways.py +44 -13
  64. cartography/intel/aws/ec2/key_pairs.py +72 -39
  65. cartography/intel/aws/ec2/launch_templates.py +143 -66
  66. cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
  67. cartography/intel/aws/ec2/load_balancers.py +165 -147
  68. cartography/intel/aws/ec2/network_acls.py +233 -0
  69. cartography/intel/aws/ec2/network_interfaces.py +150 -87
  70. cartography/intel/aws/ec2/reserved_instances.py +48 -17
  71. cartography/intel/aws/ec2/route_tables.py +327 -0
  72. cartography/intel/aws/ec2/security_groups.py +189 -121
  73. cartography/intel/aws/ec2/snapshots.py +93 -91
  74. cartography/intel/aws/ec2/subnets.py +70 -58
  75. cartography/intel/aws/ec2/tgw.py +111 -39
  76. cartography/intel/aws/ec2/util.py +1 -1
  77. cartography/intel/aws/ec2/volumes.py +69 -41
  78. cartography/intel/aws/ec2/vpc.py +157 -116
  79. cartography/intel/aws/ec2/vpc_peerings.py +317 -121
  80. cartography/intel/aws/ecr.py +336 -93
  81. cartography/intel/aws/ecr_image_layers.py +923 -0
  82. cartography/intel/aws/ecs.py +310 -403
  83. cartography/intel/aws/efs.py +261 -0
  84. cartography/intel/aws/eks.py +55 -29
  85. cartography/intel/aws/elasticache.py +130 -83
  86. cartography/intel/aws/elasticsearch.py +70 -24
  87. cartography/intel/aws/emr.py +61 -23
  88. cartography/intel/aws/eventbridge.py +164 -0
  89. cartography/intel/aws/glue.py +181 -0
  90. cartography/intel/aws/guardduty.py +443 -0
  91. cartography/intel/aws/iam.py +978 -464
  92. cartography/intel/aws/iam_instance_profiles.py +73 -0
  93. cartography/intel/aws/identitycenter.py +847 -0
  94. cartography/intel/aws/inspector.py +330 -133
  95. cartography/intel/aws/kms.py +235 -209
  96. cartography/intel/aws/lambda_function.py +328 -176
  97. cartography/intel/aws/organizations.py +40 -19
  98. cartography/intel/aws/permission_relationships.py +144 -68
  99. cartography/intel/aws/rds.py +467 -412
  100. cartography/intel/aws/redshift.py +116 -50
  101. cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
  102. cartography/intel/aws/resources.py +80 -42
  103. cartography/intel/aws/route53.py +419 -318
  104. cartography/intel/aws/s3.py +489 -96
  105. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  106. cartography/intel/aws/secretsmanager.py +217 -40
  107. cartography/intel/aws/securityhub.py +23 -10
  108. cartography/intel/aws/sns.py +226 -0
  109. cartography/intel/aws/sqs.py +74 -96
  110. cartography/intel/aws/ssm.py +142 -33
  111. cartography/intel/aws/util/arns.py +7 -7
  112. cartography/intel/aws/util/common.py +31 -4
  113. cartography/intel/azure/__init__.py +259 -46
  114. cartography/intel/azure/aks.py +175 -0
  115. cartography/intel/azure/app_service.py +105 -0
  116. cartography/intel/azure/compute.py +141 -120
  117. cartography/intel/azure/container_instances.py +95 -0
  118. cartography/intel/azure/cosmosdb.py +706 -519
  119. cartography/intel/azure/data_factory.py +85 -0
  120. cartography/intel/azure/data_factory_dataset.py +128 -0
  121. cartography/intel/azure/data_factory_linked_service.py +119 -0
  122. cartography/intel/azure/data_factory_pipeline.py +142 -0
  123. cartography/intel/azure/data_lake.py +124 -0
  124. cartography/intel/azure/event_grid.py +94 -0
  125. cartography/intel/azure/functions.py +124 -0
  126. cartography/intel/azure/load_balancers.py +263 -0
  127. cartography/intel/azure/logic_apps.py +101 -0
  128. cartography/intel/azure/monitor.py +105 -0
  129. cartography/intel/azure/network.py +467 -0
  130. cartography/intel/azure/permission_relationships.py +466 -0
  131. cartography/intel/azure/rbac.py +309 -0
  132. cartography/intel/azure/resource_groups.py +82 -0
  133. cartography/intel/azure/security_center.py +106 -0
  134. cartography/intel/azure/sql.py +436 -392
  135. cartography/intel/azure/storage.py +467 -335
  136. cartography/intel/azure/subscription.py +49 -55
  137. cartography/intel/azure/tenant.py +46 -28
  138. cartography/intel/azure/util/common.py +13 -0
  139. cartography/intel/azure/util/credentials.py +58 -143
  140. cartography/intel/azure/util/tag.py +41 -0
  141. cartography/intel/bigfix/__init__.py +2 -2
  142. cartography/intel/bigfix/computers.py +93 -65
  143. cartography/intel/cloudflare/__init__.py +74 -0
  144. cartography/intel/cloudflare/accounts.py +57 -0
  145. cartography/intel/cloudflare/dnsrecords.py +64 -0
  146. cartography/intel/cloudflare/members.py +75 -0
  147. cartography/intel/cloudflare/roles.py +65 -0
  148. cartography/intel/cloudflare/zones.py +64 -0
  149. cartography/intel/create_indexes.py +5 -3
  150. cartography/intel/crowdstrike/__init__.py +26 -12
  151. cartography/intel/crowdstrike/endpoints.py +17 -45
  152. cartography/intel/crowdstrike/spotlight.py +13 -5
  153. cartography/intel/cve/__init__.py +91 -26
  154. cartography/intel/cve/feed.py +77 -56
  155. cartography/intel/digitalocean/__init__.py +22 -13
  156. cartography/intel/digitalocean/compute.py +75 -108
  157. cartography/intel/digitalocean/management.py +44 -80
  158. cartography/intel/digitalocean/platform.py +48 -43
  159. cartography/intel/dns.py +41 -12
  160. cartography/intel/duo/__init__.py +21 -16
  161. cartography/intel/duo/api_host.py +14 -9
  162. cartography/intel/duo/endpoints.py +50 -45
  163. cartography/intel/duo/groups.py +18 -14
  164. cartography/intel/duo/phones.py +37 -34
  165. cartography/intel/duo/tokens.py +26 -23
  166. cartography/intel/duo/users.py +54 -50
  167. cartography/intel/duo/web_authn_credentials.py +30 -25
  168. cartography/intel/entra/__init__.py +160 -0
  169. cartography/intel/entra/app_role_assignments.py +284 -0
  170. cartography/intel/entra/applications.py +182 -0
  171. cartography/intel/entra/federation/__init__.py +0 -0
  172. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  173. cartography/intel/entra/groups.py +198 -0
  174. cartography/intel/entra/ou.py +136 -0
  175. cartography/intel/entra/service_principals.py +217 -0
  176. cartography/intel/entra/users.py +259 -0
  177. cartography/intel/gcp/__init__.py +381 -175
  178. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  179. cartography/intel/gcp/bigtable_backup.py +91 -0
  180. cartography/intel/gcp/bigtable_cluster.py +93 -0
  181. cartography/intel/gcp/bigtable_instance.py +86 -0
  182. cartography/intel/gcp/bigtable_table.py +87 -0
  183. cartography/intel/gcp/cai.py +292 -0
  184. cartography/intel/gcp/clients.py +112 -0
  185. cartography/intel/gcp/compute.py +521 -325
  186. cartography/intel/gcp/crm/__init__.py +0 -0
  187. cartography/intel/gcp/crm/folders.py +114 -0
  188. cartography/intel/gcp/crm/orgs.py +70 -0
  189. cartography/intel/gcp/crm/projects.py +120 -0
  190. cartography/intel/gcp/dns.py +134 -179
  191. cartography/intel/gcp/gke.py +100 -107
  192. cartography/intel/gcp/iam.py +262 -0
  193. cartography/intel/gcp/permission_relationships.py +394 -0
  194. cartography/intel/gcp/policy_bindings.py +225 -0
  195. cartography/intel/gcp/storage.py +103 -158
  196. cartography/intel/github/__init__.py +66 -27
  197. cartography/intel/github/commits.py +423 -0
  198. cartography/intel/github/repos.py +871 -160
  199. cartography/intel/github/teams.py +386 -53
  200. cartography/intel/github/users.py +214 -49
  201. cartography/intel/github/util.py +50 -35
  202. cartography/intel/googleworkspace/__init__.py +193 -0
  203. cartography/intel/googleworkspace/devices.py +254 -0
  204. cartography/intel/googleworkspace/groups.py +568 -0
  205. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  206. cartography/intel/googleworkspace/tenant.py +85 -0
  207. cartography/intel/googleworkspace/users.py +138 -0
  208. cartography/intel/gsuite/__init__.py +101 -42
  209. cartography/intel/gsuite/groups.py +291 -0
  210. cartography/intel/gsuite/users.py +142 -0
  211. cartography/intel/jamf/__init__.py +19 -1
  212. cartography/intel/jamf/computers.py +37 -8
  213. cartography/intel/jamf/util.py +7 -2
  214. cartography/intel/kandji/__init__.py +6 -3
  215. cartography/intel/kandji/devices.py +40 -10
  216. cartography/intel/keycloak/__init__.py +153 -0
  217. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  218. cartography/intel/keycloak/authenticationflows.py +77 -0
  219. cartography/intel/keycloak/clients.py +187 -0
  220. cartography/intel/keycloak/groups.py +126 -0
  221. cartography/intel/keycloak/identityproviders.py +94 -0
  222. cartography/intel/keycloak/organizations.py +163 -0
  223. cartography/intel/keycloak/realms.py +61 -0
  224. cartography/intel/keycloak/roles.py +202 -0
  225. cartography/intel/keycloak/scopes.py +73 -0
  226. cartography/intel/keycloak/users.py +70 -0
  227. cartography/intel/keycloak/util.py +47 -0
  228. cartography/intel/kubernetes/__init__.py +60 -14
  229. cartography/intel/kubernetes/clusters.py +86 -0
  230. cartography/intel/kubernetes/eks.py +402 -0
  231. cartography/intel/kubernetes/namespaces.py +60 -55
  232. cartography/intel/kubernetes/pods.py +171 -75
  233. cartography/intel/kubernetes/rbac.py +597 -0
  234. cartography/intel/kubernetes/secrets.py +95 -45
  235. cartography/intel/kubernetes/services.py +131 -63
  236. cartography/intel/kubernetes/util.py +142 -14
  237. cartography/intel/lastpass/__init__.py +2 -2
  238. cartography/intel/lastpass/users.py +23 -12
  239. cartography/intel/oci/__init__.py +44 -11
  240. cartography/intel/oci/iam.py +157 -47
  241. cartography/intel/oci/organizations.py +16 -7
  242. cartography/intel/oci/utils.py +71 -25
  243. cartography/intel/okta/__init__.py +66 -15
  244. cartography/intel/okta/applications.py +57 -25
  245. cartography/intel/okta/awssaml.py +105 -41
  246. cartography/intel/okta/factors.py +19 -5
  247. cartography/intel/okta/groups.py +61 -31
  248. cartography/intel/okta/organization.py +8 -2
  249. cartography/intel/okta/origins.py +9 -3
  250. cartography/intel/okta/roles.py +20 -7
  251. cartography/intel/okta/users.py +31 -10
  252. cartography/intel/okta/utils.py +6 -4
  253. cartography/intel/ontology/__init__.py +44 -0
  254. cartography/intel/ontology/devices.py +54 -0
  255. cartography/intel/ontology/users.py +54 -0
  256. cartography/intel/ontology/utils.py +176 -0
  257. cartography/intel/openai/__init__.py +86 -0
  258. cartography/intel/openai/adminapikeys.py +89 -0
  259. cartography/intel/openai/apikeys.py +96 -0
  260. cartography/intel/openai/projects.py +97 -0
  261. cartography/intel/openai/serviceaccounts.py +82 -0
  262. cartography/intel/openai/users.py +75 -0
  263. cartography/intel/openai/util.py +45 -0
  264. cartography/intel/pagerduty/__init__.py +8 -7
  265. cartography/intel/pagerduty/escalation_policies.py +31 -12
  266. cartography/intel/pagerduty/schedules.py +21 -8
  267. cartography/intel/pagerduty/services.py +18 -7
  268. cartography/intel/pagerduty/teams.py +13 -5
  269. cartography/intel/pagerduty/users.py +6 -2
  270. cartography/intel/pagerduty/vendors.py +6 -2
  271. cartography/intel/scaleway/__init__.py +127 -0
  272. cartography/intel/scaleway/iam/__init__.py +0 -0
  273. cartography/intel/scaleway/iam/apikeys.py +71 -0
  274. cartography/intel/scaleway/iam/applications.py +71 -0
  275. cartography/intel/scaleway/iam/groups.py +71 -0
  276. cartography/intel/scaleway/iam/users.py +71 -0
  277. cartography/intel/scaleway/instances/__init__.py +0 -0
  278. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  279. cartography/intel/scaleway/instances/instances.py +92 -0
  280. cartography/intel/scaleway/projects.py +79 -0
  281. cartography/intel/scaleway/storage/__init__.py +0 -0
  282. cartography/intel/scaleway/storage/snapshots.py +86 -0
  283. cartography/intel/scaleway/storage/volumes.py +84 -0
  284. cartography/intel/scaleway/utils.py +37 -0
  285. cartography/intel/semgrep/__init__.py +30 -5
  286. cartography/intel/semgrep/dependencies.py +255 -0
  287. cartography/intel/semgrep/deployment.py +69 -0
  288. cartography/intel/semgrep/findings.py +157 -117
  289. cartography/intel/sentinelone/__init__.py +75 -0
  290. cartography/intel/sentinelone/account.py +140 -0
  291. cartography/intel/sentinelone/agent.py +139 -0
  292. cartography/intel/sentinelone/api.py +124 -0
  293. cartography/intel/sentinelone/application.py +248 -0
  294. cartography/intel/sentinelone/cve.py +119 -0
  295. cartography/intel/sentinelone/utils.py +28 -0
  296. cartography/intel/slack/__init__.py +78 -0
  297. cartography/intel/slack/channels.py +80 -0
  298. cartography/intel/slack/groups.py +90 -0
  299. cartography/intel/slack/teams.py +65 -0
  300. cartography/intel/slack/users.py +57 -0
  301. cartography/intel/slack/utils.py +29 -0
  302. cartography/intel/snipeit/__init__.py +44 -0
  303. cartography/intel/snipeit/asset.py +80 -0
  304. cartography/intel/snipeit/user.py +78 -0
  305. cartography/intel/snipeit/util.py +40 -0
  306. cartography/intel/spacelift/__init__.py +161 -0
  307. cartography/intel/spacelift/account.py +73 -0
  308. cartography/intel/spacelift/ec2_ownership.py +280 -0
  309. cartography/intel/spacelift/runs.py +463 -0
  310. cartography/intel/spacelift/spaces.py +112 -0
  311. cartography/intel/spacelift/stacks.py +119 -0
  312. cartography/intel/spacelift/util.py +122 -0
  313. cartography/intel/spacelift/workerpools.py +131 -0
  314. cartography/intel/spacelift/workers.py +128 -0
  315. cartography/intel/tailscale/__init__.py +77 -0
  316. cartography/intel/tailscale/acls.py +146 -0
  317. cartography/intel/tailscale/devices.py +127 -0
  318. cartography/intel/tailscale/postureintegrations.py +81 -0
  319. cartography/intel/tailscale/tailnets.py +76 -0
  320. cartography/intel/tailscale/users.py +80 -0
  321. cartography/intel/tailscale/utils.py +132 -0
  322. cartography/intel/trivy/__init__.py +272 -0
  323. cartography/intel/trivy/scanner.py +386 -0
  324. cartography/models/airbyte/__init__.py +0 -0
  325. cartography/models/airbyte/connection.py +138 -0
  326. cartography/models/airbyte/destination.py +75 -0
  327. cartography/models/airbyte/organization.py +19 -0
  328. cartography/models/airbyte/source.py +75 -0
  329. cartography/models/airbyte/stream.py +74 -0
  330. cartography/models/airbyte/tag.py +69 -0
  331. cartography/models/airbyte/user.py +115 -0
  332. cartography/models/airbyte/workspace.py +46 -0
  333. cartography/models/anthropic/__init__.py +0 -0
  334. cartography/models/anthropic/apikey.py +94 -0
  335. cartography/models/anthropic/organization.py +19 -0
  336. cartography/models/anthropic/user.py +52 -0
  337. cartography/models/anthropic/workspace.py +90 -0
  338. cartography/models/aws/acm/__init__.py +0 -0
  339. cartography/models/aws/acm/certificate.py +75 -0
  340. cartography/models/aws/apigateway/__init__.py +0 -0
  341. cartography/models/aws/apigateway/apigateway.py +51 -0
  342. cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
  343. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  344. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  345. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  346. cartography/models/aws/apigateway/apigatewayresource.py +70 -0
  347. cartography/models/aws/apigateway/apigatewaystage.py +75 -0
  348. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  349. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  350. cartography/models/aws/cloudtrail/__init__.py +0 -0
  351. cartography/models/aws/cloudtrail/management_events.py +153 -0
  352. cartography/models/aws/cloudtrail/trail.py +106 -0
  353. cartography/models/aws/cloudwatch/__init__.py +0 -0
  354. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  355. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  356. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  357. cartography/models/aws/codebuild/__init__.py +0 -0
  358. cartography/models/aws/codebuild/project.py +49 -0
  359. cartography/models/aws/cognito/__init__.py +0 -0
  360. cartography/models/aws/cognito/identity_pool.py +70 -0
  361. cartography/models/aws/cognito/user_pool.py +47 -0
  362. cartography/models/aws/dynamodb/gsi.py +30 -22
  363. cartography/models/aws/dynamodb/tables.py +27 -17
  364. cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
  365. cartography/models/aws/ec2/images.py +36 -34
  366. cartography/models/aws/ec2/instances.py +85 -38
  367. cartography/models/aws/ec2/keypair.py +59 -0
  368. cartography/models/aws/ec2/keypair_instance.py +76 -0
  369. cartography/models/aws/ec2/launch_configurations.py +59 -0
  370. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  371. cartography/models/aws/ec2/launch_templates.py +21 -17
  372. cartography/models/aws/ec2/load_balancer_listeners.py +72 -0
  373. cartography/models/aws/ec2/load_balancers.py +112 -0
  374. cartography/models/aws/ec2/network_acl_rules.py +106 -0
  375. cartography/models/aws/ec2/network_acls.py +95 -0
  376. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  377. cartography/models/aws/ec2/networkinterfaces.py +57 -37
  378. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  379. cartography/models/aws/ec2/reservations.py +18 -14
  380. cartography/models/aws/ec2/route_table_associations.py +97 -0
  381. cartography/models/aws/ec2/route_tables.py +128 -0
  382. cartography/models/aws/ec2/routes.py +85 -0
  383. cartography/models/aws/ec2/security_group_rules.py +109 -0
  384. cartography/models/aws/ec2/security_groups.py +90 -0
  385. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  386. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  387. cartography/models/aws/ec2/snapshots.py +58 -0
  388. cartography/models/aws/ec2/subnet_instance.py +26 -19
  389. cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
  390. cartography/models/aws/ec2/subnets.py +65 -0
  391. cartography/models/aws/ec2/volumes.py +67 -40
  392. cartography/models/aws/ec2/vpc.py +46 -0
  393. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  394. cartography/models/aws/ec2/vpc_peering.py +157 -0
  395. cartography/models/aws/ecr/__init__.py +0 -0
  396. cartography/models/aws/ecr/image.py +146 -0
  397. cartography/models/aws/ecr/image_layer.py +107 -0
  398. cartography/models/aws/ecr/repository.py +72 -0
  399. cartography/models/aws/ecr/repository_image.py +95 -0
  400. cartography/models/aws/ecs/__init__.py +0 -0
  401. cartography/models/aws/ecs/clusters.py +64 -0
  402. cartography/models/aws/ecs/container_definitions.py +93 -0
  403. cartography/models/aws/ecs/container_instances.py +84 -0
  404. cartography/models/aws/ecs/containers.py +101 -0
  405. cartography/models/aws/ecs/services.py +134 -0
  406. cartography/models/aws/ecs/task_definitions.py +135 -0
  407. cartography/models/aws/ecs/tasks.py +134 -0
  408. cartography/models/aws/efs/__init__.py +0 -0
  409. cartography/models/aws/efs/access_point.py +77 -0
  410. cartography/models/aws/efs/file_system.py +60 -0
  411. cartography/models/aws/efs/mount_target.py +79 -0
  412. cartography/models/aws/eks/clusters.py +23 -21
  413. cartography/models/aws/elasticache/__init__.py +0 -0
  414. cartography/models/aws/elasticache/cluster.py +65 -0
  415. cartography/models/aws/elasticache/topic.py +67 -0
  416. cartography/models/aws/emr.py +32 -30
  417. cartography/models/aws/eventbridge/__init__.py +0 -0
  418. cartography/models/aws/eventbridge/rule.py +77 -0
  419. cartography/models/aws/eventbridge/target.py +71 -0
  420. cartography/models/aws/glue/__init__.py +0 -0
  421. cartography/models/aws/glue/connection.py +51 -0
  422. cartography/models/aws/glue/job.py +69 -0
  423. cartography/models/aws/guardduty/__init__.py +1 -0
  424. cartography/models/aws/guardduty/detectors.py +50 -0
  425. cartography/models/aws/guardduty/findings.py +121 -0
  426. cartography/models/aws/iam/__init__.py +0 -0
  427. cartography/models/aws/iam/access_key.py +103 -0
  428. cartography/models/aws/iam/account_role.py +24 -0
  429. cartography/models/aws/iam/federated_principal.py +60 -0
  430. cartography/models/aws/iam/group.py +60 -0
  431. cartography/models/aws/iam/group_membership.py +27 -0
  432. cartography/models/aws/iam/inline_policy.py +78 -0
  433. cartography/models/aws/iam/instanceprofile.py +76 -0
  434. cartography/models/aws/iam/managed_policy.py +51 -0
  435. cartography/models/aws/iam/policy_statement.py +57 -0
  436. cartography/models/aws/iam/role.py +83 -0
  437. cartography/models/aws/iam/root_principal.py +52 -0
  438. cartography/models/aws/iam/service_principal.py +30 -0
  439. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  440. cartography/models/aws/iam/user.py +59 -0
  441. cartography/models/aws/identitycenter/__init__.py +0 -0
  442. cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
  443. cartography/models/aws/identitycenter/awspermissionset.py +162 -0
  444. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  445. cartography/models/aws/identitycenter/awsssouser.py +110 -0
  446. cartography/models/aws/inspector/findings.py +124 -58
  447. cartography/models/aws/inspector/packages.py +18 -42
  448. cartography/models/aws/kms/__init__.py +0 -0
  449. cartography/models/aws/kms/aliases.py +86 -0
  450. cartography/models/aws/kms/grants.py +65 -0
  451. cartography/models/aws/kms/keys.py +88 -0
  452. cartography/models/aws/lambda_function/__init__.py +0 -0
  453. cartography/models/aws/lambda_function/alias.py +74 -0
  454. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  455. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  456. cartography/models/aws/lambda_function/layer.py +72 -0
  457. cartography/models/aws/rds/__init__.py +0 -0
  458. cartography/models/aws/rds/cluster.py +91 -0
  459. cartography/models/aws/rds/event_subscription.py +146 -0
  460. cartography/models/aws/rds/instance.py +156 -0
  461. cartography/models/aws/rds/snapshot.py +108 -0
  462. cartography/models/aws/rds/subnet_group.py +101 -0
  463. cartography/models/aws/route53/__init__.py +0 -0
  464. cartography/models/aws/route53/dnsrecord.py +235 -0
  465. cartography/models/aws/route53/nameserver.py +63 -0
  466. cartography/models/aws/route53/subzone.py +40 -0
  467. cartography/models/aws/route53/zone.py +47 -0
  468. cartography/models/aws/s3/__init__.py +0 -0
  469. cartography/models/aws/s3/account_public_access_block.py +51 -0
  470. cartography/models/aws/s3/notification.py +24 -0
  471. cartography/models/aws/secretsmanager/__init__.py +0 -0
  472. cartography/models/aws/secretsmanager/secret.py +106 -0
  473. cartography/models/aws/secretsmanager/secret_version.py +114 -0
  474. cartography/models/aws/sns/__init__.py +0 -0
  475. cartography/models/aws/sns/topic.py +50 -0
  476. cartography/models/aws/sns/topic_subscription.py +74 -0
  477. cartography/models/aws/sqs/__init__.py +0 -0
  478. cartography/models/aws/sqs/queue.py +89 -0
  479. cartography/models/aws/ssm/instance_information.py +51 -39
  480. cartography/models/aws/ssm/instance_patch.py +32 -26
  481. cartography/models/aws/ssm/parameters.py +84 -0
  482. cartography/models/azure/__init__.py +0 -0
  483. cartography/models/azure/aks_cluster.py +54 -0
  484. cartography/models/azure/aks_nodepool.py +54 -0
  485. cartography/models/azure/app_service.py +59 -0
  486. cartography/models/azure/container_instance.py +57 -0
  487. cartography/models/azure/cosmosdb/__init__.py +0 -0
  488. cartography/models/azure/cosmosdb/account.py +77 -0
  489. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  490. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  491. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  492. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  493. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  494. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  495. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  496. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  497. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  498. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  499. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  500. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  501. cartography/models/azure/data_factory/__init__.py +0 -0
  502. cartography/models/azure/data_factory/data_factory.py +51 -0
  503. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  504. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  505. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  506. cartography/models/azure/data_lake_filesystem.py +51 -0
  507. cartography/models/azure/event_grid_topic.py +57 -0
  508. cartography/models/azure/function_app.py +59 -0
  509. cartography/models/azure/load_balancer/__init__.py +0 -0
  510. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  511. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  512. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  513. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  514. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  515. cartography/models/azure/logic_apps.py +56 -0
  516. cartography/models/azure/monitor.py +54 -0
  517. cartography/models/azure/network_interface.py +112 -0
  518. cartography/models/azure/network_security_group.py +50 -0
  519. cartography/models/azure/permission_relationships.py +60 -0
  520. cartography/models/azure/principal.py +41 -0
  521. cartography/models/azure/public_ip_address.py +50 -0
  522. cartography/models/azure/rbac.py +268 -0
  523. cartography/models/azure/resource_groups.py +52 -0
  524. cartography/models/azure/security_center.py +50 -0
  525. cartography/models/azure/sql/__init__.py +0 -0
  526. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  527. cartography/models/azure/sql/elasticpool.py +77 -0
  528. cartography/models/azure/sql/failovergroup.py +73 -0
  529. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  530. cartography/models/azure/sql/replicationlink.py +81 -0
  531. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  532. cartography/models/azure/sql/restorepoint.py +74 -0
  533. cartography/models/azure/sql/serveradadministrator.py +74 -0
  534. cartography/models/azure/sql/serverdnsalias.py +71 -0
  535. cartography/models/azure/sql/sqldatabase.py +85 -0
  536. cartography/models/azure/sql/sqlserver.py +50 -0
  537. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  538. cartography/models/azure/storage/__init__.py +0 -0
  539. cartography/models/azure/storage/account.py +59 -0
  540. cartography/models/azure/storage/blobcontainer.py +85 -0
  541. cartography/models/azure/storage/blobservice.py +71 -0
  542. cartography/models/azure/storage/fileservice.py +71 -0
  543. cartography/models/azure/storage/fileshare.py +82 -0
  544. cartography/models/azure/storage/queue.py +71 -0
  545. cartography/models/azure/storage/queueservice.py +73 -0
  546. cartography/models/azure/storage/table.py +72 -0
  547. cartography/models/azure/storage/tableservice.py +73 -0
  548. cartography/models/azure/subnet.py +101 -0
  549. cartography/models/azure/subscription.py +47 -0
  550. cartography/models/azure/tags/__init__.py +0 -0
  551. cartography/models/azure/tags/storage_tag.py +40 -0
  552. cartography/models/azure/tags/tag.py +37 -0
  553. cartography/models/azure/tenant.py +17 -0
  554. cartography/models/azure/virtual_network.py +49 -0
  555. cartography/models/azure/vm/__init__.py +0 -0
  556. cartography/models/azure/vm/datadisk.py +80 -0
  557. cartography/models/azure/vm/disk.py +55 -0
  558. cartography/models/azure/vm/snapshot.py +56 -0
  559. cartography/models/azure/vm/virtualmachine.py +59 -0
  560. cartography/models/bigfix/bigfix_computer.py +42 -38
  561. cartography/models/bigfix/bigfix_root.py +3 -3
  562. cartography/models/cloudflare/__init__.py +0 -0
  563. cartography/models/cloudflare/account.py +25 -0
  564. cartography/models/cloudflare/dnsrecord.py +55 -0
  565. cartography/models/cloudflare/member.py +86 -0
  566. cartography/models/cloudflare/role.py +44 -0
  567. cartography/models/cloudflare/zone.py +59 -0
  568. cartography/models/core/common.py +53 -2
  569. cartography/models/core/nodes.py +20 -4
  570. cartography/models/core/relationships.py +58 -6
  571. cartography/models/crowdstrike/__init__.py +0 -0
  572. cartography/models/crowdstrike/hosts.py +51 -0
  573. cartography/models/cve/cve.py +34 -32
  574. cartography/models/cve/cve_feed.py +6 -6
  575. cartography/models/digitalocean/__init__.py +0 -0
  576. cartography/models/digitalocean/account.py +21 -0
  577. cartography/models/digitalocean/droplet.py +58 -0
  578. cartography/models/digitalocean/project.py +48 -0
  579. cartography/models/duo/api_host.py +3 -3
  580. cartography/models/duo/endpoint.py +43 -41
  581. cartography/models/duo/group.py +14 -14
  582. cartography/models/duo/phone.py +27 -27
  583. cartography/models/duo/token.py +16 -16
  584. cartography/models/duo/user.py +50 -44
  585. cartography/models/duo/web_authn_credential.py +27 -19
  586. cartography/models/entra/__init__.py +0 -0
  587. cartography/models/entra/app_role_assignment.py +115 -0
  588. cartography/models/entra/application.py +49 -0
  589. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  590. cartography/models/entra/group.py +117 -0
  591. cartography/models/entra/ou.py +48 -0
  592. cartography/models/entra/service_principal.py +104 -0
  593. cartography/models/entra/tenant.py +39 -0
  594. cartography/models/entra/user.py +90 -0
  595. cartography/models/gcp/__init__.py +0 -0
  596. cartography/models/gcp/bigtable/__init__.py +0 -0
  597. cartography/models/gcp/bigtable/app_profile.py +94 -0
  598. cartography/models/gcp/bigtable/backup.py +91 -0
  599. cartography/models/gcp/bigtable/cluster.py +73 -0
  600. cartography/models/gcp/bigtable/instance.py +52 -0
  601. cartography/models/gcp/bigtable/table.py +69 -0
  602. cartography/models/gcp/compute/__init__.py +0 -0
  603. cartography/models/gcp/compute/subnet.py +74 -0
  604. cartography/models/gcp/compute/vpc.py +50 -0
  605. cartography/models/gcp/crm/__init__.py +0 -0
  606. cartography/models/gcp/crm/folders.py +98 -0
  607. cartography/models/gcp/crm/organizations.py +21 -0
  608. cartography/models/gcp/crm/projects.py +100 -0
  609. cartography/models/gcp/dns.py +109 -0
  610. cartography/models/gcp/gke.py +69 -0
  611. cartography/models/gcp/iam.py +73 -0
  612. cartography/models/gcp/permission_relationships.py +61 -0
  613. cartography/models/gcp/policy_bindings.py +93 -0
  614. cartography/models/gcp/storage/__init__.py +0 -0
  615. cartography/models/gcp/storage/bucket.py +119 -0
  616. cartography/models/github/commits.py +63 -0
  617. cartography/models/github/dependencies.py +73 -0
  618. cartography/models/github/manifests.py +49 -0
  619. cartography/models/github/orgs.py +27 -0
  620. cartography/models/github/teams.py +74 -22
  621. cartography/models/github/users.py +149 -0
  622. cartography/models/googleworkspace/__init__.py +0 -0
  623. cartography/models/googleworkspace/device.py +132 -0
  624. cartography/models/googleworkspace/group.py +382 -0
  625. cartography/models/googleworkspace/oauth_app.py +124 -0
  626. cartography/models/googleworkspace/tenant.py +30 -0
  627. cartography/models/googleworkspace/user.py +113 -0
  628. cartography/models/gsuite/__init__.py +0 -0
  629. cartography/models/gsuite/group.py +218 -0
  630. cartography/models/gsuite/tenant.py +29 -0
  631. cartography/models/gsuite/user.py +107 -0
  632. cartography/models/kandji/device.py +22 -17
  633. cartography/models/kandji/tenant.py +6 -4
  634. cartography/models/keycloak/__init__.py +0 -0
  635. cartography/models/keycloak/authenticationexecution.py +160 -0
  636. cartography/models/keycloak/authenticationflow.py +54 -0
  637. cartography/models/keycloak/client.py +179 -0
  638. cartography/models/keycloak/group.py +101 -0
  639. cartography/models/keycloak/identityprovider.py +89 -0
  640. cartography/models/keycloak/organization.py +116 -0
  641. cartography/models/keycloak/organizationdomain.py +73 -0
  642. cartography/models/keycloak/realm.py +173 -0
  643. cartography/models/keycloak/role.py +126 -0
  644. cartography/models/keycloak/scope.py +73 -0
  645. cartography/models/keycloak/user.py +55 -0
  646. cartography/models/kubernetes/__init__.py +0 -0
  647. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  648. cartography/models/kubernetes/clusterroles.py +52 -0
  649. cartography/models/kubernetes/clusters.py +26 -0
  650. cartography/models/kubernetes/containers.py +133 -0
  651. cartography/models/kubernetes/groups.py +107 -0
  652. cartography/models/kubernetes/namespaces.py +51 -0
  653. cartography/models/kubernetes/oidc.py +51 -0
  654. cartography/models/kubernetes/pods.py +80 -0
  655. cartography/models/kubernetes/rolebindings.py +159 -0
  656. cartography/models/kubernetes/roles.py +76 -0
  657. cartography/models/kubernetes/secrets.py +79 -0
  658. cartography/models/kubernetes/serviceaccounts.py +77 -0
  659. cartography/models/kubernetes/services.py +108 -0
  660. cartography/models/kubernetes/users.py +105 -0
  661. cartography/models/lastpass/tenant.py +3 -3
  662. cartography/models/lastpass/user.py +36 -28
  663. cartography/models/ontology/__init__.py +0 -0
  664. cartography/models/ontology/device.py +137 -0
  665. cartography/models/ontology/mapping/__init__.py +76 -0
  666. cartography/models/ontology/mapping/data/__init__.py +0 -0
  667. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  668. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  669. cartography/models/ontology/mapping/data/containers.py +88 -0
  670. cartography/models/ontology/mapping/data/databases.py +182 -0
  671. cartography/models/ontology/mapping/data/devices.py +194 -0
  672. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  673. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  674. cartography/models/ontology/mapping/data/users.py +63 -0
  675. cartography/models/ontology/mapping/specs.py +85 -0
  676. cartography/models/ontology/user.py +51 -0
  677. cartography/models/openai/__init__.py +0 -0
  678. cartography/models/openai/adminapikey.py +94 -0
  679. cartography/models/openai/apikey.py +88 -0
  680. cartography/models/openai/organization.py +17 -0
  681. cartography/models/openai/project.py +89 -0
  682. cartography/models/openai/serviceaccount.py +50 -0
  683. cartography/models/openai/user.py +53 -0
  684. cartography/models/scaleway/__init__.py +0 -0
  685. cartography/models/scaleway/iam/__init__.py +0 -0
  686. cartography/models/scaleway/iam/apikey.py +100 -0
  687. cartography/models/scaleway/iam/application.py +52 -0
  688. cartography/models/scaleway/iam/group.py +95 -0
  689. cartography/models/scaleway/iam/user.py +64 -0
  690. cartography/models/scaleway/instance/__init__.py +0 -0
  691. cartography/models/scaleway/instance/flexibleip.py +52 -0
  692. cartography/models/scaleway/instance/instance.py +120 -0
  693. cartography/models/scaleway/organization.py +19 -0
  694. cartography/models/scaleway/project.py +48 -0
  695. cartography/models/scaleway/storage/__init__.py +0 -0
  696. cartography/models/scaleway/storage/snapshot.py +78 -0
  697. cartography/models/scaleway/storage/volume.py +51 -0
  698. cartography/models/semgrep/dependencies.py +102 -0
  699. cartography/models/semgrep/deployment.py +5 -5
  700. cartography/models/semgrep/findings.py +58 -40
  701. cartography/models/semgrep/locations.py +27 -21
  702. cartography/models/sentinelone/__init__.py +1 -0
  703. cartography/models/sentinelone/account.py +40 -0
  704. cartography/models/sentinelone/agent.py +50 -0
  705. cartography/models/sentinelone/application.py +44 -0
  706. cartography/models/sentinelone/application_version.py +96 -0
  707. cartography/models/sentinelone/cve.py +73 -0
  708. cartography/models/slack/__init__.py +0 -0
  709. cartography/models/slack/channels.py +92 -0
  710. cartography/models/slack/group.py +129 -0
  711. cartography/models/slack/team.py +22 -0
  712. cartography/models/slack/user.py +62 -0
  713. cartography/models/snipeit/__init__.py +0 -0
  714. cartography/models/snipeit/asset.py +92 -0
  715. cartography/models/snipeit/tenant.py +19 -0
  716. cartography/models/snipeit/user.py +60 -0
  717. cartography/models/spacelift/__init__.py +0 -0
  718. cartography/models/spacelift/cloudtrailevent.py +120 -0
  719. cartography/models/spacelift/run.py +162 -0
  720. cartography/models/spacelift/space.py +131 -0
  721. cartography/models/spacelift/spaceliftaccount.py +31 -0
  722. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  723. cartography/models/spacelift/stack.py +96 -0
  724. cartography/models/spacelift/user.py +63 -0
  725. cartography/models/spacelift/worker.py +97 -0
  726. cartography/models/spacelift/workerpool.py +90 -0
  727. cartography/models/tailscale/__init__.py +0 -0
  728. cartography/models/tailscale/device.py +96 -0
  729. cartography/models/tailscale/group.py +86 -0
  730. cartography/models/tailscale/postureintegration.py +58 -0
  731. cartography/models/tailscale/tag.py +102 -0
  732. cartography/models/tailscale/tailnet.py +29 -0
  733. cartography/models/tailscale/user.py +57 -0
  734. cartography/models/trivy/__init__.py +0 -0
  735. cartography/models/trivy/findings.py +66 -0
  736. cartography/models/trivy/fix.py +66 -0
  737. cartography/models/trivy/package.py +71 -0
  738. cartography/rules/README.md +1 -0
  739. cartography/rules/__init__.py +0 -0
  740. cartography/rules/cli.py +261 -0
  741. cartography/rules/data/__init__.py +0 -0
  742. cartography/rules/data/rules/__init__.py +46 -0
  743. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  744. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  745. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  746. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  747. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  748. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  749. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  750. cartography/rules/data/rules/mfa_missing.py +46 -0
  751. cartography/rules/data/rules/object_storage_public.py +100 -0
  752. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  753. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  754. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  755. cartography/rules/formatters.py +108 -0
  756. cartography/rules/runners.py +216 -0
  757. cartography/rules/spec/__init__.py +0 -0
  758. cartography/rules/spec/model.py +267 -0
  759. cartography/rules/spec/result.py +38 -0
  760. cartography/stats.py +4 -4
  761. cartography/sync.py +137 -31
  762. cartography/util.py +187 -77
  763. cartography-0.123.0.dist-info/METADATA +230 -0
  764. cartography-0.123.0.dist-info/RECORD +856 -0
  765. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
  766. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  767. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
  768. cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
  769. cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
  770. cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
  771. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  772. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  773. cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
  774. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  775. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  776. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  777. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  778. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  779. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  780. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  781. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  782. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  783. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  784. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  785. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  786. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  787. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  788. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  789. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  790. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  791. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  792. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  793. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  794. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  795. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  796. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  797. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  798. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  799. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  800. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  801. cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
  802. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  803. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  804. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  805. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  806. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  807. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  808. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  809. cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
  810. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  811. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  812. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  813. cartography/intel/crxcavator/__init__.py +0 -44
  814. cartography/intel/crxcavator/crxcavator.py +0 -329
  815. cartography/intel/gcp/crm.py +0 -302
  816. cartography/intel/gsuite/api.py +0 -284
  817. cartography/models/aws/ec2/keypairs.py +0 -64
  818. cartography-0.93.0rc1.dist-info/METADATA +0 -55
  819. cartography-0.93.0rc1.dist-info/NOTICE +0 -4
  820. cartography-0.93.0rc1.dist-info/RECORD +0 -341
  821. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  822. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@ import logging
2
2
  from typing import Any
3
3
  from typing import Dict
4
4
  from typing import Generator
5
+ from typing import Iterable
5
6
  from typing import List
6
7
  from typing import Tuple
7
8
 
@@ -14,10 +15,34 @@ from azure.mgmt.sql.models import SecurityAlertPolicyName
14
15
  from azure.mgmt.sql.models import TransparentDataEncryptionName
15
16
  from msrestazure.azure_exceptions import CloudError
16
17
 
17
- from .util.credentials import Credentials
18
- from cartography.util import run_cleanup_job
18
+ from cartography.client.core.tx import load
19
+ from cartography.graph.job import GraphJob
20
+ from cartography.models.azure.sql.databasethreatdetectionpolicy import (
21
+ AzureDatabaseThreatDetectionPolicySchema,
22
+ )
23
+ from cartography.models.azure.sql.elasticpool import AzureElasticPoolSchema
24
+ from cartography.models.azure.sql.failovergroup import AzureFailoverGroupSchema
25
+ from cartography.models.azure.sql.recoverabledatabase import (
26
+ AzureRecoverableDatabaseSchema,
27
+ )
28
+ from cartography.models.azure.sql.replicationlink import AzureReplicationLinkSchema
29
+ from cartography.models.azure.sql.restorabledroppeddatabase import (
30
+ AzureRestorableDroppedDatabaseSchema,
31
+ )
32
+ from cartography.models.azure.sql.restorepoint import AzureRestorePointSchema
33
+ from cartography.models.azure.sql.serveradadministrator import (
34
+ AzureServerADAdministratorSchema,
35
+ )
36
+ from cartography.models.azure.sql.serverdnsalias import AzureServerDNSAliasSchema
37
+ from cartography.models.azure.sql.sqldatabase import AzureSQLDatabaseSchema
38
+ from cartography.models.azure.sql.sqlserver import AzureSQLServerSchema
39
+ from cartography.models.azure.sql.transparentdataencryption import (
40
+ AzureTransparentDataEncryptionSchema,
41
+ )
19
42
  from cartography.util import timeit
20
43
 
44
+ from .util.credentials import Credentials
45
+
21
46
  logger = logging.getLogger(__name__)
22
47
 
23
48
 
@@ -51,57 +76,45 @@ def get_server_list(credentials: Credentials, subscription_id: str) -> List[Dict
51
76
  return []
52
77
 
53
78
  for server in server_list:
54
- x = server['id'].split('/')
55
- server['resourceGroup'] = x[x.index('resourceGroups') + 1]
79
+ x = server["id"].split("/")
80
+ server["resourceGroup"] = x[x.index("resourceGroups") + 1]
56
81
 
57
82
  return server_list
58
83
 
59
84
 
60
85
  @timeit
61
86
  def load_server_data(
62
- neo4j_session: neo4j.Session, subscription_id: str, server_list: List[Dict],
63
- azure_update_tag: int,
87
+ neo4j_session: neo4j.Session,
88
+ subscription_id: str,
89
+ server_list: List[Dict],
90
+ azure_update_tag: int,
64
91
  ) -> None:
65
- """
66
- Ingest the server details into neo4j.
67
- """
68
- ingest_server = """
69
- UNWIND $server_list as server
70
- MERGE (s:AzureSQLServer{id: server.id})
71
- ON CREATE SET s.firstseen = timestamp(),
72
- s.resourcegroup = server.resourceGroup, s.location = server.location
73
- SET s.lastupdated = $azure_update_tag,
74
- s.name = server.name,
75
- s.kind = server.kind,
76
- s.state = server.state,
77
- s.version = server.version
78
- WITH s
79
- MATCH (owner:AzureSubscription{id: $AZURE_SUBSCRIPTION_ID})
80
- MERGE (owner)-[r:RESOURCE]->(s)
81
- ON CREATE SET r.firstseen = timestamp()
82
- SET r.lastupdated = $azure_update_tag
83
- """
84
-
85
- neo4j_session.run(
86
- ingest_server,
87
- server_list=server_list,
92
+ load(
93
+ neo4j_session,
94
+ AzureSQLServerSchema(),
95
+ server_list,
96
+ lastupdated=azure_update_tag,
88
97
  AZURE_SUBSCRIPTION_ID=subscription_id,
89
- azure_update_tag=azure_update_tag,
90
98
  )
91
99
 
92
100
 
93
101
  @timeit
94
102
  def sync_server_details(
95
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
96
- server_list: List[Dict], sync_tag: int,
103
+ neo4j_session: neo4j.Session,
104
+ credentials: Credentials,
105
+ subscription_id: str,
106
+ server_list: List[Dict],
107
+ sync_tag: int,
97
108
  ) -> None:
98
109
  details = get_server_details(credentials, subscription_id, server_list)
99
- load_server_details(neo4j_session, credentials, subscription_id, details, sync_tag) # type: ignore
110
+ load_server_details(neo4j_session, credentials, subscription_id, details, sync_tag)
100
111
 
101
112
 
102
113
  @timeit
103
114
  def get_server_details(
104
- credentials: Credentials, subscription_id: str, server_list: List[Dict],
115
+ credentials: Credentials,
116
+ subscription_id: str,
117
+ server_list: List[Dict],
105
118
  ) -> Generator[Any, Any, Any]:
106
119
  """
107
120
  Iterate over each servers to get its resource details.
@@ -110,17 +123,25 @@ def get_server_details(
110
123
  dns_alias = get_dns_aliases(credentials, subscription_id, server)
111
124
  ad_admins = get_ad_admins(credentials, subscription_id, server)
112
125
  r_databases = get_recoverable_databases(credentials, subscription_id, server)
113
- rd_databases = get_restorable_dropped_databases(credentials, subscription_id, server)
126
+ rd_databases = get_restorable_dropped_databases(
127
+ credentials,
128
+ subscription_id,
129
+ server,
130
+ )
114
131
  fgs = get_failover_groups(credentials, subscription_id, server)
115
132
  elastic_pools = get_elastic_pools(credentials, subscription_id, server)
116
133
  databases = get_databases(credentials, subscription_id, server)
117
- yield server['id'], server['name'], server[
118
- 'resourceGroup'
134
+ yield server["id"], server["name"], server[
135
+ "resourceGroup"
119
136
  ], dns_alias, ad_admins, r_databases, rd_databases, fgs, elastic_pools, databases
120
137
 
121
138
 
122
139
  @timeit
123
- def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
140
+ def get_dns_aliases(
141
+ credentials: Credentials,
142
+ subscription_id: str,
143
+ server: Dict,
144
+ ) -> List[Dict]:
124
145
  """
125
146
  Returns details of the DNS aliases in a server.
126
147
  """
@@ -129,12 +150,17 @@ def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict
129
150
  dns_aliases = list(
130
151
  map(
131
152
  lambda x: x.as_dict(),
132
- client.server_dns_aliases.list_by_server(server['resourceGroup'], server['name']),
153
+ client.server_dns_aliases.list_by_server(
154
+ server["resourceGroup"],
155
+ server["name"],
156
+ ),
133
157
  ),
134
158
  )
135
159
 
136
160
  except ClientAuthenticationError as e:
137
- logger.warning(f"Client Authentication Error while retrieving DNS Aliases - {e}")
161
+ logger.warning(
162
+ f"Client Authentication Error while retrieving DNS Aliases - {e}",
163
+ )
138
164
  return []
139
165
  except ResourceNotFoundError as e:
140
166
  logger.warning(f"DNS Alias resource not found error - {e}")
@@ -147,7 +173,11 @@ def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict
147
173
 
148
174
 
149
175
  @timeit
150
- def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
176
+ def get_ad_admins(
177
+ credentials: Credentials,
178
+ subscription_id: str,
179
+ server: Dict,
180
+ ) -> List[Dict]:
151
181
  """
152
182
  Returns details of the Server AD Administrators in a server.
153
183
  """
@@ -157,14 +187,16 @@ def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict)
157
187
  map(
158
188
  lambda x: x.as_dict(),
159
189
  client.server_azure_ad_administrators.list_by_server(
160
- server['resourceGroup'],
161
- server['name'],
190
+ server["resourceGroup"],
191
+ server["name"],
162
192
  ),
163
193
  ),
164
194
  )
165
195
 
166
196
  except ClientAuthenticationError as e:
167
- logger.warning(f"Client Authentication Error while retrieving Azure AD Administrators - {e}")
197
+ logger.warning(
198
+ f"Client Authentication Error while retrieving Azure AD Administrators - {e}",
199
+ )
168
200
  return []
169
201
  except ResourceNotFoundError as e:
170
202
  logger.warning(f"Azure AD Administrators resource not found error - {e}")
@@ -177,7 +209,11 @@ def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict)
177
209
 
178
210
 
179
211
  @timeit
180
- def get_recoverable_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
212
+ def get_recoverable_databases(
213
+ credentials: Credentials,
214
+ subscription_id: str,
215
+ server: Dict,
216
+ ) -> List[Dict]:
181
217
  """
182
218
  Returns details of the Recoverable databases in a server.
183
219
  """
@@ -187,8 +223,8 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
187
223
  map(
188
224
  lambda x: x.as_dict(),
189
225
  client.recoverable_databases.list_by_server(
190
- server['resourceGroup'],
191
- server['name'],
226
+ server["resourceGroup"],
227
+ server["name"],
192
228
  ),
193
229
  ),
194
230
  )
@@ -197,7 +233,9 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
197
233
  # The API returns a '404 CloudError: Not Found for url: <url>' if no recoverable databases are present.
198
234
  return []
199
235
  except ClientAuthenticationError as e:
200
- logger.warning(f"Client Authentication Error while retrieving recoverable databases - {e}")
236
+ logger.warning(
237
+ f"Client Authentication Error while retrieving recoverable databases - {e}",
238
+ )
201
239
  return []
202
240
  except ResourceNotFoundError as e:
203
241
  logger.warning(f"Recoverable databases resource not found error - {e}")
@@ -210,7 +248,11 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
210
248
 
211
249
 
212
250
  @timeit
213
- def get_restorable_dropped_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
251
+ def get_restorable_dropped_databases(
252
+ credentials: Credentials,
253
+ subscription_id: str,
254
+ server: Dict,
255
+ ) -> List[Dict]:
214
256
  """
215
257
  Returns details of the Restorable Dropped Databases in a server.
216
258
  """
@@ -220,13 +262,16 @@ def get_restorable_dropped_databases(credentials: Credentials, subscription_id:
220
262
  map(
221
263
  lambda x: x.as_dict(),
222
264
  client.restorable_dropped_databases.list_by_server(
223
- server['resourceGroup'], server['name'],
265
+ server["resourceGroup"],
266
+ server["name"],
224
267
  ),
225
268
  ),
226
269
  )
227
270
 
228
271
  except ClientAuthenticationError as e:
229
- logger.warning(f"Client Authentication Error while retrieving Restorable Dropped Databases - {e}")
272
+ logger.warning(
273
+ f"Client Authentication Error while retrieving Restorable Dropped Databases - {e}",
274
+ )
230
275
  return []
231
276
  except ResourceNotFoundError as e:
232
277
  logger.warning(f"Restorable Dropped Databases resource not found error - {e}")
@@ -239,18 +284,30 @@ def get_restorable_dropped_databases(credentials: Credentials, subscription_id:
239
284
 
240
285
 
241
286
  @timeit
242
- def get_failover_groups(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
287
+ def get_failover_groups(
288
+ credentials: Credentials,
289
+ subscription_id: str,
290
+ server: Dict,
291
+ ) -> List[Dict]:
243
292
  """
244
293
  Returns details of Failover groups in a server.
245
294
  """
246
295
  try:
247
296
  client = get_client(credentials, subscription_id)
248
297
  failover_groups = list(
249
- map(lambda x: x.as_dict(), client.failover_groups.list_by_server(server['resourceGroup'], server['name'])),
298
+ map(
299
+ lambda x: x.as_dict(),
300
+ client.failover_groups.list_by_server(
301
+ server["resourceGroup"],
302
+ server["name"],
303
+ ),
304
+ ),
250
305
  )
251
306
 
252
307
  except ClientAuthenticationError as e:
253
- logger.warning(f"Client Authentication Error while retrieving Failover groups - {e}")
308
+ logger.warning(
309
+ f"Client Authentication Error while retrieving Failover groups - {e}",
310
+ )
254
311
  return []
255
312
  except ResourceNotFoundError as e:
256
313
  logger.warning(f"Failover groups resource not found error - {e}")
@@ -263,18 +320,30 @@ def get_failover_groups(credentials: Credentials, subscription_id: str, server:
263
320
 
264
321
 
265
322
  @timeit
266
- def get_elastic_pools(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
323
+ def get_elastic_pools(
324
+ credentials: Credentials,
325
+ subscription_id: str,
326
+ server: Dict,
327
+ ) -> List[Dict]:
267
328
  """
268
329
  Returns details of Elastic Pools in a server.
269
330
  """
270
331
  try:
271
332
  client = get_client(credentials, subscription_id)
272
333
  elastic_pools = list(
273
- map(lambda x: x.as_dict(), client.elastic_pools.list_by_server(server['resourceGroup'], server['name'])),
334
+ map(
335
+ lambda x: x.as_dict(),
336
+ client.elastic_pools.list_by_server(
337
+ server["resourceGroup"],
338
+ server["name"],
339
+ ),
340
+ ),
274
341
  )
275
342
 
276
343
  except ClientAuthenticationError as e:
277
- logger.warning(f"Client Authentication Error while retrieving Elastic Pools - {e}")
344
+ logger.warning(
345
+ f"Client Authentication Error while retrieving Elastic Pools - {e}",
346
+ )
278
347
  return []
279
348
  except ResourceNotFoundError as e:
280
349
  logger.warning(f"Elastic Pools resource not found error - {e}")
@@ -287,18 +356,30 @@ def get_elastic_pools(credentials: Credentials, subscription_id: str, server: Di
287
356
 
288
357
 
289
358
  @timeit
290
- def get_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
359
+ def get_databases(
360
+ credentials: Credentials,
361
+ subscription_id: str,
362
+ server: Dict,
363
+ ) -> List[Dict]:
291
364
  """
292
365
  Returns details of Databases in a SQL server.
293
366
  """
294
367
  try:
295
368
  client = get_client(credentials, subscription_id)
296
369
  databases = list(
297
- map(lambda x: x.as_dict(), client.databases.list_by_server(server['resourceGroup'], server['name'])),
370
+ map(
371
+ lambda x: x.as_dict(),
372
+ client.databases.list_by_server(
373
+ server["resourceGroup"],
374
+ server["name"],
375
+ ),
376
+ ),
298
377
  )
299
378
 
300
379
  except ClientAuthenticationError as e:
301
- logger.warning(f"Client Authentication Error while retrieving SQL databases - {e}")
380
+ logger.warning(
381
+ f"Client Authentication Error while retrieving SQL databases - {e}",
382
+ )
302
383
  return []
303
384
  except ResourceNotFoundError as e:
304
385
  logger.warning(f"SQL databases resource not found error - {e}")
@@ -312,12 +393,12 @@ def get_databases(credentials: Credentials, subscription_id: str, server: Dict)
312
393
 
313
394
  @timeit
314
395
  def load_server_details(
315
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
316
- details: List[Tuple[Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]], update_tag: int,
396
+ neo4j_session: neo4j.Session,
397
+ credentials: Credentials,
398
+ subscription_id: str,
399
+ details: Iterable[Tuple[Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]],
400
+ update_tag: int,
317
401
  ) -> None:
318
- """
319
- Create dictionaries for every resource in the server so we can import them in a single query
320
- """
321
402
  dns_aliases = []
322
403
  ad_admins = []
323
404
  recoverable_databases = []
@@ -326,311 +407,267 @@ def load_server_details(
326
407
  elastic_pools = []
327
408
  databases = []
328
409
 
329
- for server_id, name, rg, dns_alias, ad_admin, r_database, rd_database, fg, elastic_pool, database in details:
410
+ for (
411
+ server_id,
412
+ name,
413
+ rg,
414
+ dns_alias,
415
+ ad_admin,
416
+ r_database,
417
+ rd_database,
418
+ fg,
419
+ elastic_pool,
420
+ database,
421
+ ) in details:
330
422
  if len(dns_alias) > 0:
331
423
  for alias in dns_alias:
332
- alias['server_name'] = name
333
- alias['server_id'] = server_id
424
+ alias["server_name"] = name
425
+ alias["server_id"] = server_id
334
426
  dns_aliases.append(alias)
335
427
 
336
428
  if len(ad_admin) > 0:
337
429
  for admin in ad_admin:
338
- admin['server_name'] = name
339
- admin['server_id'] = server_id
430
+ admin["server_name"] = name
431
+ admin["server_id"] = server_id
340
432
  ad_admins.append(admin)
341
433
 
342
434
  if len(r_database) > 0:
343
435
  for rdb in r_database:
344
- rdb['server_name'] = name
345
- rdb['server_id'] = server_id
436
+ rdb["server_name"] = name
437
+ rdb["server_id"] = server_id
346
438
  recoverable_databases.append(rdb)
347
439
 
348
440
  if len(rd_database) > 0:
349
441
  for rddb in rd_database:
350
- rddb['server_name'] = name
351
- rddb['server_id'] = server_id
442
+ rddb["server_name"] = name
443
+ rddb["server_id"] = server_id
352
444
  restorable_dropped_databases.append(rddb)
353
445
 
354
446
  if len(fg) > 0:
355
447
  for group in fg:
356
- group['server_name'] = name
357
- group['server_id'] = server_id
448
+ group["server_name"] = name
449
+ group["server_id"] = server_id
358
450
  failover_groups.append(group)
359
451
 
360
452
  if len(elastic_pool) > 0:
361
453
  for pool in elastic_pool:
362
- pool['server_name'] = name
363
- pool['server_id'] = server_id
454
+ pool["server_name"] = name
455
+ pool["server_id"] = server_id
364
456
  elastic_pools.append(pool)
365
457
 
366
458
  if len(database) > 0:
367
459
  for db in database:
368
- db['server_name'] = name
369
- db['server_id'] = server_id
370
- db['resource_group_name'] = rg
460
+ db["server_name"] = name
461
+ db["server_id"] = server_id
462
+ db["resource_group_name"] = rg
371
463
  databases.append(db)
372
464
 
373
- _load_server_dns_aliases(neo4j_session, dns_aliases, update_tag)
374
- _load_server_ad_admins(neo4j_session, ad_admins, update_tag)
375
- _load_recoverable_databases(neo4j_session, recoverable_databases, update_tag)
376
- _load_restorable_dropped_databases(neo4j_session, restorable_dropped_databases, update_tag)
377
- _load_failover_groups(neo4j_session, failover_groups, update_tag)
378
- _load_elastic_pools(neo4j_session, elastic_pools, update_tag)
379
- _load_databases(neo4j_session, databases, update_tag)
380
-
381
- sync_database_details(neo4j_session, credentials, subscription_id, databases, update_tag)
465
+ _load_elastic_pools(neo4j_session, elastic_pools, subscription_id, update_tag)
466
+ _load_failover_groups(neo4j_session, failover_groups, subscription_id, update_tag)
467
+ _load_databases(neo4j_session, databases, subscription_id, update_tag)
468
+ _load_recoverable_databases(
469
+ neo4j_session, recoverable_databases, subscription_id, update_tag
470
+ )
471
+ _load_restorable_dropped_databases(
472
+ neo4j_session,
473
+ restorable_dropped_databases,
474
+ subscription_id,
475
+ update_tag,
476
+ )
477
+ _load_server_dns_aliases(neo4j_session, dns_aliases, subscription_id, update_tag)
478
+ _load_server_ad_admins(neo4j_session, ad_admins, subscription_id, update_tag)
479
+
480
+ sync_database_details(
481
+ neo4j_session,
482
+ credentials,
483
+ subscription_id,
484
+ databases,
485
+ update_tag,
486
+ )
382
487
 
383
488
 
384
489
  @timeit
385
490
  def _load_server_dns_aliases(
386
- neo4j_session: neo4j.Session, dns_aliases: List[Dict], update_tag: int,
491
+ neo4j_session: neo4j.Session,
492
+ dns_aliases: List[Dict],
493
+ subscription_id: str,
494
+ update_tag: int,
387
495
  ) -> None:
388
496
  """
389
497
  Ingest the DNS Alias details into neo4j.
390
498
  """
391
- ingest_dns_aliases = """
392
- UNWIND $dns_aliases_list as dns_alias
393
- MERGE (alias:AzureServerDNSAlias{id: dns_alias.id})
394
- ON CREATE SET alias.firstseen = timestamp()
395
- SET alias.name = dns_alias.name,
396
- alias.dnsrecord = dns_alias.azure_dns_record,
397
- alias.lastupdated = $azure_update_tag
398
- WITH alias, dns_alias
399
- MATCH (s:AzureSQLServer{id: dns_alias.server_id})
400
- MERGE (s)-[r:USED_BY]->(alias)
401
- ON CREATE SET r.firstseen = timestamp()
402
- SET r.lastupdated = $azure_update_tag
403
- """
404
-
405
- neo4j_session.run(
406
- ingest_dns_aliases,
407
- dns_aliases_list=dns_aliases,
408
- azure_update_tag=update_tag,
499
+ load(
500
+ neo4j_session,
501
+ AzureServerDNSAliasSchema(),
502
+ dns_aliases,
503
+ lastupdated=update_tag,
504
+ AZURE_SUBSCRIPTION_ID=subscription_id,
409
505
  )
410
506
 
411
507
 
412
508
  @timeit
413
509
  def _load_server_ad_admins(
414
- neo4j_session: neo4j.Session, ad_admins: List[Dict], update_tag: int,
510
+ neo4j_session: neo4j.Session,
511
+ ad_admins: List[Dict],
512
+ subscription_id: str,
513
+ update_tag: int,
415
514
  ) -> None:
416
515
  """
417
516
  Ingest the Server AD Administrators details into neo4j.
418
517
  """
419
- ingest_ad_admins = """
420
- UNWIND $ad_admins_list as ad_admin
421
- MERGE (a:AzureServerADAdministrator{id: ad_admin.id})
422
- ON CREATE SET a.firstseen = timestamp()
423
- SET a.name = ad_admin.name,
424
- a.administratortype = ad_admin.administrator_type,
425
- a.login = ad_admin.login,
426
- a.lastupdated = $azure_update_tag
427
- WITH a, ad_admin
428
- MATCH (s:AzureSQLServer{id: ad_admin.server_id})
429
- MERGE (s)-[r:ADMINISTERED_BY]->(a)
430
- ON CREATE SET r.firstseen = timestamp()
431
- SET r.lastupdated = $azure_update_tag
432
- """
433
-
434
- neo4j_session.run(
435
- ingest_ad_admins,
436
- ad_admins_list=ad_admins,
437
- azure_update_tag=update_tag,
518
+ load(
519
+ neo4j_session,
520
+ AzureServerADAdministratorSchema(),
521
+ ad_admins,
522
+ lastupdated=update_tag,
523
+ AZURE_SUBSCRIPTION_ID=subscription_id,
438
524
  )
439
525
 
440
526
 
441
527
  @timeit
442
528
  def _load_recoverable_databases(
443
- neo4j_session: neo4j.Session, recoverable_databases: List[Dict], update_tag: int,
529
+ neo4j_session: neo4j.Session,
530
+ recoverable_databases: List[Dict],
531
+ subscription_id: str,
532
+ update_tag: int,
444
533
  ) -> None:
445
534
  """
446
535
  Ingest the recoverable database details into neo4j.
447
536
  """
448
- ingest_recoverable_databases = """
449
- UNWIND $recoverable_databases_list as rec_db
450
- MERGE (rd:AzureRecoverableDatabase{id: rec_db.id})
451
- ON CREATE SET rd.firstseen = timestamp()
452
- SET rd.name = rec_db.name,
453
- rd.edition = rec_db.edition,
454
- rd.servicelevelobjective = rec_db.service_level_objective,
455
- rd.lastbackupdate = rec_db.last_available_backup_date,
456
- rd.lastupdated = $azure_update_tag
457
- WITH rd, rec_db
458
- MATCH (s:AzureSQLServer{id: rec_db.server_id})
459
- MERGE (s)-[r:RESOURCE]->(rd)
460
- ON CREATE SET r.firstseen = timestamp()
461
- SET r.lastupdated = $azure_update_tag
462
- """
463
-
464
- neo4j_session.run(
465
- ingest_recoverable_databases,
466
- recoverable_databases_list=recoverable_databases,
467
- azure_update_tag=update_tag,
537
+ load(
538
+ neo4j_session,
539
+ AzureRecoverableDatabaseSchema(),
540
+ recoverable_databases,
541
+ lastupdated=update_tag,
542
+ AZURE_SUBSCRIPTION_ID=subscription_id,
468
543
  )
469
544
 
470
545
 
471
546
  @timeit
472
547
  def _load_restorable_dropped_databases(
473
- neo4j_session: neo4j.Session, restorable_dropped_databases: List[Dict], update_tag: int,
548
+ neo4j_session: neo4j.Session,
549
+ restorable_dropped_databases: List[Dict],
550
+ subscription_id: str,
551
+ update_tag: int,
474
552
  ) -> None:
475
553
  """
476
554
  Ingest the restorable dropped database details into neo4j.
477
555
  """
478
- ingest_restorable_dropped_databases = """
479
- UNWIND $restorable_dropped_databases_list as res_dropped_db
480
- MERGE (rdd:AzureRestorableDroppedDatabase{id: res_dropped_db.id})
481
- ON CREATE SET rdd.firstseen = timestamp(), rdd.location = res_dropped_db.location
482
- SET rdd.name = res_dropped_db.name,
483
- rdd.databasename = res_dropped_db.database_name,
484
- rdd.creationdate = res_dropped_db.creation_date,
485
- rdd.deletiondate = res_dropped_db.deletion_date,
486
- rdd.restoredate = res_dropped_db.earliest_restore_date,
487
- rdd.edition = res_dropped_db.edition,
488
- rdd.servicelevelobjective = res_dropped_db.service_level_objective,
489
- rdd.maxsizebytes = res_dropped_db.max_size_bytes,
490
- rdd.lastupdated = $azure_update_tag
491
- WITH rdd, res_dropped_db
492
- MATCH (s:AzureSQLServer{id: res_dropped_db.server_id})
493
- MERGE (s)-[r:RESOURCE]->(rdd)
494
- ON CREATE SET r.firstseen = timestamp()
495
- SET r.lastupdated = $azure_update_tag
496
- """
497
-
498
- neo4j_session.run(
499
- ingest_restorable_dropped_databases,
500
- restorable_dropped_databases_list=restorable_dropped_databases,
501
- azure_update_tag=update_tag,
556
+ load(
557
+ neo4j_session,
558
+ AzureRestorableDroppedDatabaseSchema(),
559
+ restorable_dropped_databases,
560
+ lastupdated=update_tag,
561
+ AZURE_SUBSCRIPTION_ID=subscription_id,
502
562
  )
503
563
 
504
564
 
505
565
  @timeit
506
566
  def _load_failover_groups(
507
- neo4j_session: neo4j.Session, failover_groups: List[Dict], update_tag: int,
567
+ neo4j_session: neo4j.Session,
568
+ failover_groups: List[Dict],
569
+ subscription_id: str,
570
+ update_tag: int,
508
571
  ) -> None:
509
572
  """
510
573
  Ingest the failover groups details into neo4j.
511
574
  """
512
- ingest_failover_groups = """
513
- UNWIND $failover_groups_list as fg
514
- MERGE (f:AzureFailoverGroup{id: fg.id})
515
- ON CREATE SET f.firstseen = timestamp(), f.location = fg.location
516
- SET f.name = fg.name,
517
- f.replicationrole = fg.replication_role,
518
- f.replicationstate = fg.replication_state,
519
- f.lastupdated = $azure_update_tag
520
- WITH f, fg
521
- MATCH (s:AzureSQLServer{id: fg.server_id})
522
- MERGE (s)-[r:RESOURCE]->(f)
523
- ON CREATE SET r.firstseen = timestamp()
524
- SET r.lastupdated = $azure_update_tag
525
- """
526
-
527
- neo4j_session.run(
528
- ingest_failover_groups,
529
- failover_groups_list=failover_groups,
530
- azure_update_tag=update_tag,
575
+ load(
576
+ neo4j_session,
577
+ AzureFailoverGroupSchema(),
578
+ failover_groups,
579
+ lastupdated=update_tag,
580
+ AZURE_SUBSCRIPTION_ID=subscription_id,
531
581
  )
532
582
 
533
583
 
534
584
  @timeit
535
585
  def _load_elastic_pools(
536
- neo4j_session: neo4j.Session, elastic_pools: List[Dict], update_tag: int,
586
+ neo4j_session: neo4j.Session,
587
+ elastic_pools: List[Dict],
588
+ subscription_id: str,
589
+ update_tag: int,
537
590
  ) -> None:
538
591
  """
539
592
  Ingest the elastic pool details into neo4j.
540
593
  """
541
- ingest_elastic_pools = """
542
- UNWIND $elastic_pools_list as ep
543
- MERGE (e:AzureElasticPool{id: ep.id})
544
- ON CREATE SET e.firstseen = timestamp(), e.location = ep.location
545
- SET e.name = ep.name,
546
- e.kind = ep.kind,
547
- e.creationdate = ep.creation_date,
548
- e.state = ep.state,
549
- e.maxsizebytes = ep.max_size_bytes,
550
- e.licensetype = ep.license_type,
551
- e.zoneredundant = ep.zone_redundant,
552
- e.lastupdated = $azure_update_tag
553
- WITH e, ep
554
- MATCH (s:AzureSQLServer{id: ep.server_id})
555
- MERGE (s)-[r:RESOURCE]->(e)
556
- ON CREATE SET r.firstseen = timestamp()
557
- SET r.lastupdated = $azure_update_tag
558
- """
559
-
560
- neo4j_session.run(
561
- ingest_elastic_pools,
562
- elastic_pools_list=elastic_pools,
563
- azure_update_tag=update_tag,
594
+ load(
595
+ neo4j_session,
596
+ AzureElasticPoolSchema(),
597
+ elastic_pools,
598
+ lastupdated=update_tag,
599
+ AZURE_SUBSCRIPTION_ID=subscription_id,
564
600
  )
565
601
 
566
602
 
567
603
  @timeit
568
604
  def _load_databases(
569
- neo4j_session: neo4j.Session, databases: List[Dict], update_tag: int,
605
+ neo4j_session: neo4j.Session,
606
+ databases: List[Dict],
607
+ subscription_id: str,
608
+ update_tag: int,
570
609
  ) -> None:
571
610
  """
572
611
  Ingest the database details into neo4j.
573
612
  """
574
- ingest_databases = """
575
- UNWIND $databases_list as az_database
576
- MERGE (d:AzureSQLDatabase{id: az_database.id})
577
- ON CREATE SET d.firstseen = timestamp(), d.location = az_database.location
578
- SET d.name = az_database.name,
579
- d.kind = az_database.kind,
580
- d.creationdate = az_database.creation_date,
581
- d.databaseid = az_database.database_id,
582
- d.maxsizebytes = az_database.max_size_bytes,
583
- d.licensetype = az_database.license_type,
584
- d.secondarylocation = az_database.default_secondary_location,
585
- d.elasticpoolid = az_database.elastic_pool_id,
586
- d.collation = az_database.collation,
587
- d.failovergroupid = az_database.failover_group_id,
588
- d.zoneredundant = az_database.zone_redundant,
589
- d.restorabledroppeddbid = az_database.restorable_dropped_database_id,
590
- d.recoverabledbid = az_database.recoverable_database_id,
591
- d.lastupdated = $azure_update_tag
592
- WITH d, az_database
593
- MATCH (s:AzureSQLServer{id: az_database.server_id})
594
- MERGE (s)-[r:RESOURCE]->(d)
595
- ON CREATE SET r.firstseen = timestamp()
596
- SET r.lastupdated = $azure_update_tag
597
- """
598
-
599
- neo4j_session.run(
600
- ingest_databases,
601
- databases_list=databases,
602
- azure_update_tag=update_tag,
613
+ load(
614
+ neo4j_session,
615
+ AzureSQLDatabaseSchema(),
616
+ databases,
617
+ lastupdated=update_tag,
618
+ AZURE_SUBSCRIPTION_ID=subscription_id,
603
619
  )
604
620
 
605
621
 
606
622
  @timeit
607
623
  def sync_database_details(
608
- neo4j_session: neo4j.Session, credentials: Credentials,
609
- subscription_id: str, databases: List[Dict], update_tag: int,
624
+ neo4j_session: neo4j.Session,
625
+ credentials: Credentials,
626
+ subscription_id: str,
627
+ databases: List[Dict],
628
+ update_tag: int,
610
629
  ) -> None:
611
630
  db_details = get_database_details(credentials, subscription_id, databases)
612
- load_database_details(neo4j_session, db_details, update_tag) # type: ignore
631
+ load_database_details(neo4j_session, db_details, subscription_id, update_tag) # type: ignore
613
632
 
614
633
 
615
634
  @timeit
616
635
  def get_database_details(
617
- credentials: Credentials, subscription_id: str, databases: List[Dict],
636
+ credentials: Credentials,
637
+ subscription_id: str,
638
+ databases: List[Dict],
618
639
  ) -> Generator[Any, Any, Any]:
619
640
  """
620
641
  Iterate over the databases to get the details of resources in it.
621
642
  """
622
643
  for database in databases:
623
- replication_links = get_replication_links(credentials, subscription_id, database)
624
- db_threat_detection_policies = get_db_threat_detection_policies(credentials, subscription_id, database)
644
+ replication_links = get_replication_links(
645
+ credentials,
646
+ subscription_id,
647
+ database,
648
+ )
649
+ db_threat_detection_policies = get_db_threat_detection_policies(
650
+ credentials,
651
+ subscription_id,
652
+ database,
653
+ )
625
654
  restore_points = get_restore_points(credentials, subscription_id, database)
626
- transparent_data_encryptions = get_transparent_data_encryptions(credentials, subscription_id, database)
655
+ transparent_data_encryptions = get_transparent_data_encryptions(
656
+ credentials,
657
+ subscription_id,
658
+ database,
659
+ )
627
660
  yield database[
628
- 'id'
661
+ "id"
629
662
  ], replication_links, db_threat_detection_policies, restore_points, transparent_data_encryptions
630
663
 
631
664
 
632
665
  @timeit
633
- def get_replication_links(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
666
+ def get_replication_links(
667
+ credentials: Credentials,
668
+ subscription_id: str,
669
+ database: Dict,
670
+ ) -> List[Dict]:
634
671
  """
635
672
  Returns the details of replication links in a database.
636
673
  """
@@ -640,15 +677,17 @@ def get_replication_links(credentials: Credentials, subscription_id: str, databa
640
677
  map(
641
678
  lambda x: x.as_dict(),
642
679
  client.replication_links.list_by_database(
643
- database['resource_group_name'],
644
- database['server_name'],
645
- database['name'],
680
+ database["resource_group_name"],
681
+ database["server_name"],
682
+ database["name"],
646
683
  ),
647
684
  ),
648
685
  )
649
686
 
650
687
  except ClientAuthenticationError as e:
651
- logger.warning(f"Client Authentication Error while retrieving replication links - {e}")
688
+ logger.warning(
689
+ f"Client Authentication Error while retrieving replication links - {e}",
690
+ )
652
691
  return []
653
692
  except ResourceNotFoundError as e:
654
693
  logger.warning(f"Replication links resource not found error - {e}")
@@ -661,33 +700,45 @@ def get_replication_links(credentials: Credentials, subscription_id: str, databa
661
700
 
662
701
 
663
702
  @timeit
664
- def get_db_threat_detection_policies(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
703
+ def get_db_threat_detection_policies(
704
+ credentials: Credentials,
705
+ subscription_id: str,
706
+ database: Dict,
707
+ ) -> List[Dict]:
665
708
  """
666
709
  Returns the threat detection policy of a database.
667
710
  """
668
711
  try:
669
712
  client = get_client(credentials, subscription_id)
670
713
  db_threat_detection_policies = client.database_threat_detection_policies.get(
671
- database['resource_group_name'],
672
- database['server_name'],
673
- database['name'],
714
+ database["resource_group_name"],
715
+ database["server_name"],
716
+ database["name"],
674
717
  SecurityAlertPolicyName.DEFAULT,
675
718
  ).as_dict()
676
719
  except ClientAuthenticationError as e:
677
- logger.warning(f"Client Authentication Error while retrieving threat detection policy - {e}")
720
+ logger.warning(
721
+ f"Client Authentication Error while retrieving threat detection policy - {e}",
722
+ )
678
723
  return []
679
724
  except ResourceNotFoundError as e:
680
725
  logger.warning(f"Threat detection policy resource not found error - {e}")
681
726
  return []
682
727
  except HttpResponseError as e:
683
- logger.warning(f"Error while retrieving database threat detection policies - {e}")
728
+ logger.warning(
729
+ f"Error while retrieving database threat detection policies - {e}",
730
+ )
684
731
  return []
685
732
 
686
733
  return db_threat_detection_policies
687
734
 
688
735
 
689
736
  @timeit
690
- def get_restore_points(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
737
+ def get_restore_points(
738
+ credentials: Credentials,
739
+ subscription_id: str,
740
+ database: Dict,
741
+ ) -> List[Dict]:
691
742
  """
692
743
  Returns the details of restore points in a database.
693
744
  """
@@ -697,15 +748,17 @@ def get_restore_points(credentials: Credentials, subscription_id: str, database:
697
748
  map(
698
749
  lambda x: x.as_dict(),
699
750
  client.restore_points.list_by_database(
700
- database['resource_group_name'],
701
- database['server_name'],
702
- database['name'],
751
+ database["resource_group_name"],
752
+ database["server_name"],
753
+ database["name"],
703
754
  ),
704
755
  ),
705
756
  )
706
757
 
707
758
  except ClientAuthenticationError as e:
708
- logger.warning(f"Client Authentication Error while retrieving restore points - {e}")
759
+ logger.warning(
760
+ f"Client Authentication Error while retrieving restore points - {e}",
761
+ )
709
762
  return []
710
763
  except ResourceNotFoundError as e:
711
764
  logger.warning(f"Restore points resource not found error - {e}")
@@ -718,20 +771,26 @@ def get_restore_points(credentials: Credentials, subscription_id: str, database:
718
771
 
719
772
 
720
773
  @timeit
721
- def get_transparent_data_encryptions(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
774
+ def get_transparent_data_encryptions(
775
+ credentials: Credentials,
776
+ subscription_id: str,
777
+ database: Dict,
778
+ ) -> List[Dict]:
722
779
  """
723
780
  Returns the details of transparent data encryptions in a database.
724
781
  """
725
782
  try:
726
783
  client = get_client(credentials, subscription_id)
727
784
  transparent_data_encryptions_list = client.transparent_data_encryptions.get(
728
- database['resource_group_name'],
729
- database['server_name'],
730
- database['name'],
785
+ database["resource_group_name"],
786
+ database["server_name"],
787
+ database["name"],
731
788
  TransparentDataEncryptionName.CURRENT,
732
789
  ).as_dict()
733
790
  except ClientAuthenticationError as e:
734
- logger.warning(f"Client Authentication Error while retrieving transparent data encryptions - {e}")
791
+ logger.warning(
792
+ f"Client Authentication Error while retrieving transparent data encryptions - {e}",
793
+ )
735
794
  return []
736
795
  except ResourceNotFoundError as e:
737
796
  logger.warning(f"Transparent data encryptions resource not found error - {e}")
@@ -745,7 +804,10 @@ def get_transparent_data_encryptions(credentials: Credentials, subscription_id:
745
804
 
746
805
  @timeit
747
806
  def load_database_details(
748
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any, Any, Any, Any]], update_tag: int,
807
+ neo4j_session: neo4j.Session,
808
+ details: List[Tuple[Any, Any, Any, Any, Any]],
809
+ subscription_id: str,
810
+ update_tag: int,
749
811
  ) -> None:
750
812
  """
751
813
  Create dictionaries for every resource in a database so we can import them in a single query
@@ -755,180 +817,162 @@ def load_database_details(
755
817
  restore_points = []
756
818
  encryptions_list = []
757
819
 
758
- for databaseId, replication_link, db_threat_detection_policy, restore_point, transparent_data_encryption in details:
820
+ for (
821
+ databaseId,
822
+ replication_link,
823
+ db_threat_detection_policy,
824
+ restore_point,
825
+ transparent_data_encryption,
826
+ ) in details:
759
827
  if len(replication_link) > 0:
760
828
  for link in replication_link:
761
- link['database_id'] = databaseId
829
+ link["database_id"] = databaseId
762
830
  replication_links.append(link)
763
831
 
764
832
  if len(db_threat_detection_policy) > 0:
765
- db_threat_detection_policy['database_id'] = databaseId
833
+ db_threat_detection_policy["database_id"] = databaseId
766
834
  threat_detection_policies.append(db_threat_detection_policy)
767
835
 
768
836
  if len(restore_point) > 0:
769
837
  for point in restore_point:
770
- point['database_id'] = databaseId
838
+ point["database_id"] = databaseId
771
839
  restore_points.append(point)
772
840
 
773
841
  if len(transparent_data_encryption) > 0:
774
- transparent_data_encryption['database_id'] = databaseId
842
+ transparent_data_encryption["database_id"] = databaseId
775
843
  encryptions_list.append(transparent_data_encryption)
776
844
 
777
- _load_replication_links(neo4j_session, replication_links, update_tag)
778
- _load_db_threat_detection_policies(neo4j_session, threat_detection_policies, update_tag)
779
- _load_restore_points(neo4j_session, restore_points, update_tag)
780
- _load_transparent_data_encryptions(neo4j_session, encryptions_list, update_tag)
845
+ _load_replication_links(
846
+ neo4j_session, replication_links, subscription_id, update_tag
847
+ )
848
+ _load_db_threat_detection_policies(
849
+ neo4j_session,
850
+ threat_detection_policies,
851
+ subscription_id,
852
+ update_tag,
853
+ )
854
+ _load_restore_points(neo4j_session, restore_points, subscription_id, update_tag)
855
+ _load_transparent_data_encryptions(
856
+ neo4j_session, encryptions_list, subscription_id, update_tag
857
+ )
781
858
 
782
859
 
783
860
  @timeit
784
861
  def _load_replication_links(
785
- neo4j_session: neo4j.Session, replication_links: List[Dict], update_tag: int,
862
+ neo4j_session: neo4j.Session,
863
+ replication_links: List[Dict],
864
+ subscription_id: str,
865
+ update_tag: int,
786
866
  ) -> None:
787
867
  """
788
868
  Ingest replication links into neo4j.
789
869
  """
790
- ingest_replication_links = """
791
- UNWIND $replication_links_list as replication_link
792
- MERGE (rl:AzureReplicationLink{id: replication_link.id})
793
- ON CREATE SET rl.firstseen = timestamp(),
794
- rl.location = replication_link.location
795
- SET rl.name = replication_link.name,
796
- rl.partnerdatabase = replication_link.partner_database,
797
- rl.partnerlocation = replication_link.partner_location,
798
- rl.partnerrole = replication_link.partner_role,
799
- rl.partnerserver = replication_link.partner_server,
800
- rl.mode = replication_link.replication_mode,
801
- rl.state = replication_link.replication_state,
802
- rl.percentcomplete = replication_link.percent_complete,
803
- rl.role = replication_link.role,
804
- rl.starttime = replication_link.start_time,
805
- rl.terminationallowed = replication_link.is_termination_allowed,
806
- rl.lastupdated = $azure_update_tag
807
- WITH rl, replication_link
808
- MATCH (d:AzureSQLDatabase{id: replication_link.database_id})
809
- MERGE (d)-[r:CONTAINS]->(rl)
810
- ON CREATE SET r.firstseen = timestamp()
811
- SET r.lastupdated = $azure_update_tag
812
- """
813
-
814
- neo4j_session.run(
815
- ingest_replication_links,
816
- replication_links_list=replication_links,
817
- azure_update_tag=update_tag,
870
+ load(
871
+ neo4j_session,
872
+ AzureReplicationLinkSchema(),
873
+ replication_links,
874
+ lastupdated=update_tag,
875
+ AZURE_SUBSCRIPTION_ID=subscription_id,
818
876
  )
819
877
 
820
878
 
821
879
  @timeit
822
880
  def _load_db_threat_detection_policies(
823
- neo4j_session: neo4j.Session, threat_detection_policies: List[Dict], update_tag: int,
881
+ neo4j_session: neo4j.Session,
882
+ threat_detection_policies: List[Dict],
883
+ subscription_id: str,
884
+ update_tag: int,
824
885
  ) -> None:
825
886
  """
826
887
  Ingest threat detection policy into neo4j.
827
888
  """
828
- ingest_threat_detection_policies = """
829
- UNWIND $threat_detection_policies_list as tdp
830
- MERGE (policy:AzureDatabaseThreatDetectionPolicy{id: tdp.id})
831
- ON CREATE SET policy.firstseen = timestamp(),
832
- policy.location = tdp.location
833
- SET policy.name = tdp.name,
834
- policy.location = tdp.location,
835
- policy.kind = tdp.kind,
836
- policy.emailadmins = tdp.email_account_admins,
837
- policy.emailaddresses = tdp.email_addresses,
838
- policy.retentiondays = tdp.retention_days,
839
- policy.state = tdp.state,
840
- policy.storageendpoint = tdp.storage_endpoint,
841
- policy.useserverdefault = tdp.use_server_default,
842
- policy.disabledalerts = tdp.disabled_alerts,
843
- policy.lastupdated = $azure_update_tag
844
- WITH policy, tdp
845
- MATCH (d:AzureSQLDatabase{id: tdp.database_id})
846
- MERGE (d)-[r:CONTAINS]->(policy)
847
- ON CREATE SET r.firstseen = timestamp()
848
- SET r.lastupdated = $azure_update_tag
849
- """
850
-
851
- neo4j_session.run(
852
- ingest_threat_detection_policies,
853
- threat_detection_policies_list=threat_detection_policies,
854
- azure_update_tag=update_tag,
889
+ load(
890
+ neo4j_session,
891
+ AzureDatabaseThreatDetectionPolicySchema(),
892
+ threat_detection_policies,
893
+ lastupdated=update_tag,
894
+ AZURE_SUBSCRIPTION_ID=subscription_id,
855
895
  )
856
896
 
857
897
 
858
898
  @timeit
859
899
  def _load_restore_points(
860
- neo4j_session: neo4j.Session, restore_points: List[Dict], update_tag: int,
900
+ neo4j_session: neo4j.Session,
901
+ restore_points: List[Dict],
902
+ subscription_id: str,
903
+ update_tag: int,
861
904
  ) -> None:
862
905
  """
863
906
  Ingest restore points into neo4j.
864
907
  """
865
- ingest_restore_points = """
866
- UNWIND $restore_points_list as rp
867
- MERGE (point:AzureRestorePoint{id: rp.id})
868
- ON CREATE SET point.firstseen = timestamp(),
869
- point.location = rp.location
870
- SET point.name = rp.name,
871
- point.restoredate = rp.earliest_restore_date,
872
- point.restorepointtype = rp.restore_point_type,
873
- point.creationdate = rp.restore_point_creation_date,
874
- point.lastupdated = $azure_update_tag
875
- WITH point, rp
876
- MATCH (d:AzureSQLDatabase{id: rp.database_id})
877
- MERGE (d)-[r:CONTAINS]->(point)
878
- ON CREATE SET r.firstseen = timestamp()
879
- SET r.lastupdated = $azure_update_tag
880
- """
881
-
882
- neo4j_session.run(
883
- ingest_restore_points,
884
- restore_points_list=restore_points,
885
- azure_update_tag=update_tag,
908
+ load(
909
+ neo4j_session,
910
+ AzureRestorePointSchema(),
911
+ restore_points,
912
+ lastupdated=update_tag,
913
+ AZURE_SUBSCRIPTION_ID=subscription_id,
886
914
  )
887
915
 
888
916
 
889
917
  @timeit
890
918
  def _load_transparent_data_encryptions(
891
- neo4j_session: neo4j.Session, encryptions_list: List[Dict], update_tag: int,
919
+ neo4j_session: neo4j.Session,
920
+ encryptions_list: List[Dict],
921
+ subscription_id: str,
922
+ update_tag: int,
892
923
  ) -> None:
893
924
  """
894
925
  Ingest transparent data encryptions into neo4j.
895
926
  """
896
- ingest_data_encryptions = """
897
- UNWIND $transparent_data_encryptions_list as e
898
- MERGE (tae:AzureTransparentDataEncryption{id: e.id})
899
- ON CREATE SET tae.firstseen = timestamp(),
900
- tae.location = e.location
901
- SET tae.name = e.name,
902
- tae.status = e.status,
903
- tae.lastupdated = $azure_update_tag
904
- WITH tae, e
905
- MATCH (d:AzureSQLDatabase{id: e.database_id})
906
- MERGE (d)-[r:CONTAINS]->(tae)
907
- ON CREATE SET r.firstseen = timestamp()
908
- SET r.lastupdated = $azure_update_tag
909
- """
910
-
911
- neo4j_session.run(
912
- ingest_data_encryptions,
913
- transparent_data_encryptions_list=encryptions_list,
914
- azure_update_tag=update_tag,
927
+ load(
928
+ neo4j_session,
929
+ AzureTransparentDataEncryptionSchema(),
930
+ encryptions_list,
931
+ lastupdated=update_tag,
932
+ AZURE_SUBSCRIPTION_ID=subscription_id,
915
933
  )
916
934
 
917
935
 
918
936
  @timeit
919
937
  def cleanup_azure_sql_servers(
920
- neo4j_session: neo4j.Session, common_job_parameters: Dict,
938
+ neo4j_session: neo4j.Session,
939
+ common_job_parameters: Dict,
921
940
  ) -> None:
922
- run_cleanup_job('azure_sql_server_cleanup.json', neo4j_session, common_job_parameters)
941
+ for node in [
942
+ AzureSQLServerSchema,
943
+ AzureServerDNSAliasSchema,
944
+ AzureServerADAdministratorSchema,
945
+ AzureReplicationLinkSchema,
946
+ AzureRestorePointSchema,
947
+ AzureTransparentDataEncryptionSchema,
948
+ AzureDatabaseThreatDetectionPolicySchema,
949
+ AzureSQLDatabaseSchema,
950
+ AzureElasticPoolSchema,
951
+ AzureFailoverGroupSchema,
952
+ AzureRecoverableDatabaseSchema,
953
+ AzureRestorableDroppedDatabaseSchema,
954
+ ]:
955
+ GraphJob.from_node_schema(node(), common_job_parameters).run(
956
+ neo4j_session,
957
+ )
923
958
 
924
959
 
925
960
  @timeit
926
961
  def sync(
927
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
928
- sync_tag: int, common_job_parameters: Dict,
962
+ neo4j_session: neo4j.Session,
963
+ credentials: Credentials,
964
+ subscription_id: str,
965
+ sync_tag: int,
966
+ common_job_parameters: Dict,
929
967
  ) -> None:
930
968
  logger.info("Syncing Azure SQL for subscription '%s'.", subscription_id)
931
969
  server_list = get_server_list(credentials, subscription_id)
932
970
  load_server_data(neo4j_session, subscription_id, server_list, sync_tag)
933
- sync_server_details(neo4j_session, credentials, subscription_id, server_list, sync_tag)
971
+ sync_server_details(
972
+ neo4j_session,
973
+ credentials,
974
+ subscription_id,
975
+ server_list,
976
+ sync_tag,
977
+ )
934
978
  cleanup_azure_sql_servers(neo4j_session, common_job_parameters)