1
1
use anyhow:: Result ;
2
2
use log:: { info, warn} ;
3
+ use x509_parser:: { prelude:: { parse_x509_pem} , parse_x509_certificate} ;
3
4
use std:: collections:: HashMap ;
4
5
use tokio:: time:: Instant ;
5
6
use tonic:: {
@@ -27,6 +28,7 @@ use crate::cli_args::{ARGS, INPUTS, OUTPUTS};
27
28
use crate :: metrics:: {
28
29
NAVI_VERSION , NUM_PREDICTIONS , NUM_REQUESTS_FAILED , NUM_REQUESTS_FAILED_BY_MODEL ,
29
30
NUM_REQUESTS_RECEIVED , NUM_REQUESTS_RECEIVED_BY_MODEL , RESPONSE_TIME_COLLECTOR ,
31
+ CERT_EXPIRY_EPOCH
30
32
} ;
31
33
use crate :: predict_service:: { Model , PredictService } ;
32
34
use crate :: tf_proto:: tensorflow_serving:: model_spec:: VersionChoice :: Version ;
@@ -233,6 +235,12 @@ impl<T: Model> PredictionService for PredictService<T> {
233
235
}
234
236
}
235
237
238
+ // A function that takes a timestamp as input and returns a ticker stream
239
+ fn report_expiry ( expiry_time : i64 ) {
240
+ info ! ( "Certificate expires at epoch: {:?}" , expiry_time) ;
241
+ CERT_EXPIRY_EPOCH . set ( expiry_time as i64 ) ;
242
+ }
243
+
236
244
pub fn bootstrap < T : Model > ( model_factory : ModelFactory < T > ) -> Result < ( ) > {
237
245
info ! ( "package: {}, version: {}, args: {:?}" , NAME , VERSION , * ARGS ) ;
238
246
//we follow SemVer. So here we assume MAJOR.MINOR.PATCH
@@ -249,6 +257,7 @@ pub fn bootstrap<T: Model>(model_factory: ModelFactory<T>) -> Result<()> {
249
257
) ;
250
258
}
251
259
260
+
252
261
tokio:: runtime:: Builder :: new_multi_thread ( )
253
262
. thread_name ( "async worker" )
254
263
. worker_threads ( ARGS . num_worker_threads )
@@ -266,6 +275,21 @@ pub fn bootstrap<T: Model>(model_factory: ModelFactory<T>) -> Result<()> {
266
275
let mut builder = if ARGS . ssl_dir . is_empty ( ) {
267
276
Server :: builder ( )
268
277
} else {
278
+ // Read the pem file as a string
279
+ let pem_str = std:: fs:: read_to_string ( format ! ( "{}/server.crt" , ARGS . ssl_dir) ) . unwrap ( ) ;
280
+ let res = parse_x509_pem ( & pem_str. as_bytes ( ) ) ;
281
+ match res {
282
+ Ok ( ( rem, pem_2) ) => {
283
+ assert ! ( rem. is_empty( ) ) ;
284
+ assert_eq ! ( pem_2. label, String :: from( "CERTIFICATE" ) ) ;
285
+ let res_x509 = parse_x509_certificate ( & pem_2. contents ) ;
286
+ info ! ( "Certificate label: {}" , pem_2. label) ;
287
+ assert ! ( res_x509. is_ok( ) ) ;
288
+ report_expiry ( res_x509. unwrap ( ) . 1 . validity ( ) . not_after . timestamp ( ) ) ;
289
+ } ,
290
+ _ => panic ! ( "PEM parsing failed: {:?}" , res) ,
291
+ }
292
+
269
293
let key = tokio:: fs:: read ( format ! ( "{}/server.key" , ARGS . ssl_dir) )
270
294
. await
271
295
. expect ( "can't find key file" ) ;
@@ -281,7 +305,7 @@ pub fn bootstrap<T: Model>(model_factory: ModelFactory<T>) -> Result<()> {
281
305
let identity = Identity :: from_pem ( pem. clone ( ) , key) ;
282
306
let client_ca_cert = Certificate :: from_pem ( pem. clone ( ) ) ;
283
307
let tls = ServerTlsConfig :: new ( )
284
- . identity ( identity)
308
+ . identity ( identity)
285
309
. client_ca_root ( client_ca_cert) ;
286
310
Server :: builder ( )
287
311
. tls_config ( tls)
0 commit comments