Skip to content

Commit

Permalink
use new birdc interface
Browse files Browse the repository at this point in the history
  • Loading branch information
annikahannig committed Aug 21, 2024
1 parent 556c525 commit 967ccb7
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 195 deletions.
86 changes: 13 additions & 73 deletions src/api/neighbors.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
use std::collections::HashMap;
use std::io::BufReader;

use anyhow::Result;
use axum::extract::Path;
use tokio::task;

use crate::{
api::{
responses::{NeighborsResponse, RoutesResponse},
Error,
},
bird,
parsers::{
neighbors::NeighborReader, parser::BlockIterator,
routes::RE_ROUTES_START, routes_worker::RoutesWorkerPool,
},
state::{Neighbor, Route},
bird::{Birdc, ProtocolID},
};

/// List all neighbors (show protocols all, filter BGP)
pub async fn list() -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowProtocolsAll)?;
let buf = BufReader::new(result);
let reader = NeighborReader::new(buf);
let neighbors: Vec<Neighbor> =
reader.filter(|n| !n.id.is_empty()).collect();

let neighbors: HashMap<String, Neighbor> =
neighbors.into_iter().map(|n| (n.id.clone(), n)).collect();
let birdc = Birdc::default();
let protocols = birdc.show_protocols_all().await?;

let response = NeighborsResponse {
protocols: neighbors,
protocols,
..Default::default()
};
let body = serde_json::to_string(&response)?;
Expand All @@ -41,24 +26,9 @@ pub async fn list() -> Result<String, Error> {
pub async fn list_routes_received(
Path(id): Path<String>,
) -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowRouteAllProtocol(id))?;
let buf = BufReader::new(result);
let blocks = BlockIterator::new(buf, &RE_ROUTES_START);
let mut routes: Vec<Route> = vec![];

// Spawn workers
let (blocks_tx, mut results_rx) = RoutesWorkerPool::spawn();

task::spawn_blocking(move || {
for block in blocks {
blocks_tx.send(block).unwrap();
}
});

while let Some(result) = results_rx.recv().await {
let result = result?;
routes.extend(result);
}
let birdc = Birdc::default();
let protocol = ProtocolID::parse(&id)?;
let routes = birdc.show_route_all_protocol(&protocol).await?;

let response = RoutesResponse {
routes,
Expand All @@ -72,25 +42,9 @@ pub async fn list_routes_received(
pub async fn list_routes_filtered(
Path(id): Path<String>,
) -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowRouteAllFilteredProtocol(id))?;
let buf = BufReader::new(result);
let blocks = BlockIterator::new(buf, &RE_ROUTES_START);
let mut routes: Vec<Route> = vec![];

// Spawn workers
let (blocks_tx, mut results_rx) = RoutesWorkerPool::spawn();

task::spawn_blocking(move || {
for block in blocks {
blocks_tx.send(block).unwrap();
}
});

while let Some(result) = results_rx.recv().await {
let result = result?;
routes.extend(result);
}

let birdc = Birdc::default();
let protocol = ProtocolID::parse(&id)?;
let routes = birdc.show_route_all_filtered_protocol(&protocol).await?;
let response = RoutesResponse {
routes,
..Default::default()
Expand All @@ -104,23 +58,9 @@ pub async fn list_routes_filtered(
pub async fn list_routes_noexport(
Path(id): Path<String>,
) -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowRouteAllNoexportProtocol(id))?;
let buf = BufReader::new(result);
let blocks = BlockIterator::new(buf, &RE_ROUTES_START);
let mut routes: Vec<Route> = vec![];

// Spawn workers
let (blocks_tx, mut results_rx) = RoutesWorkerPool::spawn();
task::spawn_blocking(move || {
for block in blocks {
blocks_tx.send(block).unwrap();
}
});

while let Some(result) = results_rx.recv().await {
let result = result?;
routes.extend(result);
}
let birdc = Birdc::default();
let protocol = ProtocolID::parse(&id)?;
let routes = birdc.show_route_all_noexport_protocol(&protocol).await?;

let response = RoutesResponse {
routes,
Expand Down
24 changes: 22 additions & 2 deletions src/api/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,36 @@ impl Default for StatusResponse {
}
}

#[derive(Serialize, Deserialize, Debug, Default)]
#[derive(Serialize, Deserialize, Debug)]
pub struct NeighborsResponse {
pub api: ApiStatus,
pub cached_at: DateTime<Utc>,
pub protocols: HashMap<String, Neighbor>,
}

#[derive(Serialize, Deserialize, Debug, Default)]
impl Default for NeighborsResponse {
fn default() -> Self {
NeighborsResponse {
api: ApiStatus::default(),
cached_at: Utc::now(),
protocols: HashMap::new(),
}
}
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RoutesResponse {
pub api: ApiStatus,
pub cached_at: DateTime<Utc>,
pub routes: Vec<Route>,
}

impl Default for RoutesResponse {
fn default() -> Self {
RoutesResponse {
api: ApiStatus::default(),
cached_at: Utc::now(),
routes: Vec::new(),
}
}
}
10 changes: 5 additions & 5 deletions src/api/server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use axum::{routing::get, Router};
use tower_http::trace::TraceLayer;

use crate::api::{neighbors, status, tables};

Expand All @@ -17,7 +18,6 @@ async fn welcome() -> &'static str {

/// Start the API http server
pub async fn start(opts: &Opts) -> Result<()> {
let addr = opts.listen.parse()?;
let app = Router::new()
.route("/", get(welcome))
.route("/status", get(status::retrieve))
Expand All @@ -38,11 +38,11 @@ pub async fn start(opts: &Opts) -> Result<()> {
.route(
"/routes/table/:table/filtered",
get(tables::list_routes_filtered),
);
)
.layer(TraceLayer::new_for_http());

axum::Server::bind(&addr)
.serve(app.into_make_service())
.await?;
let listener = tokio::net::TcpListener::bind(&opts.listen).await?;
axum::serve(listener, app).await?;

Ok(())
}
18 changes: 7 additions & 11 deletions src/api/status.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
use std::io::{BufRead, BufReader};

use anyhow::Result;

use crate::api::{responses::StatusResponse, Error};
use crate::bird;
use crate::parsers::parser::Parse;
use crate::state::{ApiStatus, BirdStatus};
use crate::{
api::{responses::StatusResponse, Error},
bird::Birdc,
state::ApiStatus,
};

/// Get the current status
pub async fn retrieve() -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowStatus)?;
let reader = BufReader::new(result);
let block = reader.lines().map(|l| l.unwrap()).collect::<Vec<String>>();
let status = BirdStatus::parse(block).unwrap();

let birdc = Birdc::default();
let status = birdc.show_status().await?;
let response = StatusResponse {
api: ApiStatus::default(),
status,
Expand Down
52 changes: 8 additions & 44 deletions src/api/tables.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,17 @@
use std::io::BufReader;

use anyhow::Result;
use axum::extract::Path;
use tokio::task;

use crate::{
api::{responses::RoutesResponse, Error},
bird,
parsers::{
parser::BlockIterator, routes::RE_ROUTES_START,
routes_worker::RoutesWorkerPool,
},
state::Route,
bird::{Birdc, TableID},
};

/// List all routes in a table
pub async fn list_routes(Path(table): Path<String>) -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowRouteAllTable(table))?;
let buf = BufReader::new(result);
let blocks = BlockIterator::new(buf, &RE_ROUTES_START);
let mut routes: Vec<Route> = vec![];

// Spawn workers
let (blocks_tx, mut results_rx) = RoutesWorkerPool::spawn();

task::spawn_blocking(move || {
for block in blocks {
blocks_tx.send(block).unwrap();
}
});

while let Some(result) = results_rx.recv().await {
let result = result?;
routes.extend(result);
}
let birdc = Birdc::default();
let table = TableID::parse(&table)?;

let routes = birdc.show_route_all_table(&table).await?;
let response = RoutesResponse {
routes,
..Default::default()
Expand All @@ -47,23 +24,9 @@ pub async fn list_routes(Path(table): Path<String>) -> Result<String, Error> {
pub async fn list_routes_filtered(
Path(table): Path<String>,
) -> Result<String, Error> {
let result = bird::birdc(bird::Command::ShowRouteAllFilteredTable(table))?;
let buf = BufReader::new(result);
let blocks = BlockIterator::new(buf, &RE_ROUTES_START);
let mut routes: Vec<Route> = vec![];

// Spawn workers
let (blocks_tx, mut results_rx) = RoutesWorkerPool::spawn();
task::spawn_blocking(move || {
for block in blocks {
blocks_tx.send(block).unwrap();
}
});

while let Some(result) = results_rx.recv().await {
let result = result?;
routes.extend(result);
}
let birdc = Birdc::default();
let table = TableID::parse(&table)?;
let routes = birdc.show_route_all_filtered_table(&table).await?;

let response = RoutesResponse {
routes,
Expand All @@ -72,3 +35,4 @@ pub async fn list_routes_filtered(
let body = serde_json::to_string(&response)?;
Ok(body)
}

Loading

0 comments on commit 967ccb7

Please sign in to comment.