diff --git a/src/libs/kata-types/src/initdata.rs b/src/libs/kata-types/src/initdata.rs index 65ad341ea3..abf98b781e 100644 --- a/src/libs/kata-types/src/initdata.rs +++ b/src/libs/kata-types/src/initdata.rs @@ -8,6 +8,7 @@ use flate2::read::GzDecoder; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256, Sha384, Sha512}; use std::{collections::HashMap, io::Read}; +use crate::sl; /// Currently, initdata only supports version 0.1.0. const INITDATA_VERSION: &str = "0.1.0"; @@ -203,12 +204,18 @@ pub fn calculate_initdata_digest( Ok(b64encoded_digest) } -/// The argument `initda_annotation` is a Standard base64 encoded string containing a TOML formatted content. +/// The argument `initdata_annotation` is a Standard base64 encoded string containing a TOML formatted content. /// This function decodes the base64 string, parses the TOML content into an InitData structure. -pub fn add_hypervisor_initdata_overrides(initda_annotation: &str) -> Result { +pub fn add_hypervisor_initdata_overrides(initdata_annotation: &str) -> Result { + // If the initdata is empty, return an empty string + if initdata_annotation.is_empty() { + info!(sl!(), "initdata_annotation is empty"); + return Ok("".to_string()); + } + // Base64 decode the annotation value let b64_decoded = - base64::decode_config(initda_annotation, base64::STANDARD).context("base64 decode")?; + base64::decode_config(initdata_annotation, base64::STANDARD).context("base64 decode")?; // Gzip decompress the decoded data let mut gz_decoder = GzDecoder::new(&b64_decoded[..]); @@ -231,6 +238,139 @@ mod tests { use flate2::Compression; use std::io::Write; + // create gzipped and base64 encoded string + fn create_encoded_input(content: &str) -> String { + let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); + encoder.write_all(content.as_bytes()).unwrap(); + let compressed = encoder.finish().unwrap(); + base64::encode_config(&compressed, base64::STANDARD) + } + + #[test] + fn test_empty_annotation() { + // Test with empty string input + let result = add_hypervisor_initdata_overrides(""); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), ""); + } + + #[test] + fn test_empty_data_section() { + // Test with empty data section + let toml_content = r#" +algorithm = "sha384" +version = "0.1.0" + +[data] +"#; + let encoded = create_encoded_input(toml_content); + + let result = add_hypervisor_initdata_overrides(&encoded); + assert!(result.is_ok()); + } + + #[test] + fn test_valid_complete_initdata() { + // Test with complete InitData structure + let toml_content = r#" +algorithm = "sha384" +version = "0.1.0" + +[data] +"aa.toml" = ''' +[token_configs] +[token_configs.coco_as] +url = 'http://kbs-service.xxx.cluster.local:8080' + +[token_configs.kbs] +url = 'http://kbs-service.xxx.cluster.local:8080' +''' + +"cdh.toml" = ''' +socket = 'unix:///run/guest-services/cdh.sock' +credentials = [] + +[kbc] +name = 'cc_kbc' +url = 'http://kbs-service.xxx.cluster.local:8080' +''' +"#; + let encoded = create_encoded_input(toml_content); + + let result = add_hypervisor_initdata_overrides(&encoded); + assert!(result.is_ok()); + + let output = result.unwrap(); + assert!(!output.is_empty()); + assert!(output.contains("algorithm")); + assert!(output.contains("version")); + } + + #[test] + fn test_invalid_base64() { + // Test with invalid base64 string + let invalid_base64 = "This is not valid base64!"; + + let result = add_hypervisor_initdata_overrides(invalid_base64); + assert!(result.is_err()); + + let error = result.unwrap_err(); + assert!(error.to_string().contains("base64 decode")); + } + + #[test] + fn test_valid_base64_invalid_gzip() { + // Test with valid base64 but invalid gzip content + let not_gzipped = "This is not gzipped content"; + let encoded = base64::encode_config(not_gzipped.as_bytes(), base64::STANDARD); + + let result = add_hypervisor_initdata_overrides(&encoded); + assert!(result.is_err()); + + let error = result.unwrap_err(); + assert!(error.to_string().contains("gz decoder failed")); + } + + #[test] + fn test_missing_algorithm() { + // Test with missing algorithm field + let toml_content = r#" +version = "0.1.0" + +[data] +"test.toml" = ''' +key = "value" +''' +"#; + let encoded = create_encoded_input(toml_content); + + let result = add_hypervisor_initdata_overrides(&encoded); + // This might fail depending on whether algorithm is required + if result.is_err() { + assert!(result.unwrap_err().to_string().contains("parse initdata")); + } + } + + #[test] + fn test_missing_version() { + // Test with missing version field + let toml_content = r#" +algorithm = "sha384" + +[data] +"test.toml" = ''' +key = "value" +''' +"#; + let encoded = create_encoded_input(toml_content); + + let result = add_hypervisor_initdata_overrides(&encoded); + // This might fail depending on whether version is required + if result.is_err() { + assert!(result.unwrap_err().to_string().contains("parse initdata")); + } + } + /// Test InitData creation and serialization #[test] fn test_init_data() { diff --git a/tests/integration/kubernetes/k8s-initdata.bats b/tests/integration/kubernetes/k8s-initdata.bats index 15bcc4993c..1e98cf316a 100644 --- a/tests/integration/kubernetes/k8s-initdata.bats +++ b/tests/integration/kubernetes/k8s-initdata.bats @@ -182,7 +182,7 @@ EOF return 1 fi - assert_logs_contain "${node}" kata "${node_start_time}" "\[CDH\] \[ERROR\]: Get Resource failed" + assert_logs_contain "${node}" kata "${node_start_time}" "\[CDH\] \[ERROR\]: Image Client error: Initialize resource provider failed: Get resource failed" } teardown() {