cartography 0.104.0rc2__py3-none-any.whl → 0.123.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (642) hide show
  1. cartography/_version.py +16 -3
  2. cartography/cli.py +466 -5
  3. cartography/client/aws/__init__.py +19 -0
  4. cartography/client/aws/ecr.py +51 -0
  5. cartography/client/core/tx.py +357 -8
  6. cartography/config.py +153 -0
  7. cartography/data/azure_permission_relationships.yaml +20 -0
  8. cartography/data/gcp_permission_relationships.yaml +21 -0
  9. cartography/data/indexes.cypher +0 -186
  10. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  11. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  12. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  13. cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
  14. cartography/driftdetect/cli.py +3 -2
  15. cartography/graph/cleanupbuilder.py +198 -41
  16. cartography/graph/job.py +54 -6
  17. cartography/graph/querybuilder.py +528 -27
  18. cartography/graph/statement.py +5 -1
  19. cartography/intel/airbyte/__init__.py +105 -0
  20. cartography/intel/airbyte/connections.py +120 -0
  21. cartography/intel/airbyte/destinations.py +81 -0
  22. cartography/intel/airbyte/organizations.py +59 -0
  23. cartography/intel/airbyte/sources.py +78 -0
  24. cartography/intel/airbyte/tags.py +64 -0
  25. cartography/intel/airbyte/users.py +106 -0
  26. cartography/intel/airbyte/util.py +122 -0
  27. cartography/intel/airbyte/workspaces.py +63 -0
  28. cartography/intel/aws/__init__.py +24 -9
  29. cartography/intel/aws/acm.py +124 -0
  30. cartography/intel/aws/apigateway.py +253 -22
  31. cartography/intel/aws/apigatewayv2.py +116 -0
  32. cartography/intel/aws/cloudtrail.py +17 -39
  33. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  34. cartography/intel/aws/cloudwatch.py +150 -4
  35. cartography/intel/aws/codebuild.py +132 -0
  36. cartography/intel/aws/cognito.py +201 -0
  37. cartography/intel/aws/config.py +7 -3
  38. cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
  39. cartography/intel/aws/ec2/instances.py +25 -1
  40. cartography/intel/aws/ec2/internet_gateways.py +4 -2
  41. cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
  42. cartography/intel/aws/ec2/network_interfaces.py +5 -1
  43. cartography/intel/aws/ec2/reserved_instances.py +3 -1
  44. cartography/intel/aws/ec2/security_groups.py +140 -122
  45. cartography/intel/aws/ec2/snapshots.py +47 -84
  46. cartography/intel/aws/ec2/subnets.py +37 -63
  47. cartography/intel/aws/ec2/tgw.py +11 -5
  48. cartography/intel/aws/ec2/volumes.py +1 -1
  49. cartography/intel/aws/ec2/vpc.py +140 -124
  50. cartography/intel/aws/ec2/vpc_peerings.py +262 -125
  51. cartography/intel/aws/ecr.py +269 -98
  52. cartography/intel/aws/ecr_image_layers.py +923 -0
  53. cartography/intel/aws/ecs.py +251 -380
  54. cartography/intel/aws/efs.py +179 -11
  55. cartography/intel/aws/elasticache.py +102 -79
  56. cartography/intel/aws/elasticsearch.py +13 -4
  57. cartography/intel/aws/eventbridge.py +164 -0
  58. cartography/intel/aws/glue.py +181 -0
  59. cartography/intel/aws/guardduty.py +443 -0
  60. cartography/intel/aws/iam.py +750 -493
  61. cartography/intel/aws/identitycenter.py +605 -83
  62. cartography/intel/aws/inspector.py +221 -105
  63. cartography/intel/aws/kms.py +173 -201
  64. cartography/intel/aws/lambda_function.py +272 -189
  65. cartography/intel/aws/organizations.py +10 -9
  66. cartography/intel/aws/permission_relationships.py +10 -20
  67. cartography/intel/aws/rds.py +337 -446
  68. cartography/intel/aws/redshift.py +9 -4
  69. cartography/intel/aws/resourcegroupstaggingapi.py +78 -19
  70. cartography/intel/aws/resources.py +18 -0
  71. cartography/intel/aws/route53.py +386 -332
  72. cartography/intel/aws/s3.py +322 -14
  73. cartography/intel/aws/secretsmanager.py +81 -49
  74. cartography/intel/aws/securityhub.py +3 -1
  75. cartography/intel/aws/sns.py +62 -2
  76. cartography/intel/aws/sqs.py +36 -90
  77. cartography/intel/aws/ssm.py +3 -5
  78. cartography/intel/azure/__init__.py +202 -48
  79. cartography/intel/azure/aks.py +175 -0
  80. cartography/intel/azure/app_service.py +105 -0
  81. cartography/intel/azure/compute.py +59 -112
  82. cartography/intel/azure/container_instances.py +95 -0
  83. cartography/intel/azure/cosmosdb.py +222 -361
  84. cartography/intel/azure/data_factory.py +85 -0
  85. cartography/intel/azure/data_factory_dataset.py +128 -0
  86. cartography/intel/azure/data_factory_linked_service.py +119 -0
  87. cartography/intel/azure/data_factory_pipeline.py +142 -0
  88. cartography/intel/azure/data_lake.py +124 -0
  89. cartography/intel/azure/event_grid.py +94 -0
  90. cartography/intel/azure/functions.py +124 -0
  91. cartography/intel/azure/load_balancers.py +263 -0
  92. cartography/intel/azure/logic_apps.py +101 -0
  93. cartography/intel/azure/monitor.py +105 -0
  94. cartography/intel/azure/network.py +467 -0
  95. cartography/intel/azure/permission_relationships.py +466 -0
  96. cartography/intel/azure/rbac.py +309 -0
  97. cartography/intel/azure/resource_groups.py +82 -0
  98. cartography/intel/azure/security_center.py +106 -0
  99. cartography/intel/azure/sql.py +145 -292
  100. cartography/intel/azure/storage.py +185 -262
  101. cartography/intel/azure/subscription.py +21 -43
  102. cartography/intel/azure/tenant.py +39 -30
  103. cartography/intel/azure/util/common.py +13 -0
  104. cartography/intel/azure/util/credentials.py +49 -174
  105. cartography/intel/azure/util/tag.py +41 -0
  106. cartography/intel/create_indexes.py +2 -1
  107. cartography/intel/crowdstrike/spotlight.py +5 -2
  108. cartography/intel/dns.py +5 -2
  109. cartography/intel/entra/__init__.py +100 -1
  110. cartography/intel/entra/app_role_assignments.py +284 -0
  111. cartography/intel/entra/applications.py +182 -0
  112. cartography/intel/entra/federation/__init__.py +0 -0
  113. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  114. cartography/intel/entra/groups.py +198 -0
  115. cartography/intel/entra/ou.py +48 -24
  116. cartography/intel/entra/service_principals.py +217 -0
  117. cartography/intel/entra/users.py +105 -57
  118. cartography/intel/gcp/__init__.py +334 -396
  119. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  120. cartography/intel/gcp/bigtable_backup.py +91 -0
  121. cartography/intel/gcp/bigtable_cluster.py +93 -0
  122. cartography/intel/gcp/bigtable_instance.py +86 -0
  123. cartography/intel/gcp/bigtable_table.py +87 -0
  124. cartography/intel/gcp/cai.py +292 -0
  125. cartography/intel/gcp/clients.py +112 -0
  126. cartography/intel/gcp/compute.py +128 -119
  127. cartography/intel/gcp/crm/__init__.py +0 -0
  128. cartography/intel/gcp/crm/folders.py +114 -0
  129. cartography/intel/gcp/crm/orgs.py +70 -0
  130. cartography/intel/gcp/crm/projects.py +120 -0
  131. cartography/intel/gcp/dns.py +83 -169
  132. cartography/intel/gcp/gke.py +72 -113
  133. cartography/intel/gcp/iam.py +111 -91
  134. cartography/intel/gcp/permission_relationships.py +394 -0
  135. cartography/intel/gcp/policy_bindings.py +225 -0
  136. cartography/intel/gcp/storage.py +75 -159
  137. cartography/intel/github/__init__.py +62 -25
  138. cartography/intel/github/commits.py +423 -0
  139. cartography/intel/github/repos.py +463 -85
  140. cartography/intel/github/teams.py +3 -3
  141. cartography/intel/github/users.py +5 -0
  142. cartography/intel/github/util.py +12 -0
  143. cartography/intel/googleworkspace/__init__.py +193 -0
  144. cartography/intel/googleworkspace/devices.py +254 -0
  145. cartography/intel/googleworkspace/groups.py +568 -0
  146. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  147. cartography/intel/googleworkspace/tenant.py +85 -0
  148. cartography/intel/googleworkspace/users.py +138 -0
  149. cartography/intel/gsuite/__init__.py +17 -9
  150. cartography/intel/gsuite/groups.py +291 -0
  151. cartography/intel/gsuite/users.py +142 -0
  152. cartography/intel/jamf/computers.py +7 -1
  153. cartography/intel/keycloak/__init__.py +153 -0
  154. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  155. cartography/intel/keycloak/authenticationflows.py +77 -0
  156. cartography/intel/keycloak/clients.py +187 -0
  157. cartography/intel/keycloak/groups.py +126 -0
  158. cartography/intel/keycloak/identityproviders.py +94 -0
  159. cartography/intel/keycloak/organizations.py +163 -0
  160. cartography/intel/keycloak/realms.py +61 -0
  161. cartography/intel/keycloak/roles.py +202 -0
  162. cartography/intel/keycloak/scopes.py +73 -0
  163. cartography/intel/keycloak/users.py +70 -0
  164. cartography/intel/keycloak/util.py +47 -0
  165. cartography/intel/kubernetes/__init__.py +60 -14
  166. cartography/intel/kubernetes/clusters.py +86 -0
  167. cartography/intel/kubernetes/eks.py +402 -0
  168. cartography/intel/kubernetes/namespaces.py +59 -57
  169. cartography/intel/kubernetes/pods.py +168 -75
  170. cartography/intel/kubernetes/rbac.py +597 -0
  171. cartography/intel/kubernetes/secrets.py +95 -45
  172. cartography/intel/kubernetes/services.py +131 -67
  173. cartography/intel/kubernetes/util.py +142 -14
  174. cartography/intel/oci/iam.py +23 -9
  175. cartography/intel/oci/organizations.py +3 -1
  176. cartography/intel/oci/utils.py +28 -5
  177. cartography/intel/okta/applications.py +15 -5
  178. cartography/intel/okta/awssaml.py +14 -10
  179. cartography/intel/okta/factors.py +3 -1
  180. cartography/intel/okta/groups.py +5 -2
  181. cartography/intel/okta/organization.py +3 -1
  182. cartography/intel/okta/origins.py +3 -1
  183. cartography/intel/okta/roles.py +5 -2
  184. cartography/intel/okta/users.py +10 -2
  185. cartography/intel/ontology/__init__.py +44 -0
  186. cartography/intel/ontology/devices.py +54 -0
  187. cartography/intel/ontology/users.py +54 -0
  188. cartography/intel/ontology/utils.py +176 -0
  189. cartography/intel/pagerduty/escalation_policies.py +13 -6
  190. cartography/intel/pagerduty/schedules.py +9 -4
  191. cartography/intel/pagerduty/services.py +7 -3
  192. cartography/intel/pagerduty/teams.py +5 -2
  193. cartography/intel/pagerduty/users.py +3 -1
  194. cartography/intel/pagerduty/vendors.py +3 -1
  195. cartography/intel/scaleway/__init__.py +127 -0
  196. cartography/intel/scaleway/iam/__init__.py +0 -0
  197. cartography/intel/scaleway/iam/apikeys.py +71 -0
  198. cartography/intel/scaleway/iam/applications.py +71 -0
  199. cartography/intel/scaleway/iam/groups.py +71 -0
  200. cartography/intel/scaleway/iam/users.py +71 -0
  201. cartography/intel/scaleway/instances/__init__.py +0 -0
  202. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  203. cartography/intel/scaleway/instances/instances.py +92 -0
  204. cartography/intel/scaleway/projects.py +79 -0
  205. cartography/intel/scaleway/storage/__init__.py +0 -0
  206. cartography/intel/scaleway/storage/snapshots.py +86 -0
  207. cartography/intel/scaleway/storage/volumes.py +84 -0
  208. cartography/intel/scaleway/utils.py +37 -0
  209. cartography/intel/sentinelone/__init__.py +75 -0
  210. cartography/intel/sentinelone/account.py +140 -0
  211. cartography/intel/sentinelone/agent.py +139 -0
  212. cartography/intel/sentinelone/api.py +124 -0
  213. cartography/intel/sentinelone/application.py +248 -0
  214. cartography/intel/sentinelone/cve.py +119 -0
  215. cartography/intel/sentinelone/utils.py +28 -0
  216. cartography/intel/slack/__init__.py +78 -0
  217. cartography/intel/slack/channels.py +80 -0
  218. cartography/intel/slack/groups.py +90 -0
  219. cartography/intel/slack/teams.py +65 -0
  220. cartography/intel/slack/users.py +57 -0
  221. cartography/intel/slack/utils.py +29 -0
  222. cartography/intel/spacelift/__init__.py +161 -0
  223. cartography/intel/spacelift/account.py +73 -0
  224. cartography/intel/spacelift/ec2_ownership.py +280 -0
  225. cartography/intel/spacelift/runs.py +463 -0
  226. cartography/intel/spacelift/spaces.py +112 -0
  227. cartography/intel/spacelift/stacks.py +119 -0
  228. cartography/intel/spacelift/util.py +122 -0
  229. cartography/intel/spacelift/workerpools.py +131 -0
  230. cartography/intel/spacelift/workers.py +128 -0
  231. cartography/intel/trivy/__init__.py +272 -0
  232. cartography/intel/trivy/scanner.py +386 -0
  233. cartography/models/airbyte/__init__.py +0 -0
  234. cartography/models/airbyte/connection.py +138 -0
  235. cartography/models/airbyte/destination.py +75 -0
  236. cartography/models/airbyte/organization.py +19 -0
  237. cartography/models/airbyte/source.py +75 -0
  238. cartography/models/airbyte/stream.py +74 -0
  239. cartography/models/airbyte/tag.py +69 -0
  240. cartography/models/airbyte/user.py +115 -0
  241. cartography/models/airbyte/workspace.py +46 -0
  242. cartography/models/anthropic/apikey.py +4 -0
  243. cartography/models/anthropic/user.py +4 -0
  244. cartography/models/aws/acm/__init__.py +0 -0
  245. cartography/models/aws/acm/certificate.py +75 -0
  246. cartography/models/aws/apigateway/__init__.py +0 -0
  247. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  248. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  249. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  250. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  251. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  252. cartography/models/aws/cloudtrail/management_events.py +153 -0
  253. cartography/models/aws/cloudtrail/trail.py +45 -0
  254. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  255. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  256. cartography/models/aws/codebuild/__init__.py +0 -0
  257. cartography/models/aws/codebuild/project.py +49 -0
  258. cartography/models/aws/cognito/__init__.py +0 -0
  259. cartography/models/aws/cognito/identity_pool.py +70 -0
  260. cartography/models/aws/cognito/user_pool.py +47 -0
  261. cartography/models/aws/dynamodb/tables.py +2 -0
  262. cartography/models/aws/ec2/instances.py +25 -1
  263. cartography/models/aws/ec2/networkinterfaces.py +4 -0
  264. cartography/models/aws/ec2/security_group_rules.py +109 -0
  265. cartography/models/aws/ec2/security_groups.py +90 -0
  266. cartography/models/aws/ec2/snapshots.py +58 -0
  267. cartography/models/aws/ec2/subnet_instance.py +2 -0
  268. cartography/models/aws/ec2/subnet_networkinterface.py +2 -0
  269. cartography/models/aws/ec2/subnets.py +65 -0
  270. cartography/models/aws/ec2/volumes.py +20 -0
  271. cartography/models/aws/ec2/vpc.py +46 -0
  272. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  273. cartography/models/aws/ec2/vpc_peering.py +157 -0
  274. cartography/models/aws/ecr/__init__.py +0 -0
  275. cartography/models/aws/ecr/image.py +146 -0
  276. cartography/models/aws/ecr/image_layer.py +107 -0
  277. cartography/models/aws/ecr/repository.py +72 -0
  278. cartography/models/aws/ecr/repository_image.py +95 -0
  279. cartography/models/aws/ecs/__init__.py +0 -0
  280. cartography/models/aws/ecs/clusters.py +64 -0
  281. cartography/models/aws/ecs/container_definitions.py +93 -0
  282. cartography/models/aws/ecs/container_instances.py +84 -0
  283. cartography/models/aws/ecs/containers.py +101 -0
  284. cartography/models/aws/ecs/services.py +134 -0
  285. cartography/models/aws/ecs/task_definitions.py +135 -0
  286. cartography/models/aws/ecs/tasks.py +134 -0
  287. cartography/models/aws/efs/access_point.py +77 -0
  288. cartography/models/aws/efs/file_system.py +60 -0
  289. cartography/models/aws/efs/mount_target.py +29 -2
  290. cartography/models/aws/elasticache/__init__.py +0 -0
  291. cartography/models/aws/elasticache/cluster.py +65 -0
  292. cartography/models/aws/elasticache/topic.py +67 -0
  293. cartography/models/aws/eventbridge/__init__.py +0 -0
  294. cartography/models/aws/eventbridge/rule.py +77 -0
  295. cartography/models/aws/eventbridge/target.py +71 -0
  296. cartography/models/aws/glue/__init__.py +0 -0
  297. cartography/models/aws/glue/connection.py +51 -0
  298. cartography/models/aws/glue/job.py +69 -0
  299. cartography/models/aws/guardduty/__init__.py +1 -0
  300. cartography/models/aws/guardduty/detectors.py +50 -0
  301. cartography/models/aws/guardduty/findings.py +121 -0
  302. cartography/models/aws/iam/access_key.py +103 -0
  303. cartography/models/aws/iam/account_role.py +24 -0
  304. cartography/models/aws/iam/federated_principal.py +60 -0
  305. cartography/models/aws/iam/group.py +60 -0
  306. cartography/models/aws/iam/group_membership.py +27 -0
  307. cartography/models/aws/iam/inline_policy.py +78 -0
  308. cartography/models/aws/iam/managed_policy.py +51 -0
  309. cartography/models/aws/iam/policy_statement.py +57 -0
  310. cartography/models/aws/iam/role.py +83 -0
  311. cartography/models/aws/iam/root_principal.py +52 -0
  312. cartography/models/aws/iam/service_principal.py +30 -0
  313. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  314. cartography/models/aws/iam/user.py +59 -0
  315. cartography/models/aws/identitycenter/awsidentitycenter.py +1 -0
  316. cartography/models/aws/identitycenter/awspermissionset.py +70 -0
  317. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  318. cartography/models/aws/identitycenter/awsssouser.py +49 -9
  319. cartography/models/aws/inspector/findings.py +37 -0
  320. cartography/models/aws/inspector/packages.py +1 -31
  321. cartography/models/aws/kms/__init__.py +0 -0
  322. cartography/models/aws/kms/aliases.py +86 -0
  323. cartography/models/aws/kms/grants.py +65 -0
  324. cartography/models/aws/kms/keys.py +88 -0
  325. cartography/models/aws/lambda_function/__init__.py +0 -0
  326. cartography/models/aws/lambda_function/alias.py +74 -0
  327. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  328. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  329. cartography/models/aws/lambda_function/layer.py +72 -0
  330. cartography/models/aws/rds/__init__.py +0 -0
  331. cartography/models/aws/rds/cluster.py +91 -0
  332. cartography/models/aws/rds/event_subscription.py +146 -0
  333. cartography/models/aws/rds/instance.py +156 -0
  334. cartography/models/aws/rds/snapshot.py +108 -0
  335. cartography/models/aws/rds/subnet_group.py +101 -0
  336. cartography/models/aws/route53/__init__.py +0 -0
  337. cartography/models/aws/route53/dnsrecord.py +235 -0
  338. cartography/models/aws/route53/nameserver.py +63 -0
  339. cartography/models/aws/route53/subzone.py +40 -0
  340. cartography/models/aws/route53/zone.py +47 -0
  341. cartography/models/aws/s3/notification.py +24 -0
  342. cartography/models/aws/secretsmanager/secret.py +106 -0
  343. cartography/models/aws/secretsmanager/secret_version.py +0 -2
  344. cartography/models/aws/sns/topic_subscription.py +74 -0
  345. cartography/models/aws/sqs/__init__.py +0 -0
  346. cartography/models/aws/sqs/queue.py +89 -0
  347. cartography/models/azure/__init__.py +0 -0
  348. cartography/models/azure/aks_cluster.py +54 -0
  349. cartography/models/azure/aks_nodepool.py +54 -0
  350. cartography/models/azure/app_service.py +59 -0
  351. cartography/models/azure/container_instance.py +57 -0
  352. cartography/models/azure/cosmosdb/__init__.py +0 -0
  353. cartography/models/azure/cosmosdb/account.py +77 -0
  354. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  355. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  356. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  357. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  358. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  359. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  360. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  361. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  362. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  363. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  364. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  365. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  366. cartography/models/azure/data_factory/__init__.py +0 -0
  367. cartography/models/azure/data_factory/data_factory.py +51 -0
  368. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  369. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  370. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  371. cartography/models/azure/data_lake_filesystem.py +51 -0
  372. cartography/models/azure/event_grid_topic.py +57 -0
  373. cartography/models/azure/function_app.py +59 -0
  374. cartography/models/azure/load_balancer/__init__.py +0 -0
  375. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  376. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  377. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  378. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  379. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  380. cartography/models/azure/logic_apps.py +56 -0
  381. cartography/models/azure/monitor.py +54 -0
  382. cartography/models/azure/network_interface.py +112 -0
  383. cartography/models/azure/network_security_group.py +50 -0
  384. cartography/models/azure/permission_relationships.py +60 -0
  385. cartography/models/azure/principal.py +41 -0
  386. cartography/models/azure/public_ip_address.py +50 -0
  387. cartography/models/azure/rbac.py +268 -0
  388. cartography/models/azure/resource_groups.py +52 -0
  389. cartography/models/azure/security_center.py +50 -0
  390. cartography/models/azure/sql/__init__.py +0 -0
  391. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  392. cartography/models/azure/sql/elasticpool.py +77 -0
  393. cartography/models/azure/sql/failovergroup.py +73 -0
  394. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  395. cartography/models/azure/sql/replicationlink.py +81 -0
  396. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  397. cartography/models/azure/sql/restorepoint.py +74 -0
  398. cartography/models/azure/sql/serveradadministrator.py +74 -0
  399. cartography/models/azure/sql/serverdnsalias.py +71 -0
  400. cartography/models/azure/sql/sqldatabase.py +85 -0
  401. cartography/models/azure/sql/sqlserver.py +50 -0
  402. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  403. cartography/models/azure/storage/__init__.py +0 -0
  404. cartography/models/azure/storage/account.py +59 -0
  405. cartography/models/azure/storage/blobcontainer.py +85 -0
  406. cartography/models/azure/storage/blobservice.py +71 -0
  407. cartography/models/azure/storage/fileservice.py +71 -0
  408. cartography/models/azure/storage/fileshare.py +82 -0
  409. cartography/models/azure/storage/queue.py +71 -0
  410. cartography/models/azure/storage/queueservice.py +73 -0
  411. cartography/models/azure/storage/table.py +72 -0
  412. cartography/models/azure/storage/tableservice.py +73 -0
  413. cartography/models/azure/subnet.py +101 -0
  414. cartography/models/azure/subscription.py +47 -0
  415. cartography/models/azure/tags/__init__.py +0 -0
  416. cartography/models/azure/tags/storage_tag.py +40 -0
  417. cartography/models/azure/tags/tag.py +37 -0
  418. cartography/models/azure/tenant.py +17 -0
  419. cartography/models/azure/virtual_network.py +49 -0
  420. cartography/models/azure/vm/__init__.py +0 -0
  421. cartography/models/azure/vm/datadisk.py +80 -0
  422. cartography/models/azure/vm/disk.py +55 -0
  423. cartography/models/azure/vm/snapshot.py +56 -0
  424. cartography/models/azure/vm/virtualmachine.py +59 -0
  425. cartography/models/bigfix/bigfix_computer.py +1 -1
  426. cartography/models/cloudflare/member.py +4 -0
  427. cartography/models/core/common.py +1 -0
  428. cartography/models/core/nodes.py +15 -2
  429. cartography/models/core/relationships.py +44 -0
  430. cartography/models/crowdstrike/hosts.py +1 -1
  431. cartography/models/digitalocean/droplet.py +2 -0
  432. cartography/models/duo/endpoint.py +1 -1
  433. cartography/models/duo/phone.py +2 -2
  434. cartography/models/duo/user.py +4 -0
  435. cartography/models/entra/app_role_assignment.py +115 -0
  436. cartography/models/entra/application.py +49 -0
  437. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  438. cartography/models/entra/group.py +117 -0
  439. cartography/models/entra/service_principal.py +104 -0
  440. cartography/models/entra/user.py +42 -51
  441. cartography/models/gcp/__init__.py +0 -0
  442. cartography/models/gcp/bigtable/__init__.py +0 -0
  443. cartography/models/gcp/bigtable/app_profile.py +94 -0
  444. cartography/models/gcp/bigtable/backup.py +91 -0
  445. cartography/models/gcp/bigtable/cluster.py +73 -0
  446. cartography/models/gcp/bigtable/instance.py +52 -0
  447. cartography/models/gcp/bigtable/table.py +69 -0
  448. cartography/models/gcp/compute/__init__.py +0 -0
  449. cartography/models/gcp/compute/subnet.py +74 -0
  450. cartography/models/gcp/compute/vpc.py +50 -0
  451. cartography/models/gcp/crm/__init__.py +0 -0
  452. cartography/models/gcp/crm/folders.py +98 -0
  453. cartography/models/gcp/crm/organizations.py +21 -0
  454. cartography/models/gcp/crm/projects.py +100 -0
  455. cartography/models/gcp/dns.py +109 -0
  456. cartography/models/gcp/gke.py +69 -0
  457. cartography/models/gcp/iam.py +3 -0
  458. cartography/models/gcp/permission_relationships.py +61 -0
  459. cartography/models/gcp/policy_bindings.py +93 -0
  460. cartography/models/gcp/storage/__init__.py +0 -0
  461. cartography/models/gcp/storage/bucket.py +119 -0
  462. cartography/models/github/commits.py +63 -0
  463. cartography/models/github/dependencies.py +73 -0
  464. cartography/models/github/manifests.py +49 -0
  465. cartography/models/github/users.py +10 -0
  466. cartography/models/googleworkspace/__init__.py +0 -0
  467. cartography/models/googleworkspace/device.py +132 -0
  468. cartography/models/googleworkspace/group.py +382 -0
  469. cartography/models/googleworkspace/oauth_app.py +124 -0
  470. cartography/models/googleworkspace/tenant.py +30 -0
  471. cartography/models/googleworkspace/user.py +113 -0
  472. cartography/models/gsuite/__init__.py +0 -0
  473. cartography/models/gsuite/group.py +218 -0
  474. cartography/models/gsuite/tenant.py +29 -0
  475. cartography/models/gsuite/user.py +107 -0
  476. cartography/models/kandji/device.py +1 -2
  477. cartography/models/keycloak/__init__.py +0 -0
  478. cartography/models/keycloak/authenticationexecution.py +160 -0
  479. cartography/models/keycloak/authenticationflow.py +54 -0
  480. cartography/models/keycloak/client.py +179 -0
  481. cartography/models/keycloak/group.py +101 -0
  482. cartography/models/keycloak/identityprovider.py +89 -0
  483. cartography/models/keycloak/organization.py +116 -0
  484. cartography/models/keycloak/organizationdomain.py +73 -0
  485. cartography/models/keycloak/realm.py +173 -0
  486. cartography/models/keycloak/role.py +126 -0
  487. cartography/models/keycloak/scope.py +73 -0
  488. cartography/models/keycloak/user.py +55 -0
  489. cartography/models/kubernetes/__init__.py +0 -0
  490. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  491. cartography/models/kubernetes/clusterroles.py +52 -0
  492. cartography/models/kubernetes/clusters.py +26 -0
  493. cartography/models/kubernetes/containers.py +133 -0
  494. cartography/models/kubernetes/groups.py +107 -0
  495. cartography/models/kubernetes/namespaces.py +51 -0
  496. cartography/models/kubernetes/oidc.py +51 -0
  497. cartography/models/kubernetes/pods.py +80 -0
  498. cartography/models/kubernetes/rolebindings.py +159 -0
  499. cartography/models/kubernetes/roles.py +76 -0
  500. cartography/models/kubernetes/secrets.py +79 -0
  501. cartography/models/kubernetes/serviceaccounts.py +77 -0
  502. cartography/models/kubernetes/services.py +108 -0
  503. cartography/models/kubernetes/users.py +105 -0
  504. cartography/models/lastpass/user.py +4 -0
  505. cartography/models/ontology/__init__.py +0 -0
  506. cartography/models/ontology/device.py +137 -0
  507. cartography/models/ontology/mapping/__init__.py +76 -0
  508. cartography/models/ontology/mapping/data/__init__.py +0 -0
  509. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  510. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  511. cartography/models/ontology/mapping/data/containers.py +88 -0
  512. cartography/models/ontology/mapping/data/databases.py +182 -0
  513. cartography/models/ontology/mapping/data/devices.py +194 -0
  514. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  515. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  516. cartography/models/ontology/mapping/data/users.py +63 -0
  517. cartography/models/ontology/mapping/specs.py +85 -0
  518. cartography/models/ontology/user.py +51 -0
  519. cartography/models/openai/adminapikey.py +4 -0
  520. cartography/models/openai/apikey.py +4 -0
  521. cartography/models/openai/user.py +4 -0
  522. cartography/models/scaleway/__init__.py +0 -0
  523. cartography/models/scaleway/iam/__init__.py +0 -0
  524. cartography/models/scaleway/iam/apikey.py +100 -0
  525. cartography/models/scaleway/iam/application.py +52 -0
  526. cartography/models/scaleway/iam/group.py +95 -0
  527. cartography/models/scaleway/iam/user.py +64 -0
  528. cartography/models/scaleway/instance/__init__.py +0 -0
  529. cartography/models/scaleway/instance/flexibleip.py +52 -0
  530. cartography/models/scaleway/instance/instance.py +120 -0
  531. cartography/models/scaleway/organization.py +19 -0
  532. cartography/models/scaleway/project.py +48 -0
  533. cartography/models/scaleway/storage/__init__.py +0 -0
  534. cartography/models/scaleway/storage/snapshot.py +78 -0
  535. cartography/models/scaleway/storage/volume.py +51 -0
  536. cartography/models/sentinelone/__init__.py +1 -0
  537. cartography/models/sentinelone/account.py +40 -0
  538. cartography/models/sentinelone/agent.py +50 -0
  539. cartography/models/sentinelone/application.py +44 -0
  540. cartography/models/sentinelone/application_version.py +96 -0
  541. cartography/models/sentinelone/cve.py +73 -0
  542. cartography/models/slack/__init__.py +0 -0
  543. cartography/models/slack/channels.py +92 -0
  544. cartography/models/slack/group.py +129 -0
  545. cartography/models/slack/team.py +22 -0
  546. cartography/models/slack/user.py +62 -0
  547. cartography/models/snipeit/asset.py +2 -0
  548. cartography/models/snipeit/user.py +4 -0
  549. cartography/models/spacelift/__init__.py +0 -0
  550. cartography/models/spacelift/cloudtrailevent.py +120 -0
  551. cartography/models/spacelift/run.py +162 -0
  552. cartography/models/spacelift/space.py +131 -0
  553. cartography/models/spacelift/spaceliftaccount.py +31 -0
  554. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  555. cartography/models/spacelift/stack.py +96 -0
  556. cartography/models/spacelift/user.py +63 -0
  557. cartography/models/spacelift/worker.py +97 -0
  558. cartography/models/spacelift/workerpool.py +90 -0
  559. cartography/models/tailscale/device.py +2 -1
  560. cartography/models/tailscale/user.py +6 -1
  561. cartography/models/trivy/__init__.py +0 -0
  562. cartography/models/trivy/findings.py +66 -0
  563. cartography/models/trivy/fix.py +66 -0
  564. cartography/models/trivy/package.py +71 -0
  565. cartography/rules/README.md +1 -0
  566. cartography/rules/__init__.py +0 -0
  567. cartography/rules/cli.py +261 -0
  568. cartography/rules/data/__init__.py +0 -0
  569. cartography/rules/data/rules/__init__.py +46 -0
  570. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  571. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  572. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  573. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  574. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  575. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  576. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  577. cartography/rules/data/rules/mfa_missing.py +46 -0
  578. cartography/rules/data/rules/object_storage_public.py +100 -0
  579. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  580. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  581. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  582. cartography/rules/formatters.py +108 -0
  583. cartography/rules/runners.py +216 -0
  584. cartography/rules/spec/__init__.py +0 -0
  585. cartography/rules/spec/model.py +267 -0
  586. cartography/rules/spec/result.py +38 -0
  587. cartography/sync.py +25 -5
  588. cartography/util.py +101 -31
  589. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/METADATA +61 -22
  590. cartography-0.123.0.dist-info/RECORD +856 -0
  591. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  592. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  593. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  594. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  595. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  596. cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
  597. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  598. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  599. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  600. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  601. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  602. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  603. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  604. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  605. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  606. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  607. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  608. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  609. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  610. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  611. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  612. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  613. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  614. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  615. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  616. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  617. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  618. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  619. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  620. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  621. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  622. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  623. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  624. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  625. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  626. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  627. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  628. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  629. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  630. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  631. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  632. cartography/intel/gcp/crm.py +0 -355
  633. cartography/intel/gsuite/api.py +0 -342
  634. cartography-0.104.0rc2.dist-info/RECORD +0 -455
  635. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  636. /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
  637. /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
  638. /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
  639. /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
  640. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/WHEEL +0 -0
  641. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/licenses/LICENSE +0 -0
  642. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,32 @@
1
1
  import logging
2
2
  from typing import Dict
3
3
  from typing import List
4
- from typing import Optional
5
4
 
6
5
  import neo4j
7
6
 
8
7
  from cartography.config import Config
9
8
  from cartography.util import timeit
10
9
 
10
+ from . import aks
11
+ from . import app_service
11
12
  from . import compute
13
+ from . import container_instances
12
14
  from . import cosmosdb
15
+ from . import data_factory
16
+ from . import data_factory_dataset
17
+ from . import data_factory_linked_service
18
+ from . import data_factory_pipeline
19
+ from . import data_lake
20
+ from . import event_grid
21
+ from . import functions
22
+ from . import load_balancers
23
+ from . import logic_apps
24
+ from . import monitor
25
+ from . import network
26
+ from . import permission_relationships
27
+ from . import rbac
28
+ from . import resource_groups
29
+ from . import security_center
13
30
  from . import sql
14
31
  from . import storage
15
32
  from . import subscription
@@ -27,30 +44,162 @@ def _sync_one_subscription(
27
44
  update_tag: int,
28
45
  common_job_parameters: Dict,
29
46
  ) -> None:
47
+ container_instances.sync(
48
+ neo4j_session,
49
+ credentials,
50
+ subscription_id,
51
+ update_tag,
52
+ common_job_parameters,
53
+ )
30
54
  compute.sync(
31
55
  neo4j_session,
32
- credentials.arm_credentials,
56
+ credentials.credential,
33
57
  subscription_id,
34
58
  update_tag,
35
59
  common_job_parameters,
36
60
  )
37
61
  cosmosdb.sync(
38
62
  neo4j_session,
39
- credentials.arm_credentials,
63
+ credentials.credential,
64
+ subscription_id,
65
+ update_tag,
66
+ common_job_parameters,
67
+ )
68
+ app_service.sync(
69
+ neo4j_session,
70
+ credentials,
71
+ subscription_id,
72
+ update_tag,
73
+ common_job_parameters,
74
+ )
75
+ functions.sync(
76
+ neo4j_session,
77
+ credentials,
78
+ subscription_id,
79
+ update_tag,
80
+ common_job_parameters,
81
+ )
82
+ event_grid.sync(
83
+ neo4j_session,
84
+ credentials,
85
+ subscription_id,
86
+ update_tag,
87
+ common_job_parameters,
88
+ )
89
+ logic_apps.sync(
90
+ neo4j_session,
91
+ credentials,
92
+ subscription_id,
93
+ update_tag,
94
+ common_job_parameters,
95
+ )
96
+ rbac.sync(
97
+ neo4j_session,
98
+ credentials,
40
99
  subscription_id,
41
100
  update_tag,
42
101
  common_job_parameters,
43
102
  )
44
103
  sql.sync(
45
104
  neo4j_session,
46
- credentials.arm_credentials,
105
+ credentials.credential,
47
106
  subscription_id,
48
107
  update_tag,
49
108
  common_job_parameters,
50
109
  )
51
110
  storage.sync(
52
111
  neo4j_session,
53
- credentials.arm_credentials,
112
+ credentials.credential,
113
+ subscription_id,
114
+ update_tag,
115
+ common_job_parameters,
116
+ )
117
+ resource_groups.sync(
118
+ neo4j_session,
119
+ credentials,
120
+ subscription_id,
121
+ update_tag,
122
+ common_job_parameters,
123
+ )
124
+ aks.sync(
125
+ neo4j_session,
126
+ credentials,
127
+ subscription_id,
128
+ update_tag,
129
+ common_job_parameters,
130
+ )
131
+ factories_raw = data_factory.sync_data_factories(
132
+ neo4j_session,
133
+ credentials,
134
+ subscription_id,
135
+ update_tag,
136
+ common_job_parameters,
137
+ )
138
+ linked_services_by_factory = (
139
+ data_factory_linked_service.sync_data_factory_linked_services(
140
+ neo4j_session,
141
+ credentials,
142
+ factories_raw,
143
+ subscription_id,
144
+ update_tag,
145
+ common_job_parameters,
146
+ )
147
+ )
148
+ datasets_by_factory = data_factory_dataset.sync_data_factory_datasets(
149
+ neo4j_session,
150
+ credentials,
151
+ factories_raw,
152
+ linked_services_by_factory,
153
+ subscription_id,
154
+ update_tag,
155
+ common_job_parameters,
156
+ )
157
+ data_factory_pipeline.sync_data_factory_pipelines(
158
+ neo4j_session,
159
+ credentials,
160
+ factories_raw,
161
+ datasets_by_factory,
162
+ subscription_id,
163
+ update_tag,
164
+ common_job_parameters,
165
+ )
166
+ data_lake.sync(
167
+ neo4j_session,
168
+ credentials,
169
+ subscription_id,
170
+ update_tag,
171
+ common_job_parameters,
172
+ )
173
+ network.sync(
174
+ neo4j_session,
175
+ credentials,
176
+ subscription_id,
177
+ update_tag,
178
+ common_job_parameters,
179
+ )
180
+ load_balancers.sync(
181
+ neo4j_session,
182
+ credentials,
183
+ subscription_id,
184
+ update_tag,
185
+ common_job_parameters,
186
+ )
187
+ monitor.sync(
188
+ neo4j_session,
189
+ credentials,
190
+ subscription_id,
191
+ update_tag,
192
+ common_job_parameters,
193
+ )
194
+ security_center.sync(
195
+ neo4j_session,
196
+ credentials,
197
+ subscription_id,
198
+ update_tag,
199
+ common_job_parameters,
200
+ )
201
+ permission_relationships.sync(
202
+ neo4j_session,
54
203
  subscription_id,
55
204
  update_tag,
56
205
  common_job_parameters,
@@ -59,13 +208,12 @@ def _sync_one_subscription(
59
208
 
60
209
  def _sync_tenant(
61
210
  neo4j_session: neo4j.Session,
62
- tenant_id: str,
63
- current_user: Optional[str],
211
+ credentials: Credentials,
64
212
  update_tag: int,
65
213
  common_job_parameters: Dict,
66
214
  ) -> None:
67
- logger.info("Syncing Azure Tenant: %s", tenant_id)
68
- tenant.sync(neo4j_session, tenant_id, current_user, update_tag, common_job_parameters) # type: ignore
215
+ logger.info("Syncing Azure Tenant: %s", credentials.tenant_id)
216
+ tenant.sync(neo4j_session, credentials.tenant_id, None, update_tag, common_job_parameters) # type: ignore
69
217
 
70
218
 
71
219
  def _sync_multiple_subscriptions(
@@ -106,56 +254,62 @@ def start_azure_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
106
254
  common_job_parameters = {
107
255
  "UPDATE_TAG": config.update_tag,
108
256
  "permission_relationships_file": config.permission_relationships_file,
257
+ "azure_permission_relationships_file": config.azure_permission_relationships_file,
109
258
  }
110
259
 
111
- try:
112
- if config.azure_sp_auth:
113
- credentials = Authenticator().authenticate_sp(
114
- config.azure_tenant_id,
115
- config.azure_client_id,
116
- config.azure_client_secret,
260
+ if config.azure_sp_auth:
261
+ if not (
262
+ config.azure_tenant_id
263
+ and config.azure_client_id
264
+ and config.azure_client_secret
265
+ ):
266
+ raise ValueError(
267
+ "Azure Service Principal authentication requested, but tenant ID, client ID, "
268
+ "and client secret were not all provided.",
117
269
  )
118
- else:
119
- credentials = Authenticator().authenticate_cli()
120
-
121
- except Exception as e:
122
- logger.error(
123
- (
124
- "Unable to authenticate with Azure Service Principal, an error occurred: %s."
125
- "Make sure your Azure Service Principal details are provided correctly."
126
- ),
127
- e,
270
+
271
+ credentials = Authenticator().authenticate_sp(
272
+ config.azure_tenant_id,
273
+ config.azure_client_id,
274
+ config.azure_client_secret,
275
+ )
276
+ else:
277
+ credentials = Authenticator().authenticate_cli()
278
+
279
+ if not credentials:
280
+ raise RuntimeError(
281
+ "Azure authentication failed. Ensure Azure CLI login or Service Principal credentials are configured.",
128
282
  )
129
- return
283
+
284
+ common_job_parameters["TENANT_ID"] = credentials.tenant_id
130
285
 
131
286
  _sync_tenant(
132
287
  neo4j_session,
133
- credentials.get_tenant_id(),
134
- credentials.get_current_user(),
288
+ credentials,
135
289
  config.update_tag,
136
290
  common_job_parameters,
137
291
  )
292
+ if credentials.tenant_id:
293
+ if config.azure_sync_all_subscriptions:
294
+ subscriptions = subscription.get_all_azure_subscriptions(credentials)
138
295
 
139
- if config.azure_sync_all_subscriptions:
140
- subscriptions = subscription.get_all_azure_subscriptions(credentials)
296
+ else:
297
+ sub_id_to_sync = config.azure_subscription_id or credentials.subscription_id
298
+ subscriptions = subscription.get_current_azure_subscription(
299
+ credentials,
300
+ sub_id_to_sync,
301
+ )
141
302
 
142
- else:
143
- subscriptions = subscription.get_current_azure_subscription(
144
- credentials,
145
- credentials.subscription_id,
146
- )
303
+ if not subscriptions:
304
+ raise RuntimeError(
305
+ "No Azure subscriptions found. Ensure the credentials have access to at least one subscription.",
306
+ )
147
307
 
148
- if not subscriptions:
149
- logger.warning(
150
- "No valid Azure credentials are found. No Azure subscriptions can be synced. Exiting Azure sync stage.",
308
+ _sync_multiple_subscriptions(
309
+ neo4j_session,
310
+ credentials,
311
+ credentials.tenant_id,
312
+ subscriptions,
313
+ config.update_tag,
314
+ common_job_parameters,
151
315
  )
152
- return
153
-
154
- _sync_multiple_subscriptions(
155
- neo4j_session,
156
- credentials,
157
- credentials.get_tenant_id(),
158
- subscriptions,
159
- config.update_tag,
160
- common_job_parameters,
161
- )
@@ -0,0 +1,175 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import neo4j
5
+ from azure.core.exceptions import ClientAuthenticationError
6
+ from azure.core.exceptions import HttpResponseError
7
+ from azure.mgmt.containerservice import ContainerServiceClient
8
+
9
+ from cartography.client.core.tx import load
10
+ from cartography.graph.job import GraphJob
11
+ from cartography.models.azure.aks_cluster import AzureKubernetesClusterSchema
12
+ from cartography.models.azure.aks_nodepool import AzureKubernetesNodePoolSchema
13
+ from cartography.util import timeit
14
+
15
+ from .util.credentials import Credentials
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def _get_resource_group_from_id(resource_id: str) -> str:
21
+ """
22
+ Helper function to parse the resource group name from a full resource ID string.
23
+ """
24
+ # CORRECTED: Convert to lowercase to handle case inconsistencies from the API.
25
+ parts = resource_id.lower().split("/")
26
+ try:
27
+ # The resource group name is always the string after 'resourcegroups'
28
+ rg_index = parts.index("resourcegroups")
29
+ return parts[rg_index + 1]
30
+ except (ValueError, IndexError):
31
+ logger.warning(
32
+ f"Could not parse resource group name from resource ID: {resource_id}"
33
+ )
34
+ return ""
35
+
36
+
37
+ @timeit
38
+ def get_aks_clusters(
39
+ client: ContainerServiceClient, subscription_id: str
40
+ ) -> list[dict]:
41
+ try:
42
+ return [cluster.as_dict() for cluster in client.managed_clusters.list()]
43
+ except (ClientAuthenticationError, HttpResponseError) as e:
44
+ logger.warning(
45
+ f"Failed to get AKS clusters for subscription {subscription_id}: {str(e)}"
46
+ )
47
+ return []
48
+
49
+
50
+ @timeit
51
+ def get_agent_pools(
52
+ client: ContainerServiceClient,
53
+ cluster_name: str,
54
+ resource_group_name: str,
55
+ ) -> list[dict]:
56
+ try:
57
+ return [
58
+ pool.as_dict()
59
+ for pool in client.agent_pools.list(resource_group_name, cluster_name)
60
+ ]
61
+ except (ClientAuthenticationError, HttpResponseError) as e:
62
+ logger.warning(
63
+ f"Failed to get agent pools for cluster {cluster_name}: {str(e)}"
64
+ )
65
+ return []
66
+
67
+
68
+ @timeit
69
+ def transform_aks_clusters(clusters: list[dict]) -> list[dict]:
70
+ transformed_clusters: list[dict[str, Any]] = []
71
+ for cluster in clusters:
72
+ transformed_cluster = {
73
+ "id": cluster.get("id"),
74
+ "name": cluster.get("name"),
75
+ "location": cluster.get("location"),
76
+ "provisioning_state": cluster.get("properties", {}).get(
77
+ "provisioning_state"
78
+ ),
79
+ "kubernetes_version": cluster.get("properties", {}).get(
80
+ "kubernetes_version"
81
+ ),
82
+ "fqdn": cluster.get("properties", {}).get("fqdn"),
83
+ }
84
+ transformed_clusters.append(transformed_cluster)
85
+ return transformed_clusters
86
+
87
+
88
+ @timeit
89
+ def transform_agent_pools(agent_pools: list[dict]) -> list[dict]:
90
+ transformed_pools: list[dict[str, Any]] = []
91
+ for pool in agent_pools:
92
+ transformed_pool = {
93
+ "id": pool.get("id"),
94
+ "name": pool.get("name"),
95
+ "provisioning_state": pool.get("properties", {}).get("provisioning_state"),
96
+ "vm_size": pool.get("properties", {}).get("vm_size"),
97
+ "os_type": pool.get("properties", {}).get("os_type"),
98
+ "count": pool.get("properties", {}).get("count"),
99
+ }
100
+ transformed_pools.append(transformed_pool)
101
+ return transformed_pools
102
+
103
+
104
+ @timeit
105
+ def load_aks_clusters(
106
+ neo4j_session: neo4j.Session,
107
+ data: list[dict[str, Any]],
108
+ subscription_id: str,
109
+ update_tag: int,
110
+ ) -> None:
111
+ load(
112
+ neo4j_session,
113
+ AzureKubernetesClusterSchema(),
114
+ data,
115
+ lastupdated=update_tag,
116
+ AZURE_SUBSCRIPTION_ID=subscription_id,
117
+ )
118
+
119
+
120
+ @timeit
121
+ def load_agent_pools(
122
+ neo4j_session: neo4j.Session,
123
+ data: list[dict[str, Any]],
124
+ cluster_id: str,
125
+ update_tag: int,
126
+ ) -> None:
127
+ load(
128
+ neo4j_session,
129
+ AzureKubernetesNodePoolSchema(),
130
+ data,
131
+ lastupdated=update_tag,
132
+ CLUSTER_ID=cluster_id,
133
+ )
134
+
135
+
136
+ @timeit
137
+ def cleanup_clusters(neo4j_session: neo4j.Session, common_job_parameters: dict) -> None:
138
+ GraphJob.from_node_schema(
139
+ AzureKubernetesClusterSchema(), common_job_parameters
140
+ ).run(neo4j_session)
141
+
142
+
143
+ @timeit
144
+ def sync(
145
+ neo4j_session: neo4j.Session,
146
+ credentials: Credentials,
147
+ subscription_id: str,
148
+ update_tag: int,
149
+ common_job_parameters: dict,
150
+ ) -> None:
151
+ logger.info(f"Syncing Azure Kubernetes Service for subscription {subscription_id}.")
152
+ client = ContainerServiceClient(credentials.credential, subscription_id)
153
+
154
+ clusters = get_aks_clusters(client, subscription_id)
155
+ transformed_clusters = transform_aks_clusters(clusters)
156
+ load_aks_clusters(neo4j_session, transformed_clusters, subscription_id, update_tag)
157
+
158
+ for cluster in clusters:
159
+ cluster_id = cluster.get("id")
160
+ if not cluster_id:
161
+ continue
162
+
163
+ resource_group_name = _get_resource_group_from_id(cluster_id)
164
+ if resource_group_name:
165
+ agent_pools = get_agent_pools(client, cluster["name"], resource_group_name)
166
+ transformed_pools = transform_agent_pools(agent_pools)
167
+ load_agent_pools(neo4j_session, transformed_pools, cluster_id, update_tag)
168
+
169
+ pool_cleanup_params = common_job_parameters.copy()
170
+ pool_cleanup_params["CLUSTER_ID"] = cluster_id
171
+ GraphJob.from_node_schema(
172
+ AzureKubernetesNodePoolSchema(), pool_cleanup_params
173
+ ).run(neo4j_session)
174
+
175
+ cleanup_clusters(neo4j_session, common_job_parameters)
@@ -0,0 +1,105 @@
1
+ import logging
2
+ from typing import Any
3
+ from typing import Dict
4
+ from typing import List
5
+
6
+ import neo4j
7
+ from azure.core.exceptions import ClientAuthenticationError
8
+ from azure.core.exceptions import HttpResponseError
9
+ from azure.mgmt.web import WebSiteManagementClient
10
+
11
+ from cartography.client.core.tx import load
12
+ from cartography.graph.job import GraphJob
13
+ from cartography.models.azure.app_service import AzureAppServiceSchema
14
+ from cartography.util import timeit
15
+
16
+ from .util.credentials import Credentials
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ @timeit
22
+ def get_app_services(credentials: Credentials, subscription_id: str) -> List[Dict]:
23
+ """
24
+ Get a list of App Services from the given Azure subscription.
25
+ """
26
+ try:
27
+ client = WebSiteManagementClient(credentials.credential, subscription_id)
28
+ # NOTE: This is the same API call as Functions. We get all web apps
29
+ # and then filter them in the transform stage.
30
+ return [app.as_dict() for app in client.web_apps.list()]
31
+ except (ClientAuthenticationError, HttpResponseError) as e:
32
+ logger.warning(
33
+ f"Failed to get app services for subscription {subscription_id}: {str(e)}"
34
+ )
35
+ return []
36
+
37
+
38
+ @timeit
39
+ def transform_app_services(app_services_response: List[Dict]) -> List[Dict]:
40
+ """
41
+ Transform the raw API response to the dictionary structure that the model expects.
42
+ """
43
+ transformed_apps: List[Dict[str, Any]] = []
44
+ for app in app_services_response:
45
+ if "functionapp" not in app.get("kind", ""):
46
+ transformed_app = {
47
+ "id": app.get("id"),
48
+ "name": app.get("name"),
49
+ "kind": app.get("kind"),
50
+ "location": app.get("location"),
51
+ "state": app.get("state"),
52
+ "default_host_name": app.get("default_host_name"),
53
+ "https_only": app.get("https_only"),
54
+ }
55
+ transformed_apps.append(transformed_app)
56
+ return transformed_apps
57
+
58
+
59
+ @timeit
60
+ def load_app_services(
61
+ neo4j_session: neo4j.Session,
62
+ data: List[Dict[str, Any]],
63
+ subscription_id: str,
64
+ update_tag: int,
65
+ ) -> None:
66
+ """
67
+ Load the transformed Azure App Service data to Neo4j.
68
+ """
69
+ load(
70
+ neo4j_session,
71
+ AzureAppServiceSchema(),
72
+ data,
73
+ lastupdated=update_tag,
74
+ AZURE_SUBSCRIPTION_ID=subscription_id,
75
+ )
76
+
77
+
78
+ @timeit
79
+ def cleanup_app_services(
80
+ neo4j_session: neo4j.Session, common_job_parameters: Dict
81
+ ) -> None:
82
+ """
83
+ Run the cleanup job for Azure App Services.
84
+ """
85
+ GraphJob.from_node_schema(AzureAppServiceSchema(), common_job_parameters).run(
86
+ neo4j_session
87
+ )
88
+
89
+
90
+ @timeit
91
+ def sync(
92
+ neo4j_session: neo4j.Session,
93
+ credentials: Credentials,
94
+ subscription_id: str,
95
+ update_tag: int,
96
+ common_job_parameters: Dict,
97
+ ) -> None:
98
+ """
99
+ The main sync function for Azure App Services.
100
+ """
101
+ logger.info(f"Syncing Azure App Services for subscription {subscription_id}.")
102
+ raw_apps = get_app_services(credentials, subscription_id)
103
+ transformed_apps = transform_app_services(raw_apps)
104
+ load_app_services(neo4j_session, transformed_apps, subscription_id, update_tag)
105
+ cleanup_app_services(neo4j_session, common_job_parameters)