feat: 初步增加 Windows 支持

This commit is contained in:
mofeng-git
2026-05-18 22:43:28 +08:00
parent 0b9d94f53f
commit 935fa823f2
163 changed files with 11419 additions and 7581 deletions

View File

@@ -62,10 +62,8 @@ pub async fn redfish_auth_middleware(
}
fn is_redfish_public_endpoint(path: &str, method: &Method) -> bool {
matches!(
path,
"/" | "/v1" | "/v1/" | "/v1/odata"
) || path.starts_with("/v1/$metadata")
matches!(path, "/" | "/v1" | "/v1/" | "/v1/odata")
|| path.starts_with("/v1/$metadata")
|| (path == "/v1/SessionService/Sessions" && *method == Method::POST)
}

View File

@@ -8,29 +8,20 @@ use axum::{
use std::sync::Arc;
use super::{empty_collection, resource_not_found};
use super::super::schema::*;
use super::{empty_collection, resource_not_found};
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
Router::new()
.route("/v1/AccountService", get(account_service))
.route(
"/v1/AccountService/Accounts",
get(account_list),
)
.route("/v1/AccountService/Accounts", get(account_list))
.route(
"/v1/AccountService/Accounts/{account_id}",
get(account_detail),
)
.route(
"/v1/AccountService/Roles",
get(roles_stub),
)
.route(
"/v1/AccountService/Roles/{role_id}",
get(role_detail_stub),
)
.route("/v1/AccountService/Roles", get(roles_stub))
.route("/v1/AccountService/Roles/{role_id}", get(role_detail_stub))
.with_state(state)
}
@@ -77,7 +68,10 @@ async fn account_list(State(state): State<Arc<AppState>>) -> Response {
"/redfish/v1/$metadata#ManagerAccountCollection.ManagerAccountCollection",
"Accounts Collection",
"Collection of Accounts",
vec![odata_ref(&format!("/redfish/v1/AccountService/Accounts/{}", user.id))],
vec![odata_ref(&format!(
"/redfish/v1/AccountService/Accounts/{}",
user.id
))],
))
.into_response()
}

View File

@@ -7,8 +7,8 @@ use axum::{
use std::sync::Arc;
use super::{empty_collection, get_power_state, validate_id, RESOURCE_ID};
use super::super::schema::*;
use super::{empty_collection, get_power_state, validate_id, RESOURCE_ID};
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
@@ -64,9 +64,7 @@ async fn chassis_detail(
.into_response()
}
async fn chassis_power(
Path(chassis_id): Path<String>,
) -> Response {
async fn chassis_power(Path(chassis_id): Path<String>) -> Response {
if let Some(resp) = validate_id(&chassis_id) {
return resp;
}

View File

@@ -48,8 +48,7 @@ async fn event_service() -> Json<EventService> {
server_sent_event_uri: Some("/redfish/v1/EventService/SSE".to_string()),
actions: EventServiceActions {
submit_test_event: ActionTarget {
target: "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"
.to_string(),
target: "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent".to_string(),
},
},
})

View File

@@ -7,8 +7,8 @@ use axum::{
use std::sync::Arc;
use super::{empty_collection, validate_id, RESOURCE_ID};
use super::super::schema::*;
use super::{empty_collection, validate_id, RESOURCE_ID};
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
@@ -86,7 +86,10 @@ async fn manager_detail(
manager_for_servers: vec![odata_ref(&format!("/redfish/v1/Systems/{}", RESOURCE_ID))],
manager_for_chassis: vec![odata_ref(&format!("/redfish/v1/Chassis/{}", RESOURCE_ID))],
},
network_protocol: odata_ref(&format!("/redfish/v1/Managers/{}/NetworkProtocol", manager_id)),
network_protocol: odata_ref(&format!(
"/redfish/v1/Managers/{}/NetworkProtocol",
manager_id
)),
})
.into_response()
}

View File

@@ -4,6 +4,7 @@ mod event;
mod managers;
mod session;
mod systems;
#[cfg(unix)]
mod virtual_media;
use axum::{
@@ -191,7 +192,6 @@ pub fn create_redfish_router(state: Arc<AppState>) -> Router {
.merge(systems::router(state.clone()))
.merge(chassis::router(state.clone()))
.merge(managers::router(state.clone()))
.merge(virtual_media::router(state.clone()))
.merge(session::router(state.clone()))
.merge(account::router(state.clone()))
.merge(event::router(state.clone()))
@@ -200,6 +200,9 @@ pub fn create_redfish_router(state: Arc<AppState>) -> Router {
redfish_auth_middleware,
));
#[cfg(unix)]
let redfish_routes = redfish_routes.merge(virtual_media::router(state.clone()));
Router::new()
.route("/redfish", get(service_root_redirect))
.nest("/redfish/", redfish_routes)

View File

@@ -9,8 +9,8 @@ use tracing::info;
use std::sync::Arc;
use super::empty_collection;
use super::super::schema::*;
use super::empty_collection;
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
@@ -56,7 +56,10 @@ async fn session_list(State(state): State<Arc<AppState>>) -> Response {
let mut members = Vec::new();
for id in &session_ids {
if state.sessions.get(id).await.ok().flatten().is_some() {
members.push(odata_ref(&format!("/redfish/v1/SessionService/Sessions/{}", id)));
members.push(odata_ref(&format!(
"/redfish/v1/SessionService/Sessions/{}",
id
)));
}
}

View File

@@ -8,8 +8,8 @@ use axum::{
use std::sync::Arc;
use tracing::info;
use super::{get_power_state, validate_id, service_unavailable, empty_collection, RESOURCE_ID};
use super::super::schema::*;
use super::{empty_collection, get_power_state, service_unavailable, validate_id, RESOURCE_ID};
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
@@ -208,13 +208,14 @@ async fn system_reset(
}
}
async fn system_set_default_boot_order(
Path(system_id): Path<String>,
) -> Response {
async fn system_set_default_boot_order(Path(system_id): Path<String>) -> Response {
if let Some(resp) = validate_id(&system_id) {
return resp;
}
info!("Redfish: SetDefaultBootOrder for system {} (accepted, no-op)", system_id);
info!(
"Redfish: SetDefaultBootOrder for system {} (accepted, no-op)",
system_id
);
StatusCode::NO_CONTENT.into_response()
}

View File

@@ -9,8 +9,8 @@ use tracing::{info, warn};
use std::sync::Arc;
use super::{empty_collection, validate_id, service_unavailable, resource_not_found, RESOURCE_ID};
use super::super::schema::*;
use super::{empty_collection, resource_not_found, service_unavailable, validate_id, RESOURCE_ID};
use crate::state::AppState;
pub(crate) fn router(state: Arc<AppState>) -> Router<Arc<AppState>> {
@@ -95,7 +95,10 @@ async fn virtual_media_detail(
Json(VirtualMedia {
odata_type: "#VirtualMedia.v1_6_2.VirtualMedia".to_string(),
odata_id: format!("/redfish/v1/Managers/{}/VirtualMedia/{}", manager_id, media_id),
odata_id: format!(
"/redfish/v1/Managers/{}/VirtualMedia/{}",
manager_id, media_id
),
odata_context: "/redfish/v1/$metadata#VirtualMedia.VirtualMedia".to_string(),
id: media_id.clone(),
name: "Virtual Media 1".to_string(),
@@ -153,7 +156,9 @@ async fn virtual_media_insert(
if msd.state().await.connected {
return (
StatusCode::CONFLICT,
Json(RedfishError::general_error("Virtual media already inserted")),
Json(RedfishError::general_error(
"Virtual media already inserted",
)),
)
.into_response();
}

View File

@@ -527,7 +527,10 @@ pub struct RedfishError {
pub struct RedfishErrorBody {
pub code: String,
pub message: String,
#[serde(rename = "@Message.ExtendedInfo", skip_serializing_if = "Vec::is_empty")]
#[serde(
rename = "@Message.ExtendedInfo",
skip_serializing_if = "Vec::is_empty"
)]
pub extended_info: Vec<RedfishExtendedInfo>,
}