mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
refactor: 移除 Python upstream 依赖,清理全部 legacy/Python 兼容层
- 移除 upstream_base_url 参数及 AETHER_GATEWAY_UPSTREAM 环境变量,gateway 不再需要指向 Python 宿主 - 删除所有 LEGACY_*/PYTHON_* 常量、路由组、header 定义及 sunset/phaseout 机制 - 将 legacy_gateway_bridge 重命名为 internal_gateway,executor 相关命名统一为 execution_runtime - dev.sh 新增 Postgres/Redis 预检查,移除 upstream 相关启动参数和提示 - 新增 ai_public 路由处理器 - 全量适配 handler、test、state、control 等模块的命名和接口变更
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::Response;
|
||||
|
||||
#[path = "adaptive/routes.rs"]
|
||||
mod adaptive_routes;
|
||||
@@ -8,7 +10,7 @@ mod adaptive_shared;
|
||||
pub(crate) async fn maybe_build_local_admin_adaptive_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
adaptive_routes::maybe_build_local_admin_adaptive_response(state, request_context, request_body)
|
||||
.await
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
use super::adaptive_shared::*;
|
||||
use super::*;
|
||||
use super::super::build_proxy_error_response;
|
||||
use super::adaptive_shared::{
|
||||
admin_adaptive_adjustment_items, admin_adaptive_dispatcher_not_found_response,
|
||||
admin_adaptive_effective_limit, admin_adaptive_find_key, admin_adaptive_key_id_from_path,
|
||||
admin_adaptive_key_not_found_response, admin_adaptive_key_payload,
|
||||
admin_adaptive_load_candidate_keys,
|
||||
};
|
||||
use crate::gateway::handlers::{query_param_value, unix_secs_to_rfc3339};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN_ADAPTIVE_DATA_UNAVAILABLE_DETAIL: &str = "Admin adaptive data unavailable";
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct AdminAdaptiveToggleModeRequest {
|
||||
@@ -11,7 +28,7 @@ struct AdminAdaptiveToggleModeRequest {
|
||||
pub(super) async fn maybe_build_local_admin_adaptive_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -24,10 +41,10 @@ pub(super) async fn maybe_build_local_admin_adaptive_response(
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_proxy_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
"maintenance_mode",
|
||||
"Admin adaptive routes require Rust maintenance backend",
|
||||
"data_unavailable",
|
||||
ADMIN_ADAPTIVE_DATA_UNAVAILABLE_DETAIL,
|
||||
Some(json!({
|
||||
"error": "Admin adaptive routes require Rust maintenance backend",
|
||||
"error": ADMIN_ADAPTIVE_DATA_UNAVAILABLE_DETAIL,
|
||||
})),
|
||||
)));
|
||||
}
|
||||
@@ -169,10 +186,10 @@ pub(super) async fn maybe_build_local_admin_adaptive_response(
|
||||
if !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_proxy_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
"maintenance_mode",
|
||||
"Admin adaptive routes require Rust maintenance backend",
|
||||
"data_unavailable",
|
||||
ADMIN_ADAPTIVE_DATA_UNAVAILABLE_DETAIL,
|
||||
Some(json!({
|
||||
"error": "Admin adaptive routes require Rust maintenance backend",
|
||||
"error": ADMIN_ADAPTIVE_DATA_UNAVAILABLE_DETAIL,
|
||||
})),
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::json_string_list;
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) fn admin_adaptive_effective_limit(
|
||||
key: &aether_data::repository::provider_catalog::StoredProviderCatalogKey,
|
||||
) -> Option<u32> {
|
||||
pub(super) fn admin_adaptive_effective_limit(key: &StoredProviderCatalogKey) -> Option<u32> {
|
||||
if key.rpm_limit.is_none() {
|
||||
key.learned_rpm_limit
|
||||
} else {
|
||||
@@ -22,9 +29,7 @@ pub(super) fn admin_adaptive_adjustment_items(
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(super) fn admin_adaptive_key_payload(
|
||||
key: &aether_data::repository::provider_catalog::StoredProviderCatalogKey,
|
||||
) -> serde_json::Value {
|
||||
pub(super) fn admin_adaptive_key_payload(key: &StoredProviderCatalogKey) -> serde_json::Value {
|
||||
json!({
|
||||
"id": key.id,
|
||||
"name": key.name,
|
||||
@@ -77,8 +82,7 @@ pub(super) fn admin_adaptive_key_id_from_path(path: &str) -> Option<String> {
|
||||
pub(super) async fn admin_adaptive_find_key(
|
||||
state: &AppState,
|
||||
key_id: &str,
|
||||
) -> Result<Option<aether_data::repository::provider_catalog::StoredProviderCatalogKey>, GatewayError>
|
||||
{
|
||||
) -> Result<Option<StoredProviderCatalogKey>, GatewayError> {
|
||||
Ok(state
|
||||
.read_provider_catalog_keys_by_ids(std::slice::from_ref(&key_id.to_string()))
|
||||
.await?
|
||||
@@ -89,8 +93,7 @@ pub(super) async fn admin_adaptive_find_key(
|
||||
pub(super) async fn admin_adaptive_load_candidate_keys(
|
||||
state: &AppState,
|
||||
provider_id: Option<&str>,
|
||||
) -> Result<Vec<aether_data::repository::provider_catalog::StoredProviderCatalogKey>, GatewayError>
|
||||
{
|
||||
) -> Result<Vec<StoredProviderCatalogKey>, GatewayError> {
|
||||
if let Some(provider_id) = provider_id.filter(|value| !value.trim().is_empty()) {
|
||||
return state
|
||||
.list_provider_catalog_keys_by_provider_ids(std::slice::from_ref(
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::admin::{
|
||||
default_admin_user_api_key_name, format_optional_unix_secs_iso8601,
|
||||
generate_admin_user_api_key_plaintext, hash_admin_user_api_key, masked_user_api_key_display,
|
||||
normalize_admin_optional_api_key_name, normalize_admin_user_api_formats,
|
||||
normalize_admin_user_string_list,
|
||||
};
|
||||
use crate::gateway::handlers::public::serialize_admin_system_users_export_wallet;
|
||||
use crate::gateway::handlers::{
|
||||
decrypt_catalog_secret_with_fallbacks, encrypt_catalog_secret_with_fallbacks, query_param_bool,
|
||||
query_param_optional_bool, query_param_value,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN_API_KEYS_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin standalone API key routes require Rust maintenance backend";
|
||||
const ADMIN_API_KEYS_DATA_UNAVAILABLE_DETAIL: &str = "Admin standalone API key data unavailable";
|
||||
|
||||
#[path = "api_keys/mutation_routes.rs"]
|
||||
mod admin_api_keys_mutation_routes;
|
||||
@@ -23,7 +40,7 @@ use self::admin_api_keys_shared::{
|
||||
admin_api_key_total_tokens_by_ids, admin_api_keys_id_from_path, admin_api_keys_operator_id,
|
||||
admin_api_keys_parse_limit, admin_api_keys_parse_skip, build_admin_api_key_detail_payload,
|
||||
build_admin_api_key_list_item_payload, build_admin_api_keys_bad_request_response,
|
||||
build_admin_api_keys_maintenance_response, build_admin_api_keys_not_found_response,
|
||||
build_admin_api_keys_data_unavailable_response, build_admin_api_keys_not_found_response,
|
||||
AdminStandaloneApiKeyCreateRequest, AdminStandaloneApiKeyFieldPresence,
|
||||
AdminStandaloneApiKeyToggleRequest, AdminStandaloneApiKeyUpdateRequest,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
use super::*;
|
||||
use super::admin_api_keys_shared::{
|
||||
admin_api_key_total_tokens_by_ids, admin_api_keys_id_from_path, admin_api_keys_operator_id,
|
||||
build_admin_api_key_detail_payload, build_admin_api_keys_bad_request_response,
|
||||
build_admin_api_keys_data_unavailable_response, build_admin_api_keys_not_found_response,
|
||||
AdminStandaloneApiKeyCreateRequest, AdminStandaloneApiKeyFieldPresence,
|
||||
AdminStandaloneApiKeyToggleRequest, AdminStandaloneApiKeyUpdateRequest,
|
||||
};
|
||||
use super::{
|
||||
default_admin_user_api_key_name, encrypt_catalog_secret_with_fallbacks,
|
||||
format_optional_unix_secs_iso8601, generate_admin_user_api_key_plaintext,
|
||||
hash_admin_user_api_key, masked_user_api_key_display, normalize_admin_optional_api_key_name,
|
||||
normalize_admin_user_api_formats, normalize_admin_user_string_list,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn build_admin_create_api_key_response(
|
||||
state: &AppState,
|
||||
@@ -6,11 +26,11 @@ pub(super) async fn build_admin_create_api_key_response(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_auth_api_key_writer() {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
}
|
||||
|
||||
let Some(operator_id) = admin_api_keys_operator_id(request_context) else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
let Some(request_body) = request_body else {
|
||||
return Ok(build_admin_api_keys_bad_request_response(
|
||||
@@ -88,7 +108,7 @@ pub(super) async fn build_admin_create_api_key_response(
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
|
||||
Ok(Json(json!({
|
||||
@@ -115,11 +135,11 @@ pub(super) async fn build_admin_update_api_key_response(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_auth_api_key_writer() {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
}
|
||||
|
||||
let Some(api_key_id) = admin_api_keys_id_from_path(&request_context.request_path) else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
let Some(request_body) = request_body else {
|
||||
return Ok(build_admin_api_keys_bad_request_response(
|
||||
@@ -233,11 +253,11 @@ pub(super) async fn build_admin_toggle_api_key_response(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_auth_api_key_writer() {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
}
|
||||
|
||||
let Some(api_key_id) = admin_api_keys_id_from_path(&request_context.request_path) else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
|
||||
let requested_active = match request_body {
|
||||
@@ -288,11 +308,11 @@ pub(super) async fn build_admin_delete_api_key_response(
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_auth_api_key_writer() {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
}
|
||||
|
||||
let Some(api_key_id) = admin_api_keys_id_from_path(&request_context.request_path) else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
|
||||
match state.delete_standalone_api_key(&api_key_id).await? {
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
use super::*;
|
||||
use super::admin_api_keys_shared::{
|
||||
admin_api_key_total_tokens_by_ids, admin_api_keys_id_from_path, admin_api_keys_parse_limit,
|
||||
admin_api_keys_parse_skip, build_admin_api_key_detail_payload,
|
||||
build_admin_api_key_list_item_payload, build_admin_api_keys_bad_request_response,
|
||||
build_admin_api_keys_data_unavailable_response, build_admin_api_keys_not_found_response,
|
||||
};
|
||||
use super::{decrypt_catalog_secret_with_fallbacks, query_param_bool, query_param_optional_bool};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn build_admin_list_api_keys_response(
|
||||
state: &AppState,
|
||||
@@ -61,7 +75,7 @@ pub(super) async fn build_admin_api_key_detail_response(
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some(api_key_id) = admin_api_keys_id_from_path(&request_context.request_path) else {
|
||||
return Ok(build_admin_api_keys_maintenance_response());
|
||||
return Ok(build_admin_api_keys_data_unavailable_response());
|
||||
};
|
||||
|
||||
if state
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
use super::*;
|
||||
use super::admin_api_keys_mutation_routes::{
|
||||
build_admin_create_api_key_response, build_admin_delete_api_key_response,
|
||||
build_admin_toggle_api_key_response, build_admin_update_api_key_response,
|
||||
};
|
||||
use super::admin_api_keys_read_routes::{
|
||||
build_admin_api_key_detail_response, build_admin_list_api_keys_response,
|
||||
};
|
||||
use super::admin_api_keys_shared::build_admin_api_keys_data_unavailable_response;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{body::Body, http, response::Response};
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_api_keys_routes_response(
|
||||
state: &AppState,
|
||||
@@ -70,6 +79,6 @@ pub(super) async fn maybe_build_local_admin_api_keys_routes_response(
|
||||
build_admin_delete_api_key_response(state, request_context).await?,
|
||||
))
|
||||
}
|
||||
_ => Ok(Some(build_admin_api_keys_maintenance_response())),
|
||||
_ => Ok(Some(build_admin_api_keys_data_unavailable_response())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
format_optional_unix_secs_iso8601, http, json, masked_user_api_key_display, query_param_value,
|
||||
serialize_admin_system_users_export_wallet, AppState, Body, GatewayError,
|
||||
GatewayPublicRequestContext, IntoResponse, Json, Response,
|
||||
};
|
||||
use crate::gateway::handlers::admin::api_keys::ADMIN_API_KEYS_DATA_UNAVAILABLE_DETAIL;
|
||||
|
||||
#[derive(Debug, Default, serde::Deserialize)]
|
||||
pub(super) struct AdminStandaloneApiKeyCreateRequest {
|
||||
@@ -40,10 +45,10 @@ pub(super) struct AdminStandaloneApiKeyFieldPresence {
|
||||
pub(super) allowed_models: bool,
|
||||
}
|
||||
|
||||
pub(super) fn build_admin_api_keys_maintenance_response() -> Response<Body> {
|
||||
pub(super) fn build_admin_api_keys_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_API_KEYS_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_API_KEYS_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{query_param_value, unix_secs_to_rfc3339};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use regex::Regex;
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
const ADMIN_BILLING_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin billing routes require Rust maintenance backend";
|
||||
const ADMIN_BILLING_DATA_UNAVAILABLE_DETAIL: &str = "Admin billing data unavailable";
|
||||
|
||||
#[path = "billing/collectors.rs"]
|
||||
mod billing_collectors;
|
||||
@@ -19,10 +27,10 @@ fn default_admin_billing_json_object() -> serde_json::Value {
|
||||
json!({})
|
||||
}
|
||||
|
||||
fn build_admin_billing_maintenance_response() -> Response<Body> {
|
||||
fn build_admin_billing_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_BILLING_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_BILLING_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
@@ -189,7 +197,7 @@ fn admin_billing_optional_epoch_value(
|
||||
pub(crate) async fn maybe_build_local_admin_billing_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -276,6 +284,6 @@ pub(crate) async fn maybe_build_local_admin_billing_response(
|
||||
}
|
||||
|
||||
match decision.route_kind.as_deref() {
|
||||
_ => Ok(Some(build_admin_billing_maintenance_response())),
|
||||
_ => Ok(Some(build_admin_billing_data_unavailable_response())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_billing_optional_bool_filter, admin_billing_optional_epoch_value,
|
||||
admin_billing_optional_filter, admin_billing_pages, admin_billing_parse_page,
|
||||
admin_billing_parse_page_size, admin_billing_validate_safe_expression,
|
||||
build_admin_billing_bad_request_response, build_admin_billing_not_found_response,
|
||||
build_admin_billing_read_only_response, default_admin_billing_true,
|
||||
normalize_admin_billing_optional_text, normalize_admin_billing_required_text,
|
||||
};
|
||||
use crate::gateway::handlers::unix_secs_to_rfc3339;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
fn default_admin_billing_collector_value_type() -> String {
|
||||
"float".to_string()
|
||||
@@ -258,7 +276,7 @@ WHERE id = $1
|
||||
|
||||
async fn parse_admin_billing_collector_request(
|
||||
state: &AppState,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
existing_id: Option<&str>,
|
||||
) -> Result<crate::gateway::AdminBillingCollectorWriteInput, Response<Body>> {
|
||||
let Some(request_body) = request_body else {
|
||||
@@ -389,7 +407,7 @@ async fn parse_admin_billing_collector_request(
|
||||
|
||||
async fn build_admin_create_dimension_collector_response(
|
||||
state: &AppState,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let input = match parse_admin_billing_collector_request(state, request_body, None).await {
|
||||
Ok(value) => value,
|
||||
@@ -414,7 +432,7 @@ async fn build_admin_create_dimension_collector_response(
|
||||
async fn build_admin_update_dimension_collector_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some(collector_id) = admin_billing_collector_id_from_path(&request_context.request_path)
|
||||
else {
|
||||
@@ -450,7 +468,7 @@ async fn build_admin_update_dimension_collector_response(
|
||||
pub(super) async fn maybe_build_local_admin_billing_collectors_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
build_admin_billing_bad_request_response, build_admin_billing_not_found_response,
|
||||
build_admin_billing_read_only_response, normalize_admin_billing_required_text,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
fn default_admin_billing_preset_mode() -> String {
|
||||
"merge".to_string()
|
||||
@@ -238,7 +249,7 @@ fn resolve_admin_billing_preset_collectors(
|
||||
}
|
||||
|
||||
fn parse_admin_billing_preset_apply_request(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<(String, String), Response<Body>> {
|
||||
let Some(request_body) = request_body else {
|
||||
return Err(build_admin_billing_bad_request_response("请求体不能为空"));
|
||||
@@ -266,7 +277,7 @@ fn parse_admin_billing_preset_apply_request(
|
||||
|
||||
async fn build_admin_apply_billing_preset_response(
|
||||
state: &AppState,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let (preset, mode) = match parse_admin_billing_preset_apply_request(request_body) {
|
||||
Ok(value) => value,
|
||||
@@ -315,7 +326,7 @@ async fn build_admin_apply_billing_preset_response(
|
||||
pub(super) async fn maybe_build_local_admin_billing_presets_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_billing_optional_bool_filter, admin_billing_optional_epoch_value,
|
||||
admin_billing_optional_filter, admin_billing_pages, admin_billing_parse_page,
|
||||
admin_billing_parse_page_size, admin_billing_validate_safe_expression,
|
||||
build_admin_billing_bad_request_response, build_admin_billing_not_found_response,
|
||||
build_admin_billing_read_only_response, default_admin_billing_json_object,
|
||||
default_admin_billing_true, normalize_admin_billing_optional_text,
|
||||
normalize_admin_billing_required_text,
|
||||
};
|
||||
use crate::gateway::handlers::unix_secs_to_rfc3339;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
fn default_admin_billing_rule_task_type() -> String {
|
||||
"chat".to_string()
|
||||
@@ -54,7 +73,7 @@ fn admin_billing_rule_id_from_path(request_path: &str) -> Option<String> {
|
||||
}
|
||||
|
||||
fn parse_admin_billing_rule_request(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<crate::gateway::AdminBillingRuleWriteInput, Response<Body>> {
|
||||
let Some(request_body) = request_body else {
|
||||
return Err(build_admin_billing_bad_request_response("请求体不能为空"));
|
||||
@@ -314,7 +333,7 @@ WHERE id = $1
|
||||
|
||||
async fn build_admin_create_billing_rule_response(
|
||||
state: &AppState,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let input = match parse_admin_billing_rule_request(request_body) {
|
||||
Ok(value) => value,
|
||||
@@ -339,7 +358,7 @@ async fn build_admin_create_billing_rule_response(
|
||||
async fn build_admin_update_billing_rule_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some(rule_id) = admin_billing_rule_id_from_path(&request_context.request_path) else {
|
||||
return Ok(build_admin_billing_bad_request_response("缺少 rule_id"));
|
||||
@@ -367,7 +386,7 @@ async fn build_admin_update_billing_rule_response(
|
||||
pub(super) async fn maybe_build_local_admin_billing_rules_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pub(crate) use super::*;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub(crate) fn normalize_string_list(values: Option<Vec<String>>) -> Option<Vec<String>> {
|
||||
let mut out = Vec::new();
|
||||
@@ -120,6 +120,12 @@ mod provider;
|
||||
#[path = "catalog_write_helpers/reveal.rs"]
|
||||
mod reveal;
|
||||
|
||||
pub(crate) use self::keys::*;
|
||||
pub(crate) use self::provider::*;
|
||||
pub(crate) use self::reveal::*;
|
||||
pub(crate) use self::keys::{
|
||||
build_admin_create_provider_key_record, build_admin_provider_keys_payload,
|
||||
build_admin_update_provider_key_record,
|
||||
};
|
||||
pub(crate) use self::provider::{
|
||||
build_admin_create_provider_record, build_admin_fixed_provider_endpoint_record,
|
||||
build_admin_update_provider_record,
|
||||
};
|
||||
pub(crate) use self::reveal::{build_admin_export_key_payload, build_admin_reveal_key_payload};
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
normalize_auth_type, normalize_json_object, normalize_string_list, validate_vertex_api_formats,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
build_admin_provider_key_response, decrypt_catalog_secret_with_fallbacks,
|
||||
encrypt_catalog_secret_with_fallbacks, json_string_list, parse_catalog_auth_config_json,
|
||||
AdminProviderKeyCreateRequest, AdminProviderKeyUpdateRequest,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(crate) async fn build_admin_create_provider_key_record(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
normalize_json_object, normalize_provider_billing_type, normalize_provider_type_input,
|
||||
parse_optional_rfc3339_unix_secs,
|
||||
};
|
||||
use crate::gateway::api::ai::{
|
||||
admin_default_body_rules_for_signature, admin_endpoint_signature_parts,
|
||||
};
|
||||
use crate::gateway::handlers::public::normalize_admin_base_url;
|
||||
use crate::gateway::handlers::{AdminProviderCreateRequest, AdminProviderUpdateRequest};
|
||||
use crate::gateway::provider_transport::provider_type_enables_format_conversion_by_default;
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(crate) async fn build_admin_update_provider_record(
|
||||
state: &AppState,
|
||||
|
||||
@@ -6,7 +6,13 @@ fn normalize_reveal_auth_type(value: &str) -> &str {
|
||||
}
|
||||
}
|
||||
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{
|
||||
decrypt_catalog_secret_with_fallbacks, parse_catalog_auth_config_json,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use chrono::{SecondsFormat, Utc};
|
||||
use serde_json::json;
|
||||
|
||||
pub(crate) fn build_admin_reveal_key_payload(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
pub(crate) use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN_AWS_REGIONS: &[&str] = &[
|
||||
"af-south-1",
|
||||
@@ -31,8 +38,7 @@ const ADMIN_AWS_REGIONS: &[&str] = &[
|
||||
"us-west-1",
|
||||
"us-west-2",
|
||||
];
|
||||
const ADMIN_MODEL_CATALOG_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin model catalog routes require Rust maintenance backend";
|
||||
const ADMIN_MODEL_CATALOG_DATA_UNAVAILABLE_DETAIL: &str = "Admin model catalog data unavailable";
|
||||
|
||||
#[path = "core/management_tokens_routes.rs"]
|
||||
mod admin_core_management_tokens_routes;
|
||||
@@ -45,10 +51,10 @@ mod admin_core_oauth_routes;
|
||||
#[path = "core/system_routes.rs"]
|
||||
mod admin_core_system_routes;
|
||||
|
||||
fn build_admin_model_catalog_maintenance_response() -> Response<Body> {
|
||||
fn build_admin_model_catalog_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_MODEL_CATALOG_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_MODEL_CATALOG_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
@@ -56,7 +62,7 @@ fn build_admin_model_catalog_maintenance_response() -> Response<Body> {
|
||||
pub(crate) async fn maybe_build_local_admin_core_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if let Some(response) = admin_core_management_tokens_routes::maybe_build_local_admin_core_management_tokens_response(
|
||||
state,
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::internal::build_management_token_payload;
|
||||
use crate::gateway::handlers::{
|
||||
admin_management_token_id_from_path, admin_management_token_status_id_from_path,
|
||||
is_admin_management_tokens_root, query_param_optional_bool, query_param_value,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use aether_data::repository::management_tokens::ManagementTokenListQuery;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_core_management_tokens_response(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
use super::*;
|
||||
use super::super::{
|
||||
build_admin_model_catalog_payload, clear_admin_external_models_cache,
|
||||
read_admin_external_models_cache,
|
||||
};
|
||||
use super::build_admin_model_catalog_data_unavailable_response;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_core_model_response(
|
||||
state: &AppState,
|
||||
@@ -14,10 +26,10 @@ pub(super) async fn maybe_build_local_admin_core_model_response(
|
||||
&& request_context.request_path == "/api/admin/models/catalog"
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_model_catalog_maintenance_response()));
|
||||
return Ok(Some(build_admin_model_catalog_data_unavailable_response()));
|
||||
}
|
||||
let Some(payload) = build_admin_model_catalog_payload(state).await else {
|
||||
return Ok(Some(build_admin_model_catalog_maintenance_response()));
|
||||
return Ok(Some(build_admin_model_catalog_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::public::{
|
||||
admin_module_by_name, admin_module_name_from_enabled_path, admin_module_name_from_status_path,
|
||||
build_admin_module_runtime_state, build_admin_module_status_payload,
|
||||
build_admin_module_validation_result, build_admin_modules_status_payload,
|
||||
module_available_from_env, AdminSetModuleEnabledRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_core_modules_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
use super::*;
|
||||
use super::super::{
|
||||
build_admin_oauth_provider_payload, build_admin_oauth_supported_types_payload,
|
||||
build_admin_oauth_upsert_record, build_proxy_error_response,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_oauth_provider_type_from_path, admin_oauth_test_provider_type_from_path,
|
||||
AdminOAuthProviderUpsertRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_core_oauth_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,9 +1,33 @@
|
||||
use super::*;
|
||||
use super::super::build_proxy_error_response;
|
||||
use super::ADMIN_AWS_REGIONS;
|
||||
use crate::gateway::handlers::public::{
|
||||
apply_admin_email_template_update, apply_admin_system_config_update,
|
||||
apply_admin_system_settings_update, build_admin_api_formats_payload,
|
||||
build_admin_email_template_payload, build_admin_email_templates_payload,
|
||||
build_admin_system_check_update_payload, build_admin_system_config_detail_payload,
|
||||
build_admin_system_config_export_payload, build_admin_system_configs_payload,
|
||||
build_admin_system_settings_payload, build_admin_system_stats_payload,
|
||||
build_admin_system_users_export_payload, current_aether_version, delete_admin_system_config,
|
||||
preview_admin_email_template, reset_admin_email_template,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_system_config_key_from_path, admin_system_email_template_preview_type_from_path,
|
||||
admin_system_email_template_reset_type_from_path, admin_system_email_template_type_from_path,
|
||||
is_admin_system_configs_root, is_admin_system_email_templates_root,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_core_system_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -94,7 +118,7 @@ pub(super) async fn maybe_build_local_admin_core_system_response(
|
||||
return Ok(Some(
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": "Admin system maintenance requires Rust backend" })),
|
||||
Json(json!({ "detail": "Admin system data unavailable" })),
|
||||
)
|
||||
.into_response(),
|
||||
));
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
pub(crate) use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::Response;
|
||||
|
||||
#[path = "endpoints/health.rs"]
|
||||
mod endpoints_health;
|
||||
@@ -12,7 +14,7 @@ mod endpoints_rpm;
|
||||
pub(crate) async fn maybe_build_local_admin_endpoints_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if let Some(response) =
|
||||
endpoints_health::maybe_build_local_admin_endpoints_health_response(state, request_context)
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
pub(crate) use super::*;
|
||||
use super::super::{
|
||||
admin_health_key_id, admin_recover_key_id, build_admin_endpoint_health_status_payload,
|
||||
build_admin_health_summary_payload, build_admin_key_health_payload, recover_admin_key_health,
|
||||
recover_all_admin_key_health,
|
||||
};
|
||||
use crate::gateway::handlers::public::{
|
||||
build_api_format_health_monitor_payload, ApiFormatHealthMonitorOptions,
|
||||
};
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN_ENDPOINT_HEALTH_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin endpoint health routes require Rust maintenance backend";
|
||||
const ADMIN_ENDPOINT_HEALTH_DATA_UNAVAILABLE_DETAIL: &str =
|
||||
"Admin endpoint health data unavailable";
|
||||
|
||||
fn build_admin_endpoint_health_maintenance_response() -> Response<Body> {
|
||||
fn build_admin_endpoint_health_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_ENDPOINT_HEALTH_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_ENDPOINT_HEALTH_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
@@ -24,10 +40,10 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
&& request_context.request_path == "/api/admin/endpoints/health/summary"
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let Some(payload) = build_admin_health_summary_payload(state).await else {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
@@ -39,7 +55,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
.starts_with("/api/admin/endpoints/health/key/")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let Some(key_id) = admin_health_key_id(&request_context.request_path) else {
|
||||
return Ok(Some(
|
||||
@@ -73,7 +89,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
.starts_with("/api/admin/endpoints/health/keys/")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let Some(key_id) = admin_recover_key_id(&request_context.request_path) else {
|
||||
return Ok(Some(
|
||||
@@ -105,10 +121,10 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
&& request_context.request_path == "/api/admin/endpoints/health/keys"
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let Some(payload) = recover_all_admin_key_health(state).await else {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
@@ -118,7 +134,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
&& request_context.request_path == "/api/admin/endpoints/health/api-formats"
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_request_candidate_data_reader() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let lookback_hours = query_param_value(
|
||||
request_context.request_query_string.as_deref(),
|
||||
@@ -146,7 +162,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
)
|
||||
.await
|
||||
else {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
@@ -156,7 +172,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
&& request_context.request_path == "/api/admin/endpoints/health/status"
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_request_candidate_data_reader() {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
}
|
||||
let lookback_hours = query_param_value(
|
||||
request_context.request_query_string.as_deref(),
|
||||
@@ -167,7 +183,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_health_response(
|
||||
.unwrap_or(6);
|
||||
let Some(payload) = build_admin_endpoint_health_status_payload(state, lookback_hours).await
|
||||
else {
|
||||
return Ok(Some(build_admin_endpoint_health_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoint_health_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
|
||||
@@ -1,9 +1,33 @@
|
||||
pub(crate) use super::*;
|
||||
use super::super::{
|
||||
admin_clear_oauth_invalid_key_id, admin_export_key_id, admin_provider_id_for_refresh_quota,
|
||||
admin_reveal_key_id, admin_update_key_id, build_admin_create_provider_key_record,
|
||||
build_admin_export_key_payload, build_admin_provider_key_response,
|
||||
build_admin_provider_keys_payload, build_admin_reveal_key_payload,
|
||||
build_admin_update_provider_key_record, normalize_string_id_list,
|
||||
refresh_antigravity_provider_quota_locally, refresh_codex_provider_quota_locally,
|
||||
refresh_kiro_provider_quota_locally,
|
||||
};
|
||||
use crate::gateway::handlers::public::build_admin_keys_grouped_by_format_payload;
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_id_for_keys, query_param_value, AdminProviderKeyBatchDeleteRequest,
|
||||
AdminProviderKeyCreateRequest, AdminProviderKeyUpdateRequest, AdminProviderQuotaRefreshRequest,
|
||||
OAUTH_ACCOUNT_BLOCK_PREFIX,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeSet;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_endpoints_keys_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
pub(crate) use super::*;
|
||||
use super::super::{
|
||||
admin_default_body_rules_api_format, admin_endpoint_id, admin_provider_id_for_endpoints,
|
||||
build_admin_create_provider_endpoint_record, build_admin_endpoint_payload,
|
||||
build_admin_provider_endpoint_response, build_admin_provider_endpoints_payload,
|
||||
build_admin_update_provider_endpoint_record, endpoint_key_counts_by_format,
|
||||
key_api_formats_without_entry,
|
||||
};
|
||||
use crate::gateway::api::ai::admin_default_body_rules_for_signature;
|
||||
use crate::gateway::handlers::{
|
||||
query_param_value, AdminProviderEndpointCreateRequest, AdminProviderEndpointUpdateRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
const ADMIN_ENDPOINTS_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin endpoint routes require Rust maintenance backend";
|
||||
const ADMIN_ENDPOINTS_DATA_UNAVAILABLE_DETAIL: &str = "Admin endpoint data unavailable";
|
||||
|
||||
fn build_admin_endpoints_maintenance_response() -> Response<Body> {
|
||||
fn build_admin_endpoints_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_ENDPOINTS_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_ENDPOINTS_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
@@ -14,7 +32,7 @@ fn build_admin_endpoints_maintenance_response() -> Response<Body> {
|
||||
pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -28,7 +46,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
&& request_context.request_path.ends_with("/endpoints")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
let Some(provider_id) = admin_provider_id_for_endpoints(&request_context.request_path)
|
||||
else {
|
||||
@@ -68,7 +86,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
&& request_context.request_path.ends_with("/endpoints")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
let Some(provider_id) = admin_provider_id_for_endpoints(&request_context.request_path)
|
||||
else {
|
||||
@@ -130,7 +148,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
}
|
||||
};
|
||||
let Some(created) = state.create_provider_catalog_endpoint(&record).await? else {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
};
|
||||
let now_unix_secs = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@@ -157,7 +175,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
.starts_with("/api/admin/endpoints/")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
let Some(endpoint_id) = admin_endpoint_id(&request_context.request_path) else {
|
||||
return Ok(Some(
|
||||
@@ -265,7 +283,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
.update_provider_catalog_endpoint(&updated_record)
|
||||
.await?
|
||||
else {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
};
|
||||
let now_unix_secs = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@@ -303,7 +321,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
.starts_with("/api/admin/endpoints/")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() || !state.has_provider_catalog_data_writer() {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
let Some(endpoint_id) = admin_endpoint_id(&request_context.request_path) else {
|
||||
return Ok(Some(
|
||||
@@ -359,7 +377,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
.await?
|
||||
.is_none()
|
||||
{
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
affected_keys_count += 1;
|
||||
}
|
||||
@@ -388,7 +406,7 @@ pub(super) async fn maybe_build_local_admin_endpoints_routes_response(
|
||||
.starts_with("/api/admin/endpoints/")
|
||||
{
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_endpoints_maintenance_response()));
|
||||
return Ok(Some(build_admin_endpoints_data_unavailable_response()));
|
||||
}
|
||||
let Some(endpoint_id) = admin_endpoint_id(&request_context.request_path) else {
|
||||
return Ok(Some(
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
pub(crate) use super::*;
|
||||
use super::super::{admin_rpm_key_id, build_admin_key_rpm_payload};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_endpoints_rpm_response(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
pub(crate) use super::*;
|
||||
|
||||
#[path = "endpoints_health_helpers/endpoints.rs"]
|
||||
mod endpoints;
|
||||
#[path = "endpoints_health_helpers/keys.rs"]
|
||||
@@ -7,6 +5,14 @@ mod keys;
|
||||
#[path = "endpoints_health_helpers/status.rs"]
|
||||
mod status;
|
||||
|
||||
pub(crate) use self::endpoints::*;
|
||||
pub(crate) use self::keys::*;
|
||||
pub(crate) use self::status::*;
|
||||
pub(crate) use self::endpoints::{
|
||||
build_admin_create_provider_endpoint_record, build_admin_endpoint_payload,
|
||||
build_admin_provider_endpoints_payload, build_admin_update_provider_endpoint_record,
|
||||
};
|
||||
pub(crate) use self::keys::{
|
||||
build_admin_key_health_payload, build_admin_key_rpm_payload, recover_admin_key_health,
|
||||
recover_all_admin_key_health,
|
||||
};
|
||||
pub(crate) use self::status::{
|
||||
build_admin_endpoint_health_status_payload, build_admin_health_summary_payload,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
use super::*;
|
||||
use crate::gateway::api::ai::{
|
||||
admin_default_body_rules_for_signature, admin_endpoint_signature_parts,
|
||||
};
|
||||
use crate::gateway::handlers::public::{admin_requested_force_stream, normalize_admin_base_url};
|
||||
use crate::gateway::provider_transport::provider_type_is_fixed;
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::super::{build_admin_provider_endpoint_response, endpoint_key_counts_by_format};
|
||||
use crate::gateway::handlers::{
|
||||
AdminProviderEndpointCreateRequest, AdminProviderEndpointUpdateRequest,
|
||||
};
|
||||
|
||||
pub(crate) async fn build_admin_provider_endpoints_payload(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::public::provider_key_api_formats;
|
||||
use crate::gateway::scheduler::count_recent_rpm_requests_for_provider_key_since;
|
||||
use crate::gateway::AppState;
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(crate) async fn build_admin_key_health_payload(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::public::{
|
||||
api_format_display_name, build_public_health_timeline, provider_key_api_formats,
|
||||
};
|
||||
use crate::gateway::handlers::unix_secs_to_rfc3339;
|
||||
use crate::gateway::scheduler::{is_provider_key_circuit_open, provider_key_health_score};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::candidates::PublicHealthTimelineBucket;
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(crate) async fn build_admin_endpoint_health_status_payload(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::{self, Response};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::Json;
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
const ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin Gemini Files routes require Rust maintenance backend";
|
||||
const ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL: &str = "Admin Gemini files data unavailable";
|
||||
const ADMIN_GEMINI_FILE_UPLOAD_DETAIL: &str = "Admin Gemini file upload requires Rust uploader";
|
||||
const ADMIN_GEMINI_FILES_DEFAULT_PAGE: usize = 1;
|
||||
const ADMIN_GEMINI_FILES_DEFAULT_PAGE_SIZE: usize = 20;
|
||||
@@ -15,7 +21,7 @@ mod admin_gemini_files_upload;
|
||||
pub(crate) async fn maybe_build_local_admin_gemini_files_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -48,9 +54,7 @@ pub(crate) async fn maybe_build_local_admin_gemini_files_response(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn admin_gemini_files_key_capable(
|
||||
key: &aether_data::repository::provider_catalog::StoredProviderCatalogKey,
|
||||
) -> bool {
|
||||
fn admin_gemini_files_key_capable(key: &StoredProviderCatalogKey) -> bool {
|
||||
key.is_active
|
||||
&& key
|
||||
.capabilities
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_gemini_files_error_response, admin_gemini_files_key_capable,
|
||||
admin_gemini_files_now_unix_secs, ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DEFAULT_PAGE, ADMIN_GEMINI_FILES_DEFAULT_PAGE_SIZE,
|
||||
ADMIN_GEMINI_FILES_MAX_PAGE_SIZE,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_gemini_file_mapping_id_from_path, is_admin_gemini_files_capable_keys_root,
|
||||
is_admin_gemini_files_mappings_root, is_admin_gemini_files_stats_root,
|
||||
query_param_optional_bool, query_param_value, unix_secs_to_rfc3339,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::body::Body;
|
||||
use axum::http::{self, Response};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::Json;
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct AdminGeminiFilesPageQuery {
|
||||
@@ -61,7 +78,7 @@ where
|
||||
{
|
||||
let user_ids = mappings
|
||||
.filter_map(|mapping| mapping.user_id.clone())
|
||||
.collect::<std::collections::BTreeSet<_>>()
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
let users = state.list_users_by_ids(&user_ids).await?;
|
||||
@@ -146,7 +163,7 @@ pub(super) async fn maybe_build_local_admin_gemini_files_read_response(
|
||||
if !state.has_gemini_file_mapping_data_reader() {
|
||||
return Ok(Some(admin_gemini_files_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
)));
|
||||
}
|
||||
let page = match admin_gemini_files_page_query(request_context)? {
|
||||
@@ -200,7 +217,7 @@ pub(super) async fn maybe_build_local_admin_gemini_files_read_response(
|
||||
if !state.has_gemini_file_mapping_data_reader() {
|
||||
return Ok(Some(admin_gemini_files_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
)));
|
||||
}
|
||||
let stats = state.summarize_gemini_file_mappings(now_unix_secs).await?;
|
||||
@@ -230,7 +247,7 @@ pub(super) async fn maybe_build_local_admin_gemini_files_read_response(
|
||||
if !state.has_gemini_file_mapping_data_writer() {
|
||||
return Ok(Some(admin_gemini_files_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
)));
|
||||
}
|
||||
let Some(mapping_id) =
|
||||
@@ -262,7 +279,7 @@ pub(super) async fn maybe_build_local_admin_gemini_files_read_response(
|
||||
if !state.has_gemini_file_mapping_data_writer() {
|
||||
return Ok(Some(admin_gemini_files_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
)));
|
||||
}
|
||||
let deleted_count = state
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_gemini_files_error_response, admin_gemini_files_key_capable,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use crate::gateway::handlers::{is_admin_gemini_files_upload_root, query_param_value};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult, RequestBody};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
|
||||
};
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::{self, Response};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::Json;
|
||||
use base64::Engine as _;
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct AdminGeminiFilesUploadRequest {
|
||||
@@ -18,7 +34,7 @@ struct AdminGeminiFilesUploadExecutionSuccess {
|
||||
pub(super) async fn maybe_build_local_admin_gemini_files_upload_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
match request_context
|
||||
.control_decision
|
||||
@@ -32,7 +48,7 @@ pub(super) async fn maybe_build_local_admin_gemini_files_upload_response(
|
||||
if !state.has_gemini_file_mapping_data_writer() {
|
||||
return Ok(Some(admin_gemini_files_error_response(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
ADMIN_GEMINI_FILES_RUST_BACKEND_DETAIL,
|
||||
ADMIN_GEMINI_FILES_DATA_UNAVAILABLE_DETAIL,
|
||||
)));
|
||||
}
|
||||
let upload =
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
pub(crate) use super::*;
|
||||
|
||||
#[path = "global_models/helpers.rs"]
|
||||
mod global_models_helpers;
|
||||
#[path = "global_models/routes.rs"]
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
use super::*;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) const ADMIN_GLOBAL_MODELS_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin global model routes require Rust maintenance backend";
|
||||
pub(super) const ADMIN_GLOBAL_MODELS_DATA_UNAVAILABLE_DETAIL: &str =
|
||||
"Admin global model data unavailable";
|
||||
|
||||
pub(super) fn build_admin_global_models_maintenance_response() -> Response<Body> {
|
||||
pub(super) fn build_admin_global_models_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_GLOBAL_MODELS_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_GLOBAL_MODELS_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
use super::*;
|
||||
use super::super::{
|
||||
build_admin_assign_global_model_to_providers_payload, build_admin_global_model_create_record,
|
||||
build_admin_global_model_payload, build_admin_global_model_providers_payload,
|
||||
build_admin_global_model_response, build_admin_global_model_routing_payload,
|
||||
build_admin_global_model_update_record, build_admin_global_models_payload,
|
||||
resolve_admin_global_model_by_id_or_err,
|
||||
};
|
||||
use super::global_models_helpers::{
|
||||
build_admin_global_models_data_unavailable_response,
|
||||
ADMIN_GLOBAL_MODELS_DATA_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_global_model_assign_to_providers_id, admin_global_model_id_from_path,
|
||||
admin_global_model_providers_id, admin_global_model_routing_id, is_admin_global_models_root,
|
||||
query_param_optional_bool, query_param_value, AdminBatchAssignToProvidersRequest,
|
||||
AdminBatchDeleteIdsRequest, AdminGlobalModelCreateRequest, AdminGlobalModelUpdateRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -14,7 +39,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_method == http::Method::GET
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(global_model_id) = admin_global_model_routing_id(&request_context.request_path)
|
||||
else {
|
||||
@@ -43,7 +68,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& is_admin_global_models_root(&request_context.request_path)
|
||||
{
|
||||
if !state.has_global_model_data_reader() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let skip = query_param_value(request_context.request_query_string.as_deref(), "skip")
|
||||
.and_then(|value| value.parse::<usize>().ok())
|
||||
@@ -58,7 +83,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
let Some(payload) =
|
||||
build_admin_global_models_payload(state, skip, limit, is_active, search).await
|
||||
else {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
};
|
||||
return Ok(Some(Json(payload).into_response()));
|
||||
}
|
||||
@@ -68,7 +93,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_method == http::Method::GET
|
||||
{
|
||||
if !state.has_global_model_data_reader() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(global_model_id) = admin_global_model_id_from_path(&request_context.request_path)
|
||||
else {
|
||||
@@ -98,7 +123,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& is_admin_global_models_root(&request_context.request_path)
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_global_model_data_writer() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(request_body) = request_body else {
|
||||
return Ok(Some(
|
||||
@@ -157,7 +182,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
}
|
||||
None => (
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_GLOBAL_MODELS_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_GLOBAL_MODELS_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response(),
|
||||
},
|
||||
@@ -169,7 +194,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_method == http::Method::PATCH
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_global_model_data_writer() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(global_model_id) = admin_global_model_id_from_path(&request_context.request_path)
|
||||
else {
|
||||
@@ -284,7 +309,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_method == http::Method::DELETE
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_global_model_data_writer() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(global_model_id) = admin_global_model_id_from_path(&request_context.request_path)
|
||||
else {
|
||||
@@ -327,7 +352,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_path == "/api/admin/models/global/batch-delete"
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_global_model_data_writer() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(request_body) = request_body else {
|
||||
return Ok(Some(
|
||||
@@ -441,7 +466,7 @@ pub(crate) async fn maybe_build_local_admin_global_models_response(
|
||||
&& request_context.request_method == http::Method::GET
|
||||
{
|
||||
if !state.has_global_model_data_reader() || !state.has_provider_catalog_data_reader() {
|
||||
return Ok(Some(build_admin_global_models_maintenance_response()));
|
||||
return Ok(Some(build_admin_global_models_data_unavailable_response()));
|
||||
}
|
||||
let Some(global_model_id) = admin_global_model_providers_id(&request_context.request_path)
|
||||
else {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
response::Response,
|
||||
};
|
||||
|
||||
#[path = "ldap/builders.rs"]
|
||||
mod ldap_builders;
|
||||
@@ -10,7 +14,7 @@ mod ldap_shared;
|
||||
pub(crate) async fn maybe_build_local_admin_ldap_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
ldap_routes::maybe_build_local_admin_ldap_response(state, request_context, request_body).await
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use super::ldap_shared::*;
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{
|
||||
decrypt_catalog_secret_with_fallbacks, encrypt_catalog_secret_with_fallbacks,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(super) struct AdminLdapConfigUpdateRequest {
|
||||
|
||||
@@ -3,12 +3,19 @@ use super::ldap_builders::{
|
||||
AdminLdapConfigTestRequest, AdminLdapConfigUpdateRequest,
|
||||
};
|
||||
use super::ldap_shared::*;
|
||||
use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_ldap_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
use super::*;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) const ADMIN_LDAP_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin LDAP routes require Rust maintenance backend";
|
||||
pub(super) const ADMIN_LDAP_DATA_UNAVAILABLE_DETAIL: &str = "Admin LDAP data unavailable";
|
||||
pub(super) const ADMIN_LDAP_TEST_FAILURE_MESSAGE: &str = "连接失败,请检查服务器地址、端口和凭据";
|
||||
|
||||
pub(super) fn admin_ldap_default_search_filter() -> String {
|
||||
@@ -100,7 +105,7 @@ pub(super) fn admin_ldap_bad_request_response(detail: impl Into<String>) -> Resp
|
||||
pub(super) fn admin_ldap_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_LDAP_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_LDAP_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,46 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{json_string_list, unix_secs_to_rfc3339};
|
||||
use crate::gateway::GatewayPublicRequestContext;
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub(crate) fn build_unhandled_admin_proxy_response(
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
) -> Response<Body> {
|
||||
let decision = request_context.control_decision.as_ref();
|
||||
(
|
||||
http::StatusCode::NOT_IMPLEMENTED,
|
||||
Json(json!({
|
||||
"detail": "admin proxy route not implemented in rust frontdoor",
|
||||
"route_family": decision.and_then(|value| value.route_family.as_deref()),
|
||||
"route_kind": decision.and_then(|value| value.route_kind.as_deref()),
|
||||
"request_path": request_context.request_path,
|
||||
})),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
pub(crate) fn build_admin_proxy_auth_required_response(
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
) -> Response<Body> {
|
||||
let decision = request_context.control_decision.as_ref();
|
||||
(
|
||||
http::StatusCode::UNAUTHORIZED,
|
||||
Json(json!({
|
||||
"detail": "admin authentication required",
|
||||
"route_family": decision.and_then(|value| value.route_family.as_deref()),
|
||||
"route_kind": decision.and_then(|value| value.route_kind.as_deref()),
|
||||
"request_path": request_context.request_path,
|
||||
})),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
pub(crate) fn provider_catalog_key_supports_format(
|
||||
key: &StoredProviderCatalogKey,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
pub(crate) use super::*;
|
||||
use super::{
|
||||
admin_clear_oauth_invalid_key_id, admin_export_key_id, admin_provider_id_for_refresh_quota,
|
||||
admin_reveal_key_id, admin_update_key_id, build_admin_provider_key_response,
|
||||
INTERNAL_GATEWAY_PATH_PREFIXES,
|
||||
};
|
||||
|
||||
mod adaptive;
|
||||
mod api_keys;
|
||||
@@ -38,37 +42,69 @@ mod users;
|
||||
mod video_tasks;
|
||||
mod wallets;
|
||||
|
||||
pub(crate) use self::adaptive::*;
|
||||
pub(crate) use self::api_keys::*;
|
||||
pub(crate) use self::billing::*;
|
||||
pub(crate) use self::catalog_write_helpers::*;
|
||||
pub(crate) use self::core::*;
|
||||
pub(crate) use self::endpoints::*;
|
||||
pub(crate) use self::endpoints_health_helpers::*;
|
||||
pub(crate) use self::gemini_files::*;
|
||||
pub(crate) use self::global_models::*;
|
||||
pub(crate) use self::ldap::*;
|
||||
pub(crate) use self::misc_helpers::*;
|
||||
pub(crate) use self::models_helpers::*;
|
||||
pub(crate) use self::adaptive::maybe_build_local_admin_adaptive_response;
|
||||
use self::adaptive::*;
|
||||
pub(crate) use self::api_keys::maybe_build_local_admin_api_keys_response;
|
||||
use self::api_keys::*;
|
||||
pub(crate) use self::billing::maybe_build_local_admin_billing_response;
|
||||
use self::billing::*;
|
||||
use self::catalog_write_helpers::*;
|
||||
pub(crate) use self::core::maybe_build_local_admin_core_response;
|
||||
use self::core::*;
|
||||
pub(crate) use self::endpoints::maybe_build_local_admin_endpoints_response;
|
||||
use self::endpoints::*;
|
||||
pub(crate) use self::endpoints_health_helpers::build_admin_endpoint_health_status_payload;
|
||||
use self::endpoints_health_helpers::*;
|
||||
pub(crate) use self::gemini_files::maybe_build_local_admin_gemini_files_response;
|
||||
use self::gemini_files::*;
|
||||
pub(crate) use self::global_models::maybe_build_local_admin_global_models_response;
|
||||
use self::global_models::*;
|
||||
pub(crate) use self::ldap::maybe_build_local_admin_ldap_response;
|
||||
use self::ldap::*;
|
||||
use self::misc_helpers::*;
|
||||
pub(crate) use self::misc_helpers::{
|
||||
build_admin_proxy_auth_required_response, build_unhandled_admin_proxy_response,
|
||||
provider_catalog_key_supports_format,
|
||||
};
|
||||
use self::models_helpers::*;
|
||||
pub(crate) use self::monitoring::maybe_build_local_admin_monitoring_root_response as maybe_build_local_admin_monitoring_response;
|
||||
pub(crate) use self::oauth_helpers::*;
|
||||
pub(crate) use self::payments::*;
|
||||
pub(crate) use self::pool::*;
|
||||
pub(crate) use self::provider_models::*;
|
||||
pub(crate) use self::provider_oauth_dispatch::*;
|
||||
pub(crate) use self::provider_oauth_quota::*;
|
||||
pub(crate) use self::provider_oauth_refresh::*;
|
||||
pub(crate) use self::provider_oauth_state::*;
|
||||
use self::oauth_helpers::*;
|
||||
pub(crate) use self::payments::maybe_build_local_admin_payments_response;
|
||||
use self::payments::*;
|
||||
pub(crate) use self::pool::maybe_build_local_admin_pool_response;
|
||||
use self::pool::*;
|
||||
pub(crate) use self::provider_models::maybe_build_local_admin_provider_models_response;
|
||||
use self::provider_models::*;
|
||||
pub(crate) use self::provider_oauth_dispatch::maybe_build_local_admin_provider_oauth_response;
|
||||
use self::provider_oauth_dispatch::*;
|
||||
use self::provider_oauth_quota::*;
|
||||
pub(crate) use self::provider_oauth_refresh::build_internal_control_error_response;
|
||||
use self::provider_oauth_refresh::*;
|
||||
use self::provider_oauth_state::*;
|
||||
pub(crate) use self::provider_ops::admin_provider_ops_local_action_response;
|
||||
pub(crate) use self::provider_ops::maybe_build_local_admin_provider_ops_response;
|
||||
pub(crate) use self::provider_query::*;
|
||||
pub(crate) use self::provider_strategy::*;
|
||||
pub(crate) use self::providers::*;
|
||||
pub(crate) use self::providers_helpers::*;
|
||||
pub(crate) use self::proxy_nodes::*;
|
||||
pub(crate) use self::security::*;
|
||||
pub(crate) use self::stats::*;
|
||||
pub(crate) use self::usage::*;
|
||||
pub(crate) use self::users::*;
|
||||
pub(crate) use self::video_tasks::*;
|
||||
pub(crate) use self::wallets::*;
|
||||
pub(crate) use self::provider_query::maybe_build_local_admin_provider_query_response;
|
||||
use self::provider_query::*;
|
||||
pub(crate) use self::provider_strategy::maybe_build_local_admin_provider_strategy_response;
|
||||
use self::provider_strategy::*;
|
||||
pub(crate) use self::providers::maybe_build_local_admin_providers_response;
|
||||
use self::providers::*;
|
||||
use self::providers_helpers::*;
|
||||
pub(crate) use self::proxy_nodes::maybe_build_local_admin_proxy_nodes_response;
|
||||
use self::proxy_nodes::*;
|
||||
pub(crate) use self::security::maybe_build_local_admin_security_response;
|
||||
use self::security::*;
|
||||
use self::stats::*;
|
||||
pub(crate) use self::stats::{
|
||||
admin_stats_bad_request_response, list_usage_for_optional_range,
|
||||
maybe_build_local_admin_stats_response, parse_bounded_u32, round_to, AdminStatsTimeRange,
|
||||
AdminStatsUsageFilter,
|
||||
};
|
||||
pub(crate) use self::usage::maybe_build_local_admin_usage_response;
|
||||
use self::usage::*;
|
||||
pub(crate) use self::users::maybe_build_local_admin_users_response;
|
||||
use self::users::*;
|
||||
pub(crate) use self::video_tasks::maybe_build_local_admin_video_tasks_response;
|
||||
use self::video_tasks::*;
|
||||
pub(crate) use self::wallets::maybe_build_local_admin_wallets_response;
|
||||
use self::wallets::*;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{
|
||||
ADMIN_EXTERNAL_MODELS_CACHE_KEY, ADMIN_EXTERNAL_MODELS_CACHE_TTL_SECS,
|
||||
OFFICIAL_EXTERNAL_MODEL_PROVIDERS,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use serde_json::json;
|
||||
|
||||
fn mark_admin_external_models_official(mut payload: serde_json::Value) -> serde_json::Value {
|
||||
let Some(models) = payload
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_provider_model_effective_capability, admin_provider_model_effective_input_price,
|
||||
admin_provider_model_effective_output_price, model_tiered_pricing_first_tier_value,
|
||||
timestamp_or_now,
|
||||
};
|
||||
use crate::gateway::handlers::json_string_list;
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::global_models::{
|
||||
AdminGlobalModelListQuery, StoredAdminGlobalModel, StoredAdminProviderModel,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(crate) async fn resolve_admin_global_model_by_id_or_err(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
use super::*;
|
||||
use super::resolve_admin_global_model_by_id_or_err;
|
||||
use crate::gateway::handlers::admin::provider_catalog_key_supports_format;
|
||||
use crate::gateway::handlers::{json_string_list, masked_catalog_api_key};
|
||||
use crate::gateway::scheduler::{is_provider_key_circuit_open, provider_key_health_score};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::global_models::{
|
||||
AdminProviderModelListQuery, UpsertAdminProviderModelRecord,
|
||||
};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(crate) async fn build_admin_global_model_routing_payload(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
use super::*;
|
||||
use super::super::{normalize_json_array, normalize_json_object, normalize_string_list};
|
||||
use super::{
|
||||
admin_provider_model_effective_capability, admin_provider_model_effective_input_price,
|
||||
admin_provider_model_effective_output_price, admin_provider_model_name_exists,
|
||||
normalize_optional_price, normalize_required_trimmed_string,
|
||||
resolve_admin_global_model_by_id_or_err,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
AdminGlobalModelCreateRequest, AdminGlobalModelUpdateRequest, AdminImportProviderModelsRequest,
|
||||
AdminProviderModelCreateRequest, AdminProviderModelUpdateRequest,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::global_models::{
|
||||
AdminProviderModelListQuery, CreateAdminGlobalModelRecord, StoredAdminGlobalModel,
|
||||
StoredAdminProviderModel, UpdateAdminGlobalModelRecord, UpsertAdminProviderModelRecord,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(crate) async fn build_admin_global_model_create_record(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
pub(crate) use super::*;
|
||||
use crate::gateway::handlers::unix_secs_to_rfc3339;
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_data::repository::global_models::{
|
||||
AdminProviderModelListQuery, StoredAdminProviderModel,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[path = "models/external_cache.rs"]
|
||||
mod models_external_cache;
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
use super::*;
|
||||
use super::INTERNAL_GATEWAY_PATH_PREFIXES;
|
||||
use crate::gateway::handlers::{query_param_value, unix_secs_to_rfc3339};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use aether_crypto::decrypt_python_fernet_ciphertext;
|
||||
#[cfg(test)]
|
||||
use aether_crypto::DEVELOPMENT_ENCRYPTION_KEY;
|
||||
use axum::{body::Body, response::Response, Json};
|
||||
use chrono::Utc;
|
||||
use serde_json::json;
|
||||
|
||||
#[path = "monitoring/activity.rs"]
|
||||
mod activity;
|
||||
@@ -27,12 +35,12 @@ mod routes;
|
||||
mod test_support;
|
||||
#[path = "monitoring/trace.rs"]
|
||||
mod trace;
|
||||
use activity::{
|
||||
use self::activity::{
|
||||
build_admin_monitoring_audit_logs_response,
|
||||
build_admin_monitoring_suspicious_activities_response,
|
||||
build_admin_monitoring_system_status_response, build_admin_monitoring_user_behavior_response,
|
||||
};
|
||||
use cache::{
|
||||
use self::cache::{
|
||||
build_admin_monitoring_cache_affinities_response,
|
||||
build_admin_monitoring_cache_affinity_delete_response,
|
||||
build_admin_monitoring_cache_affinity_response, build_admin_monitoring_cache_config_response,
|
||||
@@ -47,21 +55,21 @@ use cache::{
|
||||
build_admin_monitoring_redis_cache_categories_response,
|
||||
build_admin_monitoring_redis_keys_delete_response,
|
||||
};
|
||||
use cache_affinity::{
|
||||
use self::cache_affinity::{
|
||||
admin_monitoring_cache_affinity_record, admin_monitoring_scheduler_affinity_cache_key,
|
||||
clear_admin_monitoring_scheduler_affinity_entries,
|
||||
delete_admin_monitoring_cache_affinity_entries_for_tests,
|
||||
delete_admin_monitoring_cache_affinity_raw_keys,
|
||||
};
|
||||
use cache_identity::{
|
||||
use self::cache_identity::{
|
||||
admin_monitoring_find_user_summary_by_id, admin_monitoring_list_export_api_key_records_by_ids,
|
||||
admin_monitoring_load_affinity_identity_maps,
|
||||
};
|
||||
use cache_payloads::{
|
||||
use self::cache_payloads::{
|
||||
admin_monitoring_cache_affinity_sort_value, admin_monitoring_masked_provider_key_prefix,
|
||||
admin_monitoring_masked_user_api_key_prefix,
|
||||
};
|
||||
use cache_route_helpers::{
|
||||
use self::cache_route_helpers::{
|
||||
admin_monitoring_cache_affinity_delete_params_from_path,
|
||||
admin_monitoring_cache_affinity_not_found_response,
|
||||
admin_monitoring_cache_affinity_unavailable_response,
|
||||
@@ -73,39 +81,38 @@ use cache_route_helpers::{
|
||||
admin_monitoring_cache_users_user_identifier_from_path,
|
||||
admin_monitoring_redis_unavailable_response, parse_admin_monitoring_keyword_filter,
|
||||
};
|
||||
use cache_store::{
|
||||
use self::cache_store::{
|
||||
admin_monitoring_has_test_redis_keys, build_admin_monitoring_cache_snapshot,
|
||||
delete_admin_monitoring_namespaced_keys, list_admin_monitoring_cache_affinity_records,
|
||||
list_admin_monitoring_cache_affinity_records_by_affinity_keys,
|
||||
list_admin_monitoring_namespaced_keys, load_admin_monitoring_cache_affinity_entries_for_tests,
|
||||
};
|
||||
use common::{
|
||||
admin_monitoring_bad_request_response, admin_monitoring_maintenance_response,
|
||||
use self::common::{
|
||||
admin_monitoring_bad_request_response, admin_monitoring_data_unavailable_response,
|
||||
admin_monitoring_not_found_response, admin_monitoring_usage_is_error,
|
||||
admin_monitoring_user_behavior_user_id_from_path, AdminMonitoringCacheAffinityRecord,
|
||||
AdminMonitoringCacheSnapshot,
|
||||
};
|
||||
use resilience::{
|
||||
use self::resilience::{
|
||||
build_admin_monitoring_reset_error_stats_response,
|
||||
build_admin_monitoring_resilience_circuit_history_response,
|
||||
build_admin_monitoring_resilience_status_response,
|
||||
};
|
||||
use route_filters::{
|
||||
use self::route_filters::{
|
||||
admin_monitoring_escape_like_pattern, parse_admin_monitoring_days,
|
||||
parse_admin_monitoring_event_type_filter, parse_admin_monitoring_hours,
|
||||
parse_admin_monitoring_limit, parse_admin_monitoring_offset,
|
||||
parse_admin_monitoring_username_filter,
|
||||
};
|
||||
use routes::{
|
||||
use self::routes::{
|
||||
match_admin_monitoring_route, maybe_build_local_admin_monitoring_response, AdminMonitoringRoute,
|
||||
};
|
||||
use trace::{
|
||||
use self::trace::{
|
||||
build_admin_monitoring_trace_provider_stats_response,
|
||||
build_admin_monitoring_trace_request_response,
|
||||
};
|
||||
|
||||
const ADMIN_MONITORING_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin monitoring routes require Rust maintenance backend";
|
||||
const ADMIN_MONITORING_DATA_UNAVAILABLE_DETAIL: &str = "Admin monitoring data unavailable";
|
||||
const ADMIN_MONITORING_CACHE_AFFINITY_REDIS_REQUIRED_DETAIL: &str =
|
||||
"Redis未初始化,无法获取缓存亲和性";
|
||||
const ADMIN_MONITORING_REDIS_REQUIRED_DETAIL: &str = "Redis 未启用";
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
use super::*;
|
||||
use super::INTERNAL_GATEWAY_PATH_PREFIXES;
|
||||
use super::{
|
||||
admin_monitoring_bad_request_response, admin_monitoring_escape_like_pattern,
|
||||
admin_monitoring_usage_is_error, admin_monitoring_user_behavior_user_id_from_path,
|
||||
parse_admin_monitoring_days, parse_admin_monitoring_event_type_filter,
|
||||
parse_admin_monitoring_hours, parse_admin_monitoring_limit, parse_admin_monitoring_offset,
|
||||
parse_admin_monitoring_username_filter,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
fn build_admin_monitoring_audit_logs_payload(
|
||||
@@ -434,11 +448,9 @@ pub(super) async fn build_admin_monitoring_system_status_response(
|
||||
"nodes": tunnel.nodes,
|
||||
"active_streams": tunnel.active_streams,
|
||||
},
|
||||
"legacy_bridge": {
|
||||
"status": LEGACY_INTERNAL_GATEWAY_PHASEOUT_STATUS,
|
||||
"sunset_date": LEGACY_INTERNAL_GATEWAY_SUNSET_DATE,
|
||||
"sunset_http_date": LEGACY_INTERNAL_GATEWAY_SUNSET_HTTP_DATE,
|
||||
"metric_name": "legacy_internal_bridge_total",
|
||||
"internal_gateway": {
|
||||
"status": "rust_native_control_plane",
|
||||
"path_prefixes": INTERNAL_GATEWAY_PATH_PREFIXES,
|
||||
},
|
||||
"recent_errors": recent_errors,
|
||||
}))
|
||||
|
||||
@@ -1,4 +1,42 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_monitoring_bad_request_response, admin_monitoring_cache_affinity_delete_params_from_path,
|
||||
admin_monitoring_cache_affinity_not_found_response, admin_monitoring_cache_affinity_sort_value,
|
||||
admin_monitoring_cache_affinity_unavailable_response,
|
||||
admin_monitoring_cache_affinity_user_identifier_from_path,
|
||||
admin_monitoring_cache_model_mapping_provider_params_from_path,
|
||||
admin_monitoring_cache_model_name_from_path, admin_monitoring_cache_provider_id_from_path,
|
||||
admin_monitoring_cache_redis_category_from_path,
|
||||
admin_monitoring_cache_users_not_found_response,
|
||||
admin_monitoring_cache_users_user_identifier_from_path,
|
||||
admin_monitoring_find_user_summary_by_id, admin_monitoring_has_test_redis_keys,
|
||||
admin_monitoring_list_export_api_key_records_by_ids,
|
||||
admin_monitoring_load_affinity_identity_maps, admin_monitoring_masked_provider_key_prefix,
|
||||
admin_monitoring_masked_user_api_key_prefix, admin_monitoring_not_found_response,
|
||||
admin_monitoring_redis_unavailable_response, build_admin_monitoring_cache_snapshot,
|
||||
clear_admin_monitoring_scheduler_affinity_entries,
|
||||
delete_admin_monitoring_cache_affinity_raw_keys, delete_admin_monitoring_namespaced_keys,
|
||||
list_admin_monitoring_cache_affinity_records,
|
||||
list_admin_monitoring_cache_affinity_records_by_affinity_keys,
|
||||
list_admin_monitoring_namespaced_keys, load_admin_monitoring_cache_affinity_entries_for_tests,
|
||||
parse_admin_monitoring_keyword_filter, parse_admin_monitoring_limit,
|
||||
parse_admin_monitoring_offset, ADMIN_MONITORING_CACHE_AFFINITY_DEFAULT_TTL_SECS,
|
||||
ADMIN_MONITORING_CACHE_RESERVATION_RATIO,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_HIGH_LOAD_THRESHOLD,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_LOW_LOAD_THRESHOLD,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_PROBE_PHASE_REQUESTS,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_PROBE_RESERVATION,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_STABLE_MAX_RESERVATION,
|
||||
ADMIN_MONITORING_DYNAMIC_RESERVATION_STABLE_MIN_RESERVATION,
|
||||
ADMIN_MONITORING_REDIS_CACHE_CATEGORIES,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn build_admin_monitoring_cache_stats_response(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use super::AdminMonitoringCacheAffinityRecord;
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
|
||||
fn parse_admin_monitoring_cache_affinity_key(raw_key: &str) -> Option<(String, String, String)> {
|
||||
let parts = raw_key.split(':').collect::<Vec<_>>();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use super::AdminMonitoringCacheAffinityRecord;
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
|
||||
pub(super) async fn admin_monitoring_list_export_api_key_records_by_ids(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use super::*;
|
||||
use crate::gateway::AppState;
|
||||
use aether_crypto::decrypt_python_fernet_ciphertext;
|
||||
#[cfg(test)]
|
||||
use aether_crypto::DEVELOPMENT_ENCRYPTION_KEY;
|
||||
|
||||
pub(super) fn admin_monitoring_masked_user_api_key_prefix(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
ADMIN_MONITORING_CACHE_AFFINITY_REDIS_REQUIRED_DETAIL, ADMIN_MONITORING_REDIS_REQUIRED_DETAIL,
|
||||
};
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) fn parse_admin_monitoring_keyword_filter(query: Option<&str>) -> Option<String> {
|
||||
query_param_value(query, "keyword")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use super::super::round_to;
|
||||
use super::cache_affinity::admin_monitoring_cache_affinity_record;
|
||||
use super::*;
|
||||
use super::{AdminMonitoringCacheAffinityRecord, AdminMonitoringCacheSnapshot};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
|
||||
async fn count_admin_monitoring_cache_affinity_entries(state: &AppState) -> usize {
|
||||
let Some(runner) = state.redis_kv_runner() else {
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
use super::*;
|
||||
use super::ADMIN_MONITORING_DATA_UNAVAILABLE_DETAIL;
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) struct AdminMonitoringCacheSnapshot {
|
||||
pub(super) scheduler_name: String,
|
||||
@@ -28,10 +35,10 @@ pub(super) struct AdminMonitoringCacheAffinityRecord {
|
||||
pub(super) request_count: u64,
|
||||
}
|
||||
|
||||
pub(super) fn admin_monitoring_maintenance_response() -> Response<Body> {
|
||||
pub(super) fn admin_monitoring_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_MONITORING_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_MONITORING_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
use super::*;
|
||||
use super::{admin_monitoring_bad_request_response, admin_monitoring_usage_is_error};
|
||||
use crate::gateway::handlers::{
|
||||
provider_key_health_summary, query_param_value, unix_secs_to_rfc3339,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
struct AdminMonitoringResilienceSnapshot {
|
||||
timestamp: chrono::DateTime<chrono::Utc>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
|
||||
pub(super) fn admin_monitoring_escape_like_pattern(value: &str) -> String {
|
||||
value
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
build_admin_monitoring_audit_logs_response, build_admin_monitoring_cache_affinities_response,
|
||||
build_admin_monitoring_cache_affinity_delete_response,
|
||||
build_admin_monitoring_cache_affinity_response, build_admin_monitoring_cache_config_response,
|
||||
build_admin_monitoring_cache_flush_response, build_admin_monitoring_cache_metrics_response,
|
||||
build_admin_monitoring_cache_provider_delete_response,
|
||||
build_admin_monitoring_cache_stats_response,
|
||||
build_admin_monitoring_cache_users_delete_response,
|
||||
build_admin_monitoring_model_mapping_delete_model_response,
|
||||
build_admin_monitoring_model_mapping_delete_provider_response,
|
||||
build_admin_monitoring_model_mapping_delete_response,
|
||||
build_admin_monitoring_model_mapping_stats_response,
|
||||
build_admin_monitoring_redis_cache_categories_response,
|
||||
build_admin_monitoring_redis_keys_delete_response,
|
||||
build_admin_monitoring_reset_error_stats_response,
|
||||
build_admin_monitoring_resilience_circuit_history_response,
|
||||
build_admin_monitoring_resilience_status_response,
|
||||
build_admin_monitoring_suspicious_activities_response,
|
||||
build_admin_monitoring_system_status_response,
|
||||
build_admin_monitoring_trace_provider_stats_response,
|
||||
build_admin_monitoring_trace_request_response, build_admin_monitoring_user_behavior_response,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{body::Body, http, response::Response};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(super) enum AdminMonitoringRoute {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::*;
|
||||
use crate::gateway::GatewayPublicRequestContext;
|
||||
use aether_crypto::{encrypt_python_fernet_plaintext, DEVELOPMENT_ENCRYPTION_KEY};
|
||||
use axum::http::Uri;
|
||||
use axum::http::{self, Uri};
|
||||
use serde_json::json;
|
||||
|
||||
use aether_data::repository::auth::StoredAuthApiKeyExportRecord;
|
||||
use aether_data::repository::candidates::{RequestCandidateStatus, StoredRequestCandidate};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::test_support::*;
|
||||
use super::*;
|
||||
use super::{maybe_build_local_admin_monitoring_response, AppState};
|
||||
use axum::body::to_bytes;
|
||||
use serde_json::json;
|
||||
use std::sync::Arc;
|
||||
|
||||
use aether_data::repository::auth::{
|
||||
@@ -23,7 +24,7 @@ mod basics;
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_affinities_returns_empty_payload_without_runtime_or_test_entries() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(http::Method::GET, "/api/admin/monitoring/cache/affinities");
|
||||
|
||||
let response = maybe_build_local_admin_monitoring_response(&state, &context)
|
||||
@@ -54,7 +55,7 @@ async fn admin_monitoring_cache_affinity_returns_not_found_without_runtime_or_te
|
||||
sample_monitoring_export_api_key("user-1", "user-key-1"),
|
||||
]),
|
||||
);
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_user_reader_for_tests(
|
||||
@@ -102,7 +103,7 @@ async fn admin_monitoring_cache_affinities_and_affinity_return_local_payload_fro
|
||||
vec![sample_monitoring_catalog_endpoint()],
|
||||
vec![sample_monitoring_catalog_key()],
|
||||
));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_provider_catalog_reader_for_tests(
|
||||
@@ -208,7 +209,7 @@ async fn admin_monitoring_cache_users_delete_returns_local_payload_from_test_sto
|
||||
sample_monitoring_export_api_key("user-1", "user-key-1"),
|
||||
]),
|
||||
);
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_user_reader_for_tests(
|
||||
@@ -270,7 +271,7 @@ async fn admin_monitoring_cache_users_delete_returns_local_payload_from_test_sto
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_users_delete_returns_not_found_for_unknown_identifier() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_cache_affinity_entry_for_tests(
|
||||
"cache_affinity:user-key-1:openai:model-alpha",
|
||||
@@ -308,7 +309,7 @@ async fn admin_monitoring_cache_users_delete_returns_not_found_for_unknown_ident
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_flush_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_cache_affinity_entry_for_tests(
|
||||
"cache_affinity:user-key-1:openai:model-alpha",
|
||||
@@ -356,7 +357,7 @@ async fn admin_monitoring_cache_flush_returns_local_payload_from_test_store() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_provider_delete_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_cache_affinity_entry_for_tests(
|
||||
"cache_affinity:user-key-1:openai:model-alpha",
|
||||
@@ -414,7 +415,7 @@ async fn admin_monitoring_cache_provider_delete_returns_local_payload_from_test_
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_model_mapping_delete_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_redis_key_for_tests("model:id:model-1", json!({"id": "model-1"}))
|
||||
.with_admin_monitoring_redis_key_for_tests(
|
||||
@@ -456,7 +457,7 @@ async fn admin_monitoring_model_mapping_delete_returns_local_payload_from_test_s
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_model_mapping_delete_model_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_redis_key_for_tests(
|
||||
"global_model:name:model-alpha",
|
||||
@@ -504,7 +505,7 @@ async fn admin_monitoring_model_mapping_delete_model_returns_local_payload_from_
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_model_mapping_delete_provider_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_redis_key_for_tests(
|
||||
"model:provider_global:provider-1:model-alpha",
|
||||
@@ -553,7 +554,7 @@ async fn admin_monitoring_model_mapping_delete_provider_returns_local_payload_fr
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_redis_keys_delete_returns_local_payload_from_test_store() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_redis_key_for_tests("dashboard:summary:user-1", json!({"ok": true}))
|
||||
.with_admin_monitoring_redis_key_for_tests("dashboard:stats:user-1", json!({"ok": true}))
|
||||
@@ -596,7 +597,7 @@ async fn admin_monitoring_cache_affinity_delete_returns_local_payload_from_test_
|
||||
sample_monitoring_export_api_key("user-1", "user-key-1"),
|
||||
]),
|
||||
);
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_user_reader_for_tests(
|
||||
@@ -657,7 +658,7 @@ async fn admin_monitoring_cache_affinity_delete_returns_local_payload_from_test_
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_affinity_delete_returns_not_found_for_mismatched_endpoint() {
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_admin_monitoring_cache_affinity_entry_for_tests(
|
||||
"cache_affinity:user-key-1:openai:model-alpha",
|
||||
@@ -716,7 +717,7 @@ async fn admin_monitoring_cache_metrics_returns_local_payload() {
|
||||
now - 120,
|
||||
),
|
||||
]));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_usage_reader_for_tests(
|
||||
@@ -757,7 +758,7 @@ async fn admin_monitoring_cache_metrics_returns_local_payload() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_cache_config_returns_local_payload() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(http::Method::GET, "/api/admin/monitoring/cache/config");
|
||||
|
||||
let response = maybe_build_local_admin_monitoring_response(&state, &context)
|
||||
@@ -793,7 +794,7 @@ async fn admin_monitoring_cache_config_returns_local_payload() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_model_mapping_stats_returns_local_payload_without_redis() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::GET,
|
||||
"/api/admin/monitoring/cache/model-mapping/stats",
|
||||
@@ -848,7 +849,7 @@ async fn admin_monitoring_reset_error_stats_returns_local_payload_and_clears_fut
|
||||
Some(502),
|
||||
now - 120,
|
||||
)]));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_provider_catalog_and_usage_reader_for_tests(
|
||||
@@ -903,7 +904,7 @@ async fn admin_monitoring_reset_error_stats_returns_local_payload_and_clears_fut
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_redis_keys_returns_local_payload_without_redis() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(http::Method::GET, "/api/admin/monitoring/cache/redis-keys");
|
||||
|
||||
let response = maybe_build_local_admin_monitoring_response(&state, &context)
|
||||
@@ -923,7 +924,7 @@ async fn admin_monitoring_redis_keys_returns_local_payload_without_redis() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_redis_keys_delete_returns_unavailable_without_redis() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::DELETE,
|
||||
"/api/admin/monitoring/cache/redis-keys/upstream_models",
|
||||
@@ -965,7 +966,7 @@ async fn admin_monitoring_circuit_history_returns_local_payload() {
|
||||
})),
|
||||
)],
|
||||
));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_provider_catalog_reader_for_tests(
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
use super::*;
|
||||
use super::super::test_support::{request_context, sample_key, sample_provider, sample_usage};
|
||||
use super::super::{
|
||||
match_admin_monitoring_route, maybe_build_local_admin_monitoring_response,
|
||||
AdminMonitoringRoute, ADMIN_MONITORING_REDIS_REQUIRED_DETAIL,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::InMemoryProviderCatalogReadRepository;
|
||||
use aether_data::repository::usage::InMemoryUsageReadRepository;
|
||||
use axum::body::to_bytes;
|
||||
use serde_json::json;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn admin_monitoring_matches_typical_routes() {
|
||||
@@ -61,7 +71,7 @@ fn admin_monitoring_matches_cache_delete_shapes_and_trailing_slashes() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_model_mapping_delete_requires_redis_without_runtime_or_test_entries() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::DELETE,
|
||||
"/api/admin/monitoring/cache/model-mapping",
|
||||
@@ -84,7 +94,7 @@ async fn admin_monitoring_model_mapping_delete_requires_redis_without_runtime_or
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_user_behavior_returns_empty_local_payload_without_postgres() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::GET,
|
||||
"/api/admin/monitoring/user-behavior/user-123?days=30",
|
||||
@@ -112,7 +122,7 @@ async fn admin_monitoring_user_behavior_returns_empty_local_payload_without_post
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_audit_logs_returns_empty_local_payload_without_postgres() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::GET,
|
||||
"/api/admin/monitoring/audit-logs?username=alice&event_type=login_failed&days=14&limit=20&offset=5",
|
||||
@@ -140,7 +150,7 @@ async fn admin_monitoring_audit_logs_returns_empty_local_payload_without_postgre
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_monitoring_suspicious_activities_returns_empty_local_payload_without_postgres() {
|
||||
let state = AppState::new("http://127.0.0.1:9").expect("state should build");
|
||||
let state = AppState::new().expect("state should build");
|
||||
let context = request_context(
|
||||
http::Method::GET,
|
||||
"/api/admin/monitoring/suspicious-activities?hours=48",
|
||||
@@ -204,7 +214,7 @@ async fn admin_monitoring_resilience_status_returns_local_payload() {
|
||||
now - 172_800,
|
||||
),
|
||||
]));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_provider_catalog_and_usage_reader_for_tests(
|
||||
@@ -275,7 +285,7 @@ async fn admin_monitoring_cache_stats_returns_local_payload() {
|
||||
now - 120,
|
||||
),
|
||||
]));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_data_state_for_tests(
|
||||
crate::gateway::gateway_data::GatewayDataState::with_usage_reader_for_tests(
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
use super::test_support::*;
|
||||
use super::*;
|
||||
use super::super::maybe_build_local_admin_monitoring_response;
|
||||
use super::super::test_support::{
|
||||
request_context, sample_candidate, sample_endpoint, sample_key, sample_provider,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use axum::body::to_bytes;
|
||||
use serde_json::json;
|
||||
use std::sync::Arc;
|
||||
|
||||
use aether_data::repository::candidates::{
|
||||
@@ -35,7 +39,7 @@ async fn admin_monitoring_trace_request_returns_local_payload() {
|
||||
vec![sample_endpoint()],
|
||||
vec![sample_key()],
|
||||
));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_decision_trace_data_readers_for_tests(request_candidates, provider_catalog);
|
||||
let context = request_context(
|
||||
@@ -121,7 +125,7 @@ async fn admin_monitoring_trace_provider_stats_returns_local_payload() {
|
||||
None,
|
||||
),
|
||||
]));
|
||||
let state = AppState::new("http://127.0.0.1:9")
|
||||
let state = AppState::new()
|
||||
.expect("state should build")
|
||||
.with_request_candidate_data_reader_for_tests(request_candidates);
|
||||
let context = request_context(
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_monitoring_bad_request_response, admin_monitoring_not_found_response,
|
||||
parse_admin_monitoring_limit,
|
||||
};
|
||||
use crate::gateway::handlers::{query_param_value, unix_secs_to_rfc3339};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
fn admin_monitoring_trace_request_id_from_path(request_path: &str) -> Option<String> {
|
||||
let value = request_path
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{
|
||||
encrypt_catalog_secret_with_fallbacks, AdminOAuthProviderUpsertRequest,
|
||||
};
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::oauth_providers::{
|
||||
EncryptedSecretUpdate, UpsertOAuthProviderConfigRecord,
|
||||
};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use url::Url;
|
||||
|
||||
pub(crate) fn build_admin_oauth_supported_types_payload() -> Vec<serde_json::Value> {
|
||||
vec![json!({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{body::Body, response::Response};
|
||||
|
||||
#[path = "payment/postgres.rs"]
|
||||
mod payment_postgres;
|
||||
@@ -11,8 +12,16 @@ mod payments_routes;
|
||||
#[path = "payments/shared.rs"]
|
||||
mod payments_shared;
|
||||
|
||||
use payment_postgres::*;
|
||||
use payments_shared::*;
|
||||
use self::payments_shared::{
|
||||
admin_payment_operator_id, admin_payment_order_id_from_detail_path,
|
||||
admin_payment_order_id_from_suffix_path, build_admin_payment_callback_payload,
|
||||
build_admin_payment_callback_payload_from_record, build_admin_payment_order_not_found_response,
|
||||
build_admin_payment_order_payload, build_admin_payment_orders_page_response,
|
||||
build_admin_payments_backend_unavailable_response, build_admin_payments_bad_request_response,
|
||||
build_admin_payments_data_unavailable_response, normalize_admin_payment_currency,
|
||||
normalize_admin_payment_optional_string, normalize_admin_payment_positive_number,
|
||||
parse_admin_payments_limit, parse_admin_payments_offset, AdminPaymentOrderCreditRequest,
|
||||
};
|
||||
|
||||
pub(crate) async fn maybe_build_local_admin_payments_response(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
build_admin_payment_callback_payload, build_admin_payment_callback_payload_from_record,
|
||||
build_admin_payments_bad_request_response, parse_admin_payments_limit,
|
||||
parse_admin_payments_offset,
|
||||
};
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_payment_callbacks_response(
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
admin_payment_operator_id, admin_payment_order_id_from_detail_path,
|
||||
admin_payment_order_id_from_suffix_path, build_admin_payment_order_not_found_response,
|
||||
build_admin_payment_order_payload, build_admin_payment_orders_page_response,
|
||||
build_admin_payments_backend_unavailable_response, build_admin_payments_bad_request_response,
|
||||
normalize_admin_payment_currency, normalize_admin_payment_optional_string,
|
||||
normalize_admin_payment_positive_number, parse_admin_payments_limit,
|
||||
parse_admin_payments_offset, AdminPaymentOrderCreditRequest,
|
||||
};
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_payment_orders_response(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
build_admin_payments_data_unavailable_response,
|
||||
payments_callbacks::maybe_build_local_admin_payment_callbacks_response,
|
||||
payments_orders::maybe_build_local_admin_payment_orders_response,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{body::Body, http, response::Response};
|
||||
|
||||
pub(super) async fn maybe_build_local_admin_payments_response(
|
||||
state: &AppState,
|
||||
@@ -44,7 +50,7 @@ pub(super) async fn maybe_build_local_admin_payments_response(
|
||||
}
|
||||
|
||||
let route_kind = decision.route_kind.as_deref();
|
||||
if let Some(response) = payments_orders::maybe_build_local_admin_payment_orders_response(
|
||||
if let Some(response) = maybe_build_local_admin_payment_orders_response(
|
||||
state,
|
||||
request_context,
|
||||
request_body,
|
||||
@@ -54,15 +60,12 @@ pub(super) async fn maybe_build_local_admin_payments_response(
|
||||
{
|
||||
return Ok(Some(response));
|
||||
}
|
||||
if let Some(response) = payments_callbacks::maybe_build_local_admin_payment_callbacks_response(
|
||||
state,
|
||||
request_context,
|
||||
route_kind,
|
||||
)
|
||||
.await?
|
||||
if let Some(response) =
|
||||
maybe_build_local_admin_payment_callbacks_response(state, request_context, route_kind)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(response));
|
||||
}
|
||||
|
||||
Ok(Some(build_admin_payments_maintenance_response()))
|
||||
Ok(Some(build_admin_payments_data_unavailable_response()))
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{query_param_value, unix_secs_to_rfc3339};
|
||||
use crate::gateway::{GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use sqlx::Row;
|
||||
|
||||
const ADMIN_PAYMENTS_RUST_BACKEND_DETAIL: &str =
|
||||
"Admin payments routes require Rust maintenance backend";
|
||||
const ADMIN_PAYMENTS_DATA_UNAVAILABLE_DETAIL: &str = "Admin payments data unavailable";
|
||||
|
||||
#[derive(Debug, Default, serde::Deserialize)]
|
||||
pub(super) struct AdminPaymentOrderCreditRequest {
|
||||
@@ -18,10 +25,10 @@ pub(super) struct AdminPaymentOrderCreditRequest {
|
||||
pub(super) gateway_response: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
pub(super) fn build_admin_payments_maintenance_response() -> Response<Body> {
|
||||
pub(super) fn build_admin_payments_data_unavailable_response() -> Response<Body> {
|
||||
(
|
||||
http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({ "detail": ADMIN_PAYMENTS_RUST_BACKEND_DETAIL })),
|
||||
Json(json!({ "detail": ADMIN_PAYMENTS_DATA_UNAVAILABLE_DETAIL })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::query_param_value;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN_POOL_RUST_BACKEND_DETAIL: &str = "Admin pool routes require Rust maintenance backend";
|
||||
const ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL: &str =
|
||||
"Admin pool overview requires provider catalog reader";
|
||||
const ADMIN_POOL_PROVIDER_CATALOG_WRITER_UNAVAILABLE_DETAIL: &str =
|
||||
@@ -132,7 +139,7 @@ fn is_admin_pool_route(request_context: &GatewayPublicRequestContext) -> bool {
|
||||
pub(crate) async fn maybe_build_local_admin_pool_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,28 @@
|
||||
use super::*;
|
||||
use super::super::{clear_admin_provider_pool_cooldown, reset_admin_provider_pool_cost};
|
||||
use super::{
|
||||
admin_pool_provider_id_from_path, build_admin_pool_error_response,
|
||||
ADMIN_POOL_BANNED_KEY_CLEANUP_EMPTY_MESSAGE,
|
||||
ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
|
||||
ADMIN_POOL_PROVIDER_CATALOG_WRITER_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use super::{pool_payloads, pool_selection};
|
||||
use crate::gateway::handlers::encrypt_catalog_secret_with_fallbacks;
|
||||
use crate::gateway::{
|
||||
AppState, GatewayError, GatewayPublicRequestContext, LocalProviderDeleteTaskState,
|
||||
};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
|
||||
};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeSet;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Default, serde::Deserialize)]
|
||||
struct AdminPoolBatchActionRequest {
|
||||
@@ -166,7 +190,7 @@ async fn build_admin_pool_cleanup_banned_keys_response(
|
||||
async fn build_admin_pool_batch_import_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_pool_error_response(
|
||||
@@ -345,7 +369,7 @@ async fn build_admin_pool_batch_import_response(
|
||||
async fn build_admin_pool_batch_action_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_pool_error_response(
|
||||
@@ -529,7 +553,7 @@ async fn build_admin_pool_batch_delete_task_status_response(
|
||||
pub(super) async fn maybe_build_local_admin_pool_batch_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
match decision_route_kind(request_context) {
|
||||
Some("cleanup_banned_keys") if request_context.request_method == http::Method::POST => {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{
|
||||
unix_secs_to_rfc3339, AdminProviderPoolConfig, AdminProviderPoolRuntimeState,
|
||||
};
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) fn admin_pool_api_formats(key: &StoredProviderCatalogKey) -> Vec<String> {
|
||||
key.api_formats
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
use super::*;
|
||||
use super::super::{
|
||||
admin_provider_pool_config, read_admin_provider_pool_cooldown_count,
|
||||
read_admin_provider_pool_cooldown_key_ids, read_admin_provider_pool_runtime_state,
|
||||
};
|
||||
use super::{
|
||||
admin_pool_provider_id_from_path, build_admin_pool_error_response, parse_admin_pool_page,
|
||||
parse_admin_pool_page_size, parse_admin_pool_search, parse_admin_pool_status_filter,
|
||||
AdminPoolResolveSelectionRequest, ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use super::{pool_payloads, pool_selection};
|
||||
use crate::gateway::handlers::AdminProviderPoolRuntimeState;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use aether_data::repository::provider_catalog::ProviderCatalogKeyListQuery;
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
async fn build_admin_pool_overview_payload(
|
||||
state: &AppState,
|
||||
@@ -186,7 +206,7 @@ async fn build_admin_pool_list_keys_response(
|
||||
async fn build_admin_pool_resolve_selection_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_pool_error_response(
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::decrypt_catalog_secret_with_fallbacks;
|
||||
use crate::gateway::AppState;
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
|
||||
fn admin_pool_reason_indicates_ban(reason: &str) -> bool {
|
||||
let normalized = reason.trim().to_ascii_lowercase();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
pub(crate) use super::*;
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::Response;
|
||||
|
||||
#[path = "provider_models/assign_global.rs"]
|
||||
mod provider_models_assign_global;
|
||||
@@ -22,7 +24,7 @@ mod provider_models_update;
|
||||
pub(crate) async fn maybe_build_local_admin_provider_models_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
use super::*;
|
||||
use super::super::build_admin_batch_assign_global_models_payload;
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_assign_global_models_path, AdminBatchAssignGlobalModelsRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
use super::*;
|
||||
use super::super::build_admin_provider_available_source_models_payload;
|
||||
use crate::gateway::handlers::admin_provider_available_source_models_path;
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
_request_body: Option<&axum::body::Bytes>,
|
||||
_request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
use super::*;
|
||||
use super::super::{
|
||||
admin_provider_model_name_exists, build_admin_provider_model_create_record,
|
||||
build_admin_provider_model_response,
|
||||
};
|
||||
use crate::gateway::handlers::{admin_provider_models_batch_path, AdminProviderModelCreateRequest};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeSet;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
use super::*;
|
||||
use super::super::{build_admin_provider_model_create_record, build_admin_provider_model_response};
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_id_for_models_list, AdminProviderModelCreateRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::admin_provider_model_route_parts;
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
_request_body: Option<&axum::body::Bytes>,
|
||||
_request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
use super::*;
|
||||
use super::super::build_admin_provider_model_payload;
|
||||
use crate::gateway::handlers::admin_provider_model_route_parts;
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
_request_body: Option<&axum::body::Bytes>,
|
||||
_request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
use super::*;
|
||||
use super::super::build_admin_import_provider_models_payload;
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_import_models_path, AdminImportProviderModelsRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
use super::*;
|
||||
use super::super::build_admin_provider_models_payload;
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_id_for_models_list, query_param_optional_bool, query_param_value,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
_request_body: Option<&axum::body::Bytes>,
|
||||
_request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
use super::*;
|
||||
use super::super::{build_admin_provider_model_response, build_admin_provider_model_update_record};
|
||||
use crate::gateway::handlers::{admin_provider_model_route_parts, AdminProviderModelUpdateRequest};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn maybe_handle(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
decision: &GatewayControlDecision,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
if decision.route_family.as_deref() == Some("provider_models_manage")
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
pub(crate) use super::*;
|
||||
use super::provider_oauth_state::{
|
||||
build_admin_provider_oauth_backend_unavailable_response,
|
||||
build_admin_provider_oauth_supported_types_payload,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
|
||||
#[path = "dispatch/batch.rs"]
|
||||
mod dispatch_batch;
|
||||
@@ -18,7 +28,7 @@ mod dispatch_tasks;
|
||||
pub(crate) async fn maybe_build_local_admin_provider_oauth_response(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_refresh::{
|
||||
build_internal_control_error_response, build_provider_oauth_auth_config_from_token_payload,
|
||||
create_provider_oauth_catalog_key, find_duplicate_provider_oauth_key,
|
||||
provider_oauth_active_api_formats, provider_oauth_key_proxy_value,
|
||||
refresh_provider_oauth_account_state_after_update, update_existing_provider_oauth_catalog_key,
|
||||
};
|
||||
use super::super::provider_oauth_state::{
|
||||
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
|
||||
current_unix_secs, decode_jwt_claims, exchange_admin_provider_oauth_refresh_token,
|
||||
is_fixed_provider_type_for_provider_oauth, save_provider_oauth_batch_task_payload,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_oauth_batch_import_provider_id,
|
||||
admin_provider_oauth_batch_import_task_provider_id,
|
||||
ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{to_bytes, Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tracing::warn;
|
||||
use uuid::Uuid;
|
||||
|
||||
const PROVIDER_OAUTH_BATCH_TASK_MAX_ERROR_SAMPLES: usize = 20;
|
||||
|
||||
@@ -53,7 +81,7 @@ fn build_kiro_batch_import_key_name(
|
||||
}
|
||||
|
||||
fn parse_admin_provider_oauth_batch_import_request(
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<AdminProviderOAuthBatchImportRequest, Response<Body>> {
|
||||
let Some(request_body) = request_body else {
|
||||
return Err(build_internal_control_error_response(
|
||||
@@ -673,7 +701,7 @@ async fn execute_admin_provider_oauth_batch_import(
|
||||
json!({
|
||||
"index": index,
|
||||
"status": "error",
|
||||
"error": ADMIN_PROVIDER_OAUTH_RUST_BACKEND_DETAIL,
|
||||
"error": ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL,
|
||||
"replaced": false,
|
||||
})
|
||||
})
|
||||
@@ -903,7 +931,7 @@ fn build_admin_provider_oauth_batch_task_state(
|
||||
pub(super) async fn handle_admin_provider_oauth_batch_import(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_provider_oauth_backend_unavailable_response());
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_quota::refresh_codex_provider_quota_locally;
|
||||
use super::super::provider_oauth_refresh::{
|
||||
build_internal_control_error_response, build_provider_oauth_auth_config_from_token_payload,
|
||||
create_provider_oauth_catalog_key, find_duplicate_provider_oauth_key,
|
||||
provider_oauth_active_api_formats, provider_oauth_key_proxy_value,
|
||||
refresh_provider_oauth_account_state_after_update, update_existing_provider_oauth_catalog_key,
|
||||
};
|
||||
use super::super::provider_oauth_state::{
|
||||
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
|
||||
consume_provider_oauth_state, enrich_admin_provider_oauth_auth_config,
|
||||
exchange_admin_provider_oauth_code, is_fixed_provider_type_for_provider_oauth,
|
||||
json_non_empty_string, json_u64_value, parse_provider_oauth_callback_params,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_oauth_complete_key_id, admin_provider_oauth_complete_provider_id,
|
||||
encrypt_catalog_secret_with_fallbacks,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn handle_admin_provider_oauth_complete_key(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some(key_id) = admin_provider_oauth_complete_key_id(&request_context.request_path) else {
|
||||
return Ok(build_internal_control_error_response(
|
||||
@@ -283,7 +308,7 @@ pub(super) async fn handle_admin_provider_oauth_complete_key(
|
||||
pub(super) async fn handle_admin_provider_oauth_complete_provider(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some(provider_id) =
|
||||
admin_provider_oauth_complete_provider_id(&request_context.request_path)
|
||||
|
||||
@@ -1,4 +1,30 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_refresh::{
|
||||
build_internal_control_error_response, build_provider_oauth_auth_config_from_token_payload,
|
||||
create_provider_oauth_catalog_key, find_duplicate_provider_oauth_key,
|
||||
provider_oauth_active_api_formats, provider_oauth_key_proxy_value,
|
||||
refresh_provider_oauth_account_state_after_update, update_existing_provider_oauth_catalog_key,
|
||||
};
|
||||
use super::super::provider_oauth_state::{
|
||||
build_admin_provider_oauth_backend_unavailable_response, build_kiro_device_key_name,
|
||||
current_unix_secs, decode_jwt_claims, default_kiro_device_region,
|
||||
default_kiro_device_start_url, generate_provider_oauth_nonce, json_non_empty_string,
|
||||
json_u64_value, normalize_kiro_device_region, poll_admin_kiro_device_token,
|
||||
read_provider_oauth_device_session, register_admin_kiro_device_oidc_client,
|
||||
save_provider_oauth_device_session, start_admin_kiro_device_authorization,
|
||||
StoredAdminProviderOAuthDeviceSession, KIRO_DEVICE_AUTH_SESSION_TTL_BUFFER_SECS,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_oauth_device_authorize_provider_id, admin_provider_oauth_device_poll_provider_id,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::{Body, Bytes},
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct AdminProviderOAuthDeviceAuthorizePayload {
|
||||
@@ -17,7 +43,7 @@ struct AdminProviderOAuthDevicePollPayload {
|
||||
pub(super) async fn handle_admin_provider_oauth_device_authorize(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_provider_oauth_backend_unavailable_response());
|
||||
@@ -194,7 +220,7 @@ pub(super) async fn handle_admin_provider_oauth_device_authorize(
|
||||
pub(super) async fn handle_admin_provider_oauth_device_poll(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
if !state.has_provider_catalog_data_reader() {
|
||||
return Ok(build_admin_provider_oauth_backend_unavailable_response());
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_refresh::{
|
||||
build_internal_control_error_response, build_provider_oauth_auth_config_from_token_payload,
|
||||
create_provider_oauth_catalog_key, find_duplicate_provider_oauth_key,
|
||||
provider_oauth_active_api_formats, provider_oauth_key_proxy_value,
|
||||
refresh_provider_oauth_account_state_after_update, update_existing_provider_oauth_catalog_key,
|
||||
};
|
||||
use super::super::provider_oauth_state::{
|
||||
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
|
||||
exchange_admin_provider_oauth_refresh_token, is_fixed_provider_type_for_provider_oauth,
|
||||
};
|
||||
use crate::gateway::handlers::admin_provider_oauth_import_provider_id;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn handle_admin_provider_oauth_import_refresh_token(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_quota::persist_provider_quota_refresh_state;
|
||||
use super::super::provider_oauth_refresh::{
|
||||
build_internal_control_error_response, merge_provider_oauth_refresh_failure_reason,
|
||||
normalize_provider_oauth_refresh_error_message, provider_oauth_runtime_endpoint_for_provider,
|
||||
refresh_provider_oauth_account_state_after_update,
|
||||
};
|
||||
use super::super::provider_oauth_state::is_fixed_provider_type_for_provider_oauth;
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_oauth_refresh_key_id, decrypt_catalog_secret_with_fallbacks,
|
||||
OAUTH_ACCOUNT_BLOCK_PREFIX, OAUTH_REFRESH_FAILED_PREFIX,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub(super) async fn handle_admin_provider_oauth_refresh_key(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_refresh::build_internal_control_error_response;
|
||||
use super::super::provider_oauth_state::{
|
||||
admin_provider_oauth_template, build_provider_oauth_start_response,
|
||||
generate_provider_oauth_pkce_verifier, is_fixed_provider_type_for_provider_oauth,
|
||||
provider_oauth_pkce_s256, save_provider_oauth_state,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
admin_provider_oauth_start_key_id, admin_provider_oauth_start_provider_id,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
|
||||
pub(super) async fn handle_admin_provider_oauth_start_key(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
use super::*;
|
||||
use super::super::provider_oauth_refresh::build_internal_control_error_response;
|
||||
use super::super::provider_oauth_state::read_provider_oauth_batch_task_payload;
|
||||
use crate::gateway::handlers::admin_provider_oauth_batch_import_task_path;
|
||||
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
|
||||
pub(super) async fn handle_admin_provider_oauth_batch_import_task_status(
|
||||
state: &AppState,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
pub(crate) use super::*;
|
||||
|
||||
#[path = "quota/antigravity.rs"]
|
||||
mod quota_antigravity;
|
||||
#[path = "quota/codex.rs"]
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
coerce_json_f64, coerce_json_string, execute_provider_quota_plan,
|
||||
extract_execution_error_message, persist_provider_quota_refresh_state,
|
||||
quota_refresh_success_invalid_state,
|
||||
};
|
||||
use crate::gateway::handlers::ANTIGRAVITY_FETCH_AVAILABLE_MODELS_PATH;
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult, ExecutionTimeouts, RequestBody};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn parse_antigravity_usage_response(
|
||||
value: &serde_json::Value,
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
coerce_json_bool, coerce_json_f64, coerce_json_string, coerce_json_u64,
|
||||
execute_provider_quota_plan, extract_execution_error_message, normalize_string_id_list,
|
||||
persist_provider_quota_refresh_state, provider_auto_remove_banned_keys,
|
||||
quota_refresh_success_invalid_state, should_auto_remove_structured_reason,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
CODEX_WHAM_USAGE_URL, OAUTH_ACCOUNT_BLOCK_PREFIX, OAUTH_EXPIRED_PREFIX,
|
||||
OAUTH_REQUEST_FAILED_PREFIX,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult, ExecutionTimeouts, RequestBody};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn normalize_codex_plan_type(value: Option<&str>) -> Option<String> {
|
||||
value
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
coerce_json_f64, execute_provider_quota_plan, extract_execution_error_message,
|
||||
persist_provider_quota_refresh_state, quota_refresh_success_invalid_state,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
encrypt_catalog_secret_with_fallbacks, KIRO_USAGE_LIMITS_PATH, KIRO_USAGE_SDK_VERSION,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult, ExecutionTimeouts, RequestBody};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use url::form_urlencoded;
|
||||
use uuid::Uuid;
|
||||
|
||||
fn compute_kiro_total_usage_limit(breakdown: &serde_json::Value) -> f64 {
|
||||
let mut total = breakdown
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
use super::*;
|
||||
use crate::gateway::handlers::{OAUTH_ACCOUNT_BLOCK_PREFIX, OAUTH_REFRESH_FAILED_PREFIX};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult};
|
||||
use aether_data::repository::provider_catalog::StoredProviderCatalogKey;
|
||||
use std::collections::BTreeSet;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tracing::warn;
|
||||
|
||||
pub(super) fn provider_auto_remove_banned_keys(config: Option<&serde_json::Value>) -> bool {
|
||||
config
|
||||
|
||||
@@ -1,4 +1,29 @@
|
||||
use super::*;
|
||||
use super::provider_oauth_quota::{
|
||||
persist_provider_quota_refresh_state, refresh_antigravity_provider_quota_locally,
|
||||
refresh_codex_provider_quota_locally, refresh_kiro_provider_quota_locally,
|
||||
};
|
||||
use super::provider_oauth_state::{
|
||||
enrich_admin_provider_oauth_auth_config, json_non_empty_string, json_u64_value,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
decrypt_catalog_secret_with_fallbacks, encrypt_catalog_secret_with_fallbacks,
|
||||
parse_catalog_auth_config_json, OAUTH_ACCOUNT_BLOCK_PREFIX, OAUTH_EXPIRED_PREFIX,
|
||||
OAUTH_REFRESH_FAILED_PREFIX, OAUTH_REQUEST_FAILED_PREFIX,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayError};
|
||||
use aether_data::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeSet;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(crate) fn build_internal_control_error_response(
|
||||
status: http::StatusCode,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user