Files
soft_usite/pkg/services/hostinger_service.go
T

193 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package services
import (
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
const hostingerBaseURL = "https://developers.hostinger.com/api"
// HostingerClient es el cliente HTTP para la API de Hostinger.
type HostingerClient struct {
token string
httpClient *http.Client
}
// NewHostingerClient crea un cliente con el token Bearer.
func NewHostingerClient(token string) *HostingerClient {
return &HostingerClient{
token: token,
httpClient: &http.Client{
Timeout: 20 * time.Second,
},
}
}
// get realiza una petición GET autenticada y decodifica el cuerpo en dest.
func (c *HostingerClient) get(path string, dest interface{}) error {
req, err := http.NewRequest(http.MethodGet, hostingerBaseURL+path, nil)
if err != nil {
return fmt.Errorf("hostinger: crear request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("hostinger: ejecutar request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("hostinger: leer body: %w", err)
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("hostinger: status %d %s", resp.StatusCode, string(body))
}
if dest != nil {
if err := json.Unmarshal(body, dest); err != nil {
return fmt.Errorf("hostinger: decodificar respuesta: %w", err)
}
}
return nil
}
// ─── Tipos de respuesta ──────────────────────────────────────────────────────
// HostingerVPS representa una máquina virtual VPS.
type HostingerVPS struct {
ID int `json:"id"`
Hostname string `json:"hostname"`
State string `json:"state"`
Plan string `json:"plan"`
DataCenter string `json:"data_center"`
CPU int `json:"cpus"`
RAMBytes int64 `json:"ram"`
DiskBytes int64 `json:"disk"`
IPV4 string `json:"ipv4"`
IPV6 string `json:"ipv6"`
}
// HostingerDomain representa un dominio en el portafolio.
type HostingerDomain struct {
Domain string `json:"domain"`
Status string `json:"status"`
ExpiresAt string `json:"expires_at"`
RegisteredAt string `json:"registered_at"`
}
// HostingerDNSRecord representa un registro DNS.
type HostingerDNSRecord struct {
ID int `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Content string `json:"content"`
TTL int `json:"ttl"`
Priority int `json:"priority,omitempty"`
}
// HostingerOrder representa una orden de facturación.
type HostingerOrder struct {
ID int `json:"id"`
Status string `json:"status"`
Total float64 `json:"total"`
Currency string `json:"currency"`
CreatedAt string `json:"created_at"`
}
// HostingerHosting representa una cuenta de hosting.
type HostingerHosting struct {
ID int `json:"id"`
Domain string `json:"domain"`
Plan string `json:"plan"`
State string `json:"state"`
ExpiresAt string `json:"expires_at"`
DiskUsed int64 `json:"disk_used"`
DiskLimit int64 `json:"disk_limit"`
}
// ─── Métodos de la API ───────────────────────────────────────────────────────
// GetVPSList obtiene la lista de VPS/VMs.
func (c *HostingerClient) GetVPSList() ([]HostingerVPS, error) {
var result struct {
Data []HostingerVPS `json:"data"`
}
if err := c.get("/vps/v1/virtual-machines", &result); err != nil {
// intenta respuesta array directa
var arr []HostingerVPS
if err2 := c.get("/vps/v1/virtual-machines", &arr); err2 != nil {
return nil, err
}
return arr, nil
}
return result.Data, nil
}
// GetDomains obtiene el portafolio de dominios.
func (c *HostingerClient) GetDomains() ([]HostingerDomain, error) {
var result struct {
Data []HostingerDomain `json:"data"`
}
if err := c.get("/domains/v1/portfolio", &result); err != nil {
var arr []HostingerDomain
if err2 := c.get("/domains/v1/portfolio", &arr); err2 != nil {
return nil, err
}
return arr, nil
}
return result.Data, nil
}
// GetDNSRecords obtiene los registros DNS de un dominio.
func (c *HostingerClient) GetDNSRecords(domain string) ([]HostingerDNSRecord, error) {
var result struct {
Data []HostingerDNSRecord `json:"data"`
}
path := fmt.Sprintf("/dns/v1/zones/%s/records", domain)
if err := c.get(path, &result); err != nil {
var arr []HostingerDNSRecord
if err2 := c.get(path, &arr); err2 != nil {
return nil, err
}
return arr, nil
}
return result.Data, nil
}
// GetOrders obtiene las órdenes de facturación.
func (c *HostingerClient) GetOrders() ([]HostingerOrder, error) {
var result struct {
Data []HostingerOrder `json:"data"`
}
if err := c.get("/billing/v1/orders", &result); err != nil {
var arr []HostingerOrder
if err2 := c.get("/billing/v1/orders", &arr); err2 != nil {
return nil, err
}
return arr, nil
}
return result.Data, nil
}
// GetHostingAccounts obtiene las cuentas de hosting.
func (c *HostingerClient) GetHostingAccounts() ([]HostingerHosting, error) {
var result struct {
Data []HostingerHosting `json:"data"`
}
if err := c.get("/hosting/v1/accounts", &result); err != nil {
var arr []HostingerHosting
if err2 := c.get("/hosting/v1/accounts", &arr); err2 != nil {
return nil, err
}
return arr, nil
}
return result.Data, nil
}