feat: add aggregated router-lists catalog endpoint and update module listing filters
CI / changes (push) Successful in 5s
CI / openapi (push) Successful in 22s
CI / go (push) Successful in 38s
CI / bird2 (push) Has been cancelled
CI / docker-go-prime (push) Has been cancelled
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been cancelled
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been cancelled
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been cancelled
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been cancelled
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been cancelled
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been cancelled
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been cancelled
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been cancelled
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has started running
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been cancelled
CI / docker-bird (push) Has been cancelled
CI / changes (push) Successful in 5s
CI / openapi (push) Successful in 22s
CI / go (push) Successful in 38s
CI / bird2 (push) Has been cancelled
CI / docker-go-prime (push) Has been cancelled
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been cancelled
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been cancelled
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been cancelled
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been cancelled
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been cancelled
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been cancelled
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been cancelled
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been cancelled
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has started running
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been cancelled
CI / docker-bird (push) Has been cancelled
Introduced a new endpoint `GET /v1/router-lists/catalog` that returns a consolidated view of modules, domain entries, ASNs, IP ranges, and communities. Enhanced the existing module listing functionality to support filtering by type and enabled status. Updated documentation to reflect these changes and added tests for the new endpoint and filtering capabilities.
This commit is contained in:
@@ -47,6 +47,7 @@ func (s *Server) registerRoutes() {
|
||||
|
||||
func (s *Server) registerV1(m *http.ServeMux) {
|
||||
m.HandleFunc("GET /modules", s.handleListModules)
|
||||
m.HandleFunc("GET /router-lists/catalog", s.handleRouterListsCatalog)
|
||||
m.HandleFunc("GET /modules/{module_id}", s.handleGetModule)
|
||||
m.HandleFunc("GET /peers", s.handleListPeers)
|
||||
m.HandleFunc("GET /speakers", s.handleListSpeakers)
|
||||
@@ -161,9 +162,27 @@ func (s *Server) handleListModules(w http.ResponseWriter, r *http.Request) {
|
||||
if !s.requireAtLeast(w, a, "viewer") {
|
||||
return
|
||||
}
|
||||
typeFilter := strings.TrimSpace(r.URL.Query().Get("type"))
|
||||
enabledRaw := strings.TrimSpace(r.URL.Query().Get("enabled"))
|
||||
var enabledFilter *bool
|
||||
if enabledRaw != "" {
|
||||
v, err := strconv.ParseBool(enabledRaw)
|
||||
if err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "Bad Request", "enabled must be boolean")
|
||||
return
|
||||
}
|
||||
enabledFilter = &v
|
||||
}
|
||||
|
||||
mods := s.store.ListModules(a.TenantID)
|
||||
items := make([]map[string]any, 0, len(mods))
|
||||
for _, mod := range mods {
|
||||
if typeFilter != "" && mod.Type != typeFilter {
|
||||
continue
|
||||
}
|
||||
if enabledFilter != nil && mod.Enabled != *enabledFilter {
|
||||
continue
|
||||
}
|
||||
items = append(items, moduleJSON(mod))
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{
|
||||
@@ -171,6 +190,103 @@ func (s *Server) handleListModules(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleRouterListsCatalog(w http.ResponseWriter, r *http.Request) {
|
||||
a, ok := authFromContext(r.Context())
|
||||
if !ok {
|
||||
writeProblem(w, http.StatusUnauthorized, "Unauthorized", "missing auth")
|
||||
return
|
||||
}
|
||||
if !s.requireAtLeast(w, a, "viewer") {
|
||||
return
|
||||
}
|
||||
|
||||
mods := s.store.ListModules(a.TenantID)
|
||||
moduleItems := make([]map[string]any, 0, len(mods))
|
||||
domains := make([]map[string]any, 0)
|
||||
asns := make([]map[string]any, 0)
|
||||
ipRanges := make([]map[string]any, 0)
|
||||
|
||||
for _, mod := range mods {
|
||||
switch mod.Type {
|
||||
case "DOMAINS", "AS_PREFIXES", "IP_RANGES":
|
||||
moduleItems = append(moduleItems, moduleJSON(mod))
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
switch mod.Type {
|
||||
case "DOMAINS":
|
||||
list, err := s.store.ListDomainEntries(a.TenantID, mod.ID)
|
||||
if err != nil {
|
||||
writeStoreErr(w, err)
|
||||
return
|
||||
}
|
||||
for _, x := range list {
|
||||
domains = append(domains, map[string]any{
|
||||
"module_id": mod.ID,
|
||||
"entry": domainEntryJSON(x),
|
||||
})
|
||||
}
|
||||
case "AS_PREFIXES":
|
||||
list, err := s.store.ListASEntries(a.TenantID, mod.ID)
|
||||
if err != nil {
|
||||
writeStoreErr(w, err)
|
||||
return
|
||||
}
|
||||
for _, x := range list {
|
||||
asns = append(asns, map[string]any{
|
||||
"module_id": mod.ID,
|
||||
"entry": asEntryJSON(x),
|
||||
})
|
||||
}
|
||||
case "IP_RANGES":
|
||||
list, err := s.store.ListIPRangeEntries(a.TenantID, mod.ID)
|
||||
if err != nil {
|
||||
writeStoreErr(w, err)
|
||||
return
|
||||
}
|
||||
for _, x := range list {
|
||||
ipRanges = append(ipRanges, map[string]any{
|
||||
"module_id": mod.ID,
|
||||
"entry": ipRangeJSON(x),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
comms, err := s.store.ListCommunities(a.TenantID)
|
||||
if err != nil {
|
||||
writeStoreErr(w, err)
|
||||
return
|
||||
}
|
||||
communityItems := make([]map[string]any, 0, len(comms))
|
||||
for _, c := range comms {
|
||||
communityItems = append(communityItems, map[string]any{
|
||||
"id": c.ID,
|
||||
"community": c.Community,
|
||||
"title": c.Title,
|
||||
})
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]any{
|
||||
"modules": map[string]any{
|
||||
"items": moduleItems,
|
||||
},
|
||||
"domains": map[string]any{
|
||||
"items": domains,
|
||||
},
|
||||
"asns": map[string]any{
|
||||
"items": asns,
|
||||
},
|
||||
"ip_ranges": map[string]any{
|
||||
"items": ipRanges,
|
||||
},
|
||||
"communities": map[string]any{
|
||||
"items": communityItems,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleGetModule(w http.ResponseWriter, r *http.Request) {
|
||||
a, ok := authFromContext(r.Context())
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user