5个稳定版本

1.2.2 2024年6月4日
1.2.1 2023年12月16日
1.2.0 2023年11月28日
1.1.0 2023年4月28日
1.0.0 2023年4月24日

#2 in #yggdrasil

MIT 许可协议

33KB
707

yggdrasilctl

一个用于访问 Yggdrasil网络路由器管理API 的库。

它支持同步和异步环境。您只需要提供实现 ReadWrite 特性的 socket,用于同步操作,或者来自异步运行时的 AsyncReadAsyncWrite 特性的 socket。目前支持的运行时是 tokiofutures。如果您的运行时不在列表中,请考虑创建一个问题或拉取请求。

兼容性

已成功测试与版本 yggdrasil-go0.4.40.4.70.5.10.5.40.5.50.5.6 的兼容性。您可以通过在 crate 目录中运行 YGGDRASIL_SOCKET="/run/yggdrasil/yggdrasil.sock" cargo test -p yggdrasilctl 来自行测试兼容性。

在版本 0.4.5(2022年10月)中,已更改输出列表的响应结构,已添加新的命令 addpeerremovepeergettun

在版本 0.5.0(2023年11月)中,已移除 getdht 命令,并添加了 gettree 命令。

基本用法

将以下任一行添加到 Cargo.toml 中的依赖项

# Use `std` (synchronous)
yggdrasilctl = "1"
# Use async runtime
# Available features: "use_tokio" or "use_futures"
yggdrasilctl = { version = "1", default-features = false, features = [ "use_tokio" ] }

下一步

use yggdrasilctl::Endpoint;
use std::os::unix::net::UnixStream;

// Create socket using your favorite runtime
let socket = UnixStream::connect("/run/yggdrasil/yggdrasil.sock")/*.await*/.unwrap();

// Attach endpoint to a socket
let mut endpoint = Endpoint::attach(socket);

// First you can get I/O or protocol parsing error
let maybe_error = endpoint.get_self()/*.await*/.unwrap();

// Then Admin API can return error (string) to your request
match maybe_error {
    Ok(response) => println!("Yggdrasil address: {}", response.address),
    Err(error) => println!("Admin API returned error: {error}"),
}

高级用法

您可能还需要执行 debug_* 请求,这些请求在此库中被故意未实现。为此,yggdrasilctl 允许您声明期望接收的响应结构。

首先,将 serdeserde_json 包添加到依赖项

# Imports derive macros for `Deserialize` trait
serde = { version = "1", features = [ "derive" ] }
# Imports enum `Value` that represents any possible json value
serde_json = "1"

下一步

use yggdrasilctl::Endpoint;
use serde::Deserialize;
use serde_json::Value;
use std::collections::HashMap;
use std::net::Ipv6Addr;

// Connect endpoint
use std::os::unix::net::UnixStream;
let socket = UnixStream::connect("/var/run/yggdrasil/yggdrasil.sock")/*.await*/.unwrap();
let mut endpoint = Endpoint::attach(socket);
let get_self = endpoint.get_self()/*.await*/.unwrap().unwrap();

// Declare a struct you expect to receive
#[derive(Deserialize)]
struct DebugRemoteGetSelfEntry {
    coords: String,
    key: String,
}
type DebugRemoteGetSelf = HashMap<Ipv6Addr, DebugRemoteGetSelfEntry>;

// Pass arguments to the request
let mut args = HashMap::<String, Value>::new();
args.insert("key".to_string(), Value::from(get_self.key.as_str()));

// Perform the request
let maybe_error = endpoint.request_args::<DebugRemoteGetSelf>("debug_remotegetself", args)/*.await*/.unwrap();

// Parse the request
match maybe_error {
    Ok(response) =>
        println!(
            "Yggdrasil node coordinates: {:?}",
            response[&get_self.address].coords
        ),
    Err(error) => println!("Admin API returned error: {error}"),
}

依赖项

~0.7–10MB
~93K SLoC