Skip to content
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

[nexus] add support for ingesting TUF repos #4690

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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
42 changes: 39 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ members = [
"test-utils",
"tufaceous-lib",
"tufaceous",
"update-common",
"update-engine",
"wicket-common",
"wicket-dbg",
Expand Down Expand Up @@ -130,6 +131,7 @@ default-members = [
"test-utils",
"tufaceous-lib",
"tufaceous",
"update-common",
"update-engine",
"wicket-common",
"wicket-dbg",
Expand Down Expand Up @@ -290,6 +292,7 @@ postgres-protocol = "0.6.6"
predicates = "3.0.4"
pretty_assertions = "1.4.0"
pretty-hex = "0.4.0"
prettyplease = "0.2.15"
proc-macro2 = "1.0"
progenitor = { git = "https://github.com/oxidecomputer/progenitor", branch = "main" }
progenitor-client = { git = "https://github.com/oxidecomputer/progenitor", branch = "main" }
Expand Down Expand Up @@ -385,6 +388,7 @@ trybuild = "1.0.85"
tufaceous = { path = "tufaceous" }
tufaceous-lib = { path = "tufaceous-lib" }
unicode-width = "0.1.11"
update-common = { path = "update-common" }
update-engine = { path = "update-engine" }
usdt = "0.3"
uuid = { version = "1.6.1", features = ["serde", "v4"] }
Expand Down
83 changes: 82 additions & 1 deletion common/src/api/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use dropshot::HttpError;
pub use error::*;

pub use crate::api::internal::shared::SwitchLocation;
use crate::update::ArtifactHash;
use crate::update::ArtifactId;
use anyhow::anyhow;
use anyhow::Context;
use api_identity::ObjectIdentity;
Expand Down Expand Up @@ -739,7 +741,8 @@ pub enum ResourceType {
Oximeter,
MetricProducer,
RoleBuiltin,
UpdateArtifact,
TufRepo,
TufArtifact,
SwitchPort,
SystemUpdate,
ComponentUpdate,
Expand Down Expand Up @@ -2604,6 +2607,84 @@ pub struct BgpImportedRouteIpv4 {
pub switch: SwitchLocation,
}

/// A description of an uploaded TUF repository.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct TufRepoDescription {
// Information about the repository.
pub repo: TufRepoMeta,

// Information about the artifacts present in the repository.
pub artifacts: Vec<TufArtifactMeta>,
}

/// Metadata about a TUF repository.
///
/// Found within a [`TufRepoDescription`].
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct TufRepoMeta {
/// The hash of the repository.
///
/// This is a slight abuse of `ArtifactHash`, since that's the hash of
/// individual artifacts within the repository. However, we use it here for
/// convenience.
pub hash: ArtifactHash,

/// The version of the targets role.
pub targets_role_version: u64,

/// The time until which the repo is valid.
pub valid_until: DateTime<Utc>,

/// The system version in artifacts.json.
pub system_version: SemverVersion,

/// The file name of the repository.
///
/// This is purely used for debugging and may not always be correct (e.g.
/// with wicket, we read the file contents from stdin so we don't know the
/// correct file name).
pub file_name: String,
}

/// Metadata about an individual TUF artifact.
///
/// Found within a [`TufRepoDescription`].
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct TufArtifactMeta {
/// The artifact ID.
pub id: ArtifactId,

/// The hash of the artifact.
pub hash: ArtifactHash,

/// The size of the artifact in bytes.
pub size: u64,
}

/// Data about a successful TUF repo import into Nexus.
#[derive(Debug, Clone, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct TufRepoInsertResponse {
/// The repository as present in the database.
pub recorded: TufRepoDescription,

/// Whether this repository already existed or is new.
pub status: TufRepoInsertStatus,
}

/// Status of a TUF repo import.
///
/// Part of [`TufRepoInsertResponse`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum TufRepoInsertStatus {
/// The repository already existed in the database.
AlreadyExists,

/// The repository did not exist, and was inserted into the database.
Inserted,
}

#[cfg(test)]
mod test {
use serde::Deserialize;
Expand Down
7 changes: 7 additions & 0 deletions common/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ pub struct ArtifactId {
pub kind: ArtifactKind,
}

/// Used for user-friendly messages.
impl fmt::Display for ArtifactId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} v{} ({})", self.name, self.version, self.kind)
}
}

/// A hash-based identifier for an artifact.
///
/// Some places, e.g. the installinator, request artifacts by hash rather than
Expand Down
3 changes: 3 additions & 0 deletions nexus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ assert_matches.workspace = true
async-trait.workspace = true
base64.workspace = true
buf-list.workspace = true
bytes.workspace = true
cancel-safe-futures.workspace = true
camino.workspace = true
camino-tempfile.workspace = true
clap.workspace = true
chrono.workspace = true
crucible-agent-client.workspace = true
Expand Down Expand Up @@ -85,6 +87,7 @@ oximeter.workspace = true
oximeter-instruments = { workspace = true, features = ["http-instruments"] }
oximeter-producer.workspace = true
rustls = { workspace = true }
update-common.workspace = true
omicron-workspace-hack.workspace = true

[dev-dependencies]
Expand Down
3 changes: 3 additions & 0 deletions nexus/authz-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ serde.workspace = true
serde_tokenstream.workspace = true
syn.workspace = true
omicron-workspace-hack.workspace = true

[dev-dependencies]
prettyplease.workspace = true
Loading