Skip to content

Commit

Permalink
PRO-446: Added support for configuring trust stores and key stores
Browse files Browse the repository at this point in the history
GraphDB Tomcat and GraphDB gRPC cluster can now be configured with TLS for secure
communication with GraphDB.

- Added Tomcat TLS configurations under `configuration.tls`
- Added gRPC TLS configurations under `cluster.tls`
- Updated jobs and scripts to use `https` or `http` depending on whether
  the Tomcat connector security is configured
- Added template for rendering the GraphDB protocol
- Added the protocol in the cronjob for backups
- Used volume projection to simplify the statefulset
- Read key/trust stores passwords as files
- Renamed privateKey to certificateKey
  • Loading branch information
Secchol committed Jan 10, 2025
1 parent 8b55cb4 commit a88971d
Show file tree
Hide file tree
Showing 18 changed files with 594 additions and 36 deletions.
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@
- Added `license.mountPath` to configure where the license volume is mounted
- Added `license.optional` to configure the license volume as optional if needed
- Added `license.readOnly` to configure the read/write mode of the license volume mount
- Added new configuration properties for GraphDB Tomcat connector SSL/TLS
- Added `configuration.tls.keystore` to configure a keystore with its properties
- Added `configuration.tls.truststore` to configure a truststore with its properties
- Added `configuration.tls.certificateRevocationList` to configure a certificate revocation list
- Added new configuration properties for configuring GraphDB cluster security (SSL/TLS)
- Added `cluster.tls.mode` to configure cluster security mode
- Added `cluster.tls.keystore` to configure a keystore with its properties
- Added `cluster.tls.truststore` to configure a truststore with its properties
- Added `cluster.tls.certificate` to configure a certificate
- Added `cluster.tls.certificateChain` to configure a certificate chain
- Added `cluster.tls.certificateKey` to configure a private key with its properties
- Added `cluster.tls.rootCerts` to configure root certificates to be trusted
- Added `cluster.tls.certificateRevocationList` to configure a certificate revocation list
- Updated jobs and scripts to use `https` or `http` depending on whether the Tomcat connector security is configured

- Updated to GraphDB [10.8.0](https://graphdb.ontotext.com/documentation/10.8/release-notes.html#graphdb-10-8-0)

Expand All @@ -30,6 +44,11 @@
mount. This allows kubelet to update the license when the Secret has been updated.
- Changed the license volume mount as read-only by default with `license.readOnly`

### Fixed

- Removed the `quotes` tag from graphdb and proxy `configmap-properties` and `secret-properties` templates
which caused invalid rendering of extra properties.

## Version 11.2.2

### New
Expand Down Expand Up @@ -70,7 +89,7 @@
### Improvement

- Added GraphDB configuration examples
- Added GraphDB security configration examples
- Added GraphDB security configuration examples

## Version 11.1.4

Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,30 @@ IMPORTANT: This is generated by helm-docs, do not attempt modifying it on hand a
| cluster.jobs.createCluster.enabled | bool | `true` | |
| cluster.jobs.patchCluster.enabled | bool | `true` | |
| cluster.jobs.scaleCluster.enabled | bool | `true` | |
| cluster.tls.certificate.certificateKey | string | `"certificate.pem"` | |
| cluster.tls.certificate.existingSecret | string | `""` | |
| cluster.tls.certificateChain.certificateChainKey | string | `"certChain.pem"` | |
| cluster.tls.certificateChain.existingSecret | string | `""` | |
| cluster.tls.certificateKey.existingSecret | string | `""` | |
| cluster.tls.certificateKey.privateKeyKey | string | `"privatekey.pem"` | |
| cluster.tls.certificateKey.privateKeyPasswordKey | string | `"privatekey_password"` | |
| cluster.tls.certificateRevocationList.certificateRevocationListKey | string | `"crl.pem"` | |
| cluster.tls.certificateRevocationList.existingSecret | string | `""` | |
| cluster.tls.keystore.existingSecret | string | `""` | |
| cluster.tls.keystore.keyAlias | string | `"graphdb"` | |
| cluster.tls.keystore.keystoreKey | string | `"keystore.jks"` | |
| cluster.tls.keystore.keystorePasswordKey | string | `"keystore_password"` | |
| cluster.tls.keystore.keystoreProvider | string | `"SUN"` | |
| cluster.tls.keystore.keystoreType | string | `"JKS"` | |
| cluster.tls.mode | string | `"DEFAULT"` | |
| cluster.tls.mountPath | string | `"/etc/graphdb/tls/grpc/"` | |
| cluster.tls.rootCerts.existingSecret | string | `""` | |
| cluster.tls.rootCerts.rootCertsKey | string | `"rootCerts.pem"` | |
| cluster.tls.truststore.existingSecret | string | `""` | |
| cluster.tls.truststore.truststoreKey | string | `"truststore.jks"` | |
| cluster.tls.truststore.truststorePasswordKey | string | `"truststore_password"` | |
| cluster.tls.truststore.truststoreProvider | string | `"SUN"` | |
| cluster.tls.truststore.truststoreType | string | `"JKS"` | |
| cluster.token.existingSecret | string | `""` | |
| cluster.token.secret | string | `"s3cr37"` | |
| cluster.token.secretKey | string | `""` | |
Expand All @@ -352,6 +376,20 @@ IMPORTANT: This is generated by helm-docs, do not attempt modifying it on hand a
| configuration.logback.existingConfigmap | string | `""` | |
| configuration.properties | object | `{}` | |
| configuration.secretProperties | object | `{}` | |
| configuration.tls.certificateRevocationList.certificateRevocationListKey | string | `"crl.pem"` | |
| configuration.tls.certificateRevocationList.existingSecret | string | `""` | |
| configuration.tls.keystore.existingSecret | string | `""` | |
| configuration.tls.keystore.keyAlias | string | `"graphdb"` | |
| configuration.tls.keystore.keystoreKey | string | `"keystore.jks"` | |
| configuration.tls.keystore.keystorePasswordKey | string | `"keystore_password"` | |
| configuration.tls.keystore.keystoreProvider | string | `"SUN"` | |
| configuration.tls.keystore.keystoreType | string | `"JKS"` | |
| configuration.tls.mountPath | string | `"/etc/graphdb/tls/tomcat/"` | |
| configuration.tls.truststore.existingSecret | string | `""` | |
| configuration.tls.truststore.truststoreKey | string | `"truststore.jks"` | |
| configuration.tls.truststore.truststorePasswordKey | string | `"truststore_password"` | |
| configuration.tls.truststore.truststoreProvider | string | `"SUN"` | |
| configuration.tls.truststore.truststoreType | string | `"JKS"` | |
| containerPorts.http | int | `7200` | |
| containerPorts.rpc | int | `7300` | |
| dnsConfig | object | `{}` | |
Expand Down
20 changes: 10 additions & 10 deletions files/scripts/graphdb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ function createCluster {

echo "Creating cluster"
response=$(mktemp)
curl -o "$response" -isSL -m "${timeout}" -X POST \
curl -k -o "$response" -isSL -m "${timeout}" -X POST \
-d @"$configLocation" \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
"http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config"

if grep -q 'HTTP/1.1 201' "$response"; then
echo "Cluster creation successful!"
Expand All @@ -47,7 +47,7 @@ function waitService {
local max_attempts=100

echo "Waiting for ${address}"
until curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do
until curl -k --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do
if [[ ${attempt_counter} -eq ${max_attempts} ]];then
echo "Max attempts reached"
exit 1
Expand All @@ -65,7 +65,7 @@ function waitAllNodes {
for (( c=node_count; c>0; c ))
do
c=$((c-1))
waitService "http://${GRAPHDB_POD_NAME}-$c.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"
waitService "${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-$c.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"
done
}

Expand All @@ -83,11 +83,11 @@ function createRepositoryFromFile {

echo "Provisioning repository ${repositoryName}"
response=$(
curl -X POST --connect-timeout 60 --retry 3 --retry-all-errors --retry-delay 10 \
curl -k -X POST --connect-timeout 60 --retry 3 --retry-all-errors --retry-delay 10 \
-F config=@"${filename}" \
-H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
-H 'Content-Type: multipart/form-data' \
"http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"
)

if [ -z "$response" ]; then
Expand Down Expand Up @@ -135,15 +135,15 @@ function cloudBackup {
local response=
local response_status
response=$(mktemp)
response_status=$(curl -X POST \
response_status=$(curl -k -X POST \
-isSL \
-o "${response}" \
-w "Status=%{response_code}" \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-binary "${backup_options}" \
--url "http://${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/recovery/cloud-backup")
--url "${GRAPHDB_PROTOCOL}://${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/recovery/cloud-backup")

if ! echo "${response_status}" | grep -q 'Status=200' ; then
log "ERROR: Backup ${BACKUP_NAME} creation failed, response: ${response_status}"
Expand All @@ -168,15 +168,15 @@ function localBackup() {
log "Creating local backup ${backup_path}"

local response
response=$(curl -X POST \
response=$(curl -k -X POST \
-sSL \
-o "${backup_path}" \
-w "Status=%{response_code}" \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-binary "${backup_options}" \
--url "http://${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/recovery/backup")
--url "${GRAPHDB_PROTOCOL}://${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/recovery/backup")

if ! echo "${response}" | grep -q 'Status=200' ; then
log "ERROR: Backup ${BACKUP_NAME} creation failed, response: ${response}"
Expand Down
30 changes: 15 additions & 15 deletions files/scripts/update-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ function patchCluster {
local timeout=$2
local response

waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"
waitService "${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"

echo "Patching cluster"
response=$(mktemp)
curl -o "$response" -isSL -m "$timeout" -X PATCH \
curl -k -o "$response" -isSL -m "$timeout" -X PATCH \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
-d @"$configLocation" \
"http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config"

if grep -q 'HTTP/1.1 200' "$response"; then
echo "Patch successful"
Expand Down Expand Up @@ -65,16 +65,16 @@ function removeNodes {
done
nodes=\{\"nodes\":\[${nodes}\]\}

waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"
waitService "${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"

echo "Scaling the cluster down"
response=$(mktemp)
curl -o "$response" -isSL -m 15 -X DELETE \
curl -k -o "$response" -isSL -m 15 -X DELETE \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
-d "${nodes}" \
"http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node"

if grep -q 'HTTP/1.1 200' "$response"; then
echo "Scaling down successful."
Expand Down Expand Up @@ -113,16 +113,16 @@ function addNodes {
done
nodes=\{\"nodes\":\[${nodes}\]\}

waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"
waitService "${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready"

echo "Scaling the cluster up"
response=$(mktemp)
curl -o "$response" -isSL -m "${timeout}" -X POST \
curl -k -o "$response" -isSL -m "${timeout}" -X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
-d "${nodes}" \
"http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node"

if grep -q 'HTTP/1.1 200' "$response"; then
echo "Scaling successful."
Expand All @@ -141,14 +141,14 @@ function addNodes {
}

function deleteCluster {
waitService "http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"
waitService "${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories"

local response
response=$(mktemp)
curl -o "$response" -isSL -m 15 -X DELETE \
curl -k -o "$response" -isSL -m 15 -X DELETE \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Accept: */*' \
"http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config?force=false"
"${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config?force=false"

if grep -q 'HTTP/1.1 200' "$response"; then
echo "Cluster deletion successful!"
Expand All @@ -163,13 +163,13 @@ function deleteCluster {
}

function getNodeCountInCurrentCluster {
local node_address="http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}"
local node_address="${GRAPHDB_PROTOCOL}://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}"

waitService "${node_address}/rest/repositories"

local response
response=$(mktemp)
curl -o "$response" -isSL -m 15 -X GET \
curl -k -o "$response" -isSL -m 15 -X GET \
--header 'Content-Type: application/json' \
--header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \
--header 'Accept: */*' \
Expand All @@ -183,7 +183,7 @@ function waitService {
local attempt_counter=0
local max_attempts=100

until curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do
until curl -k --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do
if [[ ${attempt_counter} -eq ${max_attempts} ]]; then
echo "Max attempts reached"
exit 1
Expand Down
10 changes: 9 additions & 1 deletion templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ Renders the external URL for GraphDB.
{{- tpl .Values.configuration.externalUrl . -}}
{{- end -}}

{{/*
Render the protocol of the Tomcat connector.
*/}}
{{- define "graphdb.tomcat.protocol" -}}
{{- ternary "http" "https" (eq (.Values.configuration.tls.keystore.existingSecret | default "" | trim) "") -}}
{{- end -}}

{{/*
Renders the gRPC address of each GraphDB node that is part of the cluster as a JSON array. Used in the cluster JSON config.
*/}}
Expand All @@ -57,8 +64,9 @@ Renders the HTTP address of each GraphDB node that is part of the cluster, joine
{{- $namespace := include "graphdb.namespace" . -}}
{{- $cluster_domain := .Values.global.clusterDomain -}}
{{- $service_http_port := .Values.headlessService.ports.http -}}
{{- $protocol := include "graphdb.tomcat.protocol" . }}
{{- range $i, $node_index := until (int .Values.replicas) -}}
http://{{ $pod_name }}-{{ $node_index }}.{{ $service_name }}.{{ $namespace }}.svc.{{ $cluster_domain }}:{{ $service_http_port }}
{{ $protocol }}://{{ $pod_name }}-{{ $node_index }}.{{ $service_name }}.{{ $namespace }}.svc.{{ $cluster_domain }}:{{ $service_http_port }}
{{- if gt (sub (int $.Values.replicas) 1) $node_index -}}
{{- ", " -}}
{{- end -}}
Expand Down
Loading

0 comments on commit a88971d

Please sign in to comment.