@@ -3,6 +3,7 @@ use std::env::VarError;
33use bollard:: Docker ;
44use serde:: Deserialize ;
55use thiserror:: Error ;
6+ use tower_lsp:: jsonrpc:: { Error as LspError , ErrorCode } ;
67
78use crate :: infra:: { DockerImageBuilder , SysdigAPIToken , SysdigImageScanner } ;
89
@@ -17,19 +18,14 @@ pub struct SysdigConfig {
1718 api_token : Option < SysdigAPIToken > ,
1819}
1920
20- #[ derive( Clone , Default ) ]
21+ #[ derive( Clone ) ]
2122pub struct ComponentFactory {
22- config : Option < Config > ,
23-
24- scanner : Option < SysdigImageScanner > ,
25- builder : Option < DockerImageBuilder > ,
23+ scanner : SysdigImageScanner ,
24+ builder : DockerImageBuilder ,
2625}
2726
2827#[ derive( Error , Debug ) ]
2928pub enum ComponentFactoryError {
30- #[ error( "the configuration has not been provided" ) ]
31- ConfigurationNotProvided ,
32-
3329 #[ error( "unable to retrieve sysdig api token from env var: {0}" ) ]
3430 UnableToRetrieveAPITokenFromEnvVar ( #[ from] VarError ) ,
3531
@@ -38,43 +34,48 @@ pub enum ComponentFactoryError {
3834}
3935
4036impl ComponentFactory {
41- pub fn initialize_with ( & mut self , config : Config ) {
42- self . config . replace ( config) ;
43- self . scanner . take ( ) ;
44- }
45-
46- pub fn image_scanner ( & mut self ) -> Result < SysdigImageScanner , ComponentFactoryError > {
47- if self . scanner . is_some ( ) {
48- return Ok ( self . scanner . clone ( ) . unwrap ( ) ) ;
49- }
50-
51- let Some ( config) = & self . config else {
52- return Err ( ComponentFactoryError :: ConfigurationNotProvided ) ;
53- } ;
54-
37+ pub fn new ( config : Config ) -> Result < Self , ComponentFactoryError > {
5538 let token = config
5639 . sysdig
5740 . api_token
5841 . clone ( )
5942 . map ( Ok )
6043 . unwrap_or_else ( || std:: env:: var ( "SECURE_API_TOKEN" ) . map ( SysdigAPIToken ) ) ?;
6144
62- let image_scanner = SysdigImageScanner :: new ( config. sysdig . api_url . clone ( ) , token) ;
45+ let scanner = SysdigImageScanner :: new ( config. sysdig . api_url . clone ( ) , token) ;
6346
64- self . scanner . replace ( image_scanner) ;
65- Ok ( self . scanner . clone ( ) . unwrap ( ) )
47+ let docker_client = Docker :: connect_with_local_defaults ( ) ?;
48+ let builder = DockerImageBuilder :: new ( docker_client) ;
49+
50+ Ok ( Self { scanner, builder } )
6651 }
6752
68- pub fn image_builder ( & mut self ) -> Result < DockerImageBuilder , ComponentFactoryError > {
69- if self . builder . is_some ( ) {
70- return Ok ( self . builder . clone ( ) . unwrap ( ) ) ;
71- }
53+ pub fn image_scanner ( & self ) -> & SysdigImageScanner {
54+ & self . scanner
55+ }
7256
73- let docker_client = Docker :: connect_with_local_defaults ( ) ?;
74- let image_builder = DockerImageBuilder :: new ( docker_client) ;
57+ pub fn image_builder ( & self ) -> & DockerImageBuilder {
58+ & self . builder
59+ }
60+ }
7561
76- self . builder . replace ( image_builder) ;
77- Ok ( self . builder . clone ( ) . unwrap ( ) )
62+ impl From < ComponentFactoryError > for LspError {
63+ fn from ( err : ComponentFactoryError ) -> Self {
64+ let ( code, message) = match err {
65+ ComponentFactoryError :: UnableToRetrieveAPITokenFromEnvVar ( e) => (
66+ ErrorCode :: InternalError ,
67+ format ! ( "Could not read SECURE_API_TOKEN from environment: {}" , e) ,
68+ ) ,
69+ ComponentFactoryError :: DockerClientError ( e) => (
70+ ErrorCode :: InternalError ,
71+ format ! ( "Failed to connect to Docker: {}" , e) ,
72+ ) ,
73+ } ;
74+ LspError {
75+ code,
76+ message : message. into ( ) ,
77+ data : None ,
78+ }
7879 }
7980}
8081
@@ -83,32 +84,8 @@ mod test {
8384 use super :: { ComponentFactory , Config } ;
8485
8586 #[ test]
86- fn it_loads_the_factory_uninit ( ) {
87- let factory = ComponentFactory :: default ( ) ;
88-
89- assert ! ( factory. config. is_none( ) ) ;
90- }
91-
92- #[ test]
93- fn it_fails_to_create_the_scanner_without_config ( ) {
94- let mut factory = ComponentFactory :: default ( ) ;
95-
96- assert ! ( factory. image_scanner( ) . is_err( ) ) ;
97- }
98-
99- #[ test]
100- fn it_creates_a_scanner_after_initializing ( ) {
101- let mut factory = ComponentFactory :: default ( ) ;
102-
103- factory. initialize_with ( Config :: default ( ) ) ;
104-
105- assert ! ( factory. image_scanner( ) . is_ok( ) ) ;
106- }
107-
108- #[ test]
109- fn it_creates_a_builder_without_config ( ) {
110- let mut factory = ComponentFactory :: default ( ) ;
111-
112- assert ! ( factory. image_builder( ) . is_ok( ) ) ;
87+ fn it_creates_a_factory ( ) {
88+ let factory = ComponentFactory :: new ( Config :: default ( ) ) ;
89+ assert ! ( factory. is_ok( ) ) ;
11390 }
11491}
0 commit comments