Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7c7d79a
UNSOI-3673 Deployment files for Plan.R Tools
paulwellnerbou Mar 30, 2026
53f6308
Increase timeouts
paulwellnerbou Mar 30, 2026
10e947f
Fix path mapping and complete test yaml
paulwellnerbou Mar 30, 2026
35bf1e2
Merge branch 'main' into UNSOI-3673-planr-tools-in-unified-installieren
paulwellnerbou Mar 30, 2026
5d8bd4f
[UNSOI-3673] [planr-tools] strip path prefix in HTTPRoute via URLRewr…
paulwellnerbou Mar 30, 2026
f821a32
Remove review file
paulwellnerbou Mar 30, 2026
f9b1b80
Rename credentials more precisely
paulwellnerbou Mar 30, 2026
7f8219b
[UNSOI-3673] [planr-tools] centralize app key list in _helpers.tpl
paulwellnerbou Mar 30, 2026
62871c0
Rename credentials (password, too)
paulwellnerbou Mar 30, 2026
2624e6d
[UNSOI-3673] [planr-tools] rename appKeys helper to app-keys
paulwellnerbou Mar 30, 2026
d2142e0
[UNSOI-3673] [planr-tools] guard nginx ingress annotations behind ing…
paulwellnerbou Mar 30, 2026
89b6754
[UNSOI-3673] [planr-tools] remove unused ingress.pathType from values…
paulwellnerbou Mar 30, 2026
2963d5b
[UNSOI-3673] [planr-tools] document required secret and ingress contr…
paulwellnerbou Mar 30, 2026
4ddb9f3
Remove review md file
paulwellnerbou Mar 30, 2026
39ba740
Improve test description
paulwellnerbou Mar 30, 2026
f6b0741
Use empty strings for values expected to be found in secrets instead …
paulwellnerbou Mar 30, 2026
31361d4
Disable jolokia and endpoints management endpoints
paulwellnerbou Mar 30, 2026
2c3d9ab
[UNSOI-3673] [planr-tools] restrict actuator exposure to health,info …
paulwellnerbou Mar 30, 2026
6508d72
[UNSOI-3673] [planr-tools] compute config checksum from rendered appl…
paulwellnerbou Mar 30, 2026
346839d
[UNSOI-3673] [planr-tools] add ingress unit tests and extend httprout…
paulwellnerbou Mar 30, 2026
c08d545
Set latest release version instead of snapshot version
paulwellnerbou Apr 20, 2026
ec9a619
Merge branch 'main' into UNSOI-3673-planr-tools-in-unified-installieren
paulwellnerbou Apr 20, 2026
2eab35a
Set chart version to 1.0.0
paulwellnerbou Apr 20, 2026
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
17 changes: 17 additions & 0 deletions charts/planr-tools/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.DS_Store
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
*.swp
*.bak
*.tmp
*.orig
*~
.project
.idea/
*.tmproj
.vscode/
13 changes: 13 additions & 0 deletions charts/planr-tools/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v2
name: planr-tools
description: A Helm chart for deploying the planr-tools applications
type: application
version: 1.0.0
appVersion: "5.1.1"
annotations:
artifacthub.io/changes: |
- kind: added
description: Initial release of the planr-tools chart.
sources:
- https://github.com/subshell/helm-charts/tree/main/charts/planr-tools
home: https://gitlab.com/subshell/kunden/planr-tools
93 changes: 93 additions & 0 deletions charts/planr-tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# planr-tools

This chart deploys the three `planr-tools` applications together:

* `newsroom-document-creator`
* `newsroom-feed`
* `newsroom-widget`

Each application is deployed as its own `Deployment`, `Service`, and `ConfigMap`, while the chart offers shared `Ingress` and `HTTPRoute` resources for path-based external access.

## Prerequisites

### Sophora credentials secret

A Kubernetes secret containing the Sophora CMS credentials is required. Create it before installing the chart:

```sh
kubectl create secret generic planr-tools-sophora-credentials \
--from-literal=username=<your-username> \
--from-literal=password=<your-password>
```

Expected keys:
- `username` — Sophora CMS username
- `password` — Sophora CMS password

### Ingress controller requirements

The `Ingress` resource uses `pathType: ImplementationSpecific` with nginx-style regex paths and a `rewrite-target` annotation to strip path prefixes before forwarding to each app. This requires an ingress controller that:

- Supports regex matching for `pathType: ImplementationSpecific`
- Supports `nginx.ingress.kubernetes.io/rewrite-target` with capture groups

The nginx ingress controller (`ingressClassName: nginx`) satisfies both requirements and is the default. Other controllers may not be compatible. Consider using `HTTPRoute` instead if you are not using nginx.

## Example values.yaml

```yaml
ingress:
enabled: true
ingressClassName: nginx
hosts:
- host: planr-tools.example.com

httpRoute:
enabled: false

applications:
documentCreator:
service:
type: ClusterIP
config:
sophora:
client:
server-connection:
urls: https://cms.example.com
username: ${SOPHORA_USERNAME}
password: ${SOPHORA_PASSWORD}

feed:
service:
type: ClusterIP
config:
sophora:
client:
server-connection:
urls: https://cms.example.com
username: ${SOPHORA_USERNAME}
password: ${SOPHORA_PASSWORD}

widget:
service:
type: ClusterIP
config:
sophora:
client:
server-connection:
urls: https://cms.example.com
username: ${SOPHORA_USERNAME}
password: ${SOPHORA_PASSWORD}

commonEnv:
- name: SOPHORA_USERNAME
valueFrom:
secretKeyRef:
name: planr-tools-sophora-credentials
key: username
- name: SOPHORA_PASSWORD
valueFrom:
secretKeyRef:
name: planr-tools-sophora-credentials
key: password
```
107 changes: 107 additions & 0 deletions charts/planr-tools/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "planr-tools.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
*/}}
{{- define "planr-tools.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "planr-tools.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels.
*/}}
{{- define "planr-tools.labels" -}}
helm.sh/chart: {{ include "planr-tools.chart" .root }}
{{ include "planr-tools.selectorLabels" . }}
{{- if .root.Chart.AppVersion }}
app.kubernetes.io/version: {{ .root.Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
{{- end }}

{{/*
Selector labels.
*/}}
{{- define "planr-tools.selectorLabels" -}}
app.kubernetes.io/name: {{ include "planr-tools.name" .root }}
app.kubernetes.io/instance: {{ .root.Release.Name }}
app.kubernetes.io/component: {{ .component.name }}
{{- end }}

{{/*
Service account name.
*/}}
{{- define "planr-tools.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "planr-tools.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
Ordered list of application keys.
Wrapped in a map because fromYaml requires a top-level map, not a bare list.
Usage: range $appKey := (include "planr-tools.app-keys" . | fromYaml).keys
*/}}
{{- define "planr-tools.app-keys" -}}
keys:
- documentCreator
- feed
- widget
{{- end }}

{{/*
Component fullname.
*/}}
{{- define "planr-tools.componentFullname" -}}
{{- printf "%s-%s" (include "planr-tools.fullname" .root) .component.name | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Component configmap name.
*/}}
{{- define "planr-tools.componentConfigName" -}}
{{- printf "%s-config" (include "planr-tools.componentFullname" .) | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Config checksum.
Computed from the fully rendered application.yml (after tpl), not the raw config map,
so that changes to values referenced inside config templates also trigger pod restarts.
*/}}
{{- define "planr-tools.componentConfigChecksum" -}}
{{- include "planr-tools.render" (dict "value" .component.config "context" .root) | sha256sum }}
{{- end }}

{{/*
Renders a value that contains templates.
*/}}
{{- define "planr-tools.render" -}}
{{- if typeIs "string" .value }}
{{- tpl .value .context }}
{{- else }}
{{- tpl (.value | toYaml) .context }}
{{- end }}
{{- end -}}
16 changes: 16 additions & 0 deletions charts/planr-tools/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{{- $root := . -}}
{{- range $appKey := (include "planr-tools.app-keys" $root | fromYaml).keys }}
{{- $component := index $root.Values.applications $appKey }}
{{- if $component.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "planr-tools.componentConfigName" (dict "root" $root "component" $component) }}
labels:
{{- include "planr-tools.labels" (dict "root" $root "component" $component) | nindent 4 }}
data:
application.yml: |-
{{- include "planr-tools.render" (dict "value" $component.config "context" $root) | nindent 4 }}
---
{{- end }}
{{- end }}
119 changes: 119 additions & 0 deletions charts/planr-tools/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{{- $root := . -}}
{{- range $appKey := (include "planr-tools.app-keys" $root | fromYaml).keys }}
{{- $component := index $root.Values.applications $appKey }}
{{- if $component.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "planr-tools.componentFullname" (dict "root" $root "component" $component) }}
labels:
{{- include "planr-tools.labels" (dict "root" $root "component" $component) | nindent 4 }}
spec:
replicas: {{ default $root.Values.replicaCount $component.replicaCount }}
selector:
matchLabels:
{{- include "planr-tools.selectorLabels" (dict "root" $root "component" $component) | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include "planr-tools.componentConfigChecksum" (dict "root" $root "component" $component) }}
{{- with $root.Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "planr-tools.selectorLabels" (dict "root" $root "component" $component) | nindent 8 }}
spec:
{{- if $component.hostname }}
hostname: {{ $component.hostname }}
{{- end }}
serviceAccountName: {{ include "planr-tools.serviceAccountName" $root }}
automountServiceAccountToken: {{ $root.Values.serviceAccount.automount }}
{{- with $root.Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml $root.Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ $component.name }}
image: "{{ $component.image.repository }}:{{ $component.image.tag | default $root.Chart.AppVersion }}"
imagePullPolicy: {{ $component.image.pullPolicy }}
securityContext:
{{- toYaml $root.Values.containerSecurityContext | nindent 12 }}
env:
- name: JAVA_OPTS
value: {{ $root.Values.javaOptions | quote }}
{{- with $root.Values.commonEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with $component.env }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if or $root.Values.commonEnvFrom $component.envFrom }}
envFrom:
{{- with $root.Values.commonEnvFrom }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with $component.envFrom }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
ports:
- name: http
containerPort: {{ $component.service.targetPort }}
protocol: TCP
{{- with $root.Values.startupProbe }}
startupProbe:
httpGet:
port: http
path: /actuator/health/liveness
failureThreshold: {{ .failureThreshold }}
initialDelaySeconds: {{ .initialDelaySeconds }}
periodSeconds: {{ .periodSeconds }}
timeoutSeconds: {{ .timeoutSeconds }}
{{- end }}
{{- with $root.Values.livenessProbe }}
livenessProbe:
httpGet:
port: http
path: /actuator/health/liveness
failureThreshold: {{ .failureThreshold }}
initialDelaySeconds: {{ .initialDelaySeconds }}
periodSeconds: {{ .periodSeconds }}
timeoutSeconds: {{ .timeoutSeconds }}
{{- end }}
{{- with $root.Values.readinessProbe }}
readinessProbe:
httpGet:
port: http
path: /actuator/health/readiness
failureThreshold: {{ .failureThreshold }}
initialDelaySeconds: {{ .initialDelaySeconds }}
periodSeconds: {{ .periodSeconds }}
timeoutSeconds: {{ .timeoutSeconds }}
{{- end }}
volumeMounts:
- name: application-config
mountPath: /app/application.yml
subPath: application.yml
resources:
{{- toYaml ($component.resources | default $root.Values.resources) | nindent 12 }}
volumes:
- name: application-config
configMap:
name: {{ include "planr-tools.componentConfigName" (dict "root" $root "component" $component) }}
{{- with $root.Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with $root.Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with $root.Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
---
{{- end }}
{{- end }}
Loading
Loading