The Zones page's New reverse zone lists every network the records use without a reverse zone, in every view, also where nothing is suggested (suggestions off, dismissed, public views), marked. Picking one fills in the network and view; size buttons (/48 /56 /64 /128, /16 /24 /32) re-mask it around a record's address, so a /48 becomes the records' own /64. Fill stays on. jarl zone suggest-reverse --all [--view V]; GET /reverse-zones/suggestions?all=1&view=. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
1.8 KiB
Go
59 lines
1.8 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"jarl/internal/auth"
|
|
"jarl/internal/engine"
|
|
)
|
|
|
|
// zoneFillPTR: POST /zones/{zone}/fill-ptr adds the PTR records a reverse
|
|
// zone lacks for its view's A and AAAA records (docs/reverse.md).
|
|
func (s *Server) zoneFillPTR(w http.ResponseWriter, r *http.Request, p *auth.Principal) error {
|
|
st, err := s.state(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
z, err := s.zoneByPath(r, st, p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.mutate(w, r, p, "", []engine.Request{engine.NewRequest(engine.OpZoneFillPTR, z.ID, engine.LinkInput{ZoneID: z.ID})}, nil)
|
|
}
|
|
|
|
// reverseSuggestions: GET /reverse-zones/suggestions lists the reverse
|
|
// zones the private views lack for their records' addresses. ?all=1 adds
|
|
// the ones not suggested unasked (public views, views with suggestions
|
|
// off, dismissed), marked hidden; ?view= narrows it to one view.
|
|
func (s *Server) reverseSuggestions(w http.ResponseWriter, r *http.Request, p *auth.Principal) error {
|
|
st, err := s.state(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
out := []engine.ReverseSuggestion{}
|
|
for _, sg := range s.eng.ReverseSuggestions(st, engine.ReverseOptions{All: queryBool(r, "all"), View: r.URL.Query().Get("view")}) {
|
|
if p.CanSeeZone(sg.Zone+".", sg.View) {
|
|
out = append(out, sg)
|
|
}
|
|
}
|
|
writeJSON(w, http.StatusOK, out)
|
|
return nil
|
|
}
|
|
|
|
// reverseDismiss: POST /reverse-zones/dismiss {"view": "internal",
|
|
// "prefix": "185.199.108.153/32"} hides a suggestion; /undismiss shows it
|
|
// again.
|
|
func (s *Server) reverseDismiss(dismiss bool) handler {
|
|
return func(w http.ResponseWriter, r *http.Request, p *auth.Principal) error {
|
|
var in engine.DismissInput
|
|
if err := decodeJSON(r, &in); err != nil {
|
|
return err
|
|
}
|
|
op := engine.OpReverseUndismiss
|
|
if dismiss {
|
|
op = engine.OpReverseDismiss
|
|
}
|
|
return s.mutate(w, r, p, "", []engine.Request{engine.NewRequest(op, 0, in)}, nil)
|
|
}
|
|
}
|