Skip to content

Commit 0785c8c

Browse files
committed
lots of case DB stuff
1 parent 9e3dda5 commit 0785c8c

File tree

14 files changed

+483
-13
lines changed

14 files changed

+483
-13
lines changed

ereport/types/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct Ereport {
3232
Serialize,
3333
Deserialize,
3434
JsonSchema,
35+
Hash,
3536
)]
3637
#[repr(transparent)]
3738
#[serde(from = "u64", into = "u64")]
@@ -103,7 +104,16 @@ impl TryFrom<i64> for Ena {
103104

104105
/// Unique identifier for an ereport.
105106
#[derive(
106-
Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord,
107+
Debug,
108+
Clone,
109+
Copy,
110+
PartialEq,
111+
Eq,
112+
Serialize,
113+
Deserialize,
114+
PartialOrd,
115+
Ord,
116+
Hash,
107117
)]
108118
pub struct EreportId {
109119
pub restart_id: EreporterRestartUuid,

nexus/db-model/src/alert_class.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use super::impl_enum_type;
66
use nexus_types::external_api::views;
7+
use omicron_common::api::external::Error;
78
use serde::de::{self, Deserialize, Deserializer};
89
use serde::ser::{Serialize, Serializer};
910
use std::fmt;
@@ -104,6 +105,22 @@ impl From<nexus_types::fm::AlertClass> for AlertClass {
104105
}
105106
}
106107

108+
impl TryFrom<AlertClass> for nexus_types::fm::AlertClass {
109+
type Error = Error;
110+
111+
fn try_from(input: AlertClass) -> Result<Self, Self::Error> {
112+
use nexus_types::fm::AlertClass as Out;
113+
match input {
114+
AlertClass::PsuRemoved => Ok(Out::PsuRemoved),
115+
AlertClass::PsuInserted => Ok(Out::PsuInserted),
116+
class => Err(Error::invalid_value(
117+
"alert_class",
118+
format!("'{class}' is not a FM alert class"),
119+
)),
120+
}
121+
}
122+
}
123+
107124
impl fmt::Display for AlertClass {
108125
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109126
write!(f, "{}", self.as_str())

nexus/db-model/src/fm.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ use chrono::{DateTime, Utc};
1919
use nexus_db_schema::schema::{fm_sitrep, fm_sitrep_history};
2020
use omicron_uuid_kinds::{CollectionKind, OmicronZoneKind, SitrepKind};
2121

22+
mod alert_request;
23+
pub use alert_request::*;
24+
mod case;
25+
pub use case::*;
26+
mod diagnosis_engine;
27+
pub use diagnosis_engine::*;
28+
2229
#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
2330
#[diesel(table_name = fm_sitrep)]
2431
pub struct SitrepMetadata {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
//! Fault management alert requests.
6+
7+
use crate::AlertClass;
8+
use crate::DbTypedUuid;
9+
use nexus_db_schema::schema::fm_alert_request;
10+
use nexus_types::fm;
11+
use omicron_uuid_kinds::{
12+
AlertKind, CaseKind, CaseUuid, SitrepKind, SitrepUuid,
13+
};
14+
15+
#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
16+
#[diesel(table_name = fm_alert_request)]
17+
pub struct AlertRequest {
18+
pub id: DbTypedUuid<AlertKind>,
19+
pub sitrep_id: DbTypedUuid<SitrepKind>,
20+
pub requested_sitrep_id: DbTypedUuid<SitrepKind>,
21+
pub case_id: DbTypedUuid<CaseKind>,
22+
#[diesel(column_name = "class")]
23+
pub class: AlertClass,
24+
pub payload: serde_json::Value,
25+
}
26+
27+
impl AlertRequest {
28+
pub fn new(
29+
current_sitrep_id: SitrepUuid,
30+
case_id: CaseUuid,
31+
req: fm::AlertRequest,
32+
) -> Self {
33+
let fm::AlertRequest { id, requested_sitrep_id, payload, class } = req;
34+
AlertRequest {
35+
id: id.into(),
36+
sitrep_id: current_sitrep_id.into(),
37+
requested_sitrep_id: requested_sitrep_id.into(),
38+
case_id: case_id.into(),
39+
class: class.into(),
40+
payload,
41+
}
42+
}
43+
}
44+
45+
impl TryFrom<AlertRequest> for fm::AlertRequest {
46+
type Error = <fm::AlertClass as TryFrom<AlertClass>>::Error;
47+
fn try_from(req: AlertRequest) -> Result<Self, Self::Error> {
48+
Ok(fm::AlertRequest {
49+
id: req.id.into(),
50+
requested_sitrep_id: req.requested_sitrep_id.into(),
51+
payload: req.payload,
52+
class: req.class.try_into()?,
53+
})
54+
}
55+
}

nexus/db-model/src/fm/case.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
//! Fault management cases.
6+
7+
use super::DiagnosisEngine;
8+
use crate::DbTypedUuid;
9+
use crate::ereport;
10+
use chrono::{DateTime, Utc};
11+
use nexus_db_schema::schema::{fm_case, fm_ereport_in_case};
12+
use omicron_uuid_kinds::{CaseKind, EreporterRestartKind, SitrepKind};
13+
14+
#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
15+
#[diesel(table_name = fm_case)]
16+
pub struct CaseMetadata {
17+
pub id: DbTypedUuid<CaseKind>,
18+
pub sitrep_id: DbTypedUuid<SitrepKind>,
19+
pub de: DiagnosisEngine,
20+
21+
pub created_sitrep_id: DbTypedUuid<SitrepKind>,
22+
pub time_created: DateTime<Utc>,
23+
24+
pub time_closed: Option<DateTime<Utc>>,
25+
pub closed_sitrep_id: Option<DbTypedUuid<SitrepKind>>,
26+
27+
pub comment: String,
28+
}
29+
30+
#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
31+
#[diesel(table_name = fm_ereport_in_case)]
32+
pub struct CaseEreport {
33+
pub restart_id: DbTypedUuid<EreporterRestartKind>,
34+
pub ena: ereport::DbEna,
35+
pub case_id: DbTypedUuid<CaseKind>,
36+
pub sitrep_id: DbTypedUuid<SitrepKind>,
37+
pub assigned_sitrep_id: DbTypedUuid<SitrepKind>,
38+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
use crate::impl_enum_type;
6+
use nexus_types::fm;
7+
use serde::{Deserialize, Serialize};
8+
use std::fmt;
9+
10+
impl_enum_type!(
11+
DiagnosisEngineEnum:
12+
13+
#[derive(
14+
Copy,
15+
Clone,
16+
Debug,
17+
PartialEq,
18+
Serialize,
19+
Deserialize,
20+
AsExpression,
21+
FromSqlRow,
22+
)]
23+
#[serde(rename_all = "snake_case")]
24+
pub enum DiagnosisEngine;
25+
26+
PowerShelf => b"power_shelf"
27+
28+
);
29+
30+
impl From<DiagnosisEngine> for fm::DiagnosisEngine {
31+
fn from(de: DiagnosisEngine) -> Self {
32+
match de {
33+
DiagnosisEngine::PowerShelf => fm::DiagnosisEngine::PowerShelf,
34+
}
35+
}
36+
}
37+
38+
impl From<fm::DiagnosisEngine> for DiagnosisEngine {
39+
fn from(fm_de: fm::DiagnosisEngine) -> Self {
40+
match fm_de {
41+
fm::DiagnosisEngine::PowerShelf => DiagnosisEngine::PowerShelf,
42+
}
43+
}
44+
}
45+
46+
impl fmt::Display for DiagnosisEngine {
47+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48+
fm::DiagnosisEngine::from(*self).fmt(f)
49+
}
50+
}

nexus/db-model/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ mod downstairs;
4141
pub mod ereport;
4242
mod ereporter_type;
4343
mod external_ip;
44-
mod fm;
44+
pub mod fm;
4545
mod generation;
4646
mod identity_provider;
4747
mod image;
@@ -187,7 +187,7 @@ pub use downstairs::*;
187187
pub use ereport::Ereport;
188188
pub use ereporter_type::*;
189189
pub use external_ip::*;
190-
pub use fm::*;
190+
pub use fm::{SitrepMetadata, SitrepVersion};
191191
pub use generation::*;
192192
pub use identity_provider::*;
193193
pub use image::*;

nexus/db-queries/src/db/datastore/ereport.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ impl DataStore {
9898
) -> LookupResult<Ereport> {
9999
opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?;
100100
let conn = self.pool_connection_authorized(opctx).await?;
101+
self.ereport_fetch_on_conn(&conn, id).await
102+
}
103+
104+
pub(crate) async fn ereport_fetch_on_conn(
105+
&self,
106+
conn: &async_bb8_diesel::Connection<DbConnection>,
107+
id: fm::EreportId,
108+
) -> LookupResult<Ereport> {
101109
let restart_id = id.restart_id.into_untyped_uuid();
102110
let ena = DbEna::from(id.ena);
103111

@@ -106,7 +114,7 @@ impl DataStore {
106114
.filter(dsl::ena.eq(ena))
107115
.filter(dsl::time_deleted.is_null())
108116
.select(Ereport::as_select())
109-
.first_async(&*conn)
117+
.first_async(conn)
110118
.await
111119
.optional()
112120
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?

0 commit comments

Comments
 (0)