spiffe_rs/workloadapi/
option.rs1use crate::logger;
2use crate::workloadapi::{backoff, client::Client, LoggerRef};
3use std::sync::Arc;
4
5pub trait ClientOption: Send + Sync {
7 fn configure_client(&self, config: &mut ClientConfig);
8}
9
10pub trait SourceOption: Send + Sync {
12 fn configure_x509_source(&self, config: &mut X509SourceConfig);
13 fn configure_jwt_source(&self, config: &mut JWTSourceConfig);
14 fn configure_bundle_source(&self, config: &mut BundleSourceConfig);
15}
16
17pub trait X509SourceOption: Send + Sync {
19 fn configure_x509_source(&self, config: &mut X509SourceConfig);
20}
21
22pub trait JWTSourceOption: Send + Sync {
24 fn configure_jwt_source(&self, config: &mut JWTSourceConfig);
25}
26
27pub trait BundleSourceOption: Send + Sync {
29 fn configure_bundle_source(&self, config: &mut BundleSourceConfig);
30}
31
32pub trait DialOption: Send + Sync {
34 fn apply(&self, endpoint: tonic::transport::Endpoint) -> tonic::transport::Endpoint;
35}
36
37pub fn with_addr(addr: impl Into<String>) -> Arc<dyn ClientOption> {
39 Arc::new(WithAddr {
40 addr: addr.into(),
41 })
42}
43
44pub fn with_dial_options(options: Vec<Arc<dyn DialOption>>) -> Arc<dyn ClientOption> {
46 Arc::new(WithDialOptions { options })
47}
48
49pub fn with_logger(log: LoggerRef) -> Arc<dyn ClientOption> {
51 Arc::new(WithLogger { log })
52}
53
54pub fn with_backoff_strategy(strategy: Arc<dyn backoff::BackoffStrategy>) -> Arc<dyn ClientOption> {
56 Arc::new(WithBackoffStrategy { strategy })
57}
58
59pub fn with_client(client: Arc<Client>) -> Arc<dyn SourceOption> {
61 Arc::new(WithClient { client })
62}
63
64pub fn with_client_options(options: Vec<Arc<dyn ClientOption>>) -> Arc<dyn SourceOption> {
66 Arc::new(WithClientOptions { options })
67}
68
69pub fn with_default_x509_svid_picker(
71 picker: Arc<dyn Fn(&[crate::svid::x509svid::SVID]) -> crate::svid::x509svid::SVID + Send + Sync>,
72) -> Arc<dyn X509SourceOption> {
73 Arc::new(WithDefaultX509SVIDPicker { picker })
74}
75
76pub fn with_default_jwt_svid_picker(
78 picker: Arc<dyn Fn(&[crate::svid::jwtsvid::SVID]) -> crate::svid::jwtsvid::SVID + Send + Sync>,
79) -> Arc<dyn JWTSourceOption> {
80 Arc::new(WithDefaultJWTSVIDPicker { picker })
81}
82
83#[derive(Clone)]
84pub struct ClientConfig {
85 pub address: Option<String>,
86 pub dial_options: Vec<Arc<dyn DialOption>>,
87 pub log: LoggerRef,
88 pub backoff_strategy: Arc<dyn backoff::BackoffStrategy>,
89}
90
91impl Default for ClientConfig {
92 fn default() -> Self {
93 Self {
94 address: None,
95 dial_options: Vec::new(),
96 log: Arc::new(logger::null_logger()),
97 backoff_strategy: Arc::new(backoff::LinearBackoffStrategy::default()),
98 }
99 }
100}
101
102pub struct WatcherConfig {
103 pub client: Option<Arc<Client>>,
104 pub client_options: Vec<Arc<dyn ClientOption>>,
105}
106
107impl Default for WatcherConfig {
108 fn default() -> Self {
109 Self {
110 client: None,
111 client_options: Vec::new(),
112 }
113 }
114}
115
116pub struct X509SourceConfig {
117 pub watcher: WatcherConfig,
118 pub picker: Option<
119 Arc<dyn Fn(&[crate::svid::x509svid::SVID]) -> crate::svid::x509svid::SVID + Send + Sync>,
120 >,
121}
122
123impl Default for X509SourceConfig {
124 fn default() -> Self {
125 Self {
126 watcher: WatcherConfig::default(),
127 picker: None,
128 }
129 }
130}
131
132pub struct JWTSourceConfig {
133 pub watcher: WatcherConfig,
134 pub picker:
135 Option<Arc<dyn Fn(&[crate::svid::jwtsvid::SVID]) -> crate::svid::jwtsvid::SVID + Send + Sync>>,
136}
137
138impl Default for JWTSourceConfig {
139 fn default() -> Self {
140 Self {
141 watcher: WatcherConfig::default(),
142 picker: None,
143 }
144 }
145}
146
147pub struct BundleSourceConfig {
148 pub watcher: WatcherConfig,
149}
150
151impl Default for BundleSourceConfig {
152 fn default() -> Self {
153 Self {
154 watcher: WatcherConfig::default(),
155 }
156 }
157}
158
159struct WithAddr {
160 addr: String,
161}
162
163impl ClientOption for WithAddr {
164 fn configure_client(&self, config: &mut ClientConfig) {
165 config.address = Some(self.addr.clone());
166 }
167}
168
169struct WithDialOptions {
170 options: Vec<Arc<dyn DialOption>>,
171}
172
173impl ClientOption for WithDialOptions {
174 fn configure_client(&self, config: &mut ClientConfig) {
175 config.dial_options.extend(self.options.iter().cloned());
176 }
177}
178
179struct WithLogger {
180 log: LoggerRef,
181}
182
183impl ClientOption for WithLogger {
184 fn configure_client(&self, config: &mut ClientConfig) {
185 config.log = self.log.clone();
186 }
187}
188
189struct WithBackoffStrategy {
190 strategy: Arc<dyn backoff::BackoffStrategy>,
191}
192
193impl ClientOption for WithBackoffStrategy {
194 fn configure_client(&self, config: &mut ClientConfig) {
195 config.backoff_strategy = self.strategy.clone();
196 }
197}
198
199struct WithClient {
200 client: Arc<Client>,
201}
202
203impl SourceOption for WithClient {
204 fn configure_x509_source(&self, config: &mut X509SourceConfig) {
205 config.watcher.client = Some(self.client.clone());
206 }
207
208 fn configure_jwt_source(&self, config: &mut JWTSourceConfig) {
209 config.watcher.client = Some(self.client.clone());
210 }
211
212 fn configure_bundle_source(&self, config: &mut BundleSourceConfig) {
213 config.watcher.client = Some(self.client.clone());
214 }
215}
216
217struct WithClientOptions {
218 options: Vec<Arc<dyn ClientOption>>,
219}
220
221impl SourceOption for WithClientOptions {
222 fn configure_x509_source(&self, config: &mut X509SourceConfig) {
223 config.watcher.client_options = self.options.clone();
224 }
225
226 fn configure_jwt_source(&self, config: &mut JWTSourceConfig) {
227 config.watcher.client_options = self.options.clone();
228 }
229
230 fn configure_bundle_source(&self, config: &mut BundleSourceConfig) {
231 config.watcher.client_options = self.options.clone();
232 }
233}
234
235struct WithDefaultX509SVIDPicker {
236 picker: Arc<dyn Fn(&[crate::svid::x509svid::SVID]) -> crate::svid::x509svid::SVID + Send + Sync>,
237}
238
239impl X509SourceOption for WithDefaultX509SVIDPicker {
240 fn configure_x509_source(&self, config: &mut X509SourceConfig) {
241 config.picker = Some(self.picker.clone());
242 }
243}
244
245impl SourceOption for WithDefaultX509SVIDPicker {
246 fn configure_x509_source(&self, config: &mut X509SourceConfig) {
247 X509SourceOption::configure_x509_source(self, config);
248 }
249
250 fn configure_jwt_source(&self, _config: &mut JWTSourceConfig) {}
251
252 fn configure_bundle_source(&self, _config: &mut BundleSourceConfig) {}
253}
254
255struct WithDefaultJWTSVIDPicker {
256 picker: Arc<dyn Fn(&[crate::svid::jwtsvid::SVID]) -> crate::svid::jwtsvid::SVID + Send + Sync>,
257}
258
259impl JWTSourceOption for WithDefaultJWTSVIDPicker {
260 fn configure_jwt_source(&self, config: &mut JWTSourceConfig) {
261 config.picker = Some(self.picker.clone());
262 }
263}
264
265impl SourceOption for WithDefaultJWTSVIDPicker {
266 fn configure_x509_source(&self, _config: &mut X509SourceConfig) {}
267
268 fn configure_jwt_source(&self, config: &mut JWTSourceConfig) {
269 JWTSourceOption::configure_jwt_source(self, config);
270 }
271
272 fn configure_bundle_source(&self, _config: &mut BundleSourceConfig) {}
273}