up
This commit is contained in:
@@ -12,9 +12,13 @@ import (
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
)
|
||||
|
||||
// ─── helpers internos ────────────────────────────────────────────────────────
|
||||
|
||||
// coolifyDo ejecuta una petición a la API de Coolify y devuelve el body crudo.
|
||||
func coolifyDo(method, endpoint string, reqBody io.Reader, contentType string, cfg *models.CoolifyConfig) ([]byte, int, error) {
|
||||
base := strings.TrimRight(cfg.BaseURL, "/")
|
||||
url := fmt.Sprintf("%s/api/v1%s", base, endpoint)
|
||||
|
||||
client := &http.Client{Timeout: 30 * time.Second}
|
||||
req, err := http.NewRequest(method, url, reqBody)
|
||||
if err != nil {
|
||||
@@ -25,6 +29,7 @@ func coolifyDo(method, endpoint string, reqBody io.Reader, contentType string, c
|
||||
if contentType != "" {
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@@ -34,6 +39,7 @@ func coolifyDo(method, endpoint string, reqBody io.Reader, contentType string, c
|
||||
return body, resp.StatusCode, nil
|
||||
}
|
||||
|
||||
// coolifyProxy resuelve config, aplica qs de la request y responde al frontend.
|
||||
func coolifyProxy(c *fiber.Ctx, method, endpoint string) error {
|
||||
cfg, err := models.GetCoolifyConfig()
|
||||
if err != nil {
|
||||
@@ -42,33 +48,34 @@ func coolifyProxy(c *fiber.Ctx, method, endpoint string) error {
|
||||
if !cfg.Activo {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "La integración Coolify está inactiva"})
|
||||
}
|
||||
|
||||
ep := endpoint
|
||||
if qs := string(c.Request().URI().QueryString()); qs != "" {
|
||||
ep = endpoint + "?" + qs
|
||||
}
|
||||
|
||||
var bodyReader io.Reader
|
||||
ct := ""
|
||||
if raw := c.Body(); len(raw) > 0 {
|
||||
bodyReader = strings.NewReader(string(raw))
|
||||
ct = c.Get("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
body, status, err := coolifyDo(method, ep, bodyReader, ct, cfg)
|
||||
if err != nil {
|
||||
// No devolver 502: Cloudflare lo intercepta y oculta el error al frontend
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "No se pudo conectar a Coolify: " + err.Error()})
|
||||
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
var result json.RawMessage
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
result = json.RawMessage(fmt.Sprintf(`{"raw":%q}`, string(body)))
|
||||
}
|
||||
// Si Coolify devuelve 5xx, bajar a 400 para que Cloudflare no lo intercepte
|
||||
if status >= 500 {
|
||||
status = fiber.StatusBadRequest
|
||||
}
|
||||
c.Status(status)
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
// ─── Página principal ─────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyIndex(c *fiber.Ctx) error {
|
||||
cfg, _ := models.GetCoolifyConfig()
|
||||
return c.Render("coolify", fiber.Map{
|
||||
@@ -78,6 +85,8 @@ func CoolifyIndex(c *fiber.Ctx) error {
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
// ─── Configuración ────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyGetConfig(c *fiber.Ctx) error {
|
||||
cfg, err := models.GetCoolifyConfig()
|
||||
if err != nil {
|
||||
@@ -118,6 +127,7 @@ func CoolifySaveConfig(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{"ok": true, "config": cfg})
|
||||
}
|
||||
|
||||
// CoolifyTestConnection verifica conectividad con /health (no requiere auth).
|
||||
func CoolifyTestConnection(c *fiber.Ctx) error {
|
||||
cfg, err := models.GetCoolifyConfig()
|
||||
if err != nil {
|
||||
@@ -127,7 +137,7 @@ func CoolifyTestConnection(c *fiber.Ctx) error {
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
resp, err := client.Get(base + "/api/health")
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "No se pudo conectar a Coolify: " + err.Error()})
|
||||
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, _ := io.ReadAll(io.LimitReader(resp.Body, 64*1024))
|
||||
@@ -139,142 +149,171 @@ func CoolifyTestConnection(c *fiber.Ctx) error {
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
// ─── Applications ─────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListApplications(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/applications")
|
||||
}
|
||||
|
||||
func CoolifyGetApplication(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
func CoolifyApplicationLogs(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/logs")
|
||||
}
|
||||
|
||||
func CoolifyApplicationEnvs(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/envs")
|
||||
}
|
||||
|
||||
func CoolifyApplicationEnvCreate(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPost, "/applications/"+c.Params("uuid")+"/envs")
|
||||
}
|
||||
|
||||
func CoolifyApplicationEnvUpdateBulk(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPatch, "/applications/"+c.Params("uuid")+"/envs")
|
||||
}
|
||||
|
||||
func CoolifyApplicationEnvDelete(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodDelete, "/applications/"+c.Params("uuid")+"/envs/"+c.Params("env_id"))
|
||||
}
|
||||
|
||||
func CoolifyApplicationStart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPost, "/applications/"+c.Params("uuid")+"/start")
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/start")
|
||||
}
|
||||
|
||||
func CoolifyApplicationStop(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPost, "/applications/"+c.Params("uuid")+"/stop")
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/stop")
|
||||
}
|
||||
|
||||
func CoolifyApplicationRestart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPost, "/applications/"+c.Params("uuid")+"/restart")
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/restart")
|
||||
}
|
||||
|
||||
func CoolifyApplicationDeployments(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/deployments")
|
||||
}
|
||||
|
||||
func CoolifyApplicationDeploy(c *fiber.Ctx) error {
|
||||
// POST /api/v1/deploy?uuid={uuid}&force=false
|
||||
return coolifyProxy(c, http.MethodPost, "/deploy")
|
||||
}
|
||||
|
||||
// ─── Servers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListServers(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/servers")
|
||||
}
|
||||
|
||||
func CoolifyGetServer(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/servers/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
func CoolifyServerResources(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/servers/"+c.Params("uuid")+"/resources")
|
||||
}
|
||||
|
||||
func CoolifyServerDomains(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/servers/"+c.Params("uuid")+"/domains")
|
||||
}
|
||||
|
||||
func CoolifyServerValidate(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/servers/"+c.Params("uuid")+"/validate")
|
||||
}
|
||||
|
||||
// ─── Services ─────────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListServices(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services")
|
||||
}
|
||||
|
||||
func CoolifyGetService(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
func CoolifyServiceStart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services/"+c.Params("uuid")+"/start")
|
||||
}
|
||||
|
||||
func CoolifyServiceStop(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services/"+c.Params("uuid")+"/stop")
|
||||
}
|
||||
|
||||
func CoolifyServiceRestart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services/"+c.Params("uuid")+"/restart")
|
||||
}
|
||||
|
||||
func CoolifyServiceEnvs(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/services/"+c.Params("uuid")+"/envs")
|
||||
}
|
||||
|
||||
func CoolifyServiceEnvUpdateBulk(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodPatch, "/services/"+c.Params("uuid")+"/envs")
|
||||
}
|
||||
|
||||
// ─── Databases ────────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListDatabases(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/databases")
|
||||
}
|
||||
|
||||
func CoolifyGetDatabase(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/databases/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
func CoolifyDatabaseStart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/databases/"+c.Params("uuid")+"/start")
|
||||
}
|
||||
|
||||
func CoolifyDatabaseStop(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/databases/"+c.Params("uuid")+"/stop")
|
||||
}
|
||||
|
||||
func CoolifyDatabaseRestart(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/databases/"+c.Params("uuid")+"/restart")
|
||||
}
|
||||
|
||||
// ─── Projects ─────────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListProjects(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/projects")
|
||||
}
|
||||
|
||||
func CoolifyGetProject(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/projects/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
func CoolifyProjectEnvironments(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/projects/"+c.Params("uuid")+"/environments")
|
||||
}
|
||||
|
||||
// ─── Deployments ──────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListDeployments(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/deployments")
|
||||
}
|
||||
|
||||
func CoolifyGetDeployment(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/deployments/"+c.Params("uuid"))
|
||||
}
|
||||
|
||||
// ─── Teams ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func CoolifyListTeams(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/teams")
|
||||
}
|
||||
|
||||
func CoolifyCurrentTeam(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/teams/current")
|
||||
}
|
||||
|
||||
func CoolifyTeamMembers(c *fiber.Ctx) error {
|
||||
return coolifyProxy(c, http.MethodGet, "/teams/current/members")
|
||||
}
|
||||
|
||||
// CoolifyWebhook recibe notificaciones push de Coolify (deployment events, etc.)
|
||||
// Configura en Coolify UI → Settings → Notifications → Webhook → URL: https://admin.u-site.app/app/coolify/webhook
|
||||
// CoolifyWebhook recibe notificaciones push de Coolify (deployments, etc.)
|
||||
// Acepta el payload y devuelve 200; el procesamiento puede extenderse aquí.
|
||||
func CoolifyWebhook(c *fiber.Ctx) error {
|
||||
var payload map[string]interface{}
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
// acepta también body vacío o texto plano
|
||||
payload = map[string]interface{}{"raw": string(c.Body())}
|
||||
}
|
||||
|
||||
// Log del evento para debug
|
||||
eventType := ""
|
||||
if t, ok := payload["type"].(string); ok {
|
||||
eventType = t
|
||||
} else if t, ok := payload["event"].(string); ok {
|
||||
eventType = t
|
||||
}
|
||||
|
||||
_ = eventType // en el futuro: guardar en DB, enviar push, etc.
|
||||
|
||||
return c.JSON(fiber.Map{"ok": true})
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user