2017-05-18 14:44:50 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"compress/gzip"
|
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
2017-06-28 12:42:28 +02:00
|
|
|
|
2017-07-10 14:02:41 +01:00
|
|
|
"log"
|
2017-05-18 14:44:50 +02:00
|
|
|
"strings"
|
|
|
|
|
2018-06-19 10:02:16 +02:00
|
|
|
"github.com/alice-lg/alice-lg/backend/api"
|
2017-05-18 14:44:50 +02:00
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Alice LG Rest API
|
|
|
|
//
|
|
|
|
// The API provides endpoints for getting
|
|
|
|
// information from the routeservers / alice datasources.
|
|
|
|
//
|
|
|
|
// Endpoints:
|
|
|
|
//
|
|
|
|
// Config
|
2018-10-03 17:59:07 +02:00
|
|
|
// Show /api/v1/config
|
2017-05-18 14:44:50 +02:00
|
|
|
//
|
|
|
|
// Routeservers
|
2018-10-03 17:59:07 +02:00
|
|
|
// List /api/v1/routeservers
|
|
|
|
// Status /api/v1/routeservers/:id/status
|
2018-10-03 18:02:56 +02:00
|
|
|
// Neighbors /api/v1/routeservers/:id/neighbors
|
|
|
|
// Routes /api/v1/routeservers/:id/neighbors/:neighborId/routes
|
2017-05-18 14:44:50 +02:00
|
|
|
//
|
2017-05-23 13:58:58 +02:00
|
|
|
// Querying
|
2019-09-25 01:53:21 +02:00
|
|
|
// LookupPrefix /api/v1/lookup/prefix?q=<prefix>
|
|
|
|
// LookupNeighbor /api/v1/lookup/neighbor?asn=1235
|
2017-05-18 14:44:50 +02:00
|
|
|
|
2017-05-18 15:26:22 +02:00
|
|
|
type apiEndpoint func(*http.Request, httprouter.Params) (api.Response, error)
|
2017-05-18 14:44:50 +02:00
|
|
|
|
|
|
|
// Wrap handler for access controll, throtteling and compression
|
|
|
|
func endpoint(wrapped apiEndpoint) httprouter.Handle {
|
|
|
|
return func(res http.ResponseWriter,
|
|
|
|
req *http.Request,
|
|
|
|
params httprouter.Params) {
|
|
|
|
|
|
|
|
// Get result from handler
|
|
|
|
result, err := wrapped(req, params)
|
|
|
|
if err != nil {
|
2018-08-05 18:25:59 +02:00
|
|
|
// Get affected rs id
|
|
|
|
rsId, paramErr := validateSourceId(params.ByName("id"))
|
|
|
|
if paramErr != nil {
|
2018-12-09 17:31:02 +01:00
|
|
|
rsId = "unknown"
|
2017-05-18 14:44:50 +02:00
|
|
|
}
|
2018-08-05 18:25:59 +02:00
|
|
|
|
|
|
|
// Make error response
|
2019-01-11 20:06:03 +01:00
|
|
|
result, status := apiErrorResponse(rsId, err)
|
2017-05-18 14:44:50 +02:00
|
|
|
payload, _ := json.Marshal(result)
|
2019-01-11 20:06:03 +01:00
|
|
|
http.Error(res, string(payload), status)
|
2017-05-18 14:44:50 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Encode json
|
|
|
|
payload, err := json.Marshal(result)
|
2017-07-10 14:02:41 +01:00
|
|
|
if err != nil {
|
|
|
|
msg := "Could not encode result as json"
|
|
|
|
http.Error(res, msg, http.StatusInternalServerError)
|
|
|
|
log.Println(err)
|
|
|
|
log.Println("This is most likely due to an older version of go.")
|
|
|
|
log.Println("Consider upgrading to golang > 1.8")
|
|
|
|
return
|
|
|
|
}
|
2017-05-18 14:44:50 +02:00
|
|
|
|
|
|
|
// Set response header
|
|
|
|
res.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
// Check if compression is supported
|
|
|
|
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
|
|
|
// Compress response
|
|
|
|
res.Header().Set("Content-Encoding", "gzip")
|
|
|
|
gz := gzip.NewWriter(res)
|
|
|
|
defer gz.Close()
|
|
|
|
gz.Write(payload)
|
|
|
|
} else {
|
|
|
|
res.Write(payload) // Fall back to uncompressed response
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register api endpoints
|
|
|
|
func apiRegisterEndpoints(router *httprouter.Router) error {
|
|
|
|
|
2017-05-19 11:32:22 +02:00
|
|
|
// Meta
|
2018-10-03 17:59:07 +02:00
|
|
|
router.GET("/api/v1/status", endpoint(apiStatusShow))
|
|
|
|
router.GET("/api/v1/config", endpoint(apiConfigShow))
|
2017-05-18 14:44:50 +02:00
|
|
|
|
|
|
|
// Routeservers
|
2018-10-03 17:59:07 +02:00
|
|
|
router.GET("/api/v1/routeservers",
|
2017-05-18 18:10:29 +02:00
|
|
|
endpoint(apiRouteserversList))
|
2018-10-03 17:59:07 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/status",
|
2017-05-18 18:10:29 +02:00
|
|
|
endpoint(apiStatus))
|
2018-10-03 18:02:56 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/neighbors",
|
2018-09-22 15:51:20 +02:00
|
|
|
endpoint(apiNeighborsList))
|
2018-10-03 18:02:56 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/neighbors/:neighborId/routes",
|
2017-05-18 18:10:29 +02:00
|
|
|
endpoint(apiRoutesList))
|
2018-10-03 18:02:56 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/neighbors/:neighborId/routes/received",
|
2018-07-13 16:45:15 +02:00
|
|
|
endpoint(apiRoutesListReceived))
|
2018-10-03 18:02:56 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/neighbors/:neighborId/routes/filtered",
|
2018-07-13 16:45:15 +02:00
|
|
|
endpoint(apiRoutesListFiltered))
|
2018-10-03 18:02:56 +02:00
|
|
|
router.GET("/api/v1/routeservers/:id/neighbors/:neighborId/routes/not-exported",
|
2018-07-13 16:45:15 +02:00
|
|
|
endpoint(apiRoutesListNotExported))
|
2017-05-18 14:44:50 +02:00
|
|
|
|
2017-05-23 13:58:58 +02:00
|
|
|
// Querying
|
2017-07-04 12:36:48 +02:00
|
|
|
if AliceConfig.Server.EnablePrefixLookup == true {
|
2018-10-03 17:59:07 +02:00
|
|
|
router.GET("/api/v1/lookup/prefix",
|
2017-07-04 12:36:48 +02:00
|
|
|
endpoint(apiLookupPrefixGlobal))
|
2019-10-07 18:13:08 +02:00
|
|
|
router.GET("/api/v1/lookup/neighbors",
|
|
|
|
endpoint(apiLookupNeighborsGlobal))
|
2017-07-04 12:36:48 +02:00
|
|
|
}
|
2017-06-19 16:44:24 +02:00
|
|
|
|
2017-05-18 14:44:50 +02:00
|
|
|
return nil
|
|
|
|
}
|