Skip to content

Commit 1268ed2

Browse files
coderdanauxesis
authored andcommitted
feat(config): add optional database connection CLI args
1 parent aea5786 commit 1268ed2

File tree

6 files changed

+78
-30
lines changed

6 files changed

+78
-30
lines changed

packages/cipherstash-proxy-integration/src/migrate/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ mod tests {
4242
log_level: LogLevel::Debug,
4343
log_format: LogFormat::Pretty,
4444
command: None,
45+
db_host: None,
46+
db_name: None,
47+
db_user: None,
4548
};
4649

4750
let config = match TandemConfig::load(&args) {

packages/cipherstash-proxy/src/cli/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ const DEFAULT_CONFIG_FILE: &str = "cipherstash-proxy.toml";
2121
/// CipherStash Proxy keeps your sensitive data in PostgreSQL encrypted and searchable, with no changes to SQL.
2222
///
2323
pub struct Args {
24+
/// Optional database host to connect to.
25+
/// Uses env or config file if not specified.
26+
#[arg(short = 'H', long)]
27+
pub db_host: Option<String>,
28+
29+
/// Optional database name to connect to.
30+
/// Uses env or config file if not specified.
31+
#[arg(value_name = "DBNAME")]
32+
pub db_name: Option<String>,
33+
34+
/// Optional database user to connect as.
35+
/// Uses env or config file if not specified.
36+
#[arg(short = 'u', long)]
37+
pub db_user: Option<String>,
38+
2439
/// Optional path to a CipherStash Proxy configuration file.
2540
///
2641
/// Default is "cipherstash-proxy.toml".

packages/cipherstash-proxy/src/config/database.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub struct DatabaseConfig {
1414
pub port: u16,
1515

1616
pub name: String,
17+
18+
#[serde(default = "DatabaseConfig::default_username")]
1719
pub username: String,
1820

1921
#[serde(deserialize_with = "protected_string_deserializer")]
@@ -40,6 +42,10 @@ impl DatabaseConfig {
4042
5432
4143
}
4244

45+
pub fn default_username() -> String {
46+
"postgres".to_string()
47+
}
48+
4349
pub const fn default_config_reload_interval() -> u64 {
4450
60
4551
}

packages/cipherstash-proxy/src/config/log.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,30 +130,30 @@ mod tests {
130130
with_no_cs_vars(|| {
131131
temp_env::with_vars([("CS_LOG__LEVEL", Some("error"))], || {
132132
let config =
133-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
133+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
134134
assert_eq!(config.log.level, LogLevel::Error);
135135
});
136136

137137
temp_env::with_vars([("CS_LOG__LEVEL", Some("WARN"))], || {
138138
let config =
139-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
139+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
140140
assert_eq!(config.log.level, LogLevel::Warn);
141141
});
142142

143143
temp_env::with_vars([("CS_LOG__OUTPUT", Some("stderr"))], || {
144144
let config =
145-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
145+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
146146
assert_eq!(config.log.output, LogOutput::Stderr);
147147
});
148148

149149
temp_env::with_vars([("CS_LOG__FORMAT", Some("Pretty"))], || {
150150
let config =
151-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
151+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
152152
assert_eq!(config.log.format, LogFormat::Pretty);
153153
});
154154

155155
temp_env::with_vars([("CS_LOG__FORMAT", Some("dEbUG"))], || {
156-
let config = TandemConfig::build("tests/config/cipherstash-proxy-test.toml");
156+
let config = TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml");
157157

158158
assert!(config.is_err());
159159
assert!(matches!(config.unwrap_err(), Error::Config(_)));

packages/cipherstash-proxy/src/config/tandem.rs

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl TandemConfig {
101101
);
102102
println!("Loading config values from environment variables.");
103103
}
104-
let mut config = TandemConfig::build(&args.config_file_path)?;
104+
let mut config = TandemConfig::build(args)?;
105105

106106
// If log level is default, it has not been set by the user in config
107107
if config.log.level == LogConfig::default_log_level() {
@@ -116,7 +116,20 @@ impl TandemConfig {
116116
Ok(config)
117117
}
118118

119-
pub fn build(path: &str) -> Result<Self, Error> {
119+
pub fn build_path(path: &str) -> Result<Self, Error> {
120+
let args = Args {
121+
config_file_path: path.to_string(),
122+
db_host: None,
123+
db_name: None,
124+
db_user: None,
125+
log_level: LogConfig::default_log_level(),
126+
log_format: LogConfig::default_log_format(),
127+
command: None,
128+
};
129+
Self::build(&args)
130+
}
131+
132+
pub fn build(args: &Args) -> Result<Self, Error> {
120133
// For parsing top-level values such as CS_HOST, CS_PORT
121134
// and for parsing nested env values such as CS_DATABASE__HOST, CS_DATABASE__PORT
122135
let cs_env_source = Environment::with_prefix(CS_PREFIX)
@@ -161,9 +174,20 @@ impl TandemConfig {
161174
env
162175
}));
163176

177+
// Command line arguments override env vars
178+
if let Some(db_host) = &args.db_host {
179+
println!("Overriding database host from command line argument");
180+
env::set_var("CS_DATABASE__HOST", db_host);
181+
}
182+
183+
if let Some(dbname) = &args.db_name {
184+
println!("Overriding database name from command line argument");
185+
env::set_var("CS_DATABASE__NAME", dbname);
186+
}
187+
164188
// Source order is important!
165189
let config = Config::builder()
166-
.add_source(config::File::with_name(path).required(false))
190+
.add_source(config::File::with_name(&args.config_file_path).required(false))
167191
.add_source(cs_env_source)
168192
.add_source(stash_setup_source)
169193
.build()?
@@ -372,7 +396,7 @@ mod tests {
372396
],
373397
|| {
374398
let config =
375-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
399+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
376400

377401
assert_eq!(config.encrypt.client_id, "CS_CLIENT_ID".to_string());
378402

@@ -404,7 +428,7 @@ mod tests {
404428
],
405429
|| {
406430
let config =
407-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
431+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
408432

409433
assert_eq!(
410434
&config.encrypt.client_id,
@@ -418,7 +442,7 @@ mod tests {
418442
#[test]
419443
fn database_as_url() {
420444
let config = with_no_cs_vars(|| {
421-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap()
445+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap()
422446
});
423447
assert_eq!(
424448
config.database.to_socket_address(),
@@ -430,14 +454,14 @@ mod tests {
430454
fn dataset_as_uuid() {
431455
temp_env::with_vars_unset(["CS_ENCRYPT__DATASET_ID", "CS_DEFAULT_KEYSET_ID"], || {
432456
let config = with_no_cs_vars(|| {
433-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap()
457+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap()
434458
});
435459
assert_eq!(
436460
config.encrypt.default_keyset_id,
437461
Some(Uuid::parse_str("484cd205-99e8-41ca-acfe-55a7e25a8ec2").unwrap())
438462
);
439463

440-
let config = TandemConfig::build("tests/config/cipherstash-proxy-bad-dataset.toml");
464+
let config = TandemConfig::build_path("tests/config/cipherstash-proxy-bad-dataset.toml");
441465

442466
assert!(config.is_err());
443467
assert!(matches!(config.unwrap_err(), Error::Config(_)));
@@ -447,20 +471,20 @@ mod tests {
447471
#[test]
448472
fn prometheus_config() {
449473
with_no_cs_vars(|| {
450-
let config = TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
474+
let config = TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
451475
assert!(!config.prometheus_enabled());
452476

453477
temp_env::with_vars([("CS_PROMETHEUS__ENABLED", Some("true"))], || {
454478
let config =
455-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
479+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
456480
assert!(config.prometheus_enabled());
457481
assert!(config.prometheus.enabled);
458482
assert_eq!(config.prometheus.port, 9930);
459483
});
460484

461485
temp_env::with_vars([("CS_PROMETHEUS__PORT", Some("7777"))], || {
462486
let config =
463-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
487+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
464488
assert!(!config.prometheus_enabled());
465489
assert!(!config.prometheus.enabled);
466490
assert_eq!(config.prometheus.port, 7777);
@@ -473,7 +497,7 @@ mod tests {
473497
],
474498
|| {
475499
let config =
476-
TandemConfig::build("tests/config/cipherstash-proxy-test.toml").unwrap();
500+
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml").unwrap();
477501
assert!(config.prometheus_enabled());
478502
assert!(config.prometheus.enabled);
479503
assert_eq!(config.prometheus.port, 7777);
@@ -549,7 +573,7 @@ mod tests {
549573

550574
with_no_cs_vars(|| {
551575
temp_env::with_vars(env, || {
552-
let config = TandemConfig::build("tests/config/unknown.toml").unwrap();
576+
let config = TandemConfig::build_path("tests/config/unknown.toml").unwrap();
553577
assert_eq!(
554578
"E4UMRN47WJNSMAKR",
555579
config.auth.workspace_crn.workspace_id.to_string()
@@ -567,7 +591,7 @@ mod tests {
567591

568592
with_no_cs_vars(|| {
569593
temp_env::with_vars(env, || {
570-
let config = TandemConfig::build("tests/config/unknown.toml");
594+
let config = TandemConfig::build_path("tests/config/unknown.toml");
571595

572596
assert_eq!(
573597
"E4UMRN47WJNSMAKR",
@@ -583,7 +607,7 @@ mod tests {
583607

584608
with_no_cs_vars(|| {
585609
temp_env::with_vars(env, || {
586-
let config = TandemConfig::build("tests/config/unknown.toml");
610+
let config = TandemConfig::build_path("tests/config/unknown.toml");
587611
assert!(config.is_err());
588612

589613
if let Err(e) = config {
@@ -604,7 +628,7 @@ mod tests {
604628

605629
with_no_cs_vars(|| {
606630
temp_env::with_vars(env, || {
607-
let config = TandemConfig::build("tests/config/unknown.toml");
631+
let config = TandemConfig::build_path("tests/config/unknown.toml");
608632
assert!(config.is_err());
609633

610634
if let Err(e) = config {
@@ -620,7 +644,7 @@ mod tests {
620644

621645
with_no_cs_vars(|| {
622646
temp_env::with_vars(env, || {
623-
let result = TandemConfig::build("tests/config/unknown.toml");
647+
let result = TandemConfig::build_path("tests/config/unknown.toml");
624648
assert!(result.is_err());
625649

626650
if let Err(err) = result {
@@ -642,7 +666,7 @@ mod tests {
642666

643667
with_no_cs_vars(|| {
644668
temp_env::with_vars(env, || {
645-
let result = TandemConfig::build("tests/config/unknown.toml");
669+
let result = TandemConfig::build_path("tests/config/unknown.toml");
646670
assert!(result.is_err());
647671

648672
if let Err(err) = result {
@@ -671,7 +695,7 @@ mod tests {
671695

672696
with_no_cs_vars(|| {
673697
temp_env::with_vars(env, || {
674-
let result = TandemConfig::build("tests/config/unknown.toml");
698+
let result = TandemConfig::build_path("tests/config/unknown.toml");
675699
assert!(result.is_err());
676700

677701
if let Err(err) = result {
@@ -693,7 +717,7 @@ mod tests {
693717

694718
with_no_cs_vars(|| {
695719
temp_env::with_vars(env, || {
696-
let result = TandemConfig::build("tests/config/unknown.toml");
720+
let result = TandemConfig::build_path("tests/config/unknown.toml");
697721
assert!(result.is_err());
698722

699723
if let Err(err) = result {
@@ -725,7 +749,7 @@ mod tests {
725749

726750
with_no_cs_vars(|| {
727751
temp_env::with_vars(env, || {
728-
let result = TandemConfig::build("tests/config/unknown.toml");
752+
let result = TandemConfig::build_path("tests/config/unknown.toml");
729753
assert!(result.is_err());
730754

731755
if let Err(err) = result {
@@ -747,7 +771,7 @@ mod tests {
747771

748772
with_no_cs_vars(|| {
749773
temp_env::with_vars(env, || {
750-
let result = TandemConfig::build("tests/config/unknown.toml");
774+
let result = TandemConfig::build_path("tests/config/unknown.toml");
751775
assert!(result.is_err());
752776

753777
if let Err(err) = result {
@@ -765,7 +789,7 @@ mod tests {
765789
fn crn_can_load_from_toml() {
766790
with_no_cs_vars(|| {
767791
let config =
768-
TandemConfig::build("tests/config/cipherstash-proxy-with-crn.toml").unwrap();
792+
TandemConfig::build_path("tests/config/cipherstash-proxy-with-crn.toml").unwrap();
769793
assert_eq!(
770794
"E4UMRN47WJNSMAKR",
771795
config.auth.workspace_crn.workspace_id.to_string()
@@ -786,7 +810,7 @@ mod tests {
786810

787811
with_no_cs_vars(|| {
788812
temp_env::with_vars(env, || {
789-
let config = TandemConfig::build("tests/config/unknown.toml").unwrap();
813+
let config = TandemConfig::build_path("tests/config/unknown.toml").unwrap();
790814
assert_eq!(
791815
"E4UMRN47WJNSMAKR",
792816
config.auth.workspace_crn.workspace_id.to_string()

packages/cipherstash-proxy/src/proxy/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ mod tests {
145145
fn build_tandem_config(env: Vec<(&str, Option<&str>)>) -> TandemConfig {
146146
with_no_cs_vars(|| {
147147
temp_env::with_vars(env, || {
148-
TandemConfig::build("tests/config/unknown.toml").unwrap()
148+
TandemConfig::build_path("tests/config/unknown.toml").unwrap()
149149
})
150150
})
151151
}

0 commit comments

Comments
 (0)