Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
150 changes: 150 additions & 0 deletions Cargo.lock

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

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"crates/core",
"crates/crypto",
"crates/telemetry",
"crates/traffic",
"crates/plugin-api",
"crates/plugin",
"crates/server",
Expand Down Expand Up @@ -192,6 +193,14 @@ jsonwebtoken = { version = "11", default-features = false, features = ["use_pem"
# already links, used directly where `jsonwebtoken` has no key generation.
aws-lc-rs = { version = "1.18" }

# Traffic statistics (crates/traffic): Parquet files in the object store.
# Without the Arrow layer (its record API suffices) and with Snappy alone, a
# pure-Rust codec.
parquet = { version = "60", default-features = false, features = ["snap"] }
parquet_derive = { version = "60" }
# Country and ASN lookups in MaxMind databases (crates/traffic).
maxminddb = { version = "0.32" }

# Temp files
tempfile = { version = "3" }

Expand Down
13 changes: 11 additions & 2 deletions crates/db/src/secret_dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
//! [`insert_realm_with_secrets`] / [`realm_config`]).
//!
//! Secrets kept in `forge_setting` ([`SECRET_SETTINGS`]: the generated
//! registry-token key, the OIDC issuer keys) are text values,
//! registry-token key, the OIDC issuer keys, the MaxMind license key) are
//! text values,
//! `sealed:<base64 envelope>`, AAD-bound to `('forge_setting', 'value', 0)`
//! plus the setting's key. They take part in the re-encrypt sweep and the DEK
//! reference scan like the secret columns ([`store_secret_setting`],
Expand Down Expand Up @@ -1073,8 +1074,16 @@ pub const REGISTRY_TOKEN_KEY_SETTING: &str = "docker_token_key";
/// assertions with.
pub const OIDC_ISSUER_KEYS_SETTING: &str = "oidc_issuer_keys";

/// `forge_setting` key of the MaxMind license key the traffic statistics'
/// geolocation databases are downloaded with.
pub const MAXMIND_LICENSE_KEY_SETTING: &str = "traffic_maxmind_license_key";

/// The `forge_setting` keys whose values are secrets (module docs).
pub const SECRET_SETTINGS: &[&str] = &[REGISTRY_TOKEN_KEY_SETTING, OIDC_ISSUER_KEYS_SETTING];
pub const SECRET_SETTINGS: &[&str] = &[
REGISTRY_TOKEN_KEY_SETTING,
OIDC_ISSUER_KEYS_SETTING,
MAXMIND_LICENSE_KEY_SETTING,
];

/// Prefix of a sealed secret setting: `sealed:<base64 envelope>`.
const SEALED_SETTING: &str = "sealed:";
Expand Down
6 changes: 6 additions & 0 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ forge-core = { path = "../core" }
forge-crypto = { path = "../crypto" }
forge-plugin = { path = "../plugin" }
forge-telemetry = { path = "../telemetry" }
forge-traffic = { path = "../traffic" }
# The built-in format plugins (crates/formats/docker, crates/formats/nuget,
# crates/formats/npm, crates/formats/raw), linked in.
forge-format-docker = { path = "../formats/docker" }
Expand Down Expand Up @@ -79,6 +80,8 @@ tokio-util = { workspace = true }
multer = "3"
# npm audits: a gzip-compressed request body.
flate2 = { version = "1.1", default-features = false, features = ["zlib-rs"] }
# The MaxMind databases of the traffic statistics come as `.tar.gz`.
tar = { version = "0.4", default-features = false }
# The file store: the MD5 of uploads (the `.md5` sidecar), file names in
# headers, HTTP dates (`Last-Modified`, `If-Modified-Since`) and content
# types guessed from file names.
Expand Down Expand Up @@ -110,6 +113,9 @@ figment = { version = "0.10", features = ["toml", "env"] }
tikv-jemallocator = { version = "0.7", features = ["background_threads"] }

[dev-dependencies]
# Small MaxMind databases for the traffic statistics' tests.
forge-traffic = { path = "../traffic", features = ["testing"] }
tar = { version = "0.4", default-features = false }
# Builds Helm chart archives for the registry tests.
flate2 = { version = "1.1", default-features = false, features = ["zlib-rs"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "fs", "io-util", "time", "test-util"] }
Expand Down
17 changes: 17 additions & 0 deletions crates/server/src/admin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub mod roles;
pub mod settings;
pub mod token_scope;
pub mod tokens;
pub mod traffic;
pub mod trusted_publishers;
pub mod user_roles;
pub mod users;
Expand Down Expand Up @@ -351,6 +352,22 @@ pub fn admin_router(state: AppState) -> Router<AppState> {
.route("/crypto/keys", get(crypto::list_keys))
// --- local blob cache ----------------------------------------------
.route("/blob-cache", get(blob_cache::stats))
// --- traffic statistics --------------------------------------------
.route("/traffic", get(traffic::overview))
.route(
"/traffic/geoip",
get(traffic::get_geoip)
.put(traffic::put_geoip)
.delete(traffic::delete_geoip),
)
.route(
"/traffic/geoip/update",
axum::routing::post(traffic::update_geoip),
)
.route(
"/settings/traffic",
get(traffic::get_settings).put(traffic::put_settings),
)
// --- the email service ---------------------------------------------
.route(
"/settings/email",
Expand Down
Loading
Loading