mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-15 17:35:45 +00:00
7b5c36b1c6
/admin rest api implementation and tests * open api doc * Add rest admin test to all tests * Enrich /admin get peers interface, group protocols by peers in response
114 lines
4.2 KiB
Nim
114 lines
4.2 KiB
Nim
when (NimMajor, NimMinor) < (1, 4):
|
|
{.push raises: [Defect].}
|
|
else:
|
|
{.push raises: [].}
|
|
|
|
import
|
|
std/strformat,
|
|
std/sequtils,
|
|
stew/byteutils,
|
|
chronicles,
|
|
json_serialization,
|
|
presto/route,
|
|
libp2p/[peerinfo, switch]
|
|
|
|
import
|
|
../../../waku_core,
|
|
../../../waku_store,
|
|
../../../waku_filter,
|
|
../../../waku_relay,
|
|
../../../waku_node,
|
|
../../../node/peer_manager,
|
|
../responses,
|
|
../serdes,
|
|
./types
|
|
|
|
export types
|
|
|
|
logScope:
|
|
topics = "waku node rest admin api"
|
|
|
|
const ROUTE_ADMIN_V1_PEERS* = "/admin/v1/peers"
|
|
|
|
type PeerProtocolTuple = tuple[multiaddr: string, protocol: string, connected: bool]
|
|
|
|
func decodeRequestBody[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
|
if contentBody.isNone():
|
|
return err(RestApiResponse.badRequest("Missing content body"))
|
|
|
|
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
|
if reqBodyContentType != MIMETYPE_JSON:
|
|
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json"))
|
|
|
|
let reqBodyData = contentBody.get().data
|
|
|
|
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
|
if requestResult.isErr():
|
|
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
|
$requestResult.error))
|
|
|
|
return ok(requestResult.get())
|
|
|
|
proc tuplesToWakuPeers(peers: var WakuPeers, peersTup: seq[PeerProtocolTuple]) =
|
|
for peer in peersTup:
|
|
peers.add(peer.multiaddr, peer.protocol, peer.connected)
|
|
|
|
|
|
proc installAdminV1GetPeersHandler(router: var RestRouter, node: WakuNode) =
|
|
router.api(MethodGet, ROUTE_ADMIN_V1_PEERS) do () -> RestApiResponse:
|
|
var peers: WakuPeers = @[]
|
|
|
|
if not node.wakuRelay.isNil():
|
|
# Map managed peers to WakuPeers and add to return list
|
|
let relayPeers = node.peerManager
|
|
.peerStore.peers(WakuRelayCodec)
|
|
.mapIt((
|
|
multiaddr: constructMultiaddrStr(it),
|
|
protocol: WakuRelayCodec,
|
|
connected: it.connectedness == Connectedness.Connected)
|
|
)
|
|
tuplesToWakuPeers(peers, relayPeers)
|
|
|
|
if not node.wakuFilterLegacy.isNil():
|
|
# Map WakuFilter peers to WakuPeers and add to return list
|
|
let filterPeers = node.peerManager.peerStore.peers(WakuLegacyFilterCodec)
|
|
.mapIt((multiaddr: constructMultiaddrStr(it),
|
|
protocol: WakuLegacyFilterCodec,
|
|
connected: it.connectedness == Connectedness.Connected))
|
|
tuplesToWakuPeers(peers, filterPeers)
|
|
|
|
if not node.wakuStore.isNil():
|
|
# Map WakuStore peers to WakuPeers and add to return list
|
|
let storePeers = node.peerManager.peerStore
|
|
.peers(WakuStoreCodec)
|
|
.mapIt((multiaddr: constructMultiaddrStr(it),
|
|
protocol: WakuStoreCodec,
|
|
connected: it.connectedness == Connectedness.Connected))
|
|
tuplesToWakuPeers(peers, storePeers)
|
|
|
|
let resp = RestApiResponse.jsonResponse(peers, status=Http200)
|
|
if resp.isErr():
|
|
error "An error ocurred while building the json respose: ", error=resp.error
|
|
return RestApiResponse.internalServerError(fmt("An error ocurred while building the json respose: {resp.error}"))
|
|
|
|
return resp.get()
|
|
|
|
proc installAdminV1PostPeersHandler(router: var RestRouter, node: WakuNode) =
|
|
router.api(MethodPost, ROUTE_ADMIN_V1_PEERS) do (contentBody: Option[ContentBody]) -> RestApiResponse:
|
|
|
|
let peers: seq[string] = decodeRequestBody[seq[string]](contentBody).valueOr:
|
|
return RestApiResponse.badRequest(fmt("Failed to decode request: {error}"))
|
|
|
|
for i, peer in peers:
|
|
let peerInfo = parsePeerInfo(peer).valueOr:
|
|
return RestApiResponse.badRequest(fmt("Couldn't parse remote peer info: {error}"))
|
|
|
|
if not (await node.peerManager.connectRelay(peerInfo, source="rest")):
|
|
return RestApiResponse.badRequest(fmt("Failed to connect to peer at index: {i} - {peer}"))
|
|
|
|
return RestApiResponse.ok()
|
|
|
|
proc installAdminApiHandlers*(router: var RestRouter, node: WakuNode) =
|
|
installAdminV1GetPeersHandler(router, node)
|
|
installAdminV1PostPeersHandler(router, node)
|