Skip to content

PMM-15400 Set the Grafana admin password from a pre-created pmm-secret #422

PMM-15400 Set the Grafana admin password from a pre-created pmm-secret

PMM-15400 Set the Grafana admin password from a pre-created pmm-secret #422

name: PMM-HA PR checks
on:
pull_request:
paths:
- 'charts/pmm-ha/**'
- 'charts/pmm-ha-dependencies/**'
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
sparse-checkout: |
.github/
charts/pmm-ha
charts/pmm-ha-dependencies
- name: Set up Helm
uses: azure/setup-helm@v4.2.0
with:
version: v3.15.4
- uses: azure/setup-kubectl@v4
- name: Set up chart-testing
uses: helm/chart-testing-action@v2.6.1
- name: Add Helm repositories
run: |
helm repo add altinity https://helm.altinity.com
helm repo add percona https://percona.github.io/percona-helm-charts/
helm repo add vm https://victoriametrics.github.io/helm-charts/
helm repo add haproxytech https://haproxytech.github.io/helm-charts/
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts/
helm repo update
# Renders only - no cluster needed. Every case hits the fail in
# pmm.nodeExporter.validate before the lookup in pg-user-credentials-secrets.yaml.
- name: Check node-exporter mode validation
run: |
set -euo pipefail
helm dependency build charts/pmm-ha
assert_fails() { # $1 = expected substring, rest = helm args
local want="$1"; shift
local out
if out=$(helm template smoke charts/pmm-ha "$@" 2>&1); then
echo "::error::expected render to fail: $*"
exit 1
fi
if ! grep -qF "$want" <<<"$out"; then
echo "::error::wrong failure for: $*"
echo "$out"
exit 1
fi
}
collision="would collide with OpenShift's node-exporter on host port 9100"
assert_fails "$collision" --set nodeExporter.mode=openshift
# Nulling the subchart key must not disable the check: Helm treats the dependency
# condition as unresolved and renders the DaemonSet anyway.
assert_fails "$collision" --set nodeExporter.mode=openshift --set prometheus-node-exporter=null
# Non-bool `enabled` values: Helm leaves the subchart enabled and renders the
# DaemonSet, so the check must not treat them as disabled.
assert_fails "$collision" --set nodeExporter.mode=openshift --set prometheus-node-exporter.enabled=null
assert_fails "$collision" --set nodeExporter.mode=openshift --set prometheus-node-exporter.enabled=0
assert_fails "$collision" --set nodeExporter.mode=openshift --set-string prometheus-node-exporter.enabled=false
assert_fails 'nodeExporter.mode must be "internal" or "openshift"' --set nodeExporter.mode=bogus
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --config .github/ct.yaml)
if [[ -n "$changed" ]]; then
echo "changed=true" >> $GITHUB_OUTPUT
fi
- name: Run chart-testing (lint)
run: |
ct lint --config .github/ct.yaml --lint-conf .github/lintconf.yaml --chart-dirs=charts --charts=charts/pmm-ha,charts/pmm-ha-dependencies --check-version-increment=true
- name: Create kind cluster
uses: helm/kind-action@v1.10.0
if: steps.list-changed.outputs.changed == 'true'
- name: Prepare PMM-HA prerequisites
if: steps.list-changed.outputs.changed == 'true'
run: |
NS="pmm-ha-$(openssl rand -hex 5)"
echo "NS=$NS" >> $GITHUB_ENV
kubectl create namespace "$NS" || true
# pmm-secret
cat <<'EOF' | kubectl apply -n "$NS" -f -
apiVersion: v1
kind: Secret
metadata:
name: pmm-secret
labels:
app.kubernetes.io/name: pmm
type: Opaque
data:
PMM_ADMIN_PASSWORD: YWRtaW4=
PG_PASSWORD: cG1tcGFzcw==
GF_PASSWORD: Z2ZwYXNz
VMAGENT_remoteWrite_basicAuth_username: dm11c2Vy
VMAGENT_remoteWrite_basicAuth_password: dm1wYXNz
PMM_CLICKHOUSE_USER: Y2h1c2Vy
PMM_CLICKHOUSE_PASSWORD: Y2hwYXNz
EOF
# Guards the release-name-sensitive names: `pmm.fullname` equals `Release.Name` only
# when the release name already contains the chart name, so a release like `pmm-2`
# (fullname `pmm-2-pmm-ha`) is the case that regresses. `ct install` generates a
# `pmm-ha`-prefixed release name, so the normal install cannot catch this.
# Needs the cluster: templates/pg-user-credentials-secrets.yaml does an unconditional
# `lookup` + `fail` on pmm-secret, so an offline `helm template` cannot render the chart.
- name: Check release-name-sensitive names render correctly
if: steps.list-changed.outputs.changed == 'true'
run: |
set -euo pipefail
NS="${{ env.NS }}"
out=$(helm template pmm-2 charts/pmm-ha --namespace "$NS" --dry-run=server)
assert_has() { # $1 = expected substring, $2 = what it guards
if ! grep -qF -- "$1" <<<"$out"; then
echo "::error::missing from render ($2): $1"
exit 1
fi
}
assert_lacks() {
if grep -qF -- "$1" <<<"$out"; then
echo "::error::render regressed ($2): found $1"
exit 1
fi
}
# The HA peer list must use the StatefulSet name, not Release.Name.
# HAProxy has no per-pod names to check: it discovers backends through the
# headless service via server-template, with no init script (PMM-15394).
assert_has "value: \"pmm-2-pmm-ha-0.monitoring-service.${NS}.svc.cluster.local" "PMM_HA_PEERS"
assert_lacks "pmm-2-0.monitoring-service" "PMM_HA_PEERS uses Release.Name"
# ClickHouse/Keeper scrape jobs match the chi/chk pod label, which carries Release.Name.
assert_has "regex: 'pmm-2'" "clickhouse scrape job selector"
assert_has "regex: 'pmm-2-keeper'" "keeper scrape job selector"
# ...and that is only correct while the CRs are still named from Release.Name.
chi=$(helm template pmm-2 charts/pmm-ha --namespace "$NS" --dry-run=server \
-s templates/clickhouse-cluster.yaml | grep -m1 '^ name:')
[[ "$chi" == " name: pmm-2" ]] || { echo "::error::CHI name changed: $chi"; exit 1; }
# Release names are not regex-safe: a dot in the name must not widen an anchored regex.
helm template 'pmm.ha' charts/pmm-ha --namespace "$NS" --dry-run=server \
| grep -qF "regex: 'pmm\\.ha'" \
|| { echo "::error::Release.Name is not regex-escaped in vmagent scrape configs"; exit 1; }
echo "Release-name-sensitive names render correctly."
- name: Install pmm-ha-dependencies chart
if: steps.list-changed.outputs.changed == 'true'
run: |
echo "Installing pmm-ha-dependencies (operators)..."
# Using --skip-clean-up to keep operators running for pmm-ha installation
ct install --namespace "${{ env.NS }}" --config .github/ct.yaml --charts=charts/pmm-ha-dependencies --skip-clean-up
echo "Waiting for operators to be ready..."
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=victoria-metrics-operator -n "${{ env.NS }}" --timeout=300s
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=altinity-clickhouse-operator -n "${{ env.NS }}" --timeout=300s
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=pg-operator -n "${{ env.NS }}" --timeout=300s
echo "All operators are ready!"
# - name: Setup tmate session on failure
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 60
# with:
# limit-access-to-actor: true
# --dry-run=server (not helm template) because pg-user-credentials-secrets.yaml looks up
# pmm-secret. Runs after the operators so their CRDs are registered: a server dry run still
# maps every manifest through the API, so VMAgent/ClickHouseInstallation must be known.
- name: Check openshift node-exporter scrape job renders
if: steps.list-changed.outputs.changed == 'true'
run: |
set -euo pipefail
helm install smoke charts/pmm-ha -n "${{ env.NS }}" --dry-run=server \
--set nodeExporter.mode=openshift \
--set prometheus-node-exporter.enabled=false > /tmp/smoke.yaml
grep -q "job_name: 'openshift-node-exporter'" /tmp/smoke.yaml
# The point of openshift mode: the bundled DaemonSet must not be deployed.
! grep -q 'kind: DaemonSet' /tmp/smoke.yaml
- name: Run chart-testing (install pmm-ha)
if: steps.list-changed.outputs.changed == 'true'
run: |
# Install pmm-ha chart via ct (using --skip-crds from ct.yaml)
ct install --namespace "${{ env.NS }}" --config .github/ct.yaml --charts=charts/pmm-ha
- name: Build chart packages
run: |
changed=$(ct list-changed --config .github/ct.yaml)
if [[ -n "$changed" ]]; then
for chart in $changed; do
echo "Packaging $chart..."
helm package "$chart"
done
else
echo "No charts changed, skipping package"
fi
- name: Upload helm charts
uses: actions/upload-artifact@v4
with:
path: ./*.tgz
retention-days: 30
if-no-files-found: ignore
- name: Cleanup test resources
if: steps.list-changed.outputs.changed == 'true'
run: |
echo "Cleaning up test namespace: ${{ env.NS }}"
# Uninstall pmm-ha-dependencies chart (ct creates dynamic release names)
DEPS_RELEASE=$(helm list -n "${{ env.NS }}" --filter 'pmm-ha-dependencies-*' -q)
if [[ -n "$DEPS_RELEASE" ]]; then
echo "Uninstalling release: $DEPS_RELEASE"
helm uninstall "$DEPS_RELEASE" -n "${{ env.NS }}" || true
fi
# Delete namespace and all remaining resources
kubectl delete namespace "${{ env.NS }}" --timeout=120s || true
echo "Cleanup completed. CRDs are intentionally left for reuse by other tests."