diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 50261314..cfc8b744 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ concurrency: env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTIONS_LINTS_TOOLCHAIN: 1.85.0 + ACTIONS_LINTS_TOOLCHAIN: 1.88.0 jobs: linting: diff --git a/Cargo.toml b/Cargo.toml index 87d9752a..8823fb0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ resolver = "3" [workspace.package] edition = "2024" -rust-version = "1.85" +rust-version = "1.88" [workspace.dependencies] anyhow = "1.0.100" diff --git a/Containerfile b/Containerfile index a2d168bd..2aa7d88d 100644 --- a/Containerfile +++ b/Containerfile @@ -5,7 +5,7 @@ ARG build_type # Dependency build stage -FROM ghcr.io/trusted-execution-clusters/buildroot AS builder +FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder ARG build_type WORKDIR /build @@ -31,6 +31,6 @@ COPY operator/src operator/src RUN cargo build -p operator $(if [ "$build_type" = release ]; then echo --release; fi) # Distribution stage -FROM quay.io/fedora/fedora:42 +FROM quay.io/fedora/fedora:43 ARG build_type COPY --from=builder "/build/target/$build_type/operator" /usr/bin diff --git a/attestation-key-register/Containerfile b/attestation-key-register/Containerfile index a287db7a..de0677a3 100644 --- a/attestation-key-register/Containerfile +++ b/attestation-key-register/Containerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: CC0-1.0 ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot AS builder +FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder ARG build_type WORKDIR /build @@ -26,7 +26,7 @@ RUN sed -i 's/members =.*/members = ["lib", "attestation-key-register"]/' Cargo. COPY attestation-key-register/src attestation-key-register/src RUN cargo build -p attestation-key-register $(if [ "$build_type" = release ]; then echo --release; fi) -FROM quay.io/fedora/fedora:42 +FROM quay.io/fedora/fedora:43 ARG build_type COPY --from=builder "/build/target/$build_type/attestation-key-register" /usr/bin EXPOSE 8001 diff --git a/attestation-key-register/src/main.rs b/attestation-key-register/src/main.rs index fdf6202d..01ea1fbf 100644 --- a/attestation-key-register/src/main.rs +++ b/attestation-key-register/src/main.rs @@ -42,7 +42,7 @@ async fn handle_registration( client: Client, addr: Option, ) -> Result { - info!("Received registration request: {:?}", registration); + info!("Received registration request: {registration:?}"); let api: Api = Api::default_namespaced(client); @@ -52,8 +52,7 @@ async fn handle_registration( if key.spec.public_key == registration.public_key { let existing_name = key.metadata.name.unwrap_or_default(); error!( - "Duplicate public key detected: already exists in AttestationKey '{}'", - existing_name + "Duplicate public key detected: already exists in AttestationKey '{existing_name}'" ); return Ok(reply::with_status( reply::json(&serde_json::json!({ @@ -66,11 +65,11 @@ async fn handle_registration( } } Err(e) => { - error!("Failed to list AttestationKeys: {}", e); + error!("Failed to list AttestationKeys: {e}"); return Ok(reply::with_status( reply::json(&serde_json::json!({ "status": "error", - "message": format!("Failed to check for existing keys: {}", e), + "message": format!("Failed to check for existing keys: {e}"), })), StatusCode::INTERNAL_SERVER_ERROR, )); @@ -108,11 +107,11 @@ async fn handle_registration( )) } Err(e) => { - error!("Failed to create AttestationKey: {}", e); + error!("Failed to create AttestationKey: {e}"); Ok(reply::with_status( reply::json(&serde_json::json!({ "status": "error", - "message": format!("Failed to create AttestationKey: {}", e), + "message": format!("Failed to create AttestationKey: {e}"), })), StatusCode::INTERNAL_SERVER_ERROR, )) @@ -147,7 +146,7 @@ async fn main() -> anyhow::Result<()> { .and_then(handle_registration); let addr = SocketAddr::from(([0, 0, 0, 0], args.port)); - info!("Listening on {}", addr); + info!("Listening on {addr}"); warp::serve(register).run(addr).await; diff --git a/compute-pcrs/Containerfile b/compute-pcrs/Containerfile index d1aa1e0e..6286a0b4 100644 --- a/compute-pcrs/Containerfile +++ b/compute-pcrs/Containerfile @@ -4,7 +4,7 @@ # SPDX-License-Identifier: CC0-1.0 ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot AS builder +FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder ARG build_type WORKDIR /build @@ -28,7 +28,7 @@ RUN sed -i 's/members =.*/members = ["compute-pcrs", "lib"]/' Cargo.toml && \ COPY compute-pcrs/src compute-pcrs/src RUN cargo build -p compute-pcrs $(if [ "$build_type" = release ]; then echo --release; fi) -FROM quay.io/fedora/fedora:42 +FROM quay.io/fedora/fedora:43 ARG build_type COPY --from=builder "/build/target/$build_type/compute-pcrs" /usr/bin COPY --from=builder /build/reference-values /reference-values diff --git a/operator/src/attestation_key_register.rs b/operator/src/attestation_key_register.rs index 7a326537..8a6069ae 100644 --- a/operator/src/attestation_key_register.rs +++ b/operator/src/attestation_key_register.rs @@ -133,13 +133,13 @@ async fn ak_reconcile( client: Arc, ) -> Result { let ak_name = ak.metadata.name.clone().unwrap_or_default(); - info!("Attestation Key reconciliation for: {}", ak_name); + info!("Attestation Key reconciliation for: {ak_name}"); let client = Arc::unwrap_or_clone(client); let machines: Api = Api::default_namespaced(client.clone()); let lp = ListParams::default(); let machine_list: ObjectList = machines.list(&lp).await.map_err(|e| { - eprintln!("Error fetching machine list: {}", e); + eprintln!("Error fetching machine list: {e}"); ControllerError::Anyhow(e.into()) })?; for machine in &machine_list.items { @@ -180,15 +180,15 @@ async fn machine_reconcile( let aks: Api = Api::default_namespaced(client.clone()); let lp = ListParams::default(); let ak_list: ObjectList = aks.list(&lp).await.map_err(|e| { - eprintln!("Error fetching attestation key list: {}", e); + eprintln!("Error fetching attestation key list: {e}"); ControllerError::Anyhow(e.into()) })?; for ak in ak_list.items { - if let Some(ak_address) = &ak.spec.address { - if *ak_address == machine_address { - approve_ak(&ak, &machine, client.clone()).await?; - return Ok(Action::await_change()); - } + if let Some(ak_address) = &ak.spec.address + && *ak_address == machine_address + { + approve_ak(&ak, &machine, client.clone()).await?; + return Ok(Action::await_change()); } } Ok(Action::await_change()) @@ -313,10 +313,7 @@ async fn secret_reconcile( return Ok(Action::await_change()); } - info!( - "Secret reconciliation for AttestationKey secret: {}", - secret_name - ); + info!("Secret reconciliation for AttestationKey secret: {secret_name}"); let secrets: Api = Api::default_namespaced(Arc::unwrap_or_clone(client.clone())); finalizer(&secrets, ATTESTATION_KEY_SECRET_FINALIZER, secret, |ev| async move { @@ -328,15 +325,14 @@ async fn secret_reconcile( .await .map(|_| Action::await_change()) .map_err(|e| { - eprintln!("Error updating attestation key volumes on secret apply: {}", e); + eprintln!("Error updating attestation key volumes on secret apply: {e}"); finalizer::Error::::ApplyFailed(e.into()) }) } Event::Cleanup(secret) => { let secret_name = secret.metadata.name.clone().unwrap_or_default(); info!( - "AttestationKey secret {} is being deleted, updating trustee deployment volumes", - secret_name + "AttestationKey secret {secret_name} is being deleted, updating trustee deployment volumes" ); let client = Arc::unwrap_or_clone(client); // Update trustee deployment - secrets with deletion_timestamp will be filtered out @@ -345,8 +341,7 @@ async fn secret_reconcile( .map(|_| Action::await_change()) .map_err(|e| { eprintln!( - "Error updating attestation key volumes during secret deletion: {}", - e + "Error updating attestation key volumes during secret deletion: {e}" ); finalizer::Error::::CleanupFailed(e.into()) }) diff --git a/operator/src/reference_values.rs b/operator/src/reference_values.rs index 29bd6485..671d5351 100644 --- a/operator/src/reference_values.rs +++ b/operator/src/reference_values.rs @@ -297,13 +297,13 @@ pub async fn handle_new_image( let config_maps: Api = Api::default_namespaced(ctx.client.clone()); let mut image_pcrs_map = config_maps.get(PCR_CONFIG_MAP).await?; let mut image_pcrs = get_image_pcrs(image_pcrs_map.clone())?; - if let Some(pcr) = image_pcrs.0.get(resource_name) { - if pcr.reference == boot_image { - info!("Image {boot_image} was to be allowed, but already was allowed"); - return trustee::update_reference_values(ctx) - .await - .map(|_| COMMITTED_REASON); - } + if let Some(pcr) = image_pcrs.0.get(resource_name) + && pcr.reference == boot_image + { + info!("Image {boot_image} was to be allowed, but already was allowed"); + return trustee::update_reference_values(ctx) + .await + .map(|_| COMMITTED_REASON); } let image_ref: oci_client::Reference = boot_image.parse()?; if image_ref.digest().is_none() { diff --git a/operator/src/trustee.rs b/operator/src/trustee.rs index abdb9dbf..38947b4c 100644 --- a/operator/src/trustee.rs +++ b/operator/src/trustee.rs @@ -256,7 +256,7 @@ pub async fn update_attestation_keys(client: Client) -> Result<()> { name: secret_name.to_string(), items: Some(vec![KeyToPath { key: "public_key".to_string(), - path: format!("{}.pub", secret_name), + path: format!("{secret_name}.pub"), ..Default::default() }]), ..Default::default() diff --git a/register-server/Containerfile b/register-server/Containerfile index 975a202f..7124a1cf 100644 --- a/register-server/Containerfile +++ b/register-server/Containerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: CC0-1.0 ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot AS builder +FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder ARG build_type WORKDIR /build @@ -27,7 +27,7 @@ RUN sed -i 's/members =.*/members = ["lib", "register-server"]/' Cargo.toml && \ COPY register-server/src register-server/src RUN cargo build -p register-server $(if [ "$build_type" = release ]; then echo --release; fi) -FROM quay.io/fedora/fedora:42 +FROM quay.io/fedora/fedora:43 ARG build_type COPY --from=builder "/build/target/$build_type/register-server" /usr/bin EXPOSE 3030 diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index 08e47cce..8ba3d43c 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -370,13 +370,12 @@ impl TestContext { async move { let deployment = api.get(&name).await?; - if let Some(status) = &deployment.status { - if let Some(available_replicas) = status.available_replicas { - if available_replicas == 1 { - test_info!(&tn, "{} deployment has 1 available replica", name); - return Ok(()); - } - } + if let Some(status) = &deployment.status + && let Some(available_replicas) = status.available_replicas + && available_replicas == 1 + { + test_info!(&tn, "{} deployment has 1 available replica", name); + return Ok(()); } Err(anyhow!( @@ -485,14 +484,14 @@ impl TestContext { let ns = self.test_namespace.clone(); let sa_src = workspace_root.join("config/rbac/service_account.yaml"); let sa_content = std::fs::read_to_string(&sa_src)? - .replace("namespace: system", &format!("namespace: {}", ns)); + .replace("namespace: system", &format!("namespace: {ns}")); let sa_dst = rbac_temp_dir.join("service_account.yaml"); std::fs::write(&sa_dst, sa_content)?; let role_path = rbac_temp_dir.join("role.yaml"); let role_content = std::fs::read_to_string(&role_path)?.replace( "name: trusted-cluster-operator-role", - &format!("name: {}-trusted-cluster-operator-role", ns), + &format!("name: {ns}-trusted-cluster-operator-role"), ); std::fs::write(&role_path, role_content)?; @@ -500,21 +499,21 @@ impl TestContext { let rb = "name: manager-rolebinding"; let role = "name: trusted-cluster-operator-role"; let rb_content = std::fs::read_to_string(&rb_src)? - .replace(rb, &format!("name: {}-manager-rolebinding", ns)) - .replace(role, &format!("name: {}-trusted-cluster-operator-role", ns)) - .replace("namespace: system", &format!("namespace: {}", ns)); + .replace(rb, &format!("name: {ns}-manager-rolebinding")) + .replace(role, &format!("name: {ns}-trusted-cluster-operator-role")) + .replace("namespace: system", &format!("namespace: {ns}")); let rb_dst = rbac_temp_dir.join("role_binding.yaml"); std::fs::write(&rb_dst, rb_content)?; let le_role_src = workspace_root.join("config/rbac/leader_election_role.yaml"); let le_role_content = std::fs::read_to_string(&le_role_src)? - .replace("namespace: system", &format!("namespace: {}", ns)); + .replace("namespace: system", &format!("namespace: {ns}")); let le_role_dst = rbac_temp_dir.join("leader_election_role.yaml"); std::fs::write(&le_role_dst, le_role_content)?; let le_rb_src = workspace_root.join("config/rbac/leader_election_role_binding.yaml"); let le_rb_content = std::fs::read_to_string(&le_rb_src)? - .replace("namespace: system", &format!("namespace: {}", ns)); + .replace("namespace: system", &format!("namespace: {ns}")); let le_rb_dst = rbac_temp_dir.join("leader_election_role_binding.yaml"); std::fs::write(&le_rb_dst, le_rb_content)?; @@ -570,13 +569,13 @@ impl TestContext { let cr_content = std::fs::read_to_string(&cr_manifest_path)?; let mut cr_value: serde_yaml::Value = serde_yaml::from_str(&cr_content)?; - if let Some(spec) = cr_value.get_mut("spec") { - if let Some(spec_map) = spec.as_mapping_mut() { - spec_map.insert( - serde_yaml::Value::String("publicTrusteeAddr".to_string()), - serde_yaml::Value::String(trustee_addr.clone()), - ); - } + if let Some(spec) = cr_value.get_mut("spec") + && let Some(spec_map) = spec.as_mapping_mut() + { + spec_map.insert( + serde_yaml::Value::String("publicTrusteeAddr".to_string()), + serde_yaml::Value::String(trustee_addr.clone()), + ); } let updated_content = serde_yaml::to_string(&cr_value)?; diff --git a/test_utils/src/virt/mod.rs b/test_utils/src/virt/mod.rs index 65e4f767..d3e109c0 100644 --- a/test_utils/src/virt/mod.rs +++ b/test_utils/src/virt/mod.rs @@ -242,8 +242,7 @@ pub trait VmBackend: Send + Sync { .with_timeout(Duration::from_secs(timeout_secs)) .with_interval(Duration::from_secs(10)) .with_error_message(format!( - "SSH access to VM did not become {}available after {} seconds", - avail_prefix, timeout_secs + "SSH access to VM did not become {avail_prefix}available after {timeout_secs} seconds" )); let check_fn = || { diff --git a/tests/attestation.rs b/tests/attestation.rs index a682f4f0..608f61a5 100644 --- a/tests/attestation.rs +++ b/tests/attestation.rs @@ -38,16 +38,17 @@ impl SingleAttestationContext { async fn new(vm_name: &str, test_ctx: &TestContext) -> Result { let client = test_ctx.client(); let namespace = test_ctx.namespace(); + let backend = virt::create_backend(client.clone(), namespace, vm_name)?; - test_ctx.info(format!("Creating VM: {}", vm_name)); + test_ctx.info(format!("Creating VM: {vm_name}")); backend.create_vm().await?; - test_ctx.info(format!("Waiting for VM {} to reach Running state", vm_name)); + test_ctx.info(format!("Waiting for VM {vm_name} to reach Running state")); backend.wait_for_running(600).await?; - test_ctx.info(format!("VM {} is Running", vm_name)); + test_ctx.info(format!("VM {vm_name} is Running")); - test_ctx.info(format!("Waiting for SSH access to VM {}", vm_name)); + test_ctx.info(format!("Waiting for SSH access to VM {vm_name}")); backend.wait_for_vm_ssh_ready(600).await?; test_ctx.info("SSH access is ready"); @@ -162,29 +163,29 @@ async fn test_vm_reboot_attestation() -> anyhow::Result<()> { // Perform multiple reboots let num_reboots = 3; for i in 1..=num_reboots { - test_ctx.info(format!("Performing reboot {} of {}", i, num_reboots)); + test_ctx.info(format!("Performing reboot {i} of {num_reboots}")); // Reboot the VM via SSH let _reboot_result = att_ctx.backend.ssh_exec("sudo systemctl reboot").await; - test_ctx.info(format!("Waiting for lack of SSH access after reboot {}", i)); + test_ctx.info(format!("Waiting for lack of SSH access after reboot {i}")); att_ctx.backend.wait_for_vm_ssh_unavail(30).await?; - test_ctx.info(format!("Waiting for SSH access after reboot {}", i)); + test_ctx.info(format!("Waiting for SSH access after reboot {i}")); att_ctx.backend.wait_for_vm_ssh_ready(300).await?; // Verify encrypted root is still present after reboot - test_ctx.info(format!("Verifying encrypted root after reboot {}", i)); + test_ctx.info(format!("Verifying encrypted root after reboot {i}")); let has_encrypted_root = att_ctx.verify_encrypted_root().await?; assert!( has_encrypted_root, "VM should have encrypted root device after reboot {i}" ); - test_ctx.info(format!("Reboot {}: attestation successful", i)); + test_ctx.info(format!("Reboot {i}: attestation successful")); } test_ctx.info(format!( - "VM successfully rebooted {num_reboots} times with encrypted root device maintained", + "VM successfully rebooted {num_reboots} times with encrypted root device maintained" )); att_ctx.cleanup().await?; test_ctx.cleanup().await?; diff --git a/tests/trusted_execution_cluster.rs b/tests/trusted_execution_cluster.rs index 6a60cd49..abd0fc9c 100644 --- a/tests/trusted_execution_cluster.rs +++ b/tests/trusted_execution_cluster.rs @@ -60,14 +60,12 @@ async fn test_image_pcrs_configmap_updates() -> anyhow::Result<()> { async move { let cm = api.get("image-pcrs").await?; - if let Some(data) = &cm.data { - if let Some(image_pcrs_json) = data.get("image-pcrs.json") { - if let Ok(image_pcrs) = serde_json::from_str::(image_pcrs_json) { - if !image_pcrs.0.is_empty() { - return Ok(()); - } - } - } + if let Some(data) = &cm.data + && let Some(image_pcrs_json) = data.get("image-pcrs.json") + && let Ok(image_pcrs) = serde_json::from_str::(image_pcrs_json) + && !image_pcrs.0.is_empty() + { + return Ok(()); } Err(anyhow::anyhow!("image-pcrs ConfigMap not yet populated with image-pcrs.json data")) @@ -167,12 +165,11 @@ async fn test_image_disallow() -> anyhow::Result<()> { let api = configmap_api.clone(); async move { let cm = api.get("trustee-data").await?; - if let Some(data) = &cm.data { - if let Some(reference_values_json) = data.get("reference-values.json") { - if !reference_values_json.contains(EXPECTED_PCR4) { - return Ok(()); - } - } + if let Some(data) = &cm.data + && let Some(reference_values_json) = data.get("reference-values.json") + && !reference_values_json.contains(EXPECTED_PCR4) + { + return Ok(()); } Err(anyhow::anyhow!("Reference value not yet removed")) }