1616 *
1717 */
1818
19+ use clap:: builder:: ArgPredicate ;
1920use clap:: Parser ;
2021use crossterm:: style:: Stylize ;
2122use std:: path:: PathBuf ;
@@ -27,42 +28,45 @@ use crate::storage::{ObjectStorage, ObjectStorageError, LOCAL_SYNC_INTERVAL};
2728
2829lazy_static:: lazy_static! {
2930 #[ derive( Debug ) ]
30- pub static ref CONFIG : Arc <Config > = {
31- let storage = Box :: new( S3Config :: parse( ) ) ;
32- Arc :: new( Config :: new( storage) )
33- } ;
31+ pub static ref CONFIG : Arc <Config <S3Config >> = Arc :: new( Config :: new( ) ) ;
3432}
3533
3634pub const USERNAME_ENV : & str = "P_USERNAME" ;
37- pub const PASSOWRD_ENV : & str = "P_PASSWORD" ;
35+ pub const PASSWORD_ENV : & str = "P_PASSWORD" ;
3836pub const DEFAULT_USERNAME : & str = "parseable" ;
3937pub const DEFAULT_PASSWORD : & str = "parseable" ;
4038
4139pub trait StorageOpt : Sync + Send {
4240 fn bucket_name ( & self ) -> & str ;
4341 fn endpoint_url ( & self ) -> & str ;
44- fn warning ( & self ) ;
45- fn is_default_url ( & self ) -> bool ;
4642}
4743
48- pub struct Config {
49- pub parseable : Opt ,
50- pub storage : Box < dyn StorageOpt > ,
44+ pub struct Config < S >
45+ where
46+ S : Clone + clap:: Args + StorageOpt ,
47+ {
48+ pub parseable : Opt < S > ,
5149}
5250
53- impl Config {
54- fn new ( storage : Box < dyn StorageOpt > ) -> Config {
51+ impl < S > Config < S >
52+ where
53+ S : Clone + clap:: Args + StorageOpt ,
54+ {
55+ fn new ( ) -> Self {
5556 Config {
56- parseable : Opt :: parse ( ) ,
57- storage,
57+ parseable : Opt :: < S > :: parse ( ) ,
5858 }
5959 }
6060
61+ pub fn storage ( & self ) -> & S {
62+ & self . parseable . objectstore_config
63+ }
64+
6165 pub fn print ( & self ) {
6266 let scheme = CONFIG . parseable . get_scheme ( ) ;
6367 self . status_info ( & scheme) ;
6468 banner:: version:: print ( ) ;
65- self . warning ( ) ;
69+ self . demo ( ) ;
6670 self . storage_info ( ) ;
6771 banner:: system_info ( ) ;
6872 println ! ( ) ;
@@ -80,11 +84,11 @@ impl Config {
8084 Err ( ObjectStorageError :: NoSuchBucket ( name) ) => panic ! (
8185 "Could not start because the bucket doesn't exist. Please ensure bucket {bucket} exists on {url}" ,
8286 bucket = name,
83- url = self . storage. endpoint_url( )
87+ url = self . storage( ) . endpoint_url( )
8488 ) ,
8589 Err ( ObjectStorageError :: ConnectionError ( inner) ) => panic ! (
8690 "Failed to connect to the Object Storage Service on {url}\n Caused by: {cause}" ,
87- url = self . storage. endpoint_url( ) ,
91+ url = self . storage( ) . endpoint_url( ) ,
8892 cause = inner
8993 ) ,
9094 Err ( ObjectStorageError :: AuthenticationError ( inner) ) => panic ! (
@@ -96,15 +100,15 @@ impl Config {
96100 }
97101
98102 fn status_info ( & self , scheme : & str ) {
99- let url = format ! ( "{}://{}" , scheme, CONFIG . parseable. address) . underlined ( ) ;
103+ let url = format ! ( "{}://{}" , scheme, self . parseable. address) . underlined ( ) ;
100104 eprintln ! (
101105 "
102106 {}
103107 {}
104108 {}" ,
105109 format!( "Parseable server started at: {}" , url) . bold( ) ,
106- format!( "Username: {}" , CONFIG . parseable. username) . bold( ) ,
107- format!( "Password: {}" , CONFIG . parseable. password) . bold( ) ,
110+ format!( "Username: {}" , self . parseable. username) . bold( ) ,
111+ format!( "Password: {}" , self . parseable. password) . bold( ) ,
108112 )
109113 }
110114
@@ -116,60 +120,39 @@ impl Config {
116120 Object Storage: {}/{}" ,
117121 "Storage:" . to_string( ) . blue( ) . bold( ) ,
118122 self . parseable. local_disk_path. to_string_lossy( ) ,
119- self . storage. endpoint_url( ) ,
120- self . storage. bucket_name( )
123+ self . storage( ) . endpoint_url( ) ,
124+ self . storage( ) . bucket_name( )
121125 )
122126 }
123127
124- fn warning ( & self ) {
125- match ( self . storage . is_default_url ( ) , self . is_default_cred ( ) ) {
126- ( true , true ) => {
127- banner:: warning_line ( ) ;
128- self . cred_warning ( ) ;
129- self . storage . warning ( ) ;
130- }
131- ( true , _) => {
132- banner:: warning_line ( ) ;
133- self . storage . warning ( ) ;
134- }
135- ( _, true ) => {
136- banner:: warning_line ( ) ;
137- self . cred_warning ( ) ;
138- }
139- _ => { }
140- }
141- }
142-
143- fn is_default_cred ( & self ) -> bool {
144- CONFIG . parseable . username == DEFAULT_USERNAME
145- && CONFIG . parseable . password == DEFAULT_PASSWORD
146- }
147-
148- fn cred_warning ( & self ) {
149- if self . is_default_cred ( ) {
128+ fn demo ( & self ) {
129+ if self . is_demo ( ) {
130+ banner:: warning_line ( ) ;
150131 eprintln ! (
151132 "
152- {}
153133 {}" ,
154- "Parseable server is using default credentials."
134+ "Parseable is in demo mode with default credentials and open object store. Please use this for demo purposes only ."
155135 . to_string( )
156136 . red( ) ,
157- format!(
158- "Setup your credentials with {} and {} before storing production logs." ,
159- USERNAME_ENV , PASSOWRD_ENV
160137 )
161- . red( )
162- )
163138 }
164139 }
140+
141+ fn is_demo ( & self ) -> bool {
142+ self . parseable . demo
143+ }
165144}
166145
167146#[ derive( Debug , Clone , Parser ) ]
168147#[ command(
169- name = "Parseable config" ,
170- about = "configuration for Parseable server"
148+ name = "Parseable" ,
149+ about = "Configuration for Parseable server" ,
150+ version
171151) ]
172- pub struct Opt {
152+ pub struct Opt < S >
153+ where
154+ S : Clone + clap:: Args + StorageOpt ,
155+ {
173156 /// The location of TLS Cert file
174157 #[ arg( long, env = "P_TLS_CERT_PATH" ) ]
175158 pub tls_cert_path : Option < PathBuf > ,
@@ -194,15 +177,33 @@ pub struct Opt {
194177 pub upload_interval : u64 ,
195178
196179 /// Optional username to enable basic auth on the server
197- #[ arg( long, env = USERNAME_ENV , default_value = DEFAULT_USERNAME ) ]
180+ #[ arg(
181+ long,
182+ env = USERNAME_ENV ,
183+ default_value_if( "demo" , ArgPredicate :: IsPresent , DEFAULT_USERNAME )
184+ ) ]
198185 pub username : String ,
199186
200187 /// Optional password to enable basic auth on the server
201- #[ arg( long, env = PASSOWRD_ENV , default_value = DEFAULT_PASSWORD ) ]
188+ #[ arg(
189+ long,
190+ env = PASSWORD_ENV ,
191+ default_value_if( "demo" , ArgPredicate :: IsPresent , DEFAULT_PASSWORD )
192+ ) ]
202193 pub password : String ,
194+
195+ #[ clap( flatten) ]
196+ pub objectstore_config : S ,
197+
198+ /// Run Parseable in demo mode with default credentials and open object store
199+ #[ arg( short, long, exclusive = true ) ]
200+ pub demo : bool ,
203201}
204202
205- impl Opt {
203+ impl < S > Opt < S >
204+ where
205+ S : Clone + clap:: Args + StorageOpt ,
206+ {
206207 pub fn get_cache_path ( & self , stream_name : & str ) -> PathBuf {
207208 self . local_disk_path . join ( stream_name)
208209 }
0 commit comments