488 lines
13 KiB
Plaintext
488 lines
13 KiB
Plaintext
|
|
# Info: KCL OCI registry schemas for provisioning
|
||
|
|
# Author: Mode System Implementation
|
||
|
|
# Release: 1.0.0
|
||
|
|
# Date: 2025-10-06
|
||
|
|
|
||
|
|
"""
|
||
|
|
OCI (Open Container Initiative) registry configuration schemas
|
||
|
|
|
||
|
|
Supports multiple registry implementations:
|
||
|
|
- distribution: Docker Registry v2 (lightweight)
|
||
|
|
- zot: Cloud-native OCI registry
|
||
|
|
- harbor: Enterprise-grade registry with security scanning
|
||
|
|
- artifactory: JFrog Artifactory with OCI support
|
||
|
|
|
||
|
|
Purpose:
|
||
|
|
- Extension distribution via OCI artifacts
|
||
|
|
- KCL package distribution
|
||
|
|
- Platform container images
|
||
|
|
- Test environment images
|
||
|
|
"""
|
||
|
|
|
||
|
|
import regex
|
||
|
|
|
||
|
|
schema OCIRegistryConfig:
|
||
|
|
"""
|
||
|
|
OCI registry configuration for artifact and image distribution
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
# Local development registry
|
||
|
|
OCIRegistryConfig {
|
||
|
|
deployment = "local"
|
||
|
|
type = "zot"
|
||
|
|
endpoint = "localhost"
|
||
|
|
port = 5000
|
||
|
|
tls_enabled = False
|
||
|
|
local = LocalOCIConfig {
|
||
|
|
data_dir = "~/.provisioning/oci-registry"
|
||
|
|
config_path = "~/.provisioning/oci-registry/config.json"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Remote enterprise registry
|
||
|
|
OCIRegistryConfig {
|
||
|
|
deployment = "remote"
|
||
|
|
type = "harbor"
|
||
|
|
endpoint = "harbor.company.local"
|
||
|
|
tls_enabled = True
|
||
|
|
auth_required = True
|
||
|
|
remote = RemoteOCIConfig {
|
||
|
|
verify_ssl = True
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Deployment type
|
||
|
|
deployment: "local" | "remote" | "disabled"
|
||
|
|
|
||
|
|
# Registry implementation type
|
||
|
|
type: "distribution" | "zot" | "harbor" | "artifactory"
|
||
|
|
|
||
|
|
# Registry endpoint (hostname or IP)
|
||
|
|
endpoint: str
|
||
|
|
|
||
|
|
# Registry port (optional, defaults by type)
|
||
|
|
port?: int = 5000
|
||
|
|
|
||
|
|
# TLS/SSL configuration
|
||
|
|
tls_enabled: bool = False
|
||
|
|
tls_cert_path?: str
|
||
|
|
tls_key_path?: str
|
||
|
|
ca_cert_path?: str
|
||
|
|
|
||
|
|
# Authentication
|
||
|
|
auth_required: bool = False
|
||
|
|
username?: str
|
||
|
|
password_path?: str # Path to password file
|
||
|
|
auth_token_path?: str # Path to auth token
|
||
|
|
|
||
|
|
# Local deployment configuration
|
||
|
|
local?: LocalOCIConfig
|
||
|
|
|
||
|
|
# Remote connection configuration
|
||
|
|
remote?: RemoteOCIConfig
|
||
|
|
|
||
|
|
# Artifact namespaces/repositories
|
||
|
|
namespaces: OCINamespaces
|
||
|
|
|
||
|
|
# Registry-specific features
|
||
|
|
features?: OCIRegistryFeatures
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(endpoint) > 0, "OCI registry endpoint required"
|
||
|
|
port == Undefined or (port > 0 and port < 65536), \
|
||
|
|
"Port must be 1-65535"
|
||
|
|
deployment == "disabled" or (
|
||
|
|
(deployment == "local" and local != Undefined) or
|
||
|
|
(deployment == "remote" and remote != Undefined)
|
||
|
|
), "Config must match deployment type"
|
||
|
|
not auth_required or (
|
||
|
|
username != Undefined or auth_token_path != Undefined
|
||
|
|
), "Authentication config required when auth enabled"
|
||
|
|
not tls_enabled or (
|
||
|
|
tls_cert_path != Undefined and tls_key_path != Undefined
|
||
|
|
) or deployment == "remote", "TLS cert/key required for local TLS"
|
||
|
|
|
||
|
|
schema LocalOCIConfig:
|
||
|
|
"""
|
||
|
|
Local OCI registry deployment configuration
|
||
|
|
|
||
|
|
Used for:
|
||
|
|
- Solo mode development
|
||
|
|
- Testing OCI artifact distribution
|
||
|
|
- Offline extension development
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Data storage directory
|
||
|
|
data_dir: str
|
||
|
|
|
||
|
|
# Registry configuration file path
|
||
|
|
config_path: str
|
||
|
|
|
||
|
|
# Auto-start registry on provisioning startup
|
||
|
|
auto_start: bool = False
|
||
|
|
|
||
|
|
# Binary path (optional, uses PATH if not specified)
|
||
|
|
binary_path?: str
|
||
|
|
|
||
|
|
# Log file path
|
||
|
|
log_file?: str = "${data_dir}/registry.log"
|
||
|
|
|
||
|
|
# HTTP configuration
|
||
|
|
http_config?: LocalHTTPConfig
|
||
|
|
|
||
|
|
# Storage configuration
|
||
|
|
storage_config?: LocalStorageConfig
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(data_dir) > 0, "Data directory required"
|
||
|
|
len(config_path) > 0, "Config path required"
|
||
|
|
regex.match(data_dir, r"^[~/]"), \
|
||
|
|
"Data dir must be absolute or home-relative path"
|
||
|
|
|
||
|
|
schema LocalHTTPConfig:
|
||
|
|
"""HTTP configuration for local registry"""
|
||
|
|
|
||
|
|
listen_address: str = "127.0.0.1"
|
||
|
|
listen_port: int = 5000
|
||
|
|
read_timeout: int = 60 # seconds
|
||
|
|
write_timeout: int = 60
|
||
|
|
idle_timeout: int = 120
|
||
|
|
|
||
|
|
check:
|
||
|
|
listen_port > 0 and listen_port < 65536, "Port must be 1-65535"
|
||
|
|
|
||
|
|
schema LocalStorageConfig:
|
||
|
|
"""Storage configuration for local registry"""
|
||
|
|
|
||
|
|
# Storage backend
|
||
|
|
backend: "filesystem" | "s3" | "azure" = "filesystem"
|
||
|
|
|
||
|
|
# Filesystem storage
|
||
|
|
rootdirectory?: str
|
||
|
|
|
||
|
|
# Garbage collection
|
||
|
|
gc_enabled: bool = True
|
||
|
|
gc_interval: int = 3600 # seconds
|
||
|
|
|
||
|
|
# Deduplication
|
||
|
|
dedupe_enabled: bool = True
|
||
|
|
|
||
|
|
schema RemoteOCIConfig:
|
||
|
|
"""
|
||
|
|
Remote OCI registry connection configuration
|
||
|
|
|
||
|
|
Used for:
|
||
|
|
- Multi-user shared registry
|
||
|
|
- CI/CD artifact registry
|
||
|
|
- Enterprise production registry
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Connection timeout (seconds)
|
||
|
|
timeout: int = 30
|
||
|
|
|
||
|
|
# Retry configuration
|
||
|
|
retries: int = 3
|
||
|
|
retry_delay: int = 5 # seconds
|
||
|
|
retry_backoff: float = 2.0 # exponential backoff multiplier
|
||
|
|
|
||
|
|
# SSL/TLS verification
|
||
|
|
verify_ssl: bool = True
|
||
|
|
|
||
|
|
# Proxy configuration (optional)
|
||
|
|
http_proxy?: str
|
||
|
|
https_proxy?: str
|
||
|
|
no_proxy?: [str]
|
||
|
|
|
||
|
|
# Rate limiting
|
||
|
|
rate_limit?: RateLimitConfig
|
||
|
|
|
||
|
|
check:
|
||
|
|
timeout > 0, "Timeout must be positive"
|
||
|
|
retries >= 0, "Retries must be non-negative"
|
||
|
|
retry_backoff > 1.0, "Backoff multiplier must be > 1.0"
|
||
|
|
|
||
|
|
schema RateLimitConfig:
|
||
|
|
"""Rate limiting configuration for remote registry"""
|
||
|
|
|
||
|
|
# Requests per second
|
||
|
|
requests_per_second: int = 10
|
||
|
|
|
||
|
|
# Burst size
|
||
|
|
burst: int = 20
|
||
|
|
|
||
|
|
# Per-operation limits (optional)
|
||
|
|
pull_limit?: int
|
||
|
|
push_limit?: int
|
||
|
|
|
||
|
|
check:
|
||
|
|
requests_per_second > 0, "Rate limit must be positive"
|
||
|
|
burst > 0, "Burst size must be positive"
|
||
|
|
|
||
|
|
schema OCINamespaces:
|
||
|
|
"""
|
||
|
|
OCI registry namespaces for different artifact types
|
||
|
|
|
||
|
|
Namespaces organize artifacts by purpose and allow
|
||
|
|
different access control policies per namespace.
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Extension artifacts (providers, taskservs, clusters)
|
||
|
|
extensions: str = "provisioning-extensions"
|
||
|
|
|
||
|
|
# KCL package artifacts
|
||
|
|
kcl_packages: str = "provisioning-kcl"
|
||
|
|
|
||
|
|
# Platform service images (orchestrator, control-center)
|
||
|
|
platform_images: str = "provisioning-platform"
|
||
|
|
|
||
|
|
# Test environment images
|
||
|
|
test_images: str = "provisioning-test"
|
||
|
|
|
||
|
|
# Custom user-defined namespaces
|
||
|
|
custom?: {str: str}
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(extensions) > 0, "Extensions namespace required"
|
||
|
|
len(kcl_packages) > 0, "KCL packages namespace required"
|
||
|
|
len(platform_images) > 0, "Platform images namespace required"
|
||
|
|
len(test_images) > 0, "Test images namespace required"
|
||
|
|
# Validate namespace naming convention
|
||
|
|
regex.match(extensions, r"^[a-z0-9][a-z0-9-]*[a-z0-9]$"), \
|
||
|
|
"Extensions namespace must be lowercase alphanumeric with hyphens"
|
||
|
|
regex.match(kcl_packages, r"^[a-z0-9][a-z0-9-]*[a-z0-9]$"), \
|
||
|
|
"KCL packages namespace must be lowercase alphanumeric with hyphens"
|
||
|
|
|
||
|
|
schema OCIRegistryFeatures:
|
||
|
|
"""
|
||
|
|
Registry-specific feature configuration
|
||
|
|
|
||
|
|
Different registry implementations support different features.
|
||
|
|
This schema allows enabling/disabling features based on
|
||
|
|
registry capabilities.
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Vulnerability scanning (Harbor, Artifactory)
|
||
|
|
vulnerability_scanning: bool = False
|
||
|
|
scanner_type?: "trivy" | "clair" | "anchore"
|
||
|
|
|
||
|
|
# Image signing/verification (Notary, Cosign)
|
||
|
|
image_signing: bool = False
|
||
|
|
signing_method?: "notary" | "cosign"
|
||
|
|
|
||
|
|
# Replication (Harbor)
|
||
|
|
replication_enabled: bool = False
|
||
|
|
replication_targets?: [ReplicationTarget]
|
||
|
|
|
||
|
|
# Quota management
|
||
|
|
quota_enabled: bool = False
|
||
|
|
quota_config?: QuotaConfig
|
||
|
|
|
||
|
|
# Webhook notifications
|
||
|
|
webhook_enabled: bool = False
|
||
|
|
webhook_endpoints?: [str]
|
||
|
|
|
||
|
|
# Garbage collection
|
||
|
|
gc_enabled: bool = True
|
||
|
|
gc_schedule?: str = "0 2 * * *" # Daily at 2 AM
|
||
|
|
|
||
|
|
check:
|
||
|
|
not vulnerability_scanning or scanner_type != Undefined, \
|
||
|
|
"Scanner type required when vulnerability scanning enabled"
|
||
|
|
not image_signing or signing_method != Undefined, \
|
||
|
|
"Signing method required when image signing enabled"
|
||
|
|
|
||
|
|
schema ReplicationTarget:
|
||
|
|
"""Harbor replication target configuration"""
|
||
|
|
|
||
|
|
name: str
|
||
|
|
type: "harbor" | "docker-hub" | "aws-ecr" | "azure-acr" | "google-gcr"
|
||
|
|
endpoint: str
|
||
|
|
credentials?: str # Path to credentials file
|
||
|
|
verify_ssl: bool = True
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(name) > 0, "Replication target name required"
|
||
|
|
len(endpoint) > 0, "Replication endpoint required"
|
||
|
|
|
||
|
|
schema QuotaConfig:
|
||
|
|
"""Registry quota configuration"""
|
||
|
|
|
||
|
|
# Storage quota (GB)
|
||
|
|
storage_limit_gb: int = 100
|
||
|
|
|
||
|
|
# Artifact count limit
|
||
|
|
artifact_limit?: int = 10000
|
||
|
|
|
||
|
|
# Per-namespace quotas
|
||
|
|
namespace_quotas?: {str: NamespaceQuota}
|
||
|
|
|
||
|
|
check:
|
||
|
|
storage_limit_gb > 0, "Storage limit must be positive"
|
||
|
|
|
||
|
|
schema NamespaceQuota:
|
||
|
|
"""Per-namespace quota configuration"""
|
||
|
|
|
||
|
|
storage_limit_gb: int = 50
|
||
|
|
artifact_limit: int = 1000
|
||
|
|
|
||
|
|
check:
|
||
|
|
storage_limit_gb > 0, "Namespace storage limit must be positive"
|
||
|
|
artifact_limit > 0, "Namespace artifact limit must be positive"
|
||
|
|
|
||
|
|
# ============================================================================
|
||
|
|
# Helper Schemas
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
schema OCIArtifactReference:
|
||
|
|
"""
|
||
|
|
OCI artifact reference for pulling/pushing artifacts
|
||
|
|
|
||
|
|
Format: <registry>/<namespace>/<repository>:<tag>@<digest>
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Registry endpoint
|
||
|
|
registry: str
|
||
|
|
|
||
|
|
# Namespace/project
|
||
|
|
namespace: str
|
||
|
|
|
||
|
|
# Repository name
|
||
|
|
repository: str
|
||
|
|
|
||
|
|
# Tag (optional, defaults to "latest")
|
||
|
|
tag: str = "latest"
|
||
|
|
|
||
|
|
# Digest (optional, for content-addressable pulls)
|
||
|
|
digest?: str
|
||
|
|
|
||
|
|
# Computed full reference
|
||
|
|
full_reference: str = f"{registry}/{namespace}/{repository}:{tag}"
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(registry) > 0, "Registry required"
|
||
|
|
len(namespace) > 0, "Namespace required"
|
||
|
|
len(repository) > 0, "Repository required"
|
||
|
|
len(tag) > 0, "Tag required"
|
||
|
|
regex.match(tag, r"^[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}$"), \
|
||
|
|
"Invalid tag format"
|
||
|
|
|
||
|
|
schema OCIPullPolicy:
|
||
|
|
"""
|
||
|
|
OCI artifact pull policy configuration
|
||
|
|
|
||
|
|
Defines caching and pull behavior for artifacts
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Pull policy
|
||
|
|
policy: "always" | "if-not-present" | "never" = "if-not-present"
|
||
|
|
|
||
|
|
# Cache TTL (seconds)
|
||
|
|
cache_ttl: int = 3600
|
||
|
|
|
||
|
|
# Verify digest on cached artifacts
|
||
|
|
verify_cached: bool = True
|
||
|
|
|
||
|
|
# Allow insecure registries (development only)
|
||
|
|
allow_insecure: bool = False
|
||
|
|
|
||
|
|
check:
|
||
|
|
cache_ttl > 0, "Cache TTL must be positive"
|
||
|
|
policy in ["always", "if-not-present", "never"], \
|
||
|
|
"Invalid pull policy"
|
||
|
|
|
||
|
|
schema OCIPushPolicy:
|
||
|
|
"""
|
||
|
|
OCI artifact push policy configuration
|
||
|
|
|
||
|
|
Defines pushing behavior and constraints
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Allow overwriting existing tags
|
||
|
|
allow_overwrite: bool = False
|
||
|
|
|
||
|
|
# Require tag signing before push
|
||
|
|
require_signing: bool = False
|
||
|
|
|
||
|
|
# Automatic tagging strategy
|
||
|
|
auto_tag: bool = True
|
||
|
|
tag_format?: str = "v{version}-{timestamp}"
|
||
|
|
|
||
|
|
# Compression
|
||
|
|
compression_enabled: bool = True
|
||
|
|
compression_level: int = 6 # 0-9
|
||
|
|
|
||
|
|
check:
|
||
|
|
compression_level >= 0 and compression_level <= 9, \
|
||
|
|
"Compression level must be 0-9"
|
||
|
|
|
||
|
|
# ============================================================================
|
||
|
|
# Registry-Specific Configuration
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
schema ZotRegistryConfig(OCIRegistryConfig):
|
||
|
|
"""
|
||
|
|
Zot registry specific configuration
|
||
|
|
|
||
|
|
Zot is a lightweight, cloud-native OCI registry focused on
|
||
|
|
minimal resource usage and developer experience.
|
||
|
|
"""
|
||
|
|
|
||
|
|
type: "zot" = "zot"
|
||
|
|
|
||
|
|
# Zot-specific features
|
||
|
|
zot_features?: ZotFeatures
|
||
|
|
|
||
|
|
schema ZotFeatures:
|
||
|
|
"""Zot-specific features"""
|
||
|
|
|
||
|
|
# Enable search API
|
||
|
|
search_enabled: bool = True
|
||
|
|
|
||
|
|
# Enable metrics endpoint
|
||
|
|
metrics_enabled: bool = True
|
||
|
|
metrics_port: int = 9090
|
||
|
|
|
||
|
|
# Enable sync (pull-through cache)
|
||
|
|
sync_enabled: bool = False
|
||
|
|
sync_registries?: [str]
|
||
|
|
|
||
|
|
# Enable scrub (background verification)
|
||
|
|
scrub_enabled: bool = True
|
||
|
|
scrub_interval: str = "24h"
|
||
|
|
|
||
|
|
schema HarborRegistryConfig(OCIRegistryConfig):
|
||
|
|
"""
|
||
|
|
Harbor registry specific configuration
|
||
|
|
|
||
|
|
Harbor is an enterprise-grade container registry with
|
||
|
|
security scanning, replication, and RBAC.
|
||
|
|
"""
|
||
|
|
|
||
|
|
type: "harbor" = "harbor"
|
||
|
|
|
||
|
|
# Harbor-specific configuration
|
||
|
|
harbor_config?: HarborConfig
|
||
|
|
|
||
|
|
schema HarborConfig:
|
||
|
|
"""Harbor-specific configuration"""
|
||
|
|
|
||
|
|
# Harbor project (namespace)
|
||
|
|
project: str
|
||
|
|
|
||
|
|
# Project visibility
|
||
|
|
public_project: bool = False
|
||
|
|
|
||
|
|
# Content trust (Notary)
|
||
|
|
content_trust: bool = False
|
||
|
|
|
||
|
|
# Auto-scan on push
|
||
|
|
auto_scan: bool = True
|
||
|
|
|
||
|
|
# Prevent vulnerable images
|
||
|
|
prevent_vulnerable: bool = True
|
||
|
|
severity_threshold: "critical" | "high" | "medium" | "low" = "high"
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(project) > 0, "Harbor project required"
|