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 convertInterfaceSliceToStruct(slice []interface{}) *[]dns.Record { var domains []dns.Record for _, domain := range slice { fmt.Println(domain) } return &domains } 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 { records_new := convertInterfaceSliceToStruct(subdomains.List()) return nil, records_new } 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, } }