| 407 | |
| 408 | #[allow(clippy::result_large_err)] |
| 409 | fn sandbox_owner_reference(pod: &Pod) -> Result<SandboxOwnerReference, Status> { |
| 410 | let owner_refs = pod.metadata.owner_references.as_deref().unwrap_or_default(); |
| 411 | let mut sandbox_refs = owner_refs |
| 412 | .iter() |
| 413 | .filter(|owner| is_supported_sandbox_owner_reference(owner)); |
| 414 | let Some(owner) = sandbox_refs.next() else { |
| 415 | let unsupported_sandbox_api_versions = owner_refs |
| 416 | .iter() |
| 417 | .filter(|owner| owner.kind == SANDBOX_KIND) |
| 418 | .map(|owner| owner.api_version.as_str()) |
| 419 | .collect::<Vec<_>>(); |
| 420 | if !unsupported_sandbox_api_versions.is_empty() { |
| 421 | warn!( |
| 422 | api_versions = ?unsupported_sandbox_api_versions, |
| 423 | supported_api_versions = ?[ |
| 424 | SANDBOX_API_VERSION_FULL_V1BETA1, |
| 425 | SANDBOX_API_VERSION_FULL_V1ALPHA1, |
| 426 | ], |
| 427 | "pod Sandbox ownerReference uses unsupported apiVersion" |
| 428 | ); |
| 429 | } |
| 430 | return Err(Status::permission_denied( |
| 431 | "pod is not controlled by an OpenShell Sandbox", |
| 432 | )); |
| 433 | }; |
| 434 | if sandbox_refs.next().is_some() { |
| 435 | return Err(Status::permission_denied( |
| 436 | "pod has multiple OpenShell Sandbox owners", |
| 437 | )); |
| 438 | } |
| 439 | if owner.controller != Some(true) { |
| 440 | return Err(Status::permission_denied( |
| 441 | "pod Sandbox ownerReference is not controlling", |
| 442 | )); |
| 443 | } |
| 444 | if owner.name.is_empty() || owner.uid.is_empty() { |
| 445 | return Err(Status::permission_denied( |
| 446 | "pod Sandbox ownerReference is incomplete", |
| 447 | )); |
| 448 | } |
| 449 | Ok(SandboxOwnerReference { |
| 450 | api_version: owner.api_version.clone(), |
| 451 | name: owner.name.clone(), |
| 452 | uid: owner.uid.clone(), |
| 453 | }) |
| 454 | } |
| 455 | |
| 456 | fn is_supported_sandbox_owner_reference( |
| 457 | owner: &k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference, |