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
@@ -0,0 +1,47 @@
1
+ from typing import Any
2
+ from typing import Generator
3
+
4
+ import requests
5
+
6
+ # Connect and read timeouts of 60 seconds each; see https://requests.readthedocs.io/en/master/user/advanced/#timeouts
7
+ _TIMEOUT = (60, 60)
8
+
9
+
10
+ def get_paginated(
11
+ api_session: requests.Session,
12
+ endpoint: str,
13
+ items_per_page: int = 100,
14
+ params: dict[str, Any] | None = None,
15
+ ) -> Generator[dict[str, Any], None, None]:
16
+ """Fetch paginated results from a REST API endpoint.
17
+
18
+ This function handles pagination by making multiple requests to the API
19
+ until all pages of results have been retrieved.
20
+
21
+ Args:
22
+ api_session (requests.Session): The requests session to use for making API calls.
23
+ endpoint (str): The API endpoint to fetch data from.
24
+ items_per_page (int, optional): The number of items to retrieve per page. Defaults to 100.
25
+ params (dict[str, Any] | None, optional): Additional query parameters to include in the request. Defaults to None.
26
+
27
+ Yields:
28
+ Generator[dict[str, Any], None, None]: A generator that yields the individual items from the paginated response.
29
+ """
30
+ has_more = True
31
+ offset = 0
32
+ while has_more:
33
+ if params is None:
34
+ payload = {}
35
+ else:
36
+ payload = params.copy()
37
+ payload["first"] = offset
38
+ payload["max"] = items_per_page
39
+ req = api_session.get(endpoint, params=payload, timeout=_TIMEOUT)
40
+ req.raise_for_status()
41
+ data = req.json()
42
+ if not data:
43
+ break
44
+ yield from data
45
+ if len(data) < items_per_page:
46
+ has_more = False
47
+ offset += len(data)
@@ -1,41 +1,87 @@
1
1
  import logging
2
2
 
3
+ import boto3
3
4
  from neo4j import Session
4
5
 
5
6
  from cartography.config import Config
7
+ from cartography.intel.kubernetes.clusters import sync_kubernetes_cluster
8
+ from cartography.intel.kubernetes.eks import sync as sync_eks
6
9
  from cartography.intel.kubernetes.namespaces import sync_namespaces
7
10
  from cartography.intel.kubernetes.pods import sync_pods
11
+ from cartography.intel.kubernetes.rbac import sync_kubernetes_rbac
8
12
  from cartography.intel.kubernetes.secrets import sync_secrets
9
13
  from cartography.intel.kubernetes.services import sync_services
10
14
  from cartography.intel.kubernetes.util import get_k8s_clients
11
- from cartography.util import run_cleanup_job
12
15
  from cartography.util import timeit
13
16
 
14
17
  logger = logging.getLogger(__name__)
15
18
 
16
19
 
20
+ def get_region_from_arn(arn: str) -> str:
21
+ """
22
+ Extract AWS region from EKS cluster ARN.
23
+ Example: arn:aws:eks:us-east-1:205930638578:cluster/infra-test-eks → us-east-1
24
+ """
25
+ parts = arn.split(":")
26
+ if len(parts) < 6 or parts[2] != "eks":
27
+ raise ValueError(f"Invalid EKS cluster ARN: {arn}")
28
+ return parts[3]
29
+
30
+
17
31
  @timeit
18
32
  def start_k8s_ingestion(session: Session, config: Config) -> None:
33
+ if not config.update_tag:
34
+ logger.error("Cartography update tag not provided.")
35
+ return
19
36
 
20
- common_job_parameters = {"UPDATE_TAG": config.update_tag}
21
37
  if not config.k8s_kubeconfig:
22
- logger.error("kubeconfig not found.")
38
+ logger.error("Kubernetes kubeconfig not provided.")
23
39
  return
24
40
 
41
+ common_job_parameters = {"UPDATE_TAG": config.update_tag}
42
+
25
43
  for client in get_k8s_clients(config.k8s_kubeconfig):
26
44
  logger.info(f"Syncing data for k8s cluster {client.name}...")
27
45
  try:
28
- cluster = sync_namespaces(session, client, config.update_tag)
29
- pods = sync_pods(session, client, config.update_tag, cluster)
30
- sync_services(session, client, config.update_tag, cluster, pods)
31
- sync_secrets(session, client, config.update_tag, cluster)
46
+ cluster_info = sync_kubernetes_cluster(
47
+ session,
48
+ client,
49
+ config.update_tag,
50
+ common_job_parameters,
51
+ )
52
+ common_job_parameters["CLUSTER_ID"] = cluster_info.get("id")
53
+
54
+ sync_namespaces(session, client, config.update_tag, common_job_parameters)
55
+ sync_kubernetes_rbac(
56
+ session, client, config.update_tag, common_job_parameters
57
+ )
58
+ if config.managed_kubernetes == "eks":
59
+ # EKS identity provider sync
60
+ boto3_session = boto3.Session()
61
+ region = get_region_from_arn(cluster_info.get("id", ""))
62
+ sync_eks(
63
+ session,
64
+ client,
65
+ boto3_session,
66
+ region,
67
+ config.update_tag,
68
+ cluster_info.get("id", ""),
69
+ cluster_info.get("name", ""),
70
+ )
71
+ all_pods = sync_pods(
72
+ session,
73
+ client,
74
+ config.update_tag,
75
+ common_job_parameters,
76
+ )
77
+ sync_secrets(session, client, config.update_tag, common_job_parameters)
78
+ sync_services(
79
+ session,
80
+ client,
81
+ all_pods,
82
+ config.update_tag,
83
+ common_job_parameters,
84
+ )
32
85
  except Exception:
33
86
  logger.exception(f"Failed to sync data for k8s cluster {client.name}...")
34
87
  raise
35
-
36
- run_cleanup_job(
37
- "kubernetes_import_cleanup.json",
38
- session,
39
- common_job_parameters,
40
- package="cartography.data.jobs.cleanup",
41
- )
@@ -0,0 +1,86 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import neo4j
5
+ from kubernetes.client.models import V1Namespace
6
+ from kubernetes.client.models import VersionInfo
7
+
8
+ from cartography.client.core.tx import load
9
+ from cartography.intel.kubernetes.util import get_epoch
10
+ from cartography.intel.kubernetes.util import K8sClient
11
+ from cartography.models.kubernetes.clusters import KubernetesClusterSchema
12
+ from cartography.util import timeit
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @timeit
18
+ def get_kubernetes_cluster_namespace(client: K8sClient) -> V1Namespace:
19
+ return client.core.read_namespace("kube-system")
20
+
21
+
22
+ @timeit
23
+ def get_kubernetes_cluster_version(client: K8sClient) -> VersionInfo:
24
+ return client.version.get_code()
25
+
26
+
27
+ def transform_kubernetes_cluster(
28
+ client: K8sClient,
29
+ namespace: V1Namespace,
30
+ version: VersionInfo,
31
+ ) -> list[dict[str, Any]]:
32
+ cluster = {
33
+ "id": namespace.metadata.uid,
34
+ "creation_timestamp": get_epoch(namespace.metadata.creation_timestamp),
35
+ "external_id": client.external_id,
36
+ "name": client.name,
37
+ "git_version": version.git_version,
38
+ "version_major": version.major,
39
+ "version_minor": version.minor,
40
+ "go_version": version.go_version,
41
+ "compiler": version.compiler,
42
+ "platform": version.platform,
43
+ }
44
+
45
+ return [cluster]
46
+
47
+
48
+ def load_kubernetes_cluster(
49
+ neo4j_session: neo4j.Session,
50
+ cluster_data: list[dict[str, Any]],
51
+ update_tag: int,
52
+ ) -> None:
53
+ logger.info(
54
+ "Loading '{}' Kubernetes cluster into graph".format(cluster_data[0].get("name"))
55
+ )
56
+ load(
57
+ neo4j_session,
58
+ KubernetesClusterSchema(),
59
+ cluster_data,
60
+ lastupdated=update_tag,
61
+ )
62
+
63
+
64
+ # cleaning up the kubernetes cluster node is currently not supported
65
+ # def cleanup(
66
+ # neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]
67
+ # ) -> None:
68
+ # logger.debug("Running cleanup job for KubernetesCluster")
69
+ # run_cleanup_job(
70
+ # "kubernetes_cluster_cleanup.json", neo4j_session, common_job_parameters
71
+ # )
72
+
73
+
74
+ @timeit
75
+ def sync_kubernetes_cluster(
76
+ neo4j_session: neo4j.Session,
77
+ client: K8sClient,
78
+ update_tag: int,
79
+ common_job_parameters: dict[str, Any],
80
+ ) -> dict[str, Any]:
81
+ namespace = get_kubernetes_cluster_namespace(client)
82
+ version = get_kubernetes_cluster_version(client)
83
+ cluster_info = transform_kubernetes_cluster(client, namespace, version)
84
+
85
+ load_kubernetes_cluster(neo4j_session, cluster_info, update_tag)
86
+ return cluster_info[0]
@@ -0,0 +1,402 @@
1
+ import logging
2
+ from typing import Any
3
+ from typing import Dict
4
+ from typing import List
5
+
6
+ import boto3
7
+ import neo4j
8
+ import yaml
9
+ from kubernetes.client.models import V1ConfigMap
10
+
11
+ from cartography.client.core.tx import load
12
+ from cartography.graph.job import GraphJob
13
+ from cartography.intel.kubernetes.util import K8sClient
14
+ from cartography.models.kubernetes.groups import KubernetesGroupSchema
15
+ from cartography.models.kubernetes.oidc import KubernetesOIDCProviderSchema
16
+ from cartography.models.kubernetes.users import KubernetesUserSchema
17
+ from cartography.util import aws_handle_regions
18
+ from cartography.util import timeit
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ @timeit
24
+ def get_aws_auth_configmap(client: K8sClient) -> V1ConfigMap:
25
+ """
26
+ Get aws-auth ConfigMap from kube-system namespace.
27
+ """
28
+ logger.info(f"Retrieving aws-auth ConfigMap from cluster {client.name}")
29
+ return client.core.read_namespaced_config_map(
30
+ name="aws-auth", namespace="kube-system"
31
+ )
32
+
33
+
34
+ def parse_aws_auth_map(configmap: V1ConfigMap) -> Dict[str, List[Dict[str, Any]]]:
35
+ """
36
+ Parse mapRoles and mapUsers from aws-auth ConfigMap.
37
+
38
+ :param configmap: V1ConfigMap containing aws-auth data
39
+ :return: Dictionary with 'roles' and 'users' keys containing their respective mappings
40
+ """
41
+ result: Dict[str, List[Dict[str, Any]]] = {"roles": [], "users": []}
42
+
43
+ # Parse mapRoles
44
+ if "mapRoles" in configmap.data:
45
+ map_roles_yaml = configmap.data["mapRoles"]
46
+ role_mappings = yaml.safe_load(map_roles_yaml) or []
47
+
48
+ # Filter out templated entries for now (https://github.com/cartography-cncf/cartography/issues/1854)
49
+ filtered_role_mappings = []
50
+ for mapping in role_mappings:
51
+ username = mapping.get("username", "")
52
+ if "{{" in username:
53
+ logger.debug(f"Skipping templated username in mapRoles: {username}")
54
+ continue
55
+ filtered_role_mappings.append(mapping)
56
+
57
+ result["roles"] = filtered_role_mappings
58
+ logger.info(
59
+ f"Parsed {len(filtered_role_mappings)} role mappings from aws-auth ConfigMap"
60
+ )
61
+ else:
62
+ logger.info("No mapRoles found in aws-auth ConfigMap")
63
+
64
+ # Parse mapUsers
65
+ if "mapUsers" in configmap.data:
66
+ map_users_yaml = configmap.data["mapUsers"]
67
+ user_mappings = yaml.safe_load(map_users_yaml) or []
68
+
69
+ filtered_user_mappings = []
70
+ for mapping in user_mappings:
71
+ username = mapping.get("username", "")
72
+ if "{{" in username:
73
+ logger.debug(f"Skipping templated username in mapUsers: {username}")
74
+ continue
75
+ filtered_user_mappings.append(mapping)
76
+
77
+ result["users"] = filtered_user_mappings
78
+ logger.info(
79
+ f"Parsed {len(filtered_user_mappings)} user mappings from aws-auth ConfigMap"
80
+ )
81
+ else:
82
+ logger.info("No mapUsers found in aws-auth ConfigMap")
83
+
84
+ return result
85
+
86
+
87
+ def transform_aws_auth_mappings(
88
+ auth_mappings: Dict[str, List[Dict[str, Any]]], cluster_name: str
89
+ ) -> Dict[str, List[Dict[str, Any]]]:
90
+ """
91
+ Transform both role and user mappings from aws-auth ConfigMap into combined user/group data.
92
+ """
93
+ all_users = []
94
+ all_groups = []
95
+
96
+ # Process role mappings if they exist
97
+ if auth_mappings.get("roles"):
98
+ for mapping in auth_mappings.get("roles", []):
99
+ role_arn = mapping.get("rolearn")
100
+ username = mapping.get("username")
101
+ group_names = mapping.get("groups", [])
102
+
103
+ if not role_arn:
104
+ continue
105
+
106
+ # Create user data with AWS role relationship (only if username is provided)
107
+ if username:
108
+ all_users.append(
109
+ {
110
+ "id": f"{cluster_name}/{username}",
111
+ "name": username,
112
+ "cluster_name": cluster_name,
113
+ "aws_role_arn": role_arn,
114
+ }
115
+ )
116
+
117
+ # Create group data with AWS role relationship for each group
118
+ for group_name in group_names:
119
+ all_groups.append(
120
+ {
121
+ "id": f"{cluster_name}/{group_name}",
122
+ "name": group_name,
123
+ "cluster_name": cluster_name,
124
+ "aws_role_arn": role_arn,
125
+ }
126
+ )
127
+
128
+ # Process user mappings if they exist
129
+ if auth_mappings.get("users"):
130
+ for mapping in auth_mappings.get("users", []):
131
+ user_arn = mapping.get("userarn")
132
+ username = mapping.get("username")
133
+ group_names = mapping.get("groups", [])
134
+
135
+ if not user_arn:
136
+ continue
137
+
138
+ # Create user data with AWS user relationship (only if username is provided)
139
+ if username:
140
+ all_users.append(
141
+ {
142
+ "id": f"{cluster_name}/{username}",
143
+ "name": username,
144
+ "cluster_name": cluster_name,
145
+ "aws_user_arn": user_arn,
146
+ }
147
+ )
148
+
149
+ # Create group data with AWS user relationship for each group
150
+ for group_name in group_names:
151
+ all_groups.append(
152
+ {
153
+ "id": f"{cluster_name}/{group_name}",
154
+ "name": group_name,
155
+ "cluster_name": cluster_name,
156
+ "aws_user_arn": user_arn,
157
+ }
158
+ )
159
+
160
+ # Count entries with vs without usernames for visibility
161
+ role_entries_with_username = sum(
162
+ 1 for mapping in auth_mappings.get("roles", []) if mapping.get("username")
163
+ )
164
+ user_entries_with_username = sum(
165
+ 1 for mapping in auth_mappings.get("users", []) if mapping.get("username")
166
+ )
167
+ total_entries_with_username = (
168
+ role_entries_with_username + user_entries_with_username
169
+ )
170
+ total_entries = len(auth_mappings.get("roles", [])) + len(
171
+ auth_mappings.get("users", [])
172
+ )
173
+ entries_without_username = total_entries - total_entries_with_username
174
+
175
+ logger.info(
176
+ f"Transformed {len(all_users)} users (from {total_entries_with_username} entries with usernames) "
177
+ f"and {len(all_groups)} groups from {len(auth_mappings.get('roles', []))} role mappings "
178
+ f"and {len(auth_mappings.get('users', []))} user mappings "
179
+ f"({entries_without_username} entries without usernames created groups only)"
180
+ )
181
+
182
+ return {"users": all_users, "groups": all_groups}
183
+
184
+
185
+ @timeit
186
+ @aws_handle_regions
187
+ def get_oidc_provider(
188
+ boto3_session: boto3.session.Session,
189
+ region: str,
190
+ cluster_name: str,
191
+ ) -> List[Dict[str, Any]]:
192
+ """
193
+ Get external OIDC identity provider configurations for an EKS cluster.
194
+
195
+ Returns raw AWS API responses for configured external identity providers.
196
+ """
197
+ client = boto3_session.client("eks", region_name=region)
198
+ oidc_providers = []
199
+
200
+ # Extract just the cluster name from ARN if needed
201
+ # ARN format: arn:aws:eks:region:account:cluster/cluster-name
202
+ if cluster_name.startswith("arn:aws:eks:"):
203
+ cluster_name = cluster_name.split("/")[-1]
204
+
205
+ # Get configured external identity provider configs
206
+ configs_response = client.list_identity_provider_configs(clusterName=cluster_name)
207
+
208
+ for config in configs_response["identityProviderConfigs"]:
209
+ if config["type"] == "oidc":
210
+ # Get detailed config for this OIDC provider
211
+ detail_response = client.describe_identity_provider_config(
212
+ clusterName=cluster_name,
213
+ identityProviderConfig={"type": "oidc", "name": config["name"]},
214
+ )
215
+
216
+ oidc_providers.append(detail_response["identityProviderConfig"]["oidc"])
217
+
218
+ return oidc_providers
219
+
220
+
221
+ def transform_oidc_provider(
222
+ oidc_providers: List[Dict[str, Any]],
223
+ cluster_name: str,
224
+ ) -> List[Dict[str, Any]]:
225
+ """
226
+ Transform raw AWS OIDC provider data into standardized format.
227
+
228
+ Takes raw AWS API responses and creates OIDC provider nodes that match
229
+ the KubernetesOIDCProvider data model for infrastructure metadata.
230
+ """
231
+ transformed_providers = []
232
+
233
+ for provider in oidc_providers:
234
+ # Extract fields from raw AWS API response
235
+ provider_name = provider["identityProviderConfigName"]
236
+ issuer_url = provider["issuerUrl"]
237
+
238
+ # Create a unique ID for the external OIDC provider
239
+ # Format: cluster_name/oidc/provider_name
240
+ provider_id = f"{cluster_name}/oidc/{provider_name}"
241
+
242
+ transformed_provider = {
243
+ "id": provider_id,
244
+ "issuer_url": issuer_url,
245
+ "cluster_name": cluster_name,
246
+ "k8s_platform": "eks",
247
+ "client_id": provider.get("clientId", ""),
248
+ "status": provider.get("status", "UNKNOWN"),
249
+ "name": provider_name,
250
+ }
251
+
252
+ transformed_providers.append(transformed_provider)
253
+
254
+ return transformed_providers
255
+
256
+
257
+ def load_oidc_provider(
258
+ neo4j_session: neo4j.Session,
259
+ oidc_providers: List[Dict[str, Any]],
260
+ update_tag: int,
261
+ cluster_id: str,
262
+ cluster_name: str,
263
+ ) -> None:
264
+ """
265
+ Load OIDC providers and their relationships to users and groups into Neo4j.
266
+ """
267
+ logger.info(f"Loading {len(oidc_providers)} EKS OIDC providers")
268
+ load(
269
+ neo4j_session,
270
+ KubernetesOIDCProviderSchema(),
271
+ oidc_providers,
272
+ lastupdated=update_tag,
273
+ CLUSTER_ID=cluster_id,
274
+ CLUSTER_NAME=cluster_name,
275
+ )
276
+
277
+
278
+ def load_aws_auth_mappings(
279
+ neo4j_session: neo4j.Session,
280
+ users: List[Dict[str, Any]],
281
+ groups: List[Dict[str, Any]],
282
+ update_tag: int,
283
+ cluster_id: str,
284
+ cluster_name: str,
285
+ ) -> None:
286
+ """
287
+ Load Kubernetes Users/Groups with AWS Role and User relationships into Neo4j using schema-based loading.
288
+ """
289
+ logger.info(f"Loading {len(users)} Kubernetes Users with AWS mappings")
290
+
291
+ # Load Kubernetes Users with AWS relationships
292
+ if users:
293
+ load(
294
+ neo4j_session,
295
+ KubernetesUserSchema(),
296
+ users,
297
+ lastupdated=update_tag,
298
+ CLUSTER_ID=cluster_id,
299
+ CLUSTER_NAME=cluster_name,
300
+ )
301
+
302
+ logger.info(f"Loading {len(groups)} Kubernetes Groups with AWS mappings")
303
+
304
+ # Load Kubernetes Groups with AWS relationships
305
+ if groups:
306
+ load(
307
+ neo4j_session,
308
+ KubernetesGroupSchema(),
309
+ groups,
310
+ lastupdated=update_tag,
311
+ CLUSTER_ID=cluster_id,
312
+ CLUSTER_NAME=cluster_name,
313
+ )
314
+
315
+
316
+ def cleanup(
317
+ neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]
318
+ ) -> None:
319
+ logger.debug("Running cleanup job for EKS AWS Role and User relationships")
320
+
321
+ cleanup_job = GraphJob.from_node_schema(
322
+ KubernetesUserSchema(), common_job_parameters
323
+ )
324
+ cleanup_job.run(neo4j_session)
325
+
326
+ cleanup_job = GraphJob.from_node_schema(
327
+ KubernetesGroupSchema(), common_job_parameters
328
+ )
329
+ cleanup_job.run(neo4j_session)
330
+
331
+
332
+ def sync(
333
+ neo4j_session: neo4j.Session,
334
+ k8s_client: K8sClient,
335
+ boto3_session: boto3.session.Session,
336
+ region: str,
337
+ update_tag: int,
338
+ cluster_id: str,
339
+ cluster_name: str,
340
+ ) -> None:
341
+ """
342
+ Sync EKS identity providers:
343
+ 1. AWS IAM role and user mappings (aws-auth ConfigMap)
344
+ 2. External OIDC providers (EKS API)
345
+ """
346
+ logger.info(f"Starting EKS identity provider sync for cluster {cluster_name}")
347
+
348
+ # 1. Sync AWS IAM mappings (aws-auth ConfigMap)
349
+ logger.info("Syncing AWS IAM mappings from aws-auth ConfigMap")
350
+ configmap = get_aws_auth_configmap(k8s_client)
351
+ auth_mappings = parse_aws_auth_map(configmap)
352
+
353
+ # Transform and load both role and user mappings
354
+ if auth_mappings.get("roles") or auth_mappings.get("users"):
355
+ transformed_data = transform_aws_auth_mappings(auth_mappings, cluster_name)
356
+ load_aws_auth_mappings(
357
+ neo4j_session,
358
+ transformed_data["users"],
359
+ transformed_data["groups"],
360
+ update_tag,
361
+ cluster_id,
362
+ cluster_name,
363
+ )
364
+ logger.info(
365
+ f"Successfully synced {len(auth_mappings.get('roles', []))} AWS IAM role mappings "
366
+ f"and {len(auth_mappings.get('users', []))} AWS IAM user mappings"
367
+ )
368
+ else:
369
+ logger.info("No role or user mappings found in aws-auth ConfigMap")
370
+
371
+ # 2. Sync External OIDC providers (EKS API)
372
+ logger.info("Syncing external OIDC providers from EKS API")
373
+
374
+ # Get OIDC providers from EKS API
375
+ oidc_provider = get_oidc_provider(boto3_session, region, cluster_name)
376
+
377
+ if oidc_provider:
378
+ # Transform OIDC providers (infrastructure metadata only)
379
+ transformed_oidc_provider = transform_oidc_provider(oidc_provider, cluster_name)
380
+
381
+ # Load OIDC providers
382
+ load_oidc_provider(
383
+ neo4j_session,
384
+ transformed_oidc_provider,
385
+ update_tag,
386
+ cluster_id,
387
+ cluster_name,
388
+ )
389
+ logger.info(f"Successfully synced {len(oidc_provider)} external OIDC provider")
390
+ else:
391
+ logger.info("No external OIDC provider found for cluster")
392
+
393
+ # Cleanup
394
+ common_job_parameters = {
395
+ "UPDATE_TAG": update_tag,
396
+ "CLUSTER_ID": cluster_id,
397
+ }
398
+ cleanup(neo4j_session, common_job_parameters)
399
+
400
+ logger.info(
401
+ f"Successfully completed EKS identity provider sync for cluster {cluster_name}"
402
+ )