Skip to content

Commit 356815d

Browse files
authored
Merge pull request #238 from Jakob-Naucke/transition-time
Update transition time only on new status
2 parents 1e57bb7 + e46b3ad commit 356815d

6 files changed

Lines changed: 92 additions & 28 deletions

File tree

compute-pcrs/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ async fn main() -> Result<()> {
7474

7575
let approved_images: Api<ApprovedImage> = Api::default_namespaced(client);
7676
let image = approved_images.get(&args.resource_name).await?;
77-
let committed = committed_condition(INSTALLED_REASON, image.metadata.generation);
77+
let committed = committed_condition(INSTALLED_REASON, image.metadata.generation, &None);
7878
let conditions = Some(vec![committed]);
7979
let status = ApprovedImageStatus { conditions };
8080
update_status!(approved_images, &args.resource_name, status)?;

lib/src/lib.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,50 @@ pub fn condition_status(status: bool) -> String {
4040
}
4141
}
4242

43-
pub fn committed_condition(reason: &str, generation: Option<i64>) -> Condition {
43+
pub trait Conditions {
44+
fn conditions(&self) -> &Option<Vec<Condition>>;
45+
}
46+
47+
impl Conditions for TrustedExecutionClusterStatus {
48+
fn conditions(&self) -> &Option<Vec<Condition>> {
49+
&self.conditions
50+
}
51+
}
52+
53+
impl Conditions for AttestationKeyStatus {
54+
fn conditions(&self) -> &Option<Vec<Condition>> {
55+
&self.conditions
56+
}
57+
}
58+
59+
impl Conditions for ApprovedImageStatus {
60+
fn conditions(&self) -> &Option<Vec<Condition>> {
61+
&self.conditions
62+
}
63+
}
64+
65+
pub fn transition_time<S: Conditions>(
66+
existing_status: &Option<S>,
67+
type_: &str,
68+
new_status: &str,
69+
) -> Time {
70+
let get = |s: &S| s.conditions().clone();
71+
let conditions = existing_status.as_ref().and_then(get);
72+
let find = |c: &Condition| type_ == c.type_ && new_status == c.status;
73+
let existing = conditions.and_then(|cs| cs.into_iter().find(find));
74+
let time = existing.map(|c| c.last_transition_time);
75+
time.unwrap_or(Time(Timestamp::now()))
76+
}
77+
78+
pub fn committed_condition(
79+
reason: &str,
80+
generation: Option<i64>,
81+
existing_status: &Option<ApprovedImageStatus>,
82+
) -> Condition {
83+
let status = condition_status(reason == COMMITTED_REASON);
84+
let type_ = COMMITTED_CONDITION;
4485
Condition {
45-
type_: COMMITTED_CONDITION.to_string(),
46-
status: condition_status(reason == COMMITTED_REASON),
86+
type_: type_.to_string(),
4787
reason: reason.to_string(),
4888
message: match reason {
4989
NOT_COMMITTED_REASON_COMPUTING => "Computation is ongoing. Check jobs for progress.",
@@ -55,7 +95,8 @@ pub fn committed_condition(reason: &str, generation: Option<i64>) -> Condition {
5595
_ => "",
5696
}
5797
.to_string(),
58-
last_transition_time: Time(Timestamp::now()),
98+
last_transition_time: transition_time(existing_status, type_, &status),
99+
status,
59100
observed_generation: generation,
60101
}
61102
}

operator/src/attestation_key_register.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ async fn approve_ak(ak: &AttestationKey, machine: &Machine, client: Client) -> R
204204

205205
if !is_approved {
206206
let generation = ak.metadata.generation;
207-
let condition =
208-
attestation_key_approved_condition(ATTESTATION_KEY_MACHINE_APPROVE, generation);
207+
let approve_reason = ATTESTATION_KEY_MACHINE_APPROVE;
208+
let condition = attestation_key_approved_condition(approve_reason, generation, &ak.status);
209209
let mut conditions = ak
210210
.status
211211
.as_ref()

operator/src/conditions.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,42 @@
22
//
33
// SPDX-License-Identifier: MIT
44

5-
use k8s_openapi::apimachinery::pkg::apis::meta::v1::{Condition, Time};
6-
use k8s_openapi::jiff::Timestamp;
7-
use trusted_cluster_operator_lib::{condition_status, conditions::*};
5+
use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition;
6+
use trusted_cluster_operator_lib::{AttestationKeyStatus, TrustedExecutionClusterStatus};
7+
use trusted_cluster_operator_lib::{condition_status, conditions::*, transition_time};
88

9-
pub fn known_trustee_address_condition(known: bool, generation: Option<i64>) -> Condition {
9+
pub fn known_trustee_address_condition(
10+
known: bool,
11+
generation: Option<i64>,
12+
existing_status: &Option<TrustedExecutionClusterStatus>,
13+
) -> Condition {
1014
let err = "No publicTrusteeAddr specified. Components can deploy, \
1115
but register-server will not be able to point to Trustee until you add an address";
1216
let (reason, message) = match known {
1317
true => (KNOWN_TRUSTEE_ADDRESS_REASON, ""),
1418
false => (UNKNOWN_TRUSTEE_ADDRESS_REASON, err),
1519
};
20+
let type_ = KNOWN_TRUSTEE_ADDRESS_CONDITION;
21+
let status = condition_status(known);
1622
Condition {
17-
type_: KNOWN_TRUSTEE_ADDRESS_CONDITION.to_string(),
18-
status: condition_status(known),
23+
type_: type_.to_string(),
1924
reason: reason.to_string(),
2025
message: message.to_string(),
21-
last_transition_time: Time(Timestamp::now()),
26+
last_transition_time: transition_time(existing_status, type_, &status),
27+
status,
2228
observed_generation: generation,
2329
}
2430
}
2531

26-
pub fn installed_condition(reason: &str, generation: Option<i64>) -> Condition {
32+
pub fn installed_condition(
33+
reason: &str,
34+
generation: Option<i64>,
35+
existing_status: &Option<TrustedExecutionClusterStatus>,
36+
) -> Condition {
37+
let status = condition_status(reason == INSTALLED_REASON);
38+
let type_ = INSTALLED_CONDITION;
2739
Condition {
28-
type_: INSTALLED_CONDITION.to_string(),
29-
status: condition_status(reason == INSTALLED_REASON),
40+
type_: type_.to_string(),
3041
reason: reason.to_string(),
3142
message: match reason {
3243
NOT_INSTALLED_REASON_NON_UNIQUE => {
@@ -38,15 +49,21 @@ pub fn installed_condition(reason: &str, generation: Option<i64>) -> Condition {
3849
_ => "",
3950
}
4051
.to_string(),
41-
last_transition_time: Time(Timestamp::now()),
52+
last_transition_time: transition_time(existing_status, type_, &status),
53+
status,
4254
observed_generation: generation,
4355
}
4456
}
4557

46-
pub fn attestation_key_approved_condition(reason: &str, generation: Option<i64>) -> Condition {
58+
pub fn attestation_key_approved_condition(
59+
reason: &str,
60+
generation: Option<i64>,
61+
existing_status: &Option<AttestationKeyStatus>,
62+
) -> Condition {
63+
let status = condition_status(reason == ATTESTATION_KEY_MACHINE_APPROVE);
64+
let type_ = ATTESTATION_KEY_APPROVED_CONDITION;
4765
Condition {
48-
type_: ATTESTATION_KEY_APPROVED_CONDITION.to_string(),
49-
status: condition_status(reason == ATTESTATION_KEY_MACHINE_APPROVE),
66+
type_: type_.to_string(),
5067
reason: reason.to_string(),
5168
message: match reason {
5269
ATTESTATION_KEY_MACHINE_APPROVE => {
@@ -55,7 +72,8 @@ pub fn attestation_key_approved_condition(reason: &str, generation: Option<i64>)
5572
_ => "",
5673
}
5774
.to_string(),
58-
last_transition_time: Time(Timestamp::now()),
75+
last_transition_time: transition_time(existing_status, type_, &status),
76+
status,
5977
observed_generation: generation,
6078
}
6179
}

operator/src/main.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ async fn reconcile(
104104
) -> Result<Action, ControllerError> {
105105
let generation = cluster.metadata.generation;
106106
let known_address = cluster.spec.public_trustee_addr.is_some();
107-
let address_condition = known_trustee_address_condition(known_address, generation);
107+
let existing_status = &cluster.status;
108+
let address_condition =
109+
known_trustee_address_condition(known_address, generation, existing_status);
108110
let mut conditions = Some(vec![address_condition]);
109111

110112
let kube_client = ctx.client.clone();
@@ -114,7 +116,8 @@ async fn reconcile(
114116

115117
if cluster.metadata.deletion_timestamp.is_some() {
116118
info!("Registered deletion of TrustedExecutionCluster {name}");
117-
let condition = installed_condition(NOT_INSTALLED_REASON_UNINSTALLING, generation);
119+
let uninstalling_reason = NOT_INSTALLED_REASON_UNINSTALLING;
120+
let condition = installed_condition(uninstalling_reason, generation, existing_status);
118121
conditions.as_mut().unwrap().push(condition);
119122
update_status!(clusters, name, TrustedExecutionClusterStatus { conditions })?;
120123
return Ok(Action::await_change());
@@ -134,15 +137,17 @@ async fn reconcile(
134137
"More than one TrustedExecutionCluster found in namespace {namespace}. \
135138
trusted-cluster-operator does not support more than one TrustedExecutionCluster. Requeueing...",
136139
);
137-
let condition = installed_condition(NOT_INSTALLED_REASON_NON_UNIQUE, generation);
140+
let condition =
141+
installed_condition(NOT_INSTALLED_REASON_NON_UNIQUE, generation, existing_status);
138142
conditions.as_mut().unwrap().push(condition);
139143
update_status!(clusters, name, TrustedExecutionClusterStatus { conditions })?;
140144
return Ok(Action::requeue(Duration::from_secs(60)));
141145
}
142146

143147
info!("Setting up TrustedExecutionCluster {name}");
144148
let mut installing = conditions.clone();
145-
let condition = installed_condition(NOT_INSTALLED_REASON_INSTALLING, generation);
149+
let installing_reason = NOT_INSTALLED_REASON_INSTALLING;
150+
let condition = installed_condition(installing_reason, generation, existing_status);
146151
installing.as_mut().unwrap().push(condition);
147152
let status = TrustedExecutionClusterStatus {
148153
conditions: installing,
@@ -152,7 +157,7 @@ async fn reconcile(
152157
install_trustee_configuration(kube_client.clone(), &cluster).await?;
153158
install_register_server(kube_client.clone(), &cluster).await?;
154159
install_attestation_key_register(kube_client, &cluster).await?;
155-
let condition = installed_condition(INSTALLED_REASON, generation);
160+
let condition = installed_condition(INSTALLED_REASON, generation, existing_status);
156161
conditions.as_mut().unwrap().push(condition);
157162
update_status!(clusters, name, TrustedExecutionClusterStatus { conditions })?;
158163
Ok(Action::await_change())

operator/src/reference_values.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ async fn image_add_reconcile(
299299
(action, NOT_COMMITTED_REASON_FAILED)
300300
}
301301
};
302-
let committed = committed_condition(reason, image.metadata.generation);
302+
let committed = committed_condition(reason, image.metadata.generation, &image.status);
303303
let conditions = Some(vec![committed]);
304304
let images: Api<ApprovedImage> = Api::default_namespaced(kube_client);
305305
update_status!(images, &name, ApprovedImageStatus { conditions })

0 commit comments

Comments
 (0)