1 parent
98b65945f6
commit
0b6dcbd547
13 files changed
+417
-68
No files matched your search
+11
-4
@@ -67,7 +67,8 @@ type Hooks struct {
|
||||
DomainCheck func(name string) (any, error)
|
||||
// Resolve runs one query through the live pipeline and reports the
|
||||
// outcome, so the console can test the server it is talking to.
|
||||
Resolve func(ctx context.Context, name, qtype string) (any, error)
|
||||
Resolve func(ctx context.Context, name, qtype string) (any, error)
|
||||
ResolveUpstream func(ctx context.Context, name, qtype, upstream string) (any, error)
|
||||
// ListDomains pages the compiled rules.
|
||||
ListDomains func(q DomainQuery) (any, error)
|
||||
// AddDomain adds an inline rule and persists it.
|
||||
@@ -75,9 +76,12 @@ type Hooks struct {
|
||||
// DeleteDomain removes a rule and persists the change.
|
||||
DeleteDomain func(ctx context.Context, name, action, list string) error
|
||||
// LocalZones lists, saves and deletes UI-managed DNS master files.
|
||||
LocalZones func(ctx context.Context) ([]ZoneFile, error)
|
||||
SaveLocalZone func(ctx context.Context, name, content string) error
|
||||
DeleteLocalZone func(ctx context.Context, name string) error
|
||||
LocalZones func(ctx context.Context) ([]ZoneFile, error)
|
||||
SaveLocalZone func(ctx context.Context, name, content string) error
|
||||
DeleteLocalZone func(ctx context.Context, name string) error
|
||||
AddressOverrides func(ctx context.Context) (any, error)
|
||||
SaveAddressOverride func(ctx context.Context, domain, address string) error
|
||||
DeleteAddressOverride func(ctx context.Context, domain string) error
|
||||
// ListZones returns the compiled local zones with their records and
|
||||
// delegations, and whether the API may rewrite them.
|
||||
ListZones func() (any, error)
|
||||
@@ -290,6 +294,9 @@ func (s *Server) routes(cfg *config.Config) *http.ServeMux {
|
||||
mux.Handle("DELETE "+base+"domains/{name...}", s.authed(s.handleDomainDelete, true))
|
||||
mux.Handle("GET "+base+"domains/check", s.authed(s.handleDomainCheck, false))
|
||||
mux.Handle("POST "+base+"dns/test", s.authed(s.handleDNSTest, false))
|
||||
mux.Handle("GET "+base+"address-overrides", s.authed(s.handleAddressOverrides, false))
|
||||
mux.Handle("PUT "+base+"address-overrides", s.authed(s.handleAddressOverridePut, true))
|
||||
mux.Handle("DELETE "+base+"address-overrides/{domain}", s.authed(s.handleAddressOverrideDelete, true))
|
||||
mux.Handle("GET "+base+"local-zones", s.authed(s.handleLocalZones, false))
|
||||
mux.Handle("PUT "+base+"local-zones/{name}", s.authed(s.handleLocalZonePut, true))
|
||||
mux.Handle("DELETE "+base+"local-zones/{name}", s.authed(s.handleLocalZoneDelete, true))
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -188,8 +190,9 @@ func (s *Server) handleDNSTest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
var in struct {
|
||||
Name string `json:"name"`
|
||||
QType string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
QType string `json:"type"`
|
||||
Upstream string `json:"upstream"`
|
||||
}
|
||||
if err := decodeJSON(r, &in); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "malformed request body")
|
||||
@@ -200,7 +203,20 @@ func (s *Server) handleDNSTest(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, http.StatusBadRequest, "name is required")
|
||||
return
|
||||
}
|
||||
v, err := s.hooks.Resolve(r.Context(), name, in.QType)
|
||||
resolve := s.hooks.Resolve
|
||||
if in.Upstream != "" {
|
||||
resolve = func(ctx context.Context, n, qt string) (any, error) {
|
||||
if s.hooks.ResolveUpstream == nil {
|
||||
return nil, errors.New("direct upstream lookup unavailable")
|
||||
}
|
||||
return s.hooks.ResolveUpstream(ctx, n, qt, in.Upstream)
|
||||
}
|
||||
}
|
||||
if resolve == nil {
|
||||
writeError(w, http.StatusNotImplemented, "dns test not available")
|
||||
return
|
||||
}
|
||||
v, err := resolve(r.Context(), name, in.QType)
|
||||
if err != nil {
|
||||
writeJSON(w, http.StatusOK, map[string]any{"name": name, "error": err.Error()})
|
||||
return
|
||||
@@ -208,6 +224,50 @@ func (s *Server) handleDNSTest(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
func (s *Server) handleAddressOverrides(w http.ResponseWriter, r *http.Request) {
|
||||
if s.hooks.AddressOverrides == nil {
|
||||
writeError(w, http.StatusNotImplemented, "address overrides unavailable")
|
||||
return
|
||||
}
|
||||
v, err := s.hooks.AddressOverrides(r.Context())
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, v)
|
||||
}
|
||||
func (s *Server) handleAddressOverridePut(w http.ResponseWriter, r *http.Request) {
|
||||
if s.hooks.SaveAddressOverride == nil {
|
||||
writeError(w, http.StatusNotImplemented, "address overrides are read-only")
|
||||
return
|
||||
}
|
||||
var in struct {
|
||||
Domain string `json:"domain"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
if decodeJSON(r, &in) != nil {
|
||||
writeError(w, http.StatusBadRequest, "malformed request body")
|
||||
return
|
||||
}
|
||||
if err := s.hooks.SaveAddressOverride(r.Context(), in.Domain, in.Address); err != nil {
|
||||
writeError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"ok": true})
|
||||
}
|
||||
func (s *Server) handleAddressOverrideDelete(w http.ResponseWriter, r *http.Request) {
|
||||
if s.hooks.DeleteAddressOverride == nil {
|
||||
writeError(w, http.StatusNotImplemented, "address overrides are read-only")
|
||||
return
|
||||
}
|
||||
domain := r.PathValue("domain")
|
||||
if err := s.hooks.DeleteAddressOverride(r.Context(), domain); err != nil {
|
||||
writeError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"ok": true})
|
||||
}
|
||||
|
||||
func (s *Server) handleLocalZones(w http.ResponseWriter, r *http.Request) {
|
||||
if s.hooks.LocalZones == nil {
|
||||
writeError(w, http.StatusNotImplemented, "local zone editor is unavailable")
|
||||
|
||||
Reference in new issue
Block a user