Add install-test stage to the PR pipeline (k3d)
New install-test job in validate-charts.yml: for exactly the charts a PR changes, install them into an ephemeral k3d cluster (pinned k3d v5.9.0, k3s v1.35.5-k3s1) and require every Deployment/StatefulSet to become Ready. Runs non-blocking (continue-on-error) during the stabilization phase. Fixtures live at the repo root under ci/ (not inside chart directories, so they neither trigger publishes on merge nor get packaged): a stub OnePasswordItem CRD, per-chart test values and fixtures (dummy secrets with in-cluster DSNs, throwaway postgres/redis/dex, synapse-generate seed job, static hostPath PVs where charts pin storage classes or need RWX), plus a shared ci/run-install-test.sh harness that also runs locally. Excluded with documented reasons (ci/excluded-charts.txt): satisfactory (multi-GB image), teamspeak-server (TS6 beta license expired, image crashes on start), template-chart (placeholder image). All 14 non-excluded charts verified locally in k3d using only the committed fixtures.
This commit is contained in:
35 files changed
+1716
-1
No files matched your search
@@ -67,3 +67,37 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo "Version bump OK: $BASE_VERSION -> $NEW_VERSION"
|
echo "Version bump OK: $BASE_VERSION -> $NEW_VERSION"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
install-test:
|
||||||
|
name: "Install-test ${{ matrix.chart }}"
|
||||||
|
needs: [detect-changed-charts, build-chart]
|
||||||
|
if: needs.detect-changed-charts.outputs.any-chart-changed == 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Stabilization phase (issue #22): the job reports failures but does not
|
||||||
|
# block the PR. Promote to a required check (drop continue-on-error) once
|
||||||
|
# it has proven stable across several chart PRs.
|
||||||
|
continue-on-error: true
|
||||||
|
timeout-minutes: 30
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
chart: ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }}
|
||||||
|
env:
|
||||||
|
K3D_VERSION: v5.9.0
|
||||||
|
K3S_IMAGE: docker.io/rancher/k3s:v1.35.5-k3s1
|
||||||
|
steps:
|
||||||
|
- name: "Checkout Repository"
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: "Install Helm"
|
||||||
|
uses: azure/setup-helm@v4
|
||||||
|
- name: "Install k3d"
|
||||||
|
run: curl -sSfL https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG="$K3D_VERSION" bash
|
||||||
|
- name: "Create k3d cluster"
|
||||||
|
run: k3d cluster create install-test --image "$K3S_IMAGE" --wait --timeout 180s
|
||||||
|
# Excluded charts (see ci/excluded-charts.txt) are skipped inside the
|
||||||
|
# script with their documented reason.
|
||||||
|
- name: "Install chart and wait for readiness"
|
||||||
|
run: ci/run-install-test.sh "${{ matrix.chart }}"
|
||||||
|
- name: "Delete k3d cluster"
|
||||||
|
if: always()
|
||||||
|
run: k3d cluster delete install-test || true
|
||||||
@@ -36,7 +36,21 @@ Collection of some self-made helm-charts. Each top-level directory is a standalo
|
|||||||
- `publish-<chart>.yml` — one thin workflow per chart; triggers on pushes to `main` touching `<chart>/**` (or manually) and calls the reusable workflow below. **A push to a chart directory on `main` publishes that chart**, so the chart version must be bumped in the same change.
|
- `publish-<chart>.yml` — one thin workflow per chart; triggers on pushes to `main` touching `<chart>/**` (or manually) and calls the reusable workflow below. **A push to a chart directory on `main` publishes that chart**, so the chart version must be bumped in the same change.
|
||||||
- `publish-helm-chart.yml` — reusable workflow: `helm package`, then `helm push` to the private JK-Registry. Registry credentials come from 1Password Connect (`OP_CONNECT_TOKEN` secret, items under `op://GitHub-Actions/`).
|
- `publish-helm-chart.yml` — reusable workflow: `helm package`, then `helm push` to the private JK-Registry. Registry credentials come from 1Password Connect (`OP_CONNECT_TOKEN` secret, items under `op://GitHub-Actions/`).
|
||||||
- `change-app-version.yml` — manually dispatched app-version bump; the chart must be listed in its `chart-name` choice list.
|
- `change-app-version.yml` — manually dispatched app-version bump; the chart must be listed in its `chart-name` choice list.
|
||||||
- `validate-charts.yml` — PR pipeline: detects which charts a PR touches and, for exactly those, runs `helm lint --strict`, `helm package`, and a chart-version bump check (`template-chart` is exempt from the version check). PRs without chart changes skip the build matrix.
|
- `validate-charts.yml` — PR pipeline: detects which charts a PR touches and, for exactly those, runs `helm lint --strict`, `helm package`, and a chart-version bump check (`template-chart` is exempt from the version check). PRs without chart changes skip the build matrix. After the build stage, an **install-test** job (same changed-charts matrix) installs each changed chart into an ephemeral [k3d](https://k3d.io) cluster on the runner and requires every workload to become Ready — see below.
|
||||||
|
|
||||||
|
### Install-test (PR pipeline stage 2)
|
||||||
|
|
||||||
|
For every chart a PR changes, `ci/run-install-test.sh <chart>` runs against a throwaway k3d cluster: it applies the stub `OnePasswordItem` CRD plus the chart's fixtures, `helm install`s the chart with its CI values, and waits for all Deployments/StatefulSets to roll out (per-chart timeout). Since probes and security hardening are active on all workloads, "Ready" means the app actually answers. On failure the job dumps pod descriptions, events and container logs.
|
||||||
|
|
||||||
|
Fixtures live at the **repo root** under `ci/` (deliberately *not* inside the chart directories, so they are neither packaged into the chart tgz nor trigger the publish workflows on merge):
|
||||||
|
|
||||||
|
- `ci/common/` — fixtures applied for every chart (schema-less stub CRD for `OnePasswordItem`)
|
||||||
|
- `ci/<chart>/test-values.yaml` — values for the CI install (required for every installable chart)
|
||||||
|
- `ci/<chart>/fixtures.yaml` — dummy secrets with in-cluster connection data, throwaway infrastructure (postgres/redis/dex), static hostPath PVs/StorageClasses where the chart pins a storage class or needs RWX, and seed jobs (e.g. `synapse generate`)
|
||||||
|
- `ci/<chart>/settings.env` — optional overrides (e.g. `INSTALL_TIMEOUT` for slow starters)
|
||||||
|
- `ci/excluded-charts.txt` — charts that cannot run in CI, each with a justification. Currently: `satisfactory` (multi-GB image + 10GB+ Steam download), `teamspeak-server` (the TS6 v6.0.0-beta8 image crashes with "The default license has expired" until the appVersion is bumped), `template-chart` (scaffold with placeholder image)
|
||||||
|
|
||||||
|
Fixture images avoid Docker Hub where possible (`public.ecr.aws`/`ghcr.io`) to dodge runner rate limits. The job currently runs with `continue-on-error: true` (stabilization phase); it will be promoted to a required check once it has proven stable across several chart PRs. When adding a new chart, add its `ci/<chart>/` fixtures (or an entry in `ci/excluded-charts.txt`) — the install-test fails if both are missing. The script also runs locally against any existing cluster: `k3d cluster create t && ci/run-install-test.sh <chart> && k3d cluster delete t`.
|
||||||
|
|
||||||
## Creating a new chart
|
## Creating a new chart
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# apache-tika needs no extra values for a CI install: no secrets, no ingress,
|
||||||
|
# no persistence.
|
||||||
|
{}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
# Fixtures for the calibre-web-automated install-test: the cwa secret the
|
||||||
|
# 1Password operator would otherwise materialize and static hostPath PVs
|
||||||
|
# (the consume PVC is ReadWriteMany, which local-path cannot provision).
|
||||||
|
# This chart names resources <chart>-<release>-..., release name is ci.
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: ci-static
|
||||||
|
provisioner: kubernetes.io/no-provisioner
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: node-setup
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: setup
|
||||||
|
image: public.ecr.aws/docker/library/busybox:1.36
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- >
|
||||||
|
mkdir -p /pv/cwa/data /pv/cwa/consume &&
|
||||||
|
chmod -R 0777 /pv/cwa
|
||||||
|
volumeMounts:
|
||||||
|
- name: pv
|
||||||
|
mountPath: /pv
|
||||||
|
volumes:
|
||||||
|
- name: pv
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-cwa-data
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 2Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ci-static
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: calibre-web-automated-ci-cwa-pvc
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/cwa/data
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-cwa-consume
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ci-static
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: calibre-web-automated-ci-cwa-consume-pvc
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/cwa/consume
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: calibre-web-automated-ci-cwa-secret
|
||||||
|
stringData:
|
||||||
|
hardcover-api-token: ci-dummy-token
|
||||||
|
# Mounted as /config/.config/calibre/customize.py.json (calibre plugin
|
||||||
|
# registry); an empty JSON object is a valid file.
|
||||||
|
calibre-plugins: "{}"
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# First start unpacks the calibre library scaffold onto the volume.
|
||||||
|
INSTALL_TIMEOUT=600
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
secrets:
|
||||||
|
cwaSecretRef: op://ci/cwa
|
||||||
|
|
||||||
|
cwa:
|
||||||
|
# Both PVCs share this class and the consume PVC is RWX, which k3d's
|
||||||
|
# local-path provisioner cannot serve - the fixtures pre-bind static
|
||||||
|
# hostPath PVs of class ci-static instead.
|
||||||
|
storageClass: ci-static
|
||||||
|
storage: 2Gi
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
domain: cwa.ci.local
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Schema-less stub CRD for the 1Password operator's OnePasswordItem CR.
|
||||||
|
# The charts render OnePasswordItem resources; in CI there is no operator, so
|
||||||
|
# this stub lets them apply cleanly while the actual Kubernetes Secrets are
|
||||||
|
# hand-created per chart in ci/<chart>/fixtures.yaml.
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: onepassworditems.onepassword.com
|
||||||
|
spec:
|
||||||
|
group: onepassword.com
|
||||||
|
names:
|
||||||
|
kind: OnePasswordItem
|
||||||
|
listKind: OnePasswordItemList
|
||||||
|
plural: onepassworditems
|
||||||
|
singular: onepassworditem
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- name: v1
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# cyberchef: stateless, no secrets. Only the ingress host is required
|
||||||
|
# (clusterIssuer already has a default). The Ingress just has to apply -
|
||||||
|
# there is no ingress-nginx/cert-manager in the CI cluster.
|
||||||
|
ingress:
|
||||||
|
domain: cyberchef.ci.local
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Charts excluded from the PR install-test, one per line: <chart> <reason>.
|
||||||
|
# ci/run-install-test.sh skips these with the given reason.
|
||||||
|
satisfactory the game-server image is multiple GB and Steam downloads 10GB+ game files on first start - impractical on a CI runner
|
||||||
|
teamspeak-server the TS6 v6.0.0-beta8 image crashes on start ("The default license has expired. Please use the latest server version.", re-verified 2026-08-21); nothing to test until the appVersion is bumped
|
||||||
|
template-chart scaffold with placeholder image "registry/image:xxx", never published
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# gotenberg needs no extra values for a CI install: no secrets, no ingress,
|
||||||
|
# no persistence.
|
||||||
|
{}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Fixtures for the homeassistant install-test: the config secret the
|
||||||
|
# 1Password operator would otherwise materialize (release name: ci). The
|
||||||
|
# chart mounts the three keys as configuration.yaml, http-config.yaml and
|
||||||
|
# recorder-config.yaml under /config.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-homeassistant-config-secret
|
||||||
|
stringData:
|
||||||
|
config: |
|
||||||
|
default_config:
|
||||||
|
http: !include http-config.yaml
|
||||||
|
recorder: !include recorder-config.yaml
|
||||||
|
http-config: |
|
||||||
|
use_x_forwarded_for: true
|
||||||
|
trusted_proxies:
|
||||||
|
- 10.42.0.0/16
|
||||||
|
recorder-config: |
|
||||||
|
db_url: sqlite:////config/home-assistant_v2.db
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Home Assistant's first boot installs/initializes integrations.
|
||||||
|
INSTALL_TIMEOUT=600
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
secrets:
|
||||||
|
configSecretRef: op://ci/homeassistant-config
|
||||||
|
|
||||||
|
core:
|
||||||
|
storage:
|
||||||
|
# k3d's default dynamic provisioner (the values default "default" does
|
||||||
|
# not exist there). Home Assistant starts as root, so writability of the
|
||||||
|
# dynamically provisioned volume is not an issue.
|
||||||
|
storageClass: local-path
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# Fixtures for the matrix-synapse install-test. Synapse needs a signing key
|
||||||
|
# and a log config on its PVC before it starts, so the PVC is backed by a
|
||||||
|
# pre-bound hostPath PV and a seed Job runs "synapse generate" into that
|
||||||
|
# directory first (same pattern as the k3d verification for PRs #21/#26).
|
||||||
|
# The chart mounts homeserver.yaml from the config secret; the static config
|
||||||
|
# below points at the generated key/log-config paths. Release name: ci.
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: ci-static
|
||||||
|
provisioner: kubernetes.io/no-provisioner
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-matrix-synapse-data
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 2Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ci-static
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: ci-matrix-synapse-pvc
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/matrix-synapse
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: synapse-seed
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: generate
|
||||||
|
# Same image the chart deploys (appVersion of matrix-synapse).
|
||||||
|
image: ghcr.io/element-hq/synapse:v1.149.1
|
||||||
|
args: ["generate"]
|
||||||
|
env:
|
||||||
|
- name: SYNAPSE_SERVER_NAME
|
||||||
|
value: synapse.ci.local
|
||||||
|
- name: SYNAPSE_REPORT_STATS
|
||||||
|
value: "no"
|
||||||
|
# Match the UID/GID the chart runs synapse with, so the generated
|
||||||
|
# signing key (mode 0600) is readable by the server container.
|
||||||
|
- name: UID
|
||||||
|
value: "1000"
|
||||||
|
- name: GID
|
||||||
|
value: "1000"
|
||||||
|
volumeMounts:
|
||||||
|
- name: pv
|
||||||
|
mountPath: /data
|
||||||
|
subPath: matrix-synapse-data
|
||||||
|
volumes:
|
||||||
|
- name: pv
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/matrix-synapse
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-matrix-synapse-config-secret
|
||||||
|
stringData:
|
||||||
|
homeserver.yaml: |
|
||||||
|
server_name: "synapse.ci.local"
|
||||||
|
pid_file: /data/homeserver.pid
|
||||||
|
listeners:
|
||||||
|
- port: 8008
|
||||||
|
tls: false
|
||||||
|
type: http
|
||||||
|
x_forwarded: true
|
||||||
|
resources:
|
||||||
|
- names: [client, federation]
|
||||||
|
compress: false
|
||||||
|
database:
|
||||||
|
name: sqlite3
|
||||||
|
args:
|
||||||
|
database: /data/homeserver.db
|
||||||
|
log_config: "/data/synapse.ci.local.log.config"
|
||||||
|
media_store_path: /media_store
|
||||||
|
signing_key_path: "/data/synapse.ci.local.signing.key"
|
||||||
|
registration_shared_secret: "ci-registration-shared-secret"
|
||||||
|
macaroon_secret_key: "ci-macaroon-secret-key"
|
||||||
|
form_secret: "ci-form-secret"
|
||||||
|
report_stats: false
|
||||||
|
trusted_key_servers:
|
||||||
|
- server_name: "matrix.org"
|
||||||
|
suppress_key_server_warning: true
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Synapse first start (SQLite schema setup) plus the config seed job.
|
||||||
|
INSTALL_TIMEOUT=600
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
matrix:
|
||||||
|
serverName: synapse.ci.local
|
||||||
|
configSecretRef: op://ci/matrix-synapse-config
|
||||||
|
delegation:
|
||||||
|
enabled: true
|
||||||
|
serverUrl: ci.local
|
||||||
|
|
||||||
|
storage:
|
||||||
|
amount: 2Gi
|
||||||
|
storageClass: ci-static
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
clusterIssuer: ci
|
||||||
|
domain: matrix.ci.local
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
# Fixtures for the outline install-test: throwaway postgres + redis, a dex
|
||||||
|
# OIDC provider (outline fetches the issuer's discovery document at boot),
|
||||||
|
# and the secrets the 1Password operator would otherwise materialize
|
||||||
|
# (release name: ci). Outline's /_health probe checks Postgres AND Redis.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-outline-secret
|
||||||
|
stringData:
|
||||||
|
# Outline requires 64-char hex secrets.
|
||||||
|
outline-secret-key: 5f4dcc3b5aa765d61d8327deb882cf995f4dcc3b5aa765d61d8327deb882cf99
|
||||||
|
outline-utils-secret: 9c1185a5c5e9fc54612808977ee8f5489c1185a5c5e9fc54612808977ee8f548
|
||||||
|
discovery-url: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
client-id: ci-client
|
||||||
|
client-secret: ci-client-secret
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-outline-db-secret
|
||||||
|
stringData:
|
||||||
|
connection-url: postgres://ci:ci@postgres:5432/outline
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-outline-redis-secret
|
||||||
|
stringData:
|
||||||
|
connection-url: redis://:cipass@redis:6379
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: outline
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: public.ecr.aws/docker/library/redis:7-alpine
|
||||||
|
args: ["redis-server", "--requirepass", "cipass"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 5
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: dex-config
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
issuer: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
storage:
|
||||||
|
type: memory
|
||||||
|
web:
|
||||||
|
http: 0.0.0.0:5556
|
||||||
|
oauth2:
|
||||||
|
skipApprovalScreen: true
|
||||||
|
staticClients:
|
||||||
|
- id: ci-client
|
||||||
|
secret: ci-client-secret
|
||||||
|
name: CI Client
|
||||||
|
redirectURIs:
|
||||||
|
- https://outline.ci.local/auth/oidc.callback
|
||||||
|
enablePasswordDB: true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dex
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: dex
|
||||||
|
image: ghcr.io/dexidp/dex:v2.41.1
|
||||||
|
command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5556
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /dex/healthz
|
||||||
|
port: 5556
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/dex/cfg
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: dex-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dex
|
||||||
|
ports:
|
||||||
|
- port: 5556
|
||||||
|
targetPort: 5556
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
secrets:
|
||||||
|
configSecretRef: op://ci/outline-config
|
||||||
|
redisSecretRef: op://ci/outline-redis
|
||||||
|
dbSecretRef: op://ci/outline-db
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
domain: outline.ci.local
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
# Fixtures for the paperless-ngx install-test: throwaway postgres + redis,
|
||||||
|
# the secrets the 1Password operator would otherwise materialize (release
|
||||||
|
# name: ci), and storage plumbing. The chart hardcodes storageClassName
|
||||||
|
# "longhorn" (RWX for the consume PVC), which does not exist in k3d: a
|
||||||
|
# no-provisioner StorageClass named "longhorn" plus pre-bound hostPath PVs
|
||||||
|
# stand in for it. Paperless runs as uid 1000 with a read-only rootfs and
|
||||||
|
# hostPath volumes do not support fsGroup, so a node-setup Job pre-creates
|
||||||
|
# the exact subPath directories world-writable.
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: longhorn
|
||||||
|
provisioner: kubernetes.io/no-provisioner
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: node-setup
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: setup
|
||||||
|
image: public.ecr.aws/docker/library/busybox:1.36
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- >
|
||||||
|
mkdir -p /pv/paperless-ngx/data/data /pv/paperless-ngx/data/media
|
||||||
|
/pv/paperless-ngx/data/export /pv/paperless-ngx/consume &&
|
||||||
|
chmod -R 0777 /pv/paperless-ngx
|
||||||
|
volumeMounts:
|
||||||
|
- name: pv
|
||||||
|
mountPath: /pv
|
||||||
|
volumes:
|
||||||
|
- name: pv
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-paperless-data
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 20Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: longhorn
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: ci-paperless-ngx-volume-claim
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/paperless-ngx/data
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-paperless-consume
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: longhorn
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: ci-paperless-ngx-consume-volume-claim
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/paperless-ngx/consume
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-paperless-ngx-redis-secret
|
||||||
|
stringData:
|
||||||
|
redis-connection-url: redis://:cipass@redis:6379
|
||||||
|
key-prefix: ci
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-paperless-ngx-db-secret
|
||||||
|
stringData:
|
||||||
|
server: postgres
|
||||||
|
port: "5432"
|
||||||
|
database: paperless
|
||||||
|
username: ci
|
||||||
|
password: ci
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-paperless-ngx-secret
|
||||||
|
stringData:
|
||||||
|
username: admin
|
||||||
|
password: ci-admin-password
|
||||||
|
paperless-secret-key: paperless-ci-secret-key-0123456789abcdef0123456789abcdef
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: paperless
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: public.ecr.aws/docker/library/redis:7-alpine
|
||||||
|
args: ["redis-server", "--requirepass", "cipass"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 5
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Paperless runs database migrations and an index check on first start.
|
||||||
|
INSTALL_TIMEOUT=600
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
secrets:
|
||||||
|
redisRef: op://ci/paperless-redis
|
||||||
|
databaseRef: op://ci/paperless-db
|
||||||
|
paperlessRef: op://ci/paperless
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
domain: paperless.ci.local
|
||||||
|
|
||||||
|
# smbConnection and oidc stay disabled (defaults): the SMB CSI driver and a
|
||||||
|
# real OIDC login flow are out of scope for the CI install-test.
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
# Fixtures for the patchmon install-test: throwaway postgres + redis, a dex
|
||||||
|
# OIDC provider, the secrets the 1Password operator would otherwise
|
||||||
|
# materialize (release name: ci), a pre-bound world-writable hostPath PV for
|
||||||
|
# the assets volume (the non-root backend writes agent assets at boot;
|
||||||
|
# hostPath does not support fsGroup), and a Service alias "backend": the
|
||||||
|
# frontend image's nginx template resolves an upstream host literally named
|
||||||
|
# "backend" at startup (found during the probes verification of PR #21).
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: ci-static
|
||||||
|
provisioner: kubernetes.io/no-provisioner
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: node-setup
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: setup
|
||||||
|
image: public.ecr.aws/docker/library/busybox:1.36
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- >
|
||||||
|
mkdir -p /pv/patchmon/patchmon-assets /pv/patchmon/patchmon-agents &&
|
||||||
|
chmod -R 0777 /pv/patchmon
|
||||||
|
volumeMounts:
|
||||||
|
- name: pv
|
||||||
|
mountPath: /pv
|
||||||
|
volumes:
|
||||||
|
- name: pv
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: ci-patchmon-data
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 10Gi
|
||||||
|
accessModes:
|
||||||
|
# The assets PVC is shared by backend and frontend as ReadWriteMany.
|
||||||
|
- ReadWriteMany
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ci-static
|
||||||
|
claimRef:
|
||||||
|
namespace: default
|
||||||
|
name: ci-patchmon-pvc
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/ci-pv/patchmon
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: ci-patchmon-backend
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 3001
|
||||||
|
- name: direct
|
||||||
|
port: 3001
|
||||||
|
targetPort: 3001
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-patchmon-postgres-secret
|
||||||
|
stringData:
|
||||||
|
database-url: postgresql://ci:ci@postgres:5432/patchmon
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-patchmon-redis-secret
|
||||||
|
stringData:
|
||||||
|
host: redis
|
||||||
|
port: "6379"
|
||||||
|
username: default
|
||||||
|
password: cipass
|
||||||
|
db: "0"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-patchmon-patchmon-secret
|
||||||
|
stringData:
|
||||||
|
jwt-secret: patchmon-ci-jwt-secret-0123456789abcdef0123456789abcdef
|
||||||
|
encryption-key: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
||||||
|
session-secret: patchmon-ci-session-secret-0123456789abcdef0123456789abcdef
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-patchmon-oidc-secret
|
||||||
|
stringData:
|
||||||
|
issuer-url: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
client-id: ci-client
|
||||||
|
client-secret: ci-client-secret
|
||||||
|
redirect-uri: https://patchmon.ci.local/auth/callback
|
||||||
|
requested-scopes: openid profile email
|
||||||
|
button-text: CI SSO
|
||||||
|
user-group-name: users
|
||||||
|
admin-group-name: admins
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: patchmon
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: public.ecr.aws/docker/library/redis:7-alpine
|
||||||
|
args: ["redis-server", "--requirepass", "cipass"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 5
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: dex-config
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
issuer: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
storage:
|
||||||
|
type: memory
|
||||||
|
web:
|
||||||
|
http: 0.0.0.0:5556
|
||||||
|
oauth2:
|
||||||
|
skipApprovalScreen: true
|
||||||
|
staticClients:
|
||||||
|
- id: ci-client
|
||||||
|
secret: ci-client-secret
|
||||||
|
name: CI Client
|
||||||
|
redirectURIs:
|
||||||
|
- https://patchmon.ci.local/auth/callback
|
||||||
|
enablePasswordDB: true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dex
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: dex
|
||||||
|
image: ghcr.io/dexidp/dex:v2.41.1
|
||||||
|
command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5556
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /dex/healthz
|
||||||
|
port: 5556
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/dex/cfg
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: dex-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dex
|
||||||
|
ports:
|
||||||
|
- port: 5556
|
||||||
|
targetPort: 5556
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
secrets:
|
||||||
|
redisSecretRef: op://ci/patchmon-redis
|
||||||
|
postgresSecretRef: op://ci/patchmon-postgres
|
||||||
|
oidcSecretRef: op://ci/patchmon-oidc
|
||||||
|
patchmonSecretRef: op://ci/patchmon
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
clusterIssuer: ci
|
||||||
|
domain: patchmon.ci.local
|
||||||
|
|
||||||
|
patchmon:
|
||||||
|
storage:
|
||||||
|
# Point the RWX assets PVC at the fixture StorageClass so the pre-created
|
||||||
|
# world-writable hostPath PV is used (local-path cannot provision RWX, and
|
||||||
|
# the non-root backend must write its assets dir at boot). Note: the PVC
|
||||||
|
# template guards on .storage.storageClass but renders .storage.class,
|
||||||
|
# so both keys must be set.
|
||||||
|
storageClass: ci-static
|
||||||
|
class: ci-static
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
# Fixtures for the rallly install-test: throwaway postgres, a dex OIDC
|
||||||
|
# provider (the OIDC discovery URL must answer) and the secrets the
|
||||||
|
# 1Password operator would otherwise materialize (release name: ci).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-rallly-secret
|
||||||
|
stringData:
|
||||||
|
secret-key: rallly-ci-secret-key-0123456789abcdef0123456789abcdef
|
||||||
|
initial-admin-email: ci@example.org
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-rallly-database-secret
|
||||||
|
stringData:
|
||||||
|
database-url: postgres://ci:ci@postgres:5432/rallly
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-rallly-oidc-secret
|
||||||
|
stringData:
|
||||||
|
discovery-url: http://dex.default.svc.cluster.local:5556/dex/.well-known/openid-configuration
|
||||||
|
client-id: ci-client
|
||||||
|
client-secret: ci-client-secret
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: rallly
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: dex-config
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
issuer: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
storage:
|
||||||
|
type: memory
|
||||||
|
web:
|
||||||
|
http: 0.0.0.0:5556
|
||||||
|
oauth2:
|
||||||
|
skipApprovalScreen: true
|
||||||
|
staticClients:
|
||||||
|
- id: ci-client
|
||||||
|
secret: ci-client-secret
|
||||||
|
name: CI Client
|
||||||
|
redirectURIs:
|
||||||
|
- https://rallly.ci.local/api/auth/callback/oidc
|
||||||
|
enablePasswordDB: true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dex
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: dex
|
||||||
|
image: ghcr.io/dexidp/dex:v2.41.1
|
||||||
|
command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5556
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /dex/healthz
|
||||||
|
port: 5556
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/dex/cfg
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: dex-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dex
|
||||||
|
ports:
|
||||||
|
- port: 5556
|
||||||
|
targetPort: 5556
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
secrets:
|
||||||
|
ralllySecretRef: op://ci/rallly
|
||||||
|
oidcSecretRef: op://ci/rallly-oidc
|
||||||
|
databaseSecretRef: op://ci/rallly-db
|
||||||
|
# smtp stays disabled (default), so no smtpSecretRef is needed.
|
||||||
|
|
||||||
|
rallly:
|
||||||
|
supportEmail: ci@example.org
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
clusterIssuer: ci
|
||||||
|
domain: rallly.ci.local
|
||||||
Executable
+112
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Install-test harness: installs one chart into the cluster of the current
|
||||||
|
# kubectl context (an ephemeral k3d cluster in CI) using only the committed
|
||||||
|
# fixtures under ci/<chart>/ and requires every workload to become Ready.
|
||||||
|
#
|
||||||
|
# Usage: ci/run-install-test.sh <chart-name>
|
||||||
|
#
|
||||||
|
# Layout (repo root):
|
||||||
|
# ci/common/ fixtures applied for every chart (OnePasswordItem stub CRD)
|
||||||
|
# ci/<chart>/test-values.yaml values for the CI install (required)
|
||||||
|
# ci/<chart>/fixtures.yaml dummy secrets / throwaway infra / static PVs (optional)
|
||||||
|
# ci/<chart>/settings.env optional overrides, e.g. INSTALL_TIMEOUT=600
|
||||||
|
# ci/excluded-charts.txt charts that cannot run in CI, with reasons
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CHART="${1:?usage: $0 <chart-name>}"
|
||||||
|
NAMESPACE="default"
|
||||||
|
RELEASE="ci"
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
CI_DIR="$ROOT/ci"
|
||||||
|
|
||||||
|
# Per-chart override via ci/<chart>/settings.env (INSTALL_TIMEOUT in seconds).
|
||||||
|
INSTALL_TIMEOUT=300
|
||||||
|
FIXTURE_JOB_TIMEOUT=600
|
||||||
|
if [ -f "$CI_DIR/$CHART/settings.env" ]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$CI_DIR/$CHART/settings.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Exclusion list ---------------------------------------------------------
|
||||||
|
if [ -f "$CI_DIR/excluded-charts.txt" ]; then
|
||||||
|
REASON="$(grep -E "^$CHART([[:space:]]|$)" "$CI_DIR/excluded-charts.txt" | sed -E "s/^$CHART[[:space:]]*//" || true)"
|
||||||
|
if [ -n "$REASON" ]; then
|
||||||
|
echo "SKIP: chart '$CHART' is excluded from the install-test: $REASON"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$ROOT/$CHART" ] || [ ! -f "$ROOT/$CHART/Chart.yaml" ]; then
|
||||||
|
echo "ERROR: '$CHART' is not a chart directory" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -f "$CI_DIR/$CHART/test-values.yaml" ]; then
|
||||||
|
echo "ERROR: missing ci/$CHART/test-values.yaml — every installable chart needs CI fixtures." >&2
|
||||||
|
echo "Add test values (and fixtures.yaml if the app needs secrets/infra), or add the chart" >&2
|
||||||
|
echo "to ci/excluded-charts.txt with a justification." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Failure diagnostics ----------------------------------------------------
|
||||||
|
diagnose() {
|
||||||
|
echo "=================== INSTALL-TEST FAILED: DIAGNOSTICS ==================="
|
||||||
|
echo "--- pods ---"
|
||||||
|
kubectl -n "$NAMESPACE" get pods -o wide || true
|
||||||
|
echo "--- events (most recent last) ---"
|
||||||
|
kubectl -n "$NAMESPACE" get events --sort-by=.metadata.creationTimestamp | tail -60 || true
|
||||||
|
echo "--- describe pods ---"
|
||||||
|
kubectl -n "$NAMESPACE" describe pods || true
|
||||||
|
echo "--- container logs ---"
|
||||||
|
for POD in $(kubectl -n "$NAMESPACE" get pods -o name); do
|
||||||
|
echo "--- logs $POD ---"
|
||||||
|
kubectl -n "$NAMESPACE" logs "$POD" --all-containers --tail=150 --prefix || true
|
||||||
|
kubectl -n "$NAMESPACE" logs "$POD" --all-containers --tail=50 --previous --prefix 2>/dev/null || true
|
||||||
|
done
|
||||||
|
echo "========================================================================"
|
||||||
|
}
|
||||||
|
trap 'RC=$?; if [ $RC -ne 0 ]; then diagnose; fi; exit $RC' EXIT
|
||||||
|
|
||||||
|
# --- 1. Apply fixtures ------------------------------------------------------
|
||||||
|
echo "::group::Apply fixtures"
|
||||||
|
kubectl apply -f "$CI_DIR/common/"
|
||||||
|
if [ -f "$CI_DIR/$CHART/fixtures.yaml" ]; then
|
||||||
|
kubectl apply -f "$CI_DIR/$CHART/fixtures.yaml"
|
||||||
|
fi
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
# --- 2. Wait for fixture jobs (node setup, data seeding) and infra ----------
|
||||||
|
echo "::group::Wait for fixture jobs and infrastructure"
|
||||||
|
JOBS="$(kubectl -n "$NAMESPACE" get jobs -o name 2>/dev/null || true)"
|
||||||
|
for JOB in $JOBS; do
|
||||||
|
echo "Waiting for $JOB to complete..."
|
||||||
|
kubectl -n "$NAMESPACE" wait --for=condition=complete "$JOB" --timeout="${FIXTURE_JOB_TIMEOUT}s"
|
||||||
|
done
|
||||||
|
for RES in $(kubectl -n "$NAMESPACE" get deploy,sts -o name 2>/dev/null || true); do
|
||||||
|
echo "Waiting for fixture $RES..."
|
||||||
|
kubectl -n "$NAMESPACE" rollout status "$RES" --timeout="${FIXTURE_JOB_TIMEOUT}s"
|
||||||
|
done
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
# --- 3. Install the chart ---------------------------------------------------
|
||||||
|
echo "::group::helm install"
|
||||||
|
helm install "$RELEASE" "$ROOT/$CHART" \
|
||||||
|
--namespace "$NAMESPACE" \
|
||||||
|
-f "$CI_DIR/$CHART/test-values.yaml"
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
# --- 4. Require every workload to become Ready ------------------------------
|
||||||
|
echo "::group::Wait for workloads (timeout ${INSTALL_TIMEOUT}s each)"
|
||||||
|
WORKLOADS="$(kubectl -n "$NAMESPACE" get deploy,sts -o name)"
|
||||||
|
if [ -z "$WORKLOADS" ]; then
|
||||||
|
echo "ERROR: the release created no Deployments/StatefulSets" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
for RES in $WORKLOADS; do
|
||||||
|
echo "Waiting for $RES..."
|
||||||
|
kubectl -n "$NAMESPACE" rollout status "$RES" --timeout="${INSTALL_TIMEOUT}s"
|
||||||
|
done
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "--- final state ---"
|
||||||
|
kubectl -n "$NAMESPACE" get pods -o wide
|
||||||
|
echo "OK: chart '$CHART' installed and all workloads are Ready."
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Fixtures for the samba install-test: the users secret the 1Password
|
||||||
|
# operator would otherwise materialize (release name: ci). users.conf uses
|
||||||
|
# the dockur/samba "user:password" format.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-samba-users-secret
|
||||||
|
stringData:
|
||||||
|
users.conf: |
|
||||||
|
ciuser:ci-password
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
secrets:
|
||||||
|
sambaUsersRef: op://ci/samba-users
|
||||||
|
|
||||||
|
samba:
|
||||||
|
storageClass: local-path
|
||||||
|
shares:
|
||||||
|
- name: ci-share
|
||||||
|
validUsers: ciuser
|
||||||
|
description: CI test share
|
||||||
|
size: 1Gi
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
# Fixtures for the urlaubsverwaltung install-test: throwaway postgres, a dex
|
||||||
|
# OIDC provider (Spring performs OIDC discovery against the issuer at boot)
|
||||||
|
# and the secrets the 1Password operator would otherwise materialize.
|
||||||
|
# Note: this chart names secrets <chart>-<release>-..., release name is ci.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: urlaubsverwaltung-ci-uv-db-secret
|
||||||
|
stringData:
|
||||||
|
jdbc-url: jdbc:postgresql://postgres:5432/urlaubsverwaltung
|
||||||
|
username: ci
|
||||||
|
password: ci
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: urlaubsverwaltung-ci-uv-oidc-secret
|
||||||
|
stringData:
|
||||||
|
client-id: ci-client
|
||||||
|
client-secret: ci-client-secret
|
||||||
|
issuer-name: CI
|
||||||
|
redirect-uri: https://uv.ci.local/login/oauth2/code/default
|
||||||
|
issuer-uri: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
jwt-issuer-uri: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: urlaubsverwaltung
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: dex-config
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
issuer: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
storage:
|
||||||
|
type: memory
|
||||||
|
web:
|
||||||
|
http: 0.0.0.0:5556
|
||||||
|
oauth2:
|
||||||
|
skipApprovalScreen: true
|
||||||
|
staticClients:
|
||||||
|
- id: ci-client
|
||||||
|
secret: ci-client-secret
|
||||||
|
name: CI Client
|
||||||
|
redirectURIs:
|
||||||
|
- https://uv.ci.local/login/oauth2/code/default
|
||||||
|
enablePasswordDB: true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dex
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: dex
|
||||||
|
image: ghcr.io/dexidp/dex:v2.41.1
|
||||||
|
command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5556
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /dex/healthz
|
||||||
|
port: 5556
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/dex/cfg
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: dex-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dex
|
||||||
|
ports:
|
||||||
|
- port: 5556
|
||||||
|
targetPort: 5556
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Spring Boot startup (JVM + Liquibase migrations) can take a while.
|
||||||
|
INSTALL_TIMEOUT=600
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
secrets:
|
||||||
|
databaseSecretRef: op://ci/uv-db
|
||||||
|
oidcSecretRef: op://ci/uv-oidc
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
domain: uv.ci.local
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
# Fixtures for the voucher-vault install-test: throwaway postgres + redis
|
||||||
|
# (Celery broker), a dex OIDC provider and the secrets the 1Password
|
||||||
|
# operator would otherwise materialize (release name: ci).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-voucher-vault-secret
|
||||||
|
stringData:
|
||||||
|
secretKey: voucher-vault-ci-django-secret-0123456789abcdef0123456789abcdef
|
||||||
|
redis-url: redis://:cipass@redis:6379/0
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-voucher-vault-db-secret
|
||||||
|
stringData:
|
||||||
|
host: postgres
|
||||||
|
port: "5432"
|
||||||
|
user: ci
|
||||||
|
password: ci
|
||||||
|
database: vouchervault
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-voucher-vault-oidc-secret
|
||||||
|
stringData:
|
||||||
|
oidc-jwks-endpoint: http://dex.default.svc.cluster.local:5556/dex/keys
|
||||||
|
client-id: ci-client
|
||||||
|
client-secret: ci-client-secret
|
||||||
|
authorization-endpoint: http://dex.default.svc.cluster.local:5556/dex/auth
|
||||||
|
token-endpoint: http://dex.default.svc.cluster.local:5556/dex/token
|
||||||
|
user-endpoint: http://dex.default.svc.cluster.local:5556/dex/userinfo
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: vouchervault
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: redis
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: public.ecr.aws/docker/library/redis:7-alpine
|
||||||
|
args: ["redis-server", "--requirepass", "cipass"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 5
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: dex-config
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
issuer: http://dex.default.svc.cluster.local:5556/dex
|
||||||
|
storage:
|
||||||
|
type: memory
|
||||||
|
web:
|
||||||
|
http: 0.0.0.0:5556
|
||||||
|
oauth2:
|
||||||
|
skipApprovalScreen: true
|
||||||
|
staticClients:
|
||||||
|
- id: ci-client
|
||||||
|
secret: ci-client-secret
|
||||||
|
name: CI Client
|
||||||
|
redirectURIs:
|
||||||
|
- https://vv.ci.local/oidc/callback
|
||||||
|
enablePasswordDB: true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dex
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dex
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: dex
|
||||||
|
image: ghcr.io/dexidp/dex:v2.41.1
|
||||||
|
command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5556
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /dex/healthz
|
||||||
|
port: 5556
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/dex/cfg
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: dex-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dex
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dex
|
||||||
|
ports:
|
||||||
|
- port: 5556
|
||||||
|
targetPort: 5556
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
secrets:
|
||||||
|
voucherVaultSecretRef: op://ci/voucher-vault
|
||||||
|
oidcSecretRef: op://ci/voucher-vault-oidc
|
||||||
|
databaseSecretRef: op://ci/voucher-vault-db
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
clusterIssuer: ci
|
||||||
|
domain: vv.ci.local
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Fixtures for the zipline install-test: throwaway postgres and the secrets
|
||||||
|
# the 1Password operator would otherwise materialize (release name: ci).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-zipline-db-secret
|
||||||
|
stringData:
|
||||||
|
connection-url: postgresql://ci:ci@postgres:5432/zipline
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ci-zipline-core-secret
|
||||||
|
stringData:
|
||||||
|
server-secret: zipline-ci-core-secret-0123456789abcdef0123456789abcdef0123456789
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: public.ecr.aws/docker/library/postgres:16-alpine
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
value: ci
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: zipline
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command: ["pg_isready", "-U", "ci"]
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
config:
|
||||||
|
storage: 1Gi
|
||||||
|
storageClass: local-path
|
||||||
|
domain: zipline.ci.local
|
||||||
|
# The OnePasswordItem CRs only need non-null item paths; the actual
|
||||||
|
# Kubernetes Secrets come from ci/zipline/fixtures.yaml.
|
||||||
|
secretRef:
|
||||||
|
db: op://ci/zipline-db
|
||||||
|
zipline: op://ci/zipline-core
|
||||||
Reference in new issue
Block a user