Skip to content

Commit 0ec8f9f

Browse files
committed
chore: smoke tests passing
1 parent 2f572d2 commit 0ec8f9f

6 files changed

Lines changed: 245 additions & 174 deletions

File tree

extra/crds.yaml

Lines changed: 101 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,44 +1453,110 @@ spec:
14531453
type: string
14541454
type: object
14551455
type: object
1456-
metadataStorageDatabase:
1456+
metadataDatabase:
14571457
description: Druid requires an SQL database to store metadata into. Specify connection information here.
1458+
oneOf:
1459+
- required:
1460+
- postgresql
1461+
- required:
1462+
- mysql
1463+
- required:
1464+
- derby
14581465
properties:
1459-
connString:
1466+
derby:
14601467
description: |-
1461-
The connect string for the database, for Postgres this could look like:
1462-
`jdbc:postgresql://postgresql-druid/druid`
1463-
type: string
1464-
credentialsSecret:
1465-
description: |-
1466-
A reference to a Secret containing the database credentials.
1467-
The Secret needs to contain the keys `username` and `password`.
1468-
nullable: true
1469-
type: string
1470-
dbType:
1468+
Connection settings for an embedded [Apache Derby](https://db.apache.org/derby/) database.
1469+
1470+
Derby is an embedded, file-based Java database engine that requires no separate server process.
1471+
It is typically used for development, testing, or as a lightweight metastore backend (e.g. for
1472+
Apache Hive).
1473+
properties:
1474+
location:
1475+
description: |-
1476+
Path on the filesystem where Derby stores its database files.
1477+
1478+
If not specified, defaults to `/tmp/derby/{unique_database_name}/derby.db`.
1479+
The `{unique_database_name}` part is automatically handled by the operator and is added to
1480+
prevent clashing database files. The `create=true` flag is always appended to the JDBC URL,
1481+
so the database is created automatically if it does not yet exist at this location.
1482+
nullable: true
1483+
type: string
1484+
type: object
1485+
mysql:
14711486
description: |-
1472-
The database type. Supported values are: `derby`, `mysql` and `postgres`.
1473-
Note that a Derby database created locally in the container is not persisted!
1474-
Derby is not suitable for production use.
1475-
enum:
1476-
- derby
1477-
- mysql
1478-
- postgresql
1479-
type: string
1480-
host:
1481-
description: The host, i.e. `postgresql-druid`.
1482-
type: string
1483-
port:
1484-
description: The port, i.e. 5432
1485-
format: uint16
1486-
maximum: 65535.0
1487-
minimum: 0.0
1488-
type: integer
1489-
required:
1490-
- connString
1491-
- dbType
1492-
- host
1493-
- port
1487+
Connection settings for a [MySQL](https://www.mysql.com/) database.
1488+
1489+
Please note that - due to license issues - we don't ship the mysql driver, you need to add
1490+
it it yourself.
1491+
See <https://docs.stackable.tech/home/stable/hive/usage-guide/database-driver/> for details.
1492+
properties:
1493+
credentialsSecretName:
1494+
description: |-
1495+
Name of a Secret containing the `username` and `password` keys used to authenticate
1496+
against the MySQL server.
1497+
type: string
1498+
database:
1499+
description: Name of the database (schema) to connect to.
1500+
type: string
1501+
host:
1502+
description: Hostname or IP address of the MySQL server.
1503+
type: string
1504+
parameters:
1505+
additionalProperties:
1506+
type: string
1507+
default: {}
1508+
description: |-
1509+
Additional map of connection parameters to append to the connection URL. The given
1510+
`HashMap<String, String>` will be converted to query parameters in the form of
1511+
`?param1=value1&param2=value2`.
1512+
type: object
1513+
port:
1514+
default: 3306
1515+
description: Port the MySQL server is listening on. Defaults to `3306`.
1516+
format: uint16
1517+
maximum: 65535.0
1518+
minimum: 0.0
1519+
type: integer
1520+
required:
1521+
- credentialsSecretName
1522+
- database
1523+
- host
1524+
type: object
1525+
postgresql:
1526+
description: Connection settings for a [PostgreSQL](https://www.postgresql.org/) database.
1527+
properties:
1528+
credentialsSecretName:
1529+
description: |-
1530+
Name of a Secret containing the `username` and `password` keys used to authenticate
1531+
against the PostgreSQL server.
1532+
type: string
1533+
database:
1534+
description: Name of the database (schema) to connect to.
1535+
type: string
1536+
host:
1537+
description: Hostname or IP address of the PostgreSQL server.
1538+
type: string
1539+
parameters:
1540+
additionalProperties:
1541+
type: string
1542+
default: {}
1543+
description: |-
1544+
Additional map of JDBC connection parameters to append to the connection URL. The given
1545+
`HashMap<String, String>` will be converted to query parameters in the form of
1546+
`?param1=value1&param2=value2`.
1547+
type: object
1548+
port:
1549+
default: 5432
1550+
description: Port the PostgreSQL server is listening on. Defaults to `5432`.
1551+
format: uint16
1552+
maximum: 65535.0
1553+
minimum: 0.0
1554+
type: integer
1555+
required:
1556+
- credentialsSecretName
1557+
- database
1558+
- host
1559+
type: object
14941560
type: object
14951561
tls:
14961562
default:
@@ -1529,7 +1595,7 @@ spec:
15291595
type: string
15301596
required:
15311597
- deepStorage
1532-
- metadataStorageDatabase
1598+
- metadataDatabase
15331599
- zookeeperConfigMapName
15341600
type: object
15351601
clusterOperation:
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::ops::Deref;
2+
3+
use serde::{Deserialize, Serialize};
4+
use stackable_operator::{
5+
database_connections::{
6+
databases::{
7+
derby::DerbyConnection, mysql::MysqlConnection, postgresql::PostgresqlConnection,
8+
},
9+
drivers::jdbc::JdbcDatabaseConnection,
10+
},
11+
schemars::{self, JsonSchema},
12+
};
13+
14+
// metadata storage config properties
15+
pub const METADATA_STORAGE_TYPE: &str = "druid.metadata.storage.type";
16+
pub const METADATA_STORAGE_CONNECTOR_CONNECT_URI: &str =
17+
"druid.metadata.storage.connector.connectURI";
18+
pub const METADATA_STORAGE_USER: &str = "druid.metadata.storage.connector.user";
19+
pub const METADATA_STORAGE_PASSWORD: &str = "druid.metadata.storage.connector.password";
20+
21+
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
22+
#[serde(rename_all = "camelCase")]
23+
pub enum MetadataDatabaseConnection {
24+
// Docs are on the struct
25+
Postgresql(PostgresqlConnection),
26+
27+
/// Connection settings for a [MySQL](https://www.mysql.com/) database.
28+
///
29+
/// Please note that - due to license issues - we don't ship the mysql driver, you need to add
30+
/// it it yourself.
31+
/// See <https://docs.stackable.tech/home/stable/hive/usage-guide/database-driver/> for details.
32+
Mysql(MysqlConnection),
33+
34+
// Docs are on the struct
35+
Derby(DerbyConnection),
36+
// We don't support generic (yet?), as we need to tell the metastore the `--dbtype` on startup,
37+
// which is not known for generic connection. We could e.g. create a new struct with
38+
// #[serde(flatten)] of the GenericJdbcDatabaseConnection and an additional field
39+
// `metastoreDbType` (or similar).
40+
}
41+
42+
impl MetadataDatabaseConnection {
43+
/// Name of the database as it should be passed using the `--db-type` CLI argument to Hive
44+
pub fn as_db_type(&self) -> &str {
45+
match self {
46+
MetadataDatabaseConnection::Postgresql(_) => "postgresql",
47+
MetadataDatabaseConnection::Mysql(_) => "mysql",
48+
MetadataDatabaseConnection::Derby(_) => "derby",
49+
}
50+
}
51+
}
52+
53+
impl Deref for MetadataDatabaseConnection {
54+
type Target = dyn JdbcDatabaseConnection;
55+
56+
fn deref(&self) -> &Self::Target {
57+
match self {
58+
Self::Postgresql(p) => p,
59+
Self::Mysql(m) => m,
60+
Self::Derby(d) => d,
61+
}
62+
}
63+
}

rust/operator-binary/src/crd/mod.rs

Lines changed: 3 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ use strum::{Display, EnumDiscriminants, EnumIter, EnumString, IntoStaticStr};
4646
use crate::crd::{
4747
affinity::get_affinity,
4848
authorization::DruidAuthorization,
49+
database::MetadataDatabaseConnection,
4950
resource::RoleResource,
5051
tls::{DruidTls, default_druid_tls},
5152
};
5253

5354
pub mod affinity;
5455
pub mod authentication;
5556
pub mod authorization;
57+
pub mod database;
5658
pub mod memory;
5759
pub mod resource;
5860
pub mod security;
@@ -109,21 +111,12 @@ pub const AUTH_AUTHORIZERS_VALUE: &str = "[\"OpaAuthorizer\"]";
109111
pub const AUTH_AUTHORIZER_OPA_TYPE: &str = "druid.auth.authorizer.OpaAuthorizer.type";
110112
pub const AUTH_AUTHORIZER_OPA_TYPE_VALUE: &str = "opa";
111113
pub const AUTH_AUTHORIZER_OPA_URI: &str = "druid.auth.authorizer.OpaAuthorizer.opaUri";
112-
// metadata storage config properties
113-
const METADATA_STORAGE_TYPE: &str = "druid.metadata.storage.type";
114-
const METADATA_STORAGE_URI: &str = "druid.metadata.storage.connector.connectURI";
115-
const METADATA_STORAGE_HOST: &str = "druid.metadata.storage.connector.host";
116-
const METADATA_STORAGE_PORT: &str = "druid.metadata.storage.connector.port";
117-
const METADATA_STORAGE_USER: &str = "druid.metadata.storage.connector.user";
118-
const METADATA_STORAGE_PASSWORD: &str = "druid.metadata.storage.connector.password";
119114
// indexer properties
120115
pub const INDEXER_JAVA_OPTS: &str = "druid.indexer.runner.javaOptsArray";
121116
// historical settings
122117
pub const PROCESSING_BUFFER_SIZE_BYTES: &str = "druid.processing.buffer.sizeBytes";
123118
pub const PROCESSING_NUM_MERGE_BUFFERS: &str = "druid.processing.numMergeBuffers";
124119
pub const PROCESSING_NUM_THREADS: &str = "druid.processing.numThreads";
125-
// extra
126-
pub const CREDENTIALS_SECRET_PROPERTY: &str = "credentialsSecret";
127120
// logs
128121
pub const MAX_DRUID_LOG_FILES_SIZE: MemoryQuantity = MemoryQuantity {
129122
value: 10.0,
@@ -136,10 +129,6 @@ pub const METRICS_PORT: u16 = 9090;
136129

137130
pub const COOKIE_PASSPHRASE_ENV: &str = "OIDC_COOKIE_PASSPHRASE";
138131

139-
// DB credentials - both of these are read from an env var by Druid with the ${env:...} syntax
140-
pub const DB_USERNAME_ENV: &str = "DB_USERNAME_ENV";
141-
pub const DB_PASSWORD_ENV: &str = "DB_PASSWORD_ENV";
142-
143132
// Graceful shutdown timeouts
144133
const DEFAULT_BROKER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_minutes_unchecked(5);
145134
const DEFAULT_COORDINATOR_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_minutes_unchecked(5);
@@ -361,7 +350,7 @@ pub mod versioned {
361350
pub ingestion: Option<IngestionSpec>,
362351

363352
/// Druid requires an SQL database to store metadata into. Specify connection information here.
364-
pub metadata_storage_database: DatabaseConnectionSpec,
353+
pub metadata_database: MetadataDatabaseConnection,
365354

366355
/// TLS encryption settings for Druid, more information in the
367356
/// [security documentation](DOCS_BASE_URL_PLACEHOLDER/druid/usage-guide/security).
@@ -420,34 +409,6 @@ impl v1alpha1::DruidCluster {
420409
match file {
421410
JVM_CONFIG => {}
422411
RUNTIME_PROPS => {
423-
let mds = &self.spec.cluster_config.metadata_storage_database;
424-
result.insert(
425-
METADATA_STORAGE_TYPE.to_string(),
426-
Some(mds.db_type.to_string()),
427-
);
428-
result.insert(
429-
METADATA_STORAGE_URI.to_string(),
430-
Some(mds.conn_string.to_string()),
431-
);
432-
result.insert(
433-
METADATA_STORAGE_HOST.to_string(),
434-
Some(mds.host.to_string()),
435-
);
436-
result.insert(
437-
METADATA_STORAGE_PORT.to_string(),
438-
Some(mds.port.to_string()),
439-
);
440-
if mds.credentials_secret.is_some() {
441-
result.insert(
442-
METADATA_STORAGE_USER.to_string(),
443-
Some(format!("${{env:{DB_USERNAME_ENV}}}")),
444-
);
445-
result.insert(
446-
METADATA_STORAGE_PASSWORD.to_string(),
447-
Some(format!("${{env:{DB_PASSWORD_ENV}}}")),
448-
);
449-
}
450-
451412
// OPA
452413
if let Some(DruidAuthorization { opa: _ }) = &self.spec.cluster_config.authorization
453414
{
@@ -1155,43 +1116,6 @@ impl DruidRole {
11551116
}
11561117
}
11571118

1158-
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
1159-
#[serde(rename_all = "camelCase")]
1160-
pub struct DatabaseConnectionSpec {
1161-
/// The database type. Supported values are: `derby`, `mysql` and `postgres`.
1162-
/// Note that a Derby database created locally in the container is not persisted!
1163-
/// Derby is not suitable for production use.
1164-
pub db_type: DbType,
1165-
/// The connect string for the database, for Postgres this could look like:
1166-
/// `jdbc:postgresql://postgresql-druid/druid`
1167-
pub conn_string: String,
1168-
/// The host, i.e. `postgresql-druid`.
1169-
pub host: String,
1170-
/// The port, i.e. 5432
1171-
pub port: u16,
1172-
/// A reference to a Secret containing the database credentials.
1173-
/// The Secret needs to contain the keys `username` and `password`.
1174-
pub credentials_secret: Option<String>,
1175-
}
1176-
1177-
#[derive(
1178-
Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize, Display, EnumString,
1179-
)]
1180-
pub enum DbType {
1181-
#[serde(rename = "derby")]
1182-
#[strum(serialize = "derby")]
1183-
#[default]
1184-
Derby,
1185-
1186-
#[serde(rename = "mysql")]
1187-
#[strum(serialize = "mysql")]
1188-
Mysql,
1189-
1190-
#[serde(rename = "postgresql")]
1191-
#[strum(serialize = "postgresql")]
1192-
Postgresql,
1193-
}
1194-
11951119
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Eq, Serialize, Display)]
11961120
#[serde(rename_all = "camelCase")]
11971121
pub enum DeepStorageSpec {

0 commit comments

Comments
 (0)