Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions attestation-key-register/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,8 @@ async fn main() {
let service = app.into_make_service();
info!("Starting attestation key registration server on http://{addr}",);

let run = if args.cert_path.is_some() && args.key_path.is_some() {
let config = OpenSSLConfig::from_pem_file(args.cert_path.unwrap(), args.key_path.unwrap())
.expect("invalid PEM files");
let run = if let (Some(cert_path), Some(key_path)) = (args.cert_path, args.key_path) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also in response to

I believe we have a setting which makes cargo fmt and clippy return warnings as errors, which made me change a few other parts of the code I did not modify for the feature. Is this intentional?

Weird, we have this job that check the cargo and clippy. Might be that the version you have installed is more recent than the toolchain in the CI

)

I agree with this change, and you're invited to keep making them (in separate commits like you did here), but let me give some context as to why it's not caught by CI in the first place: This has only become a lint recently, and we use a Rust version supported by RHEL/UBI to avoid downstream patching when using a Rust feature that's newer than that. We also use the linting as of that version because sometimes a new Rust feature also becomes a lint to use that feature relatively fast or even in the same version.

With that said, we could update to 1.92 (not for this PR). Ideally it's even possible to get dependabot to update to a version supported by e.g. registry.access.redhat.com/ubi9. This could maybe also go in a doc then.

let config = OpenSSLConfig::from_pem_file(cert_path, key_path).expect("invalid PEM files");
axum_server::bind_openssl(addr, config).serve(service).await
} else {
axum_server::bind(addr).serve(service).await
Expand Down
32 changes: 8 additions & 24 deletions operator/src/attestation_key_register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::conditions::attestation_key_approved_condition;
use crate::trustee;
use operator::{
ControllerError, TLS_DIR, controller_error_policy, create_or_info_if_exists, read_certificate,
upsert_condition,
};

const INTERNAL_ATTESTATION_KEY_REGISTER_PORT: i32 = 8001;
Expand Down Expand Up @@ -200,31 +201,14 @@ async fn approve_ak(ak: &AttestationKey, machine: &Machine, client: Client) -> R
let name = ak.metadata.name.clone().unwrap_or_default();
let aks: Api<AttestationKey> = Api::default_namespaced(client.clone());

let is_approved = ak
.status
.as_ref()
.and_then(|s| s.conditions.as_ref())
.map(|conditions| {
conditions
.iter()
.any(|c| c.type_ == "Approved" && c.status == "True")
})
.unwrap_or(false);
let generation = ak.metadata.generation;
let approve_reason = ATTESTATION_KEY_MACHINE_APPROVE;
let condition = attestation_key_approved_condition(approve_reason, generation, &ak.status);
let mut conditions = ak.status.as_ref().and_then(|s| s.conditions.clone());
let changed = upsert_condition(&mut conditions, condition);

if !is_approved {
let generation = ak.metadata.generation;
let approve_reason = ATTESTATION_KEY_MACHINE_APPROVE;
let condition = attestation_key_approved_condition(approve_reason, generation, &ak.status);
let mut conditions = ak
.status
.as_ref()
.and_then(|s| s.conditions.clone())
.unwrap_or_default();
conditions.push(condition);

let status = AttestationKeyStatus {
conditions: Some(conditions),
};
if changed {
let status = AttestationKeyStatus { conditions };
update_status!(aks, &name, status)?;
info!("Approved attestation key {name}");
}
Expand Down
45 changes: 45 additions & 0 deletions operator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use anyhow::Result;
use k8s_openapi::api::core::v1::{Secret, SecretVolumeSource, Volume, VolumeMount};
use k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::{Condition, Time};
use k8s_openapi::jiff::Timestamp;
use kube::{Api, Client, runtime::controller::Action};
use log::{info, warn};
use std::fmt::{Debug, Display};
Expand Down Expand Up @@ -94,3 +96,46 @@ pub async fn read_certificate(
};
Ok(Some((volume, volume_mount)))
}

// TODO: Port this functionality to kube-rs API.
// Update condition if already present, otherwise append(insert) it into the conditions vector.
pub fn upsert_condition(
existing_conditions: &mut Option<Vec<Condition>>,
new_condition: Condition,
) -> bool {
let conditions_vec = existing_conditions.get_or_insert_with(Vec::new);

if let Some(existing) = conditions_vec
.iter_mut()
.find(|c| c.type_ == new_condition.type_)
{
let mut changed = false;

// Being faithful to kubernetes API semantics, only update transition time if status changes.
if existing.status != new_condition.status {
existing.status = new_condition.status;
existing.last_transition_time = Time(Timestamp::now());
changed = true;
}

if existing.reason != new_condition.reason {
existing.reason = new_condition.reason;
changed = true;
}

if existing.message != new_condition.message {
existing.message = new_condition.message;
changed = true;
}

if existing.observed_generation != new_condition.observed_generation {
existing.observed_generation = new_condition.observed_generation;
changed = true;
}

changed
} else {
conditions_vec.push(new_condition);
true
}
}
Loading