Skip to content

Commit 88e2031

Browse files
hawkwbnaecker
authored andcommitted
[fm] add a SitrepBuilder, to help with building sitreps (#9566)
Depends on #9552. This is [a surprise tool that will help us later][1]! [1]: https://www.youtube.com/watch?v=GTU84u_Logo
1 parent b91f7f1 commit 88e2031

9 files changed

Lines changed: 661 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ members = [
9393
"nexus/db-schema",
9494
"nexus/defaults",
9595
"nexus/external-api",
96+
"nexus/fm",
9697
"nexus/internal-api",
9798
"nexus/inventory",
9899
"nexus/lockstep-api",
@@ -271,6 +272,7 @@ default-members = [
271272
"nexus/db-schema",
272273
"nexus/defaults",
273274
"nexus/external-api",
275+
"nexus/fm",
274276
"nexus/internal-api",
275277
"nexus/inventory",
276278
"nexus/lockstep-api",
@@ -601,6 +603,7 @@ nexus-db-queries = { path = "nexus/db-queries" }
601603
nexus-db-schema = { path = "nexus/db-schema" }
602604
nexus-defaults = { path = "nexus/defaults" }
603605
nexus-external-api = { path = "nexus/external-api" }
606+
nexus-fm = { path = "nexus/fm" }
604607
nexus-inventory = { path = "nexus/inventory" }
605608
nexus-internal-api = { path = "nexus/internal-api" }
606609
nexus-lockstep-api = { path = "nexus/lockstep-api" }

nexus/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ hubtools.workspace = true
178178
hyper-rustls.workspace = true
179179
nexus-client.workspace = true
180180
nexus-db-queries = { workspace = true, features = ["testing"] }
181+
nexus-fm = { workspace = true, features = ["testing"] }
181182
nexus-lockstep-client.workspace = true
182183
nexus-test-utils.workspace = true
183184
nexus-test-utils-macros.workspace = true

nexus/fm/Cargo.toml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[package]
2+
name = "nexus-fm"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lints]
7+
workspace = true
8+
9+
[features]
10+
testing = [
11+
"omicron-test-utils",
12+
"nexus-reconfigurator-planning",
13+
"ereport-types",
14+
]
15+
16+
[dependencies]
17+
anyhow.workspace = true
18+
chrono.workspace = true
19+
iddqd.workspace = true
20+
nexus-types.workspace = true
21+
omicron-uuid-kinds.workspace = true
22+
rand.workspace = true
23+
serde.workspace = true
24+
serde_json.workspace = true
25+
slog.workspace = true
26+
slog-error-chain.workspace = true
27+
typed-rng.workspace = true
28+
29+
# deps for test utils
30+
omicron-test-utils = { workspace = true, optional = true }
31+
nexus-reconfigurator-planning = { workspace = true, optional = true }
32+
ereport-types = { workspace = true, optional = true }
33+
34+
omicron-workspace-hack.workspace = true
35+
36+
[dev-dependencies]
37+
omicron-test-utils.workspace = true
38+
nexus-reconfigurator-planning.workspace = true
39+
ereport-types.workspace = true

nexus/fm/src/builder.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
//! Sitrep builder
6+
7+
use nexus_types::fm;
8+
use nexus_types::inventory;
9+
use omicron_uuid_kinds::OmicronZoneUuid;
10+
use omicron_uuid_kinds::SitrepUuid;
11+
use slog::Logger;
12+
13+
mod case;
14+
pub use case::{AllCases, CaseBuilder};
15+
pub(crate) mod rng;
16+
pub use rng::SitrepBuilderRng;
17+
18+
#[derive(Debug)]
19+
pub struct SitrepBuilder<'a> {
20+
pub log: Logger,
21+
pub inventory: &'a inventory::Collection,
22+
pub parent_sitrep: Option<&'a fm::Sitrep>,
23+
pub sitrep_id: SitrepUuid,
24+
pub cases: case::AllCases,
25+
comment: String,
26+
}
27+
28+
impl<'a> SitrepBuilder<'a> {
29+
pub fn new(
30+
log: &Logger,
31+
inventory: &'a inventory::Collection,
32+
parent_sitrep: Option<&'a fm::Sitrep>,
33+
) -> Self {
34+
Self::new_with_rng(
35+
log,
36+
inventory,
37+
parent_sitrep,
38+
SitrepBuilderRng::from_entropy(),
39+
)
40+
}
41+
42+
pub fn new_with_rng(
43+
log: &Logger,
44+
inventory: &'a inventory::Collection,
45+
parent_sitrep: Option<&'a fm::Sitrep>,
46+
mut rng: SitrepBuilderRng,
47+
) -> Self {
48+
// TODO(eliza): should the RNG also be seeded with the parent sitrep
49+
// UUID and/or the Omicron zone UUID? Hmm.
50+
let sitrep_id = rng.sitrep_id();
51+
let log = log.new(slog::o!(
52+
"sitrep_id" => format!("{sitrep_id:?}"),
53+
"parent_sitrep_id" => format!("{:?}", parent_sitrep.as_ref().map(|s| s.id())),
54+
"inv_collection_id" => format!("{:?}", inventory.id),
55+
));
56+
57+
let cases =
58+
case::AllCases::new(log.clone(), sitrep_id, parent_sitrep, rng);
59+
60+
slog::info!(
61+
&log,
62+
"preparing sitrep {sitrep_id:?}";
63+
"existing_open_cases" => cases.len(),
64+
);
65+
66+
SitrepBuilder {
67+
log,
68+
sitrep_id,
69+
inventory,
70+
parent_sitrep,
71+
comment: String::new(),
72+
cases,
73+
}
74+
}
75+
76+
pub fn comment(&self) -> &str {
77+
&self.comment
78+
}
79+
80+
pub fn comment_mut(&mut self) -> &mut str {
81+
&mut self.comment
82+
}
83+
84+
pub fn build(
85+
self,
86+
creator_id: OmicronZoneUuid,
87+
time_created: chrono::DateTime<chrono::Utc>,
88+
) -> fm::Sitrep {
89+
fm::Sitrep {
90+
metadata: fm::SitrepMetadata {
91+
id: self.sitrep_id,
92+
parent_sitrep_id: self.parent_sitrep.map(|s| s.metadata.id),
93+
inv_collection_id: self.inventory.id,
94+
creator_id,
95+
comment: self.comment,
96+
time_created,
97+
},
98+
cases: self.cases.cases.into_iter().map(fm::Case::from).collect(),
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)