Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add info RPC call to daemon containing version, build info etc #724

Merged
merged 6 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-nym-vpn-core.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: publish-nym-vpn-core.yml
name: publish-nym-vpn-core
on:
schedule:
- cron: "4 3 * * *"
Expand Down
1 change: 1 addition & 0 deletions nym-vpn-core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions nym-vpn-core/nym-vpnc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ anyhow.workspace = true
bs58.workspace = true
clap = { workspace = true, features = ["derive"] }
parity-tokio-ipc.workspace = true
prost-types.workspace = true
prost.workspace = true
time = { workspace = true, features = ["formatting"] }
tokio = { workspace = true, features = ["macros", "rt-multi-thread"]}
Expand Down
1 change: 1 addition & 0 deletions nym-vpn-core/nym-vpnc/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) enum Command {
Connect(ConnectArgs),
Disconnect,
Status,
Info,
ImportCredential(ImportCredentialArgs),
ListenToStatus,
ListenToStateChanges,
Expand Down
44 changes: 28 additions & 16 deletions nym-vpn-core/nym-vpnc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
use anyhow::Result;
use clap::Parser;
use nym_vpn_proto::{
ConnectRequest, DisconnectRequest, Empty, ImportUserCredentialRequest, StatusRequest,
ConnectRequest, DisconnectRequest, Empty, ImportUserCredentialRequest, InfoRequest,
StatusRequest,
};
use vpnd_client::ClientType;

use crate::{
cli::{Command, ImportCredentialTypeEnum},
protobuf_conversion::{into_entry_point, into_exit_point, ipaddr_into_string},
protobuf_conversion::{
into_entry_point, into_exit_point, ipaddr_into_string, parse_offset_datetime,
},
};

mod cli;
Expand All @@ -30,6 +33,7 @@ async fn main() -> Result<()> {
Command::Connect(ref connect_args) => connect(client_type, connect_args).await?,
Command::Disconnect => disconnect(client_type).await?,
Command::Status => status(client_type).await?,
Command::Info => info(client_type).await?,
Command::ImportCredential(ref import_args) => {
import_credential(client_type, import_args).await?
}
Expand Down Expand Up @@ -74,22 +78,30 @@ async fn status(client_type: ClientType) -> Result<()> {
let response = client.vpn_status(request).await?.into_inner();
println!("{:?}", response);

let utc_since = response
if let Some(Ok(utc_since)) = response
.details
.and_then(|details| details.since)
.map(|timestamp| {
time::OffsetDateTime::from_unix_timestamp(timestamp.seconds)
.map(|t| t + time::Duration::nanoseconds(timestamp.nanos as i64))
});

if let Some(utc_since) = utc_since {
match utc_since {
Ok(utc_since) => {
println!("since (utc): {:?}", utc_since);
println!("duration: {}", time::OffsetDateTime::now_utc() - utc_since);
}
Err(err) => eprintln!("failed to parse timestamp: {err}"),
}
.map(parse_offset_datetime)
{
println!("since (utc): {:?}", utc_since);
println!("duration: {}", time::OffsetDateTime::now_utc() - utc_since);
}

Ok(())
}

async fn info(client_type: ClientType) -> Result<()> {
let mut client = vpnd_client::get_client(client_type).await?;
let request = tonic::Request::new(InfoRequest {});
let response = client.info(request).await?.into_inner();
println!("{:?}", response);

if let Some(Ok(utc_build_timestamp)) = response.build_timestamp.map(parse_offset_datetime) {
println!("build timestamp (utc): {:?}", utc_build_timestamp);
println!(
"build age: {}",
time::OffsetDateTime::now_utc() - utc_build_timestamp
);
}
Ok(())
}
Expand Down
8 changes: 8 additions & 0 deletions nym-vpn-core/nym-vpnc/src/protobuf_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,11 @@ pub(crate) fn into_exit_point(exit: ExitPoint) -> nym_vpn_proto::ExitNode {
pub(crate) fn ipaddr_into_string(ip: std::net::IpAddr) -> nym_vpn_proto::Dns {
nym_vpn_proto::Dns { ip: ip.to_string() }
}

pub(crate) fn parse_offset_datetime(
timestamp: prost_types::Timestamp,
) -> Result<time::OffsetDateTime, time::Error> {
time::OffsetDateTime::from_unix_timestamp(timestamp.seconds)
.map(|t| t + time::Duration::nanoseconds(timestamp.nanos as i64))
.map_err(time::Error::from)
}
38 changes: 25 additions & 13 deletions nym-vpn-core/nym-vpnd/src/command_interface/connection_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
use nym_vpn_lib::gateway_directory::{EntryPoint, ExitPoint};
use time::OffsetDateTime;
use tokio::sync::{mpsc::UnboundedSender, oneshot};
use tracing::{info, warn};
use tracing::{debug, info, warn};

use crate::service::{
ConnectArgs, ConnectOptions, ImportCredentialError, VpnServiceCommand, VpnServiceConnectResult,
VpnServiceDisconnectResult, VpnServiceStatusResult,
VpnServiceDisconnectResult, VpnServiceInfoResult, VpnServiceStatusResult,
};

pub(super) struct CommandInterfaceConnectionHandler {
Expand Down Expand Up @@ -36,8 +36,8 @@ impl CommandInterfaceConnectionHandler {
self.vpn_command_tx
.send(VpnServiceCommand::Connect(tx, connect_args))
.unwrap();
info!("Sent start command to VPN");
info!("Waiting for response");
debug!("Sent start command to VPN");
debug!("Waiting for response");
let result = rx.await.unwrap();
match result {
VpnServiceConnectResult::Success(ref _connect_handle) => {
Expand All @@ -55,12 +55,12 @@ impl CommandInterfaceConnectionHandler {
self.vpn_command_tx
.send(VpnServiceCommand::Disconnect(tx))
.unwrap();
info!("Sent stop command to VPN");
info!("Waiting for response");
debug!("Sent stop command to VPN");
debug!("Waiting for response");
let result = rx.await.unwrap();
match result {
VpnServiceDisconnectResult::Success => {
info!("VPN disconnect command sent successfully");
debug!("VPN disconnect command sent successfully");
}
VpnServiceDisconnectResult::NotRunning => {
info!("VPN can't stop - it's not running");
Expand All @@ -72,15 +72,27 @@ impl CommandInterfaceConnectionHandler {
result
}

pub(crate) async fn handle_info(&self) -> VpnServiceInfoResult {
let (tx, rx) = oneshot::channel();
self.vpn_command_tx
.send(VpnServiceCommand::Info(tx))
.unwrap();
debug!("Sent info command to VPN");
debug!("Waiting for response");
let info = rx.await.unwrap();
debug!("VPN info: {:?}", info);
info
}

pub(crate) async fn handle_status(&self) -> VpnServiceStatusResult {
let (tx, rx) = oneshot::channel();
self.vpn_command_tx
.send(VpnServiceCommand::Status(tx))
.unwrap();
info!("Sent status command to VPN");
info!("Waiting for response");
debug!("Sent status command to VPN");
debug!("Waiting for response");
let status = rx.await.unwrap();
info!("VPN status: {}", status);
debug!("VPN status: {}", status);
status
}

Expand All @@ -92,10 +104,10 @@ impl CommandInterfaceConnectionHandler {
self.vpn_command_tx
.send(VpnServiceCommand::ImportCredential(tx, credential))
.unwrap();
info!("Sent import credential command to VPN");
info!("Waiting for response");
debug!("Sent import credential command to VPN");
debug!("Waiting for response");
let result = rx.await.unwrap();
info!("VPN import credential result: {:?}", result);
debug!("VPN import credential result: {:?}", result);
result
}
}
35 changes: 27 additions & 8 deletions nym-vpn-core/nym-vpnd/src/command_interface/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use nym_vpn_proto::{
ConnectionStatusUpdate, DisconnectRequest, DisconnectResponse, Empty,
ImportUserCredentialRequest, ImportUserCredentialResponse, StatusRequest, StatusResponse,
};
use nym_vpn_proto::{InfoRequest, InfoResponse};
use prost_types::Timestamp;
use tokio::sync::{broadcast, mpsc::UnboundedSender};
use tracing::{error, info};
Expand Down Expand Up @@ -100,6 +101,21 @@ impl Drop for CommandInterface {

#[tonic::async_trait]
impl NymVpnd for CommandInterface {
async fn info(
&self,
request: tonic::Request<InfoRequest>,
) -> Result<tonic::Response<InfoResponse>, tonic::Status> {
info!("Got info request: {:?}", request);

let info = CommandInterfaceConnectionHandler::new(self.vpn_command_tx.clone())
.handle_info()
.await;

let response = InfoResponse::from(info);
info!("Returning info response: {:?}", response);
Ok(tonic::Response::new(response))
}

async fn vpn_connect(
&self,
request: tonic::Request<ConnectRequest>,
Expand Down Expand Up @@ -143,8 +159,9 @@ impl NymVpnd for CommandInterface {
.start();
}

info!("Returning connect response");
Ok(tonic::Response::new(ConnectResponse { success }))
let response = ConnectResponse { success };
info!("Returning connect response: {:?}", response);
Ok(tonic::Response::new(response))
}

async fn vpn_disconnect(
Expand All @@ -157,10 +174,11 @@ impl NymVpnd for CommandInterface {
.handle_disconnect()
.await;

info!("Returning disconnect response");
Ok(tonic::Response::new(DisconnectResponse {
let response = DisconnectResponse {
success: status.is_success(),
}))
};
info!("Returning disconnect response: {:?}", response);
Ok(tonic::Response::new(response))
}

async fn vpn_status(
Expand All @@ -173,8 +191,9 @@ impl NymVpnd for CommandInterface {
.handle_status()
.await;

info!("Returning status response");
Ok(tonic::Response::new(StatusResponse::from(status)))
let response = StatusResponse::from(status);
info!("Returning status response: {:?}", response);
Ok(tonic::Response::new(response))
}

async fn import_user_credential(
Expand All @@ -189,7 +208,6 @@ impl NymVpnd for CommandInterface {
.handle_import_credential(credential)
.await;

info!("Returning import credential response");
let response = match response {
Ok(time) => ImportUserCredentialResponse {
success: true,
Expand All @@ -202,6 +220,7 @@ impl NymVpnd for CommandInterface {
expiry: None,
},
};
info!("Returning import credential response: {:?}", response);

Ok(tonic::Response::new(response))
}
Expand Down
21 changes: 19 additions & 2 deletions nym-vpn-core/nym-vpnd/src/command_interface/proto_response.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only

use crate::service::{VpnServiceStateChange, VpnServiceStatusResult};
use nym_vpn_proto::{ConnectionStateChange, ConnectionStatus, Error as ProtoError, StatusResponse};
use crate::service::{VpnServiceInfoResult, VpnServiceStateChange, VpnServiceStatusResult};
use nym_vpn_proto::{
ConnectionStateChange, ConnectionStatus, Error as ProtoError, InfoResponse, StatusResponse,
};

impl From<VpnServiceStatusResult> for StatusResponse {
fn from(status: VpnServiceStatusResult) -> Self {
Expand Down Expand Up @@ -50,6 +52,21 @@ impl From<VpnServiceStatusResult> for StatusResponse {
}
}

impl From<VpnServiceInfoResult> for InfoResponse {
fn from(info: VpnServiceInfoResult) -> Self {
let build_timestamp = info.build_timestamp.map(|ts| prost_types::Timestamp {
seconds: ts.unix_timestamp(),
nanos: ts.nanosecond() as i32,
});
InfoResponse {
version: info.version,
build_timestamp,
triple: info.triple,
git_commit: info.git_commit,
}
}
}

impl From<VpnServiceStateChange> for ConnectionStateChange {
fn from(status: VpnServiceStateChange) -> Self {
let mut error = None;
Expand Down
3 changes: 2 additions & 1 deletion nym-vpn-core/nym-vpnd/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ pub(crate) use error::{ConnectionFailedError, ImportCredentialError};
pub(crate) use start::start_vpn_service;
pub(crate) use vpn_service::{
ConnectArgs, ConnectOptions, VpnServiceCommand, VpnServiceConnectResult,
VpnServiceDisconnectResult, VpnServiceStateChange, VpnServiceStatusResult,
VpnServiceDisconnectResult, VpnServiceInfoResult, VpnServiceStateChange,
VpnServiceStatusResult,
};
Loading
Loading