volixer 5 mesiacov pred
rodič
commit
4edadd9145
3 zmenil súbory, kde vykonal 221 pridanie a 1 odobranie
  1. 193 0
      handlers/dns_handler.go
  2. 23 0
      routes/dns.go
  3. 5 1
      routes/routes.go

+ 193 - 0
handlers/dns_handler.go

@@ -0,0 +1,193 @@
+package handlers
+
+import (
+	"bufio"
+	"byom-infra-api/config"
+	"encoding/json"
+	"fmt"
+	"log"
+	"math/rand"
+	"net/http"
+	"os"
+	"regexp"
+	"strings"
+
+	"github.com/gorilla/mux"
+)
+
+type DNSRecord struct {
+	FieldType string `json:"fieldType"`
+	SubDomain string `json:"subDomain"`
+	Target    string `json:"target"`
+	TTL       int    `json:"ttl"`
+}
+
+type DNSHandler struct {
+	Zone string
+}
+
+func NewDNSHandler() *DNSHandler {
+	// Try to get zone from environment variable first
+	zone := os.Getenv("OVH_DNS_ZONE")
+
+	// Fallback to default if neither is set
+	if zone == "" {
+		zone = "linuxforward.com"
+	}
+
+	return &DNSHandler{
+		Zone: zone,
+	}
+}
+
+// generateRandomWord generates a random 6-letter word from /usr/share/dict/words
+func (h *DNSHandler) generateRandomWord() (string, error) {
+	file, err := os.Open("/usr/share/dict/words")
+	if err != nil {
+		return "", err
+	}
+	defer file.Close()
+
+	var words []string
+	scanner := bufio.NewScanner(file)
+	regex := regexp.MustCompile(`^[a-zA-Z]{6}$`)
+
+	for scanner.Scan() {
+		word := strings.ToLower(scanner.Text())
+		if regex.MatchString(word) {
+			words = append(words, word)
+		}
+	}
+
+	if len(words) == 0 {
+		return "", fmt.Errorf("no suitable words found")
+	}
+
+	return words[rand.Intn(len(words))], nil
+}
+
+// CreateDNSRecord handles the creation of a new DNS record
+func (h *DNSHandler) CreateDNSRecord(w http.ResponseWriter, r *http.Request) {
+	log.Printf("Handling POST request for new DNS record from %s", r.RemoteAddr)
+
+	// Parse request body for target IP
+	var request struct {
+		Target string `json:"target"`
+	}
+
+	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
+		log.Printf("Error decoding request body: %v", err)
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+
+	// Generate random subdomain
+	word1, err := h.generateRandomWord()
+	if err != nil {
+		log.Printf("Error generating first word: %v", err)
+		http.Error(w, "Failed to generate subdomain", http.StatusInternalServerError)
+		return
+	}
+
+	word2, err := h.generateRandomWord()
+	if err != nil {
+		log.Printf("Error generating second word: %v", err)
+		http.Error(w, "Failed to generate subdomain", http.StatusInternalServerError)
+		return
+	}
+
+	// Create DNS record
+	record := DNSRecord{
+		FieldType: "A",
+		SubDomain: word1 + "-" + word2,
+		Target:    request.Target,
+		TTL:       0,
+	}
+
+	var response DNSRecord
+	err = config.OVHClient.Post("/domain/zone/"+h.Zone+"/record", record, &response)
+	if err != nil {
+		log.Printf("Error creating DNS record: %v", err)
+		http.Error(w, "Failed to create DNS record: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Refresh the zone
+	err = h.refreshZone()
+	if err != nil {
+		log.Printf("Warning: zone refresh failed: %v", err)
+	}
+
+	log.Printf("Successfully created DNS record: %s.%s", response.SubDomain, h.Zone)
+
+	w.Header().Set("Content-Type", "application/json")
+	w.WriteHeader(http.StatusCreated)
+	if err := json.NewEncoder(w).Encode(response); err != nil {
+		log.Printf("Error encoding response: %v", err)
+		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
+		return
+	}
+}
+
+// DeleteDNSRecord handles the deletion of a DNS record
+func (h *DNSHandler) DeleteDNSRecord(w http.ResponseWriter, r *http.Request) {
+	vars := mux.Vars(r)
+	recordID := vars["id"]
+	log.Printf("Handling DELETE request for DNS record: %s from %s", recordID, r.RemoteAddr)
+
+	err := config.OVHClient.Delete("/domain/zone/"+h.Zone+"/record/"+recordID, nil)
+	if err != nil {
+		log.Printf("Error deleting DNS record %s: %v", recordID, err)
+		http.Error(w, "Failed to delete DNS record: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Refresh the zone
+	err = h.refreshZone()
+	if err != nil {
+		log.Printf("Warning: zone refresh failed: %v", err)
+	}
+
+	log.Printf("Successfully deleted DNS record: %s", recordID)
+	w.WriteHeader(http.StatusNoContent)
+}
+
+// refreshZone refreshes the DNS zone
+func (h *DNSHandler) refreshZone() error {
+	return config.OVHClient.Post("/domain/zone/"+h.Zone+"/refresh", nil, nil)
+}
+
+// ListDNSRecords handles listing all A records in the DNS zone
+func (h *DNSHandler) ListDNSRecords(w http.ResponseWriter, r *http.Request) {
+	log.Printf("Handling GET request for DNS records from %s", r.RemoteAddr)
+
+	var recordIDs []int
+	err := config.OVHClient.Get("/domain/zone/"+h.Zone+"/record", &recordIDs)
+	if err != nil {
+		log.Printf("Error getting DNS record IDs: %v", err)
+		http.Error(w, "Failed to get DNS records: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	var records []DNSRecord
+	for _, id := range recordIDs {
+		var record DNSRecord
+		err := config.OVHClient.Get(fmt.Sprintf("/domain/zone/%s/record/%d", h.Zone, id), &record)
+		if err != nil {
+			log.Printf("Error getting DNS record %d: %v", id, err)
+			continue
+		}
+
+		// Only include A records
+		if record.FieldType == "A" {
+			records = append(records, record)
+		}
+	}
+
+	w.Header().Set("Content-Type", "application/json")
+	if err := json.NewEncoder(w).Encode(records); err != nil {
+		log.Printf("Error encoding response: %v", err)
+		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
+		return
+	}
+}

+ 23 - 0
routes/dns.go

@@ -0,0 +1,23 @@
+package routes
+
+import (
+	"byom-infra-api/handlers"
+	"net/http"
+)
+
+var dnsHandler = handlers.NewDNSHandler()
+
+// CreateDNSRecord forwards the request to the DNSHandler
+func CreateDNSRecord(w http.ResponseWriter, r *http.Request) {
+	dnsHandler.CreateDNSRecord(w, r)
+}
+
+// DeleteDNSRecord forwards the request to the DNSHandler
+func DeleteDNSRecord(w http.ResponseWriter, r *http.Request) {
+	dnsHandler.DeleteDNSRecord(w, r)
+}
+
+// ListDNSRecords forwards the request to the DNSHandler
+func ListDNSRecords(w http.ResponseWriter, r *http.Request) {
+	dnsHandler.ListDNSRecords(w, r)
+}

+ 5 - 1
routes/routes.go

@@ -17,5 +17,9 @@ func SetupRoutes(r *mux.Router) {
 	r.HandleFunc("/sshkey", CreateSSHKey).Methods("POST")
 	r.HandleFunc("/sshkey/{id}", DeleteSSHKey).Methods("DELETE")
 
-	// Add other routes here as needed
+	// DNS routes
+	r.HandleFunc("/dns", ListDNSRecords).Methods("GET")
+	r.HandleFunc("/dns", CreateDNSRecord).Methods("POST")
+	r.HandleFunc("/dns/{id}", DeleteDNSRecord).Methods("DELETE")
+
 }