Initial version

This commit is contained in:
Daniel Berteaud 2024-02-27 13:28:44 +01:00
parent 8c70b14261
commit 43a300fba7
25 changed files with 883 additions and 0 deletions

4
bundles.yml Normal file
View File

@ -0,0 +1,4 @@
---
dependencies:
- url: ../common.git

112
cloudbeaver.nomad.hcl Normal file
View File

@ -0,0 +1,112 @@
job "[[ .instance ]]" {
[[- $c := merge .cloudbeaver . ]]
[[ template "common/job_start" $c ]]
group "cloudbeaver" {
shutdown_delay = "6s"
[[ template "common/constraints" $c ]]
network {
mode = "bridge"
[[- if $c.prometheus.enabled ]]
port "metrics" {}
[[- end ]]
}
[[ template "common/volumes" $c ]]
service {
name = "[[ .instance ]][[ .consul.suffix ]]"
port = 8978
[[ template "common/service_meta" $c ]]
[[ template "common/connect" $c ]]
tags = [
[[ template "common/traefik_tags" $c ]]
]
}
[[ template "common/task.wait_for" $c ]]
[[ template "common/task.pgpooler" $c ]]
task "cloudbeaver" {
driver = "[[ $c.nomad.driver ]]"
config {
image = "[[ $c.image ]]"
pids_limit = 100
readonly_rootfs = true
[[ template "common/tmpfs" "/tmp" ]]
}
[[ template "common/vault.policies" $c ]]
env {
CLOUDBEAVER_WEB_CONFIG = "/local/cloudbeaver.conf"
}
[[ template "common/file_env" $c ]]
# Postgres DB config
template {
data = <<_EOT
PGDATABASE=[[ $c.postgres.database ]]
[[- if ne $c.postgres.pooler.engine "none" ]]
PGHOST=127.0.0.1
PGPORT=6432
PGUSER=[[ .instance ]]
PGPASSWORD={{ env "NOMAD_ALLOC_ID" }}
[[- else ]]
PGHOST=[[ $c.postgres.host ]]
PGPORT=[[ $c.postgres.port ]]
PGUSER=[[ $c.postgres.user ]]
PGPASSWORD=[[ $c.postgres.password ]]
[[- end ]]
_EOT
destination = "secrets/.db.env"
perms = 0400
env = true
}
# Main cloudbeaver configuration
template {
data = <<_EOT
[[- if isKind "map" $c.config ]]
[[ (merge $c.config (tmpl.Exec "cloudbeaver/cloudbeaver.conf" $c | json)) | toJSONPretty " " | replaceAll "${" "$${" ]]
[[- else if isKind "string" $c.config ]]
[[ (merge ($c.config | yaml) (tmpl.Exec "cloudbeaver/cloudbeaver.conf" $c | json)) | toJSONPretty " " | replaceAll "${" "$${" ]]
[[- end ]]
_EOT
destination = "local/cloudbeaver.conf"
}
# Logback config
template {
data = <<_EOT
[[ template "cloudbeaver/logback.xml" $c ]]
_EOT
destination = "local/logback.xml"
}
# Initial config (admin user and teams)
template {
data = <<_EOT
[[ tmpl.Exec "cloudbeaver/initial-data.conf" $c | replaceAll "${" "$${" ]]
_EOT
destination = "secrets/initial-data.conf"
uid = 100000
gid = 108978
perms = 440
}
# Mount persistent volume in /data
volume_mount {
volume = "data"
destination = "/data"
}
[[ template "common/resources" $c ]]
}
}
}

View File

@ -0,0 +1,3 @@
Kind = "service-defaults"
Name = "[[ .instance ]][[ .consul.suffix ]]"
Protocol = "http"

View File

@ -0,0 +1,15 @@
Kind = "service-intentions"
Name = "[[ .instance ]][[ .consul.suffix ]]"
Sources = [
{
Name = "[[ (merge .cloudbeaver .).traefik.instance ]]"
Permissions = [
{
Action = "allow"
HTTP {
PathPrefix = "/"
}
}
]
}
]

9
example/LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 nomad
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

3
example/README.md Normal file
View File

@ -0,0 +1,3 @@
# cloudbeaver
Cloudbever Nomad job template

View File

@ -0,0 +1,320 @@
job "cloudbeaver" {
datacenters = ["dc1"]
region = "global"
group "cloudbeaver" {
shutdown_delay = "6s"
network {
mode = "bridge"
}
volume "data" {
source = "cloudbeaver-data"
type = "csi"
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
service {
name = "cloudbeaver"
port = 8978
meta {
alloc = "${NOMAD_ALLOC_INDEX}"
job = "${NOMAD_JOB_NAME}"
}
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "postgres"
local_bind_port = 5432
# Work arround, see https://github.com/hashicorp/nomad/issues/18538
destination_type = "service"
}
}
}
sidecar_task {
config {
args = [
"-c",
"${NOMAD_SECRETS_DIR}/envoy_bootstrap.json",
"-l",
"${meta.connect.log_level}",
"--concurrency",
"${meta.connect.proxy_concurrency}",
"--disable-hot-restart"
]
}
resources {
cpu = 50
memory = 64
}
}
}
tags = [
"traefik.enable=true",
"traefik.http.routers.cloudbeaver.entrypoints=https",
"traefik.http.routers.cloudbeaver.rule=Host(`cloudbeaver.example.org`)",
"traefik.http.middlewares.csp-cloudbeaver.headers.contentsecuritypolicy=default-src 'self';font-src 'self' data:;img-src 'self' data:;script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';",
"traefik.http.routers.cloudbeaver.middlewares=security-headers@file,rate-limit-std@file,forward-proto@file,inflight-std@file,hsts@file,compression@file,csp-cloudbeaver",
]
}
# wait for required services tp be ready before starting the main task
task "wait-for" {
driver = "docker"
user = 1053
config {
image = "danielberteaud/wait-for:24.2-1"
readonly_rootfs = true
pids_limit = 20
}
lifecycle {
hook = "prestart"
}
env {
SERVICE_0 = "master.postgres.service.consul"
}
resources {
cpu = 10
memory = 10
memory_max = 30
}
}
task "cloudbeaver" {
driver = "docker"
config {
image = "danielberteaud/cloudbeaver:23.3.5"
pids_limit = 100
readonly_rootfs = true
mount {
type = "tmpfs"
target = "/tmp"
tmpfs_options {
size = 3000000
}
}
}
vault {
policies = ["cloudbeaver"]
env = false
disable_file = true
change_mode = "noop"
}
env {
CLOUDBEAVER_WEB_CONFIG = "/local/cloudbeaver.conf"
}
# Use a template block instead of env {} so we can fetch values from vault
template {
data = <<_EOT
LANG=fr_FR.utf8
TZ=Europe/Paris
_EOT
destination = "secrets/.env"
perms = 400
env = true
}
# Postgres DB config
template {
data = <<_EOT
PGDATABASE=cloudbeaver
PGHOST=127.0.0.1
PGPORT=5432
PGUSER={{ with secret "/database/creds/cloudbeaver" }}{{ .Data.username }}{{ end }}
PGPASSWORD={{ with secret "/database/creds/cloudbeaver" }}{{ .Data.password }}{{ end }}
_EOT
destination = "secrets/.db.env"
perms = 0400
env = true
}
# Main cloudbeaver configuration
template {
data = <<_EOT
{
"app": {
"adminCredentialsSaveEnabled": false,
"anonymousAccessAllowed": false,
"anonymousUserTeam": "user",
"authenticationEnabled": true,
"defaultNavigatorSettings": {
"hideFolders": false,
"hideSchemas": false,
"mergeEntities": false,
"showOnlyEntities": false,
"showSystemObjects": true,
"showUtilityObjects": false
},
"disabledDrivers": [
"sqlite:sqlite_jdbc",
"h2:h2_embedded",
"h2:h2_embedded_v2"
],
"enabledAuthProviders": [
"local"
],
"enabledDrivers": [],
"forwardProxy": true,
"plugins": {},
"publicCredentialsSaveEnabled": false,
"resourceManagerEnabled": true,
"resourceQuotas": {
"dataExportFileSizeLimit": 1000000000,
"resourceManagerFileSizeLimit": 500000,
"sqlBinaryPreviewMaxLength": 261120,
"sqlMaxRunningQueries": 100,
"sqlResultSetMemoryLimit": 2000000,
"sqlResultSetRowsLimit": 100000,
"sqlTextPreviewMaxLength": 4096
},
"supportsCustomConnections": true
},
"server": {
"contentRoot": "web",
"database": {
"driver": "postgres-jdbc",
"initialDataConfiguration": "/secrets/initial-data.conf",
"password": "$${PGPASSWORD}",
"pool": {
"maxConnections": 100,
"maxIdleConnections": 10,
"minIdleConnections": 4,
"validationQuery": "SELECT 1"
},
"url": "jdbc:postgresql://$${PGHOST}:$${PGPORT}/$${PGDATABASE}",
"user": "$${PGUSER}"
},
"develMode": false,
"driversLocation": "drivers",
"expireSessionAfterPeriod": 600000,
"productConfiguration": "conf/product.conf",
"rootURI": "/",
"serverHost": "127.0.0.1",
"serverName": "cloudbeaver",
"serverPort": 8978,
"serverURL": "https://cloudbeaver.example.org",
"serviceURI": "/api/",
"sm": {
"blockLoginPeriod": "$${CLOUDBEAVER_BLOCK_PERIOD:300}",
"enableBruteForceProtection": true,
"expiredAuthAttemptInfoTtl": 60,
"maxFailedLogin": "$${CLOUDBEAVER_MAX_FAILED_LOGINS:5}",
"minimumLoginTimeout": "$${CLOUDBEAVER_MINIMUM_LOGIN_TIMEOUT:1}",
"passwordPolicy": {
"minLength": "$${CLOUDBEAVER_POLICY_MIN_LENGTH:8}",
"minNumberCount": "$${CLOUDBEAVER_POLICY_MIN_NUMBER_COUNT:1}",
"minSymbolCount": "$${CLOUDBEAVER_POLICY_MIN_SYMBOL_COUNT:0}",
"requireMixedCase": "$${CLOUDBEAVER_POLICY_REQUIRE_MIXED_CASE:true}"
}
},
"workspaceLocation": "/data"
}
}
_EOT
destination = "local/cloudbeaver.conf"
}
# Logback config
template {
data = <<_EOT
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<!-- Disable logback status messages -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<!--
<logger name="org.jkiss" level="INFO"/>
<logger name="io.cloudbeaver" level="INFO"/>
-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
_EOT
destination = "local/logback.xml"
}
# Initial config (admin user and teams)
template {
data = <<_EOT
{
adminName: "cloudbeaver",
adminPassword: "{{ with secret "/kv/service/cloudbeaver" }}{{ .Data.data.initial_admin_pwd }}{{ end }}",
teams: [
{
subjectId: "admin",
teamName: "Admin",
description: "Administrative access. Has all permissions.",
permissions: [ "admin" ]
},
{
subjectId: "user",
teamName: "User",
description: "All users, including anonymous.",
permissions: [ ]
}
]
}
_EOT
destination = "secrets/initial-data.conf"
uid = 100000
gid = 108978
perms = 440
}
# Mount persistent volume in /data
volume_mount {
volume = "data"
destination = "/data"
}
resources {
cpu = 100
memory = 512
}
}
}
}

View File

@ -0,0 +1,3 @@
Kind = "service-defaults"
Name = "cloudbeaver"
Protocol = "http"

View File

@ -0,0 +1,15 @@
Kind = "service-intentions"
Name = "cloudbeaver"
Sources = [
{
Name = "traefik"
Permissions = [
{
Action = "allow"
HTTP {
PathPrefix = "/"
}
}
]
}
]

View File

@ -0,0 +1,27 @@
FROM danielberteaud/java:17.24.2-4
MAINTAINER Daniel Berteaud <dbd@ehtrace.com>
ENV CLOUDBEAVER_WEB_CONFIG=/opt/cloudbeaver/conf/cloudbeaver.conf
RUN set -euxo pipefail &&\
apk --no-cache add \
ca-certificates \
bash \
&&\
addgroup --gid 8978 cloudbeaver &&\
adduser --system --ingroup cloudbeaver --disabled-password --uid 8978 --home /opt/cloudbeaver --shell /sbin/nologin cloudbeaver &&\
mkdir -p /data/workspace /data/.eclipse &&\
chown -R cloudbeaver:cloudbeaver /data
COPY --from=dbeaver/cloudbeaver:23.3.5 /opt/cloudbeaver /opt/cloudbeaver
COPY root/ /
RUN set -euxo pipefail &&\
cd /opt/cloudbeaver &&\
ln -sf /data/.eclipse ./.eclipse
WORKDIR /opt/cloudbeaver
VOLUME /data
USER cloudbeaver
EXPOSE 8978
CMD ["cloudbeaver"]

View File

@ -0,0 +1,6 @@
#!/bin/sh
mkdir -p /data/workspace/.metadata \
/data/workspace/.data \
/data/workspace/GlobalConfiguration/.dbeaver \
/data/.eclipse

View File

@ -0,0 +1,41 @@
#!/bin/sh
set -euo pipefail
echo "Starting Cloudbeaver Server"
if [ ! -f "/data/workspace/GlobalConfiguration/.dbeaver/data-sources.json" ]; then
cp conf/initial-data-sources.conf /data/workspace/GlobalConfiguration/.dbeaver/data-sources.json
fi
java ${JAVA_OPTS} \
-Dfile.encoding=UTF-8 \
--add-modules=ALL-SYSTEM \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.net=ALL-UNNAMED \
--add-opens=java.base/java.nio=ALL-UNNAMED \
--add-opens=java.base/java.nio.charset=ALL-UNNAMED \
--add-opens=java.base/java.text=ALL-UNNAMED \
--add-opens=java.base/java.time=ALL-UNNAMED \
--add-opens=java.base/java.util=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens=java.base/jdk.internal.vm=ALL-UNNAMED \
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED \
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/sun.security.ssl=ALL-UNNAMED \
--add-opens=java.base/sun.security.action=ALL-UNNAMED \
--add-opens=java.base/sun.security.util=ALL-UNNAMED \
--add-opens=java.security.jgss/sun.security.jgss=ALL-UNNAMED \
--add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens=java.sql/java.sql=ALL-UNNAMED \
-jar server/plugins/org.eclipse.equinox.launcher*.jar \
-product io.cloudbeaver.product.ce.product \
-web-config ${CLOUDBEAVER_WEB_CONFIG} \
-data /data/.metadata \
-configuration /data/.eclipse \
-nl en \
-registryMultiLanguage

View File

@ -0,0 +1,12 @@
#!/bin/sh
set -euo pipefail
vault write /database/roles/cloudbeaver \
db_name="postgres" \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT \"cloudbeaver\" TO \"{{name}}\"; \
ALTER ROLE \"{{name}}\" SET role = \"cloudbeaver\"" \
default_ttl="12h" \
max_ttl="720h"

View File

@ -0,0 +1,22 @@
#!/bin/sh
set -euo pipefail
# vim: syntax=sh
export LC_ALL=C
VAULT_KV_PATH=/kv/service/cloudbeaver
RAND_CMD="tr -dc A-Za-z0-9\-_\/=~\.+ < /dev/urandom | head -c 50"
if ! vault kv list $(dirname ${VAULT_KV_PATH}) 2>/dev/null | grep -q -E "^$(basename ${VAULT_KV_PATH})\$"; then
vault kv put ${VAULT_KV_PATH} \
initial_admin_pwd="$(sh -c "${RAND_CMD}")" \
fi
for SECRET in initial_admin_pwd; do
if ! vault kv get -field ${SECRET} ${VAULT_KV_PATH} >/dev/null 2>&1; then
vault kv patch ${VAULT_KV_PATH} \
${SECRET}=$(sh -c "${RAND_CMD}")
fi
done

View File

@ -0,0 +1,7 @@
path "/kv/data/service/cloudbeaver" {
capabilities = ["read"]
}
path "/database/creds/cloudbeaver" {
capabilities = ["read"]
}

View File

@ -0,0 +1,27 @@
FROM [[ .docker.repo ]][[ .docker.base_images.java17.image ]]
MAINTAINER [[ .docker.maintainer ]]
ENV CLOUDBEAVER_WEB_CONFIG=/opt/cloudbeaver/conf/cloudbeaver.conf
RUN set -euxo pipefail &&\
apk --no-cache add \
ca-certificates \
bash \
&&\
addgroup --gid 8978 cloudbeaver &&\
adduser --system --ingroup cloudbeaver --disabled-password --uid 8978 --home /opt/cloudbeaver --shell /sbin/nologin cloudbeaver &&\
mkdir -p /data/workspace /data/.eclipse &&\
chown -R cloudbeaver:cloudbeaver /data
COPY --from=dbeaver/cloudbeaver:[[ .cloudbeaver.version ]] /opt/cloudbeaver /opt/cloudbeaver
COPY root/ /
RUN set -euxo pipefail &&\
cd /opt/cloudbeaver &&\
ln -sf /data/.eclipse ./.eclipse
WORKDIR /opt/cloudbeaver
VOLUME /data
USER cloudbeaver
EXPOSE 8978
CMD ["cloudbeaver"]

View File

@ -0,0 +1,6 @@
#!/bin/sh
mkdir -p /data/workspace/.metadata \
/data/workspace/.data \
/data/workspace/GlobalConfiguration/.dbeaver \
/data/.eclipse

View File

@ -0,0 +1,41 @@
#!/bin/sh
set -euo pipefail
echo "Starting Cloudbeaver Server"
if [ ! -f "/data/workspace/GlobalConfiguration/.dbeaver/data-sources.json" ]; then
cp conf/initial-data-sources.conf /data/workspace/GlobalConfiguration/.dbeaver/data-sources.json
fi
java ${JAVA_OPTS} \
-Dfile.encoding=UTF-8 \
--add-modules=ALL-SYSTEM \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.net=ALL-UNNAMED \
--add-opens=java.base/java.nio=ALL-UNNAMED \
--add-opens=java.base/java.nio.charset=ALL-UNNAMED \
--add-opens=java.base/java.text=ALL-UNNAMED \
--add-opens=java.base/java.time=ALL-UNNAMED \
--add-opens=java.base/java.util=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens=java.base/jdk.internal.vm=ALL-UNNAMED \
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED \
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/sun.security.ssl=ALL-UNNAMED \
--add-opens=java.base/sun.security.action=ALL-UNNAMED \
--add-opens=java.base/sun.security.util=ALL-UNNAMED \
--add-opens=java.security.jgss/sun.security.jgss=ALL-UNNAMED \
--add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens=java.sql/java.sql=ALL-UNNAMED \
-jar server/plugins/org.eclipse.equinox.launcher*.jar \
-product io.cloudbeaver.product.ce.product \
-web-config ${CLOUDBEAVER_WEB_CONFIG} \
-data /data/.metadata \
-configuration /data/.eclipse \
-nl en \
-registryMultiLanguage

View File

@ -0,0 +1,5 @@
#!/bin/sh
set -euo pipefail
[[ template "common/vault.mkpgrole.sh" merge .cloudbeaver . ]]

View File

@ -0,0 +1,5 @@
#!/bin/sh
set -euo pipefail
[[ template "common/vault.rand_secrets" merge .cloudbeaver . ]]

View File

@ -0,0 +1,81 @@
{
server: {
serverPort: 8978,
serverHost: "127.0.0.1",
serverName: "[[ .instance ]]",
workspaceLocation: "/data",
contentRoot: "web",
driversLocation: "drivers",
serverURL: "[[ .public_url ]]",
rootURI: "[[ (urlParse .public_url).Path | regexp.Replace "/$" "" ]]/",
serviceURI: "[[ (urlParse .public_url).Path | regexp.Replace "/$" "" ]]/api/",
productConfiguration: "conf/product.conf",
expireSessionAfterPeriod: 600000,
develMode: false,
sm: {
enableBruteForceProtection: true,
expiredAuthAttemptInfoTtl: 60,
maxFailedLogin: "${CLOUDBEAVER_MAX_FAILED_LOGINS:5}",
minimumLoginTimeout: "${CLOUDBEAVER_MINIMUM_LOGIN_TIMEOUT:1}",
blockLoginPeriod: "${CLOUDBEAVER_BLOCK_PERIOD:300}",
passwordPolicy: {
minLength: "${CLOUDBEAVER_POLICY_MIN_LENGTH:8}",
requireMixedCase: "${CLOUDBEAVER_POLICY_REQUIRE_MIXED_CASE:true}",
minNumberCount: "${CLOUDBEAVER_POLICY_MIN_NUMBER_COUNT:1}",
minSymbolCount: "${CLOUDBEAVER_POLICY_MIN_SYMBOL_COUNT:0}"
}
},
database: {
driver: "postgres-jdbc",
url: "jdbc:postgresql://${PGHOST}:${PGPORT}/${PGDATABASE}",
user: "${PGUSER}",
password: "${PGPASSWORD}",
initialDataConfiguration: "/secrets/initial-data.conf",
pool: {
minIdleConnections: 4,
maxIdleConnections: 10,
maxConnections: 100,
validationQuery: "SELECT 1"
}
}
},
app: {
anonymousAccessAllowed: false,
anonymousUserTeam: "user",
authenticationEnabled: true,
supportsCustomConnections: true,
forwardProxy: true,
publicCredentialsSaveEnabled: false,
adminCredentialsSaveEnabled: false,
resourceManagerEnabled: true,
resourceQuotas: {
dataExportFileSizeLimit: 1000000000,
resourceManagerFileSizeLimit: 500000,
sqlMaxRunningQueries: 100,
sqlResultSetRowsLimit: 100000,
sqlResultSetMemoryLimit: 2000000,
sqlTextPreviewMaxLength: 4096,
sqlBinaryPreviewMaxLength: 261120
},
defaultNavigatorSettings: {
showSystemObjects: true,
showUtilityObjects: false,
showOnlyEntities: false,
mergeEntities: false,
hideFolders: false,
hideSchemas: false
},
plugins: {
},
enabledAuthProviders: [
"local"
],
enabledDrivers: [
],
disabledDrivers: [
"sqlite:sqlite_jdbc",
"h2:h2_embedded",
"h2:h2_embedded_v2"
]
}
}

View File

@ -0,0 +1,18 @@
{
adminName: "cloudbeaver",
adminPassword: "{{ with secret "[[ .vault.root ]]kv/service/[[ .instance ]]" }}{{ .Data.data.initial_admin_pwd }}{{ end }}",
teams: [
{
subjectId: "admin",
teamName: "Admin",
description: "Administrative access. Has all permissions.",
permissions: [ "admin" ]
},
{
subjectId: "user",
teamName: "User",
description: "All users, including anonymous.",
permissions: [ ]
}
]
}

19
templates/logback.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<!-- Disable logback status messages -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<!--
<logger name="org.jkiss" level="INFO"/>
<logger name="io.cloudbeaver" level="INFO"/>
-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

75
variables.yml Normal file
View File

@ -0,0 +1,75 @@
---
# Name of this instance
instance: cloudbeaver
cloudbeaver:
# Version of cloudbeaver to deploy
version: 23.3.5
# Docker image to use
image: '[[ .docker.repo ]]cloudbeaver:[[ .cloudbeaver.version ]]'
# Resources for the container
resources:
cpu: 100
memory: 512
vault:
# Vault policies to attach to the container
policies:
- '[[ .instance ]][[ .consul.suffix ]]'
# Random secrets to generate
rand_secrets:
fields:
- initial_admin_pwd
consul:
connect:
# Connect to the postgres server
upstreams:
- destination_name: postgres[[ .consul.suffix ]]
local_bind_port: 5432
# Wait for postgres master to be ready before starting
wait_for:
- service: master.postgres[[ .consul.suffix ]]
# Custom env var to set in the container
env: {}
# Custom configuration which will be merged with the default template
# Eg
# config:
# app:
# enabledAuthProviders:
# - reverseProxy
# - local
# authConfigurations:
# - id: lemonldap
# provider: reverseProxy
# displayName: Lemonldap::NG
# parameters:
# user-header: X-SSO-User
# team-header: X-SSO-Groups
# team-delimiter: ','
# first-name-header: X-SSO-Firstname
# last-name-header: X-SSO-Lastname
# Can be either a map, or a string which will be parsed as YAML before merging
config: {}
# URL where cloudbeaver will be exposed
public_url: https://cloudbeaver.example.org
# Traefik settings
traefik: {}
# CSI volumes for data persistence
volumes:
data:
source: '[[ .instance ]]-data'
type: csi

View File

@ -0,0 +1,7 @@
path "[[ .vault.root ]]kv/data/service/[[ .instance ]]" {
capabilities = ["read"]
}
path "[[ .vault.root ]]database/creds/[[ .instance ]]" {
capabilities = ["read"]
}