agent/lib/src/lib.rs
//! Agent crate: the airgap courier that moves artifacts across the network
//! boundary. This is the public facade — the actual work lives in
//! [`operations`], and every endpoint is a [`ConnectorTrait`] (Nexus,
//! Artifactory, crates.io/PyPI `world`; holger/znippy/directory live server-side).
//!
//! Flow: a Source connector's assets are pulled through `operations` into a
//! carriable sink — a `.znippy` archive, a `.tar.zst`, or a loose directory —
//! then, on the secure side, pushed from that sink back into a Target connector.
//! Download/pack and read/upload are the two halves; the archive in between is
//! the thing that crosses the airgap.
//!
//! Gotcha: an upload failure is *data*, not an error — one bad asset is counted
//! and skipped so a whole push does not abort, whereas a source read/decode
//! error short-circuits. So a successful return can still hide failed assets;
//! check the tallies. Untrusted `.tar.zst` input is per-entry size-capped
//! against decompression bombs.
// Upstream credentials for a continuous mirror: named in RON as a vault
// reference, read once at boot from `nornir-vault`, held in memory for the
// process lifetime. Gated on `online` exactly like the connectors it feeds —
// the airgap tiers have no upstream and therefore link no vault.
#[cfg(feature = "online")]
pub mod creds;
/// **MIGRATE** — the ONE-TIME move of an existing Nexus / Artifactory registry
/// into holger, in a single pass. The plan and the refusals live in
/// `traits::migrate`; this is the runner and the `ConnectorTrait`-backed sink.
/// Distinct from `operations` on purpose: that is the AIRGAP courier, where the
/// archive between the two ends is the thing a human carries.
pub mod migrate;
pub mod operations;
pub mod strict;
#[cfg(feature = "online")]
pub use creds::{
provider_for, Credential, CredentialRef, CredentialStore, CredentialSummary, CredsError,
RepositoryCredential, UpstreamCredsConfig, VaultProvider, REGISTRY_CREDS_LABEL,
};
pub use strict::{
transfer_assets_to_znippy_with_options, transfer_repo_to_znippy_with_options, AssetRecord,
TransferFailure, TransferMode, TransferOptions, TransferReceipt, TransferReport,
};
// The network connectors are the reqwest carriers — re-exported ONLY when the
// `online` feature is on (see Cargo.toml). An offline (`--no-default-features`)
// build links none of them, so an offline agent binary is provably zero-egress;
// the generic `operations` / `strict` transfer engine below stays available in
// both builds because it works over the `traits::ConnectorTrait` seam.
#[cfg(feature = "online")]
pub use connector_artifactory::ArtifactoryConnector;
#[cfg(feature = "online")]
pub use connector_nexus::{fetch_oidc_token, ConnectorAuth, NexusConnector};
#[cfg(feature = "online")]
pub use connector_world::{
packages_to_assets, parse_lockfile, parse_requirements_txt, parse_uv_lockfile,
pip_packages_to_assets, resolve_with_index, PipError, PipFile, PipPackage, PypiJsonClient,
WorldConnector,
};
pub use migrate::{
discover, run_migration, AssetOutcome, ConnectorSink, MigrationOptions, MigrationProgress,
MigrationReport, DEFAULT_MIGRATION_CONCURRENCY,
};
pub use traits::migrate::{Disposition, MigrationPlan, MigrationSink, RepoPlan};
pub use traits::{ConnectorTrait, RemoteAsset, RemoteRepository};