1use std::{
2 collections::HashMap,
3 net::{IpAddr, SocketAddr},
4};
5
6use chrono::{DateTime, Utc};
7use serde::Deserialize;
8use serde_aux::prelude::*;
9
10#[derive(Deserialize, Debug)]
12#[non_exhaustive]
13pub enum BackendState {
14 NoState,
15 NeedsLogin,
16 NeedsMachineAuth,
17 Stopped,
18 Starting,
19 Running,
20}
21
22#[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#[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#[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#[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#[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#[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#[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>, #[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#[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#[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
219pub struct Certificate(pub Vec<u8>);
222
223pub struct PrivateKey(pub Vec<u8>);