Compare commits
3 Commits
a5a29a18b1
...
44301eed60
Author | SHA1 | Date |
---|---|---|
Johannes Kimmel | 44301eed60 | |
Johannes Kimmel | f05829d0c8 | |
Johannes Kimmel | 8b93868983 |
18
index.html
18
index.html
|
@ -111,16 +111,12 @@
|
|||
</figure>
|
||||
</details>
|
||||
|
||||
<h2><code>{{ .Api.Root }}</code></h2>
|
||||
|
||||
<div id="control" hx-swap="none">
|
||||
<button hx-get="/api/alloc/32">/32</button>
|
||||
<button hx-get="/api/alloc/31">/31</button>
|
||||
<button hx-get="/api/alloc/30">/30</button>
|
||||
<button hx-get="/api/alloc/29">/29</button>
|
||||
<button hx-get="/api/alloc/28">/28</button>
|
||||
<button hx-get="/api/alloc/27">/27</button>
|
||||
<button hx-get="/api/alloc/26">/26</button>
|
||||
<button hx-get="/api/alloc/25">/25</button>
|
||||
<button hx-get="/api/alloc/24">/24</button>
|
||||
{{- range .Api.AllowedLengths }}
|
||||
<button hx-get="/api/alloc/{{ . }}">/{{ . }}</button>
|
||||
{{- end }}
|
||||
</div>
|
||||
|
||||
{{ block "update" .Update }}<div id="updatemsg" class="card {{ .Type }}" hx-swap-oob="morph">{{ with .Content }}{{ . }}{{ end }}</div>{{ end }}
|
||||
|
@ -154,7 +150,7 @@
|
|||
{{- end }}
|
||||
{{ block "used" .Api }}
|
||||
<div id="state" hx-swap-oob="morph" hx-swap="none">
|
||||
<h2>grouped</h2>
|
||||
<h3>grouped</h3>
|
||||
<div id="used-grouped">
|
||||
{{- range .UsedGrouped }}
|
||||
{{- $first := index . 0 }}
|
||||
|
@ -170,7 +166,7 @@
|
|||
{{ end -}}
|
||||
</div>
|
||||
|
||||
<h2>all</h2>
|
||||
<h3>all</h3>
|
||||
<div id="used">
|
||||
<table>
|
||||
{{- range .Used }}
|
||||
|
|
|
@ -266,13 +266,21 @@ func (t *tree) Dot() string {
|
|||
|
||||
type DB struct {
|
||||
sync.Mutex
|
||||
provisions *tree
|
||||
provisions *tree
|
||||
allowedLengths []int
|
||||
}
|
||||
|
||||
func NewDB(prefix string) *DB {
|
||||
return &DB{provisions: &tree{prefix: netip.MustParsePrefix(prefix)}}
|
||||
func NewDB(prefix string, allowedLengths ...int) *DB {
|
||||
p := netip.MustParsePrefix(prefix)
|
||||
if canonical := p.Masked(); p.Addr() != canonical.Addr() {
|
||||
log.Fatalf("Prefix %q is not in canonical form, use: %q", p, canonical)
|
||||
}
|
||||
return &DB{provisions: &tree{prefix: p}, allowedLengths: allowedLengths}
|
||||
}
|
||||
|
||||
func (db *DB) AllowedLengths() []int {
|
||||
return slices.Clip(db.allowedLengths)
|
||||
}
|
||||
func (db *DB) Used() []netip.Prefix {
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
|
@ -319,6 +327,9 @@ func (db *DB) All() []*tree {
|
|||
})
|
||||
return ret
|
||||
}
|
||||
func (db *DB) Dot() string {
|
||||
return db.provisions.Dot()
|
||||
}
|
||||
func (db *DB) Alloc(bits int) (*tree, error) {
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
|
@ -399,7 +410,7 @@ func prefixShape(p netip.Prefix) Rect {
|
|||
return Rect{
|
||||
Y: 0,
|
||||
X: 0,
|
||||
H: 1 << (bits / 2),
|
||||
H: 1 << (bits / 2), // TODO: handle overflow for normal ipv6 subnet sizes :)
|
||||
W: 1 << ((bits + 1) / 2),
|
||||
}
|
||||
}
|
||||
|
|
25
main.go
25
main.go
|
@ -4,6 +4,7 @@ import (
|
|||
"embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
|
@ -30,9 +31,13 @@ func (s *server) setup() {
|
|||
|
||||
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")
|
||||
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"))
|
||||
}
|
||||
|
||||
|
@ -59,7 +64,23 @@ type UpdateMessage struct {
|
|||
}
|
||||
|
||||
func (s *server) template(w http.ResponseWriter, r *http.Request) {
|
||||
err := s.tmpl.Execute(w, PageContent{Api: s.ipdb, Treemap: s.ipdb.Treemap()})
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue