279 lines
10 KiB
Go
279 lines
10 KiB
Go
package controllers
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
|
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
|
)
|
|
|
|
// ─── Configuración ────────────────────────────────────────────────────────────
|
|
|
|
// CloudflareConfigPage renderiza la vista de gestión de Cloudflare.
|
|
func CloudflareConfigPage(c *fiber.Ctx) error {
|
|
cfg, _ := models.GetCloudflareConfig()
|
|
if err := c.Render("cloudflare", fiber.Map{
|
|
"Title": "Cloudflare API",
|
|
"Config": cfg,
|
|
"user": c.Locals("user"),
|
|
"modules": c.Locals("userModules"),
|
|
}, "layouts/main"); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SaveCloudflareConfig guarda o actualiza el API token de Cloudflare.
|
|
func SaveCloudflareConfig(c *fiber.Ctx) error {
|
|
type body struct {
|
|
ID uint `json:"id" form:"id"`
|
|
APIToken string `json:"api_token" form:"api_token"`
|
|
AccountID string `json:"account_id" form:"account_id"`
|
|
Nota string `json:"nota" form:"nota"`
|
|
}
|
|
var b body
|
|
if err := c.BodyParser(&b); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
if b.APIToken == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "api_token requerido"})
|
|
}
|
|
|
|
cfg := models.CloudflareConfig{
|
|
APIToken: strings.TrimSpace(b.APIToken),
|
|
AccountID: strings.TrimSpace(b.AccountID),
|
|
Nota: b.Nota,
|
|
}
|
|
cfg.ID = b.ID
|
|
|
|
if err := models.SaveCloudflareConfig(cfg); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"message": "Configuración guardada"})
|
|
}
|
|
|
|
// ─── Helper ───────────────────────────────────────────────────────────────────
|
|
|
|
func cloudflareClient() (*services.CloudflareClient, error) {
|
|
cfg, err := models.GetCloudflareConfig()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return services.NewCloudflareClient(strings.TrimSpace(cfg.APIToken), strings.TrimSpace(cfg.AccountID)), nil
|
|
}
|
|
|
|
// VerifyCloudflareToken verifica que el token activo sea válido contra la API de Cloudflare.
|
|
func VerifyCloudflareToken(c *fiber.Ctx) error {
|
|
cfg, err := models.GetCloudflareConfig()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"ok": false,
|
|
"error": "No hay configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
token := strings.TrimSpace(cfg.APIToken)
|
|
if token == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"ok": false, "error": "Token vacío"})
|
|
}
|
|
client := services.NewCloudflareClient(token, strings.TrimSpace(cfg.AccountID))
|
|
result, err := client.VerifyToken()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"ok": false, "error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"ok": true, "data": result})
|
|
}
|
|
|
|
// ─── Endpoints de datos ───────────────────────────────────────────────────────
|
|
|
|
// GetCloudflareUser devuelve la información del usuario autenticado en Cloudflare.
|
|
func GetCloudflareUser(c *fiber.Ctx) error {
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
data, err := client.GetUser()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": data})
|
|
}
|
|
|
|
// GetCloudflareZones lista todas las zonas (dominios) de la cuenta.
|
|
func GetCloudflareZones(c *fiber.Ctx) error {
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
data, err := client.GetZones()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": data})
|
|
}
|
|
|
|
// GetCloudflareDNS devuelve los registros DNS de una zona (:zone_id).
|
|
func GetCloudflareDNS(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
if zoneID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id requerido"})
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
data, err := client.GetDNSRecords(zoneID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": data, "zone_id": zoneID})
|
|
}
|
|
|
|
// GetCloudflareSSL devuelve los certificados SSL de una zona (:zone_id).
|
|
func GetCloudflareSSL(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
if zoneID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id requerido"})
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
data, err := client.GetSSLCertificates(zoneID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": data, "zone_id": zoneID})
|
|
}
|
|
|
|
// GetCloudflareFirewall devuelve las reglas de firewall de una zona (:zone_id).
|
|
func GetCloudflareFirewall(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
if zoneID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id requerido"})
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
data, err := client.GetFirewallRules(zoneID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": data, "zone_id": zoneID})
|
|
}
|
|
|
|
// ─── DNS CRUD ─────────────────────────────────────────────────────────────────
|
|
|
|
// CreateCloudflareDNS crea un nuevo registro DNS en la zona (:zone_id).
|
|
func CreateCloudflareDNS(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
if zoneID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id requerido"})
|
|
}
|
|
var input services.CFDNSRecordInput
|
|
if err := c.BodyParser(&input); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
if input.Type == "" || input.Name == "" || input.Content == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "type, name y content son requeridos"})
|
|
}
|
|
if input.TTL == 0 {
|
|
input.TTL = 1 // automático
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
record, err := client.CreateDNSRecord(zoneID, input)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"data": record})
|
|
}
|
|
|
|
// UpdateCloudflareDNS actualiza (PUT completo) un registro DNS (:zone_id/:record_id).
|
|
func UpdateCloudflareDNS(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
recordID := c.Params("record_id")
|
|
if zoneID == "" || recordID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id y record_id requeridos"})
|
|
}
|
|
var input services.CFDNSRecordInput
|
|
if err := c.BodyParser(&input); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
if input.Type == "" || input.Name == "" || input.Content == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "type, name y content son requeridos"})
|
|
}
|
|
if input.TTL == 0 {
|
|
input.TTL = 1
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
record, err := client.UpdateDNSRecord(zoneID, recordID, input)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": record})
|
|
}
|
|
|
|
// PatchCloudflareDNS actualiza parcialmente un registro DNS (:zone_id/:record_id).
|
|
func PatchCloudflareDNS(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
recordID := c.Params("record_id")
|
|
if zoneID == "" || recordID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id y record_id requeridos"})
|
|
}
|
|
var input services.CFDNSRecordInput
|
|
if err := c.BodyParser(&input); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
record, err := client.PatchDNSRecord(zoneID, recordID, input)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": record})
|
|
}
|
|
|
|
// DeleteCloudflareDNS elimina un registro DNS (:zone_id/:record_id).
|
|
func DeleteCloudflareDNS(c *fiber.Ctx) error {
|
|
zoneID := c.Params("zone_id")
|
|
recordID := c.Params("record_id")
|
|
if zoneID == "" || recordID == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "zone_id y record_id requeridos"})
|
|
}
|
|
client, err := cloudflareClient()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{
|
|
"error": "No se encontró configuración activa de Cloudflare",
|
|
})
|
|
}
|
|
if err := client.DeleteDNSRecord(zoneID, recordID); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"message": "Registro DNS eliminado"})
|
|
}
|