provisioning-platform/crates/catalog-registry/src/client/traits.rs

135 lines
4.1 KiB
Rust

//! Client trait hierarchy for extension sources and distributions
//!
//! Defines three-tier trait system:
//! - `ExtensionClient`: Base trait for all backends
//! - `SourceClient`: Git-based repository sources (Gitea, Forgejo, GitHub)
//! - `DistributionClient`: OCI-compatible registries (Harbor, Docker Hub, etc.)
use async_trait::async_trait;
use bytes::Bytes;
use crate::error::Result;
use crate::models::{Extension, ExtensionType, ExtensionVersion};
/// Backend type identifier
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BackendType {
Gitea,
Forgejo,
GitHub,
Oci,
}
/// Base trait for all extension clients
///
/// Common operations that all backends must support, regardless of whether
/// they're source (Git) or distribution (OCI) backends.
#[async_trait]
pub trait ExtensionClient: Send + Sync {
/// Get unique backend identifier for this instance
fn backend_id(&self) -> &str;
/// Get backend type
fn backend_type(&self) -> BackendType;
/// List all extensions available from this backend
async fn list_extensions(
&self,
extension_type: Option<ExtensionType>,
) -> Result<Vec<Extension>>;
/// Get specific extension metadata
async fn get_extension(&self, extension_type: ExtensionType, name: &str) -> Result<Extension>;
/// List all versions for an extension
async fn list_versions(
&self,
extension_type: ExtensionType,
name: &str,
) -> Result<Vec<ExtensionVersion>>;
/// Download extension artifact
async fn download_extension(
&self,
extension_type: ExtensionType,
name: &str,
version: &str,
) -> Result<Bytes>;
/// Check backend health
async fn health_check(&self) -> Result<()>;
}
/// Source client trait for Git-based backends
///
/// Extends `ExtensionClient` with operations specific to Git repository sources
/// like Gitea, Forgejo, and GitHub. These backends treat extensions as releases
/// in repositories.
#[async_trait]
pub trait SourceClient: ExtensionClient {
/// Get repository URL for an extension
async fn get_repository_url(&self, extension_type: ExtensionType, name: &str)
-> Result<String>;
/// List all releases for a repository
///
/// Returns release info including tags, assets, and creation times
async fn list_releases(&self, repo_name: &str) -> Result<Vec<ReleaseInfo>>;
/// Get release notes/description for a specific version
async fn get_release_notes(&self, repo_name: &str, version: &str) -> Result<String>;
}
/// Distribution client trait for OCI registries
///
/// Extends `ExtensionClient` with operations specific to OCI registries
/// like Docker Hub, Harbor, Quay, and ghcr.io. These backends treat extensions
/// as container images or artifacts with OCI manifests.
#[async_trait]
pub trait DistributionClient: ExtensionClient {
/// Get manifest for an artifact
async fn get_manifest(&self, repo_name: &str, tag: &str) -> Result<ManifestInfo>;
/// List all catalogs/repositories in the registry
async fn list_catalog(&self) -> Result<Vec<String>>;
/// Get digest for an artifact
async fn get_digest(&self, repo_name: &str, tag: &str) -> Result<String>;
/// Verify artifact integrity
async fn verify_artifact(&self, repo_name: &str, tag: &str, digest: &str) -> Result<bool>;
}
/// Release information from source backends
#[derive(Debug, Clone)]
pub struct ReleaseInfo {
pub tag: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub published_at: Option<chrono::DateTime<chrono::Utc>>,
pub assets: Vec<ReleaseAsset>,
pub description: String,
}
/// Asset attached to a release
#[derive(Debug, Clone)]
pub struct ReleaseAsset {
pub name: String,
pub download_url: String,
pub size: Option<u64>,
}
/// OCI manifest information
#[derive(Debug, Clone)]
pub struct ManifestInfo {
pub config_digest: String,
pub layers: Vec<LayerInfo>,
pub total_size: u64,
}
/// OCI layer information
#[derive(Debug, Clone)]
pub struct LayerInfo {
pub digest: String,
pub size: u64,
pub media_type: String,
}