From 33df4ebc124421ea771c291b74e199ca4194805f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Be=C3=B1at=20Gartzia=20Arruabarrena?= Date: Tue, 23 Dec 2025 08:33:31 +0100 Subject: [PATCH 1/2] rust: Update minimum toolchain to 1.92 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minimum rust version was set to 1.85. Fedora is way above that threshold at the moment. Future EL releases will be above that as well. While on it, fix some of the linter errors that arise from the minimum version update. Signed-off-by: BeƱat Gartzia Arruabarrena --- .github/workflows/lint.yml | 2 +- Cargo.toml | 2 +- attestation-key-register/src/main.rs | 15 ++++--- operator/src/attestation_key_register.rs | 29 ++++++-------- operator/src/reference_values.rs | 14 +++---- operator/src/trustee.rs | 2 +- test_utils/src/lib.rs | 51 +++++++++++------------- test_utils/src/virt.rs | 35 ++++++---------- tests/attestation.rs | 33 +++++++-------- tests/trusted_execution_cluster.rs | 25 +++++------- 10 files changed, 91 insertions(+), 117 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 50261314..aa3777f2 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.92.0 jobs: linting: diff --git a/Cargo.toml b/Cargo.toml index 87d9752a..ef1ce97a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ resolver = "3" [workspace.package] edition = "2024" -rust-version = "1.85" +rust-version = "1.92" [workspace.dependencies] anyhow = "1.0.100" diff --git a/attestation-key-register/src/main.rs b/attestation-key-register/src/main.rs index 165d686e..8a764973 100644 --- a/attestation-key-register/src/main.rs +++ b/attestation-key-register/src/main.rs @@ -40,7 +40,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); @@ -50,8 +50,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!({ @@ -64,11 +63,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, )); @@ -106,11 +105,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, )) @@ -145,7 +144,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/operator/src/attestation_key_register.rs b/operator/src/attestation_key_register.rs index 5f56fa54..e126d5a4 100644 --- a/operator/src/attestation_key_register.rs +++ b/operator/src/attestation_key_register.rs @@ -135,13 +135,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 { @@ -182,15 +182,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()) @@ -315,10 +315,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 { @@ -330,15 +327,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 @@ -347,8 +343,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 74ad65d2..65df147a 100644 --- a/operator/src/trustee.rs +++ b/operator/src/trustee.rs @@ -254,7 +254,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/test_utils/src/lib.rs b/test_utils/src/lib.rs index 60bd4d87..ee7fd4d9 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -225,13 +225,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::anyhow!( @@ -357,14 +356,14 @@ impl TestContext { 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)?; @@ -372,25 +371,25 @@ impl TestContext { let rb_content = std::fs::read_to_string(&rb_src)? .replace( "name: manager-rolebinding", - &format!("name: {}-manager-rolebinding", ns), + &format!("name: {ns}-manager-rolebinding"), ) .replace( "name: trusted-cluster-operator-role", - &format!("name: {}-trusted-cluster-operator-role", ns), + &format!("name: {ns}-trusted-cluster-operator-role"), ) - .replace("namespace: system", &format!("namespace: {}", ns)); + .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)?; @@ -399,7 +398,7 @@ impl TestContext { r#"# SPDX-FileCopyrightText: Generated for testing # SPDX-License-Identifier: CC0-1.0 -namespace: {} +namespace: {ns} resources: - service_account.yaml @@ -407,8 +406,7 @@ resources: - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -"#, - ns +"# ); let temp_kustomization_path = rbac_temp_dir.join("kustomization.yaml"); @@ -436,19 +434,19 @@ resources: &self.test_name, "Updating CR manifest with publicTrusteeAddr" ); - let trustee_addr = format!("kbs-service.{}.svc.cluster.local:8080", ns); + let trustee_addr = format!("kbs-service.{ns}.svc.cluster.local:8080"); let cr_manifest_path = manifests_path.join("trusted_execution_cluster_cr.yaml"); 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)?; @@ -494,8 +492,7 @@ resources: .with_timeout(Duration::from_secs(60)) .with_interval(Duration::from_secs(5)) .with_error_message(format!( - "image-pcrs ConfigMap in the namespace {} not found", - ns + "image-pcrs ConfigMap in the namespace {ns} not found" )); let test_name_owned = self.test_name.clone(); diff --git a/test_utils/src/virt.rs b/test_utils/src/virt.rs index 9ba3aace..82b9b23e 100644 --- a/test_utils/src/virt.rs +++ b/test_utils/src/virt.rs @@ -49,10 +49,7 @@ pub fn generate_ssh_key_pair() -> anyhow::Result<(String, String, std::path::Pat let stderr = String::from_utf8_lossy(&ssh_add_output.stderr); // Clean up the key file if ssh-add fails let _ = fs::remove_file(&key_path); - return Err(anyhow::anyhow!( - "Failed to add SSH key to agent: {}", - stderr - )); + return Err(anyhow::anyhow!("Failed to add SSH key to agent: {stderr}")); } Ok((private_key_str, public_key_str, key_path)) @@ -138,10 +135,8 @@ pub fn generate_ignition_config( serde_json::to_value(&config).expect("Failed to serialize ignition config"); // Add attestation key registration field - let attestation_url = format!( - "http://attestation-key-register.{}.svc.cluster.local:8001/register-ak", - namespace - ); + let attestation_url = + format!("http://attestation-key-register.{namespace}.svc.cluster.local:8001/register-ak"); if let Some(obj) = ignition_json.as_object_mut() { obj.insert( @@ -303,8 +298,7 @@ pub async fn wait_for_vm_running( .with_timeout(Duration::from_secs(timeout_secs)) .with_interval(Duration::from_secs(5)) .with_error_message(format!( - "VirtualMachine {} did not reach Running phase after {} seconds", - vm_name, timeout_secs + "VirtualMachine {vm_name} did not reach Running phase after {timeout_secs} seconds" )); poller @@ -315,17 +309,15 @@ pub async fn wait_for_vm_running( let vm = api.get(&name).await?; // Check VM status phase - if let Some(status) = vm.status { - if let Some(phase) = status.printable_status { - if phase.as_str() == "Running" { - return Ok(()); - } - } + if let Some(status) = vm.status + && let Some(phase) = status.printable_status + && phase.as_str() == "Running" + { + return Ok(()); } Err(anyhow::anyhow!( - "VirtualMachine {} is not in Running phase yet", - name + "VirtualMachine {name} is not in Running phase yet" )) } }) @@ -344,7 +336,7 @@ pub async fn virtctl_ssh_exec( )); } - let _vm_target = format!("core@vmi/{}/{}", vm_name, namespace); + let _vm_target = format!("core@vmi/{vm_name}/{namespace}"); let full_cmd = format!( "virtctl ssh -i {} core@vmi/{}/{} -t '-o IdentitiesOnly=yes' -t '-o StrictHostKeyChecking=no' --known-hosts /dev/null -c '{}'", key_path.display(), @@ -356,7 +348,7 @@ pub async fn virtctl_ssh_exec( let output = Command::new("sh").arg("-c").arg(full_cmd).output().await?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); - return Err(anyhow::anyhow!("virtctl ssh command failed: {}", stderr)); + return Err(anyhow::anyhow!("virtctl ssh command failed: {stderr}")); } Ok(String::from_utf8_lossy(&output.stdout).to_string()) @@ -392,8 +384,7 @@ async fn wait_for_vm_ssh( .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", - namespace, vm_name, avail_prefix, timeout_secs + "SSH access to VM {namespace}/{vm_name} did not become {avail_prefix}available after {timeout_secs} seconds", )); poller diff --git a/tests/attestation.rs b/tests/attestation.rs index 2947ef26..9d78e9cc 100644 --- a/tests/attestation.rs +++ b/tests/attestation.rs @@ -46,17 +46,15 @@ impl SingleAttestationContext { let (_private_key, public_key, key_path) = virt::generate_ssh_key_pair()?; test_ctx.info(format!( - "Generated SSH key pair and added to ssh-agent: {:?}", - key_path + "Generated SSH key pair and added to ssh-agent: {key_path:?}" )); let register_server_url = format!( - "http://register-server.{}.svc.cluster.local:8000/ignition-clevis-pin-trustee", - namespace + "http://register-server.{namespace}.svc.cluster.local:8000/ignition-clevis-pin-trustee" ); let image = "quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:20260129"; - test_ctx.info(format!("Creating VM: {}", vm_name)); + test_ctx.info(format!("Creating VM: {vm_name}")); virt::create_kubevirt_vm( client, namespace, @@ -67,11 +65,11 @@ impl SingleAttestationContext { ) .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")); virt::wait_for_vm_running(client, namespace, vm_name, 300).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}")); virt::wait_for_vm_ssh_ready(namespace, vm_name, &key_path, 600).await?; test_ctx.info("SSH access is ready"); @@ -124,8 +122,7 @@ async fn test_parallel_vm_attestation() -> anyhow::Result<()> { test_ctx.info("Generated SSH key pairs for both VMs"); let register_server_url = format!( - "http://register-server.{}.svc.cluster.local:8000/ignition-clevis-pin-trustee", - namespace + "http://register-server.{namespace}.svc.cluster.local:8000/ignition-clevis-pin-trustee" ); let image = "quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:20260129"; @@ -233,7 +230,7 @@ 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 = virt::virtctl_ssh_exec( @@ -244,27 +241,25 @@ async fn test_vm_reboot_attestation() -> anyhow::Result<()> { ) .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}")); virt::wait_for_vm_ssh_unavail(namespace, vm_name, &att_ctx.key_path, 30).await?; - test_ctx.info(format!("Waiting for SSH access after reboot {}", i)); + test_ctx.info(format!("Waiting for SSH access after reboot {i}")); virt::wait_for_vm_ssh_ready(namespace, vm_name, &att_ctx.key_path, 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 = virt::verify_encrypted_root(namespace, vm_name, &att_ctx.key_path, &att_ctx.root_key).await?; assert!( has_encrypted_root, - "VM should have encrypted root device after reboot {}", - i + "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 {} times with encrypted root device maintained", - num_reboots + "VM successfully rebooted {num_reboots} times with encrypted root device maintained" )); 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")) } From ed73c1e90f6652d87484138fc2e5b1f3d71ca206 Mon Sep 17 00:00:00 2001 From: Jakob Naucke Date: Wed, 14 Jan 2026 14:02:26 +0100 Subject: [PATCH 2/2] deps: bump kube-rs to v3.0.0 Needs manual updates, #150 was incomplete. Signed-off-by: Jakob Naucke --- Cargo.lock | 99 ++++++++++++-------------------- Cargo.toml | 4 +- compute-pcrs/src/main.rs | 4 +- lib/src/lib.rs | 4 +- lib/src/reference_values.rs | 4 +- operator/Cargo.toml | 1 + operator/src/conditions.rs | 8 +-- operator/src/main.rs | 4 +- operator/src/reference_values.rs | 6 +- operator/src/test_utils.rs | 4 +- operator/src/trustee.rs | 2 +- test_utils/src/mock_client.rs | 10 ++-- 12 files changed, 64 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 295482fd..d017be43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,12 +596,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -620,11 +620,10 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", @@ -645,11 +644,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.21.3", + "darling_core 0.23.0", "quote", "syn 2.0.110", ] @@ -945,9 +944,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "foreign-types" @@ -1178,21 +1177,15 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ "allocator-api2", "equivalent", "foldhash", ] -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - [[package]] name = "hdrhistogram" version = "7.5.4" @@ -1260,15 +1253,6 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "hostname" version = "0.4.1" @@ -1774,9 +1758,9 @@ dependencies = [ [[package]] name = "jsonpath-rust" -version = "0.7.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b" +checksum = "633a7320c4bb672863a3782e89b9094ad70285e097ff6832cddd0ec615beadfa" dependencies = [ "pest", "pest_derive", @@ -1812,12 +1796,12 @@ dependencies = [ [[package]] name = "k8s-openapi" -version = "0.26.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d9e5e61dd037cdc51da0d7e2b2be10f497478ea7e120d85dad632adb99882b" +checksum = "05a6d6f3611ad1d21732adbd7a2e921f598af6c92d71ae6e2620da4b67ee1f0d" dependencies = [ "base64 0.22.1", - "chrono", + "jiff", "schemars", "serde", "serde_json", @@ -1825,9 +1809,9 @@ dependencies = [ [[package]] name = "kube" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e7bb0b6a46502cc20e4575b6ff401af45cfea150b34ba272a3410b78aa014e" +checksum = "0dae7229247e4215781e5c5104a056e1e2163943e577f9084cf8bba7b5248f7a" dependencies = [ "k8s-openapi", "kube-client", @@ -1838,16 +1822,14 @@ dependencies = [ [[package]] name = "kube-client" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4987d57a184d2b5294fdad3d7fc7f278899469d21a4da39a8f6ca16426567a36" +checksum = "010875e291a9c0a4e076f4f9c35b97d82fd2372cb3bc713252c3d08b7e73ce5b" dependencies = [ "base64 0.22.1", "bytes", - "chrono", "either", "futures", - "home", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -1855,6 +1837,7 @@ dependencies = [ "hyper-openssl", "hyper-timeout", "hyper-util", + "jiff", "jsonpath-rust", "k8s-openapi", "kube-core", @@ -1874,14 +1857,14 @@ dependencies = [ [[package]] name = "kube-core" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914bbb770e7bb721a06e3538c0edd2babed46447d128f7c21caa68747060ee73" +checksum = "1ac76281aa698dd34111e25b21f5f6561932a30feabab5357152be273f8a81bb" dependencies = [ - "chrono", "derive_more", "form_urlencoded", "http 1.4.0", + "jiff", "json-patch", "k8s-openapi", "schemars", @@ -1893,11 +1876,11 @@ dependencies = [ [[package]] name = "kube-derive" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03dee8252be137772a6ab3508b81cd797dee62ee771112a2453bc85cbbe150d2" +checksum = "599c09721efcccc0e6a26e93df28c587da60ff5e099c657626fff2af0ae4cbb8" dependencies = [ - "darling 0.21.3", + "darling 0.23.0", "proc-macro2", "quote", "serde", @@ -1907,9 +1890,9 @@ dependencies = [ [[package]] name = "kube-runtime" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea4de4b562c5cc89ab10300bb63474ae1fa57ff5a19275f2e26401a323e3fd" +checksum = "6db43d26700f564baf850f681f3cb0f1195d2699bd379bfa70750ecec4dcb209" dependencies = [ "ahash", "async-broadcast", @@ -1917,7 +1900,7 @@ dependencies = [ "backon", "educe", "futures", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "hostname", "json-patch", "k8s-openapi", @@ -2361,6 +2344,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base64 0.22.1", + "chrono", "clevis-pin-trustee-lib", "compute-pcrs-lib", "env_logger", @@ -3187,9 +3171,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", @@ -3698,9 +3682,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -4230,15 +4214,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" diff --git a/Cargo.toml b/Cargo.toml index ef1ce97a..5988d5d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,8 @@ compute-pcrs-lib = { git = "https://github.com/trusted-execution-clusters/comput env_logger = "0.11.8" http = "1.4.0" ignition-config = "0.5.0" -k8s-openapi = { version = "0.26.1", features = ["v1_33", "schemars"] } -kube = { version = "2.0.1", default-features = false, features = ["derive", "runtime", "openssl-tls"] } +k8s-openapi = { version = "0.27.0", features = ["v1_33", "schemars"] } +kube = { version = "3.0.0", default-features = false, features = ["derive", "runtime", "openssl-tls"] } log = "0.4.29" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.148" diff --git a/compute-pcrs/src/main.rs b/compute-pcrs/src/main.rs index 2509e2c0..db1f5f0d 100644 --- a/compute-pcrs/src/main.rs +++ b/compute-pcrs/src/main.rs @@ -6,7 +6,7 @@ use anyhow::{Context, Result}; use clap::Parser; use compute_pcrs_lib::*; -use k8s_openapi::{api::core::v1::ConfigMap, chrono::Utc}; +use k8s_openapi::{api::core::v1::ConfigMap, jiff::Timestamp}; use kube::{Api, Client}; use trusted_cluster_operator_lib::{conditions::INSTALLED_REASON, reference_values::*, *}; @@ -57,7 +57,7 @@ async fn main() -> Result<()> { let mut image_pcrs: ImagePcrs = serde_json::from_str(image_pcrs_str)?; let image_pcr = ImagePcr { - first_seen: Utc::now(), + first_seen: Timestamp::now(), reference: args.image, pcrs, }; diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 33a79304..5ab81afb 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -8,6 +8,7 @@ pub mod reference_values; mod kopium; #[allow(clippy::all)] mod vendor_kopium; +use k8s_openapi::jiff::Timestamp; pub use kopium::approvedimages::*; pub use kopium::attestationkeys::*; pub use kopium::machines::*; @@ -17,7 +18,6 @@ pub use vendor_kopium::virtualmachines; use conditions::*; use k8s_openapi::apimachinery::pkg::apis::meta::v1::{Condition, Time}; -use k8s_openapi::chrono::Utc; #[macro_export] macro_rules! update_status { @@ -50,7 +50,7 @@ pub fn committed_condition(reason: &str, generation: Option) -> Condition { _ => "", } .to_string(), - last_transition_time: Time(Utc::now()), + last_transition_time: Time(Timestamp::now()), observed_generation: generation, } } diff --git a/lib/src/reference_values.rs b/lib/src/reference_values.rs index 0e6361f4..80661bf9 100644 --- a/lib/src/reference_values.rs +++ b/lib/src/reference_values.rs @@ -4,7 +4,7 @@ // SPDX-License-Identifier: MIT use compute_pcrs_lib::Pcr; -use k8s_openapi::chrono::{DateTime, Utc}; +use k8s_openapi::jiff::Timestamp; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -13,7 +13,7 @@ pub const PCR_CONFIG_FILE: &str = "image-pcrs.json"; #[derive(Deserialize, Serialize)] pub struct ImagePcr { - pub first_seen: DateTime, + pub first_seen: Timestamp, pub pcrs: Vec, pub reference: String, } diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 0db4174e..85ddbba1 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -11,6 +11,7 @@ rust-version.workspace = true [dependencies] anyhow.workspace = true base64 = "0.22.1" +chrono = "0.4.42" clevis-pin-trustee-lib.workspace = true trusted-cluster-operator-lib = { path = "../lib" } compute-pcrs-lib.workspace = true diff --git a/operator/src/conditions.rs b/operator/src/conditions.rs index ae2b0fab..f969b059 100644 --- a/operator/src/conditions.rs +++ b/operator/src/conditions.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use k8s_openapi::apimachinery::pkg::apis::meta::v1::{Condition, Time}; -use k8s_openapi::chrono::Utc; +use k8s_openapi::jiff::Timestamp; use trusted_cluster_operator_lib::{condition_status, conditions::*}; pub fn known_trustee_address_condition(known: bool, generation: Option) -> Condition { @@ -18,7 +18,7 @@ pub fn known_trustee_address_condition(known: bool, generation: Option) -> status: condition_status(known), reason: reason.to_string(), message: message.to_string(), - last_transition_time: Time(Utc::now()), + last_transition_time: Time(Timestamp::now()), observed_generation: generation, } } @@ -38,7 +38,7 @@ pub fn installed_condition(reason: &str, generation: Option) -> Condition { _ => "", } .to_string(), - last_transition_time: Time(Utc::now()), + last_transition_time: Time(Timestamp::now()), observed_generation: generation, } } @@ -55,7 +55,7 @@ pub fn attestation_key_approved_condition(reason: &str, generation: Option) _ => "", } .to_string(), - last_transition_time: Time(Utc::now()), + last_transition_time: Time(Timestamp::now()), observed_generation: generation, } } diff --git a/operator/src/main.rs b/operator/src/main.rs index a0ada3ff..ce4916f5 100644 --- a/operator/src/main.rs +++ b/operator/src/main.rs @@ -261,7 +261,7 @@ async fn main() -> Result<()> { #[cfg(test)] mod tests { use http::{Method, Request, StatusCode}; - use k8s_openapi::{apimachinery::pkg::apis::meta::v1::Time, chrono::Utc}; + use k8s_openapi::{apimachinery::pkg::apis::meta::v1::Time, jiff::Timestamp}; use kube::api::ObjectList; use kube::client::Body; @@ -320,7 +320,7 @@ mod tests { }; count_check!(1, clos, |client| { let mut cluster = dummy_cluster(); - cluster.metadata.deletion_timestamp = Some(Time(Utc::now())); + cluster.metadata.deletion_timestamp = Some(Time(Timestamp::now())); let result = reconcile(Arc::new(cluster), Arc::new(dummy_cluster_ctx(client))).await; assert_eq!(result.unwrap(), Action::await_change()); }); diff --git a/operator/src/reference_values.rs b/operator/src/reference_values.rs index 671d5351..2795054e 100644 --- a/operator/src/reference_values.rs +++ b/operator/src/reference_values.rs @@ -15,7 +15,7 @@ use k8s_openapi::{ }, }, apimachinery::pkg::apis::meta::v1::OwnerReference, - chrono::Utc, + jiff::Timestamp, }; use kube::api::{DeleteParams, ObjectMeta}; use kube::runtime::{ @@ -321,7 +321,7 @@ pub async fn handle_new_image( } let image_pcr = ImagePcr { - first_seen: Utc::now(), + first_seen: Timestamp::now(), pcrs: label.unwrap(), reference: boot_image.to_string(), }; @@ -377,7 +377,7 @@ mod tests { ..Default::default() }, status: Some(JobStatus { - completion_time: Some(Time(Utc::now())), + completion_time: Some(Time(Timestamp::now())), ..Default::default() }), ..Default::default() diff --git a/operator/src/test_utils.rs b/operator/src/test_utils.rs index 6d8e5717..a9c0241d 100644 --- a/operator/src/test_utils.rs +++ b/operator/src/test_utils.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use compute_pcrs_lib::Pcr; -use k8s_openapi::{api::core::v1::ConfigMap, chrono::Utc}; +use k8s_openapi::{api::core::v1::ConfigMap, jiff::Timestamp}; use kube::Client; use operator::RvContextData; use std::collections::BTreeMap; @@ -15,7 +15,7 @@ pub fn dummy_pcrs() -> ImagePcrs { ImagePcrs(BTreeMap::from([( "cos".to_string(), ImagePcr { - first_seen: Utc::now(), + first_seen: Timestamp::now(), pcrs: vec![ Pcr { id: 0, diff --git a/operator/src/trustee.rs b/operator/src/trustee.rs index 65df147a..aaf0f00c 100644 --- a/operator/src/trustee.rs +++ b/operator/src/trustee.rs @@ -6,6 +6,7 @@ use anyhow::{Context, Result}; use base64::{Engine as _, engine::general_purpose}; +use chrono::{DateTime, TimeDelta, Utc}; use clevis_pin_trustee_lib::Key as ClevisKey; use k8s_openapi::api::apps::v1::{Deployment, DeploymentSpec}; use k8s_openapi::api::core::v1::{ @@ -17,7 +18,6 @@ use k8s_openapi::apimachinery::pkg::{ apis::meta::v1::{LabelSelector, OwnerReference}, util::intstr::IntOrString, }; -use k8s_openapi::chrono::{DateTime, TimeDelta, Utc}; use kube::{ Api, Client, Resource, api::{ObjectMeta, Patch, PatchParams}, diff --git a/test_utils/src/mock_client.rs b/test_utils/src/mock_client.rs index 4118aa52..068eeb92 100644 --- a/test_utils/src/mock_client.rs +++ b/test_utils/src/mock_client.rs @@ -5,7 +5,8 @@ use http::{Method, Request, Response, StatusCode}; use kube::api::ObjectMeta; -use kube::{Client, client::Body, error::ErrorResponse}; +use kube::core::{Status, response::StatusSummary}; +use kube::{Client, client::Body}; use serde::Serialize; use std::fmt::Debug; use std::sync::atomic::{AtomicU32, Ordering}; @@ -58,11 +59,12 @@ async fn create_response>>( StatusCode::BAD_REQUEST => ("bad request", "BadRequest"), _ => (unknown_msg.as_str(), "Unknown"), }; - let error_response = ErrorResponse { - status: "Failure".to_string(), + let error_response = Status { + status: Some(StatusSummary::Failure), message: message.to_string(), reason: reason.to_string(), code: status_code.as_u16(), + ..Default::default() }; let error_json = serde_json::to_string(&error_response).unwrap(); (Body::from(error_json.into_bytes()), status_code) @@ -152,7 +154,7 @@ async fn test_error< count_check!(1, server, |client| { let err = action(client).await.unwrap_err(); let msg = "internal server error"; - assert_kube_api_error!(err, 500, "ServerTimeout", msg, "Failure"); + assert_kube_api_error!(err, 500, "ServerTimeout", msg, Some(StatusSummary::Failure)); }); }