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 { } }