godns/hosts/hosts_api.go

140 lines
2.5 KiB
Go
Raw Permalink Normal View History

2021-04-15 04:41:06 +00:00
package hosts
import (
"github.com/go-chi/chi"
"github.com/go-chi/render"
"github.com/miekg/dns"
"net/http"
"time"
)
const (
defaultDuration = 600 * time.Second
)
func EnableAPI(h Provider, r chi.Router) {
a := &api{hosts: h}
r.Route("/hosts", func(sub chi.Router) {
sub.Get("/", a.hostsGet)
sub.Post("/", a.hostsCreate)
sub.Patch("/{domain}", a.hostsUpdate)
sub.Delete("/{domain}", a.hostsDelete)
})
}
type api struct {
hosts Provider
}
// hostsGet handles GET requests on /hosts (list records)
func (a *api) hostsGet(w http.ResponseWriter, r *http.Request) {
hosts, err := a.hosts.List()
if err != nil {
return
}
render.JSON(w, r, hosts)
}
type requestBody struct {
Domain string `json:"domain"`
Type string `json:"type"`
Values []string `json:"values"`
TTL int `json:"ttl"`
}
func (b requestBody) TTLDuration() time.Duration {
if b.TTL > 0 {
return time.Duration(b.TTL) * time.Second
}
return defaultDuration
}
// hostsUpdate handles POST requests on /hosts
func (a *api) hostsCreate(w http.ResponseWriter, r *http.Request) {
var writer Writer
var ok bool
if writer, ok = a.hosts.(Writer); !ok {
w.WriteHeader(http.StatusNotImplemented)
return
}
var request requestBody
err := render.DefaultDecoder(r, &request)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
var recordType uint16
if recordType, ok = dns.StringToType[request.Type]; !ok {
w.WriteHeader(http.StatusBadRequest)
return
}
err = writer.Set(request.Domain, &Host{
Type: recordType,
Values: request.Values,
TTL: request.TTLDuration(),
})
if err != nil {
}
}
// hostsUpdate handles PATCH requests on /hosts/:domain
func (a *api) hostsUpdate(w http.ResponseWriter, r *http.Request) {
domain := chi.URLParam(r, "domain")
if domain == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
var writer Writer
var ok bool
if writer, ok = a.hosts.(Writer); !ok {
w.WriteHeader(http.StatusNotImplemented)
return
}
// TODO: Read record from provider, update data from body, save
err := writer.Set(domain, nil)
if err != nil {
}
}
// hostsDelete handles DELETE requests on /hosts/:domain
func (a *api) hostsDelete(w http.ResponseWriter, r *http.Request) {
domain := chi.URLParam(r, "domain")
if domain == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
var writer Writer
var ok bool
if writer, ok = a.hosts.(Writer); !ok {
w.WriteHeader(http.StatusNotImplemented)
return
}
err := writer.Delete(domain)
if err != nil {
}
}