Skip to content

Commit

Permalink
fix(macos): support set dns
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat616 committed Jan 9, 2025
1 parent 076fc27 commit 0cbf000
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 81 deletions.
205 changes: 149 additions & 56 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions nyanpasu_ipc/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod core;
pub mod log;
pub mod network;
pub mod status;

use serde::{de::DeserializeOwned, Deserialize, Serialize};
Expand Down
1 change: 1 addition & 0 deletions nyanpasu_ipc/src/api/network/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod set_dns;
12 changes: 12 additions & 0 deletions nyanpasu_ipc/src/api/network/set_dns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::api::R;
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, net::IpAddr};

pub const NETWORK_SET_DNS_ENDPOINT: &str = "/network/set_dns";

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct NetworkSetDnsReq<'n> {
pub dns_servers: Option<Vec<Cow<'n, IpAddr>>>,
}

pub type NetworkSetDnsRes<'a> = R<'a, ()>;
16 changes: 16 additions & 0 deletions nyanpasu_ipc/src/client/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,20 @@ impl<'a> Client<'a> {
let data = response.data.unwrap();
Ok(data)
}

pub async fn set_dns(
&self,
payload: &api::network::set_dns::NetworkSetDnsReq<'_>,
) -> Result<()> {
let payload = simd_json::serde::to_string(payload)?;
let request = Request::post(api::network::set_dns::NETWORK_SET_DNS_ENDPOINT)
.header(CONTENT_TYPE, "application/json")
.body(Body::from(payload))?;
let response = send_request(&self.0, request)
.await?
.cast_body::<api::network::set_dns::NetworkSetDnsRes>()
.await?;
response.ok()?;
Ok(())
}
}
1 change: 1 addition & 0 deletions nyanpasu_service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ hardware-lock-elision = ["parking_lot/hardware-lock-elision"]
nyanpasu-utils = { workspace = true, default-features = false, features = [
"dirs",
"os",
"network",
] }
nyanpasu-ipc = { path = "../nyanpasu_ipc", default-features = false, features = [
"server",
Expand Down
17 changes: 15 additions & 2 deletions nyanpasu_service/src/cmds/rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::borrow::Cow;
use std::{borrow::Cow, net::IpAddr};

/// This module is a shortcut for client rpc calls.
/// It is useful for testing and debugging service rpc calls.
use clap::Subcommand;
use nyanpasu_ipc::client::shortcuts::Client;
use nyanpasu_ipc::{api::network::set_dns::NetworkSetDnsReq, client::shortcuts::Client};

fn core_type_parser(s: &str) -> Result<nyanpasu_utils::core::CoreType, String> {
let mut s = s.to_string();
Expand Down Expand Up @@ -32,6 +32,8 @@ pub enum RpcCommand {
RestartCore,
/// Get the logs of the service
InspectLogs,
/// Set the dns servers
SetDns { dns_servers: Option<Vec<IpAddr>> },
}

pub async fn rpc(commands: RpcCommand) -> Result<(), crate::cmds::CommandError> {
Expand Down Expand Up @@ -76,6 +78,17 @@ pub async fn rpc(commands: RpcCommand) -> Result<(), crate::cmds::CommandError>
println!("{}", log.trim_matches('\n'));
}
}
RpcCommand::SetDns { dns_servers } => {
let client = Client::service_default();
client
.set_dns(&NetworkSetDnsReq {
dns_servers: dns_servers
.as_ref()
.map(|v| v.into_iter().map(|v| Cow::Borrowed(v)).collect()),
})
.await
.map_err(|e| crate::cmds::CommandError::Other(e.into()))?;
}
}
Ok(())
}
13 changes: 12 additions & 1 deletion nyanpasu_service/src/server/routing/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
pub mod log;
use axum::{routing::post, Router};
use nyanpasu_ipc::api::core::{
restart::CORE_RESTART_ENDPOINT, start::CORE_START_ENDPOINT, stop::CORE_STOP_ENDPOINT,
};

pub mod restart;
pub mod start;
pub mod stop;

pub fn setup() -> Router {
Router::new()
.route(CORE_START_ENDPOINT, post(start::start))
.route(CORE_STOP_ENDPOINT, post(stop::stop))
.route(CORE_RESTART_ENDPOINT, post(restart::restart))
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use axum::{http::StatusCode, Json};
use axum::{http::StatusCode, routing::get, Json, Router};
use nyanpasu_ipc::api::{
log::{LogsRes, LogsResBody},
log::{LogsRes, LogsResBody, LOGS_INSPECT_ENDPOINT, LOGS_RETRIEVE_ENDPOINT},
RBuilder,
};

pub fn setup() -> Router {
Router::new()
.route(LOGS_RETRIEVE_ENDPOINT, get(retrieve_logs))
.route(LOGS_INSPECT_ENDPOINT, get(inspect_logs))
}

pub async fn retrieve_logs() -> (StatusCode, Json<LogsRes<'static>>) {
let logs = crate::server::logger::Logger::global().retrieve_logs();
let res = RBuilder::success(LogsResBody { logs });
Expand Down
25 changes: 7 additions & 18 deletions nyanpasu_service/src/server/routing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
use core::log;

use axum::{
routing::{get, post},
Router,
};

use nyanpasu_ipc::api::{
core::{restart::CORE_RESTART_ENDPOINT, start::CORE_START_ENDPOINT, stop::CORE_STOP_ENDPOINT},
log::{LOGS_INSPECT_ENDPOINT, LOGS_RETRIEVE_ENDPOINT},
status::STATUS_ENDPOINT,
};
use axum::Router;
use tracing_attributes::instrument;

pub mod core;
pub mod logs;
pub mod network;
pub mod status;

#[instrument]
pub fn apply_routes(app: Router) -> Router {
tracing::info!("Applying routes...");
let tracing_layer = tower_http::trace::TraceLayer::new_for_http();
app.route(STATUS_ENDPOINT, get(status::status))
.route(CORE_START_ENDPOINT, post(core::start::start))
.route(CORE_STOP_ENDPOINT, post(core::stop::stop))
.route(CORE_RESTART_ENDPOINT, post(core::restart::restart))
.route(LOGS_RETRIEVE_ENDPOINT, get(log::retrieve_logs))
.route(LOGS_INSPECT_ENDPOINT, get(log::inspect_logs))
app.nest("/", status::setup())
.nest("/", core::setup())
.nest("/", logs::setup())
.nest("/", network::setup())
.layer(tracing_layer)
}
50 changes: 50 additions & 0 deletions nyanpasu_service/src/server/routing/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use axum::{http::StatusCode, routing::post, Json, Router};
use nyanpasu_ipc::api::network::set_dns::{
NetworkSetDnsReq, NetworkSetDnsRes, NETWORK_SET_DNS_ENDPOINT,
};
#[cfg(target_os = "macos")]
use nyanpasu_utils::network::macos::{get_default_network_hardware_port, set_dns};

pub fn setup() -> Router {
Router::new().route(NETWORK_SET_DNS_ENDPOINT, post(network))
}

#[cfg(target_os = "macos")]
pub async fn network(
Json(mut req): Json<NetworkSetDnsReq<'static>>,
) -> (StatusCode, Json<NetworkSetDnsRes<'static>>) {
use std::borrow::Cow;

use nyanpasu_ipc::api::RBuilder;

let default_interface = match get_default_network_hardware_port() {
Ok(interface) => interface,
Err(e) => {
return (
StatusCode::INTERNAL_SERVER_ERROR,
Json(RBuilder::other_error(Cow::Owned(e.to_string()))),
)
}
};
let dns_servers = req
.dns_servers
.take()
.map(|v| v.into_iter().map(|v| v.into_owned()).collect::<Vec<_>>());
match set_dns(&default_interface, dns_servers) {
Ok(_) => (StatusCode::OK, Json(RBuilder::success(()))),
Err(e) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(RBuilder::other_error(Cow::Owned(e.to_string()))),
),
}
}

#[cfg(not(target_os = "macos"))]
pub async fn network(
Json(_req): Json<NetworkSetDnsReq<'static>>,
) -> (StatusCode, Json<NetworkSetDnsRes<'static>>) {
(
StatusCode::NOT_IMPLEMENTED,
Json(RBuilder::not_implemented()),
)
}
9 changes: 7 additions & 2 deletions nyanpasu_service/src/server/routing/status.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use std::borrow::Cow;

use axum::{http::StatusCode, Json};
use axum::{http::StatusCode, routing::get, Json, Router};

use nyanpasu_ipc::api::{
status::{RuntimeInfos, StatusRes, StatusResBody},
status::{RuntimeInfos, StatusRes, StatusResBody, STATUS_ENDPOINT},
RBuilder,
};

pub fn setup() -> Router {
let router = Router::new();
router.route(STATUS_ENDPOINT, get(status))
}

pub async fn status() -> (StatusCode, Json<StatusRes<'static>>) {
let instance = crate::server::CoreManager::global();
let status = instance.status();
Expand Down

0 comments on commit 0cbf000

Please sign in to comment.