Compare commits

..

No commits in common. "main" and "v0.0.4-debug" have entirely different histories.

5 changed files with 70 additions and 84 deletions

View File

@ -1,17 +0,0 @@
### dnsexit-manager library
This is a part of my handmade DNS management project.
It's a driver that's create ability to manage your DNSexit subdomains via API.
#### How it works?
This driver relies on `dns-manager` library which describes all drivers API you may use.
The architecture is as simple as ABC: the drivers must implement all methods from `dns-manager`
library to be compatible with it.
It means anyone else can extend this project by creating own driver for their DNS providers.
#### To-Do list
- [ ] Better error handling
- [ ] Docs for the project
- [ ] Make an example of usage

View File

@ -8,7 +8,7 @@ import (
"net/http" "net/http"
"sync" "sync"
dns "git.jolbec.icu/OxFF/dns-manager" dns "git.uoc.run.place/OxFF/dns-manager"
) )
const API_BASE_URL = "https://api.dnsexit.com/dns/" const API_BASE_URL = "https://api.dnsexit.com/dns/"
@ -34,7 +34,18 @@ type dnsexitDTO struct {
Delete *dns.Record `json:"delete,omitempty"` Delete *dns.Record `json:"delete,omitempty"`
} }
func (c *client) AddRecord(rec *dns.Record) (*dns.Response, error) { func convertInterfaceSliceToStruct(slice []interface{}) *[]dns.Domain {
var domains []dns.Domain
for _, domain := range slice {
fmt.Println(domain)
}
return &domains
}
func (c *client) AddRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock() c.Locker.Lock()
defer c.Locker.Unlock() defer c.Locker.Unlock()
@ -45,7 +56,7 @@ func (c *client) AddRecord(rec *dns.Record) (*dns.Response, error) {
}) })
if err != nil { if err != nil {
return nil, err return err, nil
} }
fmt.Println(string(request_body)) fmt.Println(string(request_body))
@ -57,19 +68,19 @@ func (c *client) AddRecord(rec *dns.Record) (*dns.Response, error) {
) )
if err != nil { if err != nil {
return nil, err return err, nil
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return err, nil
} }
return &dns.Response{Message: string(body)}, nil return nil, &dns.Response{Message: string(body)}
} }
func (c *client) DeleteRecord(rec *dns.Record) (*dns.Response, error) { func (c *client) DeleteRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock() c.Locker.Lock()
defer c.Locker.Unlock() defer c.Locker.Unlock()
@ -79,7 +90,7 @@ func (c *client) DeleteRecord(rec *dns.Record) (*dns.Response, error) {
Delete: rec, Delete: rec,
}) })
if err != nil { if err != nil {
return nil, err return err, nil
} }
resp, err := http.Post( resp, err := http.Post(
@ -87,21 +98,20 @@ func (c *client) DeleteRecord(rec *dns.Record) (*dns.Response, error) {
"application/json", "application/json",
bytes.NewBuffer(request_body), bytes.NewBuffer(request_body),
) )
if err != nil { if err != nil {
return nil, err return err, nil
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return err, nil
} }
return &dns.Response{Message: string(body)}, nil return nil, &dns.Response{Message: string(body)}
} }
func (c *client) UpdateRecord(rec *dns.Record) (*dns.Response, error) { func (c *client) UpdateRecord(rec *dns.Record) (error, *dns.Response) {
c.Locker.Lock() c.Locker.Lock()
defer c.Locker.Unlock() defer c.Locker.Unlock()
@ -110,9 +120,8 @@ func (c *client) UpdateRecord(rec *dns.Record) (*dns.Response, error) {
Domain: c.Domain, Domain: c.Domain,
Update: rec, Update: rec,
}) })
if err != nil { if err != nil {
return nil, err return err, nil
} }
resp, err := http.Post( resp, err := http.Post(
@ -120,33 +129,32 @@ func (c *client) UpdateRecord(rec *dns.Record) (*dns.Response, error) {
"application/json", "application/json",
bytes.NewBuffer(request_body), bytes.NewBuffer(request_body),
) )
if err != nil { if err != nil {
return nil, err return err, nil
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return err, nil
} }
return &dns.Response{Message: string(body)}, nil return nil, &dns.Response{Message: string(body)}
} }
func (c *client) GetRecords() (*[]dns.Record, error) { func (c *client) GetRecords() (error, []*dns.Record) {
var subdomains = NewRecordSet() var subdomains = CreateSet()
var wg sync.WaitGroup var wg sync.WaitGroup
result_chan := make(chan []*dns.Record) result_chan := make(chan []*dns.Record)
err_chan := make(chan error) err_chan := make(chan error)
err, nameservers := c.getNSRecods() err, namesevers := c.getNSRecods()
if err != nil { if err != nil {
return nil, err return err, nil
} }
for _, ns := range *nameservers { for _, ns := range *namesevers {
wg.Add(1) wg.Add(1)
go func(ns string) { go func(ns string) {
@ -172,19 +180,19 @@ func (c *client) GetRecords() (*[]dns.Record, error) {
select { select {
case records, ok := <-result_chan: case records, ok := <-result_chan:
if !ok { if !ok {
return subdomains.List(), nil return nil, convertInterfaceSliceToStruct(subdomains.List())
} }
for _, record := range records { for record := range records {
subdomains.Add(record) subdomains.Add(record)
} }
case _, _ = <-err_chan: case _, _ = <-err_chan:
} }
} }
} }
func (conf Config) New() (dns.Actions, error) { func (conf Config) New() dns.Actions {
var api_url string = API_BASE_URL var api_url string = API_BASE_URL
if len(conf.API_URL) > 5 { if len(conf.API_URL) > 5 {
@ -196,5 +204,5 @@ func (conf Config) New() (dns.Actions, error) {
API_KEY: conf.API_KEY, API_KEY: conf.API_KEY,
API_URL: api_url, API_URL: api_url,
Domain: conf.DOMAIN_NAME, Domain: conf.DOMAIN_NAME,
}, nil }
} }

19
go.mod
View File

@ -1,16 +1,13 @@
module git.jolbec.icu/OxFF/dnsexit-manager module git.uoc.run.place/OxFF/dnsexit-manager
go 1.23.4 go 1.23.4
require ( require (
git.jolbec.icu/OxFF/dns-manager v0.0.5 git.uoc.run.place/OxFF/dns-manager v0.0.0-20250107205730-c4ab438a9fd5 // indirect
github.com/miekg/dns v1.1.62 github.com/miekg/dns v1.1.62 // indirect
) golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.27.0 // indirect
require ( golang.org/x/sync v0.7.0 // indirect
golang.org/x/mod v0.22.0 // indirect golang.org/x/sys v0.22.0 // indirect
golang.org/x/net v0.34.0 // indirect golang.org/x/tools v0.22.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/tools v0.29.0 // indirect
) )

42
set.go
View File

@ -1,35 +1,33 @@
package dnsexit_manager package dnsexit_manager
import dns "git.jolbec.icu/OxFF/dns-manager"
type RecordSet struct { type Set struct {
records map[dns.Record]struct{} elements map[interface{}]struct{}
} }
func NewRecordSet() *RecordSet { func CreateSet() *Set {
return &RecordSet{ return &Set{
records: make(map[dns.Record]struct{}), elements: make(map[interface{}]struct{}),
} }
} }
func (s *RecordSet) Add(record *dns.Record) { func (set *Set) Add(value interface{}) {
s.records[*record] = struct{}{} _, found := set.elements[value]
if !found{
set.elements[value] = struct{}{}
}
} }
func (s *RecordSet) Remove(record dns.Record) { func (set *Set) Delete(value interface{}) {
delete(s.records, record) delete(set.elements, value)
} }
func (s *RecordSet) Contains(record *dns.Record) bool { func (set *Set) List() []interface{} {
_, exists := s.records[*record] keys := make([]interface{}, 0, len(set.elements))
return exists for key := range set.elements {
} keys = append(keys, key)
}
func (s *RecordSet) List() *[]dns.Record { return keys
records := make([]dns.Record, 0, len(s.records))
for record := range s.records {
records = append(records, record)
}
return &records
} }

View File

@ -6,7 +6,7 @@ import (
"strconv" "strconv"
"strings" "strings"
dns "git.jolbec.icu/OxFF/dns-manager" dns "git.uoc.run.place/OxFF/dns-manager"
dns_req "github.com/miekg/dns" dns_req "github.com/miekg/dns"
) )