183 lines
4.1 KiB
Go
183 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"net/netip"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.freifunk-franken.de/jkimmel/sub/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/treemap.dot", s.apiDot)
|
|
//s.mux.HandleFunc("/api/provision/", s.apiProvision)
|
|
|
|
s.ipdb = ipalloc.NewDB("10.83.46.0/23", 32, 29, 28, 27, 26)
|
|
//s.ipdb = ipalloc.NewDB("fd43:5602:29bd:fffe::/64", 128, 127, 126)
|
|
//s.ipdb = ipalloc.NewDB("fd43:5602:29bd:ffff:ffff:ffff:0:0/96", 128, 127, 126)
|
|
//s.ipdb = ipalloc.NewDB("fd43:5602:29bd:ffff:ffff:ffff:ffff:0/112", 128)
|
|
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
|
|
Treemap ipalloc.Treemap
|
|
}
|
|
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,
|
|
Update: UpdateMessage{
|
|
Type: "hint",
|
|
Content: template.HTML(" "),
|
|
},
|
|
Treemap: s.ipdb.Treemap(),
|
|
},
|
|
)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
func (s *server) apiDot(w http.ResponseWriter, r *http.Request) {
|
|
_, err := io.WriteString(w, s.ipdb.Dot())
|
|
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())
|
|
}
|
|
s.tmpl.ExecuteTemplate(w, "treemap", s.ipdb.Treemap())
|
|
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, "treemap", s.ipdb.Treemap())
|
|
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)
|
|
}
|