refactor: compose deployment with pluggable spec resolver, basic test

This commit is contained in:
Pavel Sviderski
2025-03-19 16:28:17 +10:00
parent fb01604d21
commit 041d51b74f
10 changed files with 185 additions and 15 deletions
+21 -4
View File
@@ -8,13 +8,14 @@ import (
"uncloud/internal/secret"
)
type ImageDigestResolver interface {
Resolve(image string) (string, error)
}
// ServiceSpecResolver transforms user-provided service specs into deployment-ready form.
type ServiceSpecResolver struct {
ClusterDomain string
}
func NewServiceSpecResolver(clusterDomain string) *ServiceSpecResolver {
return &ServiceSpecResolver{ClusterDomain: clusterDomain}
ImageResolver ImageDigestResolver
}
// Resolve transforms a service spec into its fully resolved form ready for deployment.
@@ -26,6 +27,7 @@ func (r *ServiceSpecResolver) Resolve(spec *api.ServiceSpec) error {
steps := []func(*api.ServiceSpec) error{
r.applyDefaults,
r.resolveServiceName,
r.resolveImageDigest,
r.expandIngressPorts,
}
@@ -76,6 +78,21 @@ func (r *ServiceSpecResolver) resolveServiceName(spec *api.ServiceSpec) error {
return nil
}
func (r *ServiceSpecResolver) resolveImageDigest(spec *api.ServiceSpec) error {
if r.ImageResolver == nil {
// Skip digest resolution when no resolver is provided.
return nil
}
imageDigest, err := r.ImageResolver.Resolve(spec.Container.Image)
if err != nil {
return fmt.Errorf("resolve image digest: %w", err)
}
spec.Container.Image = imageDigest
return nil
}
// expandIngressPorts processes HTTP(S) ingress ports in a service spec by:
// 1. Setting a default hostname (service-name.cluster-domain) for ports without a hostname.
// 2. Duplicating a port with a cluster domain hostname for ports with external domains.