mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: api: Map config-validation errors to 400/409 (not 500)
Map VmError::ConfigValidation in api_error_status_code() to client-error codes: 409 Conflict for a duplicate identifier or path, 400 Bad Request otherwise. Update the OpenAPI responses for the vm.add-* and vm.restore endpoints, fix the InvalidIdentifier message, and add unit tests. Signed-off-by: Stepan Rabotkin <epicstyt@gmail.com> Assisted-by: Claude:Opus-4.8
This commit is contained in:
committed by
Rob Bradford
parent
bff57a8471
commit
dcea656a72
@@ -33,6 +33,7 @@ use crate::api::{
|
|||||||
VmPause, VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeDisk,
|
VmPause, VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeDisk,
|
||||||
VmResizeZone, VmRestore, VmResume, VmSendMigration, VmShutdown, VmSnapshot,
|
VmResizeZone, VmRestore, VmResume, VmSendMigration, VmShutdown, VmSnapshot,
|
||||||
};
|
};
|
||||||
|
use crate::config::ValidationError;
|
||||||
use crate::device_manager::DeviceManagerError;
|
use crate::device_manager::DeviceManagerError;
|
||||||
use crate::landlock::Landlock;
|
use crate::landlock::Landlock;
|
||||||
use crate::seccomp_filters::{Thread, get_seccomp_filter};
|
use crate::seccomp_filters::{Thread, get_seccomp_filter};
|
||||||
@@ -94,6 +95,12 @@ fn api_error_status_code(error: &ApiError) -> StatusCode {
|
|||||||
| VmError::NoDeviceToRemove(_)
|
| VmError::NoDeviceToRemove(_)
|
||||||
| VmError::DeviceManager(DeviceManagerError::UnknownDeviceId(_)),
|
| VmError::DeviceManager(DeviceManagerError::UnknownDeviceId(_)),
|
||||||
) => StatusCode::NotFound,
|
) => StatusCode::NotFound,
|
||||||
|
Some(VmError::ConfigValidation(e)) => match e {
|
||||||
|
ValidationError::IdentifierNotUnique(_) | ValidationError::DuplicateDevicePath(_) => {
|
||||||
|
StatusCode::Conflict
|
||||||
|
}
|
||||||
|
_ => StatusCode::BadRequest,
|
||||||
|
},
|
||||||
_ => StatusCode::InternalServerError,
|
_ => StatusCode::InternalServerError,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,6 +539,50 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_duplicate_identifier_or_path_maps_to_conflict() {
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmAddDisk(VmError::ConfigValidation(
|
||||||
|
ValidationError::IdentifierNotUnique("disk0".to_string())
|
||||||
|
))),
|
||||||
|
StatusCode::Conflict
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmAddVdpa(VmError::ConfigValidation(
|
||||||
|
ValidationError::IdentifierNotUnique("vdpa0".to_string())
|
||||||
|
))),
|
||||||
|
StatusCode::Conflict
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmAddDevice(VmError::ConfigValidation(
|
||||||
|
ValidationError::DuplicateDevicePath("/dev/foo".to_string())
|
||||||
|
))),
|
||||||
|
StatusCode::Conflict
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmRestore(VmError::ConfigValidation(
|
||||||
|
ValidationError::IdentifierNotUnique("net0".to_string())
|
||||||
|
))),
|
||||||
|
StatusCode::Conflict
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_config_maps_to_bad_request() {
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmAddDisk(VmError::ConfigValidation(
|
||||||
|
ValidationError::InvalidIdentifier("__disk0".to_string())
|
||||||
|
))),
|
||||||
|
StatusCode::BadRequest
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
api_error_status_code(&ApiError::VmAddDisk(VmError::ConfigValidation(
|
||||||
|
ValidationError::BalloonLargerThanRam(1024, 512)
|
||||||
|
))),
|
||||||
|
StatusCode::BadRequest
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_other_errors_map_to_internal_server_error() {
|
fn test_other_errors_map_to_internal_server_error() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -220,8 +220,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier or path already exists.
|
||||||
|
|
||||||
/vm.remove-device:
|
/vm.remove-device:
|
||||||
put:
|
put:
|
||||||
@@ -258,8 +262,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new disk was successfully (cold) added to the VM instance.
|
description: The new disk was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new disk could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new disk could not be added because the VM is not created.
|
description: The new disk could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new disk could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new disk could not be added to the VM instance.
|
description: The new disk could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -282,8 +290,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added because the VM is not created.
|
description: The new device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -306,8 +318,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added because the VM is not created.
|
description: The new device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -330,8 +346,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added because the VM is not created.
|
description: The new device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -354,8 +374,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added because the VM is not created.
|
description: The new device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -378,8 +402,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new device could not be added because the VM is not created.
|
description: The new device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -402,8 +430,12 @@ paths:
|
|||||||
$ref: "#/components/schemas/PciDeviceInfo"
|
$ref: "#/components/schemas/PciDeviceInfo"
|
||||||
204:
|
204:
|
||||||
description: The new vDPA device was successfully (cold) added to the VM instance.
|
description: The new vDPA device was successfully (cold) added to the VM instance.
|
||||||
|
400:
|
||||||
|
description: The new vDPA device could not be added because the configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The new vDPA device could not be added because the VM is not created.
|
description: The new vDPA device could not be added because the VM is not created.
|
||||||
|
409:
|
||||||
|
description: The new vDPA device could not be added because a device with the same identifier already exists.
|
||||||
500:
|
500:
|
||||||
description: The new vDPA device could not be added to the VM instance.
|
description: The new vDPA device could not be added to the VM instance.
|
||||||
|
|
||||||
@@ -425,6 +457,10 @@ paths:
|
|||||||
description: The new device was successfully added to the VM instance.
|
description: The new device was successfully added to the VM instance.
|
||||||
"204":
|
"204":
|
||||||
description: The new device was successfully (cold) added to the VM instance.
|
description: The new device was successfully (cold) added to the VM instance.
|
||||||
|
"400":
|
||||||
|
description: The new device could not be added because the configuration is not valid.
|
||||||
|
"409":
|
||||||
|
description: The new device could not be added because a device with the same identifier already exists.
|
||||||
"404":
|
"404":
|
||||||
description: The new device could not be added to the VM instance.
|
description: The new device could not be added to the VM instance.
|
||||||
summary: Add a new userspace device to the VM
|
summary: Add a new userspace device to the VM
|
||||||
@@ -485,8 +521,12 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
204:
|
204:
|
||||||
description: The VM instance was successfully restored.
|
description: The VM instance was successfully restored.
|
||||||
|
400:
|
||||||
|
description: The VM could not be restored because the restore configuration is not valid.
|
||||||
404:
|
404:
|
||||||
description: The VM instance could not be restored because it is already created.
|
description: The VM instance could not be restored because it is already created.
|
||||||
|
409:
|
||||||
|
description: The VM could not be restored because a device with the same identifier or path already exists.
|
||||||
|
|
||||||
/vm.receive-migration:
|
/vm.receive-migration:
|
||||||
put:
|
put:
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ pub enum ValidationError {
|
|||||||
#[error("Identifier {0} is not unique")]
|
#[error("Identifier {0} is not unique")]
|
||||||
IdentifierNotUnique(String),
|
IdentifierNotUnique(String),
|
||||||
/// Invalid identifier
|
/// Invalid identifier
|
||||||
#[error("Identifier {0} is not invalid")]
|
#[error("Identifier {0} is not valid")]
|
||||||
InvalidIdentifier(String),
|
InvalidIdentifier(String),
|
||||||
/// Placing the device behind a virtual IOMMU is not supported
|
/// Placing the device behind a virtual IOMMU is not supported
|
||||||
#[error("Device does not support being placed behind IOMMU")]
|
#[error("Device does not support being placed behind IOMMU")]
|
||||||
|
|||||||
Reference in New Issue
Block a user