16
16
*
17
17
*/
18
18
19
+ use clap:: builder:: ArgPredicate ;
19
20
use clap:: Parser ;
20
21
use crossterm:: style:: Stylize ;
21
22
use std:: path:: PathBuf ;
@@ -27,42 +28,45 @@ use crate::storage::{ObjectStorage, ObjectStorageError, LOCAL_SYNC_INTERVAL};
27
28
28
29
lazy_static:: lazy_static! {
29
30
#[ 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( ) ) ;
34
32
}
35
33
36
34
pub const USERNAME_ENV : & str = "P_USERNAME" ;
37
- pub const PASSOWRD_ENV : & str = "P_PASSWORD" ;
35
+ pub const PASSWORD_ENV : & str = "P_PASSWORD" ;
38
36
pub const DEFAULT_USERNAME : & str = "parseable" ;
39
37
pub const DEFAULT_PASSWORD : & str = "parseable" ;
40
38
41
39
pub trait StorageOpt : Sync + Send {
42
40
fn bucket_name ( & self ) -> & str ;
43
41
fn endpoint_url ( & self ) -> & str ;
44
- fn warning ( & self ) ;
45
- fn is_default_url ( & self ) -> bool ;
46
42
}
47
43
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 > ,
51
49
}
52
50
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 {
55
56
Config {
56
- parseable : Opt :: parse ( ) ,
57
- storage,
57
+ parseable : Opt :: < S > :: parse ( ) ,
58
58
}
59
59
}
60
60
61
+ pub fn storage ( & self ) -> & S {
62
+ & self . parseable . objectstore_config
63
+ }
64
+
61
65
pub fn print ( & self ) {
62
66
let scheme = CONFIG . parseable . get_scheme ( ) ;
63
67
self . status_info ( & scheme) ;
64
68
banner:: version:: print ( ) ;
65
- self . warning ( ) ;
69
+ self . demo ( ) ;
66
70
self . storage_info ( ) ;
67
71
banner:: system_info ( ) ;
68
72
println ! ( ) ;
@@ -80,11 +84,11 @@ impl Config {
80
84
Err ( ObjectStorageError :: NoSuchBucket ( name) ) => panic ! (
81
85
"Could not start because the bucket doesn't exist. Please ensure bucket {bucket} exists on {url}" ,
82
86
bucket = name,
83
- url = self . storage. endpoint_url( )
87
+ url = self . storage( ) . endpoint_url( )
84
88
) ,
85
89
Err ( ObjectStorageError :: ConnectionError ( inner) ) => panic ! (
86
90
"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( ) ,
88
92
cause = inner
89
93
) ,
90
94
Err ( ObjectStorageError :: AuthenticationError ( inner) ) => panic ! (
@@ -96,15 +100,15 @@ impl Config {
96
100
}
97
101
98
102
fn status_info ( & self , scheme : & str ) {
99
- let url = format ! ( "{}://{}" , scheme, CONFIG . parseable. address) . underlined ( ) ;
103
+ let url = format ! ( "{}://{}" , scheme, self . parseable. address) . underlined ( ) ;
100
104
eprintln ! (
101
105
"
102
106
{}
103
107
{}
104
108
{}" ,
105
109
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( ) ,
108
112
)
109
113
}
110
114
@@ -116,60 +120,39 @@ impl Config {
116
120
Object Storage: {}/{}" ,
117
121
"Storage:" . to_string( ) . blue( ) . bold( ) ,
118
122
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( )
121
125
)
122
126
}
123
127
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 ( ) ;
150
131
eprintln ! (
151
132
"
152
- {}
153
133
{}" ,
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 ."
155
135
. to_string( )
156
136
. red( ) ,
157
- format!(
158
- "Setup your credentials with {} and {} before storing production logs." ,
159
- USERNAME_ENV , PASSOWRD_ENV
160
137
)
161
- . red( )
162
- )
163
138
}
164
139
}
140
+
141
+ fn is_demo ( & self ) -> bool {
142
+ self . parseable . demo
143
+ }
165
144
}
166
145
167
146
#[ derive( Debug , Clone , Parser ) ]
168
147
#[ command(
169
- name = "Parseable config" ,
170
- about = "configuration for Parseable server"
148
+ name = "Parseable" ,
149
+ about = "Configuration for Parseable server" ,
150
+ version
171
151
) ]
172
- pub struct Opt {
152
+ pub struct Opt < S >
153
+ where
154
+ S : Clone + clap:: Args + StorageOpt ,
155
+ {
173
156
/// The location of TLS Cert file
174
157
#[ arg( long, env = "P_TLS_CERT_PATH" ) ]
175
158
pub tls_cert_path : Option < PathBuf > ,
@@ -194,15 +177,33 @@ pub struct Opt {
194
177
pub upload_interval : u64 ,
195
178
196
179
/// 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
+ ) ]
198
185
pub username : String ,
199
186
200
187
/// 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
+ ) ]
202
193
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 ,
203
201
}
204
202
205
- impl Opt {
203
+ impl < S > Opt < S >
204
+ where
205
+ S : Clone + clap:: Args + StorageOpt ,
206
+ {
206
207
pub fn get_cache_path ( & self , stream_name : & str ) -> PathBuf {
207
208
self . local_disk_path . join ( stream_name)
208
209
}
0 commit comments