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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (822) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +34 -0
  3. cartography/cli.py +903 -225
  4. cartography/client/aws/__init__.py +19 -0
  5. cartography/client/aws/ecr.py +51 -0
  6. cartography/client/core/tx.py +400 -27
  7. cartography/config.py +215 -10
  8. cartography/data/azure_permission_relationships.yaml +20 -0
  9. cartography/data/gcp_permission_relationships.yaml +21 -0
  10. cartography/data/indexes.cypher +1 -200
  11. cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
  12. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  13. cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
  14. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  15. cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
  16. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  17. cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
  18. cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
  19. cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
  20. cartography/driftdetect/__main__.py +1 -2
  21. cartography/driftdetect/add_shortcut.py +10 -2
  22. cartography/driftdetect/cli.py +72 -75
  23. cartography/driftdetect/detect_deviations.py +7 -3
  24. cartography/driftdetect/get_states.py +20 -8
  25. cartography/driftdetect/model.py +5 -5
  26. cartography/driftdetect/serializers.py +8 -6
  27. cartography/driftdetect/storage.py +2 -2
  28. cartography/graph/cleanupbuilder.py +255 -35
  29. cartography/graph/job.py +104 -20
  30. cartography/graph/querybuilder.py +689 -91
  31. cartography/graph/statement.py +49 -36
  32. cartography/intel/airbyte/__init__.py +105 -0
  33. cartography/intel/airbyte/connections.py +120 -0
  34. cartography/intel/airbyte/destinations.py +81 -0
  35. cartography/intel/airbyte/organizations.py +59 -0
  36. cartography/intel/airbyte/sources.py +78 -0
  37. cartography/intel/airbyte/tags.py +64 -0
  38. cartography/intel/airbyte/users.py +106 -0
  39. cartography/intel/airbyte/util.py +122 -0
  40. cartography/intel/airbyte/workspaces.py +63 -0
  41. cartography/intel/analysis.py +4 -1
  42. cartography/intel/anthropic/__init__.py +62 -0
  43. cartography/intel/anthropic/apikeys.py +72 -0
  44. cartography/intel/anthropic/users.py +75 -0
  45. cartography/intel/anthropic/util.py +51 -0
  46. cartography/intel/anthropic/workspaces.py +95 -0
  47. cartography/intel/aws/__init__.py +137 -59
  48. cartography/intel/aws/acm.py +124 -0
  49. cartography/intel/aws/apigateway.py +482 -217
  50. cartography/intel/aws/apigatewayv2.py +116 -0
  51. cartography/intel/aws/cloudtrail.py +105 -0
  52. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  53. cartography/intel/aws/cloudwatch.py +239 -0
  54. cartography/intel/aws/codebuild.py +132 -0
  55. cartography/intel/aws/cognito.py +201 -0
  56. cartography/intel/aws/config.py +63 -23
  57. cartography/intel/aws/dynamodb.py +108 -40
  58. cartography/intel/aws/ec2/__init__.py +2 -2
  59. cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
  60. cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
  61. cartography/intel/aws/ec2/images.py +74 -39
  62. cartography/intel/aws/ec2/instances.py +262 -137
  63. cartography/intel/aws/ec2/internet_gateways.py +44 -13
  64. cartography/intel/aws/ec2/key_pairs.py +72 -39
  65. cartography/intel/aws/ec2/launch_templates.py +143 -66
  66. cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
  67. cartography/intel/aws/ec2/load_balancers.py +165 -147
  68. cartography/intel/aws/ec2/network_acls.py +233 -0
  69. cartography/intel/aws/ec2/network_interfaces.py +150 -87
  70. cartography/intel/aws/ec2/reserved_instances.py +48 -17
  71. cartography/intel/aws/ec2/route_tables.py +327 -0
  72. cartography/intel/aws/ec2/security_groups.py +189 -121
  73. cartography/intel/aws/ec2/snapshots.py +93 -91
  74. cartography/intel/aws/ec2/subnets.py +70 -58
  75. cartography/intel/aws/ec2/tgw.py +111 -39
  76. cartography/intel/aws/ec2/util.py +1 -1
  77. cartography/intel/aws/ec2/volumes.py +69 -41
  78. cartography/intel/aws/ec2/vpc.py +157 -116
  79. cartography/intel/aws/ec2/vpc_peerings.py +317 -121
  80. cartography/intel/aws/ecr.py +336 -93
  81. cartography/intel/aws/ecr_image_layers.py +923 -0
  82. cartography/intel/aws/ecs.py +310 -403
  83. cartography/intel/aws/efs.py +261 -0
  84. cartography/intel/aws/eks.py +55 -29
  85. cartography/intel/aws/elasticache.py +130 -83
  86. cartography/intel/aws/elasticsearch.py +70 -24
  87. cartography/intel/aws/emr.py +61 -23
  88. cartography/intel/aws/eventbridge.py +164 -0
  89. cartography/intel/aws/glue.py +181 -0
  90. cartography/intel/aws/guardduty.py +443 -0
  91. cartography/intel/aws/iam.py +978 -464
  92. cartography/intel/aws/iam_instance_profiles.py +73 -0
  93. cartography/intel/aws/identitycenter.py +847 -0
  94. cartography/intel/aws/inspector.py +330 -133
  95. cartography/intel/aws/kms.py +235 -209
  96. cartography/intel/aws/lambda_function.py +328 -176
  97. cartography/intel/aws/organizations.py +40 -19
  98. cartography/intel/aws/permission_relationships.py +144 -68
  99. cartography/intel/aws/rds.py +467 -412
  100. cartography/intel/aws/redshift.py +116 -50
  101. cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
  102. cartography/intel/aws/resources.py +80 -42
  103. cartography/intel/aws/route53.py +419 -318
  104. cartography/intel/aws/s3.py +489 -96
  105. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  106. cartography/intel/aws/secretsmanager.py +217 -40
  107. cartography/intel/aws/securityhub.py +23 -10
  108. cartography/intel/aws/sns.py +226 -0
  109. cartography/intel/aws/sqs.py +74 -96
  110. cartography/intel/aws/ssm.py +142 -33
  111. cartography/intel/aws/util/arns.py +7 -7
  112. cartography/intel/aws/util/common.py +31 -4
  113. cartography/intel/azure/__init__.py +259 -46
  114. cartography/intel/azure/aks.py +175 -0
  115. cartography/intel/azure/app_service.py +105 -0
  116. cartography/intel/azure/compute.py +141 -120
  117. cartography/intel/azure/container_instances.py +95 -0
  118. cartography/intel/azure/cosmosdb.py +706 -519
  119. cartography/intel/azure/data_factory.py +85 -0
  120. cartography/intel/azure/data_factory_dataset.py +128 -0
  121. cartography/intel/azure/data_factory_linked_service.py +119 -0
  122. cartography/intel/azure/data_factory_pipeline.py +142 -0
  123. cartography/intel/azure/data_lake.py +124 -0
  124. cartography/intel/azure/event_grid.py +94 -0
  125. cartography/intel/azure/functions.py +124 -0
  126. cartography/intel/azure/load_balancers.py +263 -0
  127. cartography/intel/azure/logic_apps.py +101 -0
  128. cartography/intel/azure/monitor.py +105 -0
  129. cartography/intel/azure/network.py +467 -0
  130. cartography/intel/azure/permission_relationships.py +466 -0
  131. cartography/intel/azure/rbac.py +309 -0
  132. cartography/intel/azure/resource_groups.py +82 -0
  133. cartography/intel/azure/security_center.py +106 -0
  134. cartography/intel/azure/sql.py +436 -392
  135. cartography/intel/azure/storage.py +467 -335
  136. cartography/intel/azure/subscription.py +49 -55
  137. cartography/intel/azure/tenant.py +46 -28
  138. cartography/intel/azure/util/common.py +13 -0
  139. cartography/intel/azure/util/credentials.py +58 -143
  140. cartography/intel/azure/util/tag.py +41 -0
  141. cartography/intel/bigfix/__init__.py +2 -2
  142. cartography/intel/bigfix/computers.py +93 -65
  143. cartography/intel/cloudflare/__init__.py +74 -0
  144. cartography/intel/cloudflare/accounts.py +57 -0
  145. cartography/intel/cloudflare/dnsrecords.py +64 -0
  146. cartography/intel/cloudflare/members.py +75 -0
  147. cartography/intel/cloudflare/roles.py +65 -0
  148. cartography/intel/cloudflare/zones.py +64 -0
  149. cartography/intel/create_indexes.py +5 -3
  150. cartography/intel/crowdstrike/__init__.py +26 -12
  151. cartography/intel/crowdstrike/endpoints.py +17 -45
  152. cartography/intel/crowdstrike/spotlight.py +13 -5
  153. cartography/intel/cve/__init__.py +91 -26
  154. cartography/intel/cve/feed.py +77 -56
  155. cartography/intel/digitalocean/__init__.py +22 -13
  156. cartography/intel/digitalocean/compute.py +75 -108
  157. cartography/intel/digitalocean/management.py +44 -80
  158. cartography/intel/digitalocean/platform.py +48 -43
  159. cartography/intel/dns.py +41 -12
  160. cartography/intel/duo/__init__.py +21 -16
  161. cartography/intel/duo/api_host.py +14 -9
  162. cartography/intel/duo/endpoints.py +50 -45
  163. cartography/intel/duo/groups.py +18 -14
  164. cartography/intel/duo/phones.py +37 -34
  165. cartography/intel/duo/tokens.py +26 -23
  166. cartography/intel/duo/users.py +54 -50
  167. cartography/intel/duo/web_authn_credentials.py +30 -25
  168. cartography/intel/entra/__init__.py +160 -0
  169. cartography/intel/entra/app_role_assignments.py +284 -0
  170. cartography/intel/entra/applications.py +182 -0
  171. cartography/intel/entra/federation/__init__.py +0 -0
  172. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  173. cartography/intel/entra/groups.py +198 -0
  174. cartography/intel/entra/ou.py +136 -0
  175. cartography/intel/entra/service_principals.py +217 -0
  176. cartography/intel/entra/users.py +259 -0
  177. cartography/intel/gcp/__init__.py +381 -175
  178. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  179. cartography/intel/gcp/bigtable_backup.py +91 -0
  180. cartography/intel/gcp/bigtable_cluster.py +93 -0
  181. cartography/intel/gcp/bigtable_instance.py +86 -0
  182. cartography/intel/gcp/bigtable_table.py +87 -0
  183. cartography/intel/gcp/cai.py +292 -0
  184. cartography/intel/gcp/clients.py +112 -0
  185. cartography/intel/gcp/compute.py +521 -325
  186. cartography/intel/gcp/crm/__init__.py +0 -0
  187. cartography/intel/gcp/crm/folders.py +114 -0
  188. cartography/intel/gcp/crm/orgs.py +70 -0
  189. cartography/intel/gcp/crm/projects.py +120 -0
  190. cartography/intel/gcp/dns.py +134 -179
  191. cartography/intel/gcp/gke.py +100 -107
  192. cartography/intel/gcp/iam.py +262 -0
  193. cartography/intel/gcp/permission_relationships.py +394 -0
  194. cartography/intel/gcp/policy_bindings.py +225 -0
  195. cartography/intel/gcp/storage.py +103 -158
  196. cartography/intel/github/__init__.py +66 -27
  197. cartography/intel/github/commits.py +423 -0
  198. cartography/intel/github/repos.py +871 -160
  199. cartography/intel/github/teams.py +386 -53
  200. cartography/intel/github/users.py +214 -49
  201. cartography/intel/github/util.py +50 -35
  202. cartography/intel/googleworkspace/__init__.py +193 -0
  203. cartography/intel/googleworkspace/devices.py +254 -0
  204. cartography/intel/googleworkspace/groups.py +568 -0
  205. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  206. cartography/intel/googleworkspace/tenant.py +85 -0
  207. cartography/intel/googleworkspace/users.py +138 -0
  208. cartography/intel/gsuite/__init__.py +101 -42
  209. cartography/intel/gsuite/groups.py +291 -0
  210. cartography/intel/gsuite/users.py +142 -0
  211. cartography/intel/jamf/__init__.py +19 -1
  212. cartography/intel/jamf/computers.py +37 -8
  213. cartography/intel/jamf/util.py +7 -2
  214. cartography/intel/kandji/__init__.py +6 -3
  215. cartography/intel/kandji/devices.py +40 -10
  216. cartography/intel/keycloak/__init__.py +153 -0
  217. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  218. cartography/intel/keycloak/authenticationflows.py +77 -0
  219. cartography/intel/keycloak/clients.py +187 -0
  220. cartography/intel/keycloak/groups.py +126 -0
  221. cartography/intel/keycloak/identityproviders.py +94 -0
  222. cartography/intel/keycloak/organizations.py +163 -0
  223. cartography/intel/keycloak/realms.py +61 -0
  224. cartography/intel/keycloak/roles.py +202 -0
  225. cartography/intel/keycloak/scopes.py +73 -0
  226. cartography/intel/keycloak/users.py +70 -0
  227. cartography/intel/keycloak/util.py +47 -0
  228. cartography/intel/kubernetes/__init__.py +60 -14
  229. cartography/intel/kubernetes/clusters.py +86 -0
  230. cartography/intel/kubernetes/eks.py +402 -0
  231. cartography/intel/kubernetes/namespaces.py +60 -55
  232. cartography/intel/kubernetes/pods.py +171 -75
  233. cartography/intel/kubernetes/rbac.py +597 -0
  234. cartography/intel/kubernetes/secrets.py +95 -45
  235. cartography/intel/kubernetes/services.py +131 -63
  236. cartography/intel/kubernetes/util.py +142 -14
  237. cartography/intel/lastpass/__init__.py +2 -2
  238. cartography/intel/lastpass/users.py +23 -12
  239. cartography/intel/oci/__init__.py +44 -11
  240. cartography/intel/oci/iam.py +157 -47
  241. cartography/intel/oci/organizations.py +16 -7
  242. cartography/intel/oci/utils.py +71 -25
  243. cartography/intel/okta/__init__.py +66 -15
  244. cartography/intel/okta/applications.py +57 -25
  245. cartography/intel/okta/awssaml.py +105 -41
  246. cartography/intel/okta/factors.py +19 -5
  247. cartography/intel/okta/groups.py +61 -31
  248. cartography/intel/okta/organization.py +8 -2
  249. cartography/intel/okta/origins.py +9 -3
  250. cartography/intel/okta/roles.py +20 -7
  251. cartography/intel/okta/users.py +31 -10
  252. cartography/intel/okta/utils.py +6 -4
  253. cartography/intel/ontology/__init__.py +44 -0
  254. cartography/intel/ontology/devices.py +54 -0
  255. cartography/intel/ontology/users.py +54 -0
  256. cartography/intel/ontology/utils.py +176 -0
  257. cartography/intel/openai/__init__.py +86 -0
  258. cartography/intel/openai/adminapikeys.py +89 -0
  259. cartography/intel/openai/apikeys.py +96 -0
  260. cartography/intel/openai/projects.py +97 -0
  261. cartography/intel/openai/serviceaccounts.py +82 -0
  262. cartography/intel/openai/users.py +75 -0
  263. cartography/intel/openai/util.py +45 -0
  264. cartography/intel/pagerduty/__init__.py +8 -7
  265. cartography/intel/pagerduty/escalation_policies.py +31 -12
  266. cartography/intel/pagerduty/schedules.py +21 -8
  267. cartography/intel/pagerduty/services.py +18 -7
  268. cartography/intel/pagerduty/teams.py +13 -5
  269. cartography/intel/pagerduty/users.py +6 -2
  270. cartography/intel/pagerduty/vendors.py +6 -2
  271. cartography/intel/scaleway/__init__.py +127 -0
  272. cartography/intel/scaleway/iam/__init__.py +0 -0
  273. cartography/intel/scaleway/iam/apikeys.py +71 -0
  274. cartography/intel/scaleway/iam/applications.py +71 -0
  275. cartography/intel/scaleway/iam/groups.py +71 -0
  276. cartography/intel/scaleway/iam/users.py +71 -0
  277. cartography/intel/scaleway/instances/__init__.py +0 -0
  278. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  279. cartography/intel/scaleway/instances/instances.py +92 -0
  280. cartography/intel/scaleway/projects.py +79 -0
  281. cartography/intel/scaleway/storage/__init__.py +0 -0
  282. cartography/intel/scaleway/storage/snapshots.py +86 -0
  283. cartography/intel/scaleway/storage/volumes.py +84 -0
  284. cartography/intel/scaleway/utils.py +37 -0
  285. cartography/intel/semgrep/__init__.py +30 -5
  286. cartography/intel/semgrep/dependencies.py +255 -0
  287. cartography/intel/semgrep/deployment.py +69 -0
  288. cartography/intel/semgrep/findings.py +157 -117
  289. cartography/intel/sentinelone/__init__.py +75 -0
  290. cartography/intel/sentinelone/account.py +140 -0
  291. cartography/intel/sentinelone/agent.py +139 -0
  292. cartography/intel/sentinelone/api.py +124 -0
  293. cartography/intel/sentinelone/application.py +248 -0
  294. cartography/intel/sentinelone/cve.py +119 -0
  295. cartography/intel/sentinelone/utils.py +28 -0
  296. cartography/intel/slack/__init__.py +78 -0
  297. cartography/intel/slack/channels.py +80 -0
  298. cartography/intel/slack/groups.py +90 -0
  299. cartography/intel/slack/teams.py +65 -0
  300. cartography/intel/slack/users.py +57 -0
  301. cartography/intel/slack/utils.py +29 -0
  302. cartography/intel/snipeit/__init__.py +44 -0
  303. cartography/intel/snipeit/asset.py +80 -0
  304. cartography/intel/snipeit/user.py +78 -0
  305. cartography/intel/snipeit/util.py +40 -0
  306. cartography/intel/spacelift/__init__.py +161 -0
  307. cartography/intel/spacelift/account.py +73 -0
  308. cartography/intel/spacelift/ec2_ownership.py +280 -0
  309. cartography/intel/spacelift/runs.py +463 -0
  310. cartography/intel/spacelift/spaces.py +112 -0
  311. cartography/intel/spacelift/stacks.py +119 -0
  312. cartography/intel/spacelift/util.py +122 -0
  313. cartography/intel/spacelift/workerpools.py +131 -0
  314. cartography/intel/spacelift/workers.py +128 -0
  315. cartography/intel/tailscale/__init__.py +77 -0
  316. cartography/intel/tailscale/acls.py +146 -0
  317. cartography/intel/tailscale/devices.py +127 -0
  318. cartography/intel/tailscale/postureintegrations.py +81 -0
  319. cartography/intel/tailscale/tailnets.py +76 -0
  320. cartography/intel/tailscale/users.py +80 -0
  321. cartography/intel/tailscale/utils.py +132 -0
  322. cartography/intel/trivy/__init__.py +272 -0
  323. cartography/intel/trivy/scanner.py +386 -0
  324. cartography/models/airbyte/__init__.py +0 -0
  325. cartography/models/airbyte/connection.py +138 -0
  326. cartography/models/airbyte/destination.py +75 -0
  327. cartography/models/airbyte/organization.py +19 -0
  328. cartography/models/airbyte/source.py +75 -0
  329. cartography/models/airbyte/stream.py +74 -0
  330. cartography/models/airbyte/tag.py +69 -0
  331. cartography/models/airbyte/user.py +115 -0
  332. cartography/models/airbyte/workspace.py +46 -0
  333. cartography/models/anthropic/__init__.py +0 -0
  334. cartography/models/anthropic/apikey.py +94 -0
  335. cartography/models/anthropic/organization.py +19 -0
  336. cartography/models/anthropic/user.py +52 -0
  337. cartography/models/anthropic/workspace.py +90 -0
  338. cartography/models/aws/acm/__init__.py +0 -0
  339. cartography/models/aws/acm/certificate.py +75 -0
  340. cartography/models/aws/apigateway/__init__.py +0 -0
  341. cartography/models/aws/apigateway/apigateway.py +51 -0
  342. cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
  343. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  344. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  345. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  346. cartography/models/aws/apigateway/apigatewayresource.py +70 -0
  347. cartography/models/aws/apigateway/apigatewaystage.py +75 -0
  348. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  349. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  350. cartography/models/aws/cloudtrail/__init__.py +0 -0
  351. cartography/models/aws/cloudtrail/management_events.py +153 -0
  352. cartography/models/aws/cloudtrail/trail.py +106 -0
  353. cartography/models/aws/cloudwatch/__init__.py +0 -0
  354. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  355. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  356. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  357. cartography/models/aws/codebuild/__init__.py +0 -0
  358. cartography/models/aws/codebuild/project.py +49 -0
  359. cartography/models/aws/cognito/__init__.py +0 -0
  360. cartography/models/aws/cognito/identity_pool.py +70 -0
  361. cartography/models/aws/cognito/user_pool.py +47 -0
  362. cartography/models/aws/dynamodb/gsi.py +30 -22
  363. cartography/models/aws/dynamodb/tables.py +27 -17
  364. cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
  365. cartography/models/aws/ec2/images.py +36 -34
  366. cartography/models/aws/ec2/instances.py +85 -38
  367. cartography/models/aws/ec2/keypair.py +59 -0
  368. cartography/models/aws/ec2/keypair_instance.py +76 -0
  369. cartography/models/aws/ec2/launch_configurations.py +59 -0
  370. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  371. cartography/models/aws/ec2/launch_templates.py +21 -17
  372. cartography/models/aws/ec2/load_balancer_listeners.py +72 -0
  373. cartography/models/aws/ec2/load_balancers.py +112 -0
  374. cartography/models/aws/ec2/network_acl_rules.py +106 -0
  375. cartography/models/aws/ec2/network_acls.py +95 -0
  376. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  377. cartography/models/aws/ec2/networkinterfaces.py +57 -37
  378. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  379. cartography/models/aws/ec2/reservations.py +18 -14
  380. cartography/models/aws/ec2/route_table_associations.py +97 -0
  381. cartography/models/aws/ec2/route_tables.py +128 -0
  382. cartography/models/aws/ec2/routes.py +85 -0
  383. cartography/models/aws/ec2/security_group_rules.py +109 -0
  384. cartography/models/aws/ec2/security_groups.py +90 -0
  385. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  386. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  387. cartography/models/aws/ec2/snapshots.py +58 -0
  388. cartography/models/aws/ec2/subnet_instance.py +26 -19
  389. cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
  390. cartography/models/aws/ec2/subnets.py +65 -0
  391. cartography/models/aws/ec2/volumes.py +67 -40
  392. cartography/models/aws/ec2/vpc.py +46 -0
  393. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  394. cartography/models/aws/ec2/vpc_peering.py +157 -0
  395. cartography/models/aws/ecr/__init__.py +0 -0
  396. cartography/models/aws/ecr/image.py +146 -0
  397. cartography/models/aws/ecr/image_layer.py +107 -0
  398. cartography/models/aws/ecr/repository.py +72 -0
  399. cartography/models/aws/ecr/repository_image.py +95 -0
  400. cartography/models/aws/ecs/__init__.py +0 -0
  401. cartography/models/aws/ecs/clusters.py +64 -0
  402. cartography/models/aws/ecs/container_definitions.py +93 -0
  403. cartography/models/aws/ecs/container_instances.py +84 -0
  404. cartography/models/aws/ecs/containers.py +101 -0
  405. cartography/models/aws/ecs/services.py +134 -0
  406. cartography/models/aws/ecs/task_definitions.py +135 -0
  407. cartography/models/aws/ecs/tasks.py +134 -0
  408. cartography/models/aws/efs/__init__.py +0 -0
  409. cartography/models/aws/efs/access_point.py +77 -0
  410. cartography/models/aws/efs/file_system.py +60 -0
  411. cartography/models/aws/efs/mount_target.py +79 -0
  412. cartography/models/aws/eks/clusters.py +23 -21
  413. cartography/models/aws/elasticache/__init__.py +0 -0
  414. cartography/models/aws/elasticache/cluster.py +65 -0
  415. cartography/models/aws/elasticache/topic.py +67 -0
  416. cartography/models/aws/emr.py +32 -30
  417. cartography/models/aws/eventbridge/__init__.py +0 -0
  418. cartography/models/aws/eventbridge/rule.py +77 -0
  419. cartography/models/aws/eventbridge/target.py +71 -0
  420. cartography/models/aws/glue/__init__.py +0 -0
  421. cartography/models/aws/glue/connection.py +51 -0
  422. cartography/models/aws/glue/job.py +69 -0
  423. cartography/models/aws/guardduty/__init__.py +1 -0
  424. cartography/models/aws/guardduty/detectors.py +50 -0
  425. cartography/models/aws/guardduty/findings.py +121 -0
  426. cartography/models/aws/iam/__init__.py +0 -0
  427. cartography/models/aws/iam/access_key.py +103 -0
  428. cartography/models/aws/iam/account_role.py +24 -0
  429. cartography/models/aws/iam/federated_principal.py +60 -0
  430. cartography/models/aws/iam/group.py +60 -0
  431. cartography/models/aws/iam/group_membership.py +27 -0
  432. cartography/models/aws/iam/inline_policy.py +78 -0
  433. cartography/models/aws/iam/instanceprofile.py +76 -0
  434. cartography/models/aws/iam/managed_policy.py +51 -0
  435. cartography/models/aws/iam/policy_statement.py +57 -0
  436. cartography/models/aws/iam/role.py +83 -0
  437. cartography/models/aws/iam/root_principal.py +52 -0
  438. cartography/models/aws/iam/service_principal.py +30 -0
  439. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  440. cartography/models/aws/iam/user.py +59 -0
  441. cartography/models/aws/identitycenter/__init__.py +0 -0
  442. cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
  443. cartography/models/aws/identitycenter/awspermissionset.py +162 -0
  444. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  445. cartography/models/aws/identitycenter/awsssouser.py +110 -0
  446. cartography/models/aws/inspector/findings.py +124 -58
  447. cartography/models/aws/inspector/packages.py +18 -42
  448. cartography/models/aws/kms/__init__.py +0 -0
  449. cartography/models/aws/kms/aliases.py +86 -0
  450. cartography/models/aws/kms/grants.py +65 -0
  451. cartography/models/aws/kms/keys.py +88 -0
  452. cartography/models/aws/lambda_function/__init__.py +0 -0
  453. cartography/models/aws/lambda_function/alias.py +74 -0
  454. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  455. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  456. cartography/models/aws/lambda_function/layer.py +72 -0
  457. cartography/models/aws/rds/__init__.py +0 -0
  458. cartography/models/aws/rds/cluster.py +91 -0
  459. cartography/models/aws/rds/event_subscription.py +146 -0
  460. cartography/models/aws/rds/instance.py +156 -0
  461. cartography/models/aws/rds/snapshot.py +108 -0
  462. cartography/models/aws/rds/subnet_group.py +101 -0
  463. cartography/models/aws/route53/__init__.py +0 -0
  464. cartography/models/aws/route53/dnsrecord.py +235 -0
  465. cartography/models/aws/route53/nameserver.py +63 -0
  466. cartography/models/aws/route53/subzone.py +40 -0
  467. cartography/models/aws/route53/zone.py +47 -0
  468. cartography/models/aws/s3/__init__.py +0 -0
  469. cartography/models/aws/s3/account_public_access_block.py +51 -0
  470. cartography/models/aws/s3/notification.py +24 -0
  471. cartography/models/aws/secretsmanager/__init__.py +0 -0
  472. cartography/models/aws/secretsmanager/secret.py +106 -0
  473. cartography/models/aws/secretsmanager/secret_version.py +114 -0
  474. cartography/models/aws/sns/__init__.py +0 -0
  475. cartography/models/aws/sns/topic.py +50 -0
  476. cartography/models/aws/sns/topic_subscription.py +74 -0
  477. cartography/models/aws/sqs/__init__.py +0 -0
  478. cartography/models/aws/sqs/queue.py +89 -0
  479. cartography/models/aws/ssm/instance_information.py +51 -39
  480. cartography/models/aws/ssm/instance_patch.py +32 -26
  481. cartography/models/aws/ssm/parameters.py +84 -0
  482. cartography/models/azure/__init__.py +0 -0
  483. cartography/models/azure/aks_cluster.py +54 -0
  484. cartography/models/azure/aks_nodepool.py +54 -0
  485. cartography/models/azure/app_service.py +59 -0
  486. cartography/models/azure/container_instance.py +57 -0
  487. cartography/models/azure/cosmosdb/__init__.py +0 -0
  488. cartography/models/azure/cosmosdb/account.py +77 -0
  489. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  490. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  491. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  492. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  493. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  494. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  495. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  496. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  497. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  498. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  499. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  500. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  501. cartography/models/azure/data_factory/__init__.py +0 -0
  502. cartography/models/azure/data_factory/data_factory.py +51 -0
  503. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  504. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  505. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  506. cartography/models/azure/data_lake_filesystem.py +51 -0
  507. cartography/models/azure/event_grid_topic.py +57 -0
  508. cartography/models/azure/function_app.py +59 -0
  509. cartography/models/azure/load_balancer/__init__.py +0 -0
  510. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  511. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  512. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  513. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  514. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  515. cartography/models/azure/logic_apps.py +56 -0
  516. cartography/models/azure/monitor.py +54 -0
  517. cartography/models/azure/network_interface.py +112 -0
  518. cartography/models/azure/network_security_group.py +50 -0
  519. cartography/models/azure/permission_relationships.py +60 -0
  520. cartography/models/azure/principal.py +41 -0
  521. cartography/models/azure/public_ip_address.py +50 -0
  522. cartography/models/azure/rbac.py +268 -0
  523. cartography/models/azure/resource_groups.py +52 -0
  524. cartography/models/azure/security_center.py +50 -0
  525. cartography/models/azure/sql/__init__.py +0 -0
  526. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  527. cartography/models/azure/sql/elasticpool.py +77 -0
  528. cartography/models/azure/sql/failovergroup.py +73 -0
  529. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  530. cartography/models/azure/sql/replicationlink.py +81 -0
  531. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  532. cartography/models/azure/sql/restorepoint.py +74 -0
  533. cartography/models/azure/sql/serveradadministrator.py +74 -0
  534. cartography/models/azure/sql/serverdnsalias.py +71 -0
  535. cartography/models/azure/sql/sqldatabase.py +85 -0
  536. cartography/models/azure/sql/sqlserver.py +50 -0
  537. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  538. cartography/models/azure/storage/__init__.py +0 -0
  539. cartography/models/azure/storage/account.py +59 -0
  540. cartography/models/azure/storage/blobcontainer.py +85 -0
  541. cartography/models/azure/storage/blobservice.py +71 -0
  542. cartography/models/azure/storage/fileservice.py +71 -0
  543. cartography/models/azure/storage/fileshare.py +82 -0
  544. cartography/models/azure/storage/queue.py +71 -0
  545. cartography/models/azure/storage/queueservice.py +73 -0
  546. cartography/models/azure/storage/table.py +72 -0
  547. cartography/models/azure/storage/tableservice.py +73 -0
  548. cartography/models/azure/subnet.py +101 -0
  549. cartography/models/azure/subscription.py +47 -0
  550. cartography/models/azure/tags/__init__.py +0 -0
  551. cartography/models/azure/tags/storage_tag.py +40 -0
  552. cartography/models/azure/tags/tag.py +37 -0
  553. cartography/models/azure/tenant.py +17 -0
  554. cartography/models/azure/virtual_network.py +49 -0
  555. cartography/models/azure/vm/__init__.py +0 -0
  556. cartography/models/azure/vm/datadisk.py +80 -0
  557. cartography/models/azure/vm/disk.py +55 -0
  558. cartography/models/azure/vm/snapshot.py +56 -0
  559. cartography/models/azure/vm/virtualmachine.py +59 -0
  560. cartography/models/bigfix/bigfix_computer.py +42 -38
  561. cartography/models/bigfix/bigfix_root.py +3 -3
  562. cartography/models/cloudflare/__init__.py +0 -0
  563. cartography/models/cloudflare/account.py +25 -0
  564. cartography/models/cloudflare/dnsrecord.py +55 -0
  565. cartography/models/cloudflare/member.py +86 -0
  566. cartography/models/cloudflare/role.py +44 -0
  567. cartography/models/cloudflare/zone.py +59 -0
  568. cartography/models/core/common.py +53 -2
  569. cartography/models/core/nodes.py +20 -4
  570. cartography/models/core/relationships.py +58 -6
  571. cartography/models/crowdstrike/__init__.py +0 -0
  572. cartography/models/crowdstrike/hosts.py +51 -0
  573. cartography/models/cve/cve.py +34 -32
  574. cartography/models/cve/cve_feed.py +6 -6
  575. cartography/models/digitalocean/__init__.py +0 -0
  576. cartography/models/digitalocean/account.py +21 -0
  577. cartography/models/digitalocean/droplet.py +58 -0
  578. cartography/models/digitalocean/project.py +48 -0
  579. cartography/models/duo/api_host.py +3 -3
  580. cartography/models/duo/endpoint.py +43 -41
  581. cartography/models/duo/group.py +14 -14
  582. cartography/models/duo/phone.py +27 -27
  583. cartography/models/duo/token.py +16 -16
  584. cartography/models/duo/user.py +50 -44
  585. cartography/models/duo/web_authn_credential.py +27 -19
  586. cartography/models/entra/__init__.py +0 -0
  587. cartography/models/entra/app_role_assignment.py +115 -0
  588. cartography/models/entra/application.py +49 -0
  589. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  590. cartography/models/entra/group.py +117 -0
  591. cartography/models/entra/ou.py +48 -0
  592. cartography/models/entra/service_principal.py +104 -0
  593. cartography/models/entra/tenant.py +39 -0
  594. cartography/models/entra/user.py +90 -0
  595. cartography/models/gcp/__init__.py +0 -0
  596. cartography/models/gcp/bigtable/__init__.py +0 -0
  597. cartography/models/gcp/bigtable/app_profile.py +94 -0
  598. cartography/models/gcp/bigtable/backup.py +91 -0
  599. cartography/models/gcp/bigtable/cluster.py +73 -0
  600. cartography/models/gcp/bigtable/instance.py +52 -0
  601. cartography/models/gcp/bigtable/table.py +69 -0
  602. cartography/models/gcp/compute/__init__.py +0 -0
  603. cartography/models/gcp/compute/subnet.py +74 -0
  604. cartography/models/gcp/compute/vpc.py +50 -0
  605. cartography/models/gcp/crm/__init__.py +0 -0
  606. cartography/models/gcp/crm/folders.py +98 -0
  607. cartography/models/gcp/crm/organizations.py +21 -0
  608. cartography/models/gcp/crm/projects.py +100 -0
  609. cartography/models/gcp/dns.py +109 -0
  610. cartography/models/gcp/gke.py +69 -0
  611. cartography/models/gcp/iam.py +73 -0
  612. cartography/models/gcp/permission_relationships.py +61 -0
  613. cartography/models/gcp/policy_bindings.py +93 -0
  614. cartography/models/gcp/storage/__init__.py +0 -0
  615. cartography/models/gcp/storage/bucket.py +119 -0
  616. cartography/models/github/commits.py +63 -0
  617. cartography/models/github/dependencies.py +73 -0
  618. cartography/models/github/manifests.py +49 -0
  619. cartography/models/github/orgs.py +27 -0
  620. cartography/models/github/teams.py +74 -22
  621. cartography/models/github/users.py +149 -0
  622. cartography/models/googleworkspace/__init__.py +0 -0
  623. cartography/models/googleworkspace/device.py +132 -0
  624. cartography/models/googleworkspace/group.py +382 -0
  625. cartography/models/googleworkspace/oauth_app.py +124 -0
  626. cartography/models/googleworkspace/tenant.py +30 -0
  627. cartography/models/googleworkspace/user.py +113 -0
  628. cartography/models/gsuite/__init__.py +0 -0
  629. cartography/models/gsuite/group.py +218 -0
  630. cartography/models/gsuite/tenant.py +29 -0
  631. cartography/models/gsuite/user.py +107 -0
  632. cartography/models/kandji/device.py +22 -17
  633. cartography/models/kandji/tenant.py +6 -4
  634. cartography/models/keycloak/__init__.py +0 -0
  635. cartography/models/keycloak/authenticationexecution.py +160 -0
  636. cartography/models/keycloak/authenticationflow.py +54 -0
  637. cartography/models/keycloak/client.py +179 -0
  638. cartography/models/keycloak/group.py +101 -0
  639. cartography/models/keycloak/identityprovider.py +89 -0
  640. cartography/models/keycloak/organization.py +116 -0
  641. cartography/models/keycloak/organizationdomain.py +73 -0
  642. cartography/models/keycloak/realm.py +173 -0
  643. cartography/models/keycloak/role.py +126 -0
  644. cartography/models/keycloak/scope.py +73 -0
  645. cartography/models/keycloak/user.py +55 -0
  646. cartography/models/kubernetes/__init__.py +0 -0
  647. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  648. cartography/models/kubernetes/clusterroles.py +52 -0
  649. cartography/models/kubernetes/clusters.py +26 -0
  650. cartography/models/kubernetes/containers.py +133 -0
  651. cartography/models/kubernetes/groups.py +107 -0
  652. cartography/models/kubernetes/namespaces.py +51 -0
  653. cartography/models/kubernetes/oidc.py +51 -0
  654. cartography/models/kubernetes/pods.py +80 -0
  655. cartography/models/kubernetes/rolebindings.py +159 -0
  656. cartography/models/kubernetes/roles.py +76 -0
  657. cartography/models/kubernetes/secrets.py +79 -0
  658. cartography/models/kubernetes/serviceaccounts.py +77 -0
  659. cartography/models/kubernetes/services.py +108 -0
  660. cartography/models/kubernetes/users.py +105 -0
  661. cartography/models/lastpass/tenant.py +3 -3
  662. cartography/models/lastpass/user.py +36 -28
  663. cartography/models/ontology/__init__.py +0 -0
  664. cartography/models/ontology/device.py +137 -0
  665. cartography/models/ontology/mapping/__init__.py +76 -0
  666. cartography/models/ontology/mapping/data/__init__.py +0 -0
  667. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  668. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  669. cartography/models/ontology/mapping/data/containers.py +88 -0
  670. cartography/models/ontology/mapping/data/databases.py +182 -0
  671. cartography/models/ontology/mapping/data/devices.py +194 -0
  672. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  673. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  674. cartography/models/ontology/mapping/data/users.py +63 -0
  675. cartography/models/ontology/mapping/specs.py +85 -0
  676. cartography/models/ontology/user.py +51 -0
  677. cartography/models/openai/__init__.py +0 -0
  678. cartography/models/openai/adminapikey.py +94 -0
  679. cartography/models/openai/apikey.py +88 -0
  680. cartography/models/openai/organization.py +17 -0
  681. cartography/models/openai/project.py +89 -0
  682. cartography/models/openai/serviceaccount.py +50 -0
  683. cartography/models/openai/user.py +53 -0
  684. cartography/models/scaleway/__init__.py +0 -0
  685. cartography/models/scaleway/iam/__init__.py +0 -0
  686. cartography/models/scaleway/iam/apikey.py +100 -0
  687. cartography/models/scaleway/iam/application.py +52 -0
  688. cartography/models/scaleway/iam/group.py +95 -0
  689. cartography/models/scaleway/iam/user.py +64 -0
  690. cartography/models/scaleway/instance/__init__.py +0 -0
  691. cartography/models/scaleway/instance/flexibleip.py +52 -0
  692. cartography/models/scaleway/instance/instance.py +120 -0
  693. cartography/models/scaleway/organization.py +19 -0
  694. cartography/models/scaleway/project.py +48 -0
  695. cartography/models/scaleway/storage/__init__.py +0 -0
  696. cartography/models/scaleway/storage/snapshot.py +78 -0
  697. cartography/models/scaleway/storage/volume.py +51 -0
  698. cartography/models/semgrep/dependencies.py +102 -0
  699. cartography/models/semgrep/deployment.py +5 -5
  700. cartography/models/semgrep/findings.py +58 -40
  701. cartography/models/semgrep/locations.py +27 -21
  702. cartography/models/sentinelone/__init__.py +1 -0
  703. cartography/models/sentinelone/account.py +40 -0
  704. cartography/models/sentinelone/agent.py +50 -0
  705. cartography/models/sentinelone/application.py +44 -0
  706. cartography/models/sentinelone/application_version.py +96 -0
  707. cartography/models/sentinelone/cve.py +73 -0
  708. cartography/models/slack/__init__.py +0 -0
  709. cartography/models/slack/channels.py +92 -0
  710. cartography/models/slack/group.py +129 -0
  711. cartography/models/slack/team.py +22 -0
  712. cartography/models/slack/user.py +62 -0
  713. cartography/models/snipeit/__init__.py +0 -0
  714. cartography/models/snipeit/asset.py +92 -0
  715. cartography/models/snipeit/tenant.py +19 -0
  716. cartography/models/snipeit/user.py +60 -0
  717. cartography/models/spacelift/__init__.py +0 -0
  718. cartography/models/spacelift/cloudtrailevent.py +120 -0
  719. cartography/models/spacelift/run.py +162 -0
  720. cartography/models/spacelift/space.py +131 -0
  721. cartography/models/spacelift/spaceliftaccount.py +31 -0
  722. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  723. cartography/models/spacelift/stack.py +96 -0
  724. cartography/models/spacelift/user.py +63 -0
  725. cartography/models/spacelift/worker.py +97 -0
  726. cartography/models/spacelift/workerpool.py +90 -0
  727. cartography/models/tailscale/__init__.py +0 -0
  728. cartography/models/tailscale/device.py +96 -0
  729. cartography/models/tailscale/group.py +86 -0
  730. cartography/models/tailscale/postureintegration.py +58 -0
  731. cartography/models/tailscale/tag.py +102 -0
  732. cartography/models/tailscale/tailnet.py +29 -0
  733. cartography/models/tailscale/user.py +57 -0
  734. cartography/models/trivy/__init__.py +0 -0
  735. cartography/models/trivy/findings.py +66 -0
  736. cartography/models/trivy/fix.py +66 -0
  737. cartography/models/trivy/package.py +71 -0
  738. cartography/rules/README.md +1 -0
  739. cartography/rules/__init__.py +0 -0
  740. cartography/rules/cli.py +261 -0
  741. cartography/rules/data/__init__.py +0 -0
  742. cartography/rules/data/rules/__init__.py +46 -0
  743. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  744. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  745. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  746. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  747. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  748. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  749. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  750. cartography/rules/data/rules/mfa_missing.py +46 -0
  751. cartography/rules/data/rules/object_storage_public.py +100 -0
  752. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  753. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  754. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  755. cartography/rules/formatters.py +108 -0
  756. cartography/rules/runners.py +216 -0
  757. cartography/rules/spec/__init__.py +0 -0
  758. cartography/rules/spec/model.py +267 -0
  759. cartography/rules/spec/result.py +38 -0
  760. cartography/stats.py +4 -4
  761. cartography/sync.py +137 -31
  762. cartography/util.py +187 -77
  763. cartography-0.123.0.dist-info/METADATA +230 -0
  764. cartography-0.123.0.dist-info/RECORD +856 -0
  765. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
  766. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  767. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
  768. cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
  769. cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
  770. cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
  771. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  772. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  773. cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
  774. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  775. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  776. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  777. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  778. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  779. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  780. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  781. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  782. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  783. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  784. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  785. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  786. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  787. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  788. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  789. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  790. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  791. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  792. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  793. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  794. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  795. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  796. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  797. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  798. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  799. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  800. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  801. cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
  802. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  803. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  804. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  805. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  806. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  807. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  808. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  809. cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
  810. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  811. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  812. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  813. cartography/intel/crxcavator/__init__.py +0 -44
  814. cartography/intel/crxcavator/crxcavator.py +0 -329
  815. cartography/intel/gcp/crm.py +0 -302
  816. cartography/intel/gsuite/api.py +0 -284
  817. cartography/models/aws/ec2/keypairs.py +0 -64
  818. cartography-0.93.0rc1.dist-info/METADATA +0 -55
  819. cartography-0.93.0rc1.dist-info/NOTICE +0 -4
  820. cartography-0.93.0rc1.dist-info/RECORD +0 -341
  821. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  822. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,291 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import neo4j
5
+ from googleapiclient.discovery import Resource
6
+ from googleapiclient.errors import HttpError
7
+
8
+ from cartography.client.core.tx import load
9
+ from cartography.client.core.tx import load_matchlinks
10
+ from cartography.graph.job import GraphJob
11
+ from cartography.models.gsuite.group import GSuiteGroupSchema
12
+ from cartography.models.gsuite.group import GSuiteGroupToGroupMemberRel
13
+ from cartography.models.gsuite.group import GSuiteGroupToGroupOwnerRel
14
+ from cartography.models.gsuite.tenant import GSuiteTenantSchema
15
+ from cartography.util import timeit
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ GOOGLE_API_NUM_RETRIES = 5
20
+
21
+
22
+ @timeit
23
+ def get_all_groups(
24
+ admin: Resource, customer_id: str = "my_customer"
25
+ ) -> list[dict[str, Any]]:
26
+ """
27
+ Return list of Google Groups in your organization
28
+ Returns empty list if we are unable to enumerate the groups for any reasons
29
+
30
+ googleapiclient.discovery.build('admin', 'directory_v1', credentials=credentials, cache_discovery=False)
31
+
32
+ :param admin: google's apiclient discovery resource object. From googleapiclient.discovery.build
33
+ See https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build.
34
+ :return: list of Google groups in domain
35
+ """
36
+ request = admin.groups().list(
37
+ customer=customer_id,
38
+ maxResults=20,
39
+ orderBy="email",
40
+ )
41
+ response_objects = []
42
+ while request is not None:
43
+ try:
44
+ resp = request.execute(num_retries=GOOGLE_API_NUM_RETRIES)
45
+ response_objects.extend(resp.get("groups", []))
46
+ request = admin.groups().list_next(request, resp)
47
+ except HttpError as e:
48
+ if (
49
+ e.resp.status == 403
50
+ and "Request had insufficient authentication scopes" in str(e)
51
+ ):
52
+ logger.error(
53
+ "Missing required GSuite scopes. If using the gcloud CLI, "
54
+ "run: gcloud auth application-default login --scopes="
55
+ '"https://www.googleapis.com/auth/admin.directory.user.readonly,'
56
+ "https://www.googleapis.com/auth/admin.directory.group.readonly,"
57
+ "https://www.googleapis.com/auth/admin.directory.group.member.readonly,"
58
+ 'https://www.googleapis.com/auth/cloud-platform"'
59
+ )
60
+ raise
61
+ return response_objects
62
+
63
+
64
+ @timeit
65
+ def get_members_for_groups(
66
+ admin: Resource, groups_email: list[str]
67
+ ) -> dict[str, list[dict[str, Any]]]:
68
+ """Get all members for given groups emails
69
+
70
+ Args:
71
+ admin (Resource): google's apiclient discovery resource object. From googleapiclient.discovery.build
72
+ See https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build.
73
+ groups_email (list[str]): List of group email addresses to get members for
74
+
75
+
76
+ :return: list of dictionaries representing Users or Groups grouped by group email
77
+ """
78
+ results: dict[str, list[dict]] = {}
79
+ for group_email in groups_email:
80
+ request = admin.members().list(
81
+ groupKey=group_email,
82
+ maxResults=500,
83
+ )
84
+ members: list[dict] = []
85
+ while request is not None:
86
+ resp = request.execute(num_retries=GOOGLE_API_NUM_RETRIES)
87
+ members = members + resp.get("members", [])
88
+ request = admin.members().list_next(request, resp)
89
+ results[group_email] = members
90
+
91
+ return results
92
+
93
+
94
+ @timeit
95
+ def transform_groups(
96
+ groups: list[dict], group_memberships: dict[str, list[dict[str, Any]]]
97
+ ) -> tuple[list[dict], list[dict], list[dict]]:
98
+ """Strips list of API response objects to return list of group objects only and lists of subgroup relationships
99
+
100
+ :param groups: Raw groups from Google API
101
+ :param group_memberships: Group memberships data
102
+ :return: tuple of (groups, group_member_relationships, group_owner_relationships)
103
+ """
104
+ transformed_groups: list[dict] = []
105
+ group_member_relationships: list[dict] = []
106
+ group_owner_relationships: list[dict] = []
107
+
108
+ for group in groups:
109
+ group_id = group["id"]
110
+ group_email = group["email"]
111
+ group["member_ids"] = []
112
+ group["owner_ids"] = []
113
+
114
+ for member in group_memberships.get(group_email, []):
115
+ if member["type"] == "GROUP":
116
+ # Create group-to-group relationships
117
+ relationship_data = {
118
+ "parent_group_id": group_id,
119
+ "subgroup_id": member.get("id"),
120
+ "role": member.get("role"),
121
+ }
122
+
123
+ if member.get("role") == "OWNER":
124
+ group_owner_relationships.append(relationship_data)
125
+ else:
126
+ group_member_relationships.append(relationship_data)
127
+ continue
128
+
129
+ # Handle user memberships
130
+ if member.get("role") == "OWNER":
131
+ group["owner_ids"].append(member.get("id"))
132
+ group["member_ids"].append(member.get("id"))
133
+
134
+ transformed_groups.append(group)
135
+
136
+ return transformed_groups, group_member_relationships, group_owner_relationships
137
+
138
+
139
+ @timeit
140
+ def load_gsuite_groups(
141
+ neo4j_session: neo4j.Session,
142
+ groups: list[dict],
143
+ customer_id: str,
144
+ gsuite_update_tag: int,
145
+ ) -> None:
146
+ """
147
+ Load GSuite groups using the modern data model
148
+ """
149
+ logger.info("Ingesting %d gsuite groups", len(groups))
150
+
151
+ # Load tenant first if it doesn't exist
152
+ tenant_data = [{"id": customer_id}]
153
+ load(
154
+ neo4j_session,
155
+ GSuiteTenantSchema(),
156
+ tenant_data,
157
+ lastupdated=gsuite_update_tag,
158
+ )
159
+
160
+ # Load groups with relationship to tenant
161
+ load(
162
+ neo4j_session,
163
+ GSuiteGroupSchema(),
164
+ groups,
165
+ lastupdated=gsuite_update_tag,
166
+ CUSTOMER_ID=customer_id,
167
+ )
168
+
169
+
170
+ @timeit
171
+ def load_gsuite_group_to_group_relationships(
172
+ neo4j_session: neo4j.Session,
173
+ group_member_relationships: list[dict],
174
+ group_owner_relationships: list[dict],
175
+ customer_id: str,
176
+ gsuite_update_tag: int,
177
+ ) -> None:
178
+ """
179
+ Load GSuite group-to-group relationships using MatchLinks
180
+ """
181
+ logger.info(
182
+ "Ingesting %d group member relationships", len(group_member_relationships)
183
+ )
184
+ logger.info(
185
+ "Ingesting %d group owner relationships", len(group_owner_relationships)
186
+ )
187
+
188
+ # Load group member relationships (Group -> Group MEMBER)
189
+ if group_member_relationships:
190
+ load_matchlinks(
191
+ neo4j_session,
192
+ GSuiteGroupToGroupMemberRel(),
193
+ group_member_relationships,
194
+ lastupdated=gsuite_update_tag,
195
+ _sub_resource_label="GSuiteTenant",
196
+ _sub_resource_id=customer_id,
197
+ )
198
+
199
+ # Load group owner relationships (Group -> Group OWNER)
200
+ if group_owner_relationships:
201
+ load_matchlinks(
202
+ neo4j_session,
203
+ GSuiteGroupToGroupOwnerRel(),
204
+ group_owner_relationships,
205
+ lastupdated=gsuite_update_tag,
206
+ _sub_resource_label="GSuiteTenant",
207
+ _sub_resource_id=customer_id,
208
+ )
209
+
210
+
211
+ @timeit
212
+ def cleanup_gsuite_groups(
213
+ neo4j_session: neo4j.Session,
214
+ common_job_parameters: dict[str, Any],
215
+ customer_id: str,
216
+ gsuite_update_tag: int,
217
+ ) -> None:
218
+ """
219
+ Clean up GSuite groups and group-to-group relationships using the modern data model
220
+ """
221
+ logger.debug("Running GSuite groups cleanup job")
222
+
223
+ # Cleanup group nodes
224
+ GraphJob.from_node_schema(GSuiteGroupSchema(), common_job_parameters).run(
225
+ neo4j_session
226
+ )
227
+
228
+ # Cleanup group-to-group member relationships
229
+ GraphJob.from_matchlink(
230
+ GSuiteGroupToGroupMemberRel(),
231
+ "GSuiteTenant",
232
+ customer_id,
233
+ gsuite_update_tag,
234
+ ).run(neo4j_session)
235
+
236
+ # Cleanup group-to-group owner relationships
237
+ GraphJob.from_matchlink(
238
+ GSuiteGroupToGroupOwnerRel(),
239
+ "GSuiteTenant",
240
+ customer_id,
241
+ gsuite_update_tag,
242
+ ).run(neo4j_session)
243
+
244
+
245
+ @timeit
246
+ def sync_gsuite_groups(
247
+ neo4j_session: neo4j.Session,
248
+ admin: Resource,
249
+ gsuite_update_tag: int,
250
+ common_job_parameters: dict[str, Any],
251
+ ) -> None:
252
+ """
253
+ GET GSuite group objects using the google admin api resource, load the data into Neo4j and clean up stale nodes.
254
+
255
+ :param neo4j_session: The Neo4j session
256
+ :param admin: Google admin resource object created by `googleapiclient.discovery.build()`.
257
+ See https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build.
258
+ :param gsuite_update_tag: The timestamp value to set our new Neo4j nodes with
259
+ :param common_job_parameters: Parameters to carry to the Neo4j jobs
260
+ :return: Nothing
261
+ """
262
+ logger.debug("Syncing GSuite Groups")
263
+
264
+ customer_id = common_job_parameters.get(
265
+ "CUSTOMER_ID", "my_customer"
266
+ ) # Default to "my_customer" for backward compatibility
267
+
268
+ # 1. GET - Fetch data from API
269
+ resp_objs = get_all_groups(admin, customer_id)
270
+ group_members = get_members_for_groups(admin, [resp["email"] for resp in resp_objs])
271
+
272
+ # 2. TRANSFORM - Shape data for ingestion
273
+ groups, group_member_relationships, group_owner_relationships = transform_groups(
274
+ resp_objs, group_members
275
+ )
276
+
277
+ # 3. LOAD - Ingest to Neo4j using data model
278
+ load_gsuite_groups(neo4j_session, groups, customer_id, gsuite_update_tag)
279
+
280
+ # Load group-to-group relationships after groups are loaded
281
+ load_gsuite_group_to_group_relationships(
282
+ neo4j_session,
283
+ group_member_relationships,
284
+ group_owner_relationships,
285
+ customer_id,
286
+ gsuite_update_tag,
287
+ )
288
+
289
+ # 4. CLEANUP - Remove stale data
290
+ cleanup_params = {**common_job_parameters, "CUSTOMER_ID": customer_id}
291
+ cleanup_gsuite_groups(neo4j_session, cleanup_params, customer_id, gsuite_update_tag)
@@ -0,0 +1,142 @@
1
+ import logging
2
+ from collections import defaultdict
3
+ from typing import Any
4
+
5
+ import neo4j
6
+ from googleapiclient.discovery import Resource
7
+
8
+ from cartography.client.core.tx import load
9
+ from cartography.graph.job import GraphJob
10
+ from cartography.models.gsuite.tenant import GSuiteTenantSchema
11
+ from cartography.models.gsuite.user import GSuiteUserSchema
12
+ from cartography.util import timeit
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ GOOGLE_API_NUM_RETRIES = 5
17
+
18
+
19
+ @timeit
20
+ def get_all_users(admin: Resource) -> list[dict]:
21
+ """
22
+ Return list of Google Users in your organization
23
+ Returns empty list if we are unable to enumerate the users for any reasons
24
+ https://developers.google.com/admin-sdk/directory/v1/guides/manage-users
25
+
26
+ :param admin: apiclient discovery resource object
27
+ :return: list of Google users in domain
28
+ see https://developers.google.com/admin-sdk/directory/v1/guides/manage-users#get_all_domain_users
29
+ """
30
+ request = admin.users().list(
31
+ customer="my_customer",
32
+ maxResults=500,
33
+ orderBy="email",
34
+ )
35
+ response_objects = []
36
+ while request is not None:
37
+ resp = request.execute(num_retries=GOOGLE_API_NUM_RETRIES)
38
+ response_objects.append(resp)
39
+ request = admin.users().list_next(request, resp)
40
+ return response_objects
41
+
42
+
43
+ @timeit
44
+ def transform_users(response_objects: list[dict]) -> dict[str, list[dict[str, Any]]]:
45
+ """Transform list of API response objects to return list of user objects with flattened structure grouped by customerId
46
+ :param response_objects: Raw API response objects
47
+ :return: list of dictionary objects for data model consumption
48
+ """
49
+ results = defaultdict(list)
50
+ for response_object in response_objects:
51
+ for user in response_object["users"]:
52
+ # Flatten the nested name structure
53
+ transformed_user = user.copy()
54
+ if "name" in user and isinstance(user["name"], dict):
55
+ transformed_user["name"] = user["name"].get("fullName")
56
+ transformed_user["family_name"] = user["name"].get("familyName")
57
+ transformed_user["given_name"] = user["name"].get("givenName")
58
+ results[transformed_user["customerId"]].append(transformed_user)
59
+ return results
60
+
61
+
62
+ @timeit
63
+ def load_gsuite_users(
64
+ neo4j_session: neo4j.Session,
65
+ users_by_customer: dict[str, list[dict]],
66
+ gsuite_update_tag: int,
67
+ ) -> None:
68
+ """
69
+ Load GSuite users using the modern data model
70
+ """
71
+ logger.info("Ingesting %s gsuite tenants", len(users_by_customer))
72
+ tenant_data = [{"id": customer_id} for customer_id in users_by_customer.keys()]
73
+ load(
74
+ neo4j_session,
75
+ GSuiteTenantSchema(),
76
+ tenant_data,
77
+ lastupdated=gsuite_update_tag,
78
+ )
79
+
80
+ for customer_id, users in users_by_customer.items():
81
+ logger.info(
82
+ "Ingesting %s gsuite users for customer %s", len(users), customer_id
83
+ )
84
+ # Load users with relationship to tenant
85
+ load(
86
+ neo4j_session,
87
+ GSuiteUserSchema(),
88
+ users,
89
+ lastupdated=gsuite_update_tag,
90
+ CUSTOMER_ID=customer_id,
91
+ )
92
+
93
+
94
+ @timeit
95
+ def cleanup_gsuite_users(
96
+ neo4j_session: neo4j.Session,
97
+ common_job_parameters: dict[str, Any],
98
+ ) -> None:
99
+ """
100
+ Clean up GSuite users using the modern data model
101
+ """
102
+ logger.debug("Running GSuite users cleanup job")
103
+ GraphJob.from_node_schema(GSuiteUserSchema(), common_job_parameters).run(
104
+ neo4j_session
105
+ )
106
+
107
+
108
+ @timeit
109
+ def sync_gsuite_users(
110
+ neo4j_session: neo4j.Session,
111
+ admin: Resource,
112
+ gsuite_update_tag: int,
113
+ common_job_parameters: dict[str, Any],
114
+ ) -> list[str]:
115
+ """
116
+ GET GSuite user objects using the google admin api resource, load the data into Neo4j and clean up stale nodes.
117
+
118
+ :param neo4j_session: The Neo4j session
119
+ :param admin: Google admin resource object created by `googleapiclient.discovery.build()`.
120
+ See https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build.
121
+ :param gsuite_update_tag: The timestamp value to set our new Neo4j nodes with
122
+ :param common_job_parameters: Parameters to carry to the Neo4j jobs
123
+ :return: list of customer IDs
124
+ """
125
+ logger.debug("Syncing GSuite Users")
126
+
127
+ # 1. GET - Fetch data from API
128
+ resp_objs = get_all_users(admin)
129
+
130
+ # 2. TRANSFORM - Shape data for ingestion
131
+ users_by_customers = transform_users(resp_objs)
132
+
133
+ # 3. LOAD - Ingest to Neo4j using data model
134
+ load_gsuite_users(neo4j_session, users_by_customers, gsuite_update_tag)
135
+
136
+ # 4. CLEANUP - Remove stale data
137
+ for customer_id in users_by_customers.keys():
138
+ cleanup_params = {**common_job_parameters, "CUSTOMER_ID": customer_id}
139
+ cleanup_gsuite_users(neo4j_session, cleanup_params)
140
+
141
+ # Return the list of customer IDs
142
+ return list(users_by_customers.keys())
@@ -1,13 +1,31 @@
1
+ import logging
2
+
1
3
  import neo4j
2
4
 
3
5
  from cartography.config import Config
4
6
  from cartography.intel.jamf import computers
5
7
  from cartography.util import timeit
6
8
 
9
+ logger = logging.getLogger(__name__)
10
+
7
11
 
8
12
  @timeit
9
13
  def start_jamf_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
14
+
15
+ if not config.jamf_base_uri or not config.jamf_user or not config.jamf_password:
16
+ # If the config is not set, we don't want to run this module
17
+ logger.info(
18
+ "Jamf import is not configured - skipping this module. See docs to configure."
19
+ )
20
+ return
21
+
10
22
  common_job_parameters = {
11
23
  "UPDATE_TAG": config.update_tag,
12
24
  }
13
- computers.sync(neo4j_session, config.jamf_base_uri, config.jamf_user, config.jamf_password, common_job_parameters)
25
+ computers.sync(
26
+ neo4j_session,
27
+ config.jamf_base_uri,
28
+ config.jamf_user,
29
+ config.jamf_password,
30
+ common_job_parameters,
31
+ )
@@ -4,21 +4,29 @@ from typing import List
4
4
 
5
5
  import neo4j
6
6
 
7
+ from cartography.client.core.tx import run_write_query
7
8
  from cartography.intel.jamf.util import call_jamf_api
8
9
  from cartography.util import run_cleanup_job
9
10
  from cartography.util import timeit
10
11
 
11
-
12
12
  logger = logging.getLogger(__name__)
13
13
 
14
14
 
15
15
  @timeit
16
- def get_computer_groups(jamf_base_uri: str, jamf_user: str, jamf_password: str) -> List[Dict]:
16
+ def get_computer_groups(
17
+ jamf_base_uri: str,
18
+ jamf_user: str,
19
+ jamf_password: str,
20
+ ) -> List[Dict]:
17
21
  return call_jamf_api("/computergroups", jamf_base_uri, jamf_user, jamf_password)
18
22
 
19
23
 
20
24
  @timeit
21
- def load_computer_groups(data: Dict, neo4j_session: neo4j.Session, update_tag: int) -> None:
25
+ def load_computer_groups(
26
+ data: Dict,
27
+ neo4j_session: neo4j.Session,
28
+ update_tag: int,
29
+ ) -> None:
22
30
  ingest_groups = """
23
31
  UNWIND $JsonData as group
24
32
  MERGE (g:JamfComputerGroup{id: group.id})
@@ -28,17 +36,29 @@ def load_computer_groups(data: Dict, neo4j_session: neo4j.Session, update_tag: i
28
36
  g.lastupdated = $UpdateTag
29
37
  """
30
38
  groups = data.get("computer_groups")
31
- neo4j_session.run(ingest_groups, JsonData=groups, UpdateTag=update_tag)
39
+ run_write_query(
40
+ neo4j_session,
41
+ ingest_groups,
42
+ JsonData=groups,
43
+ UpdateTag=update_tag,
44
+ )
32
45
 
33
46
 
34
47
  @timeit
35
48
  def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
36
- run_cleanup_job('jamf_import_computers_cleanup.json', neo4j_session, common_job_parameters)
49
+ run_cleanup_job(
50
+ "jamf_import_computers_cleanup.json",
51
+ neo4j_session,
52
+ common_job_parameters,
53
+ )
37
54
 
38
55
 
39
56
  @timeit
40
57
  def sync_computer_groups(
41
- neo4j_session: neo4j.Session, update_tag: int, jamf_base_uri: str, jamf_user: str,
58
+ neo4j_session: neo4j.Session,
59
+ update_tag: int,
60
+ jamf_base_uri: str,
61
+ jamf_user: str,
42
62
  jamf_password: str,
43
63
  ) -> None:
44
64
  groups = get_computer_groups(jamf_base_uri, jamf_user, jamf_password)
@@ -47,7 +67,16 @@ def sync_computer_groups(
47
67
 
48
68
  @timeit
49
69
  def sync(
50
- neo4j_session: neo4j.Session, jamf_base_uri: str, jamf_user: str, jamf_password: str,
70
+ neo4j_session: neo4j.Session,
71
+ jamf_base_uri: str,
72
+ jamf_user: str,
73
+ jamf_password: str,
51
74
  common_job_parameters: Dict,
52
75
  ) -> None:
53
- sync_computer_groups(neo4j_session, common_job_parameters['UPDATE_TAG'], jamf_base_uri, jamf_user, jamf_password)
76
+ sync_computer_groups(
77
+ neo4j_session,
78
+ common_job_parameters["UPDATE_TAG"],
79
+ jamf_base_uri,
80
+ jamf_user,
81
+ jamf_password,
82
+ )
@@ -12,14 +12,19 @@ _TIMEOUT = (60, 60)
12
12
 
13
13
 
14
14
  @timeit
15
- def call_jamf_api(api_and_parameters: str, jamf_base_uri: str, jamf_user: str, jamf_password: str) -> List[Dict]:
15
+ def call_jamf_api(
16
+ api_and_parameters: str,
17
+ jamf_base_uri: str,
18
+ jamf_user: str,
19
+ jamf_password: str,
20
+ ) -> List[Dict]:
16
21
  uri = jamf_base_uri + api_and_parameters
17
22
  jamf_auth = requests.auth.HTTPBasicAuth(jamf_user, jamf_password)
18
23
  try:
19
24
  response = requests.get(
20
25
  uri,
21
26
  auth=jamf_auth,
22
- headers={'Accept': 'application/json'},
27
+ headers={"Accept": "application/json"},
23
28
  timeout=_TIMEOUT,
24
29
  )
25
30
  except requests.exceptions.Timeout:
@@ -19,10 +19,13 @@ def start_kandji_ingestion(neo4j_session: neo4j.Session, config: Config) -> None
19
19
 
20
20
  :return: None
21
21
  """
22
- if config.kandji_base_uri is None or config.kandji_token is None or config.kandji_tenant_id is None:
22
+ if (
23
+ config.kandji_base_uri is None
24
+ or config.kandji_token is None
25
+ or config.kandji_tenant_id is None
26
+ ):
23
27
  logger.warning(
24
- 'Required parameter(s) missing. Skipping sync.',
25
- 'See docs to configure.',
28
+ "Required parameter missing. Skipping sync. " "See docs to configure.",
26
29
  )
27
30
  return
28
31
 
@@ -12,7 +12,6 @@ from cartography.models.kandji.device import KandjiDeviceSchema
12
12
  from cartography.models.kandji.tenant import KandjiTenantSchema
13
13
  from cartography.util import timeit
14
14
 
15
-
16
15
  logger = logging.getLogger(__name__)
17
16
  _TIMEOUT = (60, 60)
18
17
 
@@ -21,14 +20,40 @@ _TIMEOUT = (60, 60)
21
20
  def get(kandji_base_uri: str, kandji_token: str) -> List[Dict[str, Any]]:
22
21
  api_endpoint = f"{kandji_base_uri}/api/v1/devices"
23
22
  headers = {
24
- 'Accept': 'application/json',
25
- 'Authorization': f'Bearer {kandji_token}',
23
+ "Accept": "application/json",
24
+ "Authorization": f"Bearer {kandji_token}",
25
+ }
26
+
27
+ offset = 0
28
+ limit = 300
29
+ params: dict[str, str | int] = {
30
+ "sort": "serial_number",
31
+ "limit": limit,
32
+ "offset": offset,
26
33
  }
27
34
 
35
+ devices: List[Dict[str, Any]] = []
28
36
  session = Session()
29
- req = session.get(api_endpoint, headers=headers, timeout=_TIMEOUT)
30
- req.raise_for_status()
31
- return req.json()
37
+ while True:
38
+ logger.debug("Kandji device offset: %s", offset)
39
+
40
+ params["offset"] = offset
41
+ response = session.get(
42
+ api_endpoint, headers=headers, timeout=_TIMEOUT, params=params
43
+ )
44
+ response.raise_for_status()
45
+
46
+ result = response.json()
47
+ # If no more result, we are done
48
+ if len(result) == 0:
49
+ break
50
+
51
+ devices.extend(result)
52
+
53
+ offset += limit
54
+
55
+ logger.debug("Kandji device count: %d", len(devices))
56
+ return devices
32
57
 
33
58
 
34
59
  @timeit
@@ -36,7 +61,7 @@ def transform(api_result: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
36
61
  result: List[Dict[str, Any]] = []
37
62
  for device in api_result:
38
63
  n_device = device
39
- n_device['id'] = device['device_id']
64
+ n_device["id"] = device["device_id"]
40
65
  result.append(n_device)
41
66
  return result
42
67
 
@@ -54,7 +79,7 @@ def load_devices(
54
79
  load(
55
80
  neo4j_session,
56
81
  KandjiTenantSchema(),
57
- [{'id': tenant_id}],
82
+ [{"id": tenant_id}],
58
83
  lastupdated=update_tag,
59
84
  )
60
85
 
@@ -67,8 +92,13 @@ def load_devices(
67
92
  )
68
93
 
69
94
 
70
- def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
71
- GraphJob.from_node_schema(KandjiDeviceSchema(), common_job_parameters).run(neo4j_session)
95
+ def cleanup(
96
+ neo4j_session: neo4j.Session,
97
+ common_job_parameters: Dict[str, Any],
98
+ ) -> None:
99
+ GraphJob.from_node_schema(KandjiDeviceSchema(), common_job_parameters).run(
100
+ neo4j_session,
101
+ )
72
102
 
73
103
 
74
104
  @timeit