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
  • Loading branch information
Secchol authored and mihailradkov committed Oct 30, 2024
1 parent cb631b6 commit fe4cdbc
Show file tree
Hide file tree
Showing 17 changed files with 696 additions and 31 deletions.
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,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.privateKey` to configure a private key with its properties
- Added `cluster.tls.certificate` to configure a certificate
- 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.rootCerts` to configure root certificates to be trusted
- Added `cluster.tls.certificateChain` to configure a certificate chain
- 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

Expand All @@ -16,6 +30,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 @@ -56,7 +75,7 @@
### Improvement

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

## Version 11.1.4

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,29 @@ 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.certificateRevocationList.certificateRevocationListKey | string | `"crl.pem"` | |
| cluster.tls.certificateRevocationList.existingSecret | string | `""` | |
| cluster.tls.keystore.existingSecret | string | `""` | |
| cluster.tls.keystore.keyAlias | string | `"mykey"` | |
| cluster.tls.keystore.keystoreKey | string | `"keystore.jks"` | |
| cluster.tls.keystore.keystorePasswordKey | string | `"pass"` | |
| cluster.tls.keystore.keystoreProvider | string | `"SUN"` | |
| cluster.tls.keystore.keystoreType | string | `"JKS"` | |
| cluster.tls.mode | string | `"DEFAULT"` | |
| cluster.tls.privateKey.existingSecret | string | `""` | |
| cluster.tls.privateKey.privateKeyKey | string | `"privatekey.pem"` | |
| cluster.tls.privateKey.privateKeyPasswordKey | string | `"pass"` | |
| 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 | `"pass"` | |
| 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 +375,19 @@ 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 | `"mykey"` | |
| configuration.tls.keystore.keystoreKey | string | `"keystore.jks"` | |
| configuration.tls.keystore.keystorePasswordKey | string | `"pass"` | |
| configuration.tls.keystore.keystoreProvider | string | `"SUN"` | |
| configuration.tls.keystore.keystoreType | string | `"JKS"` | |
| configuration.tls.truststore.existingSecret | string | `""` | |
| configuration.tls.truststore.truststoreKey | string | `"truststore.jks"` | |
| configuration.tls.truststore.truststorePasswordKey | string | `"pass"` | |
| configuration.tls.truststore.truststoreProvider | string | `"SUN"` | |
| configuration.tls.truststore.truststoreType | string | `"JKS"` | |
| containerPorts.http | int | `7200` | |
| containerPorts.rpc | int | `7300` | |
| dnsConfig | object | `{}` | |
Expand Down
12 changes: 6 additions & 6 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
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
3 changes: 2 additions & 1 deletion templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,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 := ternary "https" "http" (ne .Values.configuration.tls.keystore.existingSecret "") }}
{{- 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
52 changes: 51 additions & 1 deletion templates/graphdb/configmap-properties.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,61 @@ data:
{{- if eq (int .Values.replicas) 1}}
graphdb.external-url={{ include "graphdb.external-url" . }}
{{- end }}
{{- with .Values.configuration.tls }}
{{- if .keystore.existingSecret }}
graphdb.connector.SSLEnabled = true
graphdb.connector.scheme = https
graphdb.connector.secure = true
graphdb.connector.keystoreFile=/etc/graphdb/connector-keystore/connector-keystore.jks
graphdb.connector.keyAlias={{ .keystore.keyAlias }}
graphdb.connector.keystoreProvider={{ .keystore.keystoreProvider }}
graphdb.connector.keystoreType={{ .keystore.keystoreType }}
{{- end }}
{{- if .truststore.existingSecret }}
graphdb.connector.truststoreFile=/etc/graphdb/connector-truststore/connector-truststore.jks
graphdb.connector.truststoreProvider={{ .truststore.truststoreProvider }}
graphdb.connector.truststoreType={{ .truststore.truststoreType }}
{{- end }}
{{- if .certificateRevocationList.existingSecret}}
graphdb.connector.certificateRevocationListFile=/etc/graphdb/connector-certificate-revocation-list/connector-certificate-revocation-list.pem
{{- end }}
{{- end }}
{{- with .Values.cluster.tls }}
graphdb.raft.security.mode={{ .mode }}
{{- if .privateKey.existingSecret }}
graphdb.raft.security.certificateKeyFile=/etc/graphdb/cluster-private-key/cluster-private-key.pem
{{- end }}
{{- if .certificate.existingSecret }}
graphdb.raft.security.certificateFile=/etc/graphdb/cluster-certificate/cluster-certificate.pem
{{- end }}
{{- if .certificateChain.existingSecret }}
graphdb.raft.security.certificateChainFile=/etc/graphdb/cluster-certificate-chain/cluster-certificate-chain.pem
{{- end }}
{{- if .keystore.existingSecret }}
graphdb.raft.security.keystoreFile=/etc/graphdb/cluster-keystore/cluster-keystore.jks
graphdb.raft.security.keyAlias={{ .keystore.keyAlias }}
graphdb.raft.security.keystoreProvider={{ .keystore.keystoreProvider }}
graphdb.raft.security.keystoreType={{ .keystore.keystoreType }}
{{- end }}
{{- if .truststore.existingSecret }}
graphdb.raft.security.truststoreFile=/etc/graphdb/cluster-truststore/cluster-truststore.jks
graphdb.raft.security.truststoreProvider={{ .truststore.truststoreProvider }}
graphdb.raft.security.truststoreType={{ .truststore.truststoreType }}
{{- end }}
{{- if .rootCerts.existingSecret }}
graphdb.raft.security.rootCerts=/etc/graphdb/cluster-root-certs/cluster-root-certs.pem
{{- end }}
{{- if .certificateRevocationList.existingSecret }}
graphdb.raft.security.certificateRevocationListFile=/etc/graphdb/cluster-certificate-revocation-list/cluster-certificate-revocation-list.pem
{{- end }}
{{- end }}
{{- if .Values.configuration.properties }}
##### Overrides from values.yaml #####
{{- range $key, $val := .Values.configuration.properties -}}
{{- if ne $val nil }}
{{ $key }}={{ tpl ($val | toString) $ | quote }}
{{ $key }}={{ tpl ($val | toString) $ }}
{{- end }}
{{- end -}}
{{- end -}}
2 changes: 1 addition & 1 deletion templates/graphdb/secret-properties.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ stringData:
##### Secrets overrides from values.yaml #####
{{- range $key, $val := .Values.configuration.secretProperties -}}
{{- if ne $val nil }}
{{ $key }}={{ tpl ($val | toString) $ | quote }}
{{ $key }}={{ tpl ($val | toString) $ }}
{{- end }}
{{- end -}}
{{- end -}}
Loading

0 comments on commit fe4cdbc

Please sign in to comment.