tailscale_localapi/
types.rs

1use std::{
2    collections::HashMap,
3    net::{IpAddr, SocketAddr},
4};
5
6use chrono::{DateTime, Utc};
7use serde::Deserialize;
8use serde_aux::prelude::*;
9
10/// State of the backend
11#[derive(Deserialize, Debug)]
12#[non_exhaustive]
13pub enum BackendState {
14    NoState,
15    NeedsLogin,
16    NeedsMachineAuth,
17    Stopped,
18    Starting,
19    Running,
20}
21
22/// Status of a peer
23#[derive(Deserialize, Debug)]
24#[serde(rename_all = "PascalCase")]
25pub struct PeerStatus {
26    #[serde(rename = "ID")]
27    pub id: String,
28    pub public_key: String,
29    #[serde(rename = "HostName")]
30    pub hostname: String,
31    #[serde(rename = "DNSName")]
32    pub dnsname: String,
33    #[serde(rename = "OS")]
34    pub os: String,
35    #[serde(rename = "UserID")]
36    pub user_id: i64,
37    #[serde(
38        rename = "TailscaleIPs",
39        deserialize_with = "deserialize_default_from_null"
40    )]
41    pub tailscale_ips: Vec<IpAddr>,
42    #[serde(default, deserialize_with = "deserialize_default_from_null")]
43    pub tags: Vec<String>,
44    #[serde(default, deserialize_with = "deserialize_default_from_null")]
45    pub primary_routes: Vec<String>,
46    #[serde(deserialize_with = "deserialize_default_from_null")]
47    pub addrs: Vec<String>,
48    pub cur_addr: String,
49    pub relay: String,
50    pub rx_bytes: i64,
51    pub tx_bytes: i64,
52    pub created: DateTime<Utc>,
53    pub last_write: DateTime<Utc>,
54    pub last_seen: DateTime<Utc>,
55    pub last_handshake: DateTime<Utc>,
56    pub online: bool,
57    #[serde(default)]
58    pub keep_alive: bool,
59    pub exit_node: bool,
60    pub exit_node_option: bool,
61    pub active: bool,
62    #[serde(
63        rename = "PeerAPIURL",
64        deserialize_with = "deserialize_default_from_null"
65    )]
66    pub peer_api_url: Vec<String>,
67    #[serde(default, deserialize_with = "deserialize_default_from_null")]
68    pub capabilities: Vec<String>,
69    #[serde(
70        default,
71        rename = "sshHostKeys",
72        deserialize_with = "deserialize_default_from_null"
73    )]
74    pub ssh_hostkeys: Vec<String>,
75    #[serde(default)]
76    pub sharee_node: bool,
77    pub in_network_map: bool,
78    pub in_magic_sock: bool,
79    pub in_engine: bool,
80}
81
82/// Status of the current tailnet.
83#[derive(Deserialize, Debug)]
84#[serde(rename_all = "PascalCase")]
85pub struct TailnetStatus {
86    pub name: String,
87    #[serde(rename = "MagicDNSSuffix")]
88    pub magic_dns_suffix: String,
89    #[serde(rename = "MagicDNSEnabled")]
90    pub magic_dns_enabled: bool,
91}
92
93/// Status of the local tailscaled.
94#[derive(Deserialize, Debug)]
95#[serde(rename_all = "PascalCase")]
96pub struct Status {
97    pub version: String,
98    pub backend_state: BackendState,
99    #[serde(rename = "AuthURL")]
100    pub auth_url: String,
101    #[serde(
102        rename = "TailscaleIPs",
103        deserialize_with = "deserialize_default_from_null"
104    )]
105    pub tailscale_ips: Vec<IpAddr>,
106    #[serde(rename = "Self")]
107    pub self_status: PeerStatus,
108    #[serde(deserialize_with = "deserialize_default_from_null")]
109    pub health: Vec<String>,
110    pub current_tailnet: Option<TailnetStatus>,
111    #[serde(deserialize_with = "deserialize_default_from_null")]
112    pub cert_domains: Vec<String>,
113    #[serde(deserialize_with = "deserialize_default_from_null")]
114    pub peer: HashMap<String, PeerStatus>,
115    #[serde(deserialize_with = "deserialize_default_from_null")]
116    pub user: HashMap<i64, UserProfile>,
117}
118
119/// Service protocol
120#[derive(Deserialize, Debug, Copy, Clone)]
121#[non_exhaustive]
122pub enum ServiceProto {
123    #[serde(rename = "tcp")]
124    Tcp,
125    #[serde(rename = "udp")]
126    Udp,
127    #[serde(rename = "peerapi4")]
128    PeerAPI4,
129    #[serde(rename = "peerapi6")]
130    PeerAPI6,
131    #[serde(rename = "peerapi-dns-proxy")]
132    PeerAPIDNS,
133}
134
135/// Service running on a node
136#[derive(Deserialize, Debug, Clone)]
137#[serde(rename_all = "PascalCase")]
138pub struct Service {
139    pub proto: ServiceProto,
140    pub port: u16,
141    pub description: Option<String>,
142}
143
144/// Host information
145#[derive(Deserialize, Debug, Clone)]
146#[serde(rename_all = "PascalCase")]
147pub struct Hostinfo {
148    #[serde(rename = "OS")]
149    pub os: Option<String>,
150    #[serde(rename = "OSVersion")]
151    pub os_version: Option<String>,
152    pub hostname: Option<String>,
153    pub services: Option<Vec<Service>>,
154    #[serde(default, rename = "sshHostKeys")]
155    pub ssh_hostkeys: Option<Vec<String>>,
156}
157
158/// Node in the tailnet
159#[derive(Deserialize, Debug, Clone)]
160#[serde(rename_all = "PascalCase")]
161pub struct Node {
162    #[serde(rename = "ID")]
163    pub id: i64,
164    #[serde(rename = "StableID")]
165    pub stable_id: String,
166    pub name: String,
167    pub user: i64,
168    pub sharer: Option<i64>,
169    pub key: String,
170    pub key_expiry: DateTime<Utc>,
171    pub machine: String,
172    pub disco_key: String,
173    pub addresses: Vec<String>,
174    #[serde(rename = "AllowedIPs")]
175    pub allowed_ips: Vec<String>,
176    pub endpoints: Option<Vec<SocketAddr>>,
177    #[serde(rename = "DERP")]
178    pub derp: Option<String>,
179    pub hostinfo: Hostinfo,
180    pub created: DateTime<Utc>,
181    #[serde(default)]
182    pub tags: Vec<String>,
183    #[serde(default)]
184    pub primary_routes: Vec<String>,
185    pub last_seen: Option<DateTime<Utc>>,
186    pub online: Option<bool>,
187    pub keep_alive: Option<bool>,
188    pub machine_authorized: Option<bool>, // TODO: Check the upstream code if this has changed to MachineStatus
189    #[serde(default)]
190    pub capabilities: Vec<String>,
191    #[serde(deserialize_with = "deserialize_default_from_null")]
192    pub computed_name: String,
193    #[serde(deserialize_with = "deserialize_default_from_null")]
194    pub computed_name_with_host: String,
195}
196
197/// User profile.
198#[derive(Deserialize, Debug, Clone)]
199#[serde(rename_all = "PascalCase")]
200pub struct UserProfile {
201    #[serde(rename = "ID")]
202    pub id: i64,
203    pub login_name: String,
204    pub display_name: String,
205    #[serde(rename = "ProfilePicURL")]
206    pub profile_pic_url: Option<String>,
207}
208
209/// Whois response
210#[derive(Deserialize, Debug, Clone)]
211#[serde(rename_all = "PascalCase")]
212pub struct Whois {
213    pub node: Node,
214    pub user_profile: UserProfile,
215    #[serde(default)]
216    pub caps: Vec<String>,
217}
218
219/// DER encoded X.509 certificate for the node. This can either be the leaf
220/// certificate or part of the certificate chain.
221pub struct Certificate(pub Vec<u8>);
222
223/// DER encoded private key for the node
224pub struct PrivateKey(pub Vec<u8>);