chore: update
This commit is contained in:
@@ -75,15 +75,7 @@ func (s *Service) Create(username string, cfg ProvisionConfig) (Demo, error) {
|
||||
CreatedAt: s.now().UTC(),
|
||||
ExpiresAt: s.now().UTC().Add(s.cfg.TTL),
|
||||
}
|
||||
// Port omis dans l'URL s'il s'agit du 443 standard ; sinon affiché
|
||||
// explicitement (ex. NodePort HTTPS sans LoadBalancer). Ne concerne que
|
||||
// l'URL affichée : le Host() de l'IngressRoute reste sans port (voir
|
||||
// buildIngressRouteValues), le port n'y a pas sa place pour le matching.
|
||||
portSuffix := ""
|
||||
if s.cfg.HTTPSPort != "" && s.cfg.HTTPSPort != "443" {
|
||||
portSuffix = ":" + s.cfg.HTTPSPort
|
||||
}
|
||||
demo.URL = "https://" + demo.Namespace + "." + s.cfg.BaseDomain + portSuffix
|
||||
demo.URL = s.urlFor(demo.Namespace)
|
||||
|
||||
// Réserve les ressources externes (slots Telegram/NowPayments pré-
|
||||
// provisionnés) — contrainte réelle indépendante du nombre de démos,
|
||||
@@ -134,11 +126,16 @@ func (s *Service) ListForUser(username string) ([]Demo, error) {
|
||||
}
|
||||
|
||||
// TransferToPaid marque la démo active du client comme abonnement payant
|
||||
// (n'expire plus). Le stockage (PVC postgres/redis) est déjà en place depuis
|
||||
// la création de la démo (voir HelmProvisioner.Provision) : rien à basculer
|
||||
// côté infra, seul le statut change. No-op si le client n'a pas de démo
|
||||
// active — ce n'est pas une erreur (ex: compte créé sans jamais avoir
|
||||
// demandé de démo).
|
||||
// (n'expire plus) et déclenche la migration de son namespace vers
|
||||
// "premium-<client>" (Kubernetes ne permet pas de renommer un namespace,
|
||||
// voir HelmProvisioner.MigrateToPremiumNamespace) — no-op si déjà migrée
|
||||
// (ex. renouvellement d'un client déjà premium). Le stockage (PVC
|
||||
// postgres/redis) est déjà en place depuis la création de la démo, seules
|
||||
// les données postgres sont recopiées vers le nouveau namespace. No-op
|
||||
// total si le client n'a pas de démo active — ce n'est pas une erreur (ex:
|
||||
// compte créé sans jamais avoir demandé de démo). La migration est lente
|
||||
// (dump/restore/helm) : elle tourne en tâche de fond, cette méthode ne
|
||||
// bloque pas.
|
||||
func (s *Service) TransferToPaid(username string) error {
|
||||
existing, err := s.store.ListByUsername(auth.NormalizeUsername(username))
|
||||
if err != nil {
|
||||
@@ -158,13 +155,43 @@ func (s *Service) TransferToPaid(username string) error {
|
||||
|
||||
active.TypeAbo = "premium"
|
||||
active.ExpiresAt = s.now().UTC().AddDate(10, 0, 0) // n'expire plus, en pratique
|
||||
if _, err := s.store.Update(*active); err != nil {
|
||||
updated, err := s.store.Update(*active)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newNamespace := premiumNamespace(updated.Username)
|
||||
if newNamespace != updated.Namespace {
|
||||
newURL := s.urlFor(newNamespace)
|
||||
go func() {
|
||||
if err := s.prov.MigrateToPremiumNamespace(updated, newNamespace, newURL); err != nil {
|
||||
log.Printf("Migration namespace premium échouée pour %s: %v", updated.Namespace, err)
|
||||
return
|
||||
}
|
||||
updated.Namespace = newNamespace
|
||||
updated.URL = newURL
|
||||
if _, err := s.store.Update(updated); err != nil {
|
||||
log.Printf("Mise à jour namespace après migration premium échouée pour %s: %v", newNamespace, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// urlFor construit l'URL publique d'une démo pour un namespace donné. Port
|
||||
// omis s'il s'agit du 443 standard ; sinon affiché explicitement (ex.
|
||||
// NodePort HTTPS sans LoadBalancer). Ne concerne que l'URL affichée : le
|
||||
// Host() de l'IngressRoute reste sans port (voir buildIngressRouteValues),
|
||||
// le port n'y a pas sa place pour le matching.
|
||||
func (s *Service) urlFor(namespace string) string {
|
||||
portSuffix := ""
|
||||
if s.cfg.HTTPSPort != "" && s.cfg.HTTPSPort != "443" {
|
||||
portSuffix = ":" + s.cfg.HTTPSPort
|
||||
}
|
||||
return "https://" + namespace + "." + s.cfg.BaseDomain + portSuffix
|
||||
}
|
||||
|
||||
// Delete déclenche le teardown et libère le pool.
|
||||
func (s *Service) Delete(id string) (Demo, error) {
|
||||
d, ok := s.store.Get(id)
|
||||
|
||||
Reference in New Issue
Block a user