(store: &Store, profile_id: &str)
| 1854 | } |
| 1855 | |
| 1856 | async fn sandboxes_using_profile(store: &Store, profile_id: &str) -> Result<Vec<String>, Status> { |
| 1857 | // Collect all sandboxes that reference at least one provider — pagination |
| 1858 | // is handled by `scan_sandboxes`; the async provider lookup happens below. |
| 1859 | let candidates = scan_sandboxes(store, |sandbox| { |
| 1860 | let has_providers = sandbox |
| 1861 | .spec |
| 1862 | .as_ref() |
| 1863 | .is_some_and(|s| !s.providers.is_empty()); |
| 1864 | has_providers.then_some(sandbox) |
| 1865 | }) |
| 1866 | .await?; |
| 1867 | |
| 1868 | let mut blocking = Vec::new(); |
| 1869 | for sandbox in candidates { |
| 1870 | let spec = sandbox.spec.as_ref().expect("filtered by scan_sandboxes"); |
| 1871 | for provider_name in &spec.providers { |
| 1872 | let Some(provider) = store |
| 1873 | .get_message_by_name::<Provider>(provider_name) |
| 1874 | .await |
| 1875 | .map_err(|e| Status::internal(format!("fetch provider failed: {e}")))? |
| 1876 | else { |
| 1877 | continue; |
| 1878 | }; |
| 1879 | if normalize_profile_id(&provider.r#type).as_deref() == Some(profile_id) { |
| 1880 | blocking.push(sandbox.object_name().to_string()); |
| 1881 | break; |
| 1882 | } |
| 1883 | } |
| 1884 | } |
| 1885 | blocking.sort(); |
| 1886 | blocking.dedup(); |
| 1887 | Ok(blocking) |
| 1888 | } |
| 1889 | |
| 1890 | pub(super) async fn handle_update_provider( |
| 1891 | state: &Arc<ServerState>, |
no test coverage detected