@@ -6,6 +6,8 @@ use serde::Serialize;
6
6
use serde_json:: Value ;
7
7
use std:: cmp:: Ordering ;
8
8
use std:: collections:: HashMap ;
9
+ use std:: io:: BufReader ;
10
+ use std:: io:: Read ;
9
11
use std:: time:: Duration ;
10
12
use tracing:: warn;
11
13
@@ -23,23 +25,13 @@ pub enum ClientError {
23
25
String ( String ) ,
24
26
}
25
27
26
- #[ derive( Debug , Default ) ]
28
+ #[ derive( Debug , Default , Clone ) ]
27
29
pub ( crate ) struct Client {
28
30
pub url : String ,
29
31
pub disable_certificate_validation : bool ,
30
32
pub username : Option < String > ,
31
33
pub password : Option < String > ,
32
- }
33
-
34
- impl Clone for Client {
35
- fn clone ( & self ) -> Self {
36
- Self {
37
- url : self . url . clone ( ) ,
38
- disable_certificate_validation : self . disable_certificate_validation ,
39
- username : self . username . clone ( ) ,
40
- password : self . password . clone ( ) ,
41
- }
42
- }
34
+ cert : Option < reqwest:: Certificate > ,
43
35
}
44
36
45
37
fn default_username ( ) -> Option < String > {
@@ -50,12 +42,38 @@ fn default_password() -> Option<String> {
50
42
std:: env:: var ( "EVEBOX_ELASTICSEARCH_PASSWORD" ) . ok ( )
51
43
}
52
44
45
+ fn load_certificate_from_file ( filename : & str ) -> anyhow:: Result < reqwest:: Certificate > {
46
+ let file = std:: fs:: File :: open ( filename) ?;
47
+ let mut reader = BufReader :: new ( file) ;
48
+ let mut buffer = vec ! [ ] ;
49
+ reader. read_to_end ( & mut buffer) ?;
50
+ Ok ( reqwest:: Certificate :: from_pem ( & buffer) ?)
51
+ }
52
+
53
+ /// Load a certificate from the specified in
54
+ /// EVEBOX_ELASTICSEARCH_HTTP_CA_CERT. Returning None if not set, or
55
+ /// if an error occurs. But log the error before returning None.
56
+ fn load_certificate_from_env ( ) -> Option < reqwest:: Certificate > {
57
+ if let Ok ( filename) = std:: env:: var ( "EVEBOX_ELASTICSEARCH_CACERT" ) {
58
+ match load_certificate_from_file ( & filename) {
59
+ Ok ( cert) => Some ( cert) ,
60
+ Err ( err) => {
61
+ warn ! ( "Failed to load Elasticsearch HTTP CA certificate from {}, will continue without: {}" , filename, err) ;
62
+ None
63
+ }
64
+ }
65
+ } else {
66
+ None
67
+ }
68
+ }
69
+
53
70
impl Client {
54
71
pub fn new ( url : & str ) -> Self {
55
72
Self {
56
73
url : url. to_string ( ) ,
57
74
username : std:: env:: var ( "EVEBOX_ELASTICSEARCH_USERNAME" ) . ok ( ) ,
58
75
password : std:: env:: var ( "EVEBOX_ELASTICSEARCH_PASSWORD" ) . ok ( ) ,
76
+ cert : load_certificate_from_env ( ) ,
59
77
..Default :: default ( )
60
78
}
61
79
}
@@ -65,6 +83,11 @@ impl Client {
65
83
if self . disable_certificate_validation {
66
84
builder = builder. danger_accept_invalid_certs ( true ) ;
67
85
}
86
+
87
+ if let Some ( cert) = self . cert . clone ( ) {
88
+ builder = builder. add_root_certificate ( cert) ;
89
+ }
90
+
68
91
builder. build ( )
69
92
}
70
93
@@ -272,6 +295,7 @@ pub(crate) struct ClientBuilder {
272
295
disable_certificate_validation : bool ,
273
296
username : Option < String > ,
274
297
password : Option < String > ,
298
+ cert : Option < reqwest:: Certificate > ,
275
299
}
276
300
277
301
impl ClientBuilder {
@@ -280,6 +304,7 @@ impl ClientBuilder {
280
304
url : url. to_string ( ) ,
281
305
username : default_username ( ) ,
282
306
password : default_password ( ) ,
307
+ cert : load_certificate_from_env ( ) ,
283
308
..ClientBuilder :: default ( )
284
309
}
285
310
}
@@ -299,14 +324,21 @@ impl ClientBuilder {
299
324
self
300
325
}
301
326
327
+ pub ( crate ) fn with_cacert ( mut self , cacert : & str ) -> anyhow:: Result < Self > {
328
+ self . cert = Some ( load_certificate_from_file ( cacert) ?) ;
329
+ Ok ( self )
330
+ }
331
+
302
332
pub fn build ( self ) -> Client {
303
333
Client {
304
334
url : self . url . clone ( ) ,
305
335
disable_certificate_validation : self . disable_certificate_validation ,
306
336
username : self . username ,
307
337
password : self . password ,
338
+ cert : self . cert ,
308
339
}
309
340
}
341
+
310
342
}
311
343
312
344
#[ derive( Deserialize , Serialize , Debug ) ]
0 commit comments