Skip to content

Helm chart thunder - #33

Open
Aravinda-HWK wants to merge 19 commits into
mainfrom
helm-chart-thunder
Open

Helm chart thunder#33
Aravinda-HWK wants to merge 19 commits into
mainfrom
helm-chart-thunder

Conversation

@Aravinda-HWK

Copy link
Copy Markdown
Contributor

Description

Adds an umbrella Helm chart that wraps the upstream WSO2 Thunder v0.32.0 chart and bakes this repo's bootstrap scripts into a ConfigMap, so installing Thunder on Kubernetes is a single helm install matching the rest of the mail-plane charts. The image (ghcr.io/asgardeo/thunder:0.32.0) matches the version pinned in docker-compose.yml.

Type of Change

  • New feature
  • Bug fix
  • Documentation update
  • Code refactoring
  • Other (please describe):

Changes Made

  • New umbrella Helm chart silver-thunder at mail-infra/helm/thunder/ (Chart + values + README + values.example.yaml + .helmignore).
  • Vendors the upstream thunder v0.32.0 chart verbatim under charts/thunder/ (sourced from thunder-id/thunderid @ v0.32.0/install/helm). Vendored because the upstream chart was never published to OCI at this version — the published OCI artifact (thunderid 0.38.0+) was a later rename. Vendoring + a repository: "file://." no-op dependency entry keeps helm install a single command (no helm dependency build step required).
  • Cleaned vendored noise: deleted the upstream README (~64 KB of docs) and duplicate .helmignore. Added a small VENDORED.md sentinel inside charts/thunder/ explaining provenance and pointing back at the umbrella's README.
  • templates/bootstrap-configmap.yaml renders this repo's mail-infra/scripts/thunder/01-default-resources.sh and 02-sample-resources.sh (copied into files/ as 20- and 30- prefixed scripts) into a ConfigMap named thunder-bootstrap via (.Files.Glob "files/*.sh").AsConfig.
  • The ConfigMap is annotated as a pre-install,pre-upgrade Helm hook at weight -10 (matches the upstream's own setup-config-map / bootstrap-configmap), so it's created before the setup Job (pre-install hook at weight -5) tries to mount it. Without this, the Job's MountVolume.SetUp failed for volume "bootstrap-scripts" : configmap "thunder-bootstrap" not found and Helm rolled back the entire release.
  • Umbrella values.yaml overrides the subchart's defaults under the thunder: key for a working SQLite-on-minikube install:
    • deployment.replicaCount: 1, securityContext.readOnlyRootFilesystem: false, hpa.enabled: false (SQLite is single-writer, no autoscale).
    • All four databases (config, runtime, user, consent) switched from the chart's Postgres default to SQLite. The consent database had to be wired explicitly — without it the OpenFGC consent server crash-loops with dial tcp [::1]:5432: connect: connection refused.
    • persistence.enabled: true (PVC for SQLite data).
    • bootstrap.configMap.name: thunder-bootstrap + files: [20-default-resources.sh, 30-sample-resources.sh] (Pattern 2 — additive to the chart's built-in 10-* defaults).
    • Image pinned to ghcr.io/asgardeo/thunder:0.32.0 to match docker-compose.yml.
  • Compatible script API: at v0.32.0 the upstream common.sh already provides thunder_api_call (the rename to thunderid_api_call only happened in 0.38.0+), so no shim is needed.
  • README documents the directory layout, a "which values.yaml do I edit?" table, the bootstrap script ordering, how to update the vendored subchart (single curl … | tar -xz + cp -R), and how to access the running pod (port-forward for local minikube / cluster-internal DNS for the other mail-plane charts).

Testing

  • helm lint mail-infra/helm/thunder → 0 errors, 0 warnings.
  • helm template thunder ./mail-infra/helm/thunder --namespace pingmailer → 17 resources rendered (16 from the vendored subchart + 1 umbrella thunder-bootstrap ConfigMap), all 3 image: lines = ghcr.io/asgardeo/thunder:0.32.0, rendered consent-deployment.yaml shows type: "sqlite" (no Postgres dial).
  • Verified pre-install hook ordering: rendered umbrella ConfigMap carries helm.sh/hook: pre-install,pre-upgrade, helm.sh/hook-weight: "-10".
  • End-to-end install on minikube (image: ghcr.io/asgardeo/thunder:0.32.0):
    1. helm upgrade --install thunder ./mail-infra/helm/thunder -n pingmailer --create-namespace -f my-thunder-values.yaml
    2. Pre-install hooks: thunder-bootstrap + upstream config-maps land first; thunder-setup Job runs, executes the chart's 10-* scripts + this repo's 20-default-resources.sh (creates default OU, person schema, admin user, system resource server, system action, admin role, CONSOLE app) + 30-sample-resources.sh (no-op). Job exits 0.
    3. Main thunder-deployment pod runs, both daemons (Consent Server on :9090, Thunder Server on :8090) start cleanly. Health endpoints return 200 (/health/liveness, /health/readiness).
    4. kubectl -n pingmailer port-forward svc/thunder-service 8090:8090 + curl -k https://localhost:8090/health → 200 OK.
  • Negative test: pre-install hook timeout from earlier draft reproduced (failed pre-install: timed out waiting for the condition, ConfigMap not found) — fix verified by re-installing with the hook annotations in place.

Checklist

  • My code follows the project's coding standards
  • I have tested my changes
  • I have updated the documentation (if needed)
  • My changes don't introduce new warnings or errors

Related Issues

Fixes #

Aravinda-HWK and others added 17 commits April 23, 2026 16:00
… scripts for streamlined deployment

Co-authored-by: Copilot <copilot@github.com>
- Introduced `02-sample-resources.sh` to automate the creation of a SPA resource.
- The script sources common functions and loads environment variables from a `.env` file.
- It defines default parameters for the SPA and includes functions to extract JSON values, get organization unit IDs, and fetch flow IDs.
- Implements the `create_spa_application` function to handle the API call for creating the SPA with necessary configurations.
- Logs success or error messages based on the API response.
…rement

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
…aven config script for OAUTHBEARER support

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
- Introduced a new ConfigMap (`thunder-bootstrap`) to include bootstrap scripts for application provisioning.
- Added `30-sample-resources.sh` script to log the completion of sample resources step.
- Created `NOTES.txt` to provide installation and usage instructions for the silver-thunder chart.
- Implemented helper functions in `_helpers.tpl` for consistent naming and labeling.
- Updated `values.yaml` and `values.example.yaml` with necessary configurations for deployment and ingress.
@Aravinda-HWK
Aravinda-HWK requested a review from maneesha-xyz May 24, 2026 07:09
@Aravinda-HWK Aravinda-HWK self-assigned this May 24, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request transitions the API server to mandatory HTTPS and replaces password-based SMTP authentication with XOAUTH2 token forwarding. It introduces support for multiple recipients via a new recipients array in the request body and updates the success response status to 202 Accepted. Additionally, a new umbrella Helm chart for WSO2 Thunder is added to the infrastructure. Feedback suggests merging global template data with per-recipient fields to preserve personalization and implementing parallel email delivery to improve performance for large recipient lists.

Comment on lines +191 to 213
func sendNotifyEmail(mailer emailer.Mailer, req notifyRequest, recipients []user) error {
var sendErrors []error

for _, recipient := range recipients {
if req.Template == "" {
if err := mailer.Send(recipient.Email, "welcome.tmpl", recipient); err != nil {
sendErrors = append(sendErrors, fmt.Errorf("recipient %s: %w", recipient.Email, err))
}
continue
}

templateData := any(recipient)
if len(req.TemplateData) > 0 {
templateData = req.TemplateData
}

if err := mailer.SendWithCustomTemplate(recipient.Email, req.Template, templateData); err != nil {
sendErrors = append(sendErrors, fmt.Errorf("recipient %s: %w", recipient.Email, err))
}
}

return errors.Join(sendErrors...)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In sendNotifyEmail, if req.TemplateData is provided, it completely overrides the per-recipient data (recipient struct) for custom templates. This means that personalization fields like {{.Name}} or {{.Email}} will not be available in the custom template unless they are manually included in req.TemplateData for every request. Consider merging the per-recipient data with req.TemplateData to allow both global and personalized fields in custom templates.

Comment on lines +194 to +210
for _, recipient := range recipients {
if req.Template == "" {
if err := mailer.Send(recipient.Email, "welcome.tmpl", recipient); err != nil {
sendErrors = append(sendErrors, fmt.Errorf("recipient %s: %w", recipient.Email, err))
}
continue
}

templateData := any(recipient)
if len(req.TemplateData) > 0 {
templateData = req.TemplateData
}

if err := mailer.SendWithCustomTemplate(recipient.Email, req.Template, templateData); err != nil {
sendErrors = append(sendErrors, fmt.Errorf("recipient %s: %w", recipient.Email, err))
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Emails are currently sent sequentially in a loop. If the recipients list is large or the SMTP server is slow, this background task could take a significant amount of time to complete. Consider sending emails in parallel using goroutines and a synchronization primitive like errgroup.Group. This provides a localized concurrency improvement without the complexity of a full worker pool architecture, which can be deferred to a future PR.

References
  1. When a suggested change involves significant architectural refactoring (e.g., implementing a worker pool), it can be deferred to a future PR. A simpler, more localized solution (e.g., using a WaitGroup) can be used as an interim measure.

@@ -0,0 +1,36 @@
/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants