@@ -15,14 +15,19 @@ use std::sync::Arc;
1515use chrono:: DateTime ;
1616use chrono:: Utc ;
1717use dropshot:: endpoint;
18+ use dropshot:: EmptyScanParams ;
1819use dropshot:: HttpError ;
1920use dropshot:: HttpResponseCreated ;
2021use dropshot:: HttpResponseDeleted ;
2122use dropshot:: HttpResponseOk ;
2223use dropshot:: HttpResponseUpdatedNoContent ;
24+ use dropshot:: PaginationParams ;
2325use dropshot:: Path ;
26+ use dropshot:: Query ;
2427use dropshot:: RequestContext ;
28+ use dropshot:: ResultsPage ;
2529use dropshot:: TypedBody ;
30+ use dropshot:: WhichPage ;
2631use schemars:: JsonSchema ;
2732use serde:: Deserialize ;
2833use serde:: Serialize ;
@@ -681,47 +686,81 @@ async fn interface_clear_management_addr(
681686 . map ( |_| HttpResponseDeleted ( ) )
682687}
683688
689+ /**
690+ * Represents a cursor into a paginated request for the contents of the neighbor
691+ * list.
692+ */
693+ #[ derive( Deserialize , Serialize , JsonSchema ) ]
694+ struct NeighborToken {
695+ id : types:: NeighborId ,
696+ }
697+
684698/// A remote system that has been discovered on one of our configured interfaces
685699#[ derive( Clone , Debug , Deserialize , JsonSchema , Serialize ) ]
686700pub struct Neighbor {
701+ /// The port on which the neighbor was seen
687702 pub port : String ,
703+ /// An ID that uniquely identifies the neighbor. Note: this ID is assigned
704+ /// when we first see a neighbor we are currently tracking. If a neighbor
705+ /// goes offline long enough to be forgotten, it will be assigned a new ID
706+ /// if and when it comes back online.
707+ pub id : uuid:: Uuid ,
708+ /// When was the first beacon received from this neighbor.
688709 pub first_seen : DateTime < Utc > ,
710+ /// When was the latest beacon received from this neighbor.
689711 pub last_seen : DateTime < Utc > ,
712+ /// When was the last time this neighbor's beaconed LLDPDU contents changed.
690713 pub last_changed : DateTime < Utc > ,
714+ /// Contents of the neighbor's LLDPDU beacon.
691715 pub system_info : types:: SystemInfo ,
692716}
693717/// Return a list of the active neighbors
694718#[ endpoint {
695719 method = GET ,
696- path = "/neighbors" ,
720+ path = "/interface/{iface}/ neighbors" ,
697721} ]
698722async fn get_neighbors (
699723 rqctx : RequestContext < Arc < Global > > ,
700- ) -> Result < HttpResponseOk < Vec < Neighbor > > , HttpError > {
724+ path : Path < InterfacePathParams > ,
725+ query : Query < PaginationParams < EmptyScanParams , NeighborToken > > ,
726+ ) -> Result < HttpResponseOk < ResultsPage < Neighbor > > , HttpError > {
701727 let global: & Global = rqctx. context ( ) ;
702- Ok ( HttpResponseOk (
703- global
704- . interfaces
705- . lock ( )
706- . unwrap ( )
707- . iter ( )
708- . flat_map ( |( name, iface) | {
709- iface
710- . lock ( )
711- . unwrap ( )
712- . neighbors
713- . values ( )
728+ let pag_params = query. into_inner ( ) ;
729+ let iface = path. into_inner ( ) . iface ;
730+ let max = rqctx. page_limit ( & pag_params) ?. get ( ) ;
731+
732+ let previous = match & pag_params. page {
733+ WhichPage :: First ( ..) => None ,
734+ WhichPage :: Next ( NeighborToken { id } ) => Some ( id. clone ( ) ) ,
735+ } ;
736+
737+ let neighbors: Vec < Neighbor > =
738+ interfaces:: get_neighbors ( global, & iface, previous, max)
739+ . await
740+ . map_err ( HttpError :: from)
741+ . map ( |neighbors| {
742+ neighbors
743+ . iter ( )
714744 . map ( |n| Neighbor {
715- port : name. clone ( ) ,
745+ port : iface. clone ( ) ,
746+ id : n. id ,
716747 first_seen : n. first_seen ,
717748 last_seen : n. last_seen ,
718749 last_changed : n. last_changed ,
719750 system_info : ( & n. lldpdu ) . into ( ) ,
720751 } )
721- . collect :: < Vec < Neighbor > > ( )
722- } )
723- . collect :: < Vec < Neighbor > > ( ) ,
724- ) )
752+ . collect ( )
753+ } ) ?;
754+
755+ ResultsPage :: new ( neighbors, & EmptyScanParams { } , |n : & Neighbor , _| {
756+ NeighborToken {
757+ id : types:: NeighborId {
758+ chassis_id : n. system_info . chassis_id . clone ( ) ,
759+ port_id : n. system_info . port_id . clone ( ) ,
760+ } ,
761+ }
762+ } )
763+ . map ( HttpResponseOk )
725764}
726765
727766/// Return detailed build information about the `dpd` server itself.
0 commit comments