dnsexit-manager/dnsexit_manager.go

198 lines
3.2 KiB
Go

package dnsexit_manager
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"sync"
dns "git.uoc.run.place/OxFF/dns-manager"
)
const API_BASE_URL = "https://api.dnsexit.com/dns/"
type Config struct {
DOMAIN_NAME string
API_KEY string
API_URL string
}
type client struct {
Locker sync.Mutex
API_KEY string
API_URL string
Domain string
}
type dnsexitDTO struct {
ApiKey string `json:"apikey"`
Domain string `json:"domain"`
Add *dns.Record `json:"add,omitempty"`
Update *dns.Record `json:"update,omitempty"`
Delete *dns.Record `json:"delete,omitempty"`
}
func (c *client) AddRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock()
defer c.Locker.Unlock()
request_body, err := json.Marshal(&dnsexitDTO{
ApiKey: c.API_KEY,
Domain: c.Domain,
Add: rec,
})
if err != nil {
return err, nil
}
fmt.Println(string(request_body))
resp, err := http.Post(
c.API_URL,
"application/json",
bytes.NewBuffer(request_body),
)
if err != nil {
return err, nil
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err, nil
}
return nil, &dns.Response{Message: string(body)}
}
func (c *client) DeleteRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock()
defer c.Locker.Unlock()
request_body, err := json.Marshal(&dnsexitDTO{
ApiKey: c.API_KEY,
Domain: c.Domain,
Delete: rec,
})
if err != nil {
return err, nil
}
resp, err := http.Post(
c.API_URL,
"application/json",
bytes.NewBuffer(request_body),
)
if err != nil {
return err, nil
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err, nil
}
return nil, &dns.Response{Message: string(body)}
}
func (c *client) UpdateRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock()
defer c.Locker.Unlock()
request_body, err := json.Marshal(&dnsexitDTO{
ApiKey: c.API_KEY,
Domain: c.Domain,
Update: rec,
})
if err != nil {
return err, nil
}
resp, err := http.Post(
c.API_URL,
"application/json",
bytes.NewBuffer(request_body),
)
if err != nil {
return err, nil
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err, nil
}
return nil, &dns.Response{Message: string(body)}
}
func (c *client) GetRecords() (error, []*dns.Record) {
var subdomains = CreateSet()
var wg sync.WaitGroup
result_chan := make(chan []*dns.Record)
err_chan := make(chan error)
err, namesevers := c.getNSRecods()
if err != nil {
return err, nil
}
for _, ns := range *namesevers {
wg.Add(1)
go func(ns string) {
defer wg.Done()
err, records := find_dns_records(c.Domain, ns)
if err != nil {
err_chan <- err
return
}
result_chan <- records
}(ns)
}
go func() {
wg.Wait()
close(result_chan)
close(err_chan)
}()
for {
select {
case records, ok := <-result_chan:
if !ok {
return nil, subdomains.List()
}
for record := range records {
subdomains.Add(record)
}
case _, _ = <-err_chan:
}
}
}
func (conf Config) New() dns.Actions {
var api_url string = API_BASE_URL
if len(conf.API_URL) > 5 {
api_url = conf.API_URL
}
return &client{
Locker: sync.Mutex{},
API_KEY: conf.API_KEY,
API_URL: api_url,
Domain: conf.DOMAIN_NAME,
}
}