chore: update
This commit is contained in:
@@ -56,13 +56,19 @@ type ProvisionConfig struct {
|
|||||||
S3Endpoint string
|
S3Endpoint string
|
||||||
|
|
||||||
// Load-balancer Telegram (chart lbtelegram) : installé seulement si au
|
// Load-balancer Telegram (chart lbtelegram) : installé seulement si au
|
||||||
// moins un bot est renseigné. Le reste de la config du chart (DSN
|
// moins un bot est renseigné. GATEWAY_URL (URL publique de la démo) et
|
||||||
// postgres/redis, secrets JWT/webhook/backend-link) est généré par le
|
// les DSN/secrets sont générés par le provisioner. Les 3 réglages
|
||||||
// provisioner, pas saisi par l'admin.
|
// ci-dessous sont optionnels — laissés vides, lbtelegram applique ses
|
||||||
|
// propres défauts (failover, 300s, 30s — voir internal/config/config.go
|
||||||
|
// du service lbtelegram).
|
||||||
LBBot1Username string
|
LBBot1Username string
|
||||||
LBBot1Token string
|
LBBot1Token string
|
||||||
LBBot2Username string
|
LBBot2Username string
|
||||||
LBBot2Token string
|
LBBot2Token string
|
||||||
|
// LBStrategy : "failover" (défaut) | "roundrobin" | "leastconn"
|
||||||
|
LBStrategy string
|
||||||
|
LBJWTTTLSeconds string
|
||||||
|
LBHealthCheckInterval string // secondes
|
||||||
|
|
||||||
// Compte admin de l'application déployée (pas le compte omnex de
|
// Compte admin de l'application déployée (pas le compte omnex de
|
||||||
// l'admin qui lance la démo) — requis : sans lui, personne ne peut se
|
// l'admin qui lance la démo) — requis : sans lui, personne ne peut se
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ type createRequest struct {
|
|||||||
LBBot1Token string `json:"lb_bot1_token" binding:"omitempty"`
|
LBBot1Token string `json:"lb_bot1_token" binding:"omitempty"`
|
||||||
LBBot2Username string `json:"lb_bot2_username" binding:"omitempty,max=64"`
|
LBBot2Username string `json:"lb_bot2_username" binding:"omitempty,max=64"`
|
||||||
LBBot2Token string `json:"lb_bot2_token" binding:"omitempty"`
|
LBBot2Token string `json:"lb_bot2_token" binding:"omitempty"`
|
||||||
|
// LBStrategy : "failover" | "roundrobin" | "leastconn" (vide => failover,
|
||||||
|
// défaut appliqué par lbtelegram lui-même).
|
||||||
|
LBStrategy string `json:"lb_strategy" binding:"omitempty,oneof=failover roundrobin leastconn"`
|
||||||
|
LBJWTTTLSeconds string `json:"lb_jwt_ttl_seconds" binding:"omitempty,numeric"`
|
||||||
|
LBHealthCheckInterval string `json:"lb_health_check_interval" binding:"omitempty,numeric"`
|
||||||
|
|
||||||
// Compte admin de l'application déployée — requis, sans lui personne ne
|
// Compte admin de l'application déployée — requis, sans lui personne ne
|
||||||
// peut se connecter au backoffice de la démo.
|
// peut se connecter au backoffice de la démo.
|
||||||
@@ -63,19 +68,22 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
cfg := ProvisionConfig{
|
cfg := ProvisionConfig{
|
||||||
TelegramBotUsername: req.TelegramBotUsername,
|
TelegramBotUsername: req.TelegramBotUsername,
|
||||||
TelegramBotToken: req.TelegramBotToken,
|
TelegramBotToken: req.TelegramBotToken,
|
||||||
NowPaymentsAPIKey: req.NowPaymentsAPIKey,
|
NowPaymentsAPIKey: req.NowPaymentsAPIKey,
|
||||||
NowPaymentsIPNSecret: req.NowPaymentsIPNSecret,
|
NowPaymentsIPNSecret: req.NowPaymentsIPNSecret,
|
||||||
StorageDriver: req.StorageDriver,
|
StorageDriver: req.StorageDriver,
|
||||||
S3Bucket: req.S3Bucket,
|
S3Bucket: req.S3Bucket,
|
||||||
S3Endpoint: req.S3Endpoint,
|
S3Endpoint: req.S3Endpoint,
|
||||||
LBBot1Username: req.LBBot1Username,
|
LBBot1Username: req.LBBot1Username,
|
||||||
LBBot1Token: req.LBBot1Token,
|
LBBot1Token: req.LBBot1Token,
|
||||||
LBBot2Username: req.LBBot2Username,
|
LBBot2Username: req.LBBot2Username,
|
||||||
LBBot2Token: req.LBBot2Token,
|
LBBot2Token: req.LBBot2Token,
|
||||||
AdminUsername: req.AdminUsername,
|
LBStrategy: req.LBStrategy,
|
||||||
AdminPassword: req.AdminPassword,
|
LBJWTTTLSeconds: req.LBJWTTTLSeconds,
|
||||||
|
LBHealthCheckInterval: req.LBHealthCheckInterval,
|
||||||
|
AdminUsername: req.AdminUsername,
|
||||||
|
AdminPassword: req.AdminPassword,
|
||||||
}
|
}
|
||||||
d, err := h.svc.Create(req.LeadID, req.Username, cfg)
|
d, err := h.svc.Create(req.LeadID, req.Username, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -620,6 +620,31 @@ func (h *HelmProvisioner) buildLBTelegramValues(d Demo, cfg ProvisionConfig, bac
|
|||||||
dbURL := fmt.Sprintf("postgres://postgres:demo-postgres-pass@%s-postgresql-postgresql:5432/demo_db?sslmode=disable", d.Namespace)
|
dbURL := fmt.Sprintf("postgres://postgres:demo-postgres-pass@%s-postgresql-postgresql:5432/demo_db?sslmode=disable", d.Namespace)
|
||||||
redisURL := fmt.Sprintf("redis://:demo-redis-pass@%s-redis-redis:6379/0", d.Namespace)
|
redisURL := fmt.Sprintf("redis://:demo-redis-pass@%s-redis-redis:6379/0", d.Namespace)
|
||||||
lbRepo, lbTag := parseImage(h.lbtelegramImage)
|
lbRepo, lbTag := parseImage(h.lbtelegramImage)
|
||||||
|
host := fmt.Sprintf("%s.%s", d.Namespace, h.baseDomain)
|
||||||
|
|
||||||
|
env := map[string]string{
|
||||||
|
"PORT": "8081",
|
||||||
|
"ENV": "production",
|
||||||
|
// URL publique HTTPS de cette démo : requise par lbtelegram (panic
|
||||||
|
// sinon), utilisée pour enregistrer les webhooks Telegram de chaque
|
||||||
|
// bot (GATEWAY_URL + "/webhook/" + botID) — voir
|
||||||
|
// deploy/chart-gestion/lbtelegram/templates/ingressroute.yaml pour
|
||||||
|
// le routage public correspondant.
|
||||||
|
"GATEWAY_URL": "https://" + host,
|
||||||
|
"BOT_COUNT": fmt.Sprintf("%d", botCount),
|
||||||
|
"BOT1_USERNAME": cfg.LBBot1Username,
|
||||||
|
"BOT2_USERNAME": cfg.LBBot2Username,
|
||||||
|
"BACKEND_LINK_URL": backendURL,
|
||||||
|
}
|
||||||
|
if cfg.LBStrategy != "" {
|
||||||
|
env["LB_STRATEGY"] = cfg.LBStrategy
|
||||||
|
}
|
||||||
|
if cfg.LBJWTTTLSeconds != "" {
|
||||||
|
env["JWT_TTL_SECONDS"] = cfg.LBJWTTTLSeconds
|
||||||
|
}
|
||||||
|
if cfg.LBHealthCheckInterval != "" {
|
||||||
|
env["HEALTH_CHECK_INTERVAL"] = cfg.LBHealthCheckInterval
|
||||||
|
}
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"image": map[string]interface{}{
|
"image": map[string]interface{}{
|
||||||
@@ -627,14 +652,9 @@ func (h *HelmProvisioner) buildLBTelegramValues(d Demo, cfg ProvisionConfig, bac
|
|||||||
"tag": lbTag,
|
"tag": lbTag,
|
||||||
"pullPolicy": "Always",
|
"pullPolicy": "Always",
|
||||||
},
|
},
|
||||||
"env": map[string]string{
|
"host": host,
|
||||||
"PORT": "8081",
|
"traefikNamespace": sharedTraefikNamespace,
|
||||||
"ENV": "production",
|
"env": env,
|
||||||
"BOT_COUNT": fmt.Sprintf("%d", botCount),
|
|
||||||
"BOT1_USERNAME": cfg.LBBot1Username,
|
|
||||||
"BOT2_USERNAME": cfg.LBBot2Username,
|
|
||||||
"BACKEND_LINK_URL": backendURL,
|
|
||||||
},
|
|
||||||
"secrets": map[string]string{
|
"secrets": map[string]string{
|
||||||
"BOT1_TOKEN": cfg.LBBot1Token,
|
"BOT1_TOKEN": cfg.LBBot1Token,
|
||||||
"BOT2_TOKEN": cfg.LBBot2Token,
|
"BOT2_TOKEN": cfg.LBBot2Token,
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{{- if .Values.host }}
|
||||||
|
# Webhooks Telegram des bots du load-balancer (POST /webhook/bot1,
|
||||||
|
# /webhook/bot2, ...), voir internal/bot/registry.go du service lbtelegram :
|
||||||
|
# webhookURL = GATEWAY_URL + "/webhook/" + botID. Sans cette route, lbtelegram
|
||||||
|
# enregistre bien le webhook auprès de Telegram (GATEWAY_URL requis au
|
||||||
|
# démarrage) mais ne reçoit jamais rien : personne ne route /webhook/bot*
|
||||||
|
# vers son Service.
|
||||||
|
#
|
||||||
|
# Priorité 25 : au-dessus de la route générique /webhook/ -> backend
|
||||||
|
# (priority 20, voir deploy/chart-gestion/ingressroute/templates/ingressroute.yaml)
|
||||||
|
# pour ne pas être captée par elle.
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Namespace }}-lbtelegram-routes
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
{{- include "lbtelegram.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`{{ .Values.host }}`) && PathPrefix(`/webhook/bot`)
|
||||||
|
kind: Rule
|
||||||
|
priority: 25
|
||||||
|
middlewares:
|
||||||
|
- name: waf-chain
|
||||||
|
namespace: {{ .Values.traefikNamespace }}
|
||||||
|
services:
|
||||||
|
- name: {{ include "lbtelegram.fullname" . }}
|
||||||
|
port: {{ .Values.service.port }}
|
||||||
|
tls: {}
|
||||||
|
{{- end }}
|
||||||
@@ -54,3 +54,9 @@ securityContext:
|
|||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
port: 8081
|
port: 8081
|
||||||
|
|
||||||
|
# Routage public des webhooks Telegram (/webhook/bot1, /webhook/bot2...) via
|
||||||
|
# le Traefik partagé. host vide => pas d'IngressRoute créée (voir
|
||||||
|
# templates/ingressroute.yaml).
|
||||||
|
host: ""
|
||||||
|
traefikNamespace: traefik
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Radio,
|
Radio,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
|
Select,
|
||||||
Stack,
|
Stack,
|
||||||
Switch,
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
@@ -51,6 +52,9 @@ export function CreateDemoModal({ isOpen, onClose, onCreated, leadId, lockedUser
|
|||||||
const [lbBot1Token, setLbBot1Token] = useState('')
|
const [lbBot1Token, setLbBot1Token] = useState('')
|
||||||
const [lbBot2Username, setLbBot2Username] = useState('')
|
const [lbBot2Username, setLbBot2Username] = useState('')
|
||||||
const [lbBot2Token, setLbBot2Token] = useState('')
|
const [lbBot2Token, setLbBot2Token] = useState('')
|
||||||
|
const [lbStrategy, setLbStrategy] = useState<'failover' | 'roundrobin' | 'leastconn'>('failover')
|
||||||
|
const [lbJwtTtlSeconds, setLbJwtTtlSeconds] = useState('')
|
||||||
|
const [lbHealthCheckInterval, setLbHealthCheckInterval] = useState('')
|
||||||
|
|
||||||
const [storageDriver, setStorageDriver] = useState<StorageDriver>('local')
|
const [storageDriver, setStorageDriver] = useState<StorageDriver>('local')
|
||||||
const [s3Bucket, setS3Bucket] = useState('')
|
const [s3Bucket, setS3Bucket] = useState('')
|
||||||
@@ -72,6 +76,9 @@ export function CreateDemoModal({ isOpen, onClose, onCreated, leadId, lockedUser
|
|||||||
setLbBot1Token('')
|
setLbBot1Token('')
|
||||||
setLbBot2Username('')
|
setLbBot2Username('')
|
||||||
setLbBot2Token('')
|
setLbBot2Token('')
|
||||||
|
setLbStrategy('failover')
|
||||||
|
setLbJwtTtlSeconds('')
|
||||||
|
setLbHealthCheckInterval('')
|
||||||
setStorageDriver('local')
|
setStorageDriver('local')
|
||||||
setS3Bucket('')
|
setS3Bucket('')
|
||||||
setS3Endpoint('')
|
setS3Endpoint('')
|
||||||
@@ -120,6 +127,9 @@ export function CreateDemoModal({ isOpen, onClose, onCreated, leadId, lockedUser
|
|||||||
lbBot1Token: lbBot1Token.trim() || undefined,
|
lbBot1Token: lbBot1Token.trim() || undefined,
|
||||||
lbBot2Username: lbBot2Username.trim() || undefined,
|
lbBot2Username: lbBot2Username.trim() || undefined,
|
||||||
lbBot2Token: lbBot2Token.trim() || undefined,
|
lbBot2Token: lbBot2Token.trim() || undefined,
|
||||||
|
lbStrategy,
|
||||||
|
lbJwtTtlSeconds: lbJwtTtlSeconds.trim() || undefined,
|
||||||
|
lbHealthCheckInterval: lbHealthCheckInterval.trim() || undefined,
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
}
|
}
|
||||||
@@ -311,6 +321,37 @@ export function CreateDemoModal({ isOpen, onClose, onCreated, leadId, lockedUser
|
|||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
<HStack spacing={3} align="start">
|
||||||
|
<FormControl isDisabled={submitting}>
|
||||||
|
<FormLabel fontSize="sm">Stratégie de répartition</FormLabel>
|
||||||
|
<Select
|
||||||
|
value={lbStrategy}
|
||||||
|
onChange={(e) => setLbStrategy(e.target.value as typeof lbStrategy)}
|
||||||
|
>
|
||||||
|
<option value="failover">Failover</option>
|
||||||
|
<option value="roundrobin">Round-robin</option>
|
||||||
|
<option value="leastconn">Moins de connexions</option>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl isDisabled={submitting}>
|
||||||
|
<FormLabel fontSize="sm">TTL JWT (secondes)</FormLabel>
|
||||||
|
<Input
|
||||||
|
placeholder="300"
|
||||||
|
value={lbJwtTtlSeconds}
|
||||||
|
onChange={(e) => setLbJwtTtlSeconds(e.target.value)}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl isDisabled={submitting}>
|
||||||
|
<FormLabel fontSize="sm">Intervalle health-check (s)</FormLabel>
|
||||||
|
<Input
|
||||||
|
placeholder="30"
|
||||||
|
value={lbHealthCheckInterval}
|
||||||
|
onChange={(e) => setLbHealthCheckInterval(e.target.value)}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</HStack>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ export interface CreateDemoParams {
|
|||||||
lbBot1Token?: string
|
lbBot1Token?: string
|
||||||
lbBot2Username?: string
|
lbBot2Username?: string
|
||||||
lbBot2Token?: string
|
lbBot2Token?: string
|
||||||
|
lbStrategy?: 'failover' | 'roundrobin' | 'leastconn'
|
||||||
|
lbJwtTtlSeconds?: string
|
||||||
|
lbHealthCheckInterval?: string
|
||||||
adminUsername: string
|
adminUsername: string
|
||||||
adminPassword: string
|
adminPassword: string
|
||||||
}
|
}
|
||||||
@@ -185,6 +188,9 @@ export const api = {
|
|||||||
: {}),
|
: {}),
|
||||||
...(params.lbBot1Username ? { lb_bot1_username: params.lbBot1Username, lb_bot1_token: params.lbBot1Token } : {}),
|
...(params.lbBot1Username ? { lb_bot1_username: params.lbBot1Username, lb_bot1_token: params.lbBot1Token } : {}),
|
||||||
...(params.lbBot2Username ? { lb_bot2_username: params.lbBot2Username, lb_bot2_token: params.lbBot2Token } : {}),
|
...(params.lbBot2Username ? { lb_bot2_username: params.lbBot2Username, lb_bot2_token: params.lbBot2Token } : {}),
|
||||||
|
...(params.lbStrategy ? { lb_strategy: params.lbStrategy } : {}),
|
||||||
|
...(params.lbJwtTtlSeconds ? { lb_jwt_ttl_seconds: params.lbJwtTtlSeconds } : {}),
|
||||||
|
...(params.lbHealthCheckInterval ? { lb_health_check_interval: params.lbHealthCheckInterval } : {}),
|
||||||
admin_username: params.adminUsername,
|
admin_username: params.adminUsername,
|
||||||
admin_password: params.adminPassword,
|
admin_password: params.adminPassword,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user