-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ereport] intial types and dropshot API crate #7833
base: main
Are you sure you want to change the base?
Changes from all commits
ef473d4
451dd1e
2486745
e542817
992c6d4
0c2a0bc
e72858e
1c01fbd
683e983
f42577c
ab921b7
48e14ec
f75b9d4
3febae6
cb1d89c
b8f9d50
3c5eb13
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "ereporter-client" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[dependencies] | ||
chrono.workspace = true | ||
expectorate.workspace = true | ||
ereport-types.workspace = true | ||
http.workspace = true | ||
progenitor.workspace = true | ||
reqwest = { workspace = true, features = ["json", "rustls-tls", "stream"] } | ||
schemars.workspace = true | ||
serde.workspace = true | ||
serde_json.workspace = true | ||
slog.workspace = true | ||
omicron-uuid-kinds.workspace = true | ||
omicron-workspace-hack.workspace = true | ||
uuid.workspace = true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
progenitor::generate_api!( | ||
spec = "../../openapi/ereporter/ereporter-latest.json", | ||
inner_type = slog::Logger, | ||
derives = [schemars::JsonSchema, Clone, Eq, PartialEq], | ||
pre_hook = (|log: &slog::Logger, request: &reqwest::Request| { | ||
slog::debug!(log, "client request"; | ||
"method" => %request.method(), | ||
"uri" => %request.url(), | ||
"body" => ?&request.body(), | ||
); | ||
}), | ||
post_hook = (|log: &slog::Logger, result: &Result<_, _>| { | ||
slog::debug!(log, "client response"; "result" => ?result); | ||
}), | ||
replace = { | ||
Ena = ereport_types::Ena, | ||
TypedUuidForEreporterGenerationKind = omicron_uuid_kinds::EreporterGenerationUuid, | ||
} | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "ereporter-api" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[dependencies] | ||
ereport-types.workspace = true | ||
dropshot.workspace = true | ||
openapi-manager-types.workspace = true | ||
schemars.workspace = true | ||
semver.workspace = true | ||
serde.workspace = true | ||
serde_json.workspace = true | ||
thiserror.workspace = true | ||
uuid.workspace = true | ||
omicron-workspace-hack.workspace = true | ||
|
||
[lints] | ||
workspace = true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
//! HTTP API for ereport producers. | ||
|
||
use dropshot::HttpError; | ||
use dropshot::HttpResponseOk; | ||
use dropshot::Path; | ||
use dropshot::Query; | ||
use dropshot::RequestContext; | ||
use dropshot::ResultsPage; | ||
pub use ereport_types::Ena; | ||
pub use ereport_types::Ereport; | ||
pub use ereport_types::EreporterGenerationUuid; | ||
pub use ereport_types::Reporter; | ||
use openapi_manager_types::{ | ||
SupportedVersion, SupportedVersions, api_versions, | ||
}; | ||
use schemars::JsonSchema; | ||
use serde::Deserialize; | ||
use serde::Serialize; | ||
use std::num::NonZeroU32; | ||
use uuid::Uuid; | ||
|
||
api_versions!([ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First time I've actually seen this. Looks nice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i just followed the instructions from here --- shoutout to @davepacheco and @sunshowers for a very easy to follow guide! |
||
// WHEN CHANGING THE API (part 1 of 2): | ||
// | ||
// +- Pick a new semver and define it in the list below. The list MUST | ||
// | remain sorted, which generally means that your version should go at | ||
// | the very top. | ||
// | | ||
// | Duplicate this line, uncomment the *second* copy, update that copy for | ||
// | your new API version, and leave the first copy commented out as an | ||
// | example for the next person. | ||
// v | ||
// (next_int, IDENT), | ||
(1, INITIAL), | ||
]); | ||
|
||
// WHEN CHANGING THE API (part 2 of 2): | ||
// | ||
// The call to `api_versions!` above defines constants of type | ||
// `semver::Version` that you can use in your Dropshot API definition to specify | ||
// the version when a particular endpoint was added or removed. For example, if | ||
// you used: | ||
// | ||
// (2, ADD_FOOBAR) | ||
// | ||
// Then you could use `VERSION_ADD_FOOBAR` as the version in which endpoints | ||
// were added or removed. | ||
|
||
/// API for ereport producers. | ||
#[dropshot::api_description] | ||
pub trait EreporterApi { | ||
type Context; | ||
|
||
/// Collect a tranche of ereports from this reporter. | ||
#[endpoint { | ||
method = POST, | ||
path = "/ereports/{reporter_id}", | ||
}] | ||
async fn ereports_collect( | ||
rqctx: RequestContext<Self::Context>, | ||
path: Path<ReporterPath>, | ||
query: Query<EreportQuery>, | ||
) -> Result<HttpResponseOk<Ereports>, HttpError>; | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] | ||
pub struct ReporterPath { | ||
/// The UUID of the reporter from which to collct ereports. | ||
pub reporter_id: Uuid, | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] | ||
pub struct EreportQuery { | ||
/// The generation (restart nonce) of the reporter at which all other query | ||
/// parameters are valid. | ||
/// | ||
/// If this value does not match the reporter's current generation, the | ||
/// reporter's response will include the current generation, and will start | ||
/// at the earliest known ENA, rather than the provided `last_seen` ENA.` | ||
pub generation: EreporterGenerationUuid, | ||
|
||
/// If present, the reporter should not include ENAs earlier than this one | ||
/// in its response, provided that the query's requested generation matches | ||
/// the current generation. | ||
pub start_at: Option<Ena>, | ||
|
||
/// The ENA of the last ereport committed to persistent storage from the | ||
/// requested reporter generation. | ||
/// | ||
/// If the generation parameter matches the reporter's current generation, | ||
/// it is permitted to discard any ereports with ENAs up to and including | ||
/// this value. If the generation has changed from the provided generation, | ||
/// the reporter will not discard data. | ||
pub committed: Option<Ena>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a big fan of the "committed counter being overloaded in the normal request" pattern. Very raft like. |
||
|
||
/// Maximum number of ereports to return in this tranche. | ||
pub limit: NonZeroU32, | ||
} | ||
|
||
/// A tranche of ereports received from a reporter. | ||
hawkw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[derive(Debug, Serialize, Deserialize, JsonSchema)] | ||
pub struct Ereports { | ||
/// The reporter's current generation ID. | ||
/// | ||
/// If this is not equal to the current known generation, then the reporter | ||
/// has restarted. | ||
pub generation: EreporterGenerationUuid, | ||
/// The ereports in this tranche, and the ENA of the next page of ereports | ||
/// (if one exists).) | ||
#[serde(flatten)] | ||
pub reports: ResultsPage<Ereport>, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[package] | ||
name = "ereport-types" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[dependencies] | ||
omicron-uuid-kinds.workspace = true | ||
schemars.workspace = true | ||
serde.workspace = true | ||
serde_json.workspace = true | ||
uuid.workspace = true | ||
omicron-workspace-hack.workspace = true | ||
|
||
[lints] | ||
workspace = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: seems like it'd be nice to be consistent about
ereport
vs.ereporter
. Is there a reason they're different?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was perhaps due to me being unnecessarily cutesy with it. I was expecting to use stuff from the
-types
crate anywhere that we deal with ereports, including in the collector and eventually diagnosis engines, while the things that actually implement the APIs are reporters, thus "ereporter". I can change them to be consistent.