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(rename = "TailscaleIPs", deserialize_with = "deserialize_default_from_null")]
102    pub tailscale_ips: Vec<IpAddr>,
103    #[serde(rename = "Self")]
104    pub self_status: PeerStatus,
105    #[serde(deserialize_with = "deserialize_default_from_null")]
106    pub health: Vec<String>,
107    pub current_tailnet: Option<TailnetStatus>,
108    #[serde(deserialize_with = "deserialize_default_from_null")]
109    pub cert_domains: Vec<String>,
110    #[serde(deserialize_with = "deserialize_default_from_null")]
111    pub peer: HashMap<String, PeerStatus>,
112    #[serde(deserialize_with = "deserialize_default_from_null")]
113    pub user: HashMap<i64, UserProfile>,
114}
115
116/// Service protocol
117#[derive(Deserialize, Debug, Copy, Clone)]
118#[non_exhaustive]
119pub enum ServiceProto {
120    #[serde(rename = "tcp")]
121    Tcp,
122    #[serde(rename = "udp")]
123    Udp,
124    #[serde(rename = "peerapi4")]
125    PeerAPI4,
126    #[serde(rename = "peerapi6")]
127    PeerAPI6,
128    #[serde(rename = "peerapi-dns-proxy")]
129    PeerAPIDNS,
130}
131
132/// Service running on a node
133#[derive(Deserialize, Debug, Clone)]
134#[serde(rename_all = "PascalCase")]
135pub struct Service {
136    pub proto: ServiceProto,
137    pub port: u16,
138    pub description: Option<String>,
139}
140
141/// Host information
142#[derive(Deserialize, Debug, Clone)]
143#[serde(rename_all = "PascalCase")]
144pub struct Hostinfo {
145    #[serde(rename = "OS")]
146    pub os: Option<String>,
147    #[serde(rename = "OSVersion")]
148    pub os_version: Option<String>,
149    pub hostname: Option<String>,
150    pub services: Option<Vec<Service>>,
151    #[serde(default, rename = "sshHostKeys")]
152    pub ssh_hostkeys: Option<Vec<String>>,
153}
154
155/// Node in the tailnet
156#[derive(Deserialize, Debug, Clone)]
157#[serde(rename_all = "PascalCase")]
158pub struct Node {
159    #[serde(rename = "ID")]
160    pub id: i64,
161    #[serde(rename = "StableID")]
162    pub stable_id: String,
163    pub name: String,
164    pub user: i64,
165    pub sharer: Option<i64>,
166    pub key: String,
167    pub key_expiry: DateTime<Utc>,
168    pub machine: String,
169    pub disco_key: String,
170    pub addresses: Vec<String>,
171    #[serde(rename = "AllowedIPs")]
172    pub allowed_ips: Vec<String>,
173    pub endpoints: Option<Vec<SocketAddr>>,
174    #[serde(rename = "DERP")]
175    pub derp: Option<String>,
176    pub hostinfo: Hostinfo,
177    pub created: DateTime<Utc>,
178    #[serde(default)]
179    pub tags: Vec<String>,
180    #[serde(default)]
181    pub primary_routes: Vec<String>,
182    pub last_seen: Option<DateTime<Utc>>,
183    pub online: Option<bool>,
184    pub keep_alive: Option<bool>,
185    pub machine_authorized: Option<bool>, // TODO: Check the upstream code if this has changed to MachineStatus
186    #[serde(default)]
187    pub capabilities: Vec<String>,
188    #[serde(deserialize_with = "deserialize_default_from_null")]
189    pub computed_name: String,
190    #[serde(deserialize_with = "deserialize_default_from_null")]
191    pub computed_name_with_host: String,
192}
193
194/// User profile.
195#[derive(Deserialize, Debug, Clone)]
196#[serde(rename_all = "PascalCase")]
197pub struct UserProfile {
198    #[serde(rename = "ID")]
199    pub id: i64,
200    pub login_name: String,
201    pub display_name: String,
202    #[serde(rename = "ProfilePicURL")]
203    pub profile_pic_url: String,
204}
205
206/// Whois response
207#[derive(Deserialize, Debug, Clone)]
208#[serde(rename_all = "PascalCase")]
209pub struct Whois {
210    pub node: Node,
211    pub user_profile: UserProfile,
212    #[serde(default)]
213    pub caps: Vec<String>,
214}
215
216/// DER encoded X.509 certificate for the node. This can either be the leaf
217/// certificate or part of the certificate chain.
218pub struct Certificate(pub Vec<u8>);
219
220/// DER encoded private key for the node
221pub struct PrivateKey(pub Vec<u8>);