wireguard_conf/models/builders.rs
1use either::Either;
2use ipnet::Ipv4Net;
3
4use crate::prelude::*;
5
6/// Builder, that used for creating [`Interface`]s.
7///
8/// # Examples
9///
10/// ```
11/// use wireguard_conf::prelude::*;
12///
13/// let server_private_key = PrivateKey::random();
14///
15/// let interface = InterfaceBuilder::new()
16/// .address("10.0.0.1/24".parse().unwrap())
17/// .listen_port(6969)
18/// .private_key(server_private_key.clone())
19/// .set_dns(vec!["8.8.8.8".to_string(), "8.8.4.4".to_string()])
20/// .endpoint("vpn.example.com".to_string())
21/// // .add_peer(some_peer)
22/// .build();
23///
24/// assert_eq!(interface.address, "10.0.0.1/24".parse().unwrap());
25/// assert_eq!(interface.listen_port, Some(6969));
26/// assert_eq!(interface.private_key, server_private_key);
27/// assert_eq!(interface.dns, vec!["8.8.8.8", "8.8.4.4"]);
28/// assert_eq!(interface.endpoint, Some("vpn.example.com".to_string()));
29/// ```
30#[must_use]
31#[derive(Default)]
32pub struct InterfaceBuilder {
33 address: Ipv4Net,
34 listen_port: Option<u16>,
35 private_key: Option<PrivateKey>,
36 dns: Vec<String>,
37 endpoint: Option<String>,
38 peers: Vec<Peer>,
39}
40
41impl InterfaceBuilder {
42 pub fn new() -> InterfaceBuilder {
43 InterfaceBuilder::default()
44 }
45
46 /// Set the address.
47 ///
48 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#address)
49 pub fn address(mut self, address: Ipv4Net) -> Self {
50 self.address = address;
51 self
52 }
53
54 /// Set the listen port.
55 ///
56 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#listenport)
57 pub fn listen_port(mut self, listen_port: u16) -> Self {
58 self.listen_port = Some(listen_port);
59 self
60 }
61
62 /// Set the private key.
63 ///
64 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#privatekey)
65 pub fn private_key(mut self, private_key: PrivateKey) -> Self {
66 self.private_key = Some(private_key);
67 self
68 }
69
70 /// Set the DNS servers array.
71 ///
72 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#dns-2)
73 pub fn set_dns(mut self, dns: Vec<String>) -> Self {
74 self.dns = dns;
75 self
76 }
77
78 /// Add DNS server.
79 ///
80 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#dns-2)
81 pub fn add_dns(mut self, dns: String) -> Self {
82 self.dns.push(dns);
83 self
84 }
85
86 /// Set the endpoint.
87 ///
88 /// # Note
89 ///
90 /// - In interface's config this set `# Name = ...`
91 /// - If you export interface via [`Interface::as_peer()`], exported peer will have this
92 /// `Peer.endpoint`
93 ///
94 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#listenport)
95 pub fn endpoint(mut self, endpoint: String) -> Self {
96 self.endpoint = Some(endpoint);
97 self
98 }
99
100 /// Set the Peers array.
101 ///
102 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#peer)
103 pub fn set_peers(mut self, peers: Vec<Peer>) -> Self {
104 self.peers = peers;
105 self
106 }
107
108 /// Add peer.
109 ///
110 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#peer)
111 pub fn add_peer(mut self, peer: Peer) -> Self {
112 self.peers.push(peer);
113 self
114 }
115
116 /// Creates [`Interface`].
117 pub fn build(self) -> Interface {
118 Interface {
119 address: self.address,
120 listen_port: self.listen_port,
121 private_key: self.private_key.unwrap_or_else(PrivateKey::random),
122 dns: self.dns,
123
124 // TODO: do amnezia support
125 // amnezia_settings: None,
126
127 endpoint: self.endpoint,
128 peers: self.peers,
129 }
130 }
131}
132
133/// Builder, that used for creating [`Peer`]s.
134///
135/// # Examples
136///
137/// ```
138/// use wireguard_conf::prelude::*;
139/// use either::Either;
140///
141/// let client_private_key = PrivateKey::random();
142///
143/// let peer = PeerBuilder::new()
144/// .endpoint("public.client.example.com".to_string())
145/// .add_allowed_ip("10.0.0.2/32".parse().unwrap())
146/// .private_key(client_private_key.clone())
147/// // if you don't want to generate interface from peer, you can provide public key
148/// // instead of private_key:
149/// // .public_key(client_public_key)
150/// .build();
151///
152/// assert_eq!(peer.endpoint, Some("public.client.example.com".to_string()));
153/// assert_eq!(peer.allowed_ips, vec!["10.0.0.2/32".parse().unwrap()]);
154/// assert_eq!(peer.key, Either::Left(client_private_key));
155/// ```
156#[must_use]
157#[derive(Default)]
158pub struct PeerBuilder {
159 endpoint: Option<String>,
160 allowed_ips: Vec<Ipv4Net>,
161 key: Option<Either<PrivateKey, PublicKey>>,
162}
163
164impl PeerBuilder {
165 pub fn new() -> PeerBuilder {
166 PeerBuilder::default()
167 }
168
169 /// Sets endpoint.
170 ///
171 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#endpoint)
172 pub fn endpoint(mut self, endpoint: String) -> PeerBuilder {
173 self.endpoint = Some(endpoint);
174 self
175 }
176
177 /// Sets Allowed IPs array.
178 ///
179 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#allowedips)
180 pub fn set_allowed_ips(mut self, ip: Vec<Ipv4Net>) -> PeerBuilder {
181 self.allowed_ips = ip;
182 self
183 }
184
185 /// Adds allowed IP.
186 ///
187 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#allowedips)
188 pub fn add_allowed_ip(mut self, ip: Ipv4Net) -> PeerBuilder {
189 self.allowed_ips.push(ip);
190 self
191 }
192
193 /// Sets private key.
194 ///
195 /// # Note
196 ///
197 /// If you set private key (instead of public key), you can generate [`Interface`] from [`Peer`] (see [`Peer::as_interface()`]).
198 ///
199 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#publickey)
200 pub fn private_key(mut self, private_key: PrivateKey) -> PeerBuilder {
201 self.key = Some(Either::Left(private_key));
202 self
203 }
204
205 /// Sets public key.
206 ///
207 /// [Wireguard Docs](https://github.com/pirate/wireguard-docs?tab=readme-ov-file#publickey)
208 pub fn public_key(mut self, public_key: PublicKey) -> PeerBuilder {
209 self.key = Some(Either::Right(public_key));
210 self
211 }
212
213 /// Creates [`Peer`].
214 pub fn build(self) -> Peer {
215 let key = self
216 .key
217 .unwrap_or_else(|| Either::Left(PrivateKey::random()));
218
219 Peer {
220 endpoint: self.endpoint,
221 allowed_ips: self.allowed_ips,
222 key,
223 }
224 }
225}