mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-23 19:06:30 +00:00
Preserve the top API service job nonce (#7879)
fix(connect): preserve top api job nonce
This commit is contained in:
@@ -37,7 +37,7 @@ use super::{
|
||||
ProfileProvenance, TOP_API_CAPABILITY, TOP_CLASSIFICATION, TOP_LOCKS_CAPABILITY, TOP_SCHEMA_VERSION, TopApiOperation,
|
||||
TopCaptureLimits, TopCaptureRequest, TopCaptureScope, TopOutcome, capture_cpu_profile, capture_top_api, capture_top_locks,
|
||||
encode_signed_profile_export, measure_drive, measure_network, runtime_network_peer_aliases, sign_drive_export,
|
||||
sign_network_export, sign_top_export,
|
||||
sign_network_export, sign_top_export, sign_top_export_with_nonce,
|
||||
};
|
||||
use crate::connect::DeviceIdentity;
|
||||
|
||||
@@ -505,7 +505,7 @@ pub async fn execute_diagnostic_job(
|
||||
DiagnosticJobKind::PerformanceNetwork => {
|
||||
execute_performance_network_job(envelope, nonce, identity, provenance, cancel).await
|
||||
}
|
||||
DiagnosticJobKind::TopApi => execute_top_api_job(envelope, identity, provenance, cancel).await,
|
||||
DiagnosticJobKind::TopApi => execute_top_api_job(envelope, nonce, identity, provenance, cancel).await,
|
||||
DiagnosticJobKind::TopLocks => execute_top_locks_job(envelope, identity, provenance, cancel).await,
|
||||
}
|
||||
}
|
||||
@@ -765,6 +765,7 @@ async fn execute_profile_cpu_job(
|
||||
|
||||
async fn execute_top_api_job(
|
||||
envelope: DiagnosticJobEnvelope,
|
||||
nonce: [u8; 32],
|
||||
identity: &DeviceIdentity,
|
||||
provenance: ProfileProvenance,
|
||||
cancel: &CancellationToken,
|
||||
@@ -814,7 +815,7 @@ async fn execute_top_api_job(
|
||||
artifact_bytes: None,
|
||||
});
|
||||
}
|
||||
let export = sign_top_export(&request, &result, identity, cancel).map_err(top_export_failure)?;
|
||||
let export = sign_top_export_with_nonce(&request, &result, identity, cancel, nonce).map_err(top_export_failure)?;
|
||||
if export.archive_bytes.len() > usize::try_from(envelope.limits.max_output_bytes).unwrap_or(usize::MAX) {
|
||||
return Err(DiagnosticJobError::LimitExceeded);
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@ pub use schedule::{
|
||||
DiagnosticCollectionPolicy, DiagnosticReceipt, DiagnosticScheduleError, DiagnosticScheduleRuntime, DiagnosticScheduleStatus,
|
||||
ReceiptOutcome, run_local_environment_once, spawn_environment_schedule,
|
||||
};
|
||||
pub(crate) use top_api::sign_top_export_with_nonce;
|
||||
pub use top_api::{
|
||||
LocalTopConsent, MAX_TOP_DURATION, MAX_TOP_EXPORT_VALIDITY, SavedTopExport, SignedTopExport, TOP_API_CAPABILITY,
|
||||
TOP_CLASSIFICATION, TOP_SCHEMA_VERSION, TopApiData, TopApiOperation, TopCaptureError, TopCaptureLimits, TopCaptureRequest,
|
||||
|
||||
@@ -454,6 +454,26 @@ pub fn sign_top_export<T: Serialize>(
|
||||
result: &TopResult<T>,
|
||||
identity: &DeviceIdentity,
|
||||
cancel: &CancellationToken,
|
||||
) -> Result<SignedTopExport, TopCaptureError> {
|
||||
sign_top_export_inner(request, result, identity, cancel, None)
|
||||
}
|
||||
|
||||
pub(crate) fn sign_top_export_with_nonce<T: Serialize>(
|
||||
request: &TopCaptureRequest,
|
||||
result: &TopResult<T>,
|
||||
identity: &DeviceIdentity,
|
||||
cancel: &CancellationToken,
|
||||
nonce: [u8; 32],
|
||||
) -> Result<SignedTopExport, TopCaptureError> {
|
||||
sign_top_export_inner(request, result, identity, cancel, Some(nonce))
|
||||
}
|
||||
|
||||
fn sign_top_export_inner<T: Serialize>(
|
||||
request: &TopCaptureRequest,
|
||||
result: &TopResult<T>,
|
||||
identity: &DeviceIdentity,
|
||||
cancel: &CancellationToken,
|
||||
supplied_nonce: Option<[u8; 32]>,
|
||||
) -> Result<SignedTopExport, TopCaptureError> {
|
||||
if !matches!(result.tool_id, "top.api" | "top.disk" | "top.locks" | "top.net" | "top.rpc") {
|
||||
return Err(TopCaptureError::Result);
|
||||
@@ -495,8 +515,13 @@ pub fn sign_top_export<T: Serialize>(
|
||||
return Err(TopCaptureError::Expired);
|
||||
}
|
||||
|
||||
let mut nonce = [0u8; 32];
|
||||
SysRng.try_fill_bytes(&mut nonce).map_err(|_| TopCaptureError::Random)?;
|
||||
let nonce = if let Some(nonce) = supplied_nonce {
|
||||
nonce
|
||||
} else {
|
||||
let mut nonce = [0u8; 32];
|
||||
SysRng.try_fill_bytes(&mut nonce).map_err(|_| TopCaptureError::Random)?;
|
||||
nonce
|
||||
};
|
||||
let device_key_id = hex_lower(&Sha256::digest(identity.public_key_der()));
|
||||
let envelope = DiagnosticEnvelope {
|
||||
format_version: ENVELOPE_FORMAT,
|
||||
@@ -1046,7 +1071,7 @@ mod tests {
|
||||
|
||||
let result = capture.await.expect("capture task").expect("top.api result");
|
||||
assert_eq!(result.outcome, TopOutcome::Succeeded);
|
||||
let data = result.data.expect("successful capture data");
|
||||
let data = result.data.as_ref().expect("successful capture data");
|
||||
assert_eq!(data.operation, TopApiOperation::GetObject);
|
||||
assert_eq!(data.request_count, 2);
|
||||
assert_eq!(data.error_count, 1);
|
||||
@@ -1062,6 +1087,11 @@ mod tests {
|
||||
"windowMillis"
|
||||
]
|
||||
);
|
||||
let nonce = [7_u8; 32];
|
||||
let export = sign_top_export_with_nonce(&request, &result, &DeviceIdentity::generate(), &CancellationToken::new(), nonce)
|
||||
.expect("signed top.api export");
|
||||
let envelope: serde_json::Value = serde_json::from_slice(&export.envelope_json).expect("diagnostic envelope");
|
||||
assert_eq!(envelope["nonce"], URL_SAFE_NO_PAD.encode_to_string(nonce));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user