158 lines
3.4 KiB
Go
158 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"net/netip"
|
|
"strconv"
|
|
"strings"
|
|
"subv4/ipalloc"
|
|
)
|
|
|
|
type server struct {
|
|
mux *http.ServeMux
|
|
ipdb *ipalloc.DB
|
|
tmpl *template.Template
|
|
}
|
|
|
|
func (s *server) setup() {
|
|
s.mux = http.NewServeMux()
|
|
s.mux.HandleFunc("/js/", s.static())
|
|
s.mux.HandleFunc("/css/", s.static())
|
|
s.mux.HandleFunc("/", s.template)
|
|
s.mux.HandleFunc("/api/prefix/", s.apiPrefix)
|
|
s.mux.HandleFunc("/api/alloc/", s.apiAlloc)
|
|
s.mux.HandleFunc("/api/dealloc/", s.apiDealloc)
|
|
|
|
s.mux.HandleFunc("/api/used/", s.apiUsed)
|
|
s.mux.HandleFunc("/api/print/", s.apiPrint)
|
|
//s.mux.HandleFunc("/api/provision/", s.apiProvision)
|
|
|
|
s.ipdb = ipalloc.NewDB("10.83.46.0/23")
|
|
s.tmpl = template.Must(template.ParseFS(webcontent, "index.html"))
|
|
}
|
|
|
|
func (s *server) apiPrefix(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
switch r.Method {
|
|
case "GET":
|
|
prefixString := strings.TrimPrefix(r.URL.Path, "/api/prefix/")
|
|
prefix, err := netip.ParsePrefix(prefixString)
|
|
fmt.Fprintln(w, prefix, err)
|
|
case "POST":
|
|
}
|
|
}
|
|
|
|
type PageContent struct {
|
|
Api *ipalloc.DB
|
|
Update UpdateMessage
|
|
}
|
|
type UpdateMessage struct {
|
|
Type string
|
|
Content any
|
|
}
|
|
|
|
func (s *server) template(w http.ResponseWriter, r *http.Request) {
|
|
err := s.tmpl.Execute(w, PageContent{Api: s.ipdb})
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
func (s *server) apiUsed(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
for _, used := range s.ipdb.Used() {
|
|
fmt.Fprintln(w, used)
|
|
}
|
|
}
|
|
func (s *server) apiPrint(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
for _, p := range s.ipdb.All() {
|
|
fmt.Fprintln(w, p.Prefix(), p.Leaf())
|
|
}
|
|
}
|
|
func (s *server) apiAlloc(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
var updmsg UpdateMessage
|
|
|
|
bitsString := strings.TrimPrefix(r.URL.Path, "/api/alloc/")
|
|
bits, err := strconv.Atoi(bitsString)
|
|
if err != nil {
|
|
updmsg.Type = "warn"
|
|
updmsg.Content = err
|
|
if err := s.tmpl.ExecuteTemplate(w, "update", updmsg); err != nil {
|
|
log.Println(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
alloc, err := s.ipdb.Alloc(bits)
|
|
|
|
if err != nil {
|
|
updmsg.Type = "warn"
|
|
updmsg.Content = err
|
|
} else {
|
|
updmsg.Type = "hint"
|
|
updmsg.Content = fmt.Sprintf("Added %s", alloc.Prefix())
|
|
}
|
|
if err := s.tmpl.ExecuteTemplate(w, "update", updmsg); err != nil {
|
|
log.Println(err)
|
|
}
|
|
|
|
if err := s.tmpl.ExecuteTemplate(w, "used", s.ipdb); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
func (s *server) apiDealloc(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
var updmsg UpdateMessage
|
|
|
|
prefixString := strings.TrimPrefix(r.URL.Path, "/api/dealloc/")
|
|
prefix, err := netip.ParsePrefix(prefixString)
|
|
if err != nil {
|
|
updmsg.Type = "warn"
|
|
updmsg.Content = err
|
|
s.tmpl.ExecuteTemplate(w, "update", updmsg)
|
|
return
|
|
}
|
|
|
|
err = s.ipdb.Dealloc(prefix)
|
|
|
|
if err != nil {
|
|
updmsg.Type = "warn"
|
|
updmsg.Content = err
|
|
} else {
|
|
updmsg.Type = "hint"
|
|
updmsg.Content = fmt.Sprintf("Removed %s", prefix)
|
|
}
|
|
s.tmpl.ExecuteTemplate(w, "update", updmsg)
|
|
s.tmpl.ExecuteTemplate(w, "used", s.ipdb)
|
|
}
|
|
|
|
//go:embed js css *.html
|
|
var webcontent embed.FS
|
|
|
|
func (s *server) static() http.HandlerFunc {
|
|
fs := http.FS(webcontent)
|
|
fileserver := http.FileServer(fs)
|
|
return fileserver.ServeHTTP
|
|
}
|
|
|
|
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL)
|
|
s.mux.ServeHTTP(w, r)
|
|
}
|
|
|
|
func main() {
|
|
var s server
|
|
s.setup()
|
|
http.ListenAndServe("[::1]:8080", &s)
|
|
}
|