wasmcloud_provider_sqldb_postgres/
config.rs1use tracing::warn;
2use wasmcloud_provider_sdk::{core::secrets::SecretValue, LinkConfig};
3
4const POSTGRES_DEFAULT_PORT: u16 = 5432;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub(crate) struct ConnectionCreateOptions {
9 pub host: String,
11 pub port: u16,
13 pub username: String,
15 pub password: String,
17 pub database: String,
19 pub tls_required: bool,
21 pub pool_size: Option<usize>,
23}
24
25impl From<ConnectionCreateOptions> for deadpool_postgres::Config {
26 fn from(opts: ConnectionCreateOptions) -> Self {
27 let mut cfg = deadpool_postgres::Config::new();
28 cfg.host = Some(opts.host);
29 cfg.user = Some(opts.username);
30 cfg.password = Some(opts.password);
31 cfg.dbname = Some(opts.database);
32 cfg.port = Some(opts.port);
33 if let Some(pool_size) = opts.pool_size {
34 cfg.pool = Some(deadpool_postgres::PoolConfig {
35 max_size: pool_size,
36 ..deadpool_postgres::PoolConfig::default()
37 });
38 }
39 cfg
40 }
41}
42
43pub(crate) fn extract_prefixed_conn_config(
48 prefix: &str,
49 link_config: &LinkConfig,
50) -> Option<ConnectionCreateOptions> {
51 let LinkConfig {
52 config, secrets, ..
53 } = link_config;
54
55 let keys = [
56 format!("{prefix}HOST"),
57 format!("{prefix}PORT"),
58 format!("{prefix}USERNAME"),
59 format!("{prefix}PASSWORD"),
60 format!("{prefix}DATABASE"),
61 format!("{prefix}TLS_REQUIRED"),
62 format!("{prefix}POOL_SIZE"),
63 ];
64 match keys
65 .iter()
66 .map(|k| {
67 match (secrets.get(k).and_then(SecretValue::as_string), config.get(k)) {
69 (Some(s), Some(_)) => {
70 warn!("secret value [{k}] was found in secrets, but also exists in config. The value in secrets will be used.");
71 Some(s)
72 }
73 (Some(s), _) => Some(s),
74 (None, Some(c)) if k == &format!("{prefix}PASSWORD") => {
76 warn!("secret value [{k}] was not found in secrets, but exists in config. Prefer using secrets for sensitive values.");
77 Some(c.as_str())
78 }
79 (None, Some(c)) => {
80 Some(c.as_str())
81 }
82 (_, None) => None,
83 }
84 })
85 .collect::<Vec<Option<&str>>>()[..]
86 {
87 [Some(host), Some(port), Some(username), Some(password), Some(database), tls_required, pool_size] =>
88 {
89 let pool_size = pool_size.and_then(|pool_size| {
90 pool_size.parse::<usize>().ok().or_else(|| {
91 warn!("invalid pool size value [{pool_size}], using default");
92 None
93 })
94 });
95
96 Some(ConnectionCreateOptions {
97 host: host.to_string(),
98 port: port.parse::<u16>().unwrap_or_else(|_e| {
99 warn!("invalid port value [{port}], using {POSTGRES_DEFAULT_PORT}");
100 POSTGRES_DEFAULT_PORT
101 }),
102 username: username.to_string(),
103 password: password.to_string(),
104 tls_required: tls_required.is_some_and(|tls_required| {
105 matches!(tls_required.to_lowercase().as_str(), "true" | "yes")
106 }),
107 database: database.to_string(),
108 pool_size,
109 })
110 }
111 _ => {
112 warn!("failed to find required keys in configuration: [{:?}]", keys);
113 None
114 }
115 }
116}