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
@@ -11,15 +11,33 @@ from azure.core.exceptions import HttpResponseError
11
11
  from azure.core.exceptions import ResourceNotFoundError
12
12
  from azure.mgmt.storage import StorageManagementClient
13
13
 
14
- from .util.credentials import Credentials
15
- from cartography.util import run_cleanup_job
14
+ from cartography.client.core.tx import load
15
+ from cartography.graph.job import GraphJob
16
+ from cartography.models.azure.storage.account import AzureStorageAccountSchema
17
+ from cartography.models.azure.storage.blobcontainer import (
18
+ AzureStorageBlobContainerSchema,
19
+ )
20
+ from cartography.models.azure.storage.blobservice import AzureStorageBlobServiceSchema
21
+ from cartography.models.azure.storage.fileservice import AzureStorageFileServiceSchema
22
+ from cartography.models.azure.storage.fileshare import AzureStorageFileShareSchema
23
+ from cartography.models.azure.storage.queue import AzureStorageQueueSchema
24
+ from cartography.models.azure.storage.queueservice import AzureStorageQueueServiceSchema
25
+ from cartography.models.azure.storage.table import AzureStorageTableSchema
26
+ from cartography.models.azure.storage.tableservice import AzureStorageTableServiceSchema
27
+ from cartography.models.azure.tags.storage_tag import AzureStorageTagsSchema
16
28
  from cartography.util import timeit
17
29
 
30
+ from .util.credentials import Credentials
31
+ from .util.tag import transform_tags
32
+
18
33
  logger = logging.getLogger(__name__)
19
34
 
20
35
 
21
36
  @timeit
22
- def get_client(credentials: Credentials, subscription_id: str) -> StorageManagementClient:
37
+ def get_client(
38
+ credentials: Credentials,
39
+ subscription_id: str,
40
+ ) -> StorageManagementClient:
23
41
  """
24
42
  Getting the Azure Storage client
25
43
  """
@@ -28,17 +46,24 @@ def get_client(credentials: Credentials, subscription_id: str) -> StorageManagem
28
46
 
29
47
 
30
48
  @timeit
31
- def get_storage_account_list(credentials: Credentials, subscription_id: str) -> List[Dict]:
49
+ def get_storage_account_list(
50
+ credentials: Credentials,
51
+ subscription_id: str,
52
+ ) -> List[Dict]:
32
53
  """
33
54
  Getting the list of storage accounts
34
55
  """
35
56
  try:
36
57
  client = get_client(credentials, subscription_id)
37
- storage_account_list = list(map(lambda x: x.as_dict(), client.storage_accounts.list()))
58
+ storage_account_list = list(
59
+ map(lambda x: x.as_dict(), client.storage_accounts.list()),
60
+ )
38
61
 
39
62
  # ClientAuthenticationError and ResourceNotFoundError are subclasses under HttpResponseError
40
63
  except ClientAuthenticationError as e:
41
- logger.warning(f"Client Authentication Error while retrieving storage accounts - {e}")
64
+ logger.warning(
65
+ f"Client Authentication Error while retrieving storage accounts - {e}",
66
+ )
42
67
  return []
43
68
  except ResourceNotFoundError as e:
44
69
  logger.warning(f"Storage Account not found error - {e}")
@@ -48,91 +73,151 @@ def get_storage_account_list(credentials: Credentials, subscription_id: str) ->
48
73
  return []
49
74
 
50
75
  for storage_account in storage_account_list:
51
- x = storage_account['id'].split('/')
52
- storage_account['resourceGroup'] = x[x.index('resourceGroups') + 1]
76
+ x = storage_account["id"].split("/")
77
+ storage_account["resourceGroup"] = x[x.index("resourceGroups") + 1]
53
78
 
54
79
  return storage_account_list
55
80
 
56
81
 
57
82
  @timeit
58
83
  def load_storage_account_data(
59
- neo4j_session: neo4j.Session, subscription_id: str, storage_account_list: List[Dict],
60
- azure_update_tag: int,
84
+ neo4j_session: neo4j.Session,
85
+ subscription_id: str,
86
+ storage_account_list: List[Dict],
87
+ azure_update_tag: int,
88
+ ) -> None:
89
+ load(
90
+ neo4j_session,
91
+ AzureStorageAccountSchema(),
92
+ storage_account_list,
93
+ lastupdated=azure_update_tag,
94
+ AZURE_SUBSCRIPTION_ID=subscription_id,
95
+ )
96
+
97
+
98
+ @timeit
99
+ def load_storage_tags(
100
+ neo4j_session: neo4j.Session,
101
+ subscription_id: str,
102
+ storage_accounts: List[Dict],
103
+ update_tag: int,
61
104
  ) -> None:
62
105
  """
63
- Ingest Storage Account details into neo4j.
64
- """
65
- ingest_storage_account = """
66
- UNWIND $storage_accounts_list as account
67
- MERGE (s:AzureStorageAccount{id: account.id})
68
- ON CREATE SET s.firstseen = timestamp(),
69
- s.type = account.type, s.resourcegroup = account.resourceGroup,
70
- s.location = account.location
71
- SET s.lastupdated = $azure_update_tag,
72
- s.kind = account.kind,
73
- s.name = account.name,
74
- s.creationtime = account.creation_time,
75
- s.hnsenabled = account.is_hns_enabled,
76
- s.primarylocation = account.primary_location,
77
- s.secondarylocation = account.secondary_location,
78
- s.provisioningstate = account.provisioning_state,
79
- s.statusofprimary = account.status_of_primary,
80
- s.statusofsecondary = account.status_of_secondary,
81
- s.supportshttpstrafficonly = account.enable_https_traffic_only
82
- WITH s
83
- MATCH (owner:AzureSubscription{id: $AZURE_SUBSCRIPTION_ID})
84
- MERGE (owner)-[r:RESOURCE]->(s)
85
- ON CREATE SET r.firstseen = timestamp()
86
- SET r.lastupdated = $azure_update_tag
87
- """
88
-
89
- neo4j_session.run(
90
- ingest_storage_account,
91
- storage_accounts_list=storage_account_list,
106
+ Sync tags for storage accounts.
107
+ """
108
+ tags = transform_tags(storage_accounts, subscription_id)
109
+ load(
110
+ neo4j_session,
111
+ AzureStorageTagsSchema(),
112
+ tags,
113
+ lastupdated=update_tag,
92
114
  AZURE_SUBSCRIPTION_ID=subscription_id,
93
- azure_update_tag=azure_update_tag,
94
115
  )
95
116
 
96
117
 
97
118
  @timeit
98
119
  def sync_storage_account_details(
99
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
100
- storage_account_list: List[Dict], sync_tag: int,
120
+ neo4j_session: neo4j.Session,
121
+ credentials: Credentials,
122
+ subscription_id: str,
123
+ storage_account_list: List[Dict],
124
+ sync_tag: int,
101
125
  ) -> None:
102
- details = get_storage_account_details(credentials, subscription_id, storage_account_list)
103
- load_storage_account_details(neo4j_session, credentials, subscription_id, details, sync_tag)
126
+ # Get details
127
+ details = get_storage_account_details(
128
+ credentials,
129
+ subscription_id,
130
+ storage_account_list,
131
+ )
132
+ # Transform details
133
+ queue_services, table_services, file_services, blob_services = (
134
+ transform_storage_account_details(
135
+ details,
136
+ )
137
+ )
138
+ # Load details
139
+ _load_queue_services(neo4j_session, queue_services, subscription_id, sync_tag)
140
+ _load_table_services(neo4j_session, table_services, subscription_id, sync_tag)
141
+ _load_file_services(neo4j_session, file_services, subscription_id, sync_tag)
142
+ _load_blob_services(neo4j_session, blob_services, subscription_id, sync_tag)
143
+
144
+ sync_queue_services_details(
145
+ neo4j_session,
146
+ credentials,
147
+ subscription_id,
148
+ queue_services,
149
+ sync_tag,
150
+ )
151
+ sync_table_services_details(
152
+ neo4j_session,
153
+ credentials,
154
+ subscription_id,
155
+ table_services,
156
+ sync_tag,
157
+ )
158
+ sync_file_services_details(
159
+ neo4j_session,
160
+ credentials,
161
+ subscription_id,
162
+ file_services,
163
+ sync_tag,
164
+ )
165
+ sync_blob_services_details(
166
+ neo4j_session,
167
+ credentials,
168
+ subscription_id,
169
+ blob_services,
170
+ sync_tag,
171
+ )
104
172
 
105
173
 
106
174
  @timeit
107
175
  def get_storage_account_details(
108
- credentials: Credentials, subscription_id: str, storage_account_list: List[Dict],
176
+ credentials: Credentials,
177
+ subscription_id: str,
178
+ storage_account_list: List[Dict],
109
179
  ) -> Generator[Any, Any, Any]:
110
180
  """
111
181
  Iterates over all Storage Accounts to get the different storage services.
112
182
  """
113
183
  for storage_account in storage_account_list:
114
- queue_services = get_queue_services(credentials, subscription_id, storage_account)
115
- table_services = get_table_services(credentials, subscription_id, storage_account)
184
+ queue_services = get_queue_services(
185
+ credentials,
186
+ subscription_id,
187
+ storage_account,
188
+ )
189
+ table_services = get_table_services(
190
+ credentials,
191
+ subscription_id,
192
+ storage_account,
193
+ )
116
194
  file_services = get_file_services(credentials, subscription_id, storage_account)
117
195
  blob_services = get_blob_services(credentials, subscription_id, storage_account)
118
- yield storage_account['id'], storage_account['name'], storage_account[
119
- 'resourceGroup'
196
+ yield storage_account["id"], storage_account["name"], storage_account[
197
+ "resourceGroup"
120
198
  ], queue_services, table_services, file_services, blob_services
121
199
 
122
200
 
123
201
  @timeit
124
- def get_queue_services(credentials: Credentials, subscription_id: str, storage_account: Dict) -> List[Dict]:
202
+ def get_queue_services(
203
+ credentials: Credentials,
204
+ subscription_id: str,
205
+ storage_account: Dict,
206
+ ) -> List[Dict]:
125
207
  """
126
208
  Gets the list of queue services.
127
209
  """
128
210
  try:
129
211
  client = get_client(credentials, subscription_id)
130
212
  queue_service_list = client.queue_services.list(
131
- storage_account['resourceGroup'], storage_account['name'],
132
- ).as_dict()['value']
213
+ storage_account["resourceGroup"],
214
+ storage_account["name"],
215
+ ).as_dict()["value"]
133
216
 
134
217
  except ClientAuthenticationError as e:
135
- logger.warning(f"Client Authentication Error while retrieving queue services - {e}")
218
+ logger.warning(
219
+ f"Client Authentication Error while retrieving queue services - {e}",
220
+ )
136
221
  return []
137
222
  except ResourceNotFoundError as e:
138
223
  logger.warning(f"Queue services resource not found error - {e}")
@@ -145,18 +230,25 @@ def get_queue_services(credentials: Credentials, subscription_id: str, storage_a
145
230
 
146
231
 
147
232
  @timeit
148
- def get_table_services(credentials: Credentials, subscription_id: str, storage_account: Dict) -> List[Dict]:
233
+ def get_table_services(
234
+ credentials: Credentials,
235
+ subscription_id: str,
236
+ storage_account: Dict,
237
+ ) -> List[Dict]:
149
238
  """
150
239
  Gets the list of table services.
151
240
  """
152
241
  try:
153
242
  client = get_client(credentials, subscription_id)
154
243
  table_service_list = client.table_services.list(
155
- storage_account['resourceGroup'], storage_account['name'],
156
- ).as_dict()['value']
244
+ storage_account["resourceGroup"],
245
+ storage_account["name"],
246
+ ).as_dict()["value"]
157
247
 
158
248
  except ClientAuthenticationError as e:
159
- logger.warning(f"Client Authentication Error while retrieving table services - {e}")
249
+ logger.warning(
250
+ f"Client Authentication Error while retrieving table services - {e}",
251
+ )
160
252
  return []
161
253
  except ResourceNotFoundError as e:
162
254
  logger.warning(f"Table services resource not found error - {e}")
@@ -169,18 +261,25 @@ def get_table_services(credentials: Credentials, subscription_id: str, storage_a
169
261
 
170
262
 
171
263
  @timeit
172
- def get_file_services(credentials: Credentials, subscription_id: str, storage_account: Dict) -> List[Dict]:
264
+ def get_file_services(
265
+ credentials: Credentials,
266
+ subscription_id: str,
267
+ storage_account: Dict,
268
+ ) -> List[Dict]:
173
269
  """
174
270
  Gets the list of file services.
175
271
  """
176
272
  try:
177
273
  client = get_client(credentials, subscription_id)
178
274
  file_service_list = client.file_services.list(
179
- storage_account['resourceGroup'], storage_account['name'],
180
- ).as_dict()['value']
275
+ storage_account["resourceGroup"],
276
+ storage_account["name"],
277
+ ).as_dict()["value"]
181
278
 
182
279
  except ClientAuthenticationError as e:
183
- logger.warning(f"Client Authentication Error while retrieving file services - {e}")
280
+ logger.warning(
281
+ f"Client Authentication Error while retrieving file services - {e}",
282
+ )
184
283
  return []
185
284
  except ResourceNotFoundError as e:
186
285
  logger.warning(f"File services resource not found error - {e}")
@@ -193,7 +292,11 @@ def get_file_services(credentials: Credentials, subscription_id: str, storage_ac
193
292
 
194
293
 
195
294
  @timeit
196
- def get_blob_services(credentials: Credentials, subscription_id: str, storage_account: Dict) -> List[Dict]:
295
+ def get_blob_services(
296
+ credentials: Credentials,
297
+ subscription_id: str,
298
+ storage_account: Dict,
299
+ ) -> List[Dict]:
197
300
  """
198
301
  Gets the list of blob services.
199
302
  """
@@ -201,15 +304,18 @@ def get_blob_services(credentials: Credentials, subscription_id: str, storage_ac
201
304
  client = get_client(credentials, subscription_id)
202
305
  blob_service_list = list(
203
306
  map(
204
- lambda x: x.as_dict(), client.blob_services.list(
205
- storage_account['resourceGroup'],
206
- storage_account['name'],
307
+ lambda x: x.as_dict(),
308
+ client.blob_services.list(
309
+ storage_account["resourceGroup"],
310
+ storage_account["name"],
207
311
  ),
208
312
  ),
209
313
  )
210
314
 
211
315
  except ClientAuthenticationError as e:
212
- logger.warning(f"Client Authentication Error while retrieving blob services - {e}")
316
+ logger.warning(
317
+ f"Client Authentication Error while retrieving blob services - {e}",
318
+ )
213
319
  return []
214
320
  except ResourceNotFoundError as e:
215
321
  logger.warning(f"Blob services resource not found error - {e}")
@@ -222,189 +328,155 @@ def get_blob_services(credentials: Credentials, subscription_id: str, storage_ac
222
328
 
223
329
 
224
330
  @timeit
225
- def load_storage_account_details(
226
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
227
- details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]], update_tag: int,
228
- ) -> None:
229
- """
230
- Create dictionaries for every Azure storage service so we can import them in a single query
231
- """
331
+ def transform_storage_account_details(
332
+ storage_account_details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]],
333
+ ) -> Tuple[List[Dict], List[Dict], List[Dict], List[Dict]]:
232
334
  queue_services: List[Dict] = []
233
335
  table_services: List[Dict] = []
234
336
  file_services: List[Dict] = []
235
337
  blob_services: List[Dict] = []
236
338
 
237
- for account_id, name, resourceGroup, queue_service, table_service, file_service, blob_service in details:
339
+ for (
340
+ account_id,
341
+ name,
342
+ resourceGroup,
343
+ queue_service,
344
+ table_service,
345
+ file_service,
346
+ blob_service,
347
+ ) in storage_account_details:
238
348
  if len(queue_service) > 0:
239
349
  for service in queue_service:
240
- service['storage_account_name'] = name
241
- service['storage_account_id'] = account_id
242
- service['resource_group_name'] = resourceGroup
350
+ service["storage_account_name"] = name
351
+ service["storage_account_id"] = account_id
352
+ service["resource_group_name"] = resourceGroup
243
353
  queue_services.extend(queue_service)
244
354
 
245
355
  if len(table_service) > 0:
246
356
  for service in table_service:
247
- service['storage_account_name'] = name
248
- service['storage_account_id'] = account_id
249
- service['resource_group_name'] = resourceGroup
357
+ service["storage_account_name"] = name
358
+ service["storage_account_id"] = account_id
359
+ service["resource_group_name"] = resourceGroup
250
360
  table_services.extend(table_service)
251
361
 
252
362
  if len(file_service) > 0:
253
363
  for service in file_service:
254
- service['storage_account_name'] = name
255
- service['storage_account_id'] = account_id
256
- service['resource_group_name'] = resourceGroup
364
+ service["storage_account_name"] = name
365
+ service["storage_account_id"] = account_id
366
+ service["resource_group_name"] = resourceGroup
257
367
  file_services.extend(file_service)
258
368
 
259
369
  if len(blob_service) > 0:
260
370
  for service in blob_service:
261
- service['storage_account_name'] = name
262
- service['storage_account_id'] = account_id
263
- service['resource_group_name'] = resourceGroup
371
+ service["storage_account_name"] = name
372
+ service["storage_account_id"] = account_id
373
+ service["resource_group_name"] = resourceGroup
264
374
  blob_services.extend(blob_service)
265
-
266
- _load_queue_services(neo4j_session, queue_services, update_tag)
267
- _load_table_services(neo4j_session, table_services, update_tag)
268
- _load_file_services(neo4j_session, file_services, update_tag)
269
- _load_blob_services(neo4j_session, blob_services, update_tag)
270
-
271
- sync_queue_services_details(neo4j_session, credentials, subscription_id, queue_services, update_tag)
272
- sync_table_services_details(neo4j_session, credentials, subscription_id, table_services, update_tag)
273
- sync_file_services_details(neo4j_session, credentials, subscription_id, file_services, update_tag)
274
- sync_blob_services_details(neo4j_session, credentials, subscription_id, blob_services, update_tag)
375
+ return queue_services, table_services, file_services, blob_services
275
376
 
276
377
 
277
378
  @timeit
278
379
  def _load_queue_services(
279
- neo4j_session: neo4j.Session, queue_services: List[Dict], update_tag: int,
380
+ neo4j_session: neo4j.Session,
381
+ queue_services: List[Dict],
382
+ subscription_id: str,
383
+ update_tag: int,
280
384
  ) -> None:
281
- """
282
- Ingest Queue Service details into neo4j.
283
- """
284
- ingest_queue_services = """
285
- UNWIND $queue_services_list as qservice
286
- MERGE (qs:AzureStorageQueueService{id: qservice.id})
287
- ON CREATE SET qs.firstseen = timestamp(), qs.type = qservice.type
288
- SET qs.name = qservice.name,
289
- qs.lastupdated = $azure_update_tag
290
- WITH qs, qservice
291
- MATCH (s:AzureStorageAccount{id: qservice.storage_account_id})
292
- MERGE (s)-[r:USES]->(qs)
293
- ON CREATE SET r.firstseen = timestamp()
294
- SET r.lastupdated = $azure_update_tag
295
- """
296
-
297
- neo4j_session.run(
298
- ingest_queue_services,
299
- queue_services_list=queue_services,
300
- azure_update_tag=update_tag,
385
+ load(
386
+ neo4j_session,
387
+ AzureStorageQueueServiceSchema(),
388
+ queue_services,
389
+ lastupdated=update_tag,
390
+ AZURE_SUBSCRIPTION_ID=subscription_id,
301
391
  )
302
392
 
303
393
 
304
394
  @timeit
305
395
  def _load_table_services(
306
- neo4j_session: neo4j.Session, table_services: List[Dict], update_tag: int,
396
+ neo4j_session: neo4j.Session,
397
+ table_services: List[Dict],
398
+ subscription_id: str,
399
+ update_tag: int,
307
400
  ) -> None:
308
- """
309
- Ingest Table Service details into neo4j.
310
- """
311
- ingest_table_services = """
312
- UNWIND $table_services_list as tservice
313
- MERGE (ts:AzureStorageTableService{id: tservice.id})
314
- ON CREATE SET ts.firstseen = timestamp(), ts.type = tservice.type
315
- SET ts.name = tservice.name,
316
- ts.lastupdated = $azure_update_tag
317
- WITH ts, tservice
318
- MATCH (s:AzureStorageAccount{id: tservice.storage_account_id})
319
- MERGE (s)-[r:USES]->(ts)
320
- ON CREATE SET r.firstseen = timestamp()
321
- SET r.lastupdated = $azure_update_tag
322
- """
323
-
324
- neo4j_session.run(
325
- ingest_table_services,
326
- table_services_list=table_services,
327
- azure_update_tag=update_tag,
401
+ load(
402
+ neo4j_session,
403
+ AzureStorageTableServiceSchema(),
404
+ table_services,
405
+ lastupdated=update_tag,
406
+ AZURE_SUBSCRIPTION_ID=subscription_id,
328
407
  )
329
408
 
330
409
 
331
410
  @timeit
332
411
  def _load_file_services(
333
- neo4j_session: neo4j.Session, file_services: List[Dict], update_tag: int,
412
+ neo4j_session: neo4j.Session,
413
+ file_services: List[Dict],
414
+ subscription_id: str,
415
+ update_tag: int,
334
416
  ) -> None:
335
- """
336
- Ingest File Service details into neo4j.
337
- """
338
- ingest_file_services = """
339
- UNWIND $file_services_list as fservice
340
- MERGE (fs:AzureStorageFileService{id: fservice.id})
341
- ON CREATE SET fs.firstseen = timestamp(), fs.type = fservice.type
342
- SET fs.name = fservice.name,
343
- fs.lastupdated = $azure_update_tag
344
- WITH fs, fservice
345
- MATCH (s:AzureStorageAccount{id: fservice.storage_account_id})
346
- MERGE (s)-[r:USES]->(fs)
347
- ON CREATE SET r.firstseen = timestamp()
348
- SET r.lastupdated = $azure_update_tag
349
- """
350
-
351
- neo4j_session.run(
352
- ingest_file_services,
353
- file_services_list=file_services,
354
- azure_update_tag=update_tag,
417
+ load(
418
+ neo4j_session,
419
+ AzureStorageFileServiceSchema(),
420
+ file_services,
421
+ lastupdated=update_tag,
422
+ AZURE_SUBSCRIPTION_ID=subscription_id,
355
423
  )
356
424
 
357
425
 
358
426
  @timeit
359
427
  def _load_blob_services(
360
- neo4j_session: neo4j.Session, blob_services: List[Dict], update_tag: int,
428
+ neo4j_session: neo4j.Session,
429
+ blob_services: List[Dict],
430
+ subscription_id: str,
431
+ update_tag: int,
361
432
  ) -> None:
362
- """
363
- Ingest Blob Service details into neo4j.
364
- """
365
- ingest_blob_services = """
366
- UNWIND $blob_services_list as bservice
367
- MERGE (bs:AzureStorageBlobService{id: bservice.id})
368
- ON CREATE SET bs.firstseen = timestamp(), bs.type = bservice.type
369
- SET bs.name = bservice.name,
370
- bs.lastupdated = $azure_update_tag
371
- WITH bs, bservice
372
- MATCH (s:AzureStorageAccount{id: bservice.storage_account_id})
373
- MERGE (s)-[r:USES]->(bs)
374
- ON CREATE SET r.firstseen = timestamp()
375
- SET r.lastupdated = $azure_update_tag
376
- """
377
-
378
- neo4j_session.run(
379
- ingest_blob_services,
380
- blob_services_list=blob_services,
381
- azure_update_tag=update_tag,
433
+ load(
434
+ neo4j_session,
435
+ AzureStorageBlobServiceSchema(),
436
+ blob_services,
437
+ lastupdated=update_tag,
438
+ AZURE_SUBSCRIPTION_ID=subscription_id,
382
439
  )
383
440
 
384
441
 
385
442
  @timeit
386
443
  def sync_queue_services_details(
387
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
388
- queue_services: List[Dict], update_tag: int,
444
+ neo4j_session: neo4j.Session,
445
+ credentials: Credentials,
446
+ subscription_id: str,
447
+ queue_services: List[Dict],
448
+ update_tag: int,
389
449
  ) -> None:
390
- queue_services_details = get_queue_services_details(credentials, subscription_id, queue_services)
391
- load_queue_services_details(neo4j_session, queue_services_details, update_tag)
450
+ queue_services_details = get_queue_services_details(
451
+ credentials,
452
+ subscription_id,
453
+ queue_services,
454
+ )
455
+ load_queue_services_details(
456
+ neo4j_session, queue_services_details, subscription_id, update_tag
457
+ )
392
458
 
393
459
 
394
460
  @timeit
395
461
  def get_queue_services_details(
396
- credentials: Credentials, subscription_id: str, queue_services: List[Dict],
462
+ credentials: Credentials,
463
+ subscription_id: str,
464
+ queue_services: List[Dict],
397
465
  ) -> Generator[Any, Any, Any]:
398
466
  """
399
467
  Returning the queues with their respective queue service id.
400
468
  """
401
469
  for queue_service in queue_services:
402
470
  queues = get_queues(credentials, subscription_id, queue_service)
403
- yield queue_service['id'], queues
471
+ yield queue_service["id"], queues
404
472
 
405
473
 
406
474
  @timeit
407
- def get_queues(credentials: Credentials, subscription_id: str, queue_service: Dict) -> List[Dict]:
475
+ def get_queues(
476
+ credentials: Credentials,
477
+ subscription_id: str,
478
+ queue_service: Dict,
479
+ ) -> List[Dict]:
408
480
  """
409
481
  Getting the queues from the queue service.
410
482
  """
@@ -412,9 +484,10 @@ def get_queues(credentials: Credentials, subscription_id: str, queue_service: Di
412
484
  client = get_client(credentials, subscription_id)
413
485
  queues = list(
414
486
  map(
415
- lambda x: x.as_dict(), client.queue.list(
416
- queue_service['resource_group_name'],
417
- queue_service['storage_account_name'],
487
+ lambda x: x.as_dict(),
488
+ client.queue.list(
489
+ queue_service["resource_group_name"],
490
+ queue_service["storage_account_name"],
418
491
  ),
419
492
  ),
420
493
  )
@@ -434,7 +507,10 @@ def get_queues(credentials: Credentials, subscription_id: str, queue_service: Di
434
507
 
435
508
  @timeit
436
509
  def load_queue_services_details(
437
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
510
+ neo4j_session: neo4j.Session,
511
+ details: List[Tuple[Any, Any]],
512
+ subscription_id: str,
513
+ update_tag: int,
438
514
  ) -> None:
439
515
  """
440
516
  Create dictionary for the queue so we can import them in a single query
@@ -444,60 +520,69 @@ def load_queue_services_details(
444
520
  for queue_service_id, queue in details:
445
521
  if len(queue) > 0:
446
522
  for q in queue:
447
- q['service_id'] = queue_service_id
523
+ q["service_id"] = queue_service_id
448
524
  queues.extend(queue)
449
525
 
450
- _load_queues(neo4j_session, queues, update_tag)
526
+ _load_queues(neo4j_session, queues, subscription_id, update_tag)
451
527
 
452
528
 
453
529
  @timeit
454
- def _load_queues(neo4j_session: neo4j.Session, queues: List[Dict], update_tag: int) -> None:
530
+ def _load_queues(
531
+ neo4j_session: neo4j.Session,
532
+ queues: List[Dict],
533
+ subscription_id: str,
534
+ update_tag: int,
535
+ ) -> None:
455
536
  """
456
537
  Ingest Queue details into neo4j.
457
538
  """
458
- ingest_queues = """
459
- UNWIND $queues_list as queue
460
- MERGE (q:AzureStorageQueue{id: queue.id})
461
- ON CREATE SET q.firstseen = timestamp(), q.type = queue.type
462
- SET q.name = queue.name,
463
- q.lastupdated = $azure_update_tag
464
- WITH q, queue
465
- MATCH (qs:AzureStorageQueueService{id: queue.service_id})
466
- MERGE (qs)-[r:CONTAINS]->(q)
467
- ON CREATE SET r.firstseen = timestamp()
468
- SET r.lastupdated = $azure_update_tag
469
- """
470
-
471
- neo4j_session.run(
472
- ingest_queues,
473
- queues_list=queues,
474
- azure_update_tag=update_tag,
539
+ load(
540
+ neo4j_session,
541
+ AzureStorageQueueSchema(),
542
+ queues,
543
+ lastupdated=update_tag,
544
+ AZURE_SUBSCRIPTION_ID=subscription_id,
475
545
  )
476
546
 
477
547
 
478
548
  @timeit
479
549
  def sync_table_services_details(
480
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
481
- table_services: List[Dict], update_tag: int,
550
+ neo4j_session: neo4j.Session,
551
+ credentials: Credentials,
552
+ subscription_id: str,
553
+ table_services: List[Dict],
554
+ update_tag: int,
482
555
  ) -> None:
483
- table_services_details = get_table_services_details(credentials, subscription_id, table_services)
484
- load_table_services_details(neo4j_session, table_services_details, update_tag)
556
+ table_services_details = get_table_services_details(
557
+ credentials,
558
+ subscription_id,
559
+ table_services,
560
+ )
561
+ load_table_services_details(
562
+ neo4j_session, table_services_details, subscription_id, update_tag
563
+ )
485
564
 
486
565
 
487
566
  @timeit
488
567
  def get_table_services_details(
489
- credentials: Credentials, subscription_id: str, table_services: List[Dict],
568
+ credentials: Credentials,
569
+ subscription_id: str,
570
+ table_services: List[Dict],
490
571
  ) -> Generator[Any, Any, Any]:
491
572
  """
492
573
  Returning the tables with their respective table service id.
493
574
  """
494
575
  for table_service in table_services:
495
576
  tables = get_tables(credentials, subscription_id, table_service)
496
- yield table_service['id'], tables
577
+ yield table_service["id"], tables
497
578
 
498
579
 
499
580
  @timeit
500
- def get_tables(credentials: Credentials, subscription_id: str, table_service: Dict) -> List[Dict]:
581
+ def get_tables(
582
+ credentials: Credentials,
583
+ subscription_id: str,
584
+ table_service: Dict,
585
+ ) -> List[Dict]:
501
586
  """
502
587
  Getting the tables from the table service.
503
588
  """
@@ -505,9 +590,10 @@ def get_tables(credentials: Credentials, subscription_id: str, table_service: Di
505
590
  client = get_client(credentials, subscription_id)
506
591
  tables = list(
507
592
  map(
508
- lambda x: x.as_dict(), client.table.list(
509
- table_service['resource_group_name'],
510
- table_service['storage_account_name'],
593
+ lambda x: x.as_dict(),
594
+ client.table.list(
595
+ table_service["resource_group_name"],
596
+ table_service["storage_account_name"],
511
597
  ),
512
598
  ),
513
599
  )
@@ -527,7 +613,10 @@ def get_tables(credentials: Credentials, subscription_id: str, table_service: Di
527
613
 
528
614
  @timeit
529
615
  def load_table_services_details(
530
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
616
+ neo4j_session: neo4j.Session,
617
+ details: List[Tuple[Any, Any]],
618
+ subscription_id: str,
619
+ update_tag: int,
531
620
  ) -> None:
532
621
  """
533
622
  Create dictionary for the table so we can import them in a single query
@@ -537,61 +626,69 @@ def load_table_services_details(
537
626
  for table_service_id, table in details:
538
627
  if len(table) > 0:
539
628
  for t in table:
540
- t['service_id'] = table_service_id
629
+ t["service_id"] = table_service_id
541
630
  tables.extend(table)
542
631
 
543
- _load_tables(neo4j_session, tables, update_tag)
632
+ _load_tables(neo4j_session, tables, subscription_id, update_tag)
544
633
 
545
634
 
546
635
  @timeit
547
- def _load_tables(neo4j_session: neo4j.Session, tables: List[Dict], update_tag: int) -> None:
636
+ def _load_tables(
637
+ neo4j_session: neo4j.Session,
638
+ tables: List[Dict],
639
+ subscription_id: str,
640
+ update_tag: int,
641
+ ) -> None:
548
642
  """
549
643
  Ingest Table details into neo4j.
550
644
  """
551
- ingest_tables = """
552
- UNWIND $tables_list as table
553
- MERGE (t:AzureStorageTable{id: table.id})
554
- ON CREATE SET t.firstseen = timestamp(), t.type = table.type
555
- SET t.name = table.name,
556
- t.tablename = table.table_name,
557
- t.lastupdated = $azure_update_tag
558
- WITH t, table
559
- MATCH (ts:AzureStorageTableService{id: table.service_id})
560
- MERGE (ts)-[r:CONTAINS]->(t)
561
- ON CREATE SET r.firstseen = timestamp()
562
- SET r.lastupdated = $azure_update_tag
563
- """
564
-
565
- neo4j_session.run(
566
- ingest_tables,
567
- tables_list=tables,
568
- azure_update_tag=update_tag,
645
+ load(
646
+ neo4j_session,
647
+ AzureStorageTableSchema(),
648
+ tables,
649
+ lastupdated=update_tag,
650
+ AZURE_SUBSCRIPTION_ID=subscription_id,
569
651
  )
570
652
 
571
653
 
572
654
  @timeit
573
655
  def sync_file_services_details(
574
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
575
- file_services: List[Dict], update_tag: int,
656
+ neo4j_session: neo4j.Session,
657
+ credentials: Credentials,
658
+ subscription_id: str,
659
+ file_services: List[Dict],
660
+ update_tag: int,
576
661
  ) -> None:
577
- file_services_details = get_file_services_details(credentials, subscription_id, file_services)
578
- load_file_services_details(neo4j_session, file_services_details, update_tag)
662
+ file_services_details = get_file_services_details(
663
+ credentials,
664
+ subscription_id,
665
+ file_services,
666
+ )
667
+ load_file_services_details(
668
+ neo4j_session, file_services_details, subscription_id, update_tag
669
+ )
579
670
 
580
671
 
581
672
  @timeit
582
673
  def get_file_services_details(
583
- credentials: Credentials, subscription_id: str, file_services: List[Dict],
674
+ credentials: Credentials,
675
+ subscription_id: str,
676
+ file_services: List[Dict],
584
677
  ) -> Generator[Any, Any, Any]:
585
678
  """
586
679
  Returning the shares with their respective file service id.
587
680
  """
588
681
  for file_service in file_services:
589
682
  shares = get_shares(credentials, subscription_id, file_service)
590
- yield file_service['id'], shares
683
+ yield file_service["id"], shares
591
684
 
592
685
 
593
686
  @timeit
594
- def get_shares(credentials: Credentials, subscription_id: str, file_service: Dict) -> List[Dict]:
687
+ def get_shares(
688
+ credentials: Credentials,
689
+ subscription_id: str,
690
+ file_service: Dict,
691
+ ) -> List[Dict]:
595
692
  """
596
693
  Getting the shares from the file service.
597
694
  """
@@ -599,9 +696,10 @@ def get_shares(credentials: Credentials, subscription_id: str, file_service: Dic
599
696
  client = get_client(credentials, subscription_id)
600
697
  shares = list(
601
698
  map(
602
- lambda x: x.as_dict(), client.file_shares.list(
603
- file_service['resource_group_name'],
604
- file_service['storage_account_name'],
699
+ lambda x: x.as_dict(),
700
+ client.file_shares.list(
701
+ file_service["resource_group_name"],
702
+ file_service["storage_account_name"],
605
703
  ),
606
704
  ),
607
705
  )
@@ -621,7 +719,10 @@ def get_shares(credentials: Credentials, subscription_id: str, file_service: Dic
621
719
 
622
720
  @timeit
623
721
  def load_file_services_details(
624
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
722
+ neo4j_session: neo4j.Session,
723
+ details: List[Tuple[Any, Any]],
724
+ subscription_id: str,
725
+ update_tag: int,
625
726
  ) -> None:
626
727
  """
627
728
  Create dictionary for the shares so we can import them in a single query
@@ -631,71 +732,73 @@ def load_file_services_details(
631
732
  for file_service_id, share in details:
632
733
  if len(share) > 0:
633
734
  for s in share:
634
- s['service_id'] = file_service_id
735
+ s["service_id"] = file_service_id
635
736
  shares.extend(share)
636
737
 
637
- _load_shares(neo4j_session, shares, update_tag)
738
+ _load_shares(neo4j_session, shares, subscription_id, update_tag)
638
739
 
639
740
 
640
741
  @timeit
641
- def _load_shares(neo4j_session: neo4j.Session, shares: List[Dict], update_tag: int) -> None:
742
+ def _load_shares(
743
+ neo4j_session: neo4j.Session,
744
+ shares: List[Dict],
745
+ subscription_id: str,
746
+ update_tag: int,
747
+ ) -> None:
642
748
  """
643
749
  Ingest Share details into neo4j.
644
750
  """
645
- ingest_shares = """
646
- UNWIND $shares_list as s
647
- MERGE (share:AzureStorageFileShare{id: s.id})
648
- ON CREATE SET share.firstseen = timestamp(), share.type = s.type
649
- SET share.name = s.name,
650
- share.lastupdated = $azure_update_tag,
651
- share.lastmodifiedtime = s.last_modified_time,
652
- share.sharequota = s.share_quota,
653
- share.accesstier = s.access_tier,
654
- share.deleted = s.deleted,
655
- share.accesstierchangetime = s.access_tier_change_time,
656
- share.accesstierstatus = s.access_tier_status,
657
- share.deletedtime = s.deleted_time,
658
- share.enabledprotocols = s.enabled_protocols,
659
- share.remainingretentiondays = s.remaining_retention_days,
660
- share.shareusagebytes = s.share_usage_bytes,
661
- share.version = s.version
662
- WITH share, s
663
- MATCH (fs:AzureStorageFileService{id: s.service_id})
664
- MERGE (fs)-[r:CONTAINS]->(share)
665
- ON CREATE SET r.firstseen = timestamp()
666
- SET r.lastupdated = $azure_update_tag
667
- """
668
-
669
- neo4j_session.run(
670
- ingest_shares,
671
- shares_list=shares,
672
- azure_update_tag=update_tag,
751
+ load(
752
+ neo4j_session,
753
+ AzureStorageFileShareSchema(),
754
+ shares,
755
+ lastupdated=update_tag,
756
+ AZURE_SUBSCRIPTION_ID=subscription_id,
673
757
  )
674
758
 
675
759
 
676
760
  @timeit
677
761
  def sync_blob_services_details(
678
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
679
- blob_services: List[Dict], update_tag: int,
762
+ neo4j_session: neo4j.Session,
763
+ credentials: Credentials,
764
+ subscription_id: str,
765
+ blob_services: List[Dict],
766
+ update_tag: int,
680
767
  ) -> None:
681
- blob_services_details = get_blob_services_details(credentials, subscription_id, blob_services)
682
- load_blob_services_details(neo4j_session, blob_services_details, update_tag)
768
+ blob_services_details = get_blob_services_details(
769
+ credentials,
770
+ subscription_id,
771
+ blob_services,
772
+ )
773
+ load_blob_services_details(
774
+ neo4j_session, blob_services_details, subscription_id, update_tag
775
+ )
683
776
 
684
777
 
685
778
  @timeit
686
779
  def get_blob_services_details(
687
- credentials: Credentials, subscription_id: str, blob_services: List[Dict],
780
+ credentials: Credentials,
781
+ subscription_id: str,
782
+ blob_services: List[Dict],
688
783
  ) -> Generator[Any, Any, Any]:
689
784
  """
690
785
  Returning the blob containers with their respective blob service id.
691
786
  """
692
787
  for blob_service in blob_services:
693
- blob_containers = get_blob_containers(credentials, subscription_id, blob_service)
694
- yield blob_service['id'], blob_containers
788
+ blob_containers = get_blob_containers(
789
+ credentials,
790
+ subscription_id,
791
+ blob_service,
792
+ )
793
+ yield blob_service["id"], blob_containers
695
794
 
696
795
 
697
796
  @timeit
698
- def get_blob_containers(credentials: Credentials, subscription_id: str, blob_service: Dict) -> List[Dict]:
797
+ def get_blob_containers(
798
+ credentials: Credentials,
799
+ subscription_id: str,
800
+ blob_service: Dict,
801
+ ) -> List[Dict]:
699
802
  """
700
803
  Getting the blob containers from the blob service.
701
804
  """
@@ -705,14 +808,16 @@ def get_blob_containers(credentials: Credentials, subscription_id: str, blob_ser
705
808
  map(
706
809
  lambda x: x.as_dict(),
707
810
  client.blob_containers.list(
708
- blob_service['resource_group_name'],
709
- blob_service['storage_account_name'],
811
+ blob_service["resource_group_name"],
812
+ blob_service["storage_account_name"],
710
813
  ),
711
814
  ),
712
815
  )
713
816
 
714
817
  except ClientAuthenticationError as e:
715
- logger.warning(f"Client Authentication Error while retrieving blob containers - {e}")
818
+ logger.warning(
819
+ f"Client Authentication Error while retrieving blob containers - {e}",
820
+ )
716
821
  return []
717
822
  except ResourceNotFoundError as e:
718
823
  logger.warning(f"Blob containers resource not found error - {e}")
@@ -726,7 +831,10 @@ def get_blob_containers(credentials: Credentials, subscription_id: str, blob_ser
726
831
 
727
832
  @timeit
728
833
  def load_blob_services_details(
729
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
834
+ neo4j_session: neo4j.Session,
835
+ details: List[Tuple[Any, Any]],
836
+ subscription_id: str,
837
+ update_tag: int,
730
838
  ) -> None:
731
839
  """
732
840
  Create dictionary for the blob containers so we can import them in a single query
@@ -736,65 +844,89 @@ def load_blob_services_details(
736
844
  for blob_service_id, container in details:
737
845
  if len(container) > 0:
738
846
  for c in container:
739
- c['service_id'] = blob_service_id
847
+ c["service_id"] = blob_service_id
740
848
  blob_containers.extend(container)
741
849
 
742
- _load_blob_containers(neo4j_session, blob_containers, update_tag)
850
+ _load_blob_containers(neo4j_session, blob_containers, subscription_id, update_tag)
743
851
 
744
852
 
745
853
  @timeit
746
854
  def _load_blob_containers(
747
- neo4j_session: neo4j.Session, blob_containers: List[Dict], update_tag: int,
855
+ neo4j_session: neo4j.Session,
856
+ blob_containers: List[Dict],
857
+ subscription_id: str,
858
+ update_tag: int,
748
859
  ) -> None:
749
860
  """
750
861
  Ingest Blob Container details into neo4j.
751
862
  """
752
- ingest_blob_containers = """
753
- UNWIND $blob_containers_list as blob
754
- MERGE (bc:AzureStorageBlobContainer{id: blob.id})
755
- ON CREATE SET bc.firstseen = timestamp(), bc.type = blob.type
756
- SET bc.name = blob.name,
757
- bc.lastupdated = $azure_update_tag,
758
- bc.deleted = blob.deleted,
759
- bc.deletedtime = blob.deleted_time,
760
- bc.defaultencryptionscope = blob.default_encryption_scope,
761
- bc.publicaccess = blob.public_access,
762
- bc.leasestatus = blob.lease_status,
763
- bc.leasestate = blob.lease_state,
764
- bc.lastmodifiedtime = blob.last_modified_time,
765
- bc.remainingretentiondays = blob.remaining_retention_days,
766
- bc.version = blob.version,
767
- bc.hasimmutabilitypolicy = blob.has_immutability_policy,
768
- bc.haslegalhold = blob.has_legal_hold,
769
- bc.leaseduration = blob.leaseDuration
770
- WITH bc, blob
771
- MATCH (bs:AzureStorageBlobService{id: blob.service_id})
772
- MERGE (bs)-[r:CONTAINS]->(bc)
773
- ON CREATE SET r.firstseen = timestamp()
774
- SET r.lastupdated = $azure_update_tag
775
- """
776
-
777
- neo4j_session.run(
778
- ingest_blob_containers,
779
- blob_containers_list=blob_containers,
780
- azure_update_tag=update_tag,
863
+ load(
864
+ neo4j_session,
865
+ AzureStorageBlobContainerSchema(),
866
+ blob_containers,
867
+ lastupdated=update_tag,
868
+ AZURE_SUBSCRIPTION_ID=subscription_id,
781
869
  )
782
870
 
783
871
 
784
872
  @timeit
785
873
  def cleanup_azure_storage_accounts(
786
- neo4j_session: neo4j.Session, common_job_parameters: Dict,
874
+ neo4j_session: neo4j.Session,
875
+ common_job_parameters: Dict,
787
876
  ) -> None:
788
- run_cleanup_job('azure_storage_account_cleanup.json', neo4j_session, common_job_parameters)
877
+ for node in (
878
+ AzureStorageAccountSchema,
879
+ AzureStorageBlobServiceSchema,
880
+ AzureStorageFileServiceSchema,
881
+ AzureStorageQueueServiceSchema,
882
+ AzureStorageTableServiceSchema,
883
+ AzureStorageFileShareSchema,
884
+ AzureStorageQueueSchema,
885
+ AzureStorageTableSchema,
886
+ AzureStorageBlobContainerSchema,
887
+ ):
888
+ GraphJob.from_node_schema(node(), common_job_parameters).run(
889
+ neo4j_session,
890
+ )
891
+
892
+
893
+ @timeit
894
+ def cleanup_azure_storage_tags(
895
+ neo4j_session: neo4j.Session,
896
+ common_job_parameters: Dict,
897
+ ) -> None:
898
+ """
899
+ Delete stale Azure Storage Tags that are scoped to the current subscription.
900
+ Uses the sub-resource relationship to only clean tags belonging to this subscription.
901
+ """
902
+ GraphJob.from_node_schema(AzureStorageTagsSchema(), common_job_parameters).run(
903
+ neo4j_session
904
+ )
789
905
 
790
906
 
791
907
  @timeit
792
908
  def sync(
793
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
794
- sync_tag: int, common_job_parameters: Dict,
909
+ neo4j_session: neo4j.Session,
910
+ credentials: Credentials,
911
+ subscription_id: str,
912
+ sync_tag: int,
913
+ common_job_parameters: Dict,
795
914
  ) -> None:
796
915
  logger.info("Syncing Azure Storage for subscription '%s'.", subscription_id)
797
916
  storage_account_list = get_storage_account_list(credentials, subscription_id)
798
- load_storage_account_data(neo4j_session, subscription_id, storage_account_list, sync_tag)
799
- sync_storage_account_details(neo4j_session, credentials, subscription_id, storage_account_list, sync_tag)
917
+ load_storage_account_data(
918
+ neo4j_session,
919
+ subscription_id,
920
+ storage_account_list,
921
+ sync_tag,
922
+ )
923
+ load_storage_tags(neo4j_session, subscription_id, storage_account_list, sync_tag)
924
+ sync_storage_account_details(
925
+ neo4j_session,
926
+ credentials,
927
+ subscription_id,
928
+ storage_account_list,
929
+ sync_tag,
930
+ )
800
931
  cleanup_azure_storage_accounts(neo4j_session, common_job_parameters)
932
+ cleanup_azure_storage_tags(neo4j_session, common_job_parameters)