Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/helm-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Helm rendering tests

on:
pull_request:
paths:
- 'deploy/helm/**'
- 'deploy/tests/**'
- '.github/workflows/helm-tests.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
configmaps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: azure/setup-helm@v4
with:
version: 'v3.16.4'
- run: python -m pip install -r deploy/tests/requirements.txt
- run: python -m pytest deploy/tests -q
- run: helm lint deploy/helm
2 changes: 1 addition & 1 deletion deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.5
version: 0.1.6

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
12 changes: 6 additions & 6 deletions deploy/helm/templates/chatbot/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ data:
WEB_SERVICE: {{ .Values.web.service.name }}
TLS_ENABLED: {{ .Values.tlsEnabled | quote }}
DB_HOST: {{ .Values.postgresdb.service.name }}
DB_USER: {{ .Values.postgresdb.config.postgresUser }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName }}
DB_USER: {{ .Values.postgresdb.config.postgresUser | quote }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword | quote }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName | quote }}
DB_PORT: {{ .Values.postgresdb.port | quote }}
MONGO_DB_HOST: {{ .Values.mongodb.service.name }}
MONGO_DB_PORT: {{ .Values.mongodb.port | quote }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser | quote }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword | quote }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName | quote }}
CHATBOT_LIFE: {{ .Values.chatbotLife | quote }}
CHATBOT_OPENAI_API_KEY: {{ .Values.chatbotOpenaiApiKey | default .Values.openAIApiKey | quote }}
CHATBOT_OPENAI_BASE_URL: {{ .Values.chatbotOpenaiBaseUrl | quote }}
Expand Down
12 changes: 6 additions & 6 deletions deploy/helm/templates/community/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ data:
LOG_LEVEL: {{ .Values.logLevel | upper }}
IDENTITY_SERVICE: {{ .Values.identity.service.name }}:{{ .Values.identity.port }}
DB_HOST: {{ .Values.postgresdb.service.name }}
DB_USER: {{ .Values.postgresdb.config.postgresUser }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName }}
DB_USER: {{ .Values.postgresdb.config.postgresUser | quote }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword | quote }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName | quote }}
DB_PORT: {{ .Values.postgresdb.port | quote }}
MONGO_DB_HOST: {{ .Values.mongodb.service.name }}
MONGO_DB_PORT: {{ .Values.mongodb.port | quote }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser | quote }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword | quote }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName | quote }}
SERVER_PORT: {{ .Values.community.port | quote }}
TLS_ENABLED: {{ .Values.tlsEnabled | quote }}
6 changes: 3 additions & 3 deletions deploy/helm/templates/identity/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ data:
ENABLE_SHELL_INJECTION: {{ .Values.enableShellInjection | quote }}
ENABLE_LOG4J: {{ .Values.enableLog4j | quote }}
DB_HOST: {{ .Values.postgresdb.service.name }}
DB_USER: {{ .Values.postgresdb.config.postgresUser }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName }}
DB_USER: {{ .Values.postgresdb.config.postgresUser | quote }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword | quote }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName | quote }}
DB_PORT: {{ .Values.postgresdb.port | quote }}
MAILHOG_HOST: {{ .Values.mailhog.smtpService.name }}
MAILHOG_PORT: {{ .Values.mailhog.smtpPort | quote }}
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/templates/mongodb/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
MONGO_INITDB_ROOT_USERNAME: {{ .Values.mongodb.config.mongoUser }}
MONGO_INITDB_ROOT_PASSWORD: {{ .Values.mongodb.config.mongoPassword }}
MONGO_INITDB_ROOT_USERNAME: {{ .Values.mongodb.config.mongoUser | quote }}
MONGO_INITDB_ROOT_PASSWORD: {{ .Values.mongodb.config.mongoPassword | quote }}
6 changes: 3 additions & 3 deletions deploy/helm/templates/postgres/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
POSTGRES_USER: {{ .Values.postgresdb.config.postgresUser }}
POSTGRES_PASSWORD: {{ .Values.postgresdb.config.postgresPassword }}
POSTGRES_DB: {{ .Values.postgresdb.config.postgresDbName }}
POSTGRES_USER: {{ .Values.postgresdb.config.postgresUser | quote }}
POSTGRES_PASSWORD: {{ .Values.postgresdb.config.postgresPassword | quote }}
POSTGRES_DB: {{ .Values.postgresdb.config.postgresDbName | quote }}
12 changes: 6 additions & 6 deletions deploy/helm/templates/workshop/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ data:
IDENTITY_SERVICE: {{ .Values.identity.service.name }}:{{ .Values.identity.port }}
SECRET_KEY: {{ .Values.workshop.config.secretKey }}
DB_HOST: {{ .Values.postgresdb.service.name }}
DB_USER: {{ .Values.postgresdb.config.postgresUser }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName }}
DB_USER: {{ .Values.postgresdb.config.postgresUser | quote }}
DB_PASSWORD: {{ .Values.postgresdb.config.postgresPassword | quote }}
DB_NAME: {{ .Values.postgresdb.config.postgresDbName | quote }}
DB_PORT: {{ .Values.postgresdb.port | quote }}
MONGO_DB_HOST: {{ .Values.mongodb.service.name }}
MONGO_DB_PORT: {{ .Values.mongodb.port | quote }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName }}
MONGO_DB_USER: {{ .Values.mongodb.config.mongoUser | quote }}
MONGO_DB_PASSWORD: {{ .Values.mongodb.config.mongoPassword | quote }}
MONGO_DB_NAME: {{ .Values.mongodb.config.mongoDbName | quote }}
SERVER_PORT: {{ .Values.workshop.port | quote }}
API_GATEWAY_URL: {{ if .Values.apiGatewayServiceInstall }}"https://{{ .Values.apiGatewayService.service.name }}"{{ else }}{{ .Values.apiGatewayServiceUrl }}{{ end }}
TLS_ENABLED: {{ .Values.tlsEnabled | quote }}
Expand Down
14 changes: 14 additions & 0 deletions deploy/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Helm rendering tests

Install Helm 3 and the Python test dependencies, then run from the repository root:

```sh
python -m pip install -r deploy/tests/requirements.txt
python -m pytest deploy/tests -q
helm lint deploy/helm
```

Helm must be on `PATH`, or set `HELM_BINARY` to its executable path. These tests
render the chart locally; they do not need a Kubernetes cluster. They verify that
ConfigMap data contains strings and database credentials survive YAML rendering,
including numeric-looking values, empty strings, whitespace and special characters.
2 changes: 2 additions & 0 deletions deploy/tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest
PyYAML
83 changes: 83 additions & 0 deletions deploy/tests/test_helm_configmaps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""Render the chart and validate ConfigMap data without a Kubernetes cluster."""

import os
import shutil
import subprocess
from pathlib import Path

import pytest
import yaml

CHART = Path(__file__).resolve().parents[1] / "helm"
HELM = os.environ.get("HELM_BINARY") or shutil.which("helm")


def render_configmaps(tmp_path, overrides):
if not HELM:
pytest.skip("Helm is required; install Helm or set HELM_BINARY")
values = tmp_path / "values.yaml"
values.write_text(yaml.safe_dump(overrides), encoding="utf-8")
result = subprocess.run(
[HELM, "template", "crapi", str(CHART), "-f", str(values)],
check=True,
capture_output=True,
text=True,
)
return {
document["metadata"]["name"]: document["data"]
for document in yaml.safe_load_all(result.stdout)
if document and document["kind"] == "ConfigMap"
}


def assert_string_data(configmaps):
assert configmaps, "The chart must render ConfigMaps"
for name, data in configmaps.items():
for key, value in data.items():
assert isinstance(value, str), f"{name}.{key}: {value!r} is not a string"


def test_default_configmap_data_is_strings(tmp_path):
assert_string_data(render_configmaps(tmp_path, {}))


@pytest.mark.parametrize(
"credential",
["123456", "true", "null", "", " leading space ", "value: # comment\nnext line"],
)
def test_database_credentials_survive_yaml_rendering(tmp_path, credential):
configmaps = render_configmaps(
tmp_path,
{
"postgresdb": {
"config": {
"postgresUser": credential,
"postgresPassword": credential,
"postgresDbName": credential,
}
},
"mongodb": {
"config": {
"mongoUser": credential,
"mongoPassword": credential,
"mongoDbName": credential,
}
},
},
)
assert_string_data(configmaps)
for name in (
"crapi-chatbot-configmap",
"crapi-community-configmap",
"crapi-identity-configmap",
"crapi-workshop-configmap",
):
for key in ("DB_USER", "DB_PASSWORD", "DB_NAME"):
assert configmaps[name][key] == credential
if name != "crapi-identity-configmap":
for key in ("MONGO_DB_USER", "MONGO_DB_PASSWORD", "MONGO_DB_NAME"):
assert configmaps[name][key] == credential
for key in ("POSTGRES_USER", "POSTGRES_PASSWORD", "POSTGRES_DB"):
assert configmaps["postgres-config"][key] == credential
for key in ("MONGO_INITDB_ROOT_USERNAME", "MONGO_INITDB_ROOT_PASSWORD"):
assert configmaps["mongodb-config"][key] == credential