package controllers import ( "encoding/json" "fmt" "io" "net/http" "strings" "time" "github.com/gofiber/fiber/v2" "github.com/sujit-baniya/fiber-boilerplate/pkg/models" ) 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 { return nil, 0, err } req.Header.Set("Authorization", "Bearer "+cfg.ApiToken) req.Header.Set("Accept", "application/json") if contentType != "" { req.Header.Set("Content-Type", contentType) } resp, err := client.Do(req) if err != nil { return nil, 0, err } defer resp.Body.Close() body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024*1024)) return body, resp.StatusCode, nil } func coolifyProxy(c *fiber.Ctx, method, endpoint string) error { cfg, err := models.GetCoolifyConfig() if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Configura primero la integración Coolify"}) } 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 { 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))) } c.Status(status) return c.JSON(result) } func CoolifyIndex(c *fiber.Ctx) error { cfg, _ := models.GetCoolifyConfig() return c.Render("coolify", fiber.Map{ "user": c.Locals("user").(map[string]interface{}), "modules": c.Locals("userModules"), "config": cfg, }, "layouts/main") } func CoolifyGetConfig(c *fiber.Ctx) error { cfg, err := models.GetCoolifyConfig() if err != nil { return c.JSON(fiber.Map{"config": nil}) } masked := "••••••••" if cfg.ApiToken == "" { masked = "" } return c.JSON(fiber.Map{"config": fiber.Map{ "ID": cfg.ID, "nombre": cfg.Nombre, "base_url": cfg.BaseURL, "api_token": masked, "activo": cfg.Activo, }}) } func CoolifySaveConfig(c *fiber.Ctx) error { type Req struct { Nombre string `json:"nombre"` BaseURL string `json:"base_url"` ApiToken string `json:"api_token"` Activo bool `json:"activo"` } var req Req if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"}) } req.BaseURL = strings.TrimRight(strings.TrimSpace(req.BaseURL), "/") if req.BaseURL == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "base_url es requerido"}) } cfg, err := models.UpsertCoolifyConfig(req.Nombre, req.BaseURL, req.ApiToken, req.Activo) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"ok": true, "config": cfg}) } func CoolifyTestConnection(c *fiber.Ctx) error { cfg, err := models.GetCoolifyConfig() if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Sin config"}) } base := strings.TrimRight(cfg.BaseURL, "/") client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Get(base + "/api/health") if err != nil { return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()}) } defer resp.Body.Close() body, _ := io.ReadAll(io.LimitReader(resp.Body, 64*1024)) var result json.RawMessage if jsonErr := json.Unmarshal(body, &result); jsonErr != nil { result = json.RawMessage(fmt.Sprintf(`{"raw":%q}`, string(body))) } c.Status(resp.StatusCode) return c.JSON(result) } 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.MethodGet, "/applications/"+c.Params("uuid")+"/start") } func CoolifyApplicationStop(c *fiber.Ctx) error { return coolifyProxy(c, http.MethodGet, "/applications/"+c.Params("uuid")+"/stop") } func CoolifyApplicationRestart(c *fiber.Ctx) error { 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 { return coolifyProxy(c, http.MethodPost, "/deploy") } 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") } 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") } 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") } 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") } 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")) } 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") }